Fixed complex return types of methods

This commit is contained in:
Jochen Seyfried 2024-07-01 13:23:22 +02:00
parent aa7d82b9ac
commit c24a483880

View File

@ -49,13 +49,14 @@ public class MethodDecl implements Node {
if(!Objects.equals(this.returnType, codeBlockType))
throw new TypeCheckException("Method returns " + codeBlockType + ", but should return " + this.returnType + ". ");
result.type = codeBlock.returnType;
return result;
}
//Need to get the returnType of the method if it is an object
// methodContext (class, (identifier, (returnType, parameter)))
// typeContext (class, (type, identifier))
// typeContext (class, (identifier, type))
public void codeGen(ClassWriter cw, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, List<FieldDecl> fieldDecls) throws Exception {
localVars.put("this", classThatContainsMethod);
@ -65,7 +66,7 @@ public class MethodDecl implements Node {
// check if the method is a constructor
if (classThatContainsMethod.equals(name) && returnType == null) {
String descriptor = getMethodDescriptor(methodContext);
String descriptor = getMethodDescriptor(methodContext, typeContext);
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", descriptor, null, null);
@ -127,7 +128,7 @@ public class MethodDecl implements Node {
mv.visitEnd();
} else {
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, name, getMethodDescriptor(methodContext), null, null);
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, name, getMethodDescriptor(methodContext, typeContext), null, null);
mv.visitCode();
codeBlock.codeGen(mv, localVars, typeContext, methodContext);
@ -142,7 +143,7 @@ public class MethodDecl implements Node {
}
}
private String getMethodDescriptor(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) {
private String getMethodDescriptor(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) {
// get the method descriptor
StringBuilder descriptor = new StringBuilder("(");
@ -155,8 +156,18 @@ public class MethodDecl implements Node {
case "void" -> descriptor.append("V");
default -> {
// object
//TODO: This is not finished for objects --> classes and methods
if (returnType != null) descriptor.append("L").append(returnType).append(";");
if (param.type != null) {
String paramType = param.type;
// If it is a class reference replace the "." with "/" and return it
HashMap<String, String> classTypes = typeContext.get(classThatContainsMethod);
if (classTypes != null) {
if (classTypes.containsKey(paramType)) {
paramType = classTypes.get(paramType);
paramType.replaceAll("\\.", "/");
}
}
descriptor.append("L").append(paramType).append(";");
}
}
}
}