fixed MethodCallStatementExpression maybe

This commit is contained in:
Jochen Seyfried 2024-07-02 15:21:32 +02:00
parent 10f5dc692d
commit d5b526b8fc

View File

@ -56,6 +56,7 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
receiver.instVarExpression.thisClass = typeOfSubreceiver; receiver.instVarExpression.thisClass = typeOfSubreceiver;
receiver.instVarExpression.typeCheck(methodContext, typeContext, localVars); receiver.instVarExpression.typeCheck(methodContext, typeContext, localVars);
currentType = typeContext.get(typeOfSubreceiver).get(mostLeftField); currentType = typeContext.get(typeOfSubreceiver).get(mostLeftField);
//currentType = typeContext.get(receiver.instVarExpression.getTypeCheckResult().type).get(mostLeftField);
} else { } else {
currentType = classToSearchMethodIn; currentType = classToSearchMethodIn;
} }
@ -70,6 +71,9 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
if (currentType == null) if (currentType == null)
throw new TypeCheckException("The method " + methodName + " was not found in " + classToSearchMethodIn + "."); throw new TypeCheckException("The method " + methodName + " was not found in " + classToSearchMethodIn + ".");
receivingMethods.get(i).thisClass = this.thisClass; receivingMethods.get(i).thisClass = this.thisClass;
// currentType = return type
// ThisClass = class von methode
receivingMethods.get(i).checkParameters(methodContext, typeContext, localVars); receivingMethods.get(i).checkParameters(methodContext, typeContext, localVars);
} }
currentType = (String) methodContext.get(currentType).get(methodName).keySet().toArray()[0]; currentType = (String) methodContext.get(currentType).get(methodName).keySet().toArray()[0];
@ -108,7 +112,7 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
mv.visitFieldInsn(Opcodes.GETFIELD, thisClass, receiver.identifier, "L" + type + ";"); // Load the field onto the stack mv.visitFieldInsn(Opcodes.GETFIELD, thisClass, receiver.identifier, "L" + type + ";"); // Load the field onto the stack
} else { } else {
// It's a local variable // It's a local variable
int index = localVars.keySet().stream().toList().indexOf(receiver.identifier)+1; // +1 because the first local variable is at index 1, 0 is used for "this" int index = localVars.keySet().stream().toList().indexOf(receiver.identifier) + 1; // +1 because the first local variable is at index 1, 0 is used for "this"
int opcode = type.equals("int") ? Opcodes.ILOAD : Opcodes.ALOAD; int opcode = type.equals("int") ? Opcodes.ILOAD : Opcodes.ALOAD;
mv.visitVarInsn(opcode, index); // Load local variable onto the stack mv.visitVarInsn(opcode, index); // Load local variable onto the stack
} }
@ -119,16 +123,15 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
} else { } else {
throw new ExecutionControl.NotImplementedException("Receiver is null."); throw new ExecutionControl.NotImplementedException("Receiver is null.");
} }
String returnOfPreviousMethod = null;
// Generate the code for each argument expression
for (IExpression argument : arguments) {
argument.codeGen(mv, localVars, typeContext, methodContext);
}
// Invoke the method for each receiving method in the chain // Invoke the method for each receiving method in the chain
for (ReceivingMethod receivingMethod : receivingMethods) { for (ReceivingMethod receivingMethod : receivingMethods) {
// Get the owner class for the current method in the chain // Get the owner class for the current method in the chain
owner = receivingMethod.thisClass; if (returnOfPreviousMethod == null)
owner = thisClass;
else
// If the return of the previous method is not null, use it as the owner class for the current method in the chain
owner = returnOfPreviousMethod;
// Generate the code for each argument expression for the current method // Generate the code for each argument expression for the current method
for (IExpression argument : receivingMethod.arguments) { for (IExpression argument : receivingMethod.arguments) {
@ -136,13 +139,25 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
} }
// Invoke the current method // Invoke the current method
String descriptor = getMethodDescriptor(receivingMethod.methodName, localVars, methodContext, receivingMethod.arguments); String descriptor = getMethodDescriptor(receivingMethod.methodName, localVars, methodContext, receivingMethod.arguments, returnOfPreviousMethod);
returnOfPreviousMethod = methodContext.get(owner).get(receivingMethod.methodName).keySet().toArray()[0].toString();
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, receivingMethod.methodName, descriptor, false); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, receivingMethod.methodName, descriptor, false);
} }
// Invoke the final method
// Generate the code for each argument expression
for (IExpression argument : arguments) {
argument.codeGen(mv, localVars, typeContext, methodContext);
}
String descriptor = getMethodDescriptor(methodName, localVars, methodContext, arguments, returnOfPreviousMethod);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, methodName, descriptor, false);
} }
// ()I // ()I
private String getMethodDescriptor(String methodName, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, List<IExpression> arguments) { private String getMethodDescriptor(String methodName, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, List<IExpression> arguments, String returnOfPreviousMethod) {
StringBuilder descriptor = new StringBuilder("("); StringBuilder descriptor = new StringBuilder("(");
for (IExpression argument : arguments) { for (IExpression argument : arguments) {
@ -173,8 +188,13 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
//Return Type //Return Type
String classToSearchMethodIn = localVars.get(receiver.identifier); String classToSearchMethodIn = localVars.get(receiver.identifier);
if (classToSearchMethodIn == null) if (classToSearchMethodIn == null) {
classToSearchMethodIn = returnOfPreviousMethod;
}
if (classToSearchMethodIn == null) {
classToSearchMethodIn = thisClass; classToSearchMethodIn = thisClass;
}
String returnType = methodContext.get(classToSearchMethodIn).get(methodName).keySet().toArray()[0].toString(); String returnType = methodContext.get(classToSearchMethodIn).get(methodName).keySet().toArray()[0].toString();
@ -214,5 +234,5 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
@Override @Override
public TypeCheckResult getTypeCheckResult() { public TypeCheckResult getTypeCheckResult() {
return super.getTypeCheckResult(); return super.getTypeCheckResult();
}
} }
}