Functional Interfaces und Funn&&-Typen integriert.

modified:   resources/bytecode/javFiles/LambdaRunnable.jav
	modified:   src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java
	modified:   src/test/java/TestComplete.java
This commit is contained in:
pl@gohorb.ba-horb.de 2023-10-27 14:29:27 +02:00
parent 5d0d7a6d94
commit c00722823a
8 changed files with 78 additions and 6 deletions

View File

@ -7,7 +7,7 @@ public class LamRunnable{
public LamRunnable(){
Runnable lam = () -> {System.out.println("lambda");};
Runnable lam = () -> {var a;};
lam.run();
}
}

View File

@ -2,8 +2,11 @@ package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.Pattern;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.syntaxtree.type.*;
@ -32,12 +35,29 @@ public class FCGenerator {
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>();
for(ClassOrInterface cly : availableClasses){
pairs.addAll(getSuperTypes(cly, availableClasses, gtvs, classLoader));
//For all Functional Interfaces FI: FunN$$<... args auf dem Functional Interface ...> <. FI is added to FC
if (isFunctionalInterface(cly)) {
pairs.add(genImplFunType(cly));
}
}
return pairs;
}
private static Boolean isFunctionalInterface(ClassOrInterface cly) {
return (cly.isInterface() && cly.getMethods().size() == 1);
}
private static Pair genImplFunType(ClassOrInterface cly) {
Method m = cly.getMethods().get(0);
List<RefTypeOrTPHOrWildcardOrGeneric> tl =
(m.getParameterList().getFormalparalist().stream().map(p -> p.getType()).collect(Collectors.toList()));
tl.add(m.getReturnType());
return new Pair(new RefType(new JavaClassName("Fun" + (tl.size()-1) + "$$"), tl, new NullToken()),
new RefType(cly.getClassName(), new NullToken()));
// new FunN(lambdaParams),
}

View File

@ -880,15 +880,44 @@ public class RuleSet implements IRuleSet{
@Override
public Optional<Set<UnifyPair>> greaterFunN(UnifyPair pair) {
public Optional<Set<UnifyPair>> greaterFunN(UnifyPair pair, IFiniteClosure fc) {
if(pair.getPairOp() != PairOperator.SMALLERDOT)
return Optional.empty();
UnifyType lhsType = pair.getLhsType();
UnifyType rhsType = pair.getRhsType();
if(!(lhsType instanceof FunNType) || !(rhsType instanceof PlaceholderType))
if(!(lhsType instanceof FunNType))
return Optional.empty();
//FunN$$<...> <. FunctinalInterface wird umgewandelt in FunN$$<...> <. FunN$$<... args aus FuntionalInterface ...>
if (rhsType instanceof ReferenceType) {
UnifyType typeD = pair.getRhsType();
Optional<UnifyType> opt = fc.getRightHandedNoParameterType(typeD.getName());
if(!opt.isPresent())
return Optional.empty();
// Should be eual as typeD
UnifyType typeFunFc = opt.get();
if(!(typeFunFc instanceof FunNType))
return Optional.empty();
UnifyType newRhsType = opt.get();
Set<UnifyPair> result = new HashSet<>();
result.add(new UnifyPair(lhsType, newRhsType, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
return Optional.of(result);
}
else {
if(!(rhsType instanceof PlaceholderType))
return Optional.empty();
}
FunNType funNLhsType = (FunNType) lhsType;

View File

@ -1808,7 +1808,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
// FunN Rules
optSet = optSet.isPresent() ? optSet : rules.reduceFunN(pair);
optSet = optSet.isPresent() ? optSet : rules.greaterFunN(pair);
optSet = optSet.isPresent() ? optSet : rules.greaterFunN(pair, fc);
optSet = optSet.isPresent() ? optSet : rules.smallerFunN(pair);
// One of the rules has been applied

View File

@ -60,6 +60,7 @@ public interface IFiniteClosure {
public Set<UnifyType> smArg(FunNType type, Set<UnifyType> fBounded);
public Optional<UnifyType> getLeftHandedType(String typeName);
public Optional<UnifyType> getRightHandedNoParameterType(String typeName);
public Set<UnifyType> getAncestors(UnifyType t);
public Set<UnifyType> getChildren(UnifyType t);
public Set<UnifyType> getAllTypesByName(String typeName);

View File

@ -60,7 +60,7 @@ public interface IRuleSet {
* FunN Rules
*/
public Optional<Set<UnifyPair>> reduceFunN(UnifyPair pair);
public Optional<Set<UnifyPair>> greaterFunN(UnifyPair pair);
public Optional<Set<UnifyPair>> greaterFunN(UnifyPair pair, IFiniteClosure fc);
public Optional<Set<UnifyPair>> smallerFunN(UnifyPair pair);
/**
@ -100,4 +100,5 @@ public interface IRuleSet {
* @return An optional of the modified set, if there were any substitutions. An empty optional if there were no substitutions.
*/
public Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs);
}

View File

@ -608,6 +608,18 @@ implements IFiniteClosure {
return Optional.empty();
}
@Override
public Optional<UnifyType> getRightHandedNoParameterType(String typeName) {
if(!strInheritanceGraph.containsKey(typeName))
return Optional.empty();
for(UnifyPair pair : pairs)
if(pair.getRhsType().getName().equals(typeName) && pair.getRhsType().typeParams.size() == 0)
return Optional.of(pair.getLhsType());
return Optional.empty();
}
@Override
public Set<UnifyType> getAncestors(UnifyType t) {
if(!inheritanceGraph.containsKey(t))

View File

@ -736,4 +736,13 @@ public class TestComplete {
var m = clazz.getDeclaredMethod("m", Integer.class);
assertEquals(m.invoke(instance, 10), 60);
}
@Test
public void testLambdaRunnable() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "LambdaRunnable.jav");
var clazz = classFiles.get("LambdaRunnable");
var instance = clazz.getDeclaredConstructor().newInstance();
//var m = clazz.getDeclaredMethod("m", Integer.class);
//assertEquals(m.invoke(instance, 10), 60);
}
}