Skip to content

Commit

Permalink
add void support and fix parser
Browse files Browse the repository at this point in the history
  • Loading branch information
xpenatan committed Feb 29, 2024
1 parent c59f1cd commit e0b2c62
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 43 deletions.
3 changes: 3 additions & 0 deletions example/lib/generator/src/main/cpp/exampleLib.idl
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
};
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<Parameter> parameters = nativeMethodDeclaration.getParameters();
int size = parameters.size();
Expand Down Expand Up @@ -201,7 +204,7 @@ private void convertJavaPrimitiveArrayToJavaScriptReferenceArray(NodeList<Parame

@Override
public void onIDLConstructorGenerated(JParser jParser, IDLConstructor idlConstructor, ClassOrInterfaceDeclaration classDeclaration, ConstructorDeclaration constructorDeclaration, MethodDeclaration nativeMethodDeclaration) {
convertLongToInt(constructorDeclaration.getBody(), nativeMethodDeclaration);
// convertLongToInt(constructorDeclaration.getBody(), nativeMethodDeclaration);

String param = "";

Expand Down Expand Up @@ -250,8 +253,7 @@ public void onIDLMethodGenerated(JParser jParser, IDLMethod idlMethod, ClassOrIn
// IDL parser generate our empty methods with default return values.
// We now modify it to match teavm native calls

convertLongToInt(methodDeclaration.getBody().get(), nativeMethod);
String returnType = idlMethod.returnType;
// convertLongToInt(methodDeclaration.getBody().get(), nativeMethod);
String methodName = idlMethod.name;
String param = getParams(idlMethod, methodDeclaration);
String annotationParam = "";
Expand Down Expand Up @@ -357,7 +359,7 @@ private static String getParam(IDLFile idlFile, boolean isObject, String paramNa

@Override
public void onIDLAttributeGenerated(JParser jParser, IDLAttribute idlAttribute, boolean isSet, ClassOrInterfaceDeclaration classDeclaration, MethodDeclaration methodDeclaration, MethodDeclaration nativeMethod) {
convertLongToInt(methodDeclaration.getBody().get(), nativeMethod);
// convertLongToInt(methodDeclaration.getBody().get(), nativeMethod);

String returnTypeName = classDeclaration.getNameAsString();
String attributeName = idlAttribute.name;
Expand Down Expand Up @@ -474,41 +476,6 @@ public void onIDLEnumMethodGenerated(JParser jParser, IDLEnum idlEnum, ClassOrIn
}
}

private static void convertLongToInt(BlockStmt blockStmt, MethodDeclaration nativeMethod) {
//Convert native method params that contains long to int when calling native methods.

convertNativeMethodLongToInt(nativeMethod);
List<MethodCallExpr> all = blockStmt.findAll(MethodCallExpr.class);
convertCallerLongToInt(all);
}

public static void convertCallerLongToInt(List<MethodCallExpr> all) {
for(MethodCallExpr methodCallExpr : all) {
NodeList<Expression> arguments = methodCallExpr.getArguments();
String methodNameStr = methodCallExpr.getNameAsString();
if(methodNameStr.equals("getCPointer") || methodNameStr.contains("getPointer")) {
Optional<Node> 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<JParserItem> parserItems) {
super.onParserComplete(jParser, parserItems);
Expand Down Expand Up @@ -588,8 +555,15 @@ public void onParserComplete(JParser jParser, ArrayList<JParserItem> parserItems
}

//cast cpointer to int

List<ClassOrInterfaceDeclaration> classDeclarations = unit.findAll(ClassOrInterfaceDeclaration.class);

for(int i1 = 0; i1 < classDeclarations.size(); i1++) {
ClassOrInterfaceDeclaration classDeclaration = classDeclarations.get(i1);
convertNativeMethodLongType(classDeclaration);
}

List<MethodCallExpr> all = unit.findAll(MethodCallExpr.class);
convertCallerLongToInt(all);
}
}

Expand 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<ConstructorDeclaration> constructorDeclarations = classDeclaration.findAll(ConstructorDeclaration.class);
for(int i = 0; i < constructorDeclarations.size(); i++) {
ConstructorDeclaration constructorDeclaration = constructorDeclarations.get(i);
List<MethodCallExpr> methodCallerExprList = constructorDeclaration.findAll(MethodCallExpr.class);
updateLongToInt(classDeclaration, methodCallerExprList);
}

List<MethodDeclaration> 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<MethodCallExpr> methodCallerExprList = methodDeclaration.findAll(MethodCallExpr.class);
updateLongToInt(classDeclaration, methodCallerExprList);
}
}
}

private void updateLongToInt(ClassOrInterfaceDeclaration classDeclaration, List<MethodCallExpr> methodCallerExprList) {
for(int i1 = 0; i1 < methodCallerExprList.size(); i1++) {
MethodCallExpr methodCallExpr = methodCallerExprList.get(i1);
NodeList<Expression> arguments = methodCallExpr.getArguments();
MethodDeclaration nativeMethod = getNativeMethod(classDeclaration, methodCallExpr);
if(nativeMethod != null) {
NodeList<Parameter> 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<Node> 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<Expression> arguments = methodCallExpr.getArguments();
List<MethodDeclaration> 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<MethodDeclaration> getNativeMethodsByName(ClassOrInterfaceDeclaration classDeclaration, String name, int paramSize, String... paramTypes) {
List<MethodDeclaration> list = new ArrayList<>();
List<MethodDeclaration> 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<Parameter> 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);
}
}
}
}

0 comments on commit e0b2c62

Please sign in to comment.