forked from JavaTX/JavaCompilerCore
Get rid of inner type variables for methods
This commit is contained in:
parent
8be7f3d790
commit
9d20c0564c
@ -15,7 +15,6 @@ import de.dhbwstuttgart.target.tree.expression.TargetBlock;
|
|||||||
import de.dhbwstuttgart.target.tree.expression.TargetExpression;
|
import de.dhbwstuttgart.target.tree.expression.TargetExpression;
|
||||||
import de.dhbwstuttgart.target.tree.type.*;
|
import de.dhbwstuttgart.target.tree.type.*;
|
||||||
import de.dhbwstuttgart.typeinference.result.*;
|
import de.dhbwstuttgart.typeinference.result.*;
|
||||||
import de.dhbwstuttgart.util.BiRelation;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -61,18 +60,20 @@ public class ASTToTargetAST {
|
|||||||
System.out.println("Simplified constraints: " + simplifiedConstraints);
|
System.out.println("Simplified constraints: " + simplifiedConstraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
void findTypeVariables(RefTypeOrTPHOrWildcardOrGeneric type, Set<TypePlaceholder> typeVariables) {
|
Set<TypePlaceholder> findTypeVariables(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||||
|
var result = new HashSet<TypePlaceholder>();
|
||||||
if (type instanceof TypePlaceholder tph) {
|
if (type instanceof TypePlaceholder tph) {
|
||||||
tph = equality.getOrDefault(tph, tph);
|
tph = equality.getOrDefault(tph, tph);
|
||||||
if (concreteTypes.containsKey(tph)) {
|
if (concreteTypes.containsKey(tph)) {
|
||||||
findTypeVariables(concreteTypes.get(tph), typeVariables);
|
result.addAll(findTypeVariables(concreteTypes.get(tph)));
|
||||||
return;
|
return result;
|
||||||
}
|
}
|
||||||
typeVariables.add(tph);
|
result.add(tph);
|
||||||
} else if (type instanceof RefType refType) {
|
} else if (type instanceof RefType refType) {
|
||||||
for (var t : refType.getParaList())
|
for (var t : refType.getParaList())
|
||||||
findTypeVariables(t, typeVariables);
|
result.addAll(findTypeVariables(t));
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean hasBound(TypePlaceholder name, Set<ResultPair<?, ?>> generics) {
|
boolean hasBound(TypePlaceholder name, Set<ResultPair<?, ?>> generics) {
|
||||||
@ -125,27 +126,29 @@ public class ASTToTargetAST {
|
|||||||
|
|
||||||
HashSet<TypePlaceholder> typeVariables = new HashSet<>();
|
HashSet<TypePlaceholder> typeVariables = new HashSet<>();
|
||||||
HashSet<TypePlaceholder> typeVariablesOfFields = new HashSet<>();
|
HashSet<TypePlaceholder> typeVariablesOfFields = new HashSet<>();
|
||||||
HashSet<TypePlaceholder> allTypeVariables = new HashSet<>();
|
HashSet<TypePlaceholder> typeVariablesOfLocals = new HashSet<>();
|
||||||
|
|
||||||
for (var field : owner.getFieldDecl()) {
|
for (var field : owner.getFieldDecl()) {
|
||||||
findTypeVariables(field.getType(), typeVariablesOfFields);
|
typeVariablesOfFields.addAll(findTypeVariables(field.getType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
//findTypeVariables(method.getReturnType(), typeVariables);
|
//findTypeVariables(method.getReturnType(), typeVariables);
|
||||||
for (var arg : method.getParameterList().getFormalparalist()) {
|
for (var arg : method.getParameterList().getFormalparalist()) {
|
||||||
findTypeVariables(arg.getType(), typeVariables);
|
typeVariables.addAll(findTypeVariables(arg.getType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
method.block.accept(new TracingStatementVisitor() {
|
method.block.accept(new TracingStatementVisitor() {
|
||||||
@Override
|
@Override
|
||||||
public void visit(LocalVarDecl localVarDecl) {
|
public void visit(LocalVarDecl localVarDecl) {
|
||||||
findTypeVariables(localVarDecl.getType(), typeVariables);
|
var tphs = findTypeVariables(localVarDecl.getType());
|
||||||
|
typeVariablesOfLocals.addAll(tphs);
|
||||||
|
typeVariables.addAll(tphs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(MethodCall methodCall) {
|
public void visit(MethodCall methodCall) {
|
||||||
super.visit(methodCall);
|
super.visit(methodCall);
|
||||||
findTypeVariables(methodCall.getType(), typeVariables);
|
typeVariables.addAll(findTypeVariables(methodCall.getType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -164,7 +167,6 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var visitedMethods = new HashSet<Method>();
|
|
||||||
method.block.accept(new TracingStatementVisitor() {
|
method.block.accept(new TracingStatementVisitor() {
|
||||||
|
|
||||||
private RefTypeOrTPHOrWildcardOrGeneric superType = new Void(new NullToken());
|
private RefTypeOrTPHOrWildcardOrGeneric superType = new Void(new NullToken());
|
||||||
@ -181,8 +183,11 @@ public class ASTToTargetAST {
|
|||||||
.map(x -> x.getType())
|
.map(x -> x.getType())
|
||||||
.collect(Collectors.toCollection(HashSet::new))
|
.collect(Collectors.toCollection(HashSet::new))
|
||||||
.stream().filter(x -> x instanceof TypePlaceholder)
|
.stream().filter(x -> x instanceof TypePlaceholder)
|
||||||
|
.map(tph -> equality.getOrDefault(tph, (TypePlaceholder) tph))
|
||||||
.collect(Collectors.toCollection(HashSet::new));
|
.collect(Collectors.toCollection(HashSet::new));
|
||||||
RefTypeOrTPHOrWildcardOrGeneric T2 = superType;
|
RefTypeOrTPHOrWildcardOrGeneric T2 = superType;
|
||||||
|
if (T2 instanceof TypePlaceholder tph) T2 = equality.getOrDefault(tph, tph);
|
||||||
|
|
||||||
System.out.println("T1s: " + T1s + "\nT2: " + T2);
|
System.out.println("T1s: " + T1s + "\nT2: " + T2);
|
||||||
//Ende
|
//Ende
|
||||||
|
|
||||||
@ -198,8 +203,6 @@ public class ASTToTargetAST {
|
|||||||
var optMethod = findMethod(owner, methodCall.name, methodCall.getArgumentList());
|
var optMethod = findMethod(owner, methodCall.name, methodCall.getArgumentList());
|
||||||
if (optMethod.isEmpty()) return;
|
if (optMethod.isEmpty()) return;
|
||||||
var method = optMethod.get();
|
var method = optMethod.get();
|
||||||
if (visitedMethods.contains(method)) return;
|
|
||||||
visitedMethods.add(method);
|
|
||||||
|
|
||||||
var generics = generics(owner, method);
|
var generics = generics(owner, method);
|
||||||
Set<ResultPair<?, ?>> all = new HashSet<>(generics);
|
Set<ResultPair<?, ?>> all = new HashSet<>(generics);
|
||||||
@ -226,8 +229,6 @@ public class ASTToTargetAST {
|
|||||||
all.addAll(toAdd);
|
all.addAll(toAdd);
|
||||||
HashSet<PairTPHsmallerTPH> newPairs = new HashSet<>();
|
HashSet<PairTPHsmallerTPH> newPairs = new HashSet<>();
|
||||||
|
|
||||||
System.out.println("Result: " + result);
|
|
||||||
|
|
||||||
// Loop from hell
|
// Loop from hell
|
||||||
outer:
|
outer:
|
||||||
for (var tph : typeVariables) {
|
for (var tph : typeVariables) {
|
||||||
@ -459,12 +460,19 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
eliminateCyclesAndInfima(result);
|
eliminateCyclesAndInfima(result);
|
||||||
System.out.println(method.name + ": " + result);
|
usedTPHsOfMethods.put(method, typeVariables);
|
||||||
|
|
||||||
Set<TypePlaceholder> allUsedTPHs = new HashSet<>();
|
// For eliminating inner type variables we need to figure out which ones are actually used
|
||||||
allUsedTPHs.addAll(typeVariables);
|
var typeVariablesOfSignature = new HashSet<TypePlaceholder>();
|
||||||
allUsedTPHs.addAll(typeVariablesOfFields);
|
for (var param : method.getParameterList().getFormalparalist()) {
|
||||||
usedTPHsOfMethods.put(method, allUsedTPHs);
|
if (param.getType() instanceof TypePlaceholder tph)
|
||||||
|
typeVariablesOfSignature.add(equality.getOrDefault(tph, tph));
|
||||||
|
}
|
||||||
|
if (method.getReturnType() instanceof TypePlaceholder tph)
|
||||||
|
typeVariablesOfSignature.add(equality.getOrDefault(tph, tph));
|
||||||
|
|
||||||
|
eliminateInnerTypeVariables(typeVariablesOfSignature, result);
|
||||||
|
System.out.println(method.name + ": " + result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -509,7 +517,7 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
computedGenericsOfClasses.put(classOrInterface, result);
|
computedGenericsOfClasses.put(classOrInterface, result);
|
||||||
eliminateCyclesAndInfima(result);
|
eliminateCyclesAndInfima(result);
|
||||||
eliminateInnerTypeVariables(classOrInterface, result);
|
eliminateInnerTypeVariablesOfClass(classOrInterface, result);
|
||||||
equalizeTypeVariables(result);
|
equalizeTypeVariables(result);
|
||||||
|
|
||||||
|
|
||||||
@ -548,7 +556,7 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void eliminateInnerTypeVariables(ClassOrInterface classOrInterface, Set<ResultPair<?, ?>> input) {
|
void eliminateInnerTypeVariablesOfClass(ClassOrInterface classOrInterface, Set<ResultPair<?, ?>> input) {
|
||||||
Set<TypePlaceholder> referenced = new HashSet<>();
|
Set<TypePlaceholder> referenced = new HashSet<>();
|
||||||
for (var field : classOrInterface.getFieldDecl()) {
|
for (var field : classOrInterface.getFieldDecl()) {
|
||||||
findTphs(field.getType(), referenced);
|
findTphs(field.getType(), referenced);
|
||||||
@ -557,27 +565,25 @@ public class ASTToTargetAST {
|
|||||||
generics(classOrInterface, method);
|
generics(classOrInterface, method);
|
||||||
referenced.addAll(usedTPHsOfMethods.get(method));
|
referenced.addAll(usedTPHsOfMethods.get(method));
|
||||||
}
|
}
|
||||||
|
eliminateInnerTypeVariables(referenced, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
void eliminateInnerTypeVariables(Set<TypePlaceholder> referenced, Set<ResultPair<?, ?>> input) {
|
||||||
var oldInput = new HashSet<>(input);
|
var oldInput = new HashSet<>(input);
|
||||||
for (var pair : oldInput) {
|
for (var pair : oldInput) {
|
||||||
if (!referenced.contains(pair.getLeft())) {
|
if (pair instanceof PairTPHsmallerTPH ptph && !referenced.contains(ptph.left)) {
|
||||||
input.remove(pair);
|
input.remove(pair);
|
||||||
if (pair instanceof PairTPHsmallerTPH ptph)
|
equality.put(ptph.left, ptph.right);
|
||||||
equality.put(ptph.left, ptph.right);
|
|
||||||
for (var pair2 : oldInput) {
|
for (var pair2 : oldInput) {
|
||||||
if (pair2.getRight().equals(pair.getLeft())) {
|
if (pair2.getRight().equals(pair.getLeft())) {
|
||||||
input.remove(pair2);
|
input.remove(pair2);
|
||||||
if (pair instanceof PairTPHsmallerTPH)
|
addToPairs(input, new PairTPHsmallerTPH((TypePlaceholder) pair2.getLeft(), (TypePlaceholder) pair.getRight()));
|
||||||
addToPairs(input, new PairTPHsmallerTPH((TypePlaceholder) pair2.getLeft(), (TypePlaceholder) pair.getRight()));
|
|
||||||
else
|
|
||||||
addToPairs(input, new PairTPHequalRefTypeOrWildcardType((TypePlaceholder) pair2.getLeft(), pair.getRight()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void eliminateCycles(Set<ResultPair<?, ?>> input) {
|
void eliminateCycles(Set<ResultPair<?, ?>> input) {
|
||||||
var cycles = findCycles(input);
|
var cycles = findCycles(input);
|
||||||
for (var cycle : cycles) {
|
for (var cycle : cycles) {
|
||||||
|
Loading…
Reference in New Issue
Block a user