Fix up method resolution

This commit is contained in:
Daniel Holle 2023-11-02 15:25:25 +01:00
parent 4654ecacaf
commit f95c3c5fcf
7 changed files with 73 additions and 27 deletions

View File

@ -354,19 +354,19 @@ public class ASTFactory {
if (type == null || type.getTypeName().equals("void")) {
return new Void(new NullToken());
} else if (type.getTypeName().equals("int")) {
return new RefType(new JavaClassName("java.lang.Integer"), new ArrayList<>(), new NullToken());
return new RefType(new JavaClassName("java.lang.Integer"), new ArrayList<>(), new NullToken(), true);
} else if (type.getTypeName().equals("byte")) {
return new RefType(new JavaClassName("java.lang.Byte"), new ArrayList<>(), new NullToken());
return new RefType(new JavaClassName("java.lang.Byte"), new ArrayList<>(), new NullToken(), true);
} else if (type.getTypeName().equals("boolean")) {
return new RefType(new JavaClassName("java.lang.Boolean"), new ArrayList<>(), new NullToken());
return new RefType(new JavaClassName("java.lang.Boolean"), new ArrayList<>(), new NullToken(), true);
} else if (type.getTypeName().equals("char")) {
return new RefType(new JavaClassName("java.lang.Char"), new ArrayList<>(), new NullToken());
return new RefType(new JavaClassName("java.lang.Char"), new ArrayList<>(), new NullToken(), true);
} else if (type.getTypeName().equals("short")) {
return new RefType(new JavaClassName("java.lang.Short"), new ArrayList<>(), new NullToken());
return new RefType(new JavaClassName("java.lang.Short"), new ArrayList<>(), new NullToken(), true);
} else if (type.getTypeName().equals("double")) {
return new RefType(new JavaClassName("java.lang.Double"), new ArrayList<>(), new NullToken());
return new RefType(new JavaClassName("java.lang.Double"), new ArrayList<>(), new NullToken(), true);
} else if (type.getTypeName().equals("long")) {
return new RefType(new JavaClassName("java.lang.Long"), new ArrayList<>(), new NullToken());
return new RefType(new JavaClassName("java.lang.Long"), new ArrayList<>(), new NullToken(), true);
} else {
if (type instanceof TypeVariable) {
// GTVDeclarationContext via "(TypeVariable) type).getGenericDeclaration()"

View File

@ -38,7 +38,11 @@ public class MethodCall extends Statement
this.receiverType = receiverType;
this.signature = signature;
}
public List<RefTypeOrTPHOrWildcardOrGeneric> signatureArguments() {
return signature.subList(0, signature.size() - 1);
}
@Override
public void accept(StatementVisitor visitor) {

View File

@ -20,13 +20,17 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
*
* Bsp: java.lang.Integer mit Flag wird dann zu [int]
*/
private boolean primitiveFlag=false;
boolean primitiveFlag = false; // TODO Should be final
public RefType(JavaClassName fullyQualifiedName, Token offset)
{
this(fullyQualifiedName, new ArrayList<>(), offset);
}
public boolean isPrimitive() {
return primitiveFlag;
}
@Override
public String toString(){
String params = "";
@ -51,11 +55,15 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
return hash;
}
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset)
{
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset) {
this(fullyQualifiedName, parameter, offset, false);
}
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset, boolean primitiveFlag) {
super(offset);
this.name = (fullyQualifiedName);
this.parameter = parameter;
this.primitiveFlag = primitiveFlag;
}
public JavaClassName getName()

View File

@ -16,6 +16,7 @@ import de.dhbwstuttgart.target.tree.expression.*;
import de.dhbwstuttgart.target.tree.type.*;
import de.dhbwstuttgart.typeinference.result.*;
import javax.sql.rowset.RowSetWarning;
import java.lang.annotation.Target;
import java.util.*;
import java.util.stream.Collectors;
@ -76,21 +77,27 @@ public class ASTToTargetAST {
this.generics = all.get(0);
}
Optional<Method> findMethod(ClassOrInterface owner, String name, ArgumentList argumentList) {
return owner.getMethods().stream().filter(m -> m.name.equals(name) && parameterEquals(m.getParameterList(), argumentList)).findFirst();
Optional<Method> findMethod(ClassOrInterface owner, String name, List<TargetType> argumentList) {
Optional<Method> method = Optional.empty();
while (method.isEmpty() && !owner.getClassName().toString().equals("java.lang.Object")) {
method = owner.getMethods().stream().filter(m -> m.name.equals(name) && parameterEquals(m.getParameterList(), argumentList)).findFirst();
owner = compiler.getClass(owner.getSuperClass().getName());
}
return method;
}
boolean parameterEquals(ParameterList parameterList, ArgumentList argumentList) {
boolean parameterEquals(ParameterList parameterList, List<TargetType> arguments) {
var pars = parameterList.getFormalparalist();
var arguments = argumentList.getArguments();
if (pars.size() != arguments.size())
return false;
for (var i = 0; i < pars.size(); i++) {
var type1 = convert(pars.get(i).getType(), generics.javaGenerics);
var type2 = convert(arguments.get(i).getType(), generics.javaGenerics);
var type2 = arguments.get(i);
if (type1 instanceof TargetGenericType)
return true;
if (TargetType.toPrimitive(type2).equals(type1))
return true;
if (!type1.equals(type2))
return false;
}
@ -427,6 +434,9 @@ public class ASTToTargetAST {
var name = refType.getName().toString();
if (name.equals("void"))
return null;
if (refType.isPrimitive()) {
return TargetType.toPrimitive(refType);
}
var params = refType.getParaList().stream().map(type -> {
var res = convert(type, generics);

View File

@ -297,7 +297,7 @@ public abstract class GenerateGenerics {
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver) {
if (expressionReceiver.expr instanceof This) {
var optMethod = astToTargetAST.findMethod(owner, methodCall.name, methodCall.getArgumentList());
var optMethod = astToTargetAST.findMethod(owner, methodCall.name, methodCall.signatureArguments().stream().map(astToTargetAST::convert).toList());
if (optMethod.isEmpty()) return;
var method2 = optMethod.get();
System.out.println("In: " + method.getName() + " Method: " + method2.getName());

View File

@ -171,7 +171,7 @@ public class StatementToTargetExpression implements ASTVisitor {
return to.equals(from);
}
Optional<Method> findMethod(JavaClassName className, String name, ArgumentList args) {
Optional<Method> findMethod(JavaClassName className, String name, List<TargetType> args) {
return converter.findMethod(converter.compiler.getClass(className), name, args);
}
@ -185,20 +185,28 @@ public class StatementToTargetExpression implements ASTVisitor {
var argList = methodCall.signature.stream().map(converter::convert).toList();
argList = argList.subList(0, argList.size() - 1);
Method foundMethod;
Method foundMethod = null;
var isStatic = false;
var isInterface = true;
var signature = methodCall.signatureArguments().stream().map(converter::convert).toList();
var receiverClass = converter.currentClass;
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver && expressionReceiver.expr instanceof This) {
var thisMethod = converter.findMethod(converter.currentClass, methodCall.name, methodCall.arglist);
foundMethod = thisMethod.orElseGet(() -> findMethod(converter.currentClass.getSuperClass().getName(), methodCall.name, methodCall.arglist).orElseThrow());
} else {
receiverClass = converter.compiler.getClass(receiverName);
foundMethod = findMethod(receiverName, methodCall.name, methodCall.arglist).orElseThrow();
var thisMethod = converter.findMethod(converter.currentClass, methodCall.name, signature);
foundMethod = thisMethod.orElseGet(() -> findMethod(converter.currentClass.getSuperClass().getName(), methodCall.name, signature).orElseThrow());
} else if (!isFunNType) {
System.out.println(methodCall.signature);
foundMethod = findMethod(receiverName, methodCall.name, signature).orElseThrow();
}
returnType = converter.convert(foundMethod.getReturnType());
argList = foundMethod.getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType())).toList();
if (!isFunNType) {
returnType = converter.convert(foundMethod.getReturnType());
argList = foundMethod.getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType())).toList();
isStatic = Modifier.isStatic(foundMethod.modifier);
isInterface = receiverClass.isInterface();
}
result = new TargetMethodCall(converter.convert(methodCall.getType()), returnType, argList, converter.convert(methodCall.receiver), methodCall.getArgumentList().getArguments().stream().map(converter::convert).toList(), receiverType, methodCall.name, Modifier.isStatic(foundMethod.modifier), receiverClass.isInterface());
result = new TargetMethodCall(converter.convert(methodCall.getType()), returnType, argList, converter.convert(methodCall.receiver), methodCall.getArgumentList().getArguments().stream().map(converter::convert).toList(), receiverType, methodCall.name, isStatic, isInterface);
}
@Override

View File

@ -1,5 +1,7 @@
package de.dhbwstuttgart.target.tree.type;
import de.dhbwstuttgart.syntaxtree.type.RefType;
public sealed interface TargetType
permits TargetExtendsWildcard, TargetGenericType, TargetSpecializedType, TargetSuperWildcard, TargetPrimitiveType {
@ -37,6 +39,20 @@ public sealed interface TargetType
return type;
}
static TargetType toPrimitive(RefType type) {
return switch(type.getName().toString()) {
case "java.lang.Boolean" -> boolean_;
case "java.lang.Character" -> char_;
case "java.lang.Byte" -> byte_;
case "java.lang.Short" -> short_;
case "java.lang.Integer" -> int_;
case "java.lang.Long" -> long_;
case "java.lang.Float" -> float_;
case "java.lang.Double" -> double_;
default -> null;
};
}
static TargetType toTargetType(Class<?> clazz) {
if (clazz.isPrimitive()) {
if (clazz.equals(boolean.class)) return boolean_;