Fix #298
Some checks failed
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 2m33s

This commit is contained in:
Daniel Holle 2024-03-25 12:14:03 +01:00
parent c2ee12397f
commit e07521d9b6
3 changed files with 44 additions and 29 deletions

View File

@ -7,13 +7,8 @@ import java.util.stream.Stream;
import java.util.function.Function;
public class Bug298 {
public <R, T> Stream<R> takes(Stream<T> s, Function<? super T, ? extends R> fun) {
return null;
}
public void m() {
List<Integer> list = new ArrayList<>();
Stream<Integer> a = list.stream();
takes(a, x -> 2 * x);
list.stream().map(x -> 2 * x);
}
}

View File

@ -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<a1, a2, a3, ... >)
UnifyType typeDgen = opt.get();
// Actually greater+ because the types are ensured to have different names
Set<UnifyType> 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<UnifyPair> 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);
}

View File

@ -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<UnifyType> 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<UnifyType>();
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;
}