JavaTXCompilerInJavaTX/javatx-src/main/java/de/dhbwstuttgart/target/generate/GenericsResult.java

77 lines
2.8 KiB
Java

package de.dhbwstuttgart.target.generate;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.target.tree.type.TargetType;
import java.util.*;
public class GenericsResult {
private final GenerateGenerics generics;
GenericsResult(GenerateGenerics generics) {
this.generics = generics;
}
public GenericsResultSet get(ClassOrInterface clazz) {
var generics = this.generics.computedGenericsOfClasses.get(clazz);
return new GenericsResultSet(generics, this.generics.equality);
}
// TODO Compute generics if not present?
public GenericsResultSet get(Method method) {
var generics = this.generics.computedGenericsOfMethods.get(method);
return new GenericsResultSet(generics, this.generics.equality);
}
public BoundsList getBounds(RefTypeOrTPHOrWildcardOrGeneric type, ClassOrInterface clazz) {
return getBounds(type, clazz, null);
}
public BoundsList getBounds(RefTypeOrTPHOrWildcardOrGeneric type, ClassOrInterface clazz, Method method) {
var resolvedType = resolve(type);
type = resolvedType;
if (type instanceof TypePlaceholder) {
var methodGenerics = get(method);
var classGenerics = get(clazz);
List<Bound> result = new ArrayList<>();
Optional<Bound> bound = Optional.empty();
do {
bound = Optional.empty();
for (var pair : methodGenerics) {
if (pair.left.resolve().equals(type)) {
type = pair.resolveRight();
bound = Optional.of(new Bound(true, type));
break;
}
}
if (bound.isEmpty()) {
for (var pair : classGenerics) {
if (pair.left.resolve().equals(type)) {
type = pair.resolveRight();
bound = Optional.of(new Bound(false, type));
break;
}
}
}
bound.ifPresent(result::add);
} while (bound.isPresent());
return new BoundsList(resolvedType, result);
}
return new BoundsList(resolvedType, List.of());
}
public RefTypeOrTPHOrWildcardOrGeneric resolve(RefTypeOrTPHOrWildcardOrGeneric type) {
if (type instanceof TypePlaceholder tph)
return this.generics.getType(tph);
return type;
}
public TargetType resolveTarget(RefTypeOrTPHOrWildcardOrGeneric type) {
return this.generics.getTargetType(type);
}
}