2024-05-21 06:07:24 -05:00
|
|
|
const getStatements = {
|
|
|
|
"int": "params.getInt(%s)",
|
|
|
|
"String": "params.getString(%s)",
|
|
|
|
"boolean": "params.getBoolean(%s)",
|
|
|
|
"float": "params.getFloat(%s)",
|
|
|
|
"byte": "params.getByte(%s)",
|
|
|
|
"char": "params.getChar(%s)",
|
|
|
|
"double": "params.getDouble(%s)",
|
|
|
|
}
|
2024-05-24 03:39:34 -05:00
|
|
|
const primitiveDefaultValues = {
|
|
|
|
"int": "0",
|
|
|
|
"String": "\"\"",
|
|
|
|
"boolean": "false",
|
|
|
|
"float": "0.0f",
|
|
|
|
"byte": "(byte) 0",
|
|
|
|
"char": "\'a\'",
|
|
|
|
"double": "0.0d",
|
|
|
|
}
|
2024-05-21 19:04:52 -05:00
|
|
|
const callbackStatements = {
|
|
|
|
"boolean": "setCallbackBooleanWithDataArg",
|
|
|
|
"int": "setCallbackIntWithDataArg",
|
|
|
|
"String": "setCallbackStringWithDataArg",
|
|
|
|
"double": "setCallbackDoubleWithDataArg",
|
|
|
|
"float": "setCallbackFloatWithDataArg",
|
|
|
|
}
|
2024-05-21 06:07:24 -05:00
|
|
|
const getStatementsTypes = Object.keys(getStatements);
|
2024-05-21 19:04:52 -05:00
|
|
|
const callbackStatementsTypes = Object.keys(callbackStatements);
|
2024-05-21 06:07:24 -05:00
|
|
|
function reconJ(java, className) {
|
2024-05-21 19:04:52 -05:00
|
|
|
var usedClasses = [];
|
|
|
|
var javaText = java;
|
|
|
|
|
|
|
|
javaText = javaText.replace(/\/\/.*$/gm, '');
|
|
|
|
javaText = javaText.replace(/\/\*[\s\S]*?\*\//gm, '');
|
2024-05-31 08:22:26 -05:00
|
|
|
javaText = javaText.replace(/[ \t](public|private|protected|)\s*(static|) (class|enum) .+ \{(\W|\w)*?\n(\t)\}/gm, '');
|
2024-05-21 19:04:52 -05:00
|
|
|
|
2024-05-21 06:07:24 -05:00
|
|
|
let constructorRegex = /(public|protected|private|static|\s) +(\w+) *\(([^)]*)\)/g;
|
|
|
|
|
2024-05-21 19:04:52 -05:00
|
|
|
let constructors = [...javaText.matchAll(constructorRegex).filter((line)=>{
|
2024-05-24 03:39:34 -05:00
|
|
|
return !line[0].includes(" private ") && !line[0].includes(" protected ") && !line[0].includes("\n\t\t") && line[1] !== "private" && line[1] !== "protected";
|
2024-05-21 06:07:24 -05:00
|
|
|
})];
|
|
|
|
|
2024-05-31 08:22:26 -05:00
|
|
|
if (javaText.match(/^(public|private|protected|) abstract class /gm)) {
|
|
|
|
constructors = [];
|
|
|
|
}
|
|
|
|
|
2024-05-21 06:07:24 -05:00
|
|
|
let constructorDetails = constructors.map((constructor) => {
|
|
|
|
let constructorName = constructor[2];
|
|
|
|
let argumentString = constructor[3];
|
|
|
|
let arguments = {};
|
|
|
|
|
|
|
|
if (argumentString.trim().length > 0) {
|
|
|
|
let argumentList = argumentString.split(",");
|
|
|
|
argumentList.forEach((argument) => {
|
|
|
|
let [type, name] = argument.trim().split(" ");
|
|
|
|
arguments[name] = type;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
let argStr = "";
|
|
|
|
var argumentsKeys = Object.keys(arguments);
|
|
|
|
for (let i = 0; i < argumentsKeys.length; i++) {
|
|
|
|
const key = argumentsKeys[i];
|
2024-05-21 19:04:52 -05:00
|
|
|
if (!getStatementsTypes.includes(arguments[key])) {
|
|
|
|
usedClasses.push(arguments[key]);
|
|
|
|
}
|
2024-05-21 06:07:24 -05:00
|
|
|
argStr += `(${arguments[key]}) ${getStatementsTypes.includes(arguments[key]) ? getStatements[arguments[key]].replaceAll("%s", "\""+key+"\"") : `params.getReflective("${key}")`}`;
|
|
|
|
if (i !== argumentsKeys.length - 1) {
|
|
|
|
argStr += ", "
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-05-27 03:02:40 -05:00
|
|
|
let impl = `setCallbackReflectiveWithDataArg("exec", (BaseData params) -> {
|
2024-05-21 19:04:52 -05:00
|
|
|
return new ${className}(${argStr});
|
2024-05-21 06:07:24 -05:00
|
|
|
});
|
|
|
|
`;
|
|
|
|
|
|
|
|
return {
|
|
|
|
name: constructorName,
|
|
|
|
idx: constructors.indexOf(constructor),
|
|
|
|
arguments: arguments,
|
2024-05-24 03:39:34 -05:00
|
|
|
impl: impl,
|
|
|
|
data: constructor
|
2024-05-21 06:07:24 -05:00
|
|
|
};
|
|
|
|
});
|
|
|
|
|
2024-05-31 08:22:26 -05:00
|
|
|
let methodRegex = /(public|static|private|protected|final|\s)* +([\w\<\>\[\]]+)\s+(\w+) *\(([^)]*)\)/g;
|
2024-05-21 19:04:52 -05:00
|
|
|
|
|
|
|
let methods = [...javaText.matchAll(methodRegex).filter((line)=>{
|
2024-05-31 00:38:01 -05:00
|
|
|
return !line[0].includes("> ") && !line[0].startsWith(" else ") && !line[0].startsWith(" new ") && !line[0].includes(" private ") && !line[0].includes("\tprotected ") && !line[0].includes("\tprivate ") && !line[0].includes(" protected ") && !line[0].includes("\n\t\t") && line[0].includes("public ");
|
2024-05-21 19:04:52 -05:00
|
|
|
//Doesn't support Type<Subtype> yet
|
|
|
|
})];
|
|
|
|
|
|
|
|
let methodDetails = methods.map((method) => {
|
|
|
|
let isStatic = `${method[1]}`.includes("static");
|
|
|
|
let returnType = method[2];
|
|
|
|
let methodName = method[3];
|
|
|
|
let argumentString = method[4];
|
|
|
|
let arguments = {};
|
|
|
|
|
2024-05-31 08:22:26 -05:00
|
|
|
let methodContainsInlineClasses = false;
|
2024-05-21 19:04:52 -05:00
|
|
|
if (argumentString.trim().length > 0) {
|
|
|
|
let argumentList = argumentString.split(",");
|
|
|
|
argumentList.forEach((argument) => {
|
2024-05-31 00:38:01 -05:00
|
|
|
let [type, name] = argument.trim().split(" ").filter(potential => {
|
|
|
|
return potential !== "final";
|
|
|
|
});
|
2024-05-31 08:22:26 -05:00
|
|
|
if (type.includes(".")) {
|
|
|
|
methodContainsInlineClasses = true;
|
|
|
|
}
|
2024-05-21 19:04:52 -05:00
|
|
|
arguments[name] = type;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-05-31 08:22:26 -05:00
|
|
|
if (methodContainsInlineClasses) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2024-05-21 19:04:52 -05:00
|
|
|
let argStr = "";
|
|
|
|
var argumentsKeys = Object.keys(arguments);
|
|
|
|
for (let i = 0; i < argumentsKeys.length; i++) {
|
|
|
|
const key = argumentsKeys[i];
|
|
|
|
if (!getStatementsTypes.includes(arguments[key])) {
|
|
|
|
usedClasses.push(arguments[key]);
|
|
|
|
}
|
|
|
|
argStr += `(${arguments[key]}) ${getStatementsTypes.includes(arguments[key]) ? getStatements[arguments[key]].replaceAll("%s", "\""+key+"\"") : `params.getReflective("${key}")`}`;
|
|
|
|
if (i !== argumentsKeys.length - 1) {
|
|
|
|
argStr += ", "
|
|
|
|
}
|
|
|
|
}
|
2024-05-24 02:44:10 -05:00
|
|
|
let prefix = isStatic ? className : `((${className}) params.getReflective("_self"))`;
|
2024-05-21 19:04:52 -05:00
|
|
|
let impl;
|
|
|
|
if (returnType === "void") {
|
2024-05-27 03:02:40 -05:00
|
|
|
impl = `setCallbackVoidWithDataArg("exec", (BaseData params) -> {
|
2024-05-24 03:39:34 -05:00
|
|
|
try {
|
|
|
|
${prefix}.${methodName}(${argStr});
|
|
|
|
} catch (Exception _exception_reflect_) {
|
|
|
|
return;
|
|
|
|
}
|
2024-05-21 19:04:52 -05:00
|
|
|
});
|
|
|
|
`;
|
|
|
|
} else if (callbackStatementsTypes.includes(returnType)) {
|
2024-05-27 03:02:40 -05:00
|
|
|
impl = `${callbackStatements[returnType]}("exec", (BaseData params) -> {
|
2024-05-24 03:39:34 -05:00
|
|
|
try {
|
|
|
|
return (${returnType}) ${prefix}.${methodName}(${argStr});
|
|
|
|
} catch (Exception _exception_reflect_) {
|
|
|
|
return ${primitiveDefaultValues[returnType]};
|
|
|
|
}
|
2024-05-21 19:04:52 -05:00
|
|
|
});
|
|
|
|
`;
|
|
|
|
} else {
|
|
|
|
usedClasses.push(returnType);
|
2024-05-27 03:02:40 -05:00
|
|
|
impl = `setCallbackReflectiveWithDataArg("exec", (BaseData params) -> {
|
2024-05-24 03:39:34 -05:00
|
|
|
try {
|
|
|
|
return (${returnType}) ${prefix}.${methodName}(${argStr});
|
|
|
|
} catch (Exception _exception_reflect_) {
|
|
|
|
return null;
|
|
|
|
}
|
2024-05-21 19:04:52 -05:00
|
|
|
});
|
|
|
|
`;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
name: methodName,
|
|
|
|
returnType: returnType,
|
|
|
|
isStatic: isStatic,
|
|
|
|
arguments: arguments,
|
2024-05-22 04:15:24 -05:00
|
|
|
impl: impl,
|
2024-05-24 03:39:34 -05:00
|
|
|
idx: methods.indexOf(method),
|
|
|
|
data: method
|
2024-05-21 19:04:52 -05:00
|
|
|
};
|
|
|
|
});
|
2024-05-21 06:07:24 -05:00
|
|
|
return {
|
|
|
|
className: className,
|
2024-05-31 08:22:26 -05:00
|
|
|
constructors: constructorDetails.filter(obj => obj),
|
|
|
|
methods: methodDetails.filter(obj => obj),
|
2024-05-21 19:04:52 -05:00
|
|
|
usedClasses: [...new Set(usedClasses)]
|
2024-05-21 06:07:24 -05:00
|
|
|
}
|
|
|
|
}
|