Decouple unify from the rest of the code
Some checks failed
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 3m22s

This commit is contained in:
Daniel Holle 2024-03-28 10:35:34 +01:00
parent 877e5ed38a
commit 6850a8fa21
9 changed files with 103 additions and 99 deletions

View File

@ -292,7 +292,7 @@ public class JavaTXCompiler {
System.out.println(finiteClosure);
urm = new UnifyResultModel(cons, finiteClosure);
urm.addUnifyResultListener(resultListener);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons);
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
UnifyType lhs, rhs;
@ -428,7 +428,7 @@ public class JavaTXCompiler {
Writer logFile = log ? new FileWriter(new File(logFolder, "log_" + sourceFiles.keySet().iterator().next().getName())) : new OutputStreamWriter(new NullOutputStream());
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, classLoader, this);
System.out.println(finiteClosure);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons);
System.out.println("xxx1");
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
UnifyType lhs, rhs;

View File

@ -1,5 +1,6 @@
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.JavaClassName;
@ -25,8 +26,8 @@ public class FCGenerator {
*
* @param availableClasses - Alle geparsten Klassen
*/
public static Set<UnifyPair> toUnifyFC(Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException {
return toFC(availableClasses, classLoader).stream().map(t -> UnifyTypeFactory.convert(t)).collect(Collectors.toSet());
public static Set<UnifyPair> toUnifyFC(JavaTXCompiler compiler, Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException {
return toFC(availableClasses, classLoader).stream().map(t -> UnifyTypeFactory.convert(compiler, t)).collect(Collectors.toSet());
}
public static Set<Pair> toFC(Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException {

View File

@ -1,10 +1,12 @@
package de.dhbwstuttgart.syntaxtree.factory;
import java.io.Writer;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.exceptions.NotImplementedException;
@ -13,6 +15,7 @@ import de.dhbwstuttgart.parser.SourceLoc;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.FCGenerator;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.syntaxtree.type.WildcardType;
@ -41,7 +44,7 @@ public class UnifyTypeFactory {
Generell dürfen sie immer die gleichen Namen haben.
TODO: die transitive Hülle bilden
*/
return new FiniteClosure(FCGenerator.toUnifyFC(fromClasses, classLoader), logFile, compiler);
return new FiniteClosure(FCGenerator.toUnifyFC(compiler, fromClasses, classLoader), logFile, compiler);
}
public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr, SourceLoc location){
@ -64,23 +67,23 @@ public class UnifyTypeFactory {
* Convert from
* ASTType -> UnifyType
*/
public static UnifyType convert(RefTypeOrTPHOrWildcardOrGeneric t, Boolean innerType){
public static UnifyType convert(JavaTXCompiler compiler, RefTypeOrTPHOrWildcardOrGeneric t, Boolean innerType){
if (t instanceof GenericRefType){
return UnifyTypeFactory.convert((GenericRefType)t, innerType);
return UnifyTypeFactory.convert(compiler, (GenericRefType)t, innerType);
} else if (t instanceof TypePlaceholder){
return UnifyTypeFactory.convert((TypePlaceholder)t, innerType);
return UnifyTypeFactory.convert(compiler, (TypePlaceholder)t, innerType);
} else if (t instanceof ExtendsWildcardType){
return UnifyTypeFactory.convert((ExtendsWildcardType)t, innerType);
return UnifyTypeFactory.convert(compiler, (ExtendsWildcardType)t, innerType);
} else if (t instanceof SuperWildcardType) {
return UnifyTypeFactory.convert((SuperWildcardType) t, innerType);
return UnifyTypeFactory.convert(compiler, (SuperWildcardType) t, innerType);
} else if (t instanceof RefType){
return UnifyTypeFactory.convert((RefType)t, innerType);
return UnifyTypeFactory.convert(compiler, (RefType)t, innerType);
}
//Es wurde versucht ein Typ umzuwandeln, welcher noch nicht von der Factory abgedeckt ist
throw new NotImplementedException("Der Typ "+t+" kann nicht umgewandelt werden");
}
public static UnifyType convert(RefType t, Boolean innerType){
public static UnifyType convert(JavaTXCompiler compiler, RefType t, Boolean innerType){
//Check if it is a FunN Type:
Pattern p = Pattern.compile("Fun(\\d+)[$][$]");
Matcher m = p.matcher(t.getName().toString());
@ -88,35 +91,41 @@ public class UnifyTypeFactory {
if(b){
Integer N = Integer.valueOf(m.group(1));
if((N + 1) == t.getParaList().size()){
return convertFunN(t.getParaList(), false);
return convertFunN(compiler, t.getParaList(), false);
}
}
UnifyType ret;
if(t.getParaList() != null && t.getParaList().size() > 0){
List<UnifyType> params = new ArrayList<>();
for(RefTypeOrTPHOrWildcardOrGeneric pT : t.getParaList()){
params.add(UnifyTypeFactory.convert(pT, true));
List<UnifyType> params = new ArrayList<>();
if (t.getParaList() != null) {
for (RefTypeOrTPHOrWildcardOrGeneric pT : t.getParaList()) {
params.add(UnifyTypeFactory.convert(compiler, pT, true));
}
ret = new ReferenceType(t.getName().toString(),new TypeParams(params));
}else{
ret = new ReferenceType(t.getName().toString(), false);
}
return ret;
var clazz = compiler.getClass(t.getName());
if (clazz != null && clazz.isInterface() && clazz.isFunctionalInterface()) {
var method = clazz.getMethods().stream().filter(x -> Modifier.isAbstract(x.modifier)).findFirst().orElseThrow();
var methodParams = method.getParameterList().getFormalparalist().stream().map(x -> convert(compiler, x.getType(), true)).toList();
var generics = StreamSupport.stream(clazz.getGenerics().spliterator(), false).map(GenericTypeVar::getName).toList();
return new FunInterfaceType(t.getName().toString(), new TypeParams(params), methodParams, convert(compiler, method.getReturnType(), true), generics);
}
return new ReferenceType(t.getName().toString(),new TypeParams(params));
}
public static UnifyType convertFunN(List<RefTypeOrTPHOrWildcardOrGeneric> paraList, Boolean innerType){
public static UnifyType convertFunN(JavaTXCompiler compiler, List<RefTypeOrTPHOrWildcardOrGeneric> paraList, Boolean innerType){
UnifyType ret;
List<UnifyType> params = new ArrayList<>();
if(paraList != null && paraList.size() > 0){
for(RefTypeOrTPHOrWildcardOrGeneric pT : paraList){
params.add(UnifyTypeFactory.convert(pT, false));
params.add(UnifyTypeFactory.convert(compiler, pT, false));
}
}
ret = FunNType.getFunNType(new TypeParams(params));
return ret;
}
public static UnifyType convert(TypePlaceholder tph, Boolean innerType){
public static UnifyType convert(JavaTXCompiler compiler, TypePlaceholder tph, Boolean innerType){
if (tph.getName().equals("AFR")) {
System.out.println("XXX"+innerType);
}
@ -136,21 +145,21 @@ public class UnifyTypeFactory {
}
}
public static UnifyType convert(GenericRefType t, Boolean innerType){
public static UnifyType convert(JavaTXCompiler compiler, GenericRefType t, Boolean innerType){
return new ReferenceType(t.getParsedName(), true);
}
public static UnifyType convert(WildcardType t, Boolean innerType){
public static UnifyType convert(JavaTXCompiler compiler, WildcardType t, Boolean innerType){
if(t.isExtends())
return new ExtendsType(UnifyTypeFactory.convert(t.getInnerType(), false));
return new ExtendsType(UnifyTypeFactory.convert(compiler, t.getInnerType(), false));
else if(t.isSuper())
return new SuperType(UnifyTypeFactory.convert(t.getInnerType(), false));
return new SuperType(UnifyTypeFactory.convert(compiler, t.getInnerType(), false));
else throw new NotImplementedException();
}
public static ConstraintSet<UnifyPair> convert(ConstraintSet<Pair> constraints) {
return constraints.map(UnifyTypeFactory::convert);
public static ConstraintSet<UnifyPair> convert(JavaTXCompiler compiler, ConstraintSet<Pair> constraints) {
return constraints.map(c -> UnifyTypeFactory.convert(compiler, c));
}
//NEVER USED
@ -161,23 +170,23 @@ public class UnifyTypeFactory {
// return unifyPairConstraint;
//}
public static UnifyPair convert(Pair p) {
public static UnifyPair convert(JavaTXCompiler compiler, Pair p) {
UnifyPair ret = null;
if(p.GetOperator().equals(PairOperator.SMALLERDOT)) {
ret = generateSmallerDotPair(UnifyTypeFactory.convert(p.TA1, false)
, UnifyTypeFactory.convert(p.TA2, false), p.getLocation());
ret = generateSmallerDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false)
, UnifyTypeFactory.convert(compiler, p.TA2, false), p.getLocation());
//return ret;
}else if(p.GetOperator().equals(PairOperator.SMALLERNEQDOT)) {
ret = generateSmallNotEqualDotPair(UnifyTypeFactory.convert(p.TA1, false)
, UnifyTypeFactory.convert(p.TA2, false), p.getLocation());
ret = generateSmallNotEqualDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false)
, UnifyTypeFactory.convert(compiler, p.TA2, false), p.getLocation());
//return ret;
}else if(p.GetOperator().equals(PairOperator.EQUALSDOT)) {
ret = generateEqualDotPair(UnifyTypeFactory.convert(p.TA1, false)
, UnifyTypeFactory.convert(p.TA2, false), p.getLocation());
ret = generateEqualDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false)
, UnifyTypeFactory.convert(compiler, p.TA2, false), p.getLocation());
//return ret;
}else if(p.GetOperator().equals(PairOperator.SMALLER)){
ret = generateSmallerPair(UnifyTypeFactory.convert(p.TA1, false),
UnifyTypeFactory.convert(p.TA2, false), p.getLocation());
ret = generateSmallerPair(UnifyTypeFactory.convert(compiler, p.TA1, false),
UnifyTypeFactory.convert(compiler, p.TA2, false), p.getLocation());
}else throw new NotImplementedException();
UnifyType lhs, rhs;
if (((lhs = ret.getLhsType()) instanceof PlaceholderType)

View File

@ -19,17 +19,7 @@ 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;
import de.dhbwstuttgart.typeinference.unify.model.FunNType;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
import de.dhbwstuttgart.typeinference.unify.model.SuperType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
import de.dhbwstuttgart.typeinference.unify.model.Unifier;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
import de.dhbwstuttgart.typeinference.unify.model.WildcardType;
import de.dhbwstuttgart.typeinference.unify.model.*;
import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.unify.distributeVariance;
@ -901,12 +891,12 @@ public class RuleSet implements IRuleSet{
if(!opt.isPresent())
return Optional.empty();
if (!(typeFI instanceof ReferenceType refType) || !fc.isFunctionalInterface(refType))
if (!(typeFI instanceof ReferenceType refType) || !(refType instanceof FunInterfaceType intf))
return Optional.empty();
var fiArgs = fc.getFunctionalInterfaceTypeArguments(refType);
var fiArgs = intf.getFunctionalInterfaceTypeArguments(refType);
var retType = fiArgs.getFirst();
var lhsArgs = fc.getFunctionalInterfaceTypeArguments(lhsType);
var lhsArgs = intf.getFunctionalInterfaceTypeArguments(lhsType);
var lhsRet = lhsArgs.getFirst();
Set<UnifyPair> result = new HashSet<>();

View File

@ -74,8 +74,5 @@ public interface IFiniteClosure {
public Set<UnifyType> getChildren(UnifyType t);
public Set<UnifyType> getAllTypesByName(String typeName);
public boolean isFunctionalInterface(ReferenceType t);
public List<UnifyType> getFunctionalInterfaceTypeArguments(UnifyType t);
public int compare(UnifyType rhsType, UnifyType rhsType2, PairOperator pairop);
}

View File

@ -607,42 +607,6 @@ implements IFiniteClosure {
return strInheritanceGraph.get(typeName).stream().map(x -> x.getContent()).collect(Collectors.toCollection(HashSet::new));
}
@Override
public boolean isFunctionalInterface(ReferenceType t) {
return compiler.getClass(new JavaClassName(t.getName())).isFunctionalInterface();
}
@Override
public List<UnifyType> getFunctionalInterfaceTypeArguments(UnifyType t) {
if (t instanceof FunNType) {
var ret = new ArrayList<UnifyType>();
if (t.getTypeParams().size() > 0) {
ret.add(t.getTypeParams().get(t.getTypeParams().size() - 1));
ret.addAll(Arrays.asList(t.getTypeParams().get()).subList(0, t.getTypeParams().size() - 1));
}
return ret;
}
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;
}
return args;
}
@Override
public Optional<UnifyType> getLeftHandedType(String typeName) {
if(!strInheritanceGraph.containsKey(typeName))

View File

@ -0,0 +1,49 @@
package de.dhbwstuttgart.typeinference.unify.model;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FunInterfaceType extends ReferenceType {
final List<UnifyType> intfArgTypes;
final UnifyType intfReturnType;
final List<String> generics;
public FunInterfaceType(String name, TypeParams params, List<UnifyType> intfArgTypes, UnifyType intfReturnType, List<String> generics) {
super(name, params);
this.intfArgTypes = intfArgTypes;
this.intfReturnType = intfReturnType;
this.generics = generics;
}
public List<UnifyType> getFunctionalInterfaceTypeArguments(UnifyType t) {
if (t instanceof FunNType) {
var ret = new ArrayList<UnifyType>();
if (t.getTypeParams().size() > 0) {
ret.add(t.getTypeParams().get(t.getTypeParams().size() - 1));
ret.addAll(Arrays.asList(t.getTypeParams().get()).subList(0, t.getTypeParams().size() - 1));
}
return ret;
}
var args = new ArrayList<UnifyType>();
args.add(intfReturnType);
args.addAll(intfArgTypes);
// TODO There might be a better way of dealing with this
var i = 0;
for (var generic : generics) {
for (var j = 0; j < args.size(); j++) {
if (args.get(j).getName().equals(generic))
args.set(j, t.getTypeParams().get(i));
}
i += 1;
}
return args;
}
}

View File

@ -34,12 +34,6 @@ public class ReferenceType extends UnifyType {
this.genericTypeVar = genericTypeVar;
}
public ReferenceType(String name, UnifyType... params) {
super(name, new TypeParams(params));
hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode();
genericTypeVar = false;
}
public ReferenceType(String name, TypeParams params) {
super(name, params);
hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode();

View File

@ -233,7 +233,7 @@ public class TestComplete {
}
@Test
@Ignore("This is too complex")
//@Ignore("This is too complex")
public void matrixTest() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Matrix.jav");
var matrix = classFiles.get("Matrix");