From e0b2c62f500fdf14fba0888ff9a3508e5ed065c2 Mon Sep 17 00:00:00 2001 From: Natan Date: Wed, 28 Feb 2024 22:21:49 -0300 Subject: [PATCH] add void support and fix parser --- .../lib/generator/src/main/cpp/exampleLib.idl | 3 + .../cpp/source/exampleLib/src/NormalClass.cpp | 9 + .../cpp/source/exampleLib/src/NormalClass.h | 2 + .../jparser/idl/parser/IDLMethodParser.java | 4 +- .../jparser/teavm/TeaVMCodeParser.java | 181 ++++++++++++++---- 5 files changed, 156 insertions(+), 43 deletions(-) diff --git a/example/lib/generator/src/main/cpp/exampleLib.idl b/example/lib/generator/src/main/cpp/exampleLib.idl index 0c8c48d..c84577e 100644 --- a/example/lib/generator/src/main/cpp/exampleLib.idl +++ b/example/lib/generator/src/main/cpp/exampleLib.idl @@ -56,6 +56,9 @@ interface NormalClass { void setString([Ref] IDLString text); [Ref] IDLString getString(); [Value] IDLString getStringValue(); + + void setVoidParam(any param); + any getVoidParam(); }; NormalClass implements ParentClass; diff --git a/example/lib/generator/src/main/cpp/source/exampleLib/src/NormalClass.cpp b/example/lib/generator/src/main/cpp/source/exampleLib/src/NormalClass.cpp index f3bc8a3..296027b 100644 --- a/example/lib/generator/src/main/cpp/source/exampleLib/src/NormalClass.cpp +++ b/example/lib/generator/src/main/cpp/source/exampleLib/src/NormalClass.cpp @@ -157,3 +157,12 @@ std::string NormalClass::getStringValue() std::string test = "HELLO STRING VALUE"; return test; } + +void NormalClass::setVoidParam(void* param) +{ +} + +void* NormalClass::getVoidParam() +{ + return NULL; +} diff --git a/example/lib/generator/src/main/cpp/source/exampleLib/src/NormalClass.h b/example/lib/generator/src/main/cpp/source/exampleLib/src/NormalClass.h index 37127a2..1184f80 100644 --- a/example/lib/generator/src/main/cpp/source/exampleLib/src/NormalClass.h +++ b/example/lib/generator/src/main/cpp/source/exampleLib/src/NormalClass.h @@ -83,4 +83,6 @@ class NormalClass : public ParentClass void setString(std::string& text); std::string& getString(); std::string getStringValue(); + void setVoidParam(void* param); + void* getVoidParam(); }; diff --git a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java index ef0f4d5..d9d33be 100644 --- a/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java +++ b/jParser/idl/src/main/java/com/github/xpenatan/jparser/idl/parser/IDLMethodParser.java @@ -207,12 +207,12 @@ public static void setupCallerParam(boolean isStatic, boolean isReturnValue, Met if(type.isClassOrInterfaceType()) { if(IDLHelper.getCArray(type.asClassOrInterfaceType().getNameAsString()) != null) { String methodCall = paramName + ".getPointer()"; - paramName = variableName + " != null ? " + methodCall + " : 0"; + paramName = "(" + variableName + " != null ? " + methodCall + " : 0)"; } else if(!IDLHelper.isString(type.asClassOrInterfaceType())) { //All methods must contain a base class to get its pointer String methodCall = paramName + ".getCPointer()"; - paramName = variableName + " != null ? " + methodCall + " : 0"; + paramName = "(" + variableName + " != null ? " + methodCall + " : 0)"; } } else if(type.isArrayType()) { diff --git a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java index b427f56..2ec503d 100644 --- a/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java +++ b/jParser/teavm/src/main/java/com/github/xpenatan/jparser/teavm/TeaVMCodeParser.java @@ -11,7 +11,10 @@ import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.Parameter; +import com.github.javaparser.ast.body.VariableDeclarator; import com.github.javaparser.ast.expr.CastExpr; +import com.github.javaparser.ast.expr.ConditionalExpr; +import com.github.javaparser.ast.expr.EnclosedExpr; import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.expr.MethodCallExpr; import com.github.javaparser.ast.expr.Name; @@ -153,7 +156,7 @@ public TeaVMCodeParser(IDLReader idlReader, String module, String basePackage, S @Override protected void setJavaBodyNativeCMD(String content, MethodDeclaration nativeMethodDeclaration) { - convertNativeMethodLongToInt(nativeMethodDeclaration); +// convertNativeMethodLongToInt(nativeMethodDeclaration); String param = ""; NodeList parameters = nativeMethodDeclaration.getParameters(); int size = parameters.size(); @@ -201,7 +204,7 @@ private void convertJavaPrimitiveArrayToJavaScriptReferenceArray(NodeList all = blockStmt.findAll(MethodCallExpr.class); - convertCallerLongToInt(all); - } - - public static void convertCallerLongToInt(List all) { - for(MethodCallExpr methodCallExpr : all) { - NodeList arguments = methodCallExpr.getArguments(); - String methodNameStr = methodCallExpr.getNameAsString(); - if(methodNameStr.equals("getCPointer") || methodNameStr.contains("getPointer")) { - Optional parentNode = methodCallExpr.getParentNode(); - if(parentNode.isPresent()) { - Node node = parentNode.get(); - Type intType = StaticJavaParser.parseType(int.class.getSimpleName()); - CastExpr intCast = new CastExpr(intType, methodCallExpr); - node.replace(methodCallExpr, intCast); - } - } - } - } - - private static void convertNativeMethodLongToInt(MethodDeclaration nativeMethod) { - if(JParserHelper.isLong(nativeMethod.getType())) { - nativeMethod.setType(int.class); - } - for(Parameter parameter : nativeMethod.getParameters()) { - if(JParserHelper.isLong(parameter.getType())) { - parameter.setType(int.class); - } - } - } - @Override public void onParserComplete(JParser jParser, ArrayList parserItems) { super.onParserComplete(jParser, parserItems); @@ -588,8 +555,15 @@ public void onParserComplete(JParser jParser, ArrayList parserItems } //cast cpointer to int + + List classDeclarations = unit.findAll(ClassOrInterfaceDeclaration.class); + + for(int i1 = 0; i1 < classDeclarations.size(); i1++) { + ClassOrInterfaceDeclaration classDeclaration = classDeclarations.get(i1); + convertNativeMethodLongType(classDeclaration); + } + List all = unit.findAll(MethodCallExpr.class); - convertCallerLongToInt(all); } } @@ -599,4 +573,129 @@ protected boolean parseCodeBlock(Node node, String headerCommands, String conten String newContent = content.replace(TEMPLATE_TAG_MODULE, module); return super.parseCodeBlock(node, headerCommands, newContent); } + + private void convertNativeMethodLongType(ClassOrInterfaceDeclaration classDeclaration) { + String className = classDeclaration.getNameAsString(); + + List constructorDeclarations = classDeclaration.findAll(ConstructorDeclaration.class); + for(int i = 0; i < constructorDeclarations.size(); i++) { + ConstructorDeclaration constructorDeclaration = constructorDeclarations.get(i); + List methodCallerExprList = constructorDeclaration.findAll(MethodCallExpr.class); + updateLongToInt(classDeclaration, methodCallerExprList); + } + + List methodDeclarations = classDeclaration.findAll(MethodDeclaration.class); + for(int i = 0; i < methodDeclarations.size(); i++) { + MethodDeclaration methodDeclaration = methodDeclarations.get(i); + if(!methodDeclaration.isNative()) { + String methodName = methodDeclaration.getNameAsString(); + List methodCallerExprList = methodDeclaration.findAll(MethodCallExpr.class); + updateLongToInt(classDeclaration, methodCallerExprList); + } + } + } + + private void updateLongToInt(ClassOrInterfaceDeclaration classDeclaration, List methodCallerExprList) { + for(int i1 = 0; i1 < methodCallerExprList.size(); i1++) { + MethodCallExpr methodCallExpr = methodCallerExprList.get(i1); + NodeList arguments = methodCallExpr.getArguments(); + MethodDeclaration nativeMethod = getNativeMethod(classDeclaration, methodCallExpr); + if(nativeMethod != null) { + NodeList parameters = nativeMethod.getParameters(); + int paramSize = parameters.size(); + if(paramSize > 0) { + if(arguments.size() != paramSize) { + throw new RuntimeException("Arguments are not the same"); + } + for(int argI = 0; argI < arguments.size(); argI++) { + Expression arg = arguments.get(argI); + Parameter param = parameters.get(argI); + Type type = param.getType(); + if(JParserHelper.isLong(type)) { + Optional parentNode = arg.getParentNode(); + if(parentNode.isPresent()) { + Node node = parentNode.get(); + Type intType = StaticJavaParser.parseType(int.class.getSimpleName()); + CastExpr intCast; + if(arg instanceof ConditionalExpr) { + intCast = new CastExpr(intType, new EnclosedExpr(arg)); + } + else { + intCast = new CastExpr(intType, arg); + } + node.replace(arg, intCast); + } + } + } + } + + Node node = methodCallExpr.getParentNode().get(); + if(node instanceof VariableDeclarator) { + VariableDeclarator parentNode = (VariableDeclarator)node; + if(JParserHelper.isLong(parentNode.getType())) { + parentNode.setType(int.class); + } + } + convertNativeMethodLongToInt(nativeMethod); + } + } + } + + public MethodDeclaration getNativeMethod(ClassOrInterfaceDeclaration classDeclaration, MethodCallExpr methodCallExpr) { + String nativeMethodName = methodCallExpr.getNameAsString(); + NodeList arguments = methodCallExpr.getArguments(); + List methodsByName = getNativeMethodsByName(classDeclaration, nativeMethodName, arguments.size(), null); + int size = methodsByName.size(); + if(size == 0) { + return null; + } + if(methodsByName.size() == 1) { + MethodDeclaration methodDeclaration = methodsByName.get(0); + + if(methodDeclaration.isNative()) { + return methodDeclaration; + } + else { + return null; + } + } + else { + throw new RuntimeException("NEED TO IMPLEMENT"); + } + } + + private List getNativeMethodsByName(ClassOrInterfaceDeclaration classDeclaration, String name, int paramSize, String... paramTypes) { + List list = new ArrayList<>(); + List methodsByName = classDeclaration.getMethodsByName(name); + for(int i = 0; i < methodsByName.size(); i++) { + MethodDeclaration methodDeclaration = methodsByName.get(i); + if(!methodDeclaration.isNative()) { + continue; + } + + boolean add = false; + NodeList parameters = methodDeclaration.getParameters(); + add = parameters.size() == paramSize; + + if(add && paramTypes != null && paramTypes.length > 0 && paramTypes.length == paramSize) { + add = methodDeclaration.hasParametersOfType(paramTypes); + } + + if(add) { + list.add(methodDeclaration); + } + } + return list; + } + + private static void convertNativeMethodLongToInt(MethodDeclaration nativeMethod) { + if(JParserHelper.isLong(nativeMethod.getType())) { + nativeMethod.setType(int.class); + } + for(Parameter parameter : nativeMethod.getParameters()) { + if(JParserHelper.isLong(parameter.getType())) { + parameter.setType(int.class); + } + } + } } \ No newline at end of file