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")) { if (type == null || type.getTypeName().equals("void")) {
return new Void(new NullToken()); return new Void(new NullToken());
} else if (type.getTypeName().equals("int")) { } 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")) { } 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")) { } 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")) { } 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")) { } 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")) { } 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")) { } 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 { } else {
if (type instanceof TypeVariable) { if (type instanceof TypeVariable) {
// GTVDeclarationContext via "(TypeVariable) type).getGenericDeclaration()" // GTVDeclarationContext via "(TypeVariable) type).getGenericDeclaration()"

View File

@ -39,6 +39,10 @@ public class MethodCall extends Statement
this.signature = signature; this.signature = signature;
} }
public List<RefTypeOrTPHOrWildcardOrGeneric> signatureArguments() {
return signature.subList(0, signature.size() - 1);
}
@Override @Override
public void accept(StatementVisitor visitor) { 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] * 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) public RefType(JavaClassName fullyQualifiedName, Token offset)
{ {
this(fullyQualifiedName, new ArrayList<>(), offset); this(fullyQualifiedName, new ArrayList<>(), offset);
} }
public boolean isPrimitive() {
return primitiveFlag;
}
@Override @Override
public String toString(){ public String toString(){
String params = ""; String params = "";
@ -51,11 +55,15 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
return hash; 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); super(offset);
this.name = (fullyQualifiedName); this.name = (fullyQualifiedName);
this.parameter = parameter; this.parameter = parameter;
this.primitiveFlag = primitiveFlag;
} }
public JavaClassName getName() public JavaClassName getName()

View File

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

View File

@ -297,7 +297,7 @@ public abstract class GenerateGenerics {
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver) { if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver) {
if (expressionReceiver.expr instanceof This) { 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; if (optMethod.isEmpty()) return;
var method2 = optMethod.get(); var method2 = optMethod.get();
System.out.println("In: " + method.getName() + " Method: " + method2.getName()); System.out.println("In: " + method.getName() + " Method: " + method2.getName());

View File

@ -171,7 +171,7 @@ public class StatementToTargetExpression implements ASTVisitor {
return to.equals(from); 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); 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(); var argList = methodCall.signature.stream().map(converter::convert).toList();
argList = argList.subList(0, argList.size() - 1); 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; var receiverClass = converter.currentClass;
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver && expressionReceiver.expr instanceof This) { if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver && expressionReceiver.expr instanceof This) {
var thisMethod = converter.findMethod(converter.currentClass, methodCall.name, methodCall.arglist); var thisMethod = converter.findMethod(converter.currentClass, methodCall.name, signature);
foundMethod = thisMethod.orElseGet(() -> findMethod(converter.currentClass.getSuperClass().getName(), methodCall.name, methodCall.arglist).orElseThrow()); foundMethod = thisMethod.orElseGet(() -> findMethod(converter.currentClass.getSuperClass().getName(), methodCall.name, signature).orElseThrow());
} else { } else if (!isFunNType) {
receiverClass = converter.compiler.getClass(receiverName); System.out.println(methodCall.signature);
foundMethod = findMethod(receiverName, methodCall.name, methodCall.arglist).orElseThrow(); foundMethod = findMethod(receiverName, methodCall.name, signature).orElseThrow();
} }
if (!isFunNType) {
returnType = converter.convert(foundMethod.getReturnType()); returnType = converter.convert(foundMethod.getReturnType());
argList = foundMethod.getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType())).toList(); 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 @Override

View File

@ -1,5 +1,7 @@
package de.dhbwstuttgart.target.tree.type; package de.dhbwstuttgart.target.tree.type;
import de.dhbwstuttgart.syntaxtree.type.RefType;
public sealed interface TargetType public sealed interface TargetType
permits TargetExtendsWildcard, TargetGenericType, TargetSpecializedType, TargetSuperWildcard, TargetPrimitiveType { permits TargetExtendsWildcard, TargetGenericType, TargetSpecializedType, TargetSuperWildcard, TargetPrimitiveType {
@ -37,6 +39,20 @@ public sealed interface TargetType
return type; 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) { static TargetType toTargetType(Class<?> clazz) {
if (clazz.isPrimitive()) { if (clazz.isPrimitive()) {
if (clazz.equals(boolean.class)) return boolean_; if (clazz.equals(boolean.class)) return boolean_;