From e07521d9b6b489afda9a7ca4cdc4b60aec412bfb Mon Sep 17 00:00:00 2001 From: Daniel Holle Date: Mon, 25 Mar 2024 12:14:03 +0100 Subject: [PATCH] Fix #298 --- resources/bytecode/javFiles/Bug298.jav | 7 +-- .../typeinference/unify/RuleSet.java | 51 ++++++++++--------- .../unify/model/FiniteClosure.java | 15 ++++++ 3 files changed, 44 insertions(+), 29 deletions(-) diff --git a/resources/bytecode/javFiles/Bug298.jav b/resources/bytecode/javFiles/Bug298.jav index fd1c7164..296ee028 100644 --- a/resources/bytecode/javFiles/Bug298.jav +++ b/resources/bytecode/javFiles/Bug298.jav @@ -7,13 +7,8 @@ import java.util.stream.Stream; import java.util.function.Function; public class Bug298 { - public Stream takes(Stream s, Function fun) { - return null; - } - public void m() { List list = new ArrayList<>(); - Stream a = list.stream(); - takes(a, x -> 2 * x); + list.stream().map(x -> 2 * x); } } diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java index bed26163..262f764e 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java @@ -15,6 +15,7 @@ import java.util.stream.Collectors; import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; +import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; import de.dhbwstuttgart.typeinference.unify.model.ExtendsType; @@ -899,31 +900,35 @@ public class RuleSet implements IRuleSet{ if(!opt.isPresent()) return Optional.empty(); - // The generic Version of typeFI (FI) - UnifyType typeDgen = opt.get(); - - // Actually greater+ because the types are ensured to have different names - Set smaller = fc.getChildren(typeDgen); - opt = smaller.stream().filter(x -> x.getName().equals(pair.getLhsType().getName())).findAny(); - - if(!opt.isPresent()) + if (!(typeFI instanceof ReferenceType refType) || !fc.isFunctionalInterface(refType)) return Optional.empty(); - - TypeParams typeDParams = typeFI.getTypeParams(); - TypeParams typeDgenParams = typeDgen.getTypeParams(); - - Unifier unif = Unifier.identity(); - for(int i = 0; i < typeDParams.size(); i++) { - if (typeDgenParams.get(i) instanceof PlaceholderType) - unif.add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i)); - else System.out.println("ERROR"); - } - - UnifyType newRhsType = opt.get(); - + + var fiArgs = fc.getFunctionalInterfaceTypeArguments(refType); + var retType = fiArgs.getFirst(); + var lhsRet = lhsType.getTypeParams().get(0); + Set result = new HashSet<>(); - result.add(new UnifyPair(lhsType, unif.apply(newRhsType), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair())); - + if (retType instanceof ExtendsType) { + result.add(new UnifyPair(lhsRet, retType, PairOperator.SMALLERDOTWC)); + } else if (retType instanceof SuperType) { + return Optional.empty(); + } else { + result.add(new UnifyPair(lhsRet, retType, PairOperator.EQUALSDOT)); + } + + for (var i = 1; i < fiArgs.size(); i++) { + var lh = lhsType.getTypeParams().get(i); + var rh = fiArgs.get(i); + + if (rh instanceof SuperType) { + result.add(new UnifyPair(lh, rh, PairOperator.SMALLERDOTWC)); + } else if (rh instanceof ExtendsType) { + return Optional.empty(); + } else { + result.add(new UnifyPair(lh, rh, PairOperator.EQUALSDOT)); + } + } + return Optional.of(result); } diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index 1c1d065b..c29e0468 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -25,6 +25,8 @@ import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.parser.SourceLoc; import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typeinference.unify.MartelliMontanariUnify; import de.dhbwstuttgart.typeinference.unify.Match; @@ -613,9 +615,22 @@ implements IFiniteClosure { public List getFunctionalInterfaceTypeArguments(ReferenceType t) { var clazz = compiler.getClass(new JavaClassName(t.getName())); var intfMethod = clazz.getMethods().stream().filter(m -> Modifier.isAbstract(m.modifier)).findFirst().orElseThrow(); + var args = new ArrayList(); args.add(UnifyTypeFactory.convert(intfMethod.getReturnType(), false)); intfMethod.getParameterList().getFormalparalist().forEach(param -> args.add(UnifyTypeFactory.convert(param.getType(), false))); + + // TODO There might be a better way of dealing with this + var i = 0; + for (var generic : clazz.getGenerics()) { + for (var j = 0; j < args.size(); j++) { + if (args.get(j).getName().equals(generic.getName())) + args.set(j, t.getTypeParams().get(i)); + } + i += 1; + } + + System.out.println(args); return args; }