3 Commits

110 changed files with 5874 additions and 7092 deletions

View File

@@ -1,4 +1,3 @@
//PL 2018-12-19: typeInferenceOld nach typeInference uebertragen
package de.dhbwstuttgart.core; package de.dhbwstuttgart.core;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@@ -13,7 +12,6 @@ import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
import de.dhbwstuttgart.parser.antlr.Java8Parser.CompilationUnitContext; import de.dhbwstuttgart.parser.antlr.Java8Parser.CompilationUnitContext;
import de.dhbwstuttgart.parser.scope.GenericsRegistry; import de.dhbwstuttgart.parser.scope.GenericsRegistry;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.*;
@@ -24,545 +22,476 @@ import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.typeAlgo.TYPE; import de.dhbwstuttgart.typeinference.typeAlgo.TYPE;
import de.dhbwstuttgart.typeinference.unify.UnifyResultListener;
import de.dhbwstuttgart.typeinference.unify.UnifyResultModelParallel;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import org.apache.commons.io.output.NullOutputStream; import org.apache.commons.io.output.NullOutputStream;
import javax.annotation.Nullable;
import java.io.*;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class JavaTXCompiler { public class JavaTXCompiler {
//public static JavaTXCompiler INSTANCE;
final CompilationEnvironment environment; final CompilationEnvironment environment;
Boolean useResultModel = true; Boolean useResultModel = true;
Optional<String> unificationServer = Optional.empty(); Optional<String> unificationServer = Optional.empty();
public final Map<File, SourceFile> sourceFiles = new HashMap<>(); public final Map<File, SourceFile> sourceFiles = new HashMap<>();
Boolean log = false; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll? Boolean log = false; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll?
private final DirectoryClassLoader classLoader; private final DirectoryClassLoader classLoader;
static Writer statistics; static Writer statistics;
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException { public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
this(Arrays.asList(sourceFile), null); this(Arrays.asList(sourceFile), null);
}
public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
this(sourceFile);
this.log = log;
} }
public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException {
this(sourceFiles, null); public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
} this(sourceFile);
this.log = log;
}
public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException {
this(sourceFiles, null);
}
public JavaTXCompiler(List<File> sources, List<File> contextPath) throws IOException, ClassNotFoundException { public JavaTXCompiler(List<File> sources, List<File> contextPath) throws IOException, ClassNotFoundException {
//statistics = new FileWriter(new File(System.getProperty("user.dir") + "/" + sources.get(0).getName() + "_"+ new Timestamp(System.currentTimeMillis()))); //statistics = new FileWriter(new File(System.getProperty("user.dir") + "/" + sources.get(0).getName() + "_"+ new Timestamp(System.currentTimeMillis())));
statistics = new OutputStreamWriter(new NullOutputStream()); statistics = new OutputStreamWriter(new NullOutputStream());
statistics.write("test"); statistics.write("test");
if(contextPath == null || contextPath.isEmpty()){ if (contextPath == null || contextPath.isEmpty()) {
//When no contextPaths are given, the working directory is the sources root //When no contextPaths are given, the working directory is the sources root
contextPath = Lists.newArrayList(new File(System.getProperty("user.dir"))); contextPath = Lists.newArrayList(new File(System.getProperty("user.dir")));
} }
classLoader = new DirectoryClassLoader(contextPath, ClassLoader.getSystemClassLoader()); classLoader = new DirectoryClassLoader(contextPath, ClassLoader.getSystemClassLoader());
environment = new CompilationEnvironment(sources); environment = new CompilationEnvironment(sources);
for (File s : sources) { for (File s : sources) {
sourceFiles.put(s, parse(s)); sourceFiles.put(s, parse(s));
} }
//INSTANCE = this; //INSTANCE = this;
} }
public JavaTXCompiler(List<File> source, List<File> contextPath, String unificationServer) throws IOException, ClassNotFoundException {
this(source, contextPath); public JavaTXCompiler(List<File> source, List<File> contextPath, String unificationServer) throws IOException, ClassNotFoundException {
this.unificationServer = unificationServer == null ? Optional.empty() : Optional.of(unificationServer); this(source, contextPath);
} this.unificationServer = unificationServer == null ? Optional.empty() : Optional.of(unificationServer);
}
public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException, IOException { public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException, IOException {
List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses(); List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses();
List<ClassOrInterface> importedClasses = new ArrayList<>(); List<ClassOrInterface> importedClasses = new ArrayList<>();
ClassOrInterface objectClass = ASTFactory.createClass( ClassOrInterface objectClass = ASTFactory.createClass(
classLoader.loadClass(new JavaClassName("java.lang.Object").toString())); classLoader.loadClass(new JavaClassName("java.lang.Object").toString())
);
//Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC //Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
for (File forSourceFile : sourceFiles.keySet()){ for (File forSourceFile : sourceFiles.keySet()) {
for (JavaClassName name : sourceFiles.get(forSourceFile).getImports()) { for (JavaClassName name : sourceFiles.get(forSourceFile).getImports()) {
//TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet //TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet
ClassOrInterface importedClass = ASTFactory.createClass( ClassOrInterface importedClass = ASTFactory.createClass(
classLoader.loadClass(name.toString())); classLoader.loadClass(name.toString()));
importedClasses.add(importedClass);
}
for (Class<?> c : CompilationEnvironment.loadDefaultPackageClasses(forSourceFile, classLoader)) {
ClassOrInterface importedClass = ASTFactory.createClass(c);
importedClasses.add(importedClass); importedClasses.add(importedClass);
} }
for(Class c : CompilationEnvironment.loadDefaultPackageClasses(forSourceFile, classLoader)){
ClassOrInterface importedClass = ASTFactory.createClass(c);
importedClasses.add(importedClass);
}
} }
for (File f : this.sourceFiles.keySet()) { for (File f : this.sourceFiles.keySet()) {
SourceFile sf = sourceFiles.get(f); SourceFile sf = sourceFiles.get(f);
sf = new SourceFile(sf.getPkgName(), sf = new SourceFile(sf.getPkgName(),
sf.KlassenVektor.stream() sf.KlassenVektor.stream()
.map(cl -> new ClassOrInterface(cl)) .map(cl -> new ClassOrInterface(cl))
.collect(Collectors.toCollection(ArrayList::new)), .collect(Collectors.toCollection(ArrayList::new)),
sf.imports); sf.imports);
//sf enthaelt neues Source-File, neue Klassen-Objekte und neue //sf enthaelt neues Source-File, neue Klassen-Objekte und neue
//ArrayListen-Objekte fuer Fields, Construktoren und Methoden //ArrayListen-Objekte fuer Fields, Construktoren und Methoden
//Alle anderen Objekte werden nur kopiert. //Alle anderen Objekte werden nur kopiert.
SourceFile sf_new = sf; SourceFile sf_new = sf;
sf.KlassenVektor.forEach(cl -> addMethods(sf_new, cl, importedClasses, objectClass)); sf.KlassenVektor.forEach(cl -> addMethods(sf_new, cl, importedClasses, objectClass));
allClasses.addAll(sf.getClasses()); allClasses.addAll(sf.getClasses());
} }
allClasses.addAll(importedClasses); allClasses.addAll(importedClasses);
TYPE ty = new TYPE(sourceFiles.values(), allClasses); TYPE ty = new TYPE(sourceFiles.values(), allClasses);
return ty.getConstraints(); return ty.getConstraints();
} }
void addMethods(SourceFile sf, ClassOrInterface cl, List<ClassOrInterface> importedClasses, ClassOrInterface objectClass) { void addMethods(SourceFile sf, ClassOrInterface cl, List<ClassOrInterface> importedClasses, ClassOrInterface objectClass) {
if (!cl.areMethodsAdded()) { if (!cl.areMethodsAdded()) {
ClassOrInterface superclass = null; ClassOrInterface superclass = null;
if (cl.getSuperClass().getName().equals(new JavaClassName("java.lang.Object"))) { if (cl.getSuperClass().getName().equals(new JavaClassName("java.lang.Object"))) {
superclass = objectClass; superclass = objectClass;
} } else {
else { Optional<ClassOrInterface> optSuperclass =
Optional<ClassOrInterface> optSuperclass = importedClasses.stream().filter(x -> x.getClassName().equals(
importedClasses.stream().filter(x -> x.getClassName().equals( cl.getSuperClass().getName())).findFirst();
cl.getSuperClass().getName())).findFirst(); if (optSuperclass.isPresent()) {
if (optSuperclass.isPresent()) { superclass = optSuperclass.get();
superclass = optSuperclass.get(); } else {
} optSuperclass =
else { sf.KlassenVektor.stream().filter(x -> x.getClassName().equals(
optSuperclass = cl.getSuperClass().getName())).findFirst();
sf.KlassenVektor.stream().filter(x -> x.getClassName().equals( if (optSuperclass.isPresent()) {
cl.getSuperClass().getName())).findFirst(); superclass = optSuperclass.get();
if (optSuperclass.isPresent()) { addMethods(sf, superclass, importedClasses, objectClass);
superclass = optSuperclass.get(); } else {
addMethods(sf, superclass, importedClasses, objectClass); //throw new ClassNotFoundException("");
} }
else { }
//throw new ClassNotFoundException(""); }
} Iterator<RefTypeOrTPHOrWildcardOrGeneric> paraIt = cl.getSuperClass().getParaList().iterator();
} Iterator<GenericTypeVar> tvarVarIt = superclass.getGenerics().iterator();
}
Iterator<RefTypeOrTPHOrWildcardOrGeneric> paraIt= cl.getSuperClass().getParaList().iterator(); HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>();
Iterator<GenericTypeVar> tvarVarIt = superclass.getGenerics().iterator(); while (paraIt.hasNext()) {
gtvs.put(tvarVarIt.next().getName(), paraIt.next());
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>(); }
while (paraIt.hasNext()) { //TODO: PL 2020-05-06: Hier müssen ueberschriebene Methoden noch rausgefiltert werden
gtvs.put(tvarVarIt.next().getName(), paraIt.next()); for (Method m : superclass.getMethods()) {
} ParameterList newParaList = new ParameterList(
Iterator<Method> methodIt = superclass.getMethods().iterator(); m.getParameterList()
//TODO: PL 2020-05-06: Hier müssen ueberschriebene Methoden noch rausgefiltert werden .getFormalparalist()
while(methodIt.hasNext()) { .stream()
Method m = methodIt.next(); .map(fp -> new FormalParameter(fp.getName(), fp.getType().acceptTV(new TypeExchanger(gtvs)), fp.getOffset()))
ParameterList newParaList = new ParameterList( .collect(Collectors.toCollection(ArrayList::new)), m.getParameterList().getOffset());
m.getParameterList() cl.getMethods().add(new Method(m.modifier, m.name, m.getReturnType().acceptTV(new TypeExchanger(gtvs)), newParaList, m.block,
.getFormalparalist() //new GenericDeclarationList(newGenericsList, ((GenericDeclarationList)m.getGenerics()).getOffset()),
.stream() (GenericDeclarationList) m.getGenerics(),
.map(fp -> new FormalParameter(fp.getName(), fp.getType().acceptTV(new TypeExchanger(gtvs)), fp.getOffset())) m.getOffset(), true));
.collect(Collectors.toCollection(ArrayList::new)), m.getParameterList().getOffset()); }
cl.getMethods().add(new Method(m.modifier, m.name, m.getReturnType().acceptTV(new TypeExchanger(gtvs)), newParaList, m.block,
//new GenericDeclarationList(newGenericsList, ((GenericDeclarationList)m.getGenerics()).getOffset()), }
(GenericDeclarationList)m.getGenerics(), cl.setMethodsAdded();
m.getOffset(), true)); }
}
}
cl.setMethodsAdded();
}
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException { public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
//PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal hinzugefuegt werden //PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal hinzugefuegt werden
//List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses(); //List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses();
Set<ClassOrInterface> allClasses = new HashSet<>(); Set<ClassOrInterface> allClasses = new HashSet<>();
/* PL 2018-09-19 geloescht werden bereits in typeInference hinzugefuegt
}
allClasses.addAll(importedClasses);
return new TYPE(sourceFiles.values(), allClasses).getConstraints();
}
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException { List<ClassOrInterface> importedClasses = new ArrayList<>();
// PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal for (JavaClassName name : forSourceFile.getImports()) {
// hinzugefuegt werden // TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet
// List<ClassOrInterface> allClasses = new ClassOrInterface importedClass = ASTFactory
// ArrayList<>();//environment.getAllAvailableClasses(); .createClass(classLoader.loadClass(name.toString()));
Set<ClassOrInterface> allClasses = new HashSet<>(); importedClasses.add(importedClass);
allClasses.addAll(importedClasses);
}
return new ArrayList<>(allClasses);
}
/* /*
* PL 2018-09-19 geloescht werden bereits in typeInference hinzugefuegt for * public List<ResultSet> typeInferenceOld() throws ClassNotFoundException {
* (SourceFile sf : sourceFiles.values()) { allClasses.addAll(sf.getClasses()); * List<ClassOrInterface> allClasses = new
* } * ArrayList<>();//environment.getAllAvailableClasses(); //Alle Importierten
*/ * Klassen in allen geparsten Sourcefiles kommen ins FC for(SourceFile sf :
* this.sourceFiles.values()) { allClasses.addAll(getAvailableClasses(sf));
* allClasses.addAll(sf.getClasses()); }
*
* final ConstraintSet<Pair> cons = getConstraints();
*
* FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses);
* System.out.println(finiteClosure); ConstraintSet<UnifyPair> unifyCons =
* UnifyTypeFactory.convert(cons);
*
* TypeUnify unify = new TypeUnify(); Set<Set<UnifyPair>> results = new
* HashSet<>(); try { File logPath = new
* File(System.getProperty("user.dir")+"/target/logFiles/"); logPath.mkdirs();
* FileWriter logFile = new FileWriter(new File(logPath, "log"));
* logFile.write("FC:\\" + finiteClosure.toString()+"\n"); for(SourceFile sf :
* this.sourceFiles.values()) { logFile.write(ASTTypePrinter.print(sf)); }
* logFile.flush(); Set<List<Constraint<UnifyPair>>> cardProd =
* unifyCons.cartesianProduct(); for (List<Constraint<UnifyPair>> xCons :
* cardProd ){ Set<UnifyPair> xConsSet = new HashSet<>(); for
* (Constraint<UnifyPair> constraint : xCons) { xConsSet.addAll(constraint); }
* //.collect(Collectors.toCollection(ArrayList::new))))
* System.out.println(xConsSet); Set<String> methodParaTypeVarNames =
* allClasses.stream().map(x -> x.getMethods().stream().map(y ->
* y.getParameterList().getFormalparalist() .stream().filter(z -> z.getType()
* instanceof TypePlaceholder) .map(z ->
* ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(
* HashSet::new))) .reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return
* a;}, (a,b) -> { a.addAll(b); return a;} ) ) .reduce(new HashSet<String>(),
* (a,b) -> { a.addAll(b); return a;} );
*
* Set<String> constructorParaTypeVarNames = allClasses.stream().map(x ->
* x.getConstructors().stream().map(y ->
* y.getParameterList().getFormalparalist() .stream().filter(z -> z.getType()
* instanceof TypePlaceholder) .map(z ->
* ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(
* HashSet::new))) .reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return
* a;}, (a,b) -> { a.addAll(b); return a;} ) ) .reduce(new HashSet<String>(),
* (a,b) -> { a.addAll(b); return a;} );
*
* Set<String> paraTypeVarNames = methodParaTypeVarNames;
* paraTypeVarNames.addAll(constructorParaTypeVarNames);
*
* Set<String> returnTypeVarNames = allClasses.stream().map(x ->
* x.getMethods().stream().filter(y -> y.getReturnType() instanceof
* TypePlaceholder) .map(z ->
* ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.
* toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;}
* ).get();
*
* Set<String> fieldTypeVarNames = allClasses.stream().map(x ->
* x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof
* TypePlaceholder) .map(z ->
* ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.
* toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;}
* ).get();
*
* returnTypeVarNames.addAll(fieldTypeVarNames);
*
* xConsSet = xConsSet.stream().map(x -> { //Hier muss ueberlegt werden, ob //1.
* alle Argument- und Retuntyp-Variablen in allen UnifyPairs // mit
* disableWildcardtable() werden. //2. alle Typvariablen mit Argument- oder
* Retuntyp-Variablen //in Beziehung auch auf disableWildcardtable() gesetzt
* werden muessen //PL 2018-04-23 if ((x.getLhsType() instanceof
* PlaceholderType)) { if (paraTypeVarNames.contains(x.getLhsType().getName()))
* { ((PlaceholderType)x.getLhsType()).setVariance((byte)1);
* ((PlaceholderType)x.getLhsType()).disableWildcardtable(); } if
* (returnTypeVarNames.contains(x.getLhsType().getName())) {
* ((PlaceholderType)x.getLhsType()).setVariance((byte)-1);
* ((PlaceholderType)x.getLhsType()).disableWildcardtable(); } } if
* ((x.getRhsType() instanceof PlaceholderType)) { if
* (paraTypeVarNames.contains(x.getRhsType().getName())) {
* ((PlaceholderType)x.getRhsType()).setVariance((byte)1);
* ((PlaceholderType)x.getRhsType()).disableWildcardtable(); } if
* (returnTypeVarNames.contains(x.getRhsType().getName())) {
* ((PlaceholderType)x.getRhsType()).setVariance((byte)-1);
* ((PlaceholderType)x.getRhsType()).disableWildcardtable(); } } return x;//HIER
* DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE JEWEILS
* ANDERE SEITE }).map( y -> { if ((y.getLhsType() instanceof PlaceholderType)
* && (y.getRhsType() instanceof PlaceholderType)) { if
* (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) {
* ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType(
* )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0
* && ((PlaceholderType)y.getRhsType()).getVariance() != 0) {
* ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType(
* )).getVariance()); } } return y; } )
* .collect(Collectors.toCollection(HashSet::new));
* varianceInheritance(xConsSet); Set<Set<UnifyPair>> result =
* unify.unifySequential(xConsSet, finiteClosure, logFile, log);
* //Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
* System.out.println("RESULT: " + result); logFile.write("RES: " +
* result.toString()+"\n"); logFile.flush(); results.addAll(result); }
*
* results = results.stream().map(x -> { Optional<Set<UnifyPair>> res = new
* RuleSet().subst(x.stream().map(y -> { if (y.getPairOp() ==
* PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT); return y;
* //alle Paare a <.? b erden durch a =. b ersetzt
* }).collect(Collectors.toCollection(HashSet::new))); if (res.isPresent())
* {//wenn subst ein Erg liefert wurde was veraendert return new
* TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure); } else
* return x; //wenn nichts veraendert wurde wird x zurueckgegeben
* }).collect(Collectors.toCollection(HashSet::new));
* System.out.println("RESULT Final: " + results); logFile.write("RES_FINAL: " +
* results.toString()+"\n"); logFile.flush(); logFile.write("PLACEHOLDERS: " +
* PlaceholderType.EXISTING_PLACEHOLDERS); logFile.flush(); } catch (IOException
* e) { e.printStackTrace(); } return results.stream().map((unifyPairs -> new
* ResultSet(UnifyTypeFactory.convert(unifyPairs,
* generateTPHMap(cons))))).collect(Collectors.toList()); }
*/
List<ClassOrInterface> importedClasses = new ArrayList<>(); /**
for (JavaClassName name : forSourceFile.getImports()) { * Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine
// TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet * Variance !=0 hat auf alle Typvariablen in Theta.
ClassOrInterface importedClass = ASTFactory */
.createClass(classLoader.loadClass(name.toString())); /*
importedClasses.add(importedClass); * private void varianceInheritance(Set<UnifyPair> eq) { Set<PlaceholderType>
allClasses.addAll(importedClasses); * usedTPH = new HashSet<>(); Set<PlaceholderType> phSet = eq.stream().map(x ->
} * { Set<PlaceholderType> pair = new HashSet<>(); if (x.getLhsType() instanceof
return new ArrayList<>(allClasses); * PlaceholderType) pair.add((PlaceholderType)x.getLhsType()); if
} * (x.getRhsType() instanceof PlaceholderType)
* pair.add((PlaceholderType)x.getRhsType()); return pair; }).reduce(new
* HashSet<>(), (a,b) -> { a.addAll(b); return a;} , (c,d) -> { c.addAll(d);
* return c;});
*
* ArrayList<PlaceholderType> phSetVariance = new ArrayList<>(phSet);
* phSetVariance.removeIf(x -> (x.getVariance() == 0));
* while(!phSetVariance.isEmpty()) { PlaceholderType a =
* phSetVariance.remove(0); usedTPH.add(a); //HashMap<PlaceholderType,Integer>
* ht = new HashMap<>(); //ht.put(a, a.getVariance()); Set<UnifyPair> eq1 = new
* HashSet<>(eq); eq1.removeIf(x -> !(x.getLhsType() instanceof PlaceholderType
* && ((PlaceholderType)x.getLhsType()).equals(a))); eq1.stream().forEach(x -> {
* x.getRhsType().accept(new distributeVariance(), a.getVariance());}); eq1 =
* new HashSet<>(eq); eq1.removeIf(x -> !(x.getRhsType() instanceof
* PlaceholderType && ((PlaceholderType)x.getRhsType()).equals(a)));
* eq1.stream().forEach(x -> { x.getLhsType().accept(new distributeVariance(),
* a.getVariance());}); phSetVariance = new ArrayList<>(phSet);
* phSetVariance.removeIf(x -> (x.getVariance() == 0 || usedTPH.contains(x))); }
* }
*/
public List<ResultSet> typeInference() throws ClassNotFoundException, IOException {
/* /*
* public List<ResultSet> typeInferenceOld() throws ClassNotFoundException { * Gather all available (imported) classes from all parsed source files for putting them into the finite closure
* List<ClassOrInterface> allClasses = new */
* ArrayList<>();//environment.getAllAvailableClasses(); //Alle Importierten List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses();
* Klassen in allen geparsten Sourcefiles kommen ins FC for(SourceFile sf : for (File f : this.sourceFiles.keySet()) {
* this.sourceFiles.values()) { allClasses.addAll(getAvailableClasses(sf)); SourceFile sf = sourceFiles.get(f);
* allClasses.addAll(sf.getClasses()); } allClasses.addAll(getAvailableClasses(sf));
* allClasses.addAll(sf.getClasses());
* final ConstraintSet<Pair> cons = getConstraints(); allClasses.addAll(CompilationEnvironment.loadDefaultPackageClasses(f, classLoader).stream().map(ASTFactory::createClass).toList());
* }
* FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses);
* System.out.println(finiteClosure); ConstraintSet<UnifyPair> unifyCons =
* UnifyTypeFactory.convert(cons);
*
* TypeUnify unify = new TypeUnify(); Set<Set<UnifyPair>> results = new
* HashSet<>(); try { File logPath = new
* File(System.getProperty("user.dir")+"/target/logFiles/"); logPath.mkdirs();
* FileWriter logFile = new FileWriter(new File(logPath, "log"));
* logFile.write("FC:\\" + finiteClosure.toString()+"\n"); for(SourceFile sf :
* this.sourceFiles.values()) { logFile.write(ASTTypePrinter.print(sf)); }
* logFile.flush(); Set<List<Constraint<UnifyPair>>> cardProd =
* unifyCons.cartesianProduct(); for (List<Constraint<UnifyPair>> xCons :
* cardProd ){ Set<UnifyPair> xConsSet = new HashSet<>(); for
* (Constraint<UnifyPair> constraint : xCons) { xConsSet.addAll(constraint); }
* //.collect(Collectors.toCollection(ArrayList::new))))
* System.out.println(xConsSet); Set<String> methodParaTypeVarNames =
* allClasses.stream().map(x -> x.getMethods().stream().map(y ->
* y.getParameterList().getFormalparalist() .stream().filter(z -> z.getType()
* instanceof TypePlaceholder) .map(z ->
* ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(
* HashSet::new))) .reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return
* a;}, (a,b) -> { a.addAll(b); return a;} ) ) .reduce(new HashSet<String>(),
* (a,b) -> { a.addAll(b); return a;} );
*
* Set<String> constructorParaTypeVarNames = allClasses.stream().map(x ->
* x.getConstructors().stream().map(y ->
* y.getParameterList().getFormalparalist() .stream().filter(z -> z.getType()
* instanceof TypePlaceholder) .map(z ->
* ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(
* HashSet::new))) .reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return
* a;}, (a,b) -> { a.addAll(b); return a;} ) ) .reduce(new HashSet<String>(),
* (a,b) -> { a.addAll(b); return a;} );
*
* Set<String> paraTypeVarNames = methodParaTypeVarNames;
* paraTypeVarNames.addAll(constructorParaTypeVarNames);
*
* Set<String> returnTypeVarNames = allClasses.stream().map(x ->
* x.getMethods().stream().filter(y -> y.getReturnType() instanceof
* TypePlaceholder) .map(z ->
* ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.
* toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;}
* ).get();
*
* Set<String> fieldTypeVarNames = allClasses.stream().map(x ->
* x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof
* TypePlaceholder) .map(z ->
* ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.
* toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;}
* ).get();
*
* returnTypeVarNames.addAll(fieldTypeVarNames);
*
* xConsSet = xConsSet.stream().map(x -> { //Hier muss ueberlegt werden, ob //1.
* alle Argument- und Retuntyp-Variablen in allen UnifyPairs // mit
* disableWildcardtable() werden. //2. alle Typvariablen mit Argument- oder
* Retuntyp-Variablen //in Beziehung auch auf disableWildcardtable() gesetzt
* werden muessen //PL 2018-04-23 if ((x.getLhsType() instanceof
* PlaceholderType)) { if (paraTypeVarNames.contains(x.getLhsType().getName()))
* { ((PlaceholderType)x.getLhsType()).setVariance((byte)1);
* ((PlaceholderType)x.getLhsType()).disableWildcardtable(); } if
* (returnTypeVarNames.contains(x.getLhsType().getName())) {
* ((PlaceholderType)x.getLhsType()).setVariance((byte)-1);
* ((PlaceholderType)x.getLhsType()).disableWildcardtable(); } } if
* ((x.getRhsType() instanceof PlaceholderType)) { if
* (paraTypeVarNames.contains(x.getRhsType().getName())) {
* ((PlaceholderType)x.getRhsType()).setVariance((byte)1);
* ((PlaceholderType)x.getRhsType()).disableWildcardtable(); } if
* (returnTypeVarNames.contains(x.getRhsType().getName())) {
* ((PlaceholderType)x.getRhsType()).setVariance((byte)-1);
* ((PlaceholderType)x.getRhsType()).disableWildcardtable(); } } return x;//HIER
* DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE JEWEILS
* ANDERE SEITE }).map( y -> { if ((y.getLhsType() instanceof PlaceholderType)
* && (y.getRhsType() instanceof PlaceholderType)) { if
* (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) {
* ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType(
* )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0
* && ((PlaceholderType)y.getRhsType()).getVariance() != 0) {
* ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType(
* )).getVariance()); } } return y; } )
* .collect(Collectors.toCollection(HashSet::new));
* varianceInheritance(xConsSet); Set<Set<UnifyPair>> result =
* unify.unifySequential(xConsSet, finiteClosure, logFile, log);
* //Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
* System.out.println("RESULT: " + result); logFile.write("RES: " +
* result.toString()+"\n"); logFile.flush(); results.addAll(result); }
*
* results = results.stream().map(x -> { Optional<Set<UnifyPair>> res = new
* RuleSet().subst(x.stream().map(y -> { if (y.getPairOp() ==
* PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT); return y;
* //alle Paare a <.? b erden durch a =. b ersetzt
* }).collect(Collectors.toCollection(HashSet::new))); if (res.isPresent())
* {//wenn subst ein Erg liefert wurde was veraendert return new
* TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure); } else
* return x; //wenn nichts veraendert wurde wird x zurueckgegeben
* }).collect(Collectors.toCollection(HashSet::new));
* System.out.println("RESULT Final: " + results); logFile.write("RES_FINAL: " +
* results.toString()+"\n"); logFile.flush(); logFile.write("PLACEHOLDERS: " +
* PlaceholderType.EXISTING_PLACEHOLDERS); logFile.flush(); } catch (IOException
* e) { e.printStackTrace(); } return results.stream().map((unifyPairs -> new
* ResultSet(UnifyTypeFactory.convert(unifyPairs,
* generateTPHMap(cons))))).collect(Collectors.toList()); }
*/
/**
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine
* Variance !=0 hat auf alle Typvariablen in Theta.
*
*
*/
/*
* private void varianceInheritance(Set<UnifyPair> eq) { Set<PlaceholderType>
* usedTPH = new HashSet<>(); Set<PlaceholderType> phSet = eq.stream().map(x ->
* { Set<PlaceholderType> pair = new HashSet<>(); if (x.getLhsType() instanceof
* PlaceholderType) pair.add((PlaceholderType)x.getLhsType()); if
* (x.getRhsType() instanceof PlaceholderType)
* pair.add((PlaceholderType)x.getRhsType()); return pair; }).reduce(new
* HashSet<>(), (a,b) -> { a.addAll(b); return a;} , (c,d) -> { c.addAll(d);
* return c;});
*
* ArrayList<PlaceholderType> phSetVariance = new ArrayList<>(phSet);
* phSetVariance.removeIf(x -> (x.getVariance() == 0));
* while(!phSetVariance.isEmpty()) { PlaceholderType a =
* phSetVariance.remove(0); usedTPH.add(a); //HashMap<PlaceholderType,Integer>
* ht = new HashMap<>(); //ht.put(a, a.getVariance()); Set<UnifyPair> eq1 = new
* HashSet<>(eq); eq1.removeIf(x -> !(x.getLhsType() instanceof PlaceholderType
* && ((PlaceholderType)x.getLhsType()).equals(a))); eq1.stream().forEach(x -> {
* x.getRhsType().accept(new distributeVariance(), a.getVariance());}); eq1 =
* new HashSet<>(eq); eq1.removeIf(x -> !(x.getRhsType() instanceof
* PlaceholderType && ((PlaceholderType)x.getRhsType()).equals(a)));
* eq1.stream().forEach(x -> { x.getLhsType().accept(new distributeVariance(),
* a.getVariance());}); phSetVariance = new ArrayList<>(phSet);
* phSetVariance.removeIf(x -> (x.getVariance() == 0 || usedTPH.contains(x))); }
* }
*/
/** /*
* TODO: can this be removed? * Generate log file writer
* */
* @param resultListener Writer logFile;
* @param logFile try {
* @return // TODO: check if this makes sense and does not only always use the first source file key...
* @throws ClassNotFoundException logFile = log ? new FileWriter(System.getProperty("user.dir") + "/logFiles/" + "log_" + sourceFiles.keySet().iterator().next().getName())
* @throws IOException : new OutputStreamWriter(new NullOutputStream());
*/ } catch (IOException ioException) {
public UnifyResultModelParallel typeInferenceAsync(UnifyResultListener resultListener, Writer logFile) System.err.println("IO Exception: " + ioException.getMessage());
throws ClassNotFoundException, IOException { logFile = new OutputStreamWriter(new NullOutputStream());
}
/* /*
* Gather all available (imported) classes from all parsed source files for putting them into the finite closure * Run the actual type inference process
*/ */
List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses(); TypeInference typeInference = new TypeInference(
for (File f : this.sourceFiles.keySet()) { getConstraints(),
SourceFile sf = sourceFiles.get(f); allClasses,
allClasses.addAll(getAvailableClasses(sf)); classLoader,
allClasses.addAll(sf.getClasses()); useResultModel,
allClasses.addAll(CompilationEnvironment.loadDefaultPackageClasses(f,classLoader).stream().map(ASTFactory::createClass).collect(Collectors.toList())); log,
} logFile,
statistics
);
return typeInference.execute(this.unificationServer);
}
/* private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException {
* Run the actual type inference process CompilationUnitContext tree = JavaTXParser.parse(sourceFile);
*/ SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(sourceFile, classLoader),
TypeInference typeInference = new TypeInference( new GenericsRegistry(null));
getConstraints(),
allClasses,
classLoader,
useResultModel,
log,
logFile,
statistics
);
return typeInference.executeAsync(resultListener);
}
public List<ResultSet> typeInference() throws ClassNotFoundException, IOException {
/*
* Gather all available (imported) classes from all parsed source files for putting them into the finite closure
*/
List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses();
for (File f : this.sourceFiles.keySet()) {
SourceFile sf = sourceFiles.get(f);
allClasses.addAll(getAvailableClasses(sf));
allClasses.addAll(sf.getClasses());
allClasses.addAll(CompilationEnvironment.loadDefaultPackageClasses(f,classLoader).stream().map(ASTFactory::createClass).toList());
}
/*
* Generate log file writer
*/
Writer logFile;
try {
// TODO: check if this makes sense and does not only always use the first source file key...
logFile = log ? new FileWriter(System.getProperty("user.dir") + "/logFiles/" + "log_" + sourceFiles.keySet().iterator().next().getName())
: new OutputStreamWriter(new NullOutputStream());
}
catch (IOException ioException) {
System.err.println("IO Exception: " + ioException.getMessage());
logFile = new OutputStreamWriter(new NullOutputStream());
}
/*
* Run the actual type inference process
*/
TypeInference typeInference = new TypeInference(
getConstraints(),
allClasses,
classLoader,
useResultModel,
log,
logFile,
statistics
);
return typeInference.execute(this.unificationServer);
}
private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException {
CompilationUnitContext tree = JavaTXParser.parse(sourceFile);
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(sourceFile, classLoader),
new GenericsRegistry(null));
return generator.convert(tree, environment.packageCrawler, classLoader); return generator.convert(tree, environment.packageCrawler, classLoader);
} }
public void generateBytecode() throws ClassNotFoundException, IOException { public void generateBytecode() throws ClassNotFoundException, IOException {
generateBytecode((File) null); generateBytecode((File) null);
} }
/** /**
* @param path - can be null, then class file output is in the same directory as the parsed source files * @param path - can be null, then class file output is in the same directory as the parsed source files
*/ */
public void generateBytecode(String path) throws ClassNotFoundException, IOException { public void generateBytecode(String path) throws ClassNotFoundException, IOException {
if(path != null) if (path != null)
generateBytecode(new File(path)); generateBytecode(new File(path));
else else
generateBytecode(); generateBytecode();
} }
/** /**
* @param path - output-Directory can be null, then class file output is in the same directory as the parsed source files * @param path - output-Directory can be null, then class file output is in the same directory as the parsed source files
*/ */
public void generateBytecode(File path) throws ClassNotFoundException, IOException { public void generateBytecode(File path) throws ClassNotFoundException, IOException {
List<ResultSet> typeinferenceResult = this.typeInference(); List<ResultSet> typeinferenceResult = this.typeInference();
generateBytecode(path, typeinferenceResult); generateBytecode(path, typeinferenceResult);
} }
private Map<File, List<GenericsResult>> generatedGenerics = new HashMap<>(); private final Map<File, List<GenericsResult>> generatedGenerics = new HashMap<>();
// TODO This is a temporary solution, we should integrate with the old API for getting Generics // TODO This is a temporary solution, we should integrate with the old API for getting Generics
public Map<File, List<GenericsResult>> getGeneratedGenerics() { public Map<File, List<GenericsResult>> getGeneratedGenerics() {
return generatedGenerics; return generatedGenerics;
} }
/** /**
* @param outputPath - can be null, then class file output is in the same directory as the parsed source files * @param outputPath - can be null, then class file output is in the same directory as the parsed source files
* @param typeinferenceResult * @param typeinferenceResult
* @throws IOException * @throws IOException
*/ */
public void generateBytecode(File outputPath, List<ResultSet> typeinferenceResult) throws IOException { public void generateBytecode(@Nullable File outputPath, List<ResultSet> typeinferenceResult) throws IOException {
for (File f : sourceFiles.keySet()) { for (File f : sourceFiles.keySet()) {
HashMap<JavaClassName, byte[]> classFiles = new HashMap<>(); SourceFile sf = sourceFiles.get(f);
SourceFile sf = sourceFiles.get(f); File path;
File path; if (outputPath == null) {
if(outputPath == null){ path = f.getParentFile(); //Set path to path of the parsed .jav file
path = f.getParentFile(); //Set path to path of the parsed .jav file } else {
}else{ path = new File(outputPath, sf.getPkgName().replace(".", "/")); //add package path to root path
path = new File(outputPath ,sf.getPkgName().replace(".","/")); //add package path to root path }
}
var converter = new ASTToTargetAST(typeinferenceResult, sf, classLoader); var converter = new ASTToTargetAST(typeinferenceResult, sf, classLoader);
var generatedClasses = new HashMap<JavaClassName, byte[]>(); var generatedClasses = new HashMap<JavaClassName, byte[]>();
for (var clazz : sf.getClasses()) { for (var clazz : sf.getClasses()) {
var codegen = new Codegen(converter.convert(clazz)); var codegen = new Codegen(converter.convert(clazz));
var code = codegen.generate(); var code = codegen.generate();
generatedClasses.put(clazz.getClassName(), code); generatedClasses.put(clazz.getClassName(), code);
converter.auxiliaries.forEach((name, source) -> { converter.auxiliaries.forEach((name, source) -> {
generatedClasses.put(new JavaClassName(name), source); generatedClasses.put(new JavaClassName(name), source);
}); });
} }
generatedGenerics.put(f, converter.computedGenerics()); generatedGenerics.put(f, converter.computedGenerics());
writeClassFile(generatedClasses, path); writeClassFile(generatedClasses, path);
} }
} }
private void writeClassFile(HashMap<JavaClassName, byte[]> classFiles, File path) throws IOException { private void writeClassFile(HashMap<JavaClassName, byte[]> classFiles, File path) throws IOException {
FileOutputStream output; FileOutputStream output;
for (JavaClassName name : classFiles.keySet()) { for (JavaClassName name : classFiles.keySet()) {
byte[] bytecode = classFiles.get(name); byte[] bytecode = classFiles.get(name);
System.out.println("generating " + name + ".class file ..."); System.out.println("generating " + name + ".class file ...");
// output = new FileOutputStream(new File(System.getProperty("user.dir") + // output = new FileOutputStream(new File(System.getProperty("user.dir") +
// "/testBytecode/generatedBC/" +name+".class")); // "/testBytecode/generatedBC/" +name+".class"));
File outputFile = new File(path, name.getClassName() + ".class"); File outputFile = new File(path, name.getClassName() + ".class");
outputFile.getAbsoluteFile().getParentFile().mkdirs(); outputFile.getAbsoluteFile().getParentFile().mkdirs();
output = new FileOutputStream(outputFile); output = new FileOutputStream(outputFile);
output.write(bytecode); output.write(bytecode);
output.close(); output.close();
System.out.println(name + ".class file generated"); System.out.println(name + ".class file generated");
} }
} }
public List<GenericGenratorResultForSourceFile> getGeneratedGenericResultsForAllSourceFiles(List<ResultSet> results) { public List<GenericGenratorResultForSourceFile> getGeneratedGenericResultsForAllSourceFiles(List<ResultSet> results) {
// FIXME // FIXME
return null; return null;
} }
/* PL 2020-03-17 mit TypeExchanger in FCGenerator.java zusammenfuehren */ /* PL 2020-03-17 mit TypeExchanger in FCGenerator.java zusammenfuehren */
/**
/**
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus. * Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus.
*/ */
private static class TypeExchanger implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric>{ private static class TypeExchanger implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric> {
private final HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs; private final HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs;
TypeExchanger(HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs){ TypeExchanger(HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs) {
this.gtvs = gtvs; this.gtvs = gtvs;
} }
@Override @Override
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) { public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){ for (RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()) {
params.add(param.acceptTV(this)); params.add(param.acceptTV(this));
} }
RefTypeOrTPHOrWildcardOrGeneric ret = new RefType(refType.getName(), params, new NullToken()); return new RefType(refType.getName(), params, new NullToken());
return ret;
} }
@Override @Override
public RefTypeOrTPHOrWildcardOrGeneric visit(SuperWildcardType superWildcardType) { public RefTypeOrTPHOrWildcardOrGeneric visit(SuperWildcardType superWildcardType) {
SuperWildcardType ret = new SuperWildcardType(superWildcardType.getInnerType().acceptTV(this), superWildcardType.getOffset()); return new SuperWildcardType(superWildcardType.getInnerType().acceptTV(this), superWildcardType.getOffset());
return ret;
} }
@Override @Override
public RefTypeOrTPHOrWildcardOrGeneric visit(TypePlaceholder typePlaceholder) { public RefTypeOrTPHOrWildcardOrGeneric visit(TypePlaceholder typePlaceholder) {
return typePlaceholder; //TypePlaceholder der vererbert wird kann bei der Vererbung nicht instanziert werden. return typePlaceholder; //TypePlaceholder der vererbert wird kann bei der Vererbung nicht instanziert werden.
} }
@Override @Override
public RefTypeOrTPHOrWildcardOrGeneric visit(ExtendsWildcardType extendsWildcardType) { public RefTypeOrTPHOrWildcardOrGeneric visit(ExtendsWildcardType extendsWildcardType) {
ExtendsWildcardType ret = new ExtendsWildcardType(extendsWildcardType.getInnerType().acceptTV(this), extendsWildcardType.getOffset()); return new ExtendsWildcardType(extendsWildcardType.getInnerType().acceptTV(this), extendsWildcardType.getOffset());
return ret;
} }
@Override @Override
public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) { public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) {
if(! gtvs.containsKey(genericRefType.getParsedName())) if (!gtvs.containsKey(genericRefType.getParsedName()))
throw new DebugException("Dieser Fall darf nicht auftreten"); throw new DebugException("Cannot visit unknown generic type variable!");
return gtvs.get(genericRefType.getParsedName()); return gtvs.get(genericRefType.getParsedName());
} }

View File

@@ -4,12 +4,12 @@ import de.dhbwstuttgart.server.SocketServer;
public class JavaTXServer { public class JavaTXServer {
JavaTXServer(int port) { JavaTXServer(int port) {
try { try {
SocketServer socketServer = new SocketServer(port); SocketServer socketServer = new SocketServer(port);
socketServer.start(); socketServer.start();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
}
} }
}
} }

View File

@@ -1,26 +1,21 @@
package de.dhbwstuttgart.server; package de.dhbwstuttgart.server;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import de.dhbwstuttgart.server.packet.ErrorPacket; import de.dhbwstuttgart.server.packet.*;
import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.server.packet.InvalidPacket;
import de.dhbwstuttgart.server.packet.MessagePacket;
import de.dhbwstuttgart.server.packet.PacketContainer;
import de.dhbwstuttgart.server.packet.UnifyRequestPacket;
import de.dhbwstuttgart.server.packet.UnifyResultPacket;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.enums.ReadyState;
import org.java_websocket.handshake.ServerHandshake;
import java.net.URI; import java.net.URI;
import java.util.List; import java.util.List;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.enums.ReadyState;
import org.java_websocket.handshake.ServerHandshake;
/** /**
@@ -28,111 +23,111 @@ import org.java_websocket.handshake.ServerHandshake;
*/ */
public class SocketClient extends WebSocketClient { public class SocketClient extends WebSocketClient {
// use a latch to wait until the connection is closed by the remote host // use a latch to wait until the connection is closed by the remote host
private final CountDownLatch closeLatch = new CountDownLatch(1); private final CountDownLatch closeLatch = new CountDownLatch(1);
// temporarily: The received unify result packet // temporarily: The received unify result packet
private UnifyResultPacket unifyResultPacket = null; private UnifyResultPacket unifyResultPacket = null;
public SocketClient(String url) { public SocketClient(String url) {
super(URI.create(url)); super(URI.create(url));
// make sure, the url is in a valid format // make sure, the url is in a valid format
final String regex = "^wss?://(\\w+(\\.\\w+)?)*:(\\d+)$"; final String regex = "^wss?://(\\w+(\\.\\w+)?)*:(\\d+)$";
final Matcher matcher = Pattern.compile(regex).matcher(url); final Matcher matcher = Pattern.compile(regex).matcher(url);
if (!matcher.find()) { if (!matcher.find()) {
throw new RuntimeException("Provided string \"" + url + "\" is not a valid server URL! Use pattern ws(s?)://<host.name>:<port>"); throw new RuntimeException("Provided string \"" + url + "\" is not a valid server URL! Use pattern ws(s?)://<host.name>:<port>");
} }
}
public SocketClient(String host, int port, boolean secure) {
super(URI.create(String.format("%s://%s:%d/", secure ? "wss" : "ws", host, port)));
}
/**
* The main method for connecting, requesting and waiting for the server to unify.
* This is synchronized to prevent multiple webSockets connections at the moment, but it is not called from any
* thread except the main thread right now and is not necessary at all, probably. Maybe remove it later
*/
synchronized public List<ResultSet> execute(
IFiniteClosure finiteClosure,
ConstraintSet<Pair> constraints,
ConstraintSet<UnifyPair> unifyConstraints
) throws JsonProcessingException {
try {
// wait for the connection to be set up
this.connectBlocking();
// make sure the connection has been established successfully
if (this.getReadyState() != ReadyState.OPEN) {
throw new RuntimeException("WebSocket Client could not connect to remote host at " + this.uri);
}
// send the unify task request
UnifyRequestPacket packet = UnifyRequestPacket.create(finiteClosure, constraints, unifyConstraints);
String json = PacketContainer.serialize(packet);
this.send(json);
// block the thread, until the connection is closed by the remote host (usually after sending the results)
this.waitUntilClosed();
// wait for the connection to fully close
this.closeBlocking();
} catch (InterruptedException exception) {
System.err.println("Interrupted: " + exception);
this.notifyAll();
} }
// detect error cases, in which no error was thrown, but also no result was sent back from the server public SocketClient(String host, int port, boolean secure) {
if (this.unifyResultPacket == null) { super(URI.create(String.format("%s://%s:%d/", secure ? "wss" : "ws", host, port)));
throw new RuntimeException("Did not receive server response but closed connection already");
} }
return unifyResultPacket.getResultSet(); /**
} * The main method for connecting, requesting and waiting for the server to unify.
* This is synchronized to prevent multiple webSockets connections at the moment, but it is not called from any
* thread except the main thread right now and is not necessary at all, probably. Maybe remove it later
*/
synchronized public List<ResultSet> execute(
IFiniteClosure finiteClosure,
ConstraintSet<Pair> constraints,
ConstraintSet<UnifyPair> unifyConstraints
) throws JsonProcessingException {
try {
// wait for the connection to be set up
this.connectBlocking();
// make sure the connection has been established successfully
if (this.getReadyState() != ReadyState.OPEN) {
throw new RuntimeException("WebSocket Client could not connect to remote host at " + this.uri);
}
/** // send the unify task request
* Specific client-side implementations to handle incomming packets UnifyRequestPacket packet = UnifyRequestPacket.create(finiteClosure, constraints, unifyConstraints);
*/ String json = PacketContainer.serialize(packet);
protected void handleReceivedPacket(IPacket packet) { this.send(json);
if (packet instanceof InvalidPacket) {
System.err.println("[socket] " + ((InvalidPacket) packet).error); // block the thread, until the connection is closed by the remote host (usually after sending the results)
} else if (packet instanceof MessagePacket) { this.waitUntilClosed();
System.out.println("[socket] " + ((MessagePacket) packet).message); // wait for the connection to fully close
} else if (packet instanceof ErrorPacket) { this.closeBlocking();
System.err.println("[socket] " + ((ErrorPacket) packet).error); } catch (InterruptedException exception) {
} else if (packet instanceof UnifyResultPacket) { System.err.println("Interrupted: " + exception);
System.out.println("[socket] Received unify result"); this.notifyAll();
unifyResultPacket = (UnifyResultPacket) packet; }
// detect error cases, in which no error was thrown, but also no result was sent back from the server
if (this.unifyResultPacket == null) {
throw new RuntimeException("Did not receive server response but closed connection already");
}
return unifyResultPacket.getResultSet();
} }
}
@Override /**
public void onOpen(ServerHandshake handshakedata) { * Specific client-side implementations to handle incomming packets
System.out.println("Connected to server with status " + handshakedata.getHttpStatus()); */
} protected void handleReceivedPacket(IPacket packet) {
if (packet instanceof InvalidPacket) {
System.err.println("[socket] " + ((InvalidPacket) packet).error);
} else if (packet instanceof MessagePacket) {
System.out.println("[socket] " + ((MessagePacket) packet).message);
} else if (packet instanceof ErrorPacket) {
System.err.println("[socket] " + ((ErrorPacket) packet).error);
} else if (packet instanceof UnifyResultPacket) {
System.out.println("[socket] Received unify result");
unifyResultPacket = (UnifyResultPacket) packet;
}
}
@Override @Override
public void onMessage(String message) { public void onOpen(ServerHandshake handshakedata) {
// System.out.println("received: " + message); System.out.println("Connected to server with status " + handshakedata.getHttpStatus());
IPacket packet = PacketContainer.deserialize(message); }
this.handleReceivedPacket(packet);
}
@Override @Override
public void onClose(int code, String reason, boolean remote) { public void onMessage(String message) {
System.out.println( // System.out.println("received: " + message);
"Disconnected from server " + IPacket packet = PacketContainer.deserialize(message);
"with code " + code + " " + this.handleReceivedPacket(packet);
(reason.isEmpty() ? "" : "and reason " + reason + " ") + }
"(closed by remote: " + remote + ")"
);
this.closeLatch.countDown();
}
@Override @Override
public void onError(Exception e) { public void onClose(int code, String reason, boolean remote) {
System.out.println("Error: " + e.getMessage()); System.out.println(
e.printStackTrace(); "Disconnected from server " +
} "with code " + code + " " +
(reason.isEmpty() ? "" : "and reason " + reason + " ") +
"(closed by remote: " + remote + ")"
);
this.closeLatch.countDown();
}
public void waitUntilClosed() throws InterruptedException { @Override
closeLatch.await(); public void onError(Exception e) {
} System.out.println("Error: " + e.getMessage());
e.printStackTrace();
}
public void waitUntilClosed() throws InterruptedException {
closeLatch.await();
}
} }

View File

@@ -6,12 +6,12 @@ package de.dhbwstuttgart.server;
*/ */
public class SocketData { public class SocketData {
public final String id; public final String id;
// used for the timeout of 10 seconds, until an unused open connection is automatically closed // used for the timeout of 10 seconds, until an unused open connection is automatically closed
public boolean hasSentTask = false; public boolean hasSentTask = false;
public SocketData(String id) { public SocketData(String id) {
this.id = id; this.id = id;
} }
} }

View File

@@ -1,138 +1,135 @@
package de.dhbwstuttgart.server; package de.dhbwstuttgart.server;
import de.dhbwstuttgart.server.packet.IPacket; import de.dhbwstuttgart.server.packet.*;
import de.dhbwstuttgart.server.packet.MessagePacket;
import de.dhbwstuttgart.server.packet.PacketContainer;
import de.dhbwstuttgart.server.packet.UnifyRequestPacket;
import de.dhbwstuttgart.server.packet.UnifyResultPacket;
import de.dhbwstuttgart.typeinference.TypeInference; import de.dhbwstuttgart.typeinference.TypeInference;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.java_websocket.WebSocket; import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake; import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer; import org.java_websocket.server.WebSocketServer;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class SocketServer extends WebSocketServer { public class SocketServer extends WebSocketServer {
private static final Logger log = LoggerFactory.getLogger(SocketServer.class); private static final Logger log = LoggerFactory.getLogger(SocketServer.class);
public SocketServer(int port) { public SocketServer(int port) {
super(new InetSocketAddress(port)); super(new InetSocketAddress(port));
} }
@Override @Override
public void onOpen(WebSocket webSocket, ClientHandshake clientHandshake) { public void onOpen(WebSocket webSocket, ClientHandshake clientHandshake) {
System.out.println("New connection: " + webSocket.getResourceDescriptor()); System.out.println("New connection: " + webSocket.getResourceDescriptor());
webSocket.setAttachment(new SocketData(UUID.randomUUID().toString())); webSocket.setAttachment(new SocketData(UUID.randomUUID().toString()));
try { try {
sendMessage(webSocket, "Welcome to the server!"); sendMessage(webSocket, "Welcome to the server!");
// wait 10 seconds for the client to send a task and close the connection, if nothing has been received until then // wait 10 seconds for the client to send a task and close the connection, if nothing has been received until then
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Runnable task = () -> { Runnable task = () -> {
if (webSocket.<SocketData>getAttachment().hasSentTask || !webSocket.isOpen()) { if (webSocket.<SocketData>getAttachment().hasSentTask || !webSocket.isOpen()) {
return; return;
}
sendMessage(webSocket, "No task received after 10 seconds. Closing connection...");
webSocket.close();
};
executor.schedule(task, 10, TimeUnit.SECONDS);
executor.shutdown();
// and finally, when your program wants to exit
} catch (Exception e) {
log.error("e: ", e);
webSocket.close(1, e.getMessage());
} }
sendMessage(webSocket, "No task received after 10 seconds. Closing connection...");
webSocket.close();
};
executor.schedule(task, 10, TimeUnit.SECONDS);
executor.shutdown();
// and finally, when your program wants to exit
} catch (Exception e) {
log.error("e: ", e);
webSocket.close(1, e.getMessage());
} }
}
@Override @Override
public void onClose(WebSocket webSocket, int code, String reason, boolean remote) { public void onClose(WebSocket webSocket, int code, String reason, boolean remote) {
System.out.println("Connection closed: " + webSocket.getResourceDescriptor()); System.out.println("Connection closed: " + webSocket.getResourceDescriptor());
System.out.println( System.out.println(
"Disconnected client " + webSocket.getResourceDescriptor() + " " + "Disconnected client " + webSocket.getResourceDescriptor() + " " +
"with code " + code + " " + "with code " + code + " " +
(reason.isEmpty() ? "" : "and reason " + reason + " ") + (reason.isEmpty() ? "" : "and reason " + reason + " ") +
"(closed by client: " + remote + ")" "(closed by client: " + remote + ")"
);
}
@Override
public void onMessage(WebSocket webSocket, String s) {
// System.out.println("Received: " + s.substring(0, 50));
IPacket reconstructedPacket = PacketContainer.deserialize(s);
this.onPacketReceived(webSocket, reconstructedPacket);
}
@Override
public void onError(WebSocket webSocket, Exception e) {
webSocket.close();
}
@Override
public void onStart() {
System.out.println("Websocket server started");
}
/**
* A shorthand method for sending informational messages to the client
*/
public void sendMessage(WebSocket webSocket, String text) {
try {
MessagePacket message = new MessagePacket();
message.message = text;
webSocket.send(PacketContainer.serialize(message));
} catch (Exception e) {
System.err.println("Failed to send message: " + text);
System.err.println(e);
}
}
/**
* The server-side implementation on how to handle certain packets when received
*/
private void onPacketReceived(WebSocket webSocket, IPacket packet) {
if (packet instanceof UnifyRequestPacket unifyRequestPacket) {
// TODO: this static property will be a problem once we send more than one request per server and
// should be replaced by a dynamic object property
PlaceholderType.EXISTING_PLACEHOLDERS.clear();
sendMessage(webSocket, "You requested a unify! Please wait until I calculated everything...");
System.out.println("Client " + webSocket.<SocketData>getAttachment().id + " requested a unification. Starting now...");
webSocket.<SocketData>getAttachment().hasSentTask = true;
try {
// start the unification algorithm from the received data
List<ResultSet> result = TypeInference.executeWithoutContext(
unifyRequestPacket.retrieveFiniteClosure(),
unifyRequestPacket.retrieveConstraints(),
unifyRequestPacket.retrieveUnifyConstraints()
); );
System.out.println("Finished unification for client " + webSocket.<SocketData>getAttachment().id);
sendMessage(webSocket, "Unification finished. Found " + result.size() + " result sets");
if (webSocket.isOpen()) {
UnifyResultPacket resultPacket = UnifyResultPacket.create(result);
webSocket.send(PacketContainer.serialize(resultPacket));
}
} catch (Exception e) {
System.err.println(e);
log.error("e: ", e);
}
webSocket.close();
} else {
sendMessage(webSocket, "The package of type " + packet.getClass().getName() + " is not handled by the server!");
} }
}
@Override
public void onMessage(WebSocket webSocket, String s) {
// System.out.println("Received: " + s.substring(0, 50));
IPacket reconstructedPacket = PacketContainer.deserialize(s);
this.onPacketReceived(webSocket, reconstructedPacket);
}
@Override
public void onError(WebSocket webSocket, Exception e) {
webSocket.close();
}
@Override
public void onStart() {
System.out.println("Websocket server started");
}
/**
* A shorthand method for sending informational messages to the client
*/
public void sendMessage(WebSocket webSocket, String text) {
try {
MessagePacket message = new MessagePacket();
message.message = text;
webSocket.send(PacketContainer.serialize(message));
} catch (Exception e) {
System.err.println("Failed to send message: " + text);
System.err.println(e);
}
}
/**
* The server-side implementation on how to handle certain packets when received
*/
private void onPacketReceived(WebSocket webSocket, IPacket packet) {
if (packet instanceof UnifyRequestPacket unifyRequestPacket) {
// TODO: this static property will be a problem once we send more than one request per server and
// should be replaced by a dynamic object property
PlaceholderType.EXISTING_PLACEHOLDERS.clear();
sendMessage(webSocket, "You requested a unify! Please wait until I calculated everything...");
System.out.println("Client " + webSocket.<SocketData>getAttachment().id + " requested a unification. Starting now...");
webSocket.<SocketData>getAttachment().hasSentTask = true;
try {
// start the unification algorithm from the received data
List<ResultSet> result = TypeInference.executeWithoutContext(
unifyRequestPacket.retrieveFiniteClosure(),
unifyRequestPacket.retrieveConstraints(),
unifyRequestPacket.retrieveUnifyConstraints()
);
System.out.println("Finished unification for client " + webSocket.<SocketData>getAttachment().id);
sendMessage(webSocket, "Unification finished. Found " + result.size() + " result sets");
if (webSocket.isOpen()) {
UnifyResultPacket resultPacket = UnifyResultPacket.create(result);
webSocket.send(PacketContainer.serialize(resultPacket));
}
} catch (Exception e) {
System.err.println(e);
log.error("e: ", e);
}
webSocket.close();
} else {
sendMessage(webSocket, "The package of type " + packet.getClass().getName() + " is not handled by the server!");
}
}
} }

View File

@@ -5,10 +5,10 @@ package de.dhbwstuttgart.server.packet;
*/ */
public class ErrorPacket implements IPacket { public class ErrorPacket implements IPacket {
/** /**
* The error endpoint for messages from the server, that should be logged out outputted * The error endpoint for messages from the server, that should be logged out outputted
*/ */
public String error; public String error;
} }

View File

@@ -7,12 +7,11 @@ package de.dhbwstuttgart.server.packet;
* - Have only serializable public properties (or disable them via jackson annotations) * - Have only serializable public properties (or disable them via jackson annotations)
* A packet should have, for easy usage and consisteny: * A packet should have, for easy usage and consisteny:
* - a static create() method * - a static create() method
*
*/ */
public interface IPacket { public interface IPacket {
interface IDataContainer<T> { interface IDataContainer<T> {
T toObject(); T toObject();
} }
} }

View File

@@ -5,9 +5,9 @@ package de.dhbwstuttgart.server.packet;
*/ */
public class InvalidPacket implements IPacket { public class InvalidPacket implements IPacket {
/** /**
* If available, the error that caused this package to appear * If available, the error that caused this package to appear
*/ */
public String error = "<unknown error>"; public String error = "<unknown error>";
} }

View File

@@ -5,9 +5,9 @@ package de.dhbwstuttgart.server.packet;
*/ */
public class MessagePacket implements IPacket { public class MessagePacket implements IPacket {
/** /**
* The informational message from the server, that should be logged out outputted * The informational message from the server, that should be logged out outputted
*/ */
public String message; public String message;
} }

View File

@@ -11,74 +11,74 @@ import com.fasterxml.jackson.databind.ObjectMapper;
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class PacketContainer { public class PacketContainer {
// The jackson serializer / deserializer tool // The jackson serializer / deserializer tool
private static final ObjectMapper objectMapper = new ObjectMapper(); private static final ObjectMapper objectMapper = new ObjectMapper();
/* /*
* The available packet types. The one type that is represented in the JSON should always be the ONLY non-null value. * The available packet types. The one type that is represented in the JSON should always be the ONLY non-null value.
* They have to be private (for the moment) to let jackson fill them in while deserializing * They have to be public (for the moment) to let jackson fill them in while deserializing
*/ */
public ErrorPacket errorPacket = null; public ErrorPacket errorPacket = null;
public MessagePacket messagePacket = null; public MessagePacket messagePacket = null;
public InvalidPacket invalidPacket = null; public InvalidPacket invalidPacket = null;
public UnifyRequestPacket unifyRequestPacket = null; public UnifyRequestPacket unifyRequestPacket = null;
public UnifyResultPacket unifyResultPacket = null; public UnifyResultPacket unifyResultPacket = null;
/** /**
* Generate the JSON string for the given packet * Generate the JSON string for the given packet
* *
* @param packet The packet to serialize * @param packet The packet to serialize
* @return The json representation of the packet * @return The json representation of the packet
*/ */
public static String serialize(IPacket packet) throws JsonProcessingException { public static String serialize(IPacket packet) throws JsonProcessingException {
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
PacketContainer container = new PacketContainer(); PacketContainer container = new PacketContainer();
if (packet instanceof ErrorPacket) if (packet instanceof ErrorPacket)
container.errorPacket = (ErrorPacket) packet; container.errorPacket = (ErrorPacket) packet;
else if (packet instanceof MessagePacket) else if (packet instanceof MessagePacket)
container.messagePacket = (MessagePacket) packet; container.messagePacket = (MessagePacket) packet;
else if (packet instanceof UnifyRequestPacket) else if (packet instanceof UnifyRequestPacket)
container.unifyRequestPacket = (UnifyRequestPacket) packet; container.unifyRequestPacket = (UnifyRequestPacket) packet;
else if (packet instanceof UnifyResultPacket) else if (packet instanceof UnifyResultPacket)
container.unifyResultPacket = (UnifyResultPacket) packet; container.unifyResultPacket = (UnifyResultPacket) packet;
// Add new packets here and in the deserialize method // Add new packets here and in the deserialize method
return objectMapper.writeValueAsString(container); return objectMapper.writeValueAsString(container);
} }
/** /**
* Use the JSON string to generate the matching packet object * Use the JSON string to generate the matching packet object
* *
* @param json The serialized representation of a packet container * @param json The serialized representation of a packet container
* @return The deserialized Packet object * @return The deserialized Packet object
*/ */
public static IPacket deserialize(String json) { public static IPacket deserialize(String json) {
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
try { try {
PacketContainer container = objectMapper.readValue(json, PacketContainer.class); PacketContainer container = objectMapper.readValue(json, PacketContainer.class);
if (container.errorPacket != null) if (container.errorPacket != null)
return container.errorPacket; return container.errorPacket;
if (container.messagePacket != null) if (container.messagePacket != null)
return container.messagePacket; return container.messagePacket;
if (container.invalidPacket != null) if (container.invalidPacket != null)
return container.invalidPacket; return container.invalidPacket;
if (container.unifyRequestPacket != null) if (container.unifyRequestPacket != null)
return container.unifyRequestPacket; return container.unifyRequestPacket;
if (container.unifyResultPacket != null) if (container.unifyResultPacket != null)
return container.unifyResultPacket; return container.unifyResultPacket;
// Add new packets here and in the serialize method // Add new packets here and in the serialize method
throw new RuntimeException("Cannot map received json to any known packet class"); throw new RuntimeException("Cannot map received json to any known packet class");
} catch (Exception e) { } catch (Exception e) {
InvalidPacket packet = new InvalidPacket(); InvalidPacket packet = new InvalidPacket();
packet.error = e.getMessage(); packet.error = e.getMessage();
return packet; return packet;
}
} }
}
} }

View File

@@ -14,35 +14,35 @@ import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
*/ */
public class UnifyRequestPacket implements IPacket { public class UnifyRequestPacket implements IPacket {
public SerializedFiniteClosure finiteClosure; public SerializedFiniteClosure finiteClosure;
public SerializedPairConstraintSet constraints; public SerializedPairConstraintSet constraints;
public SerializedUnifyConstraintSet unifyConstraints; public SerializedUnifyConstraintSet unifyConstraints;
public static UnifyRequestPacket create( public static UnifyRequestPacket create(
IFiniteClosure finiteClosure, IFiniteClosure finiteClosure,
ConstraintSet<Pair> constraints, ConstraintSet<Pair> constraints,
ConstraintSet<UnifyPair> unifyConstraints ConstraintSet<UnifyPair> unifyConstraints
) { ) {
UnifyRequestPacket packet = new UnifyRequestPacket(); UnifyRequestPacket packet = new UnifyRequestPacket();
packet.finiteClosure = SerializedFiniteClosure.create(finiteClosure); packet.finiteClosure = SerializedFiniteClosure.create(finiteClosure);
packet.constraints = SerializedPairConstraintSet.create(constraints); packet.constraints = SerializedPairConstraintSet.create(constraints);
packet.unifyConstraints = SerializedUnifyConstraintSet.create(unifyConstraints); packet.unifyConstraints = SerializedUnifyConstraintSet.create(unifyConstraints);
return packet; return packet;
} }
@JsonIgnore @JsonIgnore
public IFiniteClosure retrieveFiniteClosure() { public IFiniteClosure retrieveFiniteClosure() {
return this.finiteClosure.toObject(); return this.finiteClosure.toObject();
} }
@JsonIgnore @JsonIgnore
public ConstraintSet<Pair> retrieveConstraints() { public ConstraintSet<Pair> retrieveConstraints() {
return this.constraints.toObject(); return this.constraints.toObject();
} }
@JsonIgnore @JsonIgnore
public ConstraintSet<UnifyPair> retrieveUnifyConstraints() { public ConstraintSet<UnifyPair> retrieveUnifyConstraints() {
return this.unifyConstraints.toObject(); return this.unifyConstraints.toObject();
} }
} }

View File

@@ -3,6 +3,7 @@ package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.server.packet.dataContainers.SerializedResultSet; import de.dhbwstuttgart.server.packet.dataContainers.SerializedResultSet;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@@ -11,17 +12,17 @@ import java.util.List;
*/ */
public class UnifyResultPacket implements IPacket { public class UnifyResultPacket implements IPacket {
public SerializedResultSet[] results; public SerializedResultSet[] results;
public static UnifyResultPacket create(List<ResultSet> resultSets) { public static UnifyResultPacket create(List<ResultSet> resultSets) {
UnifyResultPacket serialized = new UnifyResultPacket(); UnifyResultPacket serialized = new UnifyResultPacket();
serialized.results = resultSets.stream().map(SerializedResultSet::create).toArray(SerializedResultSet[]::new); serialized.results = resultSets.stream().map(SerializedResultSet::create).toArray(SerializedResultSet[]::new);
return serialized; return serialized;
} }
@JsonIgnore @JsonIgnore
public List<ResultSet> getResultSet() { public List<ResultSet> getResultSet() {
return Arrays.stream(this.results).map(SerializedResultSet::toObject).toList(); return Arrays.stream(this.results).map(SerializedResultSet::toObject).toList();
} }
} }

View File

@@ -3,6 +3,7 @@ package de.dhbwstuttgart.server.packet.dataContainers;
import de.dhbwstuttgart.server.packet.IPacket; import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
@@ -12,19 +13,19 @@ import java.util.HashSet;
* @see IFiniteClosure * @see IFiniteClosure
*/ */
public class SerializedFiniteClosure implements IPacket.IDataContainer<IFiniteClosure> { public class SerializedFiniteClosure implements IPacket.IDataContainer<IFiniteClosure> {
public SerializedUnifyPair[] pairs; public SerializedUnifyPair[] pairs;
public static SerializedFiniteClosure create(IFiniteClosure finiteClosure) { public static SerializedFiniteClosure create(IFiniteClosure finiteClosure) {
SerializedFiniteClosure fc = new SerializedFiniteClosure(); SerializedFiniteClosure fc = new SerializedFiniteClosure();
fc.pairs = finiteClosure.getPairs().stream().map(SerializedUnifyPair::create).toArray(SerializedUnifyPair[]::new); fc.pairs = finiteClosure.getPairs().stream().map(SerializedUnifyPair::create).toArray(SerializedUnifyPair[]::new);
return fc; return fc;
} }
@Override @Override
public IFiniteClosure toObject() { public IFiniteClosure toObject() {
return new FiniteClosure( return new FiniteClosure(
new HashSet<>(Arrays.stream(pairs).map(SerializedUnifyPair::toObject).toList()), new HashSet<>(Arrays.stream(pairs).map(SerializedUnifyPair::toObject).toList()),
null null
); );
} }
} }

View File

@@ -12,26 +12,26 @@ import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
*/ */
public class SerializedPair implements IPacket.IDataContainer<Pair> { public class SerializedPair implements IPacket.IDataContainer<Pair> {
@JsonProperty("o") @JsonProperty("o")
public PairOperator operator; public PairOperator operator;
public SerializedTokenWrapper ta1; public SerializedTokenWrapper ta1;
public SerializedTokenWrapper ta2; public SerializedTokenWrapper ta2;
public static SerializedPair create(Pair pair) { public static SerializedPair create(Pair pair) {
SerializedPair sPair = new SerializedPair(); SerializedPair sPair = new SerializedPair();
sPair.operator = pair.GetOperator(); sPair.operator = pair.GetOperator();
sPair.ta1 = SerializedTokenWrapper.create(pair.TA1); sPair.ta1 = SerializedTokenWrapper.create(pair.TA1);
sPair.ta2 = SerializedTokenWrapper.create(pair.TA2); sPair.ta2 = SerializedTokenWrapper.create(pair.TA2);
return sPair; return sPair;
} }
@Override @Override
public Pair toObject() { public Pair toObject() {
return new Pair( return new Pair(
ta1.toObject(), ta1.toObject(),
ta2.toObject(), ta2.toObject(),
operator operator
); );
} }
} }

View File

@@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import de.dhbwstuttgart.server.packet.IPacket; import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@@ -17,66 +18,66 @@ import java.util.HashSet;
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class SerializedPairConstraint implements IPacket.IDataContainer<Constraint<Pair>> { public class SerializedPairConstraint implements IPacket.IDataContainer<Constraint<Pair>> {
// serialize recursive structure // serialize recursive structure
public static final HashMap<Constraint<Pair>, String> UNIQUE_CONSTRAINT_KEY_MAP = new HashMap<>(); public static final HashMap<Constraint<Pair>, String> UNIQUE_CONSTRAINT_KEY_MAP = new HashMap<>();
public static final HashMap<String, SerializedPairConstraint> UNIQUE_CONSTRAINT_MAP = new HashMap<>(); public static final HashMap<String, SerializedPairConstraint> UNIQUE_CONSTRAINT_MAP = new HashMap<>();
// deserialize recursive structure // deserialize recursive structure
private static final HashMap<String, Constraint<Pair>> UNIQUE_OBJECT_MAP = new HashMap<>(); private static final HashMap<String, Constraint<Pair>> UNIQUE_OBJECT_MAP = new HashMap<>();
@JsonProperty("i") @JsonProperty("i")
public boolean isInherited; public boolean isInherited;
@JsonProperty("u") @JsonProperty("u")
public String uniqueKey; public String uniqueKey;
@JsonProperty("e") @JsonProperty("e")
public String extendedConstraint = null; public String extendedConstraint = null;
@JsonProperty("m") @JsonProperty("m")
public SerializedPair[] methodSignatureConstraint; public SerializedPair[] methodSignatureConstraint;
@JsonProperty("c") @JsonProperty("c")
public SerializedPair[] constraintElements; public SerializedPair[] constraintElements;
public static SerializedPairConstraint create(Constraint<Pair> constraint) { public static SerializedPairConstraint create(Constraint<Pair> constraint) {
final String uniqueKey = UNIQUE_CONSTRAINT_KEY_MAP.getOrDefault(constraint, "_" + UNIQUE_CONSTRAINT_MAP.size()); final String uniqueKey = UNIQUE_CONSTRAINT_KEY_MAP.getOrDefault(constraint, "_" + UNIQUE_CONSTRAINT_MAP.size());
if (UNIQUE_CONSTRAINT_MAP.containsKey(uniqueKey)) { if (UNIQUE_CONSTRAINT_MAP.containsKey(uniqueKey)) {
return UNIQUE_CONSTRAINT_MAP.get(uniqueKey); return UNIQUE_CONSTRAINT_MAP.get(uniqueKey);
}
SerializedPairConstraint pairConstraint = new SerializedPairConstraint();
pairConstraint.uniqueKey = uniqueKey;
UNIQUE_CONSTRAINT_KEY_MAP.put(constraint, uniqueKey);
UNIQUE_CONSTRAINT_MAP.put(uniqueKey, pairConstraint);
pairConstraint.constraintElements = constraint.stream().map(SerializedPair::create).toArray(SerializedPair[]::new);
pairConstraint.isInherited = constraint.isInherited();
pairConstraint.methodSignatureConstraint = constraint.getmethodSignatureConstraint().stream().map(SerializedPair::create).toArray(SerializedPair[]::new);
if (constraint.getExtendConstraint() != null) {
pairConstraint.extendedConstraint = SerializedPairConstraint.create(constraint.getExtendConstraint()).uniqueKey;
}
return pairConstraint;
} }
SerializedPairConstraint pairConstraint = new SerializedPairConstraint(); @Override
pairConstraint.uniqueKey = uniqueKey; public Constraint<Pair> toObject() {
UNIQUE_CONSTRAINT_KEY_MAP.put(constraint, uniqueKey); if (UNIQUE_OBJECT_MAP.containsKey(uniqueKey)) {
UNIQUE_CONSTRAINT_MAP.put(uniqueKey, pairConstraint); return UNIQUE_OBJECT_MAP.get(uniqueKey);
}
pairConstraint.constraintElements = constraint.stream().map(SerializedPair::create).toArray(SerializedPair[]::new); Constraint<Pair> constraint = new Constraint<>();
pairConstraint.isInherited = constraint.isInherited(); UNIQUE_OBJECT_MAP.put(uniqueKey, constraint);
pairConstraint.methodSignatureConstraint = constraint.getmethodSignatureConstraint().stream().map(SerializedPair::create).toArray(SerializedPair[]::new);
if (constraint.getExtendConstraint() != null) { constraint.addAll(Arrays.stream(constraintElements).map(SerializedPair::toObject).toList());
pairConstraint.extendedConstraint = SerializedPairConstraint.create(constraint.getExtendConstraint()).uniqueKey; constraint.setIsInherited(isInherited);
constraint.setmethodSignatureConstraint(new HashSet<>(
Arrays.stream(methodSignatureConstraint).map(SerializedPair::toObject).toList()
));
SerializedPairConstraint extendedConstraint = this.extendedConstraint == null ? null :
SerializedPairConstraint.UNIQUE_CONSTRAINT_MAP.get(this.extendedConstraint);
if (extendedConstraint != null) {
constraint.setExtendConstraint(extendedConstraint.toObject());
}
return constraint;
} }
return pairConstraint;
}
@Override
public Constraint<Pair> toObject() {
if (UNIQUE_OBJECT_MAP.containsKey(uniqueKey)) {
return UNIQUE_OBJECT_MAP.get(uniqueKey);
}
Constraint<Pair> constraint = new Constraint<>();
UNIQUE_OBJECT_MAP.put(uniqueKey, constraint);
constraint.addAll(Arrays.stream(constraintElements).map(SerializedPair::toObject).toList());
constraint.setIsInherited(isInherited);
constraint.setmethodSignatureConstraint(new HashSet<>(
Arrays.stream(methodSignatureConstraint).map(SerializedPair::toObject).toList()
));
SerializedPairConstraint extendedConstraint = this.extendedConstraint == null ? null :
SerializedPairConstraint.UNIQUE_CONSTRAINT_MAP.get(this.extendedConstraint);
if (extendedConstraint != null) {
constraint.setExtendConstraint(extendedConstraint.toObject());
}
return constraint;
}
} }

View File

@@ -4,13 +4,8 @@ import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
import java.util.ArrayList;
import java.util.Arrays; import java.util.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/** /**
* Serializable container of * Serializable container of
@@ -19,42 +14,42 @@ import java.util.Set;
*/ */
public class SerializedPairConstraintSet implements IPacket.IDataContainer<ConstraintSet<Pair>> { public class SerializedPairConstraintSet implements IPacket.IDataContainer<ConstraintSet<Pair>> {
public SerializedPair[] undConstraints; public SerializedPair[] undConstraints;
public SerializedPairConstraint[][] oderConstraints; public SerializedPairConstraint[][] oderConstraints;
public Map<String, SerializedPairConstraint> uniqueConstraintMap = new HashMap<>(); public Map<String, SerializedPairConstraint> uniqueConstraintMap = new HashMap<>();
public static SerializedPairConstraintSet create(ConstraintSet<Pair> constraints) { public static SerializedPairConstraintSet create(ConstraintSet<Pair> constraints) {
SerializedPairConstraintSet constraintSet = new SerializedPairConstraintSet(); SerializedPairConstraintSet constraintSet = new SerializedPairConstraintSet();
constraintSet.undConstraints = constraints.getUndConstraints().stream().map(SerializedPair::create).toArray(SerializedPair[]::new); constraintSet.undConstraints = constraints.getUndConstraints().stream().map(SerializedPair::create).toArray(SerializedPair[]::new);
constraintSet.oderConstraints = constraints.getOderConstraints().stream().map(consSet -> constraintSet.oderConstraints = constraints.getOderConstraints().stream().map(consSet ->
consSet.stream().map(SerializedPairConstraint::create).toArray(SerializedPairConstraint[]::new) consSet.stream().map(SerializedPairConstraint::create).toArray(SerializedPairConstraint[]::new)
).toArray(SerializedPairConstraint[][]::new); ).toArray(SerializedPairConstraint[][]::new);
// add all the gathered constraints to a serializable property // add all the gathered constraints to a serializable property
constraintSet.uniqueConstraintMap.putAll(SerializedPairConstraint.UNIQUE_CONSTRAINT_MAP); constraintSet.uniqueConstraintMap.putAll(SerializedPairConstraint.UNIQUE_CONSTRAINT_MAP);
return constraintSet; return constraintSet;
} }
@Override @Override
public ConstraintSet<Pair> toObject() { public ConstraintSet<Pair> toObject() {
ConstraintSet<Pair> consSet = new ConstraintSet<>(); ConstraintSet<Pair> consSet = new ConstraintSet<>();
// read all the constraints from the serializable property // read all the constraints from the serializable property
SerializedPairConstraint.UNIQUE_CONSTRAINT_MAP.putAll(this.uniqueConstraintMap); SerializedPairConstraint.UNIQUE_CONSTRAINT_MAP.putAll(this.uniqueConstraintMap);
Constraint<Pair> undCons = new Constraint<>(); Constraint<Pair> undCons = new Constraint<>();
undCons.addAll(Arrays.stream(undConstraints).map(SerializedPair::toObject).toList()); undCons.addAll(Arrays.stream(undConstraints).map(SerializedPair::toObject).toList());
consSet.addAllUndConstraint(undCons); consSet.addAllUndConstraint(undCons);
List<Set<Constraint<Pair>>> oderCons = new ArrayList<>(Arrays.stream(oderConstraints).map(cons -> List<Set<Constraint<Pair>>> oderCons = new ArrayList<>(Arrays.stream(oderConstraints).map(cons ->
new HashSet<>( new HashSet<>(
Arrays.stream(cons).map(SerializedPairConstraint::toObject).toList() Arrays.stream(cons).map(SerializedPairConstraint::toObject).toList()
) )
).toList()); ).toList());
consSet.addAllOderConstraint(oderCons); consSet.addAllOderConstraint(oderCons);
return consSet; return consSet;
} }
} }

View File

@@ -8,11 +8,7 @@ import de.dhbwstuttgart.server.packet.dataContainers.resultPairs.SerializedPairT
import de.dhbwstuttgart.server.packet.dataContainers.resultPairs.SerializedPairTPHequalRefTypeOrWildcardType; import de.dhbwstuttgart.server.packet.dataContainers.resultPairs.SerializedPairTPHequalRefTypeOrWildcardType;
import de.dhbwstuttgart.server.packet.dataContainers.resultPairs.SerializedPairTPHsmallerTPH; import de.dhbwstuttgart.server.packet.dataContainers.resultPairs.SerializedPairTPHsmallerTPH;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.typeinference.result.PairNoResult; import de.dhbwstuttgart.typeinference.result.*;
import de.dhbwstuttgart.typeinference.result.PairTPHEqualTPH;
import de.dhbwstuttgart.typeinference.result.PairTPHequalRefTypeOrWildcardType;
import de.dhbwstuttgart.typeinference.result.PairTPHsmallerTPH;
import de.dhbwstuttgart.typeinference.result.ResultPair;
/** /**
* Serializable container of * Serializable container of
@@ -22,42 +18,42 @@ import de.dhbwstuttgart.typeinference.result.ResultPair;
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class SerializedResultPairWrapper implements IPacket.IDataContainer<ResultPair<RefTypeOrTPHOrWildcardOrGeneric, RefTypeOrTPHOrWildcardOrGeneric>> { public class SerializedResultPairWrapper implements IPacket.IDataContainer<ResultPair<RefTypeOrTPHOrWildcardOrGeneric, RefTypeOrTPHOrWildcardOrGeneric>> {
@JsonProperty("nr") @JsonProperty("nr")
public SerializedPairNoResult noResult = null; public SerializedPairNoResult noResult = null;
@JsonProperty("teo") @JsonProperty("teo")
public SerializedPairTPHequalRefTypeOrWildcardType tphEqualOther = null; public SerializedPairTPHequalRefTypeOrWildcardType tphEqualOther = null;
@JsonProperty("tet") @JsonProperty("tet")
public SerializedPairTPHEqualTPH tphEqualTph = null; public SerializedPairTPHEqualTPH tphEqualTph = null;
@JsonProperty("tst") @JsonProperty("tst")
public SerializedPairTPHsmallerTPH tphSmallerTPH = null; public SerializedPairTPHsmallerTPH tphSmallerTPH = null;
public static <A extends RefTypeOrTPHOrWildcardOrGeneric, B extends RefTypeOrTPHOrWildcardOrGeneric> SerializedResultPairWrapper create(ResultPair<A, B> pair) { public static <A extends RefTypeOrTPHOrWildcardOrGeneric, B extends RefTypeOrTPHOrWildcardOrGeneric> SerializedResultPairWrapper create(ResultPair<A, B> pair) {
SerializedResultPairWrapper serialized = new SerializedResultPairWrapper(); SerializedResultPairWrapper serialized = new SerializedResultPairWrapper();
if (pair instanceof PairNoResult noResult) if (pair instanceof PairNoResult noResult)
serialized.noResult = SerializedPairNoResult.create(noResult); serialized.noResult = SerializedPairNoResult.create(noResult);
else if (pair instanceof PairTPHequalRefTypeOrWildcardType tphEqualOther) else if (pair instanceof PairTPHequalRefTypeOrWildcardType tphEqualOther)
serialized.tphEqualOther = SerializedPairTPHequalRefTypeOrWildcardType.create(tphEqualOther); serialized.tphEqualOther = SerializedPairTPHequalRefTypeOrWildcardType.create(tphEqualOther);
else if (pair instanceof PairTPHEqualTPH tphEqualTph) else if (pair instanceof PairTPHEqualTPH tphEqualTph)
serialized.tphEqualTph = SerializedPairTPHEqualTPH.create(tphEqualTph); serialized.tphEqualTph = SerializedPairTPHEqualTPH.create(tphEqualTph);
else if (pair instanceof PairTPHsmallerTPH tphSmallerTPH) else if (pair instanceof PairTPHsmallerTPH tphSmallerTPH)
serialized.tphSmallerTPH = SerializedPairTPHsmallerTPH.create(tphSmallerTPH); serialized.tphSmallerTPH = SerializedPairTPHsmallerTPH.create(tphSmallerTPH);
return serialized; return serialized;
} }
@Override @Override
@SuppressWarnings("rawtypes") // this is not optimal, but we have to conform to interface specifications @SuppressWarnings("rawtypes") // this is not optimal, but we have to conform to interface specifications
public ResultPair toObject() { public ResultPair toObject() {
if (noResult != null) if (noResult != null)
return noResult.toObject(); return noResult.toObject();
else if (tphEqualOther != null) else if (tphEqualOther != null)
return tphEqualOther.toObject(); return tphEqualOther.toObject();
else if (tphEqualTph != null) else if (tphEqualTph != null)
return tphEqualTph.toObject(); return tphEqualTph.toObject();
else if (tphSmallerTPH != null) else if (tphSmallerTPH != null)
return tphSmallerTPH.toObject(); return tphSmallerTPH.toObject();
return null; return null;
} }
} }

View File

@@ -2,6 +2,7 @@ package de.dhbwstuttgart.server.packet.dataContainers;
import de.dhbwstuttgart.server.packet.IPacket; import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
@@ -12,20 +13,20 @@ import java.util.HashSet;
*/ */
public class SerializedResultSet implements IPacket.IDataContainer<ResultSet> { public class SerializedResultSet implements IPacket.IDataContainer<ResultSet> {
public SerializedResultPairWrapper[] results; public SerializedResultPairWrapper[] results;
public static SerializedResultSet create(ResultSet resultSet) { public static SerializedResultSet create(ResultSet resultSet) {
SerializedResultSet serialized = new SerializedResultSet(); SerializedResultSet serialized = new SerializedResultSet();
serialized.results = resultSet.results.stream().map(SerializedResultPairWrapper::create).toArray(SerializedResultPairWrapper[]::new); serialized.results = resultSet.results.stream().map(SerializedResultPairWrapper::create).toArray(SerializedResultPairWrapper[]::new);
return serialized; return serialized;
} }
public ResultSet toObject() { public ResultSet toObject() {
return new ResultSet( return new ResultSet(
new HashSet<>( new HashSet<>(
Arrays.stream(this.results).map(SerializedResultPairWrapper::toObject).toList() Arrays.stream(this.results).map(SerializedResultPairWrapper::toObject).toList()
) )
); );
} }
} }

View File

@@ -3,19 +3,9 @@ package de.dhbwstuttgart.server.packet.dataContainers;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import de.dhbwstuttgart.server.packet.IPacket; import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.server.packet.dataContainers.token.SerializedExtendsWildcardType; import de.dhbwstuttgart.server.packet.dataContainers.token.*;
import de.dhbwstuttgart.server.packet.dataContainers.token.SerializedGenericRefType;
import de.dhbwstuttgart.server.packet.dataContainers.token.SerializedPlaceholderType;
import de.dhbwstuttgart.server.packet.dataContainers.token.SerializedRefType;
import de.dhbwstuttgart.server.packet.dataContainers.token.SerializedSuperWildcardType;
import de.dhbwstuttgart.server.packet.dataContainers.token.SerializedVoidType;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.syntaxtree.type.*;
/** /**
* Serializable container of * Serializable container of
@@ -25,48 +15,48 @@ import de.dhbwstuttgart.syntaxtree.type.Void;
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class SerializedTokenWrapper implements IPacket.IDataContainer<RefTypeOrTPHOrWildcardOrGeneric> { public class SerializedTokenWrapper implements IPacket.IDataContainer<RefTypeOrTPHOrWildcardOrGeneric> {
@JsonProperty("ew") @JsonProperty("ew")
public SerializedExtendsWildcardType extendsWildcardType = null; public SerializedExtendsWildcardType extendsWildcardType = null;
@JsonProperty("gr") @JsonProperty("gr")
public SerializedGenericRefType genericRefType = null; public SerializedGenericRefType genericRefType = null;
@JsonProperty("p") @JsonProperty("p")
public SerializedPlaceholderType placeholderType = null; public SerializedPlaceholderType placeholderType = null;
@JsonProperty("r") @JsonProperty("r")
public SerializedRefType refType = null; public SerializedRefType refType = null;
@JsonProperty("sw") @JsonProperty("sw")
public SerializedSuperWildcardType superWildcardType = null; public SerializedSuperWildcardType superWildcardType = null;
@JsonProperty("v") @JsonProperty("v")
public SerializedVoidType voidType = null; public SerializedVoidType voidType = null;
public static SerializedTokenWrapper create(RefTypeOrTPHOrWildcardOrGeneric type) { public static SerializedTokenWrapper create(RefTypeOrTPHOrWildcardOrGeneric type) {
SerializedTokenWrapper wrapper = new SerializedTokenWrapper(); SerializedTokenWrapper wrapper = new SerializedTokenWrapper();
if (type instanceof ExtendsWildcardType) if (type instanceof ExtendsWildcardType)
wrapper.extendsWildcardType = SerializedExtendsWildcardType.create((ExtendsWildcardType) type); wrapper.extendsWildcardType = SerializedExtendsWildcardType.create((ExtendsWildcardType) type);
else if (type instanceof GenericRefType) else if (type instanceof GenericRefType)
wrapper.genericRefType = SerializedGenericRefType.create((GenericRefType) type); wrapper.genericRefType = SerializedGenericRefType.create((GenericRefType) type);
else if (type instanceof TypePlaceholder) else if (type instanceof TypePlaceholder)
wrapper.placeholderType = SerializedPlaceholderType.create((TypePlaceholder) type); wrapper.placeholderType = SerializedPlaceholderType.create((TypePlaceholder) type);
else if (type instanceof Void) else if (type instanceof Void)
wrapper.voidType = SerializedVoidType.create((Void) type); wrapper.voidType = SerializedVoidType.create((Void) type);
else if (type instanceof RefType) else if (type instanceof RefType)
wrapper.refType = SerializedRefType.create((RefType) type); wrapper.refType = SerializedRefType.create((RefType) type);
else if (type instanceof SuperWildcardType) else if (type instanceof SuperWildcardType)
wrapper.superWildcardType = SerializedSuperWildcardType.create((SuperWildcardType) type); wrapper.superWildcardType = SerializedSuperWildcardType.create((SuperWildcardType) type);
return wrapper; return wrapper;
} }
@Override @Override
public RefTypeOrTPHOrWildcardOrGeneric toObject() { public RefTypeOrTPHOrWildcardOrGeneric toObject() {
if (extendsWildcardType != null) return extendsWildcardType.toObject(); if (extendsWildcardType != null) return extendsWildcardType.toObject();
if (genericRefType != null) return genericRefType.toObject(); if (genericRefType != null) return genericRefType.toObject();
if (placeholderType != null) return placeholderType.toObject(); if (placeholderType != null) return placeholderType.toObject();
if (refType != null) return refType.toObject(); if (refType != null) return refType.toObject();
if (superWildcardType != null) return superWildcardType.toObject(); if (superWildcardType != null) return superWildcardType.toObject();
if (voidType != null) return voidType.toObject(); if (voidType != null) return voidType.toObject();
return null; return null;
} }
} }

View File

@@ -4,11 +4,8 @@ import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import java.util.ArrayList;
import java.util.Arrays; import java.util.*;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/** /**
* Serializable container of * Serializable container of
@@ -17,33 +14,33 @@ import java.util.Set;
*/ */
public class SerializedUnifyConstraintSet implements IPacket.IDataContainer<ConstraintSet<UnifyPair>> { public class SerializedUnifyConstraintSet implements IPacket.IDataContainer<ConstraintSet<UnifyPair>> {
public SerializedUnifyPair[] undConstraints; public SerializedUnifyPair[] undConstraints;
public SerializedUnifyPairConstraint[][] oderConstraints; public SerializedUnifyPairConstraint[][] oderConstraints;
public static SerializedUnifyConstraintSet create(ConstraintSet<UnifyPair> unifyCons) { public static SerializedUnifyConstraintSet create(ConstraintSet<UnifyPair> unifyCons) {
SerializedUnifyConstraintSet constraintSet = new SerializedUnifyConstraintSet(); SerializedUnifyConstraintSet constraintSet = new SerializedUnifyConstraintSet();
constraintSet.undConstraints = unifyCons.getUndConstraints().stream().map(SerializedUnifyPair::create).toArray(SerializedUnifyPair[]::new); constraintSet.undConstraints = unifyCons.getUndConstraints().stream().map(SerializedUnifyPair::create).toArray(SerializedUnifyPair[]::new);
constraintSet.oderConstraints = unifyCons.getOderConstraints().stream().map(constraints -> constraintSet.oderConstraints = unifyCons.getOderConstraints().stream().map(constraints ->
constraints.stream().map(SerializedUnifyPairConstraint::create).toArray(SerializedUnifyPairConstraint[]::new) constraints.stream().map(SerializedUnifyPairConstraint::create).toArray(SerializedUnifyPairConstraint[]::new)
).toArray(SerializedUnifyPairConstraint[][]::new); ).toArray(SerializedUnifyPairConstraint[][]::new);
return constraintSet; return constraintSet;
} }
@Override @Override
public ConstraintSet<UnifyPair> toObject() { public ConstraintSet<UnifyPair> toObject() {
ConstraintSet<UnifyPair> consSet = new ConstraintSet<>(); ConstraintSet<UnifyPair> consSet = new ConstraintSet<>();
Constraint<UnifyPair> undCons = new Constraint<>(); Constraint<UnifyPair> undCons = new Constraint<>();
undCons.addAll(Arrays.stream(undConstraints).map(SerializedUnifyPair::toObject).toList()); undCons.addAll(Arrays.stream(undConstraints).map(SerializedUnifyPair::toObject).toList());
consSet.addAllUndConstraint(undCons); consSet.addAllUndConstraint(undCons);
List<Set<Constraint<UnifyPair>>> oderCons = new ArrayList<>(Arrays.stream(oderConstraints).map(oderConsSet -> List<Set<Constraint<UnifyPair>>> oderCons = new ArrayList<>(Arrays.stream(oderConstraints).map(oderConsSet ->
new HashSet<>( new HashSet<>(
Arrays.stream(oderConsSet).map(SerializedUnifyPairConstraint::toObject).toList() Arrays.stream(oderConsSet).map(SerializedUnifyPairConstraint::toObject).toList()
) )
).toList()); ).toList());
consSet.addAllOderConstraint(oderCons); consSet.addAllOderConstraint(oderCons);
return consSet; return consSet;
} }
} }

View File

@@ -12,21 +12,21 @@ import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
*/ */
public class SerializedUnifyPair implements IPacket.IDataContainer<UnifyPair> { public class SerializedUnifyPair implements IPacket.IDataContainer<UnifyPair> {
public SerializedUnifyTypeWrapper lhs; public SerializedUnifyTypeWrapper lhs;
public SerializedUnifyTypeWrapper rhs; public SerializedUnifyTypeWrapper rhs;
@JsonProperty("o") @JsonProperty("o")
public PairOperator operator; public PairOperator operator;
public static SerializedUnifyPair create(UnifyPair unifyPair) { public static SerializedUnifyPair create(UnifyPair unifyPair) {
SerializedUnifyPair pair = new SerializedUnifyPair(); SerializedUnifyPair pair = new SerializedUnifyPair();
pair.lhs = SerializedUnifyTypeWrapper.create(unifyPair.getLhsType()); pair.lhs = SerializedUnifyTypeWrapper.create(unifyPair.getLhsType());
pair.rhs = SerializedUnifyTypeWrapper.create(unifyPair.getRhsType()); pair.rhs = SerializedUnifyTypeWrapper.create(unifyPair.getRhsType());
pair.operator = unifyPair.getPairOp(); pair.operator = unifyPair.getPairOp();
return pair; return pair;
} }
@Override @Override
public UnifyPair toObject() { public UnifyPair toObject() {
return new UnifyPair(lhs.toObject(), rhs.toObject(), operator); return new UnifyPair(lhs.toObject(), rhs.toObject(), operator);
} }
} }

View File

@@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import de.dhbwstuttgart.server.packet.IPacket; import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
@@ -16,37 +17,37 @@ import java.util.HashSet;
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class SerializedUnifyPairConstraint implements IPacket.IDataContainer<Constraint<UnifyPair>> { public class SerializedUnifyPairConstraint implements IPacket.IDataContainer<Constraint<UnifyPair>> {
@JsonProperty("i") @JsonProperty("i")
public boolean isInherited; public boolean isInherited;
@JsonProperty("ec") @JsonProperty("ec")
public SerializedUnifyPairConstraint extendedConstraint = null; public SerializedUnifyPairConstraint extendedConstraint = null;
@JsonProperty("p") @JsonProperty("p")
public SerializedUnifyPair[] methodSignatureConstraints; public SerializedUnifyPair[] methodSignatureConstraints;
@JsonProperty("c") @JsonProperty("c")
public SerializedUnifyPair[] constraintElements; public SerializedUnifyPair[] constraintElements;
public static SerializedUnifyPairConstraint create(Constraint<UnifyPair> constraint) { public static SerializedUnifyPairConstraint create(Constraint<UnifyPair> constraint) {
SerializedUnifyPairConstraint cons = new SerializedUnifyPairConstraint(); SerializedUnifyPairConstraint cons = new SerializedUnifyPairConstraint();
cons.constraintElements = constraint.stream().map(SerializedUnifyPair::create).toArray(SerializedUnifyPair[]::new); cons.constraintElements = constraint.stream().map(SerializedUnifyPair::create).toArray(SerializedUnifyPair[]::new);
cons.isInherited = constraint.isInherited(); cons.isInherited = constraint.isInherited();
if (constraint.getExtendConstraint() != null) { if (constraint.getExtendConstraint() != null) {
cons.extendedConstraint = SerializedUnifyPairConstraint.create(constraint.getExtendConstraint()); cons.extendedConstraint = SerializedUnifyPairConstraint.create(constraint.getExtendConstraint());
}
cons.methodSignatureConstraints = constraint.getmethodSignatureConstraint().stream().map(SerializedUnifyPair::create).toArray(SerializedUnifyPair[]::new);
return cons;
} }
cons.methodSignatureConstraints = constraint.getmethodSignatureConstraint().stream().map(SerializedUnifyPair::create).toArray(SerializedUnifyPair[]::new);
return cons;
}
@Override @Override
public Constraint<UnifyPair> toObject() { public Constraint<UnifyPair> toObject() {
Constraint<UnifyPair> cons = new Constraint<>(); Constraint<UnifyPair> cons = new Constraint<>();
cons.addAll(Arrays.stream(constraintElements).map(SerializedUnifyPair::toObject).toList()); cons.addAll(Arrays.stream(constraintElements).map(SerializedUnifyPair::toObject).toList());
cons.setIsInherited(isInherited); cons.setIsInherited(isInherited);
if (extendedConstraint != null) { if (extendedConstraint != null) {
cons.setExtendConstraint(extendedConstraint.toObject()); cons.setExtendConstraint(extendedConstraint.toObject());
}
cons.setmethodSignatureConstraint(new HashSet<>(Arrays.stream(methodSignatureConstraints).map(SerializedUnifyPair::toObject).toList()));
return cons;
} }
cons.setmethodSignatureConstraint(new HashSet<>(Arrays.stream(methodSignatureConstraints).map(SerializedUnifyPair::toObject).toList()));
return cons;
}
} }

View File

@@ -3,17 +3,8 @@ package de.dhbwstuttgart.server.packet.dataContainers;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import de.dhbwstuttgart.server.packet.IPacket; import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.server.packet.dataContainers.unifyType.SerializedExtendsType; import de.dhbwstuttgart.server.packet.dataContainers.unifyType.*;
import de.dhbwstuttgart.server.packet.dataContainers.unifyType.SerializedFunNType; import de.dhbwstuttgart.typeinference.unify.model.*;
import de.dhbwstuttgart.server.packet.dataContainers.unifyType.SerializedPlaceholderType;
import de.dhbwstuttgart.server.packet.dataContainers.unifyType.SerializedReferenceType;
import de.dhbwstuttgart.server.packet.dataContainers.unifyType.SerializedSuperType;
import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
import de.dhbwstuttgart.typeinference.unify.model.FunNType;
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.UnifyType;
/** /**
* Serializable container of * Serializable container of
@@ -23,43 +14,43 @@ import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class SerializedUnifyTypeWrapper implements IPacket.IDataContainer<UnifyType> { public class SerializedUnifyTypeWrapper implements IPacket.IDataContainer<UnifyType> {
@JsonProperty("e") @JsonProperty("e")
public SerializedExtendsType extendsType = null; public SerializedExtendsType extendsType = null;
@JsonProperty("s") @JsonProperty("s")
public SerializedSuperType superType = null; public SerializedSuperType superType = null;
@JsonProperty("r") @JsonProperty("r")
public SerializedReferenceType referenceType = null; public SerializedReferenceType referenceType = null;
@JsonProperty("f") @JsonProperty("f")
public SerializedFunNType funNType = null; public SerializedFunNType funNType = null;
@JsonProperty("p") @JsonProperty("p")
public SerializedPlaceholderType placeholderType = null; public SerializedPlaceholderType placeholderType = null;
public static SerializedUnifyTypeWrapper create(UnifyType unifyType) { public static SerializedUnifyTypeWrapper create(UnifyType unifyType) {
SerializedUnifyTypeWrapper wrapper = new SerializedUnifyTypeWrapper(); SerializedUnifyTypeWrapper wrapper = new SerializedUnifyTypeWrapper();
if (unifyType instanceof ExtendsType) if (unifyType instanceof ExtendsType)
wrapper.extendsType = SerializedExtendsType.create((ExtendsType) unifyType); wrapper.extendsType = SerializedExtendsType.create((ExtendsType) unifyType);
else if (unifyType instanceof SuperType) else if (unifyType instanceof SuperType)
wrapper.superType = SerializedSuperType.create((SuperType) unifyType); wrapper.superType = SerializedSuperType.create((SuperType) unifyType);
else if (unifyType instanceof ReferenceType) else if (unifyType instanceof ReferenceType)
wrapper.referenceType = SerializedReferenceType.create((ReferenceType) unifyType); wrapper.referenceType = SerializedReferenceType.create((ReferenceType) unifyType);
else if (unifyType instanceof FunNType) else if (unifyType instanceof FunNType)
wrapper.funNType = SerializedFunNType.create((FunNType) unifyType); wrapper.funNType = SerializedFunNType.create((FunNType) unifyType);
else if (unifyType instanceof PlaceholderType) else if (unifyType instanceof PlaceholderType)
wrapper.placeholderType = SerializedPlaceholderType.create((PlaceholderType) unifyType); wrapper.placeholderType = SerializedPlaceholderType.create((PlaceholderType) unifyType);
return wrapper; return wrapper;
} }
@Override @Override
public UnifyType toObject() { public UnifyType toObject() {
if (extendsType != null) return extendsType.toObject(); if (extendsType != null) return extendsType.toObject();
if (superType != null) return superType.toObject(); if (superType != null) return superType.toObject();
if (referenceType != null) return referenceType.toObject(); if (referenceType != null) return referenceType.toObject();
if (funNType != null) return funNType.toObject(); if (funNType != null) return funNType.toObject();
if (placeholderType != null) return placeholderType.toObject(); if (placeholderType != null) return placeholderType.toObject();
return null; return null;
} }
} }

View File

@@ -12,27 +12,27 @@ import de.dhbwstuttgart.typeinference.result.PairNoResult;
*/ */
public class SerializedPairNoResult implements IPacket.IDataContainer<PairNoResult> { public class SerializedPairNoResult implements IPacket.IDataContainer<PairNoResult> {
@JsonProperty("l") @JsonProperty("l")
public SerializedTokenWrapper left; public SerializedTokenWrapper left;
@JsonProperty("r") @JsonProperty("r")
public SerializedTokenWrapper right; public SerializedTokenWrapper right;
/** /**
* Use a static create method to leave the default constructor and simplify list conversions * Use a static create method to leave the default constructor and simplify list conversions
*/ */
public static SerializedPairNoResult create(PairNoResult pair) { public static SerializedPairNoResult create(PairNoResult pair) {
SerializedPairNoResult serialized = new SerializedPairNoResult(); SerializedPairNoResult serialized = new SerializedPairNoResult();
serialized.left = SerializedTokenWrapper.create(pair.getLeft()); serialized.left = SerializedTokenWrapper.create(pair.getLeft());
serialized.right = SerializedTokenWrapper.create(pair.getRight()); serialized.right = SerializedTokenWrapper.create(pair.getRight());
return serialized; return serialized;
} }
@Override @Override
public PairNoResult toObject() { public PairNoResult toObject() {
return new PairNoResult( return new PairNoResult(
left.toObject(), left.toObject(),
right.toObject() right.toObject()
); );
} }
} }

View File

@@ -12,23 +12,23 @@ import de.dhbwstuttgart.typeinference.result.PairTPHEqualTPH;
*/ */
public class SerializedPairTPHEqualTPH implements IPacket.IDataContainer<PairTPHEqualTPH> { public class SerializedPairTPHEqualTPH implements IPacket.IDataContainer<PairTPHEqualTPH> {
@JsonProperty("l") @JsonProperty("l")
public SerializedPlaceholderType left; public SerializedPlaceholderType left;
@JsonProperty("r") @JsonProperty("r")
public SerializedPlaceholderType right; public SerializedPlaceholderType right;
public static SerializedPairTPHEqualTPH create(PairTPHEqualTPH pair) { public static SerializedPairTPHEqualTPH create(PairTPHEqualTPH pair) {
SerializedPairTPHEqualTPH serialized = new SerializedPairTPHEqualTPH(); SerializedPairTPHEqualTPH serialized = new SerializedPairTPHEqualTPH();
serialized.left = SerializedPlaceholderType.create(pair.getLeft()); serialized.left = SerializedPlaceholderType.create(pair.getLeft());
serialized.right = SerializedPlaceholderType.create(pair.getRight()); serialized.right = SerializedPlaceholderType.create(pair.getRight());
return serialized; return serialized;
} }
@Override @Override
public PairTPHEqualTPH toObject() { public PairTPHEqualTPH toObject() {
return new PairTPHEqualTPH( return new PairTPHEqualTPH(
left.toObject(), left.toObject(),
right.toObject() right.toObject()
); );
} }
} }

View File

@@ -13,24 +13,24 @@ import de.dhbwstuttgart.typeinference.result.PairTPHequalRefTypeOrWildcardType;
*/ */
public class SerializedPairTPHequalRefTypeOrWildcardType implements IPacket.IDataContainer<PairTPHequalRefTypeOrWildcardType> { public class SerializedPairTPHequalRefTypeOrWildcardType implements IPacket.IDataContainer<PairTPHequalRefTypeOrWildcardType> {
@JsonProperty("l") @JsonProperty("l")
public SerializedPlaceholderType left; public SerializedPlaceholderType left;
@JsonProperty("r") @JsonProperty("r")
public SerializedTokenWrapper right; public SerializedTokenWrapper right;
public static SerializedPairTPHequalRefTypeOrWildcardType create(PairTPHequalRefTypeOrWildcardType pair) { public static SerializedPairTPHequalRefTypeOrWildcardType create(PairTPHequalRefTypeOrWildcardType pair) {
SerializedPairTPHequalRefTypeOrWildcardType serialized = new SerializedPairTPHequalRefTypeOrWildcardType(); SerializedPairTPHequalRefTypeOrWildcardType serialized = new SerializedPairTPHequalRefTypeOrWildcardType();
serialized.left = SerializedPlaceholderType.create(pair.left); serialized.left = SerializedPlaceholderType.create(pair.left);
serialized.right = SerializedTokenWrapper.create(pair.right); serialized.right = SerializedTokenWrapper.create(pair.right);
return serialized; return serialized;
} }
@Override @Override
public PairTPHequalRefTypeOrWildcardType toObject() { public PairTPHequalRefTypeOrWildcardType toObject() {
return new PairTPHequalRefTypeOrWildcardType( return new PairTPHequalRefTypeOrWildcardType(
left.toObject(), left.toObject(),
right.toObject() right.toObject()
); );
} }
} }

View File

@@ -12,23 +12,23 @@ import de.dhbwstuttgart.typeinference.result.PairTPHsmallerTPH;
*/ */
public class SerializedPairTPHsmallerTPH implements IPacket.IDataContainer<PairTPHsmallerTPH> { public class SerializedPairTPHsmallerTPH implements IPacket.IDataContainer<PairTPHsmallerTPH> {
@JsonProperty("l") @JsonProperty("l")
public SerializedPlaceholderType left; public SerializedPlaceholderType left;
@JsonProperty("r") @JsonProperty("r")
public SerializedPlaceholderType right; public SerializedPlaceholderType right;
public static SerializedPairTPHsmallerTPH create(PairTPHsmallerTPH pair) { public static SerializedPairTPHsmallerTPH create(PairTPHsmallerTPH pair) {
SerializedPairTPHsmallerTPH serialized = new SerializedPairTPHsmallerTPH(); SerializedPairTPHsmallerTPH serialized = new SerializedPairTPHsmallerTPH();
serialized.left = SerializedPlaceholderType.create(pair.left); serialized.left = SerializedPlaceholderType.create(pair.left);
serialized.right = SerializedPlaceholderType.create(pair.right); serialized.right = SerializedPlaceholderType.create(pair.right);
return serialized; return serialized;
} }
@Override @Override
public PairTPHsmallerTPH toObject() { public PairTPHsmallerTPH toObject() {
return new PairTPHsmallerTPH( return new PairTPHsmallerTPH(
left.toObject(), left.toObject(),
right.toObject() right.toObject()
); );
} }
} }

View File

@@ -13,17 +13,17 @@ import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
*/ */
public class SerializedExtendsWildcardType implements IPacket.IDataContainer<ExtendsWildcardType> { public class SerializedExtendsWildcardType implements IPacket.IDataContainer<ExtendsWildcardType> {
@JsonProperty("e") @JsonProperty("e")
public SerializedTokenWrapper extendsType; public SerializedTokenWrapper extendsType;
public static SerializedExtendsWildcardType create(ExtendsWildcardType extendsWildcardType) { public static SerializedExtendsWildcardType create(ExtendsWildcardType extendsWildcardType) {
SerializedExtendsWildcardType type = new SerializedExtendsWildcardType(); SerializedExtendsWildcardType type = new SerializedExtendsWildcardType();
type.extendsType = SerializedTokenWrapper.create(extendsWildcardType.getInnerType()); type.extendsType = SerializedTokenWrapper.create(extendsWildcardType.getInnerType());
return type; return type;
} }
@Override @Override
public ExtendsWildcardType toObject() { public ExtendsWildcardType toObject() {
return new ExtendsWildcardType(extendsType.toObject(), new NullToken()); return new ExtendsWildcardType(extendsType.toObject(), new NullToken());
} }
} }

View File

@@ -12,17 +12,17 @@ import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
*/ */
public class SerializedGenericRefType implements IPacket.IDataContainer<GenericRefType> { public class SerializedGenericRefType implements IPacket.IDataContainer<GenericRefType> {
@JsonProperty("n") @JsonProperty("n")
public String name; public String name;
public static SerializedGenericRefType create(GenericRefType genericRefType) { public static SerializedGenericRefType create(GenericRefType genericRefType) {
SerializedGenericRefType serialized = new SerializedGenericRefType(); SerializedGenericRefType serialized = new SerializedGenericRefType();
serialized.name = genericRefType.getParsedName(); serialized.name = genericRefType.getParsedName();
return serialized; return serialized;
} }
@Override @Override
public GenericRefType toObject() { public GenericRefType toObject() {
return new GenericRefType(name, new NullToken()); return new GenericRefType(name, new NullToken());
} }
} }

View File

@@ -11,17 +11,17 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
*/ */
public class SerializedPlaceholderType implements IPacket.IDataContainer<TypePlaceholder> { public class SerializedPlaceholderType implements IPacket.IDataContainer<TypePlaceholder> {
@JsonProperty("n") @JsonProperty("n")
public String name; public String name;
public static SerializedPlaceholderType create(TypePlaceholder typePlaceholder) { public static SerializedPlaceholderType create(TypePlaceholder typePlaceholder) {
SerializedPlaceholderType serialized = new SerializedPlaceholderType(); SerializedPlaceholderType serialized = new SerializedPlaceholderType();
serialized.name = typePlaceholder.getName(); serialized.name = typePlaceholder.getName();
return serialized; return serialized;
} }
@Override @Override
public TypePlaceholder toObject() { public TypePlaceholder toObject() {
return (TypePlaceholder) TypePlaceholder.of(name); return (TypePlaceholder) TypePlaceholder.of(name);
} }
} }

View File

@@ -6,6 +6,7 @@ import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.server.packet.IPacket; import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.server.packet.dataContainers.SerializedTokenWrapper; import de.dhbwstuttgart.server.packet.dataContainers.SerializedTokenWrapper;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import java.util.Arrays; import java.util.Arrays;
/** /**
@@ -15,26 +16,26 @@ import java.util.Arrays;
*/ */
public class SerializedRefType implements IPacket.IDataContainer<RefType> { public class SerializedRefType implements IPacket.IDataContainer<RefType> {
@JsonProperty("n") @JsonProperty("n")
public String name; public String name;
@JsonProperty("p") @JsonProperty("p")
public SerializedTokenWrapper[] parameters; public SerializedTokenWrapper[] parameters;
public static SerializedRefType create(RefType refType) { public static SerializedRefType create(RefType refType) {
SerializedRefType serialized = new SerializedRefType(); SerializedRefType serialized = new SerializedRefType();
serialized.name = refType.getName().toString(); serialized.name = refType.getName().toString();
serialized.parameters = refType.getParaList().stream().map(SerializedTokenWrapper::create).toArray(SerializedTokenWrapper[]::new); serialized.parameters = refType.getParaList().stream().map(SerializedTokenWrapper::create).toArray(SerializedTokenWrapper[]::new);
return serialized; return serialized;
} }
@Override @Override
public RefType toObject() { public RefType toObject() {
return new RefType( return new RefType(
new JavaClassName(name), new JavaClassName(name),
Arrays.stream(parameters).map(SerializedTokenWrapper::toObject).toList(), Arrays.stream(parameters).map(SerializedTokenWrapper::toObject).toList(),
new NullToken() new NullToken()
); );
} }
} }

View File

@@ -13,18 +13,18 @@ import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
*/ */
public class SerializedSuperWildcardType implements IPacket.IDataContainer<SuperWildcardType> { public class SerializedSuperWildcardType implements IPacket.IDataContainer<SuperWildcardType> {
@JsonProperty("s") @JsonProperty("s")
public SerializedTokenWrapper superType; public SerializedTokenWrapper superType;
public static SerializedSuperWildcardType create(SuperWildcardType superWildcardType) { public static SerializedSuperWildcardType create(SuperWildcardType superWildcardType) {
SerializedSuperWildcardType type = new SerializedSuperWildcardType(); SerializedSuperWildcardType type = new SerializedSuperWildcardType();
type.superType = SerializedTokenWrapper.create(superWildcardType.getInnerType()); type.superType = SerializedTokenWrapper.create(superWildcardType.getInnerType());
type.superType = SerializedTokenWrapper.create(superWildcardType.getInnerType()); type.superType = SerializedTokenWrapper.create(superWildcardType.getInnerType());
return type; return type;
} }
@Override @Override
public SuperWildcardType toObject() { public SuperWildcardType toObject() {
return new SuperWildcardType(superType.toObject(), new NullToken()); return new SuperWildcardType(superType.toObject(), new NullToken());
} }
} }

View File

@@ -11,14 +11,14 @@ import de.dhbwstuttgart.syntaxtree.type.Void;
*/ */
public class SerializedVoidType implements IPacket.IDataContainer<Void> { public class SerializedVoidType implements IPacket.IDataContainer<Void> {
public int i = 0; public int i = 0;
public static SerializedVoidType create(Void voidType) { public static SerializedVoidType create(Void voidType) {
return new SerializedVoidType(); return new SerializedVoidType();
} }
@Override @Override
public Void toObject() { public Void toObject() {
return new Void(new NullToken()); return new Void(new NullToken());
} }
} }

View File

@@ -10,17 +10,17 @@ import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
*/ */
public class SerializedExtendsType extends SerializedWildcardType implements IPacket.IDataContainer<ExtendsType> { public class SerializedExtendsType extends SerializedWildcardType implements IPacket.IDataContainer<ExtendsType> {
public static SerializedExtendsType create(ExtendsType extendsType) { public static SerializedExtendsType create(ExtendsType extendsType) {
SerializedExtendsType type = new SerializedExtendsType(); SerializedExtendsType type = new SerializedExtendsType();
type.readWildcardTypeValues(extendsType); type.readWildcardTypeValues(extendsType);
return type; return type;
} }
@Override @Override
public ExtendsType toObject() { public ExtendsType toObject() {
return new ExtendsType( return new ExtendsType(
this.wildcardedType.toObject() this.wildcardedType.toObject()
); );
} }
} }

View File

@@ -4,6 +4,7 @@ import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.server.packet.dataContainers.SerializedUnifyTypeWrapper; import de.dhbwstuttgart.server.packet.dataContainers.SerializedUnifyTypeWrapper;
import de.dhbwstuttgart.typeinference.unify.model.FunNType; import de.dhbwstuttgart.typeinference.unify.model.FunNType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams; import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
import java.util.Arrays; import java.util.Arrays;
/** /**
@@ -14,19 +15,19 @@ import java.util.Arrays;
public class SerializedFunNType extends SerializedUnifyType implements IPacket.IDataContainer<FunNType> { public class SerializedFunNType extends SerializedUnifyType implements IPacket.IDataContainer<FunNType> {
public static SerializedFunNType create(FunNType funN) { public static SerializedFunNType create(FunNType funN) {
SerializedFunNType type = new SerializedFunNType(); SerializedFunNType type = new SerializedFunNType();
type.readUnifyTypeValues(funN); type.readUnifyTypeValues(funN);
return type; return type;
} }
@Override @Override
public FunNType toObject() { public FunNType toObject() {
return FunNType.getFunNType( return FunNType.getFunNType(
new TypeParams( new TypeParams(
Arrays.stream(this.params).map(SerializedUnifyTypeWrapper::toObject).toList() Arrays.stream(this.params).map(SerializedUnifyTypeWrapper::toObject).toList()
) )
); );
} }
} }

View File

@@ -10,29 +10,29 @@ import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
*/ */
public class SerializedPlaceholderType extends SerializedUnifyType implements IPacket.IDataContainer<PlaceholderType> { public class SerializedPlaceholderType extends SerializedUnifyType implements IPacket.IDataContainer<PlaceholderType> {
public boolean isGenerated; public boolean isGenerated;
public boolean isInnerType; public boolean isInnerType;
public int variance; public int variance;
public byte orCons; public byte orCons;
public static SerializedPlaceholderType create(PlaceholderType placeholder) { public static SerializedPlaceholderType create(PlaceholderType placeholder) {
SerializedPlaceholderType type = new SerializedPlaceholderType(); SerializedPlaceholderType type = new SerializedPlaceholderType();
type.readUnifyTypeValues(placeholder); type.readUnifyTypeValues(placeholder);
type.isGenerated = placeholder.isGenerated(); type.isGenerated = placeholder.isGenerated();
type.isInnerType = placeholder.isInnerType(); type.isInnerType = placeholder.isInnerType();
type.variance = placeholder.getVariance(); type.variance = placeholder.getVariance();
type.orCons = placeholder.getOrCons(); type.orCons = placeholder.getOrCons();
return type; return type;
} }
@Override @Override
public PlaceholderType toObject() { public PlaceholderType toObject() {
PlaceholderType placeholderType = new PlaceholderType(this.name, this.isGenerated); PlaceholderType placeholderType = new PlaceholderType(this.name, this.isGenerated);
placeholderType.setInnerType(this.isInnerType); placeholderType.setInnerType(this.isInnerType);
placeholderType.setVariance(this.variance); placeholderType.setVariance(this.variance);
placeholderType.setOrCons(this.orCons); placeholderType.setOrCons(this.orCons);
return placeholderType; return placeholderType;
} }
} }

View File

@@ -5,6 +5,7 @@ import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.server.packet.dataContainers.SerializedUnifyTypeWrapper; import de.dhbwstuttgart.server.packet.dataContainers.SerializedUnifyTypeWrapper;
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType; import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams; import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
import java.util.Arrays; import java.util.Arrays;
/** /**
@@ -14,24 +15,24 @@ import java.util.Arrays;
*/ */
public class SerializedReferenceType extends SerializedUnifyType implements IPacket.IDataContainer<ReferenceType> { public class SerializedReferenceType extends SerializedUnifyType implements IPacket.IDataContainer<ReferenceType> {
@JsonProperty("gt") @JsonProperty("gt")
public boolean genericTypeVar; public boolean genericTypeVar;
public static SerializedReferenceType create(ReferenceType referenceType) { public static SerializedReferenceType create(ReferenceType referenceType) {
SerializedReferenceType type = new SerializedReferenceType(); SerializedReferenceType type = new SerializedReferenceType();
type.readUnifyTypeValues(referenceType); type.readUnifyTypeValues(referenceType);
type.genericTypeVar = referenceType.isGenTypeVar(); type.genericTypeVar = referenceType.isGenTypeVar();
return type; return type;
} }
@Override @Override
public ReferenceType toObject() { public ReferenceType toObject() {
ReferenceType referenceType = new ReferenceType(this.name, this.genericTypeVar); ReferenceType referenceType = new ReferenceType(this.name, this.genericTypeVar);
return (ReferenceType) referenceType.setTypeParams( return (ReferenceType) referenceType.setTypeParams(
new TypeParams( new TypeParams(
Arrays.stream(this.params).map(SerializedUnifyTypeWrapper::toObject).toList() Arrays.stream(this.params).map(SerializedUnifyTypeWrapper::toObject).toList()
) )
); );
} }
} }

View File

@@ -10,17 +10,17 @@ import de.dhbwstuttgart.typeinference.unify.model.SuperType;
*/ */
public class SerializedSuperType extends SerializedWildcardType implements IPacket.IDataContainer<SuperType> { public class SerializedSuperType extends SerializedWildcardType implements IPacket.IDataContainer<SuperType> {
public static SerializedSuperType create(SuperType superType) { public static SerializedSuperType create(SuperType superType) {
SerializedSuperType type = new SerializedSuperType(); SerializedSuperType type = new SerializedSuperType();
type.readWildcardTypeValues(superType); type.readWildcardTypeValues(superType);
return type; return type;
} }
@Override @Override
public SuperType toObject() { public SuperType toObject() {
return new SuperType( return new SuperType(
this.wildcardedType.toObject() this.wildcardedType.toObject()
); );
} }
} }

View File

@@ -3,6 +3,7 @@ package de.dhbwstuttgart.server.packet.dataContainers.unifyType;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import de.dhbwstuttgart.server.packet.dataContainers.SerializedUnifyTypeWrapper; import de.dhbwstuttgart.server.packet.dataContainers.SerializedUnifyTypeWrapper;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType; import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
import java.util.Arrays; import java.util.Arrays;
/** /**
@@ -12,13 +13,13 @@ import java.util.Arrays;
*/ */
abstract class SerializedUnifyType { abstract class SerializedUnifyType {
@JsonProperty("n") @JsonProperty("n")
public String name; public String name;
@JsonProperty("p") @JsonProperty("p")
public SerializedUnifyTypeWrapper[] params = new SerializedUnifyTypeWrapper[]{}; public SerializedUnifyTypeWrapper[] params = new SerializedUnifyTypeWrapper[]{};
public void readUnifyTypeValues(UnifyType unifyType) { public void readUnifyTypeValues(UnifyType unifyType) {
name = unifyType.getName(); name = unifyType.getName();
params = Arrays.stream(unifyType.getTypeParams().get()).map(SerializedUnifyTypeWrapper::create).toArray(SerializedUnifyTypeWrapper[]::new); params = Arrays.stream(unifyType.getTypeParams().get()).map(SerializedUnifyTypeWrapper::create).toArray(SerializedUnifyTypeWrapper[]::new);
} }
} }

View File

@@ -10,11 +10,11 @@ import de.dhbwstuttgart.typeinference.unify.model.WildcardType;
*/ */
abstract class SerializedWildcardType extends SerializedUnifyType { abstract class SerializedWildcardType extends SerializedUnifyType {
public SerializedUnifyTypeWrapper wildcardedType; public SerializedUnifyTypeWrapper wildcardedType;
public void readWildcardTypeValues(WildcardType wildcardType) { public void readWildcardTypeValues(WildcardType wildcardType) {
this.readUnifyTypeValues(wildcardType); this.readUnifyTypeValues(wildcardType);
wildcardedType = SerializedUnifyTypeWrapper.create(wildcardType.getWildcardedType()); wildcardedType = SerializedUnifyTypeWrapper.create(wildcardType.getWildcardedType());
} }
} }

View File

@@ -182,7 +182,7 @@ public class UnifyTypeFactory {
if (lhs.getName().equals("AQ")) { if (lhs.getName().equals("AQ")) {
System.out.println(""); System.out.println("");
} }
((PlaceholderType)rhs).enableWildcardtable(); ((PlaceholderType)rhs).enableWildcardable();
} }
if (((rhs = ret.getLhsType()) instanceof PlaceholderType) if (((rhs = ret.getLhsType()) instanceof PlaceholderType)
@@ -191,7 +191,7 @@ public class UnifyTypeFactory {
if (rhs.getName().equals("AQ")) { if (rhs.getName().equals("AQ")) {
System.out.println(""); System.out.println("");
} }
((PlaceholderType)lhs).enableWildcardtable(); ((PlaceholderType)lhs).enableWildcardable();
} }
return ret; return ret;
} }
@@ -280,4 +280,4 @@ public class UnifyTypeFactory {
return ret; return ret;
} }
} }

View File

@@ -1,6 +1,5 @@
package de.dhbwstuttgart.typeinference; package de.dhbwstuttgart.typeinference;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.dhbwstuttgart.server.SocketClient; import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory; import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
@@ -8,17 +7,15 @@ import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.unify.RuleSet;
import de.dhbwstuttgart.typeinference.unify.TypeUnify; import de.dhbwstuttgart.typeinference.unify.TypeUnify;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
import de.dhbwstuttgart.typeinference.unify.UnifyResultListener;
import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl;
import de.dhbwstuttgart.typeinference.unify.UnifyResultModelParallel; import de.dhbwstuttgart.typeinference.unify.UnifyResultModelParallel;
import de.dhbwstuttgart.typeinference.unify.UnifyTaskModelParallel; import de.dhbwstuttgart.typeinference.unify.UnifyTaskModelParallel;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import org.apache.commons.io.output.NullOutputStream;
import org.apache.commons.io.output.NullWriter;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.Writer; import java.io.Writer;
@@ -27,8 +24,6 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.commons.io.output.NullOutputStream;
import org.apache.commons.io.output.NullWriter;
/** /**
* Provides the entry point of the type inference and unification algorithm via the methods * Provides the entry point of the type inference and unification algorithm via the methods
@@ -38,334 +33,194 @@ import org.apache.commons.io.output.NullWriter;
*/ */
public class TypeInference { public class TypeInference {
protected final ConstraintSet<Pair> constraints; protected final ConstraintSet<Pair> constraints;
protected final List<ClassOrInterface> allClasses; protected final List<ClassOrInterface> allClasses;
protected final ClassLoader classLoader; protected final ClassLoader classLoader;
protected final boolean shouldUnifyParallel; protected final boolean shouldUnifyParallel;
protected final boolean shouldLog; protected final boolean shouldLog;
protected final Writer logFileWriter; protected final Writer logFileWriter;
protected final Writer statisticFileWriter; protected final Writer statisticFileWriter;
public TypeInference( public TypeInference(
ConstraintSet<Pair> constraints, ConstraintSet<Pair> constraints,
List<ClassOrInterface> allClasses, List<ClassOrInterface> allClasses,
ClassLoader classLoader, ClassLoader classLoader,
boolean shouldUnifyParallel, boolean shouldUnifyParallel,
boolean shouldLog, boolean shouldLog,
Writer logFileWriter, Writer logFileWriter,
Writer statisticFileWriter Writer statisticFileWriter
) { ) {
this.constraints = constraints; this.constraints = constraints;
this.allClasses = allClasses; this.allClasses = allClasses;
this.classLoader = classLoader; this.classLoader = classLoader;
this.shouldUnifyParallel = shouldUnifyParallel; this.shouldUnifyParallel = shouldUnifyParallel;
this.shouldLog = shouldLog; this.shouldLog = shouldLog;
this.logFileWriter = logFileWriter; this.logFileWriter = logFileWriter;
this.statisticFileWriter = statisticFileWriter; this.statisticFileWriter = statisticFileWriter;
}
public UnifyResultModelParallel executeAsync(
UnifyResultListener resultListener
) throws ClassNotFoundException, IOException {
// generate finite closure
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFileWriter, classLoader);
logFileWriter.write("FC:\\" + finiteClosure.toString() + "\n");
System.out.println(finiteClosure);
// generate unifyConstraints
ConstraintSet<UnifyPair> unifyConstraints = TypeInferenceHelper.constraintsToUnifyConstraints(constraints);
logFileWriter.write("\nUnify_distributeInnerVars: " + unifyConstraints.toString());
TypeUnify unify = new TypeUnify();
TypeUnify.statistics = statisticFileWriter;
Set<String> paraTypeVarNames = new HashSet<>();
paraTypeVarNames.addAll(TypeInferenceHelper.methodParaTypeVarNames(allClasses));
paraTypeVarNames.addAll(TypeInferenceHelper.constructorParaTypeVarNames(allClasses));
Set<String> returnAndFieldTypeVarNames = new HashSet<>();
returnAndFieldTypeVarNames.addAll(TypeInferenceHelper.returnTypeVarNames(allClasses));
returnAndFieldTypeVarNames.addAll(TypeInferenceHelper.fieldTypeVarNames(allClasses));
UnifyResultModelParallel urm = new UnifyResultModelParallel(constraints, finiteClosure);
urm.addUnifyResultListener(resultListener);
unifyConstraints = unifyConstraints.map(x -> {
// Hier muss ueberlegt werden, ob
// 1. alle Argument- und Retuntyp-Variablen in allen UnifyPairs
// mit disableWildcardtable() werden.
// 2. alle Typvariablen mit Argument- oder Retuntyp-Variablen
// in Beziehung auch auf disableWildcardtable() gesetzt werden muessen
// PL 2018-04-23
if ((x.getLhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType) x.getLhsType()).setVariance((byte) 1);
((PlaceholderType) x.getLhsType()).disableWildcardtable();
}
if (returnAndFieldTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType) x.getLhsType()).setVariance((byte) -1);
((PlaceholderType) x.getLhsType()).disableWildcardtable();
}
}
if ((x.getRhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType) x.getRhsType()).setVariance((byte) 1);
((PlaceholderType) x.getRhsType()).disableWildcardtable();
}
if (returnAndFieldTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType) x.getRhsType()).setVariance((byte) -1);
((PlaceholderType) x.getRhsType()).disableWildcardtable();
}
}
return x;// HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE
// JEWEILS ANDERE SEITE
});
Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = new HashSet<>();
varianceTPH = TypeInferenceHelper.varianceInheritanceConstraintSet(unifyConstraints);
/*
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL
* 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen
* //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH);
* varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y
* -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType()
* instanceof PlaceholderType)) { if
* (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) {
* ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType(
* )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0
* && ((PlaceholderType)y.getRhsType()).getVariance() != 0) {
* ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType(
* )).getVariance()); } } return y; } ); } while
* (!varianceTPHold.equals(varianceTPH));
*/
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
// logFileWriter, log);
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyConstraints.getOderConstraints()/*.stream().map(x -> {
Set<Set<UnifyPair>> ret = new HashSet<>();
for (Constraint<UnifyPair> y : x) {
ret.add(new HashSet<>(y));
}
return ret;
}).collect(Collectors.toCollection(ArrayList::new))*/;
UnifyTaskModelParallel usedTasks = new UnifyTaskModelParallel();
unify.unifyAsync(
unifyConstraints.getUndConstraints(),
oderConstraints,
finiteClosure,
logFileWriter,
shouldLog,
urm,
usedTasks
);
return urm;
}
public List<ResultSet> execute(Optional<String> remoteServer) throws ClassNotFoundException, IOException {
// generate finite closure
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFileWriter, classLoader);
logFileWriter.write("FC:\\" + finiteClosure.toString() + "\n");
System.out.println(finiteClosure);
// generate unifyConstraints
ConstraintSet<UnifyPair> unifyConstraints = TypeInferenceHelper.constraintsToUnifyConstraints(constraints);
logFileWriter.write("\nUnify_distributeInnerVars: " + unifyConstraints.toString());
TypeUnify unify = new TypeUnify();
TypeUnify.statistics = statisticFileWriter;
Set<String> paraTypeVarNames = new HashSet<>();
paraTypeVarNames.addAll(TypeInferenceHelper.methodParaTypeVarNames(allClasses));
paraTypeVarNames.addAll(TypeInferenceHelper.constructorParaTypeVarNames(allClasses));
Set<String> returnAndFieldTypeVarNames = new HashSet<>();
returnAndFieldTypeVarNames.addAll(TypeInferenceHelper.returnTypeVarNames(allClasses));
returnAndFieldTypeVarNames.addAll(TypeInferenceHelper.fieldTypeVarNames(allClasses));
unifyConstraints = TypeInferenceHelper.makeFixedPlaceholdersNonWildcardable(unifyConstraints, paraTypeVarNames, returnAndFieldTypeVarNames);
//PL 2020-02-05 alle Oder-Constraints Receiver und Parameter werden auf variance 1 gesetzt
//Es wird davon ausgegangen, dass in OderConstraints in Bedingungen für Parameter die Typen der Argumente links stehen
//und die Typen der Rückgabewerte immer rechts stehen
/*
unifyCons.getOderConstraints().forEach(z -> z.forEach(y -> y.forEach(x -> {
if ((x.getLhsType() instanceof PlaceholderType) && x.getPairOp().compareTo(PairOperator.SMALLERDOT) == 0) {
((PlaceholderType) x.getLhsType()).setVariance((byte)1);
}
else if ((x.getRhsType() instanceof PlaceholderType) && x.getPairOp().compareTo(PairOperator.EQUALSDOT) == 0) {
((PlaceholderType) x.getRhsType()).setVariance((byte)-1);
}
})));
*/
System.out.println("Unify nach Oder-Constraints-Anpassung:" + unifyConstraints.toString());
Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = TypeInferenceHelper.varianceInheritanceConstraintSet(unifyConstraints);
/*
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL
* 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen
* //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH);
* varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y
* -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType()
* instanceof PlaceholderType)) { if
* (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) {
* ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType(
* )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0
* && ((PlaceholderType)y.getRhsType()).getVariance() != 0) {
* ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType(
* )).getVariance()); } } return y; } ); } while
* (!varianceTPHold.equals(varianceTPH));
*/
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
// logFile, log);
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyConstraints.getOderConstraints()//.stream().map(x -> {
/*Set<Set<UnifyPair>> ret = new HashSet<>();
for (Constraint<UnifyPair> y : x) {
ret.add(new HashSet<>(y));
}
return ret;
}).collect(Collectors.toCollection(ArrayList::new))*/;
UnifyTaskModelParallel usedTasks = new UnifyTaskModelParallel();
List<ResultSet> results;
if (remoteServer.isPresent()) {
SocketClient socketClient = new SocketClient(remoteServer.get());
results = socketClient.execute(
finiteClosure,
constraints,
unifyConstraints
);
} else if (shouldUnifyParallel) {
results = this.executeParallel(
unify,
unifyConstraints,
oderConstraints,
finiteClosure,
usedTasks
);
} else {
results = this.executeSequential(
unify,
unifyConstraints,
oderConstraints,
finiteClosure,
usedTasks
);
} }
System.out.println("Found " + results.size() + " results"); public static List<ResultSet> executeWithoutContext(
IFiniteClosure finiteClosure,
ConstraintSet<Pair> constraints,
ConstraintSet<UnifyPair> unifyConstraints
) {
UnifyResultModelParallel urm = new UnifyResultModelParallel(constraints, finiteClosure);
TypeUnify.statistics = new NullWriter();
statisticFileWriter.close(); (new TypeUnify()).unifyParallel(
return results; unifyConstraints.getUndConstraints(),
} unifyConstraints.getOderConstraints(),
finiteClosure,
new OutputStreamWriter(new NullOutputStream()),
false,
urm,
new UnifyTaskModelParallel() // TODO: move this to SocketData to cancel the pool once a client disconnects
);
/** return urm.getResults();
* We provide a UnifyTaskModelParallel anyway to reuse code }
*/
protected List<ResultSet> executeSequential(
TypeUnify unify,
ConstraintSet<UnifyPair> unifyCons,
List<Set<Constraint<UnifyPair>>> oderConstraints,
IFiniteClosure finiteClosure,
UnifyTaskModelParallel taskModel
) throws IOException { public List<ResultSet> execute(Optional<String> remoteServer) throws ClassNotFoundException, IOException {
Set<Set<UnifyPair>> result = unify.unifyOderConstraints( // generate finite closure
unifyCons.getUndConstraints(), IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFileWriter, classLoader);
oderConstraints, logFileWriter.write("FC:\\" + finiteClosure + "\n");
finiteClosure, System.out.println(finiteClosure);
logFileWriter,
shouldLog,
new UnifyResultModelParallel(constraints, finiteClosure),
taskModel
);
System.out.println("RESULT: " + result);
logFileWriter.write("RES: " + result.toString() + "\n");
logFileWriter.flush();
Set<Set<UnifyPair>> results = new HashSet<>(result); // generate unifyConstraints
ConstraintSet<UnifyPair> unifyConstraints = TypeInferenceHelper.constraintsToUnifyConstraints(constraints);
logFileWriter.write("\nUnify_distributeInnerVars: " + unifyConstraints.toString());
results = results.stream().map(x -> { TypeUnify unify = new TypeUnify();
// alle Paare a <.? b erden durch a =. b ersetzt TypeUnify.statistics = statisticFileWriter;
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> {
if (y.getPairOp() == PairOperator.SMALLERDOTWC)
y.setPairOp(PairOperator.EQUALSDOT);
return y;
}).collect(Collectors.toCollection(HashSet::new)));
if (res.isPresent()) {
// wenn subst ein Erg liefert wurde was veraendert
return new TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure);
} else
// wenn nichts veraendert wurde wird x zurueckgegeben
return x;
}).collect(Collectors.toCollection(HashSet::new));
System.out.println("RESULT Final: " + results);
System.out.println("Constraints for Generated Generics: " + " ???");
logFileWriter.write("RES_FINAL: " + results.toString() + "\n");
logFileWriter.write("PLACEHOLDERS: " + PlaceholderType.EXISTING_PLACEHOLDERS);
logFileWriter.flush();
return results.stream() Set<String> paraTypeVarNames = new HashSet<>();
.map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(constraints))))) paraTypeVarNames.addAll(TypeInferenceHelper.methodParaTypeVarNames(allClasses));
.collect(Collectors.toList()); paraTypeVarNames.addAll(TypeInferenceHelper.constructorParaTypeVarNames(allClasses));
}
protected List<ResultSet> executeParallel( Set<String> returnAndFieldTypeVarNames = new HashSet<>();
TypeUnify unify, returnAndFieldTypeVarNames.addAll(TypeInferenceHelper.returnTypeVarNames(allClasses));
ConstraintSet<UnifyPair> unifyCons, returnAndFieldTypeVarNames.addAll(TypeInferenceHelper.fieldTypeVarNames(allClasses));
List<Set<Constraint<UnifyPair>>> oderConstraints,
IFiniteClosure finiteClosure,
UnifyTaskModelParallel taskModel
) throws IOException {
UnifyResultModelParallel urm = new UnifyResultModelParallel(constraints, finiteClosure);
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
urm.addUnifyResultListener(li);
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFileWriter, shouldLog, urm,
taskModel);
System.out.println("RESULT Final: " + li.getResults());
System.out.println("Constraints for Generated Generics: " + " ???");
logFileWriter.write("RES_FINAL: " + li.getResults().toString() + "\n");
logFileWriter.flush();
statisticFileWriter.close();
return li.getResults();
}
public static List<ResultSet> executeWithoutContext( unifyConstraints = TypeInferenceHelper.makeFixedPlaceholdersNonWildcardable(unifyConstraints, paraTypeVarNames, returnAndFieldTypeVarNames);
IFiniteClosure finiteClosure,
ConstraintSet<Pair> constraints,
ConstraintSet<UnifyPair> unifyConstraints
) {
UnifyResultModelParallel urm = new UnifyResultModelParallel(constraints, finiteClosure);
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
urm.addUnifyResultListener(li);
TypeUnify.statistics = new NullWriter(); //PL 2020-02-05 alle Oder-Constraints Receiver und Parameter werden auf variance 1 gesetzt
//Es wird davon ausgegangen, dass in OderConstraints in Bedingungen für Parameter die Typen der Argumente links stehen
//und die Typen der Rückgabewerte immer rechts stehen
(new TypeUnify()).unifyParallel( System.out.println("Unify nach Oder-Constraints-Anpassung:" + unifyConstraints.toString());
unifyConstraints.getUndConstraints(), Set<PlaceholderType> varianceTPHold;
unifyConstraints.getOderConstraints(), Set<PlaceholderType> varianceTPH = TypeInferenceHelper.varianceInheritanceConstraintSet(unifyConstraints);
finiteClosure,
new OutputStreamWriter(new NullOutputStream()),
false,
urm,
new UnifyTaskModelParallel() // TODO: move this to SocketData to cancel the pool once a client disconnects
);
return li.getResults(); /*
} * PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL
* 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen
* //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH);
* varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y
* -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType()
* instanceof PlaceholderType)) { if
* (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) {
* ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType(
* )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0
* && ((PlaceholderType)y.getRhsType()).getVariance() != 0) {
* ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType(
* )).getVariance()); } } return y; } ); } while
* (!varianceTPHold.equals(varianceTPH));
*/
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyConstraints.getOderConstraints();
UnifyTaskModelParallel usedTasks = new UnifyTaskModelParallel();
List<ResultSet> results;
if (remoteServer.isPresent()) {
SocketClient socketClient = new SocketClient(remoteServer.get());
results = socketClient.execute(
finiteClosure,
constraints,
unifyConstraints
);
} else if (shouldUnifyParallel) {
results = this.executeParallel(
unify,
unifyConstraints,
oderConstraints,
finiteClosure,
usedTasks
);
} else {
results = this.executeSequential(
unify,
unifyConstraints,
oderConstraints,
finiteClosure
);
}
System.out.println("Found " + results.size() + " results");
statisticFileWriter.close();
return results;
}
/**
* We provide a UnifyTaskModelParallel anyway to reuse code
*/
protected List<ResultSet> executeSequential(
TypeUnify unify,
ConstraintSet<UnifyPair> unifyCons,
List<Set<Constraint<UnifyPair>>> oderConstraints,
IFiniteClosure finiteClosure
) throws IOException {
Set<Set<UnifyPair>> result = unify.unifyOderConstraints(
unifyCons.getUndConstraints(),
oderConstraints,
finiteClosure,
logFileWriter,
shouldLog,
new UnifyResultModelParallel(constraints, finiteClosure)
);
System.out.println("RESULT: " + result);
logFileWriter.write("RES: " + result.toString() + "\n");
logFileWriter.flush();
Set<Set<UnifyPair>> results = TypeInferenceHelper.resolveSubstitutions(new HashSet<>(result), finiteClosure);
System.out.println("RESULT Final: " + results);
System.out.println("Constraints for Generated Generics: " + " ???");
logFileWriter.write("RES_FINAL: " + results.toString() + "\n");
logFileWriter.write("PLACEHOLDERS: " + PlaceholderType.EXISTING_PLACEHOLDERS);
logFileWriter.flush();
return results.stream()
.map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(constraints)))))
.collect(Collectors.toList());
}
protected List<ResultSet> executeParallel(
TypeUnify unify,
ConstraintSet<UnifyPair> unifyCons,
List<Set<Constraint<UnifyPair>>> oderConstraints,
IFiniteClosure finiteClosure,
UnifyTaskModelParallel taskModel
) throws IOException {
UnifyResultModelParallel urm = new UnifyResultModelParallel(constraints, finiteClosure);
unify.unifyParallel(
unifyCons.getUndConstraints(),
oderConstraints,
finiteClosure,
logFileWriter,
shouldLog,
urm,
taskModel
);
System.out.println("RESULT Final: " + urm.getResults());
System.out.println("Constraints for Generated Generics: " + " ???");
logFileWriter.write("RESULT_FINAL: " + urm.getResults().toString() + "\n");
logFileWriter.flush();
statisticFileWriter.close();
return urm.getResults();
}
} }

View File

@@ -5,45 +5,64 @@ import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.unify.distributeVariance; import de.dhbwstuttgart.typeinference.unify.DistributeVariance;
import de.dhbwstuttgart.typeinference.unify.RuleSet;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType; import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
import java.util.ArrayList;
import java.util.HashSet; import java.util.*;
import java.util.List;
import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* Provides static helper methods for the TypeInferenceAlgorithm to reduce method size * Provides static helper methods for the TypeInferenceAlgorithm to reduce method size and prevent duplicate code
*/ */
public class TypeInferenceHelper { public class TypeInferenceHelper {
public static Set<Set<UnifyPair>> resolveSubstitutions(Set<Set<UnifyPair>> results, IFiniteClosure finiteClosure) {
return results.stream().map(x -> {
// replace all (a <.? b) constraints with (a =. b) and apply the substitution rule
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> {
if (y.getPairOp() == PairOperator.SMALLERDOTWC)
y.setPairOp(PairOperator.EQUALSDOT);
return y;
}).collect(Collectors.toCollection(HashSet::new)));
if (res.isPresent()) {
// if any constraints have been changed by the substitution, apply all the unification rules again
return new TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure);
} else {
// Otherwise return the constraints, if nothing was changes
return x;
}
}).collect(Collectors.toCollection(HashSet::new));
}
public static ConstraintSet<UnifyPair> constraintsToUnifyConstraints(ConstraintSet<Pair> constraints) { public static ConstraintSet<UnifyPair> constraintsToUnifyConstraints(ConstraintSet<Pair> constraints) {
ConstraintSet<UnifyPair> unifyConstraints = UnifyTypeFactory.convert(constraints); ConstraintSet<UnifyPair> unifyConstraints = UnifyTypeFactory.convert(constraints);
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> { Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
UnifyType lhs, rhs; UnifyType lhs, rhs;
if (((lhs = x.getLhsType()) instanceof PlaceholderType) if (((lhs = x.getLhsType()) instanceof PlaceholderType)
&& ((rhs = x.getRhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType)
&& (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) { && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
((PlaceholderType) lhs).setInnerType(true); ((PlaceholderType) lhs).setInnerType(true);
((PlaceholderType) rhs).setInnerType(true); ((PlaceholderType) rhs).setInnerType(true);
} }
return x; return x;
}; };
System.out.println("Unify:" + unifyConstraints.toString()); System.out.println("Unify:" + unifyConstraints.toString());
unifyConstraints = unifyConstraints.map(distributeInnerVars);
return unifyConstraints; return unifyConstraints.map(distributeInnerVars);
} }
public static ConstraintSet<UnifyPair> makeFixedPlaceholdersNonWildcardable( public static ConstraintSet<UnifyPair> makeFixedPlaceholdersNonWildcardable(
ConstraintSet<UnifyPair> unifyConstraints, ConstraintSet<UnifyPair> unifyConstraints,
Set<String> paraTypeVarNames, Set<String> paraTypeVarNames,
Set<String> returnAndFieldTypeVarNames Set<String> returnAndFieldTypeVarNames
) { ) {
return unifyConstraints.map(x -> { return unifyConstraints.map(x -> {
// Hier muss ueberlegt werden, ob // Hier muss ueberlegt werden, ob
@@ -55,41 +74,41 @@ public class TypeInferenceHelper {
if ((x.getLhsType() instanceof PlaceholderType)) { if ((x.getLhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getLhsType().getName())) { if (paraTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType) x.getLhsType()).setVariance((byte) 1); ((PlaceholderType) x.getLhsType()).setVariance((byte) 1);
((PlaceholderType) x.getLhsType()).disableWildcardtable(); ((PlaceholderType) x.getLhsType()).disableWildcardable();
} }
if (returnAndFieldTypeVarNames.contains(x.getLhsType().getName())) { if (returnAndFieldTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType) x.getLhsType()).setVariance((byte) -1); ((PlaceholderType) x.getLhsType()).setVariance((byte) -1);
((PlaceholderType) x.getLhsType()).disableWildcardtable(); ((PlaceholderType) x.getLhsType()).disableWildcardable();
} }
} }
if ((x.getRhsType() instanceof PlaceholderType)) { if ((x.getRhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getRhsType().getName())) { if (paraTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType) x.getRhsType()).setVariance((byte) 1); ((PlaceholderType) x.getRhsType()).setVariance((byte) 1);
((PlaceholderType) x.getRhsType()).disableWildcardtable(); ((PlaceholderType) x.getRhsType()).disableWildcardable();
} }
if (returnAndFieldTypeVarNames.contains(x.getRhsType().getName())) { if (returnAndFieldTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType) x.getRhsType()).setVariance((byte) -1); ((PlaceholderType) x.getRhsType()).setVariance((byte) -1);
((PlaceholderType) x.getRhsType()).disableWildcardtable(); ((PlaceholderType) x.getRhsType()).disableWildcardable();
} }
} }
return x;// HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE // Hier die jeweils rechte bzw. linke Seite auf die gleiche Varianz setzen, wie die jeweils andere Seite
// JEWEILS ANDERE SEITE return x;
}); });
} }
public static Set<String> methodParaTypeVarNames(List<ClassOrInterface> allClasses) { public static Set<String> methodParaTypeVarNames(List<ClassOrInterface> allClasses) {
return allClasses.stream().map(x -> x.getMethods().stream() return allClasses.stream().map(x -> x.getMethods().stream()
.map(y -> y.getParameterList().getFormalparalist().stream() .map(y -> y.getParameterList().getFormalparalist().stream()
.filter(z -> z.getType() instanceof TypePlaceholder) .filter(z -> z.getType() instanceof TypePlaceholder)
.map(z -> ((TypePlaceholder) z.getType()).getName()) .map(z -> ((TypePlaceholder) z.getType()).getName())
.collect(Collectors.toCollection(HashSet::new))) .collect(Collectors.toCollection(HashSet::new)))
.reduce(new HashSet<String>(), (a, b) -> { .reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b); a.addAll(b);
return a; return a;
}, (a, b) -> { }, (a, b) -> {
a.addAll(b); a.addAll(b);
return a; return a;
})).reduce(new HashSet<String>(), (a, b) -> { })).reduce(new HashSet<>(), (a, b) -> {
a.addAll(b); a.addAll(b);
return a; return a;
}); });
@@ -97,17 +116,17 @@ public class TypeInferenceHelper {
public static Set<String> constructorParaTypeVarNames(List<ClassOrInterface> allClasses) { public static Set<String> constructorParaTypeVarNames(List<ClassOrInterface> allClasses) {
return allClasses.stream().map(x -> x.getConstructors().stream() return allClasses.stream().map(x -> x.getConstructors().stream()
.map(y -> y.getParameterList().getFormalparalist().stream() .map(y -> y.getParameterList().getFormalparalist().stream()
.filter(z -> z.getType() instanceof TypePlaceholder) .filter(z -> z.getType() instanceof TypePlaceholder)
.map(z -> ((TypePlaceholder) z.getType()).getName()) .map(z -> ((TypePlaceholder) z.getType()).getName())
.collect(Collectors.toCollection(HashSet::new))) .collect(Collectors.toCollection(HashSet::new)))
.reduce(new HashSet<String>(), (a, b) -> { .reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b); a.addAll(b);
return a; return a;
}, (a, b) -> { }, (a, b) -> {
a.addAll(b); a.addAll(b);
return a; return a;
})).reduce(new HashSet<String>(), (a, b) -> { })).reduce(new HashSet<>(), (a, b) -> {
a.addAll(b); a.addAll(b);
return a; return a;
}); });
@@ -115,31 +134,29 @@ public class TypeInferenceHelper {
public static Set<String> returnTypeVarNames(List<ClassOrInterface> allClasses) { public static Set<String> returnTypeVarNames(List<ClassOrInterface> allClasses) {
return allClasses.stream() return allClasses.stream()
.map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder) .map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder)
.map(z -> ((TypePlaceholder) z.getReturnType()).getName()) .map(z -> ((TypePlaceholder) z.getReturnType()).getName())
.collect(Collectors.toCollection(HashSet::new))) .collect(Collectors.toCollection(HashSet::new)))
.reduce((a, b) -> { .reduce((a, b) -> {
a.addAll(b); a.addAll(b);
return a; return a;
}).get(); }).get();
} }
public static Set<String> fieldTypeVarNames(List<ClassOrInterface> allClasses) { public static Set<String> fieldTypeVarNames(List<ClassOrInterface> allClasses) {
return allClasses.stream() return allClasses.stream()
.map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder) .map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder)
.map(z -> ((TypePlaceholder) z.getReturnType()).getName()) .map(z -> ((TypePlaceholder) z.getReturnType()).getName())
.collect(Collectors.toCollection(HashSet::new))) .collect(Collectors.toCollection(HashSet::new)))
.reduce((a, b) -> { .reduce((a, b) -> {
a.addAll(b); a.addAll(b);
return a; return a;
}).get(); }).get();
} }
/** /**
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine * Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine
* Variance !=0 hat auf alle Typvariablen in Theta. * Variance !=0 hat auf alle Typvariablen in Theta.
*
*
*/ */
public static Set<PlaceholderType> varianceInheritanceConstraintSet(ConstraintSet<UnifyPair> cons) { public static Set<PlaceholderType> varianceInheritanceConstraintSet(ConstraintSet<UnifyPair> cons) {
Set<UnifyPair> eq = cons.getAll(); Set<UnifyPair> eq = cons.getAll();
@@ -162,7 +179,7 @@ public class TypeInferenceHelper {
ArrayList<PlaceholderType> phSetVariance = new ArrayList<>(phSet); ArrayList<PlaceholderType> phSetVariance = new ArrayList<>(phSet);
phSetVariance.removeIf(x -> (x.getVariance() == 0)); phSetVariance.removeIf(x -> (x.getVariance() == 0));
while (!phSetVariance.isEmpty()) { while (!phSetVariance.isEmpty()) {
PlaceholderType a = phSetVariance.remove(0); PlaceholderType a = phSetVariance.removeFirst();
usedTPH.add(a); usedTPH.add(a);
// HashMap<PlaceholderType,Integer> ht = new HashMap<>(); // HashMap<PlaceholderType,Integer> ht = new HashMap<>();
// ht.put(a, a.getVariance()); // ht.put(a, a.getVariance());
@@ -171,8 +188,8 @@ public class TypeInferenceHelper {
// ((PlaceholderType)x.getLhsType()).equals(a))); // ((PlaceholderType)x.getLhsType()).equals(a)));
// durch if-Abfrage im foreach geloest // durch if-Abfrage im foreach geloest
cons.forEach(x -> { cons.forEach(x -> {
if (x.getLhsType() instanceof PlaceholderType && ((PlaceholderType) x.getLhsType()).equals(a)) { if (x.getLhsType() instanceof PlaceholderType && x.getLhsType().equals(a)) {
x.getRhsType().accept(new distributeVariance(), a.getVariance()); x.getRhsType().accept(new DistributeVariance(), a.getVariance());
} }
}); });
// ` eq1 = new HashSet<>(eq); // ` eq1 = new HashSet<>(eq);
@@ -180,8 +197,8 @@ public class TypeInferenceHelper {
// ((PlaceholderType)x.getRhsType()).equals(a))); // ((PlaceholderType)x.getRhsType()).equals(a)));
// durch if-Abfrage im foreach geloest // durch if-Abfrage im foreach geloest
cons.forEach(x -> { cons.forEach(x -> {
if (x.getRhsType() instanceof PlaceholderType && ((PlaceholderType) x.getRhsType()).equals(a)) { if (x.getRhsType() instanceof PlaceholderType && x.getRhsType().equals(a)) {
x.getLhsType().accept(new distributeVariance(), a.getVariance()); x.getLhsType().accept(new DistributeVariance(), a.getVariance());
} }
}); });
phSetVariance = new ArrayList<>(phSet); // macht vermutlich keinen Sinn PL 2018-10-18, doch, es koennen neue phSetVariance = new ArrayList<>(phSet); // macht vermutlich keinen Sinn PL 2018-10-18, doch, es koennen neue

View File

@@ -1,6 +1,5 @@
package de.dhbwstuttgart.typeinference.assumptions; package de.dhbwstuttgart.typeinference.assumptions;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
@@ -13,13 +12,13 @@ import de.dhbwstuttgart.typeinference.constraints.GenericsResolver;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class FieldAssumption extends Assumption{ public class FieldAssumption extends Assumption {
private ClassOrInterface receiverClass; private final ClassOrInterface receiverClass;
private RefTypeOrTPHOrWildcardOrGeneric type; private final RefTypeOrTPHOrWildcardOrGeneric type;
private String name; private final String name;
public FieldAssumption(String fieldName, ClassOrInterface receiverType, public FieldAssumption(String fieldName, ClassOrInterface receiverType,
RefTypeOrTPHOrWildcardOrGeneric type, TypeScope scope){ RefTypeOrTPHOrWildcardOrGeneric type, TypeScope scope) {
super(scope); super(scope);
this.type = type; this.type = type;
this.receiverClass = receiverType; this.receiverClass = receiverType;
@@ -36,11 +35,11 @@ public class FieldAssumption extends Assumption{
public RefTypeOrTPHOrWildcardOrGeneric getReceiverType(GenericsResolver resolver) { public RefTypeOrTPHOrWildcardOrGeneric getReceiverType(GenericsResolver resolver) {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(GenericTypeVar gtv : receiverClass.getGenerics()){ for (GenericTypeVar gtv : receiverClass.getGenerics()) {
//Hier wird ein GenericRefType gebildet, welcher einen für dieses Feld eindeutigen Namen hat //Hier wird ein GenericRefType gebildet, welcher einen für dieses Feld eindeutigen Namen hat
GenericRefType genericRefType = GenericRefType genericRefType =
new GenericRefType(gtv.getName() new GenericRefType(gtv.getName()
, new NullToken()); , new NullToken());
//Dieser wird dann korrekt aufgelöst vom Resolver: //Dieser wird dann korrekt aufgelöst vom Resolver:
params.add(resolver.resolve(genericRefType)); params.add(resolver.resolve(genericRefType));
} }

View File

@@ -7,13 +7,7 @@ import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import org.antlr.v4.runtime.Token;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -21,19 +15,19 @@ import java.util.Optional;
public class FunNClass extends ClassOrInterface { public class FunNClass extends ClassOrInterface {
public FunNClass(List<GenericRefType> funNParams) { public FunNClass(List<GenericRefType> funNParams) {
super(0, new JavaClassName("Fun"+(funNParams.size()-1)), new ArrayList<>(), Optional.empty() /* eingefuegt PL 2018-11-24 */, super(0, new JavaClassName("Fun" + (funNParams.size() - 1)), new ArrayList<>(), Optional.empty() /* eingefuegt PL 2018-11-24 */,
createMethods(funNParams), new ArrayList<>(), createGenerics(funNParams), createMethods(funNParams), new ArrayList<>(), createGenerics(funNParams),
ASTFactory.createObjectType(), true, new ArrayList<>(), new NullToken()); ASTFactory.createObjectType(), true, new ArrayList<>(), new NullToken());
} }
private static GenericDeclarationList createGenerics(List<GenericRefType> funNParams) { private static GenericDeclarationList createGenerics(List<GenericRefType> funNParams) {
//PL 2018-06-22: so geaendert, dass generierte Generics den Namen der funParams entsprechen. //PL 2018-06-22: so geaendert, dass generierte Generics den Namen der funParams entsprechen.
List<GenericTypeVar> generics = new ArrayList<>(); List<GenericTypeVar> generics = new ArrayList<>();
for(GenericRefType param : funNParams){ for (GenericRefType param : funNParams) {
generics.add(new GenericTypeVar(param.getParsedName(),//NameGenerator.makeNewName(), generics.add(new GenericTypeVar(param.getParsedName(),//NameGenerator.makeNewName(),
new ArrayList<>(), new NullToken(), new NullToken())); new ArrayList<>(), new NullToken(), new NullToken()));
} }
return new GenericDeclarationList(generics, new NullToken()); return new GenericDeclarationList(generics, new NullToken());
} }

View File

@@ -13,14 +13,14 @@ import de.dhbwstuttgart.typeinference.constraints.GenericsResolver;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class MethodAssumption extends Assumption{ public class MethodAssumption extends Assumption {
private ClassOrInterface receiver;
private RefTypeOrTPHOrWildcardOrGeneric retType;
List<? extends RefTypeOrTPHOrWildcardOrGeneric> params;
private final Boolean isInherited; private final Boolean isInherited;
List<? extends RefTypeOrTPHOrWildcardOrGeneric> params;
private final ClassOrInterface receiver;
private final RefTypeOrTPHOrWildcardOrGeneric retType;
public MethodAssumption(ClassOrInterface receiver, RefTypeOrTPHOrWildcardOrGeneric retType, public MethodAssumption(ClassOrInterface receiver, RefTypeOrTPHOrWildcardOrGeneric retType,
List<? extends RefTypeOrTPHOrWildcardOrGeneric> params, TypeScope scope, Boolean isInherited){ List<? extends RefTypeOrTPHOrWildcardOrGeneric> params, TypeScope scope, Boolean isInherited) {
super(scope); super(scope);
this.receiver = receiver; this.receiver = receiver;
this.retType = retType; this.retType = retType;
@@ -28,23 +28,16 @@ public class MethodAssumption extends Assumption{
this.isInherited = isInherited; this.isInherited = isInherited;
} }
/* public ClassOrInterface getReceiver() {
public RefType getReceiverType() {
return receiver; return receiver;
} }
*/
public ClassOrInterface getReceiver(){
return receiver;
}
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() { public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
return retType; return retType;
} }
public List<? extends RefTypeOrTPHOrWildcardOrGeneric> getArgTypes(){ public List<? extends RefTypeOrTPHOrWildcardOrGeneric> getArgTypes() {
return params; return params;
} }
public RefTypeOrTPHOrWildcardOrGeneric getReturnType(GenericsResolver resolver) { public RefTypeOrTPHOrWildcardOrGeneric getReturnType(GenericsResolver resolver) {
@@ -53,35 +46,31 @@ public class MethodAssumption extends Assumption{
public List<RefTypeOrTPHOrWildcardOrGeneric> getArgTypes(GenericsResolver resolver) { public List<RefTypeOrTPHOrWildcardOrGeneric> getArgTypes(GenericsResolver resolver) {
List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
for(RefTypeOrTPHOrWildcardOrGeneric param : params){ for (RefTypeOrTPHOrWildcardOrGeneric param : params) {
param = resolver.resolve(param); param = resolver.resolve(param);
ret.add(param); ret.add(param);
} }
return ret; return ret;
} }
/**
*
* @param resolver
* @return
*/
public RefTypeOrTPHOrWildcardOrGeneric getReceiverType(GenericsResolver resolver) { public RefTypeOrTPHOrWildcardOrGeneric getReceiverType(GenericsResolver resolver) {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(GenericTypeVar gtv : receiver.getGenerics()){ for (GenericTypeVar gtv : receiver.getGenerics()) {
//Die Generics werden alle zu TPHs umgewandelt. //Die Generics werden alle zu TPHs umgewandelt.
params.add(resolver.resolve(new GenericRefType(gtv.getName(), new NullToken()))); params.add(resolver.resolve(new GenericRefType(gtv.getName(), new NullToken())));
} }
RefTypeOrTPHOrWildcardOrGeneric receiverType; RefTypeOrTPHOrWildcardOrGeneric receiverType;
if(receiver instanceof FunNClass){ if (receiver instanceof FunNClass) {
receiverType = new RefType(new JavaClassName(receiver.getClassName().toString()+"$$"), params, new NullToken()); // new FunN(params); receiverType = new RefType(new JavaClassName(receiver.getClassName().toString() + "$$"), params, new NullToken()); // new FunN(params);
}else{ } else {
receiverType = new RefType(receiver.getClassName(), params, new NullToken()); receiverType = new RefType(receiver.getClassName(), params, new NullToken());
} }
return receiverType; return receiverType;
} }
public Boolean isInherited() { public Boolean isInherited() {
return isInherited; return isInherited;
} }
} }

View File

@@ -1,22 +1,13 @@
package de.dhbwstuttgart.typeinference.assumptions; package de.dhbwstuttgart.typeinference.assumptions;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.TypeScope; import de.dhbwstuttgart.syntaxtree.TypeScope;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Set;
import java.util.Stack;
import java.util.stream.Collectors;
public class TypeInferenceBlockInformation extends TypeInferenceInformation { public class TypeInferenceBlockInformation extends TypeInferenceInformation {
private TypeScope methodContext; private final TypeScope methodContext;
private ClassOrInterface currentClass; private final ClassOrInterface currentClass;
public TypeInferenceBlockInformation(Collection<ClassOrInterface> availableClasses, public TypeInferenceBlockInformation(Collection<ClassOrInterface> availableClasses,
ClassOrInterface currentClass, TypeScope methodContext) { ClassOrInterface currentClass, TypeScope methodContext) {
@@ -24,12 +15,15 @@ public class TypeInferenceBlockInformation extends TypeInferenceInformation {
this.methodContext = new TypeScopeContainer(currentClass, methodContext); this.methodContext = new TypeScopeContainer(currentClass, methodContext);
this.currentClass = currentClass; this.currentClass = currentClass;
} }
public TypeInferenceBlockInformation(TypeInferenceBlockInformation oldScope, TypeScope newScope) { public TypeInferenceBlockInformation(TypeInferenceBlockInformation oldScope, TypeScope newScope) {
this(oldScope.getAvailableClasses(), oldScope.currentClass, new TypeScopeContainer(oldScope.methodContext, newScope)); this(oldScope.getAvailableClasses(), oldScope.currentClass, new TypeScopeContainer(oldScope.methodContext, newScope));
} }
public ClassOrInterface getCurrentClass() { public ClassOrInterface getCurrentClass() {
return currentClass; return currentClass;
} }
public TypeScope getCurrentTypeScope() { public TypeScope getCurrentTypeScope() {
return methodContext; return methodContext;
} }

View File

@@ -1,20 +1,15 @@
package de.dhbwstuttgart.typeinference.assumptions; package de.dhbwstuttgart.typeinference.assumptions;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList; import de.dhbwstuttgart.syntaxtree.Field;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Set;
/* /*
Anmerkung: Anmerkung:
@@ -27,25 +22,25 @@ Zweiteres hat den Vorteil, dass bei der Entwicklung leichter Dinge hinzugefügt
Die ganze Logik steckt in dieser Klasse. Die ganze Logik steckt in dieser Klasse.
*/ */
public class TypeInferenceInformation { public class TypeInferenceInformation {
private Collection<ClassOrInterface> classes; private final Collection<ClassOrInterface> classes;
public TypeInferenceInformation(Collection<ClassOrInterface> availableClasses){ public TypeInferenceInformation(Collection<ClassOrInterface> availableClasses) {
classes = availableClasses; classes = availableClasses;
} }
public RefTypeOrTPHOrWildcardOrGeneric checkGTV(RefTypeOrTPHOrWildcardOrGeneric type){ public RefTypeOrTPHOrWildcardOrGeneric checkGTV(RefTypeOrTPHOrWildcardOrGeneric type) {
if(type instanceof GenericRefType){ if (type instanceof GenericRefType) {
return TypePlaceholder.fresh(new NullToken()); return TypePlaceholder.fresh(new NullToken());
}else{ } else {
return type; return type;
} }
} }
public List<FieldAssumption> getFields(String name){ public List<FieldAssumption> getFields(String name) {
List<FieldAssumption> ret = new ArrayList<>(); List<FieldAssumption> ret = new ArrayList<>();
for(ClassOrInterface cl : classes){ for (ClassOrInterface cl : classes) {
for(Field m : cl.getFieldDecl()){ for (Field m : cl.getFieldDecl()) {
if(m.getName().equals(name)){ if (m.getName().equals(name)) {
ret.add(new FieldAssumption(name, cl, m.getType(), new TypeScopeContainer(cl, m))); ret.add(new FieldAssumption(name, cl, m.getType(), new TypeScopeContainer(cl, m)));
} }

View File

@@ -12,7 +12,8 @@ import java.util.stream.Collectors;
public class TypeScopeContainer implements TypeScope { public class TypeScopeContainer implements TypeScope {
ArrayList<TypeScope> scopes = new ArrayList<>(); ArrayList<TypeScope> scopes = new ArrayList<>();
Stack<RefTypeOrTPHOrWildcardOrGeneric> types = new Stack<>(); Stack<RefTypeOrTPHOrWildcardOrGeneric> types = new Stack<>();
public TypeScopeContainer(TypeScope scope1, TypeScope scope2){
public TypeScopeContainer(TypeScope scope1, TypeScope scope2) {
scopes.add(scope1); scopes.add(scope1);
scopes.add(scope2); scopes.add(scope2);
types.push(scope1.getReturnType()); types.push(scope1.getReturnType());
@@ -22,11 +23,11 @@ public class TypeScopeContainer implements TypeScope {
@Override @Override
public Iterable<? extends GenericTypeVar> getGenerics() { public Iterable<? extends GenericTypeVar> getGenerics() {
return Iterables.concat(scopes.stream(). return Iterables.concat(scopes.stream().
map(TypeScope::getGenerics).collect(Collectors.toList()).toArray(new Iterable[0])); map(TypeScope::getGenerics).collect(Collectors.toList()).toArray(new Iterable[0]));
} }
@Override @Override
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() { public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
return types.peek(); return types.peek();
} }
} }

View File

@@ -1,69 +1,64 @@
package de.dhbwstuttgart.typeinference.constraints; package de.dhbwstuttgart.typeinference.constraints;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
public class Constraint<A> extends HashSet<A> { public class Constraint<A> extends HashSet<A> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private Boolean isInherited = false;//wird nur für die Method-Constraints benoetigt /*
* wird verwendet um bei der Codegenerierung die richtige Methoden - Signatur
/* * auszuwaehlen
* wird verwendet um bei der Codegenerierung die richtige Methoden - Signatur */
* auszuwaehlen /*private*/ Set<A> methodSignatureConstraint = new HashSet<>();
*/ private Boolean isInherited = false;//wird nur für die Method-Constraints benoetigt
/*private*/ Set<A> methodSignatureConstraint = new HashSet<>(); private Constraint<A> extendConstraint = null;
private Constraint<A> extendConstraint = null; public Constraint() {
super();
public Constraint() { }
super();
} public Constraint(Boolean isInherited) {
this.isInherited = isInherited;
public Constraint(Boolean isInherited) { }
this.isInherited = isInherited;
} public Constraint(Boolean isInherited, Constraint<A> extendConstraint, Set<A> methodSignatureConstraint) {
this.isInherited = isInherited;
public Constraint(Boolean isInherited, Constraint<A> extendConstraint, Set<A> methodSignatureConstraint) { this.extendConstraint = extendConstraint;
this.isInherited = isInherited; this.methodSignatureConstraint = methodSignatureConstraint;
this.extendConstraint = extendConstraint; }
this.methodSignatureConstraint = methodSignatureConstraint;
} public void setIsInherited(Boolean isInherited) {
this.isInherited = isInherited;
public void setIsInherited(Boolean isInherited) { }
this.isInherited = isInherited;
} public Boolean isInherited() {
return isInherited;
public Boolean isInherited() { }
return isInherited;
} public Constraint<A> getExtendConstraint() {
return extendConstraint;
public Constraint<A> getExtendConstraint() { }
return extendConstraint;
} public void setExtendConstraint(Constraint<A> c) {
extendConstraint = c;
public void setExtendConstraint(Constraint<A> c) { }
extendConstraint = c;
} public Set<A> getmethodSignatureConstraint() {
return methodSignatureConstraint;
public Set<A> getmethodSignatureConstraint() { }
return methodSignatureConstraint;
} public void setmethodSignatureConstraint(Set<A> c) {
methodSignatureConstraint = c;
public void setmethodSignatureConstraint(Set<A> c) { }
methodSignatureConstraint = c;
} public String toString() {
return super.toString() + "\nisInherited = " + isInherited
//" + extendsContraint: " + (extendConstraint != null ? extendConstraint.toStringBase() : "null" )
+ "\n";
}
public String toStringBase() {
return super.toString();
}
public String toString() {
return super.toString() + "\nisInherited = " + isInherited
//" + extendsContraint: " + (extendConstraint != null ? extendConstraint.toStringBase() : "null" )
+ "\n" ;
}
public String toStringBase() {
return super.toString();
}
} }

View File

@@ -1,9 +1,7 @@
package de.dhbwstuttgart.typeinference.constraints; package de.dhbwstuttgart.typeinference.constraints;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.unify.GuavaSetOperations; import de.dhbwstuttgart.typeinference.unify.GuavaSetOperations;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import java.util.*; import java.util.*;
import java.util.function.BinaryOperator; import java.util.function.BinaryOperator;
@@ -15,7 +13,7 @@ public class ConstraintSet<A> {
Constraint<A> undConstraints = new Constraint<>(); Constraint<A> undConstraints = new Constraint<>();
List<Set<Constraint<A>>> oderConstraints = new ArrayList<>(); List<Set<Constraint<A>>> oderConstraints = new ArrayList<>();
public void addUndConstraint(A p){ public void addUndConstraint(A p) {
undConstraints.add(p); undConstraints.add(p);
} }
@@ -23,28 +21,28 @@ public class ConstraintSet<A> {
oderConstraints.add(methodConstraints); oderConstraints.add(methodConstraints);
} }
public void addAllUndConstraint(Constraint<A> allUndConstraints){ public void addAllUndConstraint(Constraint<A> allUndConstraints) {
undConstraints.addAll(allUndConstraints); undConstraints.addAll(allUndConstraints);
} }
public void addAllOderConstraint(List<Set<Constraint<A>>> allOderConstraints){ public void addAllOderConstraint(List<Set<Constraint<A>>> allOderConstraints) {
this.oderConstraints.addAll(allOderConstraints); this.oderConstraints.addAll(allOderConstraints);
} }
public void addAll(ConstraintSet constraints) { public void addAll(ConstraintSet constraints) {
this.addAllUndConstraint(constraints.undConstraints); this.addAllUndConstraint(constraints.undConstraints);
this.addAllOderConstraint(constraints.oderConstraints); this.addAllOderConstraint(constraints.oderConstraints);
} }
@Override @Override
public String toString(){ public String toString() {
BinaryOperator<String> b = (x,y) -> x+y; BinaryOperator<String> b = (x, y) -> x + y;
return "\nUND:" + this.undConstraints.toString() + "\n" + return "\nUND:" + this.undConstraints.toString() + "\n" +
"ODER:" + this.oderConstraints.stream().reduce("", (x,y) -> x.toString()+ "\n" +y, b); "ODER:" + this.oderConstraints.stream().reduce("", (x, y) -> x + "\n" + y, b);
//cartesianProduct().toString(); //cartesianProduct().toString();
} }
public Set<List<Constraint<A>>> cartesianProduct(){ public Set<List<Constraint<A>>> cartesianProduct() {
Set<Constraint<A>> toAdd = new HashSet<>(); Set<Constraint<A>> toAdd = new HashSet<>();
toAdd.add(undConstraints); toAdd.add(undConstraints);
List<Set<Constraint<A>>> allConstraints = new ArrayList<>(); List<Set<Constraint<A>>> allConstraints = new ArrayList<>();
@@ -54,7 +52,7 @@ public class ConstraintSet<A> {
} }
public <B> ConstraintSet<B> map(Function<? super A, ? extends B> o) { public <B> ConstraintSet<B> map(Function<? super A, ? extends B> o) {
Hashtable<Constraint<A>,Constraint<B>> CSA2CSB = new Hashtable<>(); Hashtable<Constraint<A>, Constraint<B>> CSA2CSB = new Hashtable<>();
ConstraintSet<B> ret = new ConstraintSet<>(); ConstraintSet<B> ret = new ConstraintSet<>();
ret.undConstraints = undConstraints.stream().map(o).collect(Collectors.toCollection(Constraint<B>::new)); ret.undConstraints = undConstraints.stream().map(o).collect(Collectors.toCollection(Constraint<B>::new));
List<Set<Constraint<B>>> newOder = new ArrayList<>(); List<Set<Constraint<B>>> newOder = new ArrayList<>();
@@ -68,23 +66,23 @@ public class ConstraintSet<A> {
CSA2CSB.put(as, newConst);} ); CSA2CSB.put(as, newConst);} );
} }
*/ */
for(Set<Constraint<A>> oderConstraint : oderConstraints){ for (Set<Constraint<A>> oderConstraint : oderConstraints) {
newOder.add( newOder.add(
oderConstraint.parallelStream().map((Constraint<A> as) -> { oderConstraint.parallelStream().map((Constraint<A> as) -> {
Constraint<B> newConst = as.stream() Constraint<B> newConst = as.stream()
.map(o) .map(o)
.collect(Collectors.toCollection((as.getExtendConstraint() != null) .collect(Collectors.toCollection((as.getExtendConstraint() != null)
? () -> new Constraint<B> (as.isInherited(), ? () -> new Constraint<B>(as.isInherited(),
as.getExtendConstraint().stream().map(o).collect(Collectors.toCollection(Constraint::new)), as.getExtendConstraint().stream().map(o).collect(Collectors.toCollection(Constraint::new)),
as.getmethodSignatureConstraint().stream().map(o).collect(Collectors.toCollection(HashSet::new))) as.getmethodSignatureConstraint().stream().map(o).collect(Collectors.toCollection(HashSet::new)))
: () -> new Constraint<B> (as.isInherited()) : () -> new Constraint<B>(as.isInherited())
)); ));
//CSA2CSB.put(as, newConst); //CSA2CSB.put(as, newConst);
return newConst; return newConst;
/* /*
Constraint<B> bs = CSA2CSB.get(as); Constraint<B> bs = CSA2CSB.get(as);
@@ -93,36 +91,36 @@ public class ConstraintSet<A> {
} }
return bs; return bs;
*/ */
}).collect(Collectors.toSet()) }).collect(Collectors.toSet())
); );
} }
ret.oderConstraints = newOder; ret.oderConstraints = newOder;
return ret; return ret;
} }
public void forEach (Consumer<? super A> c) { public void forEach(Consumer<? super A> c) {
undConstraints.stream().forEach(c); undConstraints.stream().forEach(c);
for(Set<Constraint<A>> oderConstraint : oderConstraints){ for (Set<Constraint<A>> oderConstraint : oderConstraints) {
oderConstraint.parallelStream().forEach((Constraint<A> as) -> oderConstraint.parallelStream().forEach((Constraint<A> as) ->
as.stream().forEach(c)); as.stream().forEach(c));
} }
} }
public Set<A> getAll () { public Set<A> getAll() {
Set<A> ret = new HashSet<>(); Set<A> ret = new HashSet<>();
ret.addAll(undConstraints); ret.addAll(undConstraints);
for(Set<Constraint<A>> oderConstraint : oderConstraints){ for (Set<Constraint<A>> oderConstraint : oderConstraints) {
oderConstraint.parallelStream().forEach((Constraint<A> as) -> ret.addAll(as)); oderConstraint.parallelStream().forEach((Constraint<A> as) -> ret.addAll(as));
} }
return ret; return ret;
} }
public List<Set<Constraint<A>>> getOderConstraints() { public List<Set<Constraint<A>>> getOderConstraints() {
return oderConstraints; return oderConstraints;
} }
public Set<A> getUndConstraints() { public Set<A> getUndConstraints() {
return undConstraints; return undConstraints;
} }
} }

View File

@@ -1,14 +1,11 @@
package de.dhbwstuttgart.typeinference.constraints; package de.dhbwstuttgart.typeinference.constraints;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
/** /**
* Wird für Generics benötigt * Wird für Generics benötigt
* TODO: Erklörung! * TODO: Erklörung!
*/ */
public interface GenericsResolver { public interface GenericsResolver {
public RefTypeOrTPHOrWildcardOrGeneric resolve(RefTypeOrTPHOrWildcardOrGeneric generic); RefTypeOrTPHOrWildcardOrGeneric resolve(RefTypeOrTPHOrWildcardOrGeneric generic);
} }

View File

@@ -1,130 +1,44 @@
package de.dhbwstuttgart.typeinference.constraints; package de.dhbwstuttgart.typeinference.constraints;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
public class Pair implements Serializable
{ public class Pair implements Serializable {
public final RefTypeOrTPHOrWildcardOrGeneric TA1; public final RefTypeOrTPHOrWildcardOrGeneric TA1;
public final RefTypeOrTPHOrWildcardOrGeneric TA2; public final RefTypeOrTPHOrWildcardOrGeneric TA2;
private PairOperator eOperator = PairOperator.SMALLER; private PairOperator eOperator = PairOperator.SMALLER;
private Boolean noUnification = false; private Boolean noUnification = false;
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2 )
{ public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2) {
this.TA1 = TA1; this.TA1 = TA1;
this.TA2 = TA2; this.TA2 = TA2;
if(TA1 == null || TA2 == null) if (TA1 == null || TA2 == null)
throw new NullPointerException(); throw new NullPointerException();
eOperator = PairOperator.SMALLER; eOperator = PairOperator.SMALLER;
} }
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp) public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp) {
{
// Konstruktor // Konstruktor
this(TA1,TA2); this(TA1, TA2);
this.eOperator = eOp; this.eOperator = eOp;
} }
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp, Boolean noUnification) public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp, Boolean noUnification) {
{
// Konstruktor // Konstruktor
this(TA1,TA2); this(TA1, TA2);
this.eOperator = eOp; this.eOperator = eOp;
this.noUnification = noUnification; this.noUnification = noUnification;
} }
public String toString()
{
// otth: Gibt ein Paar als String aus --> zum Debuggen und Vergleichen
String strElement1 = "NULL";
String strElement2 = "NULL";
String Operator = "<.";
if( TA1 != null )
strElement1 = TA1.toString();
if( TA2 != null )
strElement2 = TA2.toString();
/* PL ausskommentiert 2018-05-24
if(OperatorEqual())
Operator = "=";
if(OperatorSmaller())
Operator = "<.";
if(OperatorSmallerExtends())
Operator = "<?";
*/
return "\n(" + strElement1 + " " + eOperator.toString() + " " + strElement2 + ")";
/*- Equals: " + bEqual*/
}
/**
* <br/>Author: J�rg B�uerle
* @param obj
* @return
*/
public boolean equals(Object obj)
{
boolean ret = true;
ret &= (obj instanceof Pair);
if(!ret)return ret;
ret &= ((Pair)obj).TA1.equals(this.TA1);
ret &= ((Pair)obj).TA2.equals(this.TA2);
return ret;
}
/**
* Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ Equal ist.
*/
public boolean OperatorEqual()
{
return eOperator == PairOperator.EQUALSDOT;
}
/**
* Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ Smaller ist.
*/
public boolean OperatorSmaller()
{
return eOperator == PairOperator.SMALLER;
}
/**
* Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ SmallerExtends ist.
*/
public boolean OperatorSmallerExtends()
{
return eOperator == PairOperator.SMALLERDOTWC;
}
/**
* Author: Arne Lüdtke<br/>
* Gibt den Operator zurück.
*/
public PairOperator GetOperator()
{
return eOperator;
}
public boolean OperatorSmallerDot() {
return eOperator == PairOperator.SMALLERDOT;
}
static public Map<String, TypePlaceholder> generateTPHMap(ConstraintSet<Pair> constraints) { static public Map<String, TypePlaceholder> generateTPHMap(ConstraintSet<Pair> constraints) {
HashMap<String, TypePlaceholder> ret = new HashMap<>(); HashMap<String, TypePlaceholder> ret = new HashMap<>();
constraints.map((Pair p) -> { constraints.map((Pair p) -> {
@@ -138,5 +52,82 @@ public class Pair implements Serializable
}); });
return ret; return ret;
} }
public String toString() {
// otth: Gibt ein Paar als String aus --> zum Debuggen und Vergleichen
String strElement1 = "NULL";
String strElement2 = "NULL";
String Operator = "<.";
if (TA1 != null)
strElement1 = TA1.toString();
if (TA2 != null)
strElement2 = TA2.toString();
/* PL ausskommentiert 2018-05-24
if(OperatorEqual())
Operator = "=";
if(OperatorSmaller())
Operator = "<.";
if(OperatorSmallerExtends())
Operator = "<?";
*/
return "\n(" + strElement1 + " " + eOperator.toString() + " " + strElement2 + ")";
/*- Equals: " + bEqual*/
}
/**
* <br/>Author: J�rg B�uerle
*
* @param obj
* @return
*/
public boolean equals(Object obj) {
boolean ret = true;
ret &= (obj instanceof Pair);
if (!ret) return ret;
ret &= ((Pair) obj).TA1.equals(this.TA1);
ret &= ((Pair) obj).TA2.equals(this.TA2);
return ret;
}
/**
* Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ Equal ist.
*/
public boolean OperatorEqual() {
return eOperator == PairOperator.EQUALSDOT;
}
/**
* Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ Smaller ist.
*/
public boolean OperatorSmaller() {
return eOperator == PairOperator.SMALLER;
}
/**
* Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ SmallerExtends ist.
*/
public boolean OperatorSmallerExtends() {
return eOperator == PairOperator.SMALLERDOTWC;
}
/**
* Author: Arne Lüdtke<br/>
* Gibt den Operator zurück.
*/
public PairOperator GetOperator() {
return eOperator;
}
public boolean OperatorSmallerDot() {
return eOperator == PairOperator.SMALLERDOT;
}
} }
// ino.end // ino.end

View File

@@ -1,10 +1,9 @@
package de.dhbwstuttgart.typeinference.result; package de.dhbwstuttgart.typeinference.result;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
public class GenericInsertPair { public class GenericInsertPair {
public TypePlaceholder TA1; public TypePlaceholder TA1;
public TypePlaceholder TA2; public TypePlaceholder TA2;
@@ -13,19 +12,13 @@ public class GenericInsertPair {
TA2 = superType; TA2 = superType;
} }
public GenericInsertPair(Pair pair) { public boolean contains(TypePlaceholder additionalTPH) {
TA1 = (TypePlaceholder) pair.TA1; if (TA1.equals(additionalTPH)) return true;
TA2 = (TypePlaceholder) pair.TA2; return TA2.equals(additionalTPH);
} }
public boolean contains(TypePlaceholder additionalTPH) {
if(TA1.equals(additionalTPH))return true;
if(TA2.equals(additionalTPH))return true;
return false;
}
@Override @Override
public String toString() { public String toString() {
return "GenIns(" + TA1.toString() + " < " + TA2.toString() + ")"; return "GenIns(" + TA1.toString() + " < " + TA2.toString() + ")";
} }
} }

View File

@@ -2,31 +2,22 @@ package de.dhbwstuttgart.typeinference.result;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
/** /**
* enthaelt alle Paare, die in einem Ergebnis nicht vorkommen koennen * Contains all pairs, that cannot be in a result.
* sie sind noetig fuer origPairs in PairTPHsmallerTPH, da hier auch * They are required for origPairs in PairTPHsmallerTPH, because there can
* Paare vorkommen koennen die keine Result sind (z.B. bei FunN$$) * be pairs as well, that are no results (e.g. FunN$$)
*/ */
public class PairNoResult extends ResultPair<RefTypeOrTPHOrWildcardOrGeneric, RefTypeOrTPHOrWildcardOrGeneric>{ public class PairNoResult extends ResultPair<RefTypeOrTPHOrWildcardOrGeneric, RefTypeOrTPHOrWildcardOrGeneric> {
//public final TypePlaceholder left;
//public final TypePlaceholder right;
/*
* urspruengliches Paar aus diesem dieses Resultpair erzeugt wurde
* wichtig fuer generated Generics
*/
ResultPair origPair;
public PairNoResult(RefTypeOrTPHOrWildcardOrGeneric left, RefTypeOrTPHOrWildcardOrGeneric right){ public PairNoResult(RefTypeOrTPHOrWildcardOrGeneric left, RefTypeOrTPHOrWildcardOrGeneric right) {
super(left, right); super(left, right);
} }
/* noch nicht implementiert. */ /* noch nicht implementiert. */
@Override @Override
public void accept(ResultPairVisitor visitor) { public void accept(ResultPairVisitor visitor) {
throw new NotImplementedException(); throw new NotImplementedException();
//visitor.visit(this); //visitor.visit(this);
} }
} }

View File

@@ -1,6 +1,5 @@
package de.dhbwstuttgart.typeinference.result; package de.dhbwstuttgart.typeinference.result;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
public class PairTPHEqualTPH extends ResultPair<TypePlaceholder, TypePlaceholder> { public class PairTPHEqualTPH extends ResultPair<TypePlaceholder, TypePlaceholder> {

View File

@@ -1,17 +1,16 @@
package de.dhbwstuttgart.typeinference.result; package de.dhbwstuttgart.typeinference.result;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
/** /**
* Steht für A =. RefType * Steht für A =. RefType
*/ */
public class PairTPHequalRefTypeOrWildcardType extends ResultPair{ public class PairTPHequalRefTypeOrWildcardType extends ResultPair<TypePlaceholder, RefTypeOrTPHOrWildcardOrGeneric> {
public final TypePlaceholder left; public final TypePlaceholder left;
public final RefTypeOrTPHOrWildcardOrGeneric right; public final RefTypeOrTPHOrWildcardOrGeneric right;
public PairTPHequalRefTypeOrWildcardType(TypePlaceholder left, RefTypeOrTPHOrWildcardOrGeneric right){ public PairTPHequalRefTypeOrWildcardType(TypePlaceholder left, RefTypeOrTPHOrWildcardOrGeneric right) {
super(left, right); super(left, right);
this.left = left; this.left = left;
this.right = right; this.right = right;
@@ -21,9 +20,9 @@ public class PairTPHequalRefTypeOrWildcardType extends ResultPair{
public void accept(ResultPairVisitor visitor) { public void accept(ResultPairVisitor visitor) {
visitor.visit(this); visitor.visit(this);
} }
@Override @Override
public String toString() { public String toString() {
return "(" + left.toString() + " = " + right.toString() + ")"; return "(" + left.toString() + " = " + right.toString() + ")";
} }
} }

View File

@@ -6,34 +6,37 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
/** /**
* Steht für: A <. B * Steht für: A <. B
*/ */
public class PairTPHsmallerTPH extends ResultPair{ public class PairTPHsmallerTPH extends ResultPair<TypePlaceholder, TypePlaceholder> {
public final TypePlaceholder left; public final TypePlaceholder left;
public final TypePlaceholder right; public final TypePlaceholder right;
/*
* urspruengliches Paar aus diesem dieses Resultpair erzeugt wurde
* wichtig fuer generated Generics
*/
ResultPair origPair;
public PairTPHsmallerTPH(TypePlaceholder left, TypePlaceholder right){ /**
* the original pair from which this result pair was generated. Important for generated generics
*/
ResultPair<? extends RefTypeOrTPHOrWildcardOrGeneric, ? extends RefTypeOrTPHOrWildcardOrGeneric> origPair;
public PairTPHsmallerTPH(TypePlaceholder left, TypePlaceholder right) {
super(left, right); super(left, right);
this.left = left; this.left = left;
this.right = right; this.right = right;
} }
public PairTPHsmallerTPH(TypePlaceholder left, TypePlaceholder right, ResultPair origPair){ public PairTPHsmallerTPH(
this(left, right); TypePlaceholder left,
this.origPair = origPair; TypePlaceholder right,
ResultPair<? extends RefTypeOrTPHOrWildcardOrGeneric, ? extends RefTypeOrTPHOrWildcardOrGeneric> origPair
) {
this(left, right);
this.origPair = origPair;
} }
@Override @Override
public void accept(ResultPairVisitor visitor) { public void accept(ResultPairVisitor visitor) {
visitor.visit(this); visitor.visit(this);
} }
@Override @Override
public String toString() { public String toString() {
return "(" + left.toString() + " < " + right.toString() + ")"; return "(" + left.toString() + " < " + right.toString() + ")";
} }
} }

View File

@@ -1,27 +1,20 @@
package de.dhbwstuttgart.typeinference.result; package de.dhbwstuttgart.typeinference.result;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import java.util.Set; public class ResolvedType {
public class ResolvedType{
private ResultPair<?, ?> resultPair;
public final RefTypeOrTPHOrWildcardOrGeneric resolvedType; public final RefTypeOrTPHOrWildcardOrGeneric resolvedType;
//public final Set<GenericInsertPair> additionalGenerics; private ResultPair<?, ?> resultPair;
public ResolvedType(RefTypeOrTPHOrWildcardOrGeneric resolvedType, Set<GenericInsertPair> additionalGenerics){ public ResolvedType(RefTypeOrTPHOrWildcardOrGeneric resolvedType) {
this.resolvedType = resolvedType; this.resolvedType = resolvedType;
//this.additionalGenerics = additionalGenerics;
} }
public void setResultPair(ResultPair<?, ?> resultPair) { public ResultPair<?, ?> getResultPair() {
this.resultPair = resultPair; return resultPair;
} }
public ResultPair<?, ?> getResultPair() { public void setResultPair(ResultPair<?, ?> resultPair) {
return resultPair; this.resultPair = resultPair;
} }
} }

View File

@@ -5,17 +5,17 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
/** /**
* Paare, welche das Unifikationsergebnis darstellen * Paare, welche das Unifikationsergebnis darstellen
*/ */
public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B extends RefTypeOrTPHOrWildcardOrGeneric> { public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric, B extends RefTypeOrTPHOrWildcardOrGeneric> {
private final A left; private final A left;
private final B right; private final B right;
public abstract void accept(ResultPairVisitor visitor); public ResultPair(A left, B right) {
public ResultPair(A left, B right){
this.left = left; this.left = left;
this.right = right; this.right = right;
} }
public abstract void accept(ResultPairVisitor visitor);
public A getLeft() { public A getLeft() {
return left; return left;
} }
@@ -23,40 +23,37 @@ public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B ext
public B getRight() { public B getRight() {
return right; return right;
} }
public String toString() { public String toString() {
return "(" + left.toString() + ", " + right.toString() + ")"; return "(" + left.toString() + ", " + right.toString() + ")";
} }
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result + ((left == null) ? 0 : left.getOffset().hashCode()); result = prime * result + ((left == null) ? 0 : left.getOffset().hashCode());
result = prime * result + ((right == null) ? 0 : right.getOffset().hashCode()); result = prime * result + ((right == null) ? 0 : right.getOffset().hashCode());
return result; return result;
} }
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ResultPair<?, ?> other = (ResultPair<?, ?>) obj;
if (left == null) {
if (other.left != null)
return false;
} else if (!left.getOffset().equals(other.left.getOffset()))
return false;
if (right == null) {
return other.right == null;
} else return right.getOffset().equals(other.right.getOffset());
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ResultPair<?,?> other = (ResultPair<?,?>) obj;
if (left == null) {
if (other.left != null)
return false;
} else if (!left.getOffset().equals(other.left.getOffset()))
return false;
if (right == null) {
if (other.right != null)
return false;
} else if (!right.getOffset().equals(other.right.getOffset()))
return false;
return true;
}
} }

View File

@@ -2,9 +2,11 @@ package de.dhbwstuttgart.typeinference.result;
public interface ResultPairVisitor { public interface ResultPairVisitor {
void visit(PairTPHsmallerTPH p); void visit(PairTPHsmallerTPH p);
void visit(PairTPHequalRefTypeOrWildcardType p); void visit(PairTPHequalRefTypeOrWildcardType p);
void visit(PairTPHEqualTPH p); void visit(PairTPHEqualTPH p);
//bisher nicht umgesetzt //bisher nicht umgesetzt
//void visit(PairNoResult p); //void visit(PairNoResult p);
} }

View File

@@ -1,44 +1,43 @@
package de.dhbwstuttgart.typeinference.result; package de.dhbwstuttgart.typeinference.result;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.type.*;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public class ResultSet { public class ResultSet {
public final Set<ResultPair> results; public final Set<ResultPair> results;
public Set<ResultPair<TypePlaceholder, TypePlaceholder>> genIns; public Set<ResultPair<TypePlaceholder, TypePlaceholder>> genIns;
public ResultSet(Set<ResultPair> set){ public ResultSet(Set<ResultPair> set) {
this.results = set; this.results = set;
this.genIns = new HashSet<>(); this.genIns = new HashSet<>();
results.forEach(x -> { if (x instanceof PairTPHsmallerTPH) { this.genIns.add(x);}} ); results.forEach(x -> {
if (x instanceof PairTPHsmallerTPH) {
this.genIns.add(x);
}
});
} }
public boolean contains(ResultPair toCheck) { public boolean contains(ResultPair toCheck) {
return this.results.contains(toCheck); return this.results.contains(toCheck);
} }
public void remove(ResultPair toCheck) { public void remove(ResultPair toCheck) {
results.remove(toCheck); results.remove(toCheck);
} }
public ResolvedType resolveType(RefTypeOrTPHOrWildcardOrGeneric type) { public ResolvedType resolveType(RefTypeOrTPHOrWildcardOrGeneric type) {
if(type instanceof TypePlaceholder) if (type instanceof TypePlaceholder)
return new Resolver(this).resolve((TypePlaceholder)type); return new Resolver(this).resolve((TypePlaceholder) type);
if(type instanceof GenericRefType)return new ResolvedType(type, new HashSet<>()); if (type instanceof GenericRefType) return new ResolvedType(type);
if(type instanceof RefType) { if (type instanceof RefType) {
RelatedTypeWalker related = new RelatedTypeWalker(null, this); RelatedTypeWalker related = new RelatedTypeWalker(null, this);
type.accept(related); type.accept(related);
return new ResolvedType(type, related.relatedTPHs); return new ResolvedType(type);
} else { } else {
throw new NotImplementedException(); throw new NotImplementedException();
//return new ResolvedType(type,new HashSet<>()); //return new ResolvedType(type,new HashSet<>());
@@ -46,74 +45,73 @@ public class ResultSet {
} }
public String toString() { public String toString() {
return results.toString(); return results.toString();
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (o instanceof ResultSet) { if (o instanceof ResultSet other) {
ResultSet other = (ResultSet)o; return this.results.equals(other.results);
return this.results.equals(other.results); } else {
} else { return false;
return false; }
} }
}
@Override @Override
public int hashCode() { public int hashCode() {
return results.hashCode(); return results.hashCode();
} }
} }
class Resolver implements ResultSetVisitor { class Resolver implements ResultSetVisitor {
private final ResultSet result; private final ResultSet result;
private final Set<GenericInsertPair> additionalTPHs = new HashSet<>();
private TypePlaceholder toResolve; private TypePlaceholder toResolve;
private RefTypeOrTPHOrWildcardOrGeneric resolved; private RefTypeOrTPHOrWildcardOrGeneric resolved;
private final Set<GenericInsertPair> additionalTPHs = new HashSet<>(); private ResultPair<?, ?> currentPair;
private ResultPair<?,?> currentPair;
public Resolver(ResultSet resultPairs){ public Resolver(ResultSet resultPairs) {
this.result = resultPairs; this.result = resultPairs;
} }
public ResolvedType resolve(TypePlaceholder tph){ public ResolvedType resolve(TypePlaceholder tph) {
toResolve = tph; toResolve = tph;
resolved = null; resolved = null;
System.out.println(tph.toString()); System.out.println(tph.toString());
for(ResultPair<?,?> resultPair : result.results) { for (ResultPair<?, ?> resultPair : result.results) {
if(resultPair instanceof PairTPHEqualTPH && ((PairTPHEqualTPH) resultPair).getLeft().equals(toResolve)){ if (resultPair instanceof PairTPHEqualTPH && ((PairTPHEqualTPH) resultPair).getLeft().equals(toResolve)) {
currentPair = resultPair; currentPair = resultPair;
return resolve(((PairTPHEqualTPH) resultPair).getRight()); return resolve(((PairTPHEqualTPH) resultPair).getRight());
} }
} }
for(ResultPair<?,?> resultPair : result.results){ for (ResultPair<?, ?> resultPair : result.results) {
currentPair = resultPair; currentPair = resultPair;
resultPair.accept(this); resultPair.accept(this);
} }
if(resolved==null){//TPH kommt nicht im Result vor: if (resolved == null) {//TPH kommt nicht im Result vor:
resolved = tph; resolved = tph;
} }
ResolvedType result = new ResolvedType(resolved, additionalTPHs);//resolved; ResolvedType result = new ResolvedType(resolved); //resolved;
result.setResultPair(currentPair); result.setResultPair(currentPair);
return result; return result;
} }
@Override @Override
public void visit(PairTPHsmallerTPH p) { public void visit(PairTPHsmallerTPH p) {
currentPair = p; currentPair = p;
if(p.left.equals(toResolve)){ if (p.left.equals(toResolve)) {
additionalTPHs.add(new GenericInsertPair(p.left, p.right)); additionalTPHs.add(new GenericInsertPair(p.left, p.right));
additionalTPHs.addAll(new RelatedTypeWalker(p.right, result).relatedTPHs); additionalTPHs.addAll(new RelatedTypeWalker(p.right, result).relatedTPHs);
} }
if(p.right.equals(toResolve)) if (p.right.equals(toResolve))
additionalTPHs.addAll(new RelatedTypeWalker(p.left, result).relatedTPHs); additionalTPHs.addAll(new RelatedTypeWalker(p.left, result).relatedTPHs);
} }
@Override @Override
public void visit(PairTPHequalRefTypeOrWildcardType p) { public void visit(PairTPHequalRefTypeOrWildcardType p) {
currentPair = p; currentPair = p;
if(p.left.equals(toResolve)){ if (p.left.equals(toResolve)) {
resolved = p.right; resolved = p.right;
RelatedTypeWalker related = new RelatedTypeWalker(null, result); RelatedTypeWalker related = new RelatedTypeWalker(null, result);
p.right.accept(related); p.right.accept(related);
@@ -150,8 +148,7 @@ class Resolver implements ResultSetVisitor {
public void visit(ExtendsWildcardType extendsWildcardType) { public void visit(ExtendsWildcardType extendsWildcardType) {
} }
} }
@@ -162,23 +159,23 @@ class Resolver implements ResultSetVisitor {
class TPHResolver implements ResultSetVisitor { class TPHResolver implements ResultSetVisitor {
private final TypePlaceholder tph; private final TypePlaceholder tph;
Set<GenericInsertPair> resolved = new HashSet<>();
private final ResultSet resultSet; private final ResultSet resultSet;
Set<GenericInsertPair> resolved = new HashSet<>();
TPHResolver(TypePlaceholder tph, ResultSet resultSet){ TPHResolver(TypePlaceholder tph, ResultSet resultSet) {
this.resultSet = resultSet; this.resultSet = resultSet;
this.tph = tph; this.tph = tph;
for(ResultPair p : resultSet.results){ for (ResultPair p : resultSet.results) {
p.accept(this); p.accept(this);
} }
if(resolved.size() == 0){ if (resolved.isEmpty()) {
resolved.add(new GenericInsertPair(tph, null)); resolved.add(new GenericInsertPair(tph, null));
} }
} }
@Override @Override
public void visit(PairTPHsmallerTPH p) { public void visit(PairTPHsmallerTPH p) {
if(p.left.equals(tph) || p.right.equals(tph)){ if (p.left.equals(tph) || p.right.equals(tph)) {
resolved.add(new GenericInsertPair(p.left, p.right)); resolved.add(new GenericInsertPair(p.left, p.right));
} }
} }
@@ -186,10 +183,10 @@ class TPHResolver implements ResultSetVisitor {
@Override @Override
public void visit(PairTPHequalRefTypeOrWildcardType p) { public void visit(PairTPHequalRefTypeOrWildcardType p) {
TypePlaceholder otherSide = null; TypePlaceholder otherSide = null;
if(p.right.equals(tph)){ if (p.right.equals(tph)) {
otherSide = p.left; otherSide = p.left;
} }
if(otherSide != null){ if (otherSide != null) {
Set<ResultPair> newResultSet = new HashSet<>(this.resultSet.results); Set<ResultPair> newResultSet = new HashSet<>(this.resultSet.results);
newResultSet.remove(p); newResultSet.remove(p);
resolved.addAll(new TPHResolver(otherSide, new ResultSet(newResultSet)).resolved); resolved.addAll(new TPHResolver(otherSide, new ResultSet(newResultSet)).resolved);
@@ -236,29 +233,30 @@ class RelatedTypeWalker implements ResultSetVisitor {
/** /**
* Läuft über das resultSet und speichert alle TPHs, welche mit start in Verbindung stehen * Läuft über das resultSet und speichert alle TPHs, welche mit start in Verbindung stehen
* @param start - kann null sein, wenn der Walker für einen RefType benutzt wird *
* @param start - kann null sein, wenn der Walker für einen RefType benutzt wird
* @param resultSet * @param resultSet
*/ */
RelatedTypeWalker(TypePlaceholder start, ResultSet resultSet){ RelatedTypeWalker(TypePlaceholder start, ResultSet resultSet) {
this.toResolve = start; this.toResolve = start;
this.resultSet = resultSet; this.resultSet = resultSet;
int resolved = 0; int resolved = 0;
do{ do {
resolved = relatedTPHs.size(); resolved = relatedTPHs.size();
for(ResultPair p : resultSet.results){ for (ResultPair p : resultSet.results) {
p.accept(this); p.accept(this);
p.accept(this); p.accept(this);
} }
}while(resolved - relatedTPHs.size() > 0); } while (resolved - relatedTPHs.size() > 0);
} }
@Override @Override
public void visit(PairTPHsmallerTPH p) { public void visit(PairTPHsmallerTPH p) {
if(p.getRight().equals(toResolve)){ if (p.getRight().equals(toResolve)) {
relatedTPHs.addAll(new TPHResolver(p.right, resultSet).resolved); relatedTPHs.addAll(new TPHResolver(p.right, resultSet).resolved);
//relatedTPHs.addAll(new RelatedTypeWalker(p.right, resultSet).relatedTPHs); //relatedTPHs.addAll(new RelatedTypeWalker(p.right, resultSet).relatedTPHs);
} }
if(p.getLeft().equals(toResolve)){ if (p.getLeft().equals(toResolve)) {
relatedTPHs.addAll(new TPHResolver(p.left, resultSet).resolved); relatedTPHs.addAll(new TPHResolver(p.left, resultSet).resolved);
//relatedTPHs.addAll(new RelatedTypeWalker(p.left, resultSet).relatedTPHs); //relatedTPHs.addAll(new RelatedTypeWalker(p.left, resultSet).relatedTPHs);
} }
@@ -266,7 +264,7 @@ class RelatedTypeWalker implements ResultSetVisitor {
@Override @Override
public void visit(PairTPHequalRefTypeOrWildcardType p) { public void visit(PairTPHequalRefTypeOrWildcardType p) {
if(p.getLeft().equals(toResolve)){ if (p.getLeft().equals(toResolve)) {
p.getRight().accept(this); p.getRight().accept(this);
} }
} }
@@ -283,7 +281,7 @@ class RelatedTypeWalker implements ResultSetVisitor {
@Override @Override
public void visit(RefType refType) { public void visit(RefType refType) {
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){ for (RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()) {
param.accept(this); param.accept(this);
} }
} }
@@ -306,4 +304,4 @@ class RelatedTypeWalker implements ResultSetVisitor {
@Override @Override
public void visit(GenericRefType genericRefType) { public void visit(GenericRefType genericRefType) {
} }
} }

View File

@@ -2,7 +2,7 @@ package de.dhbwstuttgart.typeinference.result;
import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.*;
public interface ResultSetVisitor extends ResultPairVisitor{ public interface ResultSetVisitor extends ResultPairVisitor {
void visit(RefType refType); void visit(RefType refType);

View File

@@ -1,6 +1,5 @@
package de.dhbwstuttgart.typeinference.typeAlgo; package de.dhbwstuttgart.typeinference.typeAlgo;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.typeinference.constraints.GenericsResolver; import de.dhbwstuttgart.typeinference.constraints.GenericsResolver;
@@ -9,25 +8,24 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
/** /**
* Ein GenericsResolver, welcher Generics mit dem selben Namen den selben TPH zuordnet * A generics resolver, which assigns generics with the same name to the same TPH
*/ */
public class GenericsResolverSameName implements GenericsResolver, TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric>{ public class GenericsResolverSameName implements GenericsResolver, TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric> {
HashMap<String, TypePlaceholder> map = new HashMap<>(); HashMap<String, TypePlaceholder> map = new HashMap<>();
@Override @Override
public RefTypeOrTPHOrWildcardOrGeneric resolve(RefTypeOrTPHOrWildcardOrGeneric generic) { public RefTypeOrTPHOrWildcardOrGeneric resolve(RefTypeOrTPHOrWildcardOrGeneric generic) {
return generic.acceptTV(this); return generic.acceptTV(this);
} }
@Override @Override
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) { public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){ for (RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()) {
params.add(param.acceptTV(this)); params.add(param.acceptTV(this));
} }
RefType ret = new RefType(refType.getName(), params, refType.getOffset()); return new RefType(refType.getName(), params, refType.getOffset());
return ret;
} }
@Override @Override
@@ -48,7 +46,7 @@ public class GenericsResolverSameName implements GenericsResolver, TypeVisitor<R
@Override @Override
public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) { public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) {
String name = genericRefType.getParsedName(); String name = genericRefType.getParsedName();
if(!map.containsKey(name)){ if (!map.containsKey(name)) {
map.put(name, TypePlaceholder.fresh(genericRefType.getOffset())); map.put(name, TypePlaceholder.fresh(genericRefType.getOffset()));
} }
return map.get(name); return map.get(name);

View File

@@ -1,49 +1,48 @@
package de.dhbwstuttgart.typeinference.typeAlgo; package de.dhbwstuttgart.typeinference.typeAlgo;
import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.syntaxtree.Constructor;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.statement.Statement;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.util.BiRelation; import de.dhbwstuttgart.typeinference.constraints.Pair;
import java.util.*; import java.util.Collection;
public class TYPE { public class TYPE {
private final Collection<SourceFile> sfs; private final Collection<SourceFile> sfs;
private final TypeInferenceInformation typeInferenceInformation; private final TypeInferenceInformation typeInferenceInformation;
public TYPE(Collection<SourceFile> sourceFiles, Collection<ClassOrInterface> allAvailableClasses){ public TYPE(Collection<SourceFile> sourceFiles, Collection<ClassOrInterface> allAvailableClasses) {
sfs = sourceFiles; sfs = sourceFiles;
this.typeInferenceInformation = new TypeInferenceInformation(allAvailableClasses); this.typeInferenceInformation = new TypeInferenceInformation(allAvailableClasses);
} }
public ConstraintSet getConstraints() { public ConstraintSet<Pair> getConstraints() {
ConstraintSet ret = new ConstraintSet(); ConstraintSet<Pair> ret = new ConstraintSet<>();
for(SourceFile sf : sfs) for (SourceFile sf : sfs)
for (ClassOrInterface cl : sf.KlassenVektor) { for (ClassOrInterface cl : sf.KlassenVektor) {
ret.addAll(getConstraintsClass(cl ,typeInferenceInformation)); ret.addAll(getConstraintsClass(cl, typeInferenceInformation));
} }
return ret; return ret;
} }
private ConstraintSet getConstraintsClass(ClassOrInterface cl, TypeInferenceInformation info) { private ConstraintSet<Pair> getConstraintsClass(ClassOrInterface cl, TypeInferenceInformation info) {
ConstraintSet ret = new ConstraintSet(); ConstraintSet<Pair> ret = new ConstraintSet<>();
ConstraintSet methConstrains;
for(Method m : cl.getMethods()){ for (Method m : cl.getMethods()) {
ret.addAll(methConstrains = getConstraintsMethod(m,info, cl)); ConstraintSet<Pair> methConstrains = getConstraintsMethod(m, info, cl);
ret.addAll(methConstrains);
m.constraints.addAll(methConstrains); m.constraints.addAll(methConstrains);
} }
for(Constructor m : cl.getConstructors()){ for (Constructor m : cl.getConstructors()) {
ret.addAll(getConstraintsConstructor(m,info, cl)); ret.addAll(getConstraintsConstructor(m, info, cl));
} }
if (cl.getfieldInitializations().isPresent()) { if (cl.getfieldInitializations().isPresent()) {
ret.addAll(getConstraintsConstructor(cl.getfieldInitializations().get(), info, cl)); ret.addAll(getConstraintsConstructor(cl.getfieldInitializations().get(), info, cl));
} }
return ret; return ret;
} }
@@ -68,20 +67,20 @@ public class TYPE {
return new TypeInferenceInformation(classes); return new TypeInferenceInformation(classes);
} }
*/ */
private ConstraintSet getConstraintsMethod(Method m, TypeInferenceInformation info, ClassOrInterface currentClass) { private ConstraintSet<Pair> getConstraintsMethod(Method m, TypeInferenceInformation info, ClassOrInterface currentClass) {
if(m.block == null)return new ConstraintSet(); //Abstrakte Methoden generieren keine Constraints if (m.block == null) return new ConstraintSet<>(); //Abstrakte Methoden generieren keine Constraints
TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m); TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m);
TYPEStmt methodScope = new TYPEStmt(blockInfo); TYPEStmt methodScope = new TYPEStmt(blockInfo);
m.block.accept(methodScope); m.block.accept(methodScope);
return methodScope.getConstraints(); return methodScope.getConstraints();
} }
private ConstraintSet getConstraintsConstructor(Constructor m, TypeInferenceInformation info, ClassOrInterface currentClass) { private ConstraintSet<Pair> getConstraintsConstructor(Constructor m, TypeInferenceInformation info, ClassOrInterface currentClass) {
TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m); TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m);
TYPEStmt methodScope = new TYPEStmt(blockInfo); TYPEStmt methodScope = new TYPEStmt(blockInfo);
//for(Statement stmt : m.fieldInitializations)stmt.accept(methodScope); //for(Statement stmt : m.fieldInitializations)stmt.accept(methodScope);
ConstraintSet ret = this.getConstraintsMethod(m, info, currentClass); ConstraintSet<Pair> ret = this.getConstraintsMethod(m, info, currentClass);
ret.addAll(methodScope.getConstraints()); ret.addAll(methodScope.getConstraints());
return ret; return ret;
} }

View File

@@ -11,43 +11,47 @@ import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator; import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption; import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.FunNClass; import de.dhbwstuttgart.typeinference.assumptions.FunNClass;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption; import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.*; import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.unify.model.ExtendsType; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.GenericsResolver;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.util.BiRelation;
import java.util.*; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
public class TYPEStmt implements StatementVisitor{ public class TYPEStmt implements StatementVisitor {
private final TypeInferenceBlockInformation info; private final TypeInferenceBlockInformation info;
private final ConstraintSet constraintsSet = new ConstraintSet(); private final ConstraintSet<Pair> constraintsSet = new ConstraintSet<>();
private final RefType number = new RefType(ASTFactory.createClass(Number.class).getClassName(), new NullToken());
private final RefType longg = new RefType(ASTFactory.createClass(Long.class).getClassName(), new NullToken());
private final RefType integer = new RefType(ASTFactory.createClass(Integer.class).getClassName(), new NullToken());
private final RefType shortt = new RefType(ASTFactory.createClass(Short.class).getClassName(), new NullToken());
private final RefType bytee = new RefType(ASTFactory.createClass(Byte.class).getClassName(), new NullToken());
private final RefType floatt = new RefType(ASTFactory.createClass(Float.class).getClassName(), new NullToken());
private final RefType doublee = new RefType(ASTFactory.createClass(Double.class).getClassName(), new NullToken());
private final RefType string = new RefType(ASTFactory.createClass(String.class).getClassName(), new NullToken());
private final RefType bool = new RefType(ASTFactory.createClass(Boolean.class).getClassName(), new NullToken());
public TYPEStmt(TypeInferenceBlockInformation info){ public TYPEStmt(TypeInferenceBlockInformation info) {
this.info = info; this.info = info;
} }
public ConstraintSet getConstraints() {
return constraintsSet;
}
/** /**
* Erstellt einen neuen GenericResolver * Creates a new GenericsResolver
* Die Idee dieser Datenstruktur ist es, GTVs einen eindeutigen TPH zuzuweisen. * The idea behind this data-structure is to assign a unique TPH to GTVs.
* Bei Methodenaufrufen oder anderen Zugriffen, bei denen alle benutzten GTVs jeweils einen einheitlichen TPH bekommen müssen * On method calls or other accesses where all used GTVs must get a unique TPH, this class can be used.
* kann diese Klasse eingesetzt werden. Wichtig ist, dass hierfür jeweils eine frische Instanz benutzt wird. * It is important to always use a fresh instance for that.
* @return
*/ */
private static GenericsResolver getResolverInstance(){ private static GenericsResolver getResolverInstance() {
return new GenericsResolverSameName(); return new GenericsResolverSameName();
} }
@@ -55,10 +59,73 @@ public class TYPEStmt implements StatementVisitor{
return null; return null;
} }
public static List<MethodAssumption> getMethods(String name, int numArgs, TypeInferenceBlockInformation info) {
List<MethodAssumption> ret = new ArrayList<>();
//TODO: apply Methoden wieder anfügen. Diese könnten möglicherweise auch in den Assumptions auftauchen (überdenken)
if (name.equals("apply")) {
List<GenericRefType> funNParams = new ArrayList<>();
for (int i = 0; i < numArgs + 1; i++) {
//funNParams.add(TypePlaceholder.fresh(new NullToken()));
funNParams.add(new GenericRefType(NameGenerator.makeNewName(),
new NullToken()));
}
funNParams.get(funNParams.size() - 1);
ret.add(new MethodAssumption(new FunNClass(funNParams), funNParams.get(funNParams.size() - 1), funNParams.subList(0, funNParams.size() - 1),
new TypeScope() {
@Override
public Iterable<? extends GenericTypeVar> getGenerics() {
throw new NotImplementedException();
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
throw new NotImplementedException();
}
}, false));
}
for (ClassOrInterface cl : info.getAvailableClasses()) {
for (Method m : cl.getMethods()) {
if (m.getName().equals(name) &&
m.getParameterList().getFormalparalist().size() == numArgs) {
RefTypeOrTPHOrWildcardOrGeneric retType = m.getReturnType();//info.checkGTV(m.getReturnType());
ret.add(new MethodAssumption(cl, retType, convertParams(m.getParameterList(), info),
createTypeScope(cl, m), m.isInherited));
}
}
}
return ret;
}
public static List<MethodAssumption> getMethods(String name, ArgumentList arglist, TypeInferenceBlockInformation info) {
return getMethods(name, arglist.getArguments().size(), info);
}
protected static List<RefTypeOrTPHOrWildcardOrGeneric> convertParams(ParameterList parameterList, TypeInferenceBlockInformation info) {
//TODO: Hier müssen die Parameter mit den TPHs in den GEnerics des Receivers verknüpft werden
/*
Beispiel:
auto test = new List<String>();
test.add("hallo");
Hier kriegt der Receiver ja den COnstraint TPH REceiver <. List<TPH A>
Dann mus bei dem Parameter der COnstraint entstehen: TPH A <. String
*/
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for (FormalParameter fp : parameterList.getFormalparalist()) {
params.add(fp.getType()); //info.checkGTV(fp.getType())); //PL 2018-06-22 GTV sollen in Argumenten erhalten bleiben
}
return params;
}
public ConstraintSet<Pair> getConstraints() {
return constraintsSet;
}
@Override @Override
public void visit(ArgumentList arglist) { public void visit(ArgumentList arglist) {
for(int i = 0;i<arglist.getArguments().size();i++){ for (int i = 0; i < arglist.getArguments().size(); i++) {
arglist.getArguments().get(i).accept(this); arglist.getArguments().get(i).accept(this);
} }
} }
@@ -69,13 +136,12 @@ public class TYPEStmt implements StatementVisitor{
lambdaParams.add(tphRetType); lambdaParams.add(tphRetType);
//lambdaParams.add(0,tphRetType); //lambdaParams.add(0,tphRetType);
constraintsSet.addUndConstraint( constraintsSet.addUndConstraint(
new Pair(lambdaExpression.getType(), new Pair(lambdaExpression.getType(),
new RefType(new JavaClassName("Fun"+(lambdaParams.size()-1)+"$$"), lambdaParams, new NullToken()), new RefType(new JavaClassName("Fun" + (lambdaParams.size() - 1) + "$$"), lambdaParams, new NullToken()),
//new FunN(lambdaParams), PairOperator.EQUALSDOT));
PairOperator.EQUALSDOT));
constraintsSet.addUndConstraint( constraintsSet.addUndConstraint(
new Pair(lambdaExpression.getReturnType(), new Pair(lambdaExpression.getReturnType(),
tphRetType,PairOperator.EQUALSDOT)); tphRetType, PairOperator.EQUALSDOT));
//Constraints des Bodys generieren: //Constraints des Bodys generieren:
TYPEStmt lambdaScope = new TYPEStmt(new TypeInferenceBlockInformation(info, lambdaExpression)); TYPEStmt lambdaScope = new TYPEStmt(new TypeInferenceBlockInformation(info, lambdaExpression));
@@ -88,12 +154,12 @@ public class TYPEStmt implements StatementVisitor{
assign.lefSide.accept(this); assign.lefSide.accept(this);
assign.rightSide.accept(this); assign.rightSide.accept(this);
constraintsSet.addUndConstraint(new Pair( constraintsSet.addUndConstraint(new Pair(
assign.rightSide.getType(), assign.lefSide.getType(), PairOperator.SMALLERDOT)); assign.rightSide.getType(), assign.lefSide.getType(), PairOperator.SMALLERDOT));
} }
@Override @Override
public void visit(Block block) { public void visit(Block block) {
for(Statement stmt : block.getStatements()){ for (Statement stmt : block.getStatements()) {
stmt.accept(this); stmt.accept(this);
} }
} }
@@ -111,17 +177,17 @@ public class TYPEStmt implements StatementVisitor{
@Override @Override
public void visit(FieldVar fieldVar) { public void visit(FieldVar fieldVar) {
fieldVar.receiver.accept(this); fieldVar.receiver.accept(this);
Set<Constraint> oderConstraints = new HashSet<>(); Set<Constraint<Pair>> oderConstraints = new HashSet<>();
for(FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)){ for (FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)) {
Constraint constraint = new Constraint(); Constraint<Pair> constraint = new Constraint<>();
GenericsResolver resolver = getResolverInstance(); GenericsResolver resolver = getResolverInstance();
constraint.add(new Pair(fieldVar.receiver.getType(), fieldAssumption.getReceiverType(resolver), PairOperator.SMALLERDOT)); //PL 2019-12-09: SMALLERDOT eingefuegt, EQUALSDOT entfernt, wenn ds Field privat ist muesste es EQUALSDOT lauten constraint.add(new Pair(fieldVar.receiver.getType(), fieldAssumption.getReceiverType(resolver), PairOperator.SMALLERDOT)); //PL 2019-12-09: SMALLERDOT eingefuegt, EQUALSDOT entfernt, wenn ds Field privat ist muesste es EQUALSDOT lauten
constraint.add(new Pair( constraint.add(new Pair(
fieldVar.getType(), fieldAssumption.getType(resolver), PairOperator.EQUALSDOT)); fieldVar.getType(), fieldAssumption.getType(resolver), PairOperator.EQUALSDOT));
oderConstraints.add(constraint); oderConstraints.add(constraint);
} }
if(oderConstraints.size() == 0) if (oderConstraints.isEmpty())
throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset()); throw new TypeinferenceException("Kein Feld " + fieldVar.fieldVarName + " gefunden", fieldVar.getOffset());
constraintsSet.addOderConstraint(oderConstraints); constraintsSet.addOderConstraint(oderConstraints);
} }
@@ -141,7 +207,7 @@ public class TYPEStmt implements StatementVisitor{
ifStmt.then_block.accept(this); ifStmt.then_block.accept(this);
//Beide Blöcke müssen den gleichen Supertyp haben, welcher den Rückgabetyp des If-Stmts darstellt //Beide Blöcke müssen den gleichen Supertyp haben, welcher den Rückgabetyp des If-Stmts darstellt
constraintsSet.addUndConstraint(new Pair(ifStmt.else_block.getType(), ifStmt.getType(), PairOperator.SMALLERDOT)); constraintsSet.addUndConstraint(new Pair(ifStmt.else_block.getType(), ifStmt.getType(), PairOperator.SMALLERDOT));
if(ifStmt.else_block != null){ if (ifStmt.else_block != null) {
ifStmt.else_block.accept(this); ifStmt.else_block.accept(this);
constraintsSet.addUndConstraint(new Pair(ifStmt.else_block.getType(), ifStmt.getType(), PairOperator.SMALLERDOT)); constraintsSet.addUndConstraint(new Pair(ifStmt.else_block.getType(), ifStmt.getType(), PairOperator.SMALLERDOT));
} }
@@ -155,30 +221,30 @@ public class TYPEStmt implements StatementVisitor{
@Override @Override
public void visit(LocalVar localVar) { public void visit(LocalVar localVar) {
// Es werden nur bei Feldvariablen Constraints generiert. Lokale Variablen sind eindeutig // Constraints are only generated for field variables. Local variables are unambiguous
} }
@Override @Override
public void visit(LocalVarDecl localVarDecl) { public void visit(LocalVarDecl localVarDecl) {
//Hier ist nichts zu tun. Allen lokalen Variablen bekommen beim parsen schon den korrekten Typ // Nothing to do here. All local variables get their correct type already while being parsed
} }
@Override @Override
//Es wird in OderConstraints davon ausgegangen dass die Bedingungen für die Typen der Argumente links stehen // In oder-constraints it is assumed, that the conditions for the argument types are placed left
//und die Typen der Rückgabewerte immer rechts stehen (vgl. JavaTXCompiler) // and the types of the return values are placed right (see JavaTXCompiler)
public void visit(MethodCall methodCall) { public void visit(MethodCall methodCall) {
methodCall.receiver.accept(this); methodCall.receiver.accept(this);
//Overloading: //Overloading:
Set<Constraint<Pair>> methodConstraints = new HashSet<>(); Set<Constraint<Pair>> methodConstraints = new HashSet<>();
for(MethodAssumption m : this.getMethods(methodCall.name, methodCall.arglist, info)){ for (MethodAssumption m : getMethods(methodCall.name, methodCall.arglist, info)) {
GenericsResolver resolver = getResolverInstance(); GenericsResolver resolver = getResolverInstance();
Set<Constraint<Pair>> oneMethodConstraints = generateConstraint(methodCall, m, info, resolver); Set<Constraint<Pair>> oneMethodConstraints = generateConstraint(methodCall, m, info, resolver);
methodConstraints.addAll(oneMethodConstraints); methodConstraints.addAll(oneMethodConstraints);
/* pl 2023-01-20: in generateConstraint bereits umgesetzt /* pl 2023-01-20: in generateConstraint bereits umgesetzt
Constraint<Pair> extendsOneMethodConstraint = oneMethodConstraint.stream() Constraint<Pair> extendsOneMethodConstraint = oneMethodConstraint.stream()
.map(x -> (x.TA1 instanceof TypePlaceholder && .map(x -> (x.TA1 instanceof TypePlaceholder &&
x.GetOperator() == PairOperator.EQUALSDOT && x.GetOperator() == PairOperator.EQUALSDOT &&
!(x.TA2 instanceof TypePlaceholder)) !(x.TA2 instanceof TypePlaceholder))
? new Pair(x.TA1, new ExtendsWildcardType(x.TA2, x.TA2.getOffset()), PairOperator.EQUALSDOT) ? new Pair(x.TA1, new ExtendsWildcardType(x.TA2, x.TA2.getOffset()), PairOperator.EQUALSDOT)
@@ -189,8 +255,8 @@ public class TYPEStmt implements StatementVisitor{
methodConstraints.add(extendsOneMethodConstraint); methodConstraints.add(extendsOneMethodConstraint);
*/ */
} }
if(methodConstraints.size()<1){ if (methodConstraints.isEmpty()) {
throw new TypeinferenceException("Methode "+methodCall.name+" ist nicht vorhanden!",methodCall.getOffset()); throw new TypeinferenceException("Methode " + methodCall.name + " ist nicht vorhanden!", methodCall.getOffset());
} }
constraintsSet.addOderConstraint(methodConstraints); constraintsSet.addOderConstraint(methodConstraints);
} }
@@ -198,12 +264,12 @@ public class TYPEStmt implements StatementVisitor{
@Override @Override
public void visit(NewClass methodCall) { public void visit(NewClass methodCall) {
//Overloading: //Overloading:
Set<Constraint> methodConstraints = new HashSet<>(); Set<Constraint<Pair>> methodConstraints = new HashSet<>();
for(MethodAssumption m : this.getConstructors(info, (RefType) methodCall.getType(), methodCall.getArgumentList())){ for (MethodAssumption m : this.getConstructors(info, (RefType) methodCall.getType(), methodCall.getArgumentList())) {
methodConstraints.add(generateConstructorConstraint(methodCall, m, info, getResolverInstance())); methodConstraints.add(generateConstructorConstraint(methodCall, m, info, getResolverInstance()));
} }
if(methodConstraints.size()<1){ if (methodConstraints.isEmpty()) {
throw new TypeinferenceException("Konstruktor in Klasse "+methodCall.getType().toString()+" ist nicht vorhanden!",methodCall.getOffset()); throw new TypeinferenceException("Konstruktor in Klasse " + methodCall.getType().toString() + " ist nicht vorhanden!", methodCall.getOffset());
} }
constraintsSet.addOderConstraint(methodConstraints); constraintsSet.addOderConstraint(methodConstraints);
} }
@@ -218,132 +284,122 @@ public class TYPEStmt implements StatementVisitor{
receiver.expr.accept(this); receiver.expr.accept(this);
} }
private final RefType number = new RefType(ASTFactory.createClass(Number.class).getClassName(), new NullToken());
private final RefType longg = new RefType(ASTFactory.createClass(Long.class).getClassName(), new NullToken());
private final RefType integer = new RefType(ASTFactory.createClass(Integer.class).getClassName(), new NullToken());
private final RefType shortt = new RefType(ASTFactory.createClass(Short.class).getClassName(), new NullToken());
private final RefType bytee = new RefType(ASTFactory.createClass(Byte.class).getClassName(), new NullToken());
private final RefType floatt = new RefType(ASTFactory.createClass(Float.class).getClassName(), new NullToken());
private final RefType doublee = new RefType(ASTFactory.createClass(Double.class).getClassName(), new NullToken());
private final RefType string = new RefType(ASTFactory.createClass(String.class).getClassName(), new NullToken());
private final RefType bool = new RefType(ASTFactory.createClass(Boolean.class).getClassName(), new NullToken());
@Override @Override
public void visit(UnaryExpr unaryExpr) { public void visit(UnaryExpr unaryExpr) {
if(unaryExpr.operation == UnaryExpr.Operation.POSTDECREMENT || if (unaryExpr.operation == UnaryExpr.Operation.POSTDECREMENT ||
unaryExpr.operation == UnaryExpr.Operation.POSTINCREMENT || unaryExpr.operation == UnaryExpr.Operation.POSTINCREMENT ||
unaryExpr.operation == UnaryExpr.Operation.PREDECREMENT || unaryExpr.operation == UnaryExpr.Operation.PREDECREMENT ||
unaryExpr.operation == UnaryExpr.Operation.PREINCREMENT){ unaryExpr.operation == UnaryExpr.Operation.PREINCREMENT) {
//@see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.14.2 //@see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.14.2
//Expression muss zu Numeric Convertierbar sein. also von Numeric erben // Expression must be convertable to Numeric and also inherit from Numeric
constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), number, PairOperator.SMALLERNEQDOT)); constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), number, PairOperator.SMALLERNEQDOT));
//The type of the postfix increment expression is the type of the variable // The type of the postfix increment expression is the type of the variable
constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), unaryExpr.getType(), PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), unaryExpr.getType(), PairOperator.EQUALSDOT));
}else{ } else {
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
@Override @Override
//Es wird in OderConstraints davon ausgegangen dass die Bedingungen für die Typen der Argumente links stehen // In oder-constraints it is assumed, that the conditions for the argument types are placed left
//und die Typen der Rückgabewerte immer rechts stehen (vgl. JavaTXCompiler) // and the types of the return values are placed right (see JavaTXCompiler)
public void visit(BinaryExpr binary) { public void visit(BinaryExpr binary) {
binary.lexpr.accept(this); binary.lexpr.accept(this);
binary.rexpr.accept(this); binary.rexpr.accept(this);
if(binary.operation.equals(BinaryExpr.Operator.DIV) || if (binary.operation.equals(BinaryExpr.Operator.DIV) ||
binary.operation.equals(BinaryExpr.Operator.MUL)|| binary.operation.equals(BinaryExpr.Operator.MUL) ||
binary.operation.equals(BinaryExpr.Operator.MOD)|| binary.operation.equals(BinaryExpr.Operator.MOD) ||
binary.operation.equals(BinaryExpr.Operator.ADD)|| binary.operation.equals(BinaryExpr.Operator.ADD) ||
binary.operation.equals(BinaryExpr.Operator.SUB)) { binary.operation.equals(BinaryExpr.Operator.SUB)) {
Set<Constraint<Pair>> numericAdditionOrStringConcatenation = new HashSet<>(); Set<Constraint<Pair>> numericAdditionOrStringConcatenation = new HashSet<>();
// TODO PL 2018-11-06 // TODO PL 2018-11-06
// Auf importierte Typen einschraenken // Auf importierte Typen einschraenken
// pruefen, ob Typen richtig bestimmt werden. // pruefen, ob Typen richtig bestimmt werden.
//Zuerst der Fall für Numerische AusdrücPairOpnumericeratorke, das sind Mul, Mod und Div immer: //Zuerst der Fall für Numerische AusdrücPairOpnumericeratorke, das sind Mul, Mod und Div immer:
//see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17 //see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17
//Expression muss zu Numeric Convertierbar sein. also von Numeric erben //Expression muss zu Numeric Convertierbar sein. also von Numeric erben
Constraint<Pair> numeric; Constraint<Pair> numeric;
//PL eingefuegt 2018-07-17 //PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(bytee.getName())) { if (info.getAvailableClasses().stream().map(ClassOrInterface::getClassName).collect(Collectors.toCollection(HashSet::new)).contains(bytee.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), bytee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.lexpr.getType(), bytee, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), bytee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), bytee, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), integer, PairOperator.EQUALSDOT)); numeric.add(new Pair(binary.getType(), integer, PairOperator.EQUALSDOT));
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
//PL eingefuegt 2018-07-17 //PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(shortt.getName())) { if (info.getAvailableClasses().stream().map(ClassOrInterface::getClassName).collect(Collectors.toCollection(HashSet::new)).contains(shortt.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), shortt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.lexpr.getType(), shortt, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), shortt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), shortt, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), integer, PairOperator.EQUALSDOT)); numeric.add(new Pair(binary.getType(), integer, PairOperator.EQUALSDOT));
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
//PL eingefuegt 2018-07-17 //PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(integer.getName())) { if (info.getAvailableClasses().stream().map(ClassOrInterface::getClassName).collect(Collectors.toCollection(HashSet::new)).contains(integer.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), integer, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.lexpr.getType(), integer, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), integer, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), integer, PairOperator.SMALLERDOT));
numeric.add(new Pair(integer, binary.getType(), PairOperator.EQUALSDOT)); numeric.add(new Pair(integer, binary.getType(), PairOperator.EQUALSDOT));
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
//PL eingefuegt 2018-07-17 //PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(longg.getName())) { if (info.getAvailableClasses().stream().map(ClassOrInterface::getClassName).collect(Collectors.toCollection(HashSet::new)).contains(longg.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), longg, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.lexpr.getType(), longg, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), longg, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), longg, PairOperator.SMALLERDOT));
numeric.add(new Pair(longg, binary.getType(), PairOperator.EQUALSDOT)); numeric.add(new Pair(longg, binary.getType(), PairOperator.EQUALSDOT));
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
//PL eingefuegt 2018-07-17 //PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(floatt.getName())) { if (info.getAvailableClasses().stream().map(ClassOrInterface::getClassName).collect(Collectors.toCollection(HashSet::new)).contains(floatt.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), floatt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.lexpr.getType(), floatt, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), floatt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), floatt, PairOperator.SMALLERDOT));
numeric.add(new Pair(floatt, binary.getType(), PairOperator.EQUALSDOT)); numeric.add(new Pair(floatt, binary.getType(), PairOperator.EQUALSDOT));
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
//PL eingefuegt 2018-07-17 //PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(doublee.getName())) { if (info.getAvailableClasses().stream().map(ClassOrInterface::getClassName).collect(Collectors.toCollection(HashSet::new)).contains(doublee.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), doublee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.lexpr.getType(), doublee, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT));
numeric.add(new Pair(doublee, binary.getType(), PairOperator.EQUALSDOT)); numeric.add(new Pair(doublee, binary.getType(), PairOperator.EQUALSDOT));
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
/* PL auskommentiert Anfang 2018-07-17 /* PL auskommentiert Anfang 2018-07-17
/* /*
In Java passiert bei den binären Operatoren eine sogenannte Type Promotion: In Java passiert bei den binären Operatoren eine sogenannte Type Promotion:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2 https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2
Das bedeutet, dass Java die Typen je nach belieben castet, so lange sie nur von Number erben Das bedeutet, dass Java die Typen je nach belieben castet, so lange sie nur von Number erben
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.getType(), number, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), number, PairOperator.SMALLERDOT));
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
* PL auskommentiert Ende 2018-07-17 */ * PL auskommentiert Ende 2018-07-17 */
if(binary.operation.equals(BinaryExpr.Operator.ADD)) { if (binary.operation.equals(BinaryExpr.Operator.ADD)) {
//Dann kann der Ausdruck auch das aneinanderfügen zweier Strings sein: ("a" + "b") oder (1 + 2) //Dann kann der Ausdruck auch das aneinanderfügen zweier Strings sein: ("a" + "b") oder (1 + 2)
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(string.getName())) { if (info.getAvailableClasses().stream().map(ClassOrInterface::getClassName).collect(Collectors.toCollection(HashSet::new)).contains(string.getName())) {
Constraint<Pair> stringConcat = new Constraint<>(); Constraint<Pair> stringConcat = new Constraint<>();
stringConcat.add(new Pair(binary.lexpr.getType(), string, PairOperator.EQUALSDOT)); stringConcat.add(new Pair(binary.lexpr.getType(), string, PairOperator.EQUALSDOT));
stringConcat.add(new Pair(binary.rexpr.getType(), string, PairOperator.EQUALSDOT)); stringConcat.add(new Pair(binary.rexpr.getType(), string, PairOperator.EQUALSDOT));
stringConcat.add(new Pair(string, binary.getType(), PairOperator.EQUALSDOT)); stringConcat.add(new Pair(string, binary.getType(), PairOperator.EQUALSDOT));
numericAdditionOrStringConcatenation.add(stringConcat); numericAdditionOrStringConcatenation.add(stringConcat);
} }
} }
if(numericAdditionOrStringConcatenation.size()<1){ if (numericAdditionOrStringConcatenation.isEmpty()) {
throw new TypeinferenceException("Kein Typ für " + binary.operation.toString() + " vorhanden", binary.getOffset()); throw new TypeinferenceException("Kein Typ für " + binary.operation + " vorhanden", binary.getOffset());
} }
constraintsSet.addOderConstraint(numericAdditionOrStringConcatenation); constraintsSet.addOderConstraint(numericAdditionOrStringConcatenation);
}else if(binary.operation.equals(BinaryExpr.Operator.LESSEQUAL) || } else if (binary.operation.equals(BinaryExpr.Operator.LESSEQUAL) ||
binary.operation.equals(BinaryExpr.Operator.BIGGEREQUAL) || binary.operation.equals(BinaryExpr.Operator.BIGGEREQUAL) ||
binary.operation.equals(BinaryExpr.Operator.BIGGERTHAN) || binary.operation.equals(BinaryExpr.Operator.BIGGERTHAN) ||
binary.operation.equals(BinaryExpr.Operator.LESSTHAN)) { binary.operation.equals(BinaryExpr.Operator.LESSTHAN)) {
/* //eingefuegt PL 2018-05-24 /* //eingefuegt PL 2018-05-24
Set<Constraint<Pair>> numericRelationConcatenation = new HashSet<>(); Set<Constraint<Pair>> numericRelationConcatenation = new HashSet<>();
Constraint<Pair> numeric = new Constraint<>(); Constraint<Pair> numeric = new Constraint<>();
@@ -376,13 +432,13 @@ public class TYPEStmt implements StatementVisitor{
numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT));
numericRelationConcatenation.add(numeric); numericRelationConcatenation.add(numeric);
//***ACHTUNG: Moeglicherweise oder und und-Contraint falsch //***ACHTUNG: Moeglicherweise oder und und-Contraint falsch
constraintsSet.addOderConstraint(numericRelationConcatenation); constraintsSet.addOderConstraint(numericRelationConcatenation);
//***ACHTUNG: Moeglicherweise oder und und-Contraint falsch //***ACHTUNG: Moeglicherweise oder und und-Contraint falsch
*/ */
//Testeise eingefuegt PL 2018-05-24 //Testeise eingefuegt PL 2018-05-24
//Hier sollte evtl. noch importe angefragt werden PL 2019-05-07 //Hier sollte evtl. noch importe angefragt werden PL 2019-05-07
constraintsSet.addUndConstraint(new Pair(binary.lexpr.getType(), number, PairOperator.SMALLERNEQDOT)); constraintsSet.addUndConstraint(new Pair(binary.lexpr.getType(), number, PairOperator.SMALLERNEQDOT));
constraintsSet.addUndConstraint(new Pair(binary.rexpr.getType(), number, PairOperator.SMALLERNEQDOT)); constraintsSet.addUndConstraint(new Pair(binary.rexpr.getType(), number, PairOperator.SMALLERNEQDOT));
//Rückgabetyp ist Boolean //Rückgabetyp ist Boolean
@@ -393,109 +449,103 @@ public class TYPEStmt implements StatementVisitor{
//constraintsSet.addUndConstraint(new Pair(binary.rexpr.getType(), number, PairOperator.SMALLERDOT)); //constraintsSet.addUndConstraint(new Pair(binary.rexpr.getType(), number, PairOperator.SMALLERDOT));
//Rückgabetyp ist Boolean //Rückgabetyp ist Boolean
//constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT)); //constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT));
}else if(binary.operation.equals(BinaryExpr.Operator.EQUAL) || binary.operation.equals(BinaryExpr.Operator.NOTEQUAL)){ } else if (binary.operation.equals(BinaryExpr.Operator.EQUAL) || binary.operation.equals(BinaryExpr.Operator.NOTEQUAL)) {
/*Auszug aus https://docs.oracle.com/javase/specs/jls/se9/html/jls-15.html#jls-15.21 /*Auszug aus https://docs.oracle.com/javase/specs/jls/se9/html/jls-15.html#jls-15.21
The equality operators may be used to compare two operands that are convertible (§5.1.8) to numeric type, or two operands of type boolean or Boolean, or two operands that are each of either reference type or the null type. All other cases result in a compile-time error. The equality operators may be used to compare two operands that are convertible (§5.1.8) to numeric type, or two operands of type boolean or Boolean, or two operands that are each of either reference type or the null type. All other cases result in a compile-time error.
*/ */
//Der Equals Operator geht mit fast allen Typen, daher werden hier keine Constraints gesetzt //Der Equals Operator geht mit fast allen Typen, daher werden hier keine Constraints gesetzt
constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT));
}else{ } else {
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
@Override @Override
public void visit(Literal literal) { public void visit(Literal literal) {
//Nothing to do here. Literale erzeugen keine Constraints //PL 2018-06-23 Literale haben einen Typ. Der muesste hier eingefuegt werden
//PL 2018-06-23 Sie haben einen Typ. Der muesste hier eingefuegt werden //wie hier fuer double gezeigt. Im Moment auskommentiert, weil zu wenige Literaltypen
//wie hier fuer double gezeigt. Im Momment auskommentiert, weil zu wenige Literaltypen //funktionieren
//funktionieren if (literal.value instanceof Short) {
if (literal.value instanceof Short) { constraintsSet.addUndConstraint(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT));
constraintsSet.addUndConstraint(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT)); return;
return; }
} if (literal.value instanceof Byte) {
if (literal.value instanceof Byte) { constraintsSet.addUndConstraint(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT));
constraintsSet.addUndConstraint(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT)); return;
return; }
} if (literal.value instanceof Float) {
if (literal.value instanceof Float) { constraintsSet.addUndConstraint(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT));
constraintsSet.addUndConstraint(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT)); return;
return; }
} if (literal.value instanceof Double) {
if (literal.value instanceof Double) { constraintsSet.addUndConstraint(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT));
constraintsSet.addUndConstraint(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT)); return;
return; }
} if (literal.value instanceof Long) {
if (literal.value instanceof Long) { constraintsSet.addUndConstraint(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT));
constraintsSet.addUndConstraint(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT)); return;
return; }
} if (literal.value instanceof Integer) {
if (literal.value instanceof Integer) { HashSet<JavaClassName> clNames = info.getAvailableClasses().stream().map(ClassOrInterface::getClassName).collect(Collectors.toCollection(HashSet::new));
//constraintsSet.addUndConstraint(new Pair(literal.getType(),integer, PairOperator.EQUALSDOT)); Set<Constraint<Pair>> oderConstraints = new HashSet<>();
// /* Constraint<Pair> constraint = new Constraint<>();
HashSet<JavaClassName> clNames = info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)); constraint.add(new Pair(literal.getType(), integer, PairOperator.EQUALSDOT));
Set<Constraint> oderConstraints = new HashSet<>(); oderConstraints.add(constraint);
Constraint constraint = new Constraint(); if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Double"))) {
constraint.add(new Pair(literal.getType(), integer, PairOperator.EQUALSDOT)); constraint = new Constraint<>();
oderConstraints.add(constraint); constraint.add(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT));
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Double")).findAny().isPresent()) { oderConstraints.add(constraint);
constraint = new Constraint(); }
constraint.add(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT)); if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Long"))) {
oderConstraints.add(constraint); constraint = new Constraint<>();
} constraint.add(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT));
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Long")).findAny().isPresent()) { oderConstraints.add(constraint);
constraint = new Constraint(); }
constraint.add(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT)); if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Float"))) {
oderConstraints.add(constraint); constraint = new Constraint<>();
} constraint.add(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT));
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Float")).findAny().isPresent()) { oderConstraints.add(constraint);
constraint = new Constraint(); }
constraint.add(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT)); if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Short"))) {
oderConstraints.add(constraint); constraint = new Constraint<>();
} constraint.add(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT));
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Short")).findAny().isPresent()) { oderConstraints.add(constraint);
constraint = new Constraint(); }
constraint.add(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT)); if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Byte"))) {
oderConstraints.add(constraint); constraint = new Constraint<>();
} constraint.add(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT));
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Byte")).findAny().isPresent()) { oderConstraints.add(constraint);
constraint = new Constraint(); }
constraint.add(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT)); constraintsSet.addOderConstraint(oderConstraints);
oderConstraints.add(constraint); return;
} }
constraintsSet.addOderConstraint(oderConstraints); if (literal.value instanceof Short) {
// */ constraintsSet.addUndConstraint(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT));
return; return;
} }
if (literal.value instanceof Short) { if (literal.value instanceof Byte) {
constraintsSet.addUndConstraint(new Pair(literal.getType(),shortt, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT));
return; return;
} }
if (literal.value instanceof Byte) { if (literal.value instanceof Float) {
constraintsSet.addUndConstraint(new Pair(literal.getType(),bytee, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT));
return; return;
} }
if (literal.value instanceof Float) { if (literal.value instanceof String) {
constraintsSet.addUndConstraint(new Pair(literal.getType(),floatt, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), string, PairOperator.EQUALSDOT));
return; return;
} }
if (literal.value instanceof String) { if (literal.value instanceof Boolean) {
constraintsSet.addUndConstraint(new Pair(literal.getType(),string, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), bool, PairOperator.EQUALSDOT));
return; } else {
} throw new NotImplementedException();
if (literal.value instanceof Boolean) { }
constraintsSet.addUndConstraint(new Pair(literal.getType(),bool, PairOperator.EQUALSDOT));
return;
}
else {
throw new NotImplementedException();
}
} }
@Override @Override
public void visit(Return returnExpr) { public void visit(Return returnExpr) {
returnExpr.retexpr.accept(this); returnExpr.retexpr.accept(this);
constraintsSet.addUndConstraint(new Pair(returnExpr.getType(),info.getCurrentTypeScope().getReturnType(), PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(returnExpr.getType(), info.getCurrentTypeScope().getReturnType(), PairOperator.EQUALSDOT));
} }
@Override @Override
@@ -518,36 +568,22 @@ public class TYPEStmt implements StatementVisitor{
//Im Falle von this, müssen die Generics in der Klasse als RefTypes behandelt werden. //Im Falle von this, müssen die Generics in der Klasse als RefTypes behandelt werden.
ClassOrInterface currentClass = info.getCurrentClass(); ClassOrInterface currentClass = info.getCurrentClass();
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(GenericTypeVar gtv : currentClass.getGenerics()){ for (GenericTypeVar gtv : currentClass.getGenerics()) {
params.add(new GenericRefType(gtv.getName(), aThis.getOffset())); params.add(new GenericRefType(gtv.getName(), aThis.getOffset()));
} }
RefType thisType = new RefType(currentClass.getClassName(), params, aThis.getOffset()); RefType thisType = new RefType(currentClass.getClassName(), params, aThis.getOffset());
constraintsSet.addUndConstraint(new Pair( constraintsSet.addUndConstraint(new Pair(
aThis.getType(), thisType, PairOperator.EQUALSDOT)); aThis.getType(), thisType, PairOperator.EQUALSDOT));
}
private static TypeScope createNullTypeScope() {
return new TypeScope() {
@Override
public Iterable<? extends GenericTypeVar> getGenerics() {
return new ArrayList<>();
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
return null;
}
};
} }
@Override @Override
public void visit(WhileStmt whileStmt) { public void visit(WhileStmt whileStmt) {
RefType booleanType = new RefType(ASTFactory.createClass(java.lang.Boolean.class).getClassName(), new NullToken()); RefType booleanType = new RefType(ASTFactory.createClass(java.lang.Boolean.class).getClassName(), new NullToken());
//Expression inferieren: // Infer expression:
whileStmt.expr.accept(this); whileStmt.expr.accept(this);
//Expression muss boolean sein: // Expression must be boolean:
constraintsSet.addUndConstraint(new Pair(whileStmt.expr.getType(), booleanType, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(whileStmt.expr.getType(), booleanType, PairOperator.EQUALSDOT));
//LoopBlock inferieren: // Infer loopBlock:
whileStmt.loopBlock.accept(this); whileStmt.loopBlock.accept(this);
} }
@@ -556,11 +592,15 @@ public class TYPEStmt implements StatementVisitor{
throw new NotImplementedException(); throw new NotImplementedException();
} }
/*
METHOD CALL Section:
*/
@Override @Override
public void visit(AssignToField assignLeftSide) { public void visit(AssignToField assignLeftSide) {
//Hier ist kein Code nötig. Es werden keine extra Constraints generiert //Hier ist kein Code nötig. Es werden keine extra Constraints generiert
//HIER muss Code rein PL 2018-10-24 //HIER muss Code rein PL 2018-10-24
assignLeftSide.field.accept(this); assignLeftSide.field.accept(this);
} }
@Override @Override
@@ -573,63 +613,48 @@ public class TYPEStmt implements StatementVisitor{
//TODO: Für einen super-Call werden keine Constraints erzeugt bisher //TODO: Für einen super-Call werden keine Constraints erzeugt bisher
} }
/*
METHOD CALL Section:
*/
protected Set<Constraint<Pair>> generateConstraint(MethodCall forMethod, MethodAssumption assumption, protected Set<Constraint<Pair>> generateConstraint(MethodCall forMethod, MethodAssumption assumption,
TypeInferenceBlockInformation info, GenericsResolver resolver){ TypeInferenceBlockInformation info, GenericsResolver resolver) {
Constraint<Pair> methodConstraint, extendsMethodConstraint; Constraint<Pair> methodConstraint, extendsMethodConstraint;
methodConstraint = new Constraint<>(assumption.isInherited()); methodConstraint = new Constraint<>(assumption.isInherited());
extendsMethodConstraint = new Constraint<>(assumption.isInherited());// PL 2023-01-24: Ersetzt die Dopplung in visit(MethodCall) extendsMethodConstraint = new Constraint<>(assumption.isInherited());// PL 2023-01-24: Ersetzt die Dopplung in visit(MethodCall)
ClassOrInterface receiverCl = assumption.getReceiver();
/*
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(GenericTypeVar gtv : receiverCl.getGenerics()){
//Die Generics werden alle zu TPHs umgewandelt.
params.add(resolver.resolve(gtv.getName()));
}
RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(assumption.getReceiver().getClassName(), params, forMethod.getOffset());
*/
RefTypeOrTPHOrWildcardOrGeneric receiverType = assumption.getReceiverType(resolver); RefTypeOrTPHOrWildcardOrGeneric receiverType = assumption.getReceiverType(resolver);
methodConstraint.add(new Pair(forMethod.receiver.getType(), receiverType, PairOperator.EQUALSDOT));//PL 2020-03-17 SMALLERDOT in EQUALSDOT umgewandelt, weil alle geerbten Methoden in den jeweilen Klassen enthalten sind. methodConstraint.add(new Pair(forMethod.receiver.getType(), receiverType, PairOperator.EQUALSDOT));//PL 2020-03-17 SMALLERDOT in EQUALSDOT umgewandelt, weil alle geerbten Methoden in den jeweilen Klassen enthalten sind.
//PL 2023-01-24: dafuer ? extends receiverType noch ergaenzt //PL 2023-01-24: dafuer ? extends receiverType noch ergaenzt
extendsMethodConstraint.add(new Pair(forMethod.receiver.getType(), new ExtendsWildcardType(receiverType, receiverType.getOffset()), PairOperator.EQUALSDOT)); extendsMethodConstraint.add(new Pair(forMethod.receiver.getType(), new ExtendsWildcardType(receiverType, receiverType.getOffset()), PairOperator.EQUALSDOT));
//gegenseite Verschraenkung der beiden Mengen von Typannahmen //gegenseite Verschraenkung der beiden Mengen von Typannahmen
methodConstraint.setExtendConstraint(extendsMethodConstraint); methodConstraint.setExtendConstraint(extendsMethodConstraint);
extendsMethodConstraint.setExtendConstraint(methodConstraint); extendsMethodConstraint.setExtendConstraint(methodConstraint);
//Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ANFANG //Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ANFANG
//methodConstraint.add(new Pair(forMethod.receiverType, retType, //methodConstraint.add(new Pair(forMethod.receiverType, retType,
// PairOperator.EQUALSDOT)); // PairOperator.EQUALSDOT));
//Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ENDE //Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ENDE
methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT)); methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT));
extendsMethodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT)); extendsMethodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT));
//methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT)); //methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT));
//extendsMethodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT)); //extendsMethodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT));
((TypePlaceholder)forMethod.getType()).setOrCons((byte)-1);//fuer Maximums-Bestimmung ((TypePlaceholder) forMethod.getType()).setOrCons((byte) -1);//fuer Maximums-Bestimmung
Set<Pair> parameterContraints = generateParameterConstraints(forMethod, assumption, info, resolver); Set<Pair> parameterContraints = generateParameterConstraints(forMethod, assumption, info, resolver);
methodConstraint.addAll(parameterContraints); methodConstraint.addAll(parameterContraints);
extendsMethodConstraint.addAll(parameterContraints); extendsMethodConstraint.addAll(parameterContraints);
Set<Pair> methodSignatureConstraint = generatemethodSignatureConstraint(forMethod, assumption, info, resolver); Set<Pair> methodSignatureConstraint = generatemethodSignatureConstraint(forMethod, assumption, info, resolver);
System.out.println("methodSignatureConstraint; " + methodSignatureConstraint); System.out.println("methodSignatureConstraint; " + methodSignatureConstraint);
methodConstraint.setmethodSignatureConstraint(methodSignatureConstraint); methodConstraint.setmethodSignatureConstraint(methodSignatureConstraint);
extendsMethodConstraint.setmethodSignatureConstraint(methodSignatureConstraint); extendsMethodConstraint.setmethodSignatureConstraint(methodSignatureConstraint);
Set<Constraint<Pair>> ret = new HashSet<>(); Set<Constraint<Pair>> ret = new HashSet<>();
ret.add(methodConstraint); ret.add(methodConstraint);
ret.add(extendsMethodConstraint); ret.add(extendsMethodConstraint);
@@ -639,107 +664,46 @@ public class TYPEStmt implements StatementVisitor{
protected Set<Pair> generateParameterConstraints(MethodCall foMethod, MethodAssumption assumption, protected Set<Pair> generateParameterConstraints(MethodCall foMethod, MethodAssumption assumption,
TypeInferenceBlockInformation info, GenericsResolver resolver) { TypeInferenceBlockInformation info, GenericsResolver resolver) {
Set<Pair> ret = new HashSet<>(); Set<Pair> ret = new HashSet<>();
for(int i = 0;i<foMethod.arglist.getArguments().size();i++){ for (int i = 0; i < foMethod.arglist.getArguments().size(); i++) {
foMethod.arglist.getArguments().get(i).accept(this); foMethod.arglist.getArguments().get(i).accept(this);
RefTypeOrTPHOrWildcardOrGeneric argType = foMethod.arglist.getArguments().get(i).getType(); RefTypeOrTPHOrWildcardOrGeneric argType = foMethod.arglist.getArguments().get(i).getType();
RefTypeOrTPHOrWildcardOrGeneric assType = assumption.getArgTypes(resolver).get(i); RefTypeOrTPHOrWildcardOrGeneric assType = assumption.getArgTypes(resolver).get(i);
ret.add(new Pair(argType, assType, PairOperator.SMALLERDOT)); ret.add(new Pair(argType, assType, PairOperator.SMALLERDOT));
//Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ANFANG //Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ANFANG
// ret.add(new Pair(foMethod.argTypes.get(i), assType, PairOperator.EQUALSDOT)); // ret.add(new Pair(foMethod.argTypes.get(i), assType, PairOperator.EQUALSDOT));
//Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ENDE //Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ENDE
} }
return ret; return ret;
} }
protected Set<Pair> generatemethodSignatureConstraint(MethodCall foMethod, MethodAssumption assumption, protected Set<Pair> generatemethodSignatureConstraint(MethodCall foMethod, MethodAssumption assumption,
TypeInferenceBlockInformation info, GenericsResolver resolver) { TypeInferenceBlockInformation info, GenericsResolver resolver) {
Set<Pair> ret = new HashSet<>(); Set<Pair> ret = new HashSet<>();
for(int i = 0; i<foMethod.arglist.getArguments().size(); i++){ for (int i = 0; i < foMethod.arglist.getArguments().size(); i++) {
//Zuordnung von MethoCall.signature (Argumenttypen) zu der Argumenttypen der ausgewaehlten Methode (assumption.params) //Zuordnung von MethoCall.signature (Argumenttypen) zu der Argumenttypen der ausgewaehlten Methode (assumption.params)
ret.add(new Pair(foMethod.signature.get(i), assumption.getArgTypes().get(i), PairOperator.EQUALSDOT)); ret.add(new Pair(foMethod.signature.get(i), assumption.getArgTypes().get(i), PairOperator.EQUALSDOT));
} }
//Zuordnung von MethodCall.signature(ReturnType) zu dem ReturnType der ausgewaehlten Methode (assumption.returnType) //Zuordnung von MethodCall.signature(ReturnType) zu dem ReturnType der ausgewaehlten Methode (assumption.returnType)
System.out.println(foMethod.name); System.out.println(foMethod.name);
ret.add(new Pair(foMethod.signature.get(foMethod.signature.size()-1), assumption.getReturnType(), PairOperator.EQUALSDOT)); ret.add(new Pair(foMethod.signature.get(foMethod.signature.size() - 1), assumption.getReturnType(), PairOperator.EQUALSDOT));
return ret;
}
public static List<MethodAssumption> getMethods(String name, int numArgs, TypeInferenceBlockInformation info) {
List<MethodAssumption> ret = new ArrayList<>();
//TODO: apply Methoden wieder anfügen. Diese könnten möglicherweise auch in den Assumptions auftauchen (überdenken)
if(name.equals("apply")){
List<GenericRefType> funNParams = new ArrayList<>();
for(int i = 0; i< numArgs + 1 ; i++){
//funNParams.add(TypePlaceholder.fresh(new NullToken()));
funNParams.add(new GenericRefType(NameGenerator.makeNewName(),
new NullToken()));
}
funNParams.get(funNParams.size()-1);
ret.add(new MethodAssumption(new FunNClass(funNParams), funNParams.get(funNParams.size()-1), funNParams.subList(0, funNParams.size()-1),
new TypeScope() {
@Override
public Iterable<? extends GenericTypeVar> getGenerics() {
throw new NotImplementedException();
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
throw new NotImplementedException();
}
}, false));
}
for(ClassOrInterface cl : info.getAvailableClasses()){
for(Method m : cl.getMethods()){
if(m.getName().equals(name) &&
m.getParameterList().getFormalparalist().size() == numArgs){
RefTypeOrTPHOrWildcardOrGeneric retType = m.getReturnType();//info.checkGTV(m.getReturnType());
ret.add(new MethodAssumption(cl, retType, convertParams(m.getParameterList(),info),
createTypeScope(cl, m), m.isInherited));
}
}
}
return ret; return ret;
} }
public static List<MethodAssumption> getMethods(String name, ArgumentList arglist, TypeInferenceBlockInformation info) { public List<MethodAssumption> getConstructors(TypeInferenceBlockInformation info, RefType ofType, ArgumentList argList) {
return getMethods(name, arglist.getArguments().size(), info);
}
protected static List<RefTypeOrTPHOrWildcardOrGeneric> convertParams(ParameterList parameterList, TypeInferenceBlockInformation info){
//TODO: Hier müssen die Parameter mit den TPHs in den GEnerics des Receivers verknüpft werden
/*
BEispiel:
auto test = new List<String>();
test.add("hallo");
Hier kriegt der Receiver ja den COnstraint TPH REceiver <. List<TPH A>
Dann mus bei dem Parameter der COnstraint entstehen: TPH A <. String
*/
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(FormalParameter fp : parameterList.getFormalparalist()){
params.add(fp.getType()); //info.checkGTV(fp.getType())); //PL 2018-06-22 GTV sollen in Argumenten erhalten bleiben
}
return params;
}
public List<MethodAssumption> getConstructors(TypeInferenceBlockInformation info, RefType ofType, ArgumentList argList){
List<MethodAssumption> ret = new ArrayList<>(); List<MethodAssumption> ret = new ArrayList<>();
for(ClassOrInterface cl : info.getAvailableClasses()){ for (ClassOrInterface cl : info.getAvailableClasses()) {
if(cl.getClassName().equals(ofType.getName())){ if (cl.getClassName().equals(ofType.getName())) {
for(Method m : cl.getConstructors()){ for (Method m : cl.getConstructors()) {
if(m.getParameterList().getFormalparalist().size() == argList.getArguments().size()){ if (m.getParameterList().getFormalparalist().size() == argList.getArguments().size()) {
ret.add(new MethodAssumption(cl, cl.generateTypeOfThisClass(), convertParams(m.getParameterList(), ret.add(new MethodAssumption(cl, cl.generateTypeOfThisClass(), convertParams(m.getParameterList(),
info), createTypeScope(cl, m), m.isInherited)); info), createTypeScope(cl, m), m.isInherited));
} }
} }
} }
@@ -748,12 +712,12 @@ public class TYPEStmt implements StatementVisitor{
} }
protected Constraint<Pair> generateConstructorConstraint(NewClass forConstructor, MethodAssumption assumption, protected Constraint<Pair> generateConstructorConstraint(NewClass forConstructor, MethodAssumption assumption,
TypeInferenceBlockInformation info, GenericsResolver resolver){ TypeInferenceBlockInformation info, GenericsResolver resolver) {
Constraint methodConstraint = new Constraint(); Constraint<Pair> methodConstraint = new Constraint<>();
//WELCHEN SINN MACHT DIESER CONSTRAINT??? //WELCHEN SINN MACHT DIESER CONSTRAINT???
//Ist er nicht immer classname <. classname und damit redundant? //Ist er nicht immer classname <. classname und damit redundant?
methodConstraint.add(new Pair(assumption.getReturnType(resolver), forConstructor.getType(), methodConstraint.add(new Pair(assumption.getReturnType(resolver), forConstructor.getType(),
PairOperator.SMALLERDOT)); PairOperator.SMALLERDOT));
//WELCHEN SINN MACHT DIESER CONSTRAINT??? //WELCHEN SINN MACHT DIESER CONSTRAINT???
methodConstraint.addAll(generateParameterConstraints(forConstructor, assumption, info, resolver)); methodConstraint.addAll(generateParameterConstraints(forConstructor, assumption, info, resolver));
return methodConstraint; return methodConstraint;

View File

@@ -0,0 +1,51 @@
package de.dhbwstuttgart.typeinference.unify;
import de.dhbwstuttgart.typeinference.unify.model.FunNType;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class DistributeVariance extends VisitUnifyTypeVisitor<Integer> {
public static int inverseVariance(int variance) {
// TODO: or should this simply be "return -variance;" ???
return switch (variance) {
case 1 -> -1;
case -1 -> 1;
default -> 0;
};
}
@Override
public PlaceholderType visit(PlaceholderType phty, Integer ht) {
if (ht != 0) {
if (phty.getVariance() == 0) {
phty.setVariance(ht);
}
//PL 2018-05-17 urspruengliche Variance nicht veraendern
//else if (phty.getVariance() != ht) {
// phty.setVariance(0);
//}
}
return phty;
}
public FunNType visit(FunNType funnty, Integer ht) {
List<UnifyType> param = new ArrayList<>(Arrays.asList(funnty.getTypeParams().get()));
UnifyType resultType = param.removeLast();
Integer htInverse = inverseVariance(ht);
param = param.stream()
.map(x -> x.accept(this, htInverse))
.collect(Collectors.toCollection(ArrayList::new));
param.add(resultType.accept(this, ht));
return FunNType.getFunNType(new TypeParams(param));
}
}

View File

@@ -0,0 +1,15 @@
package de.dhbwstuttgart.typeinference.unify;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import java.util.HashMap;
public class FreshPlaceholder extends VisitUnifyTypeVisitor<HashMap<PlaceholderType, PlaceholderType>> {
@Override
public PlaceholderType visit(PlaceholderType phty, HashMap<PlaceholderType, PlaceholderType> ht) {
return ht.get(phty);
}
}

View File

@@ -1,23 +1,22 @@
package de.dhbwstuttgart.typeinference.unify; package de.dhbwstuttgart.typeinference.unify;
import com.google.common.collect.Sets;
import de.dhbwstuttgart.typeinference.unify.interfaces.ISetOperations;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import com.google.common.collect.Sets;
import de.dhbwstuttgart.typeinference.unify.interfaces.ISetOperations;
/** /**
* Implements set operations using google guava. * Implements set operations using google guava.
* @author DH10STF
* *
* @author DH10STF
*/ */
public class GuavaSetOperations implements ISetOperations { public class GuavaSetOperations implements ISetOperations {
@Override @Override
public <B> Set<List<B>> cartesianProduct(List<? extends Set<? extends B>> sets) { public <B> Set<List<B>> cartesianProduct(List<? extends Set<? extends B>> sets) {
// Wraps the call to google guava // Wraps the call to google guava
return Sets.cartesianProduct(sets); return Sets.cartesianProduct(sets);
} }
} }

View File

@@ -1,108 +1,100 @@
package de.dhbwstuttgart.typeinference.unify; package de.dhbwstuttgart.typeinference.unify;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify; import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.*;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams; import java.util.*;
import de.dhbwstuttgart.typeinference.unify.model.Unifier; import java.util.stream.Collectors;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
/** /**
* Implementation of the Martelli-Montanari unification algorithm. * Implementation of the Martelli-Montanari unification algorithm.
*
* @author Florian Steurer * @author Florian Steurer
*/ */
public class MartelliMontanariUnify implements IUnify { public class MartelliMontanariUnify implements IUnify {
@Override @Override
public Optional<Unifier> unify(Set<UnifyType> terms) { public Optional<Unifier> unify(Set<UnifyType> terms) {
// Sets with less than 2 terms are trivially unified // Sets with less than 2 terms are trivially unified
if(terms.size() < 2) if (terms.size() < 2)
return Optional.of(Unifier.identity()); return Optional.of(Unifier.identity());
// For the the set of terms {t1,...,tn},
// build a list of equations {(t1 = t2), (t2 = t3), (t3 = t4), ....}
ArrayList<UnifyPair> termsList = new ArrayList<UnifyPair>();
Iterator<UnifyType> iter = terms.iterator();
UnifyType prev = iter.next();
while(iter.hasNext()) {
UnifyType next = iter.next();
termsList.add(new UnifyPair(prev, next, PairOperator.EQUALSDOT));
prev = next;
}
// Start with the identity unifier. Substitutions will be added later.
Unifier mgu = Unifier.identity();
// Apply rules while possible
int idx = 0;
while(idx < termsList.size()) {
UnifyPair pair = termsList.get(idx);
UnifyType rhsType = pair.getRhsType();
UnifyType lhsType = pair.getLhsType();
TypeParams rhsTypeParams = rhsType.getTypeParams();
TypeParams lhsTypeParams = lhsType.getTypeParams();
// REDUCE - Rule
if(!(rhsType instanceof PlaceholderType) && !(lhsType instanceof PlaceholderType)) {
Set<UnifyPair> result = new HashSet<>();
// f<...> = g<...> with f != g are not unifiable
if(!rhsType.getName().equals(lhsType.getName()))
return Optional.empty(); // conflict
// f<t1,...,tn> = f<s1,...,sm> are not unifiable
if(rhsTypeParams.size() != lhsTypeParams.size())
return Optional.empty(); // conflict
// f = g is not unifiable (cannot be f = f because erase rule would have been applied)
//if(rhsTypeParams.size() == 0)
//return Optional.empty();
// Unpack the arguments
for(int i = 0; i < rhsTypeParams.size(); i++)
result.add(new UnifyPair(rhsTypeParams.get(i), lhsTypeParams.get(i), PairOperator.EQUALSDOT));
termsList.remove(idx);
termsList.addAll(result);
continue;
}
// DELETE - Rule
if(pair.getRhsType().equals(pair.getLhsType())) {
termsList.remove(idx);
continue;
}
// SWAP - Rule // For the the set of terms {t1,...,tn},
if(!(lhsType instanceof PlaceholderType) && (rhsType instanceof PlaceholderType)) { // build a list of equations {(t1 = t2), (t2 = t3), (t3 = t4), ....}
termsList.remove(idx); ArrayList<UnifyPair> termsList = new ArrayList<UnifyPair>();
termsList.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT)); Iterator<UnifyType> iter = terms.iterator();
continue; UnifyType prev = iter.next();
} while (iter.hasNext()) {
UnifyType next = iter.next();
// OCCURS-CHECK termsList.add(new UnifyPair(prev, next, PairOperator.EQUALSDOT));
if(pair.getLhsType() instanceof PlaceholderType prev = next;
&& pair.getRhsType().getTypeParams().occurs((PlaceholderType) pair.getLhsType())) }
return Optional.empty();
// Start with the identity unifier. Substitutions will be added later.
// SUBST - Rule Unifier mgu = Unifier.identity();
if(lhsType instanceof PlaceholderType) {
mgu.add((PlaceholderType) lhsType, rhsType); // Apply rules while possible
//PL 2018-04-01 nach checken, ob es richtig ist, dass keine Substitutionen uebergeben werden muessen. int idx = 0;
termsList = termsList.stream().map(x -> mgu.apply(x)).collect(Collectors.toCollection(ArrayList::new)); while (idx < termsList.size()) {
idx = idx+1 == termsList.size() ? 0 : idx+1; UnifyPair pair = termsList.get(idx);
continue; UnifyType rhsType = pair.getRhsType();
} UnifyType lhsType = pair.getLhsType();
TypeParams rhsTypeParams = rhsType.getTypeParams();
idx++; TypeParams lhsTypeParams = lhsType.getTypeParams();
}
// REDUCE - Rule
return Optional.of(mgu); if (!(rhsType instanceof PlaceholderType) && !(lhsType instanceof PlaceholderType)) {
} Set<UnifyPair> result = new HashSet<>();
// f<...> = g<...> with f != g are not unifiable
if (!rhsType.getName().equals(lhsType.getName()))
return Optional.empty(); // conflict
// f<t1,...,tn> = f<s1,...,sm> are not unifiable
if (rhsTypeParams.size() != lhsTypeParams.size())
return Optional.empty(); // conflict
// f = g is not unifiable (cannot be f = f because erase rule would have been applied)
//if(rhsTypeParams.size() == 0)
//return Optional.empty();
// Unpack the arguments
for (int i = 0; i < rhsTypeParams.size(); i++)
result.add(new UnifyPair(rhsTypeParams.get(i), lhsTypeParams.get(i), PairOperator.EQUALSDOT));
termsList.remove(idx);
termsList.addAll(result);
continue;
}
// DELETE - Rule
if (pair.getRhsType().equals(pair.getLhsType())) {
termsList.remove(idx);
continue;
}
// SWAP - Rule
if (!(lhsType instanceof PlaceholderType) && (rhsType instanceof PlaceholderType)) {
termsList.remove(idx);
termsList.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT));
continue;
}
// OCCURS-CHECK
if (pair.getLhsType() instanceof PlaceholderType
&& pair.getRhsType().getTypeParams().occurs((PlaceholderType) pair.getLhsType()))
return Optional.empty();
// SUBST - Rule
if (lhsType instanceof PlaceholderType) {
mgu.add((PlaceholderType) lhsType, rhsType);
//PL 2018-04-01 nach checken, ob es richtig ist, dass keine Substitutionen uebergeben werden muessen.
termsList = termsList.stream().map(x -> mgu.apply(x)).collect(Collectors.toCollection(ArrayList::new));
idx = idx + 1 == termsList.size() ? 0 : idx + 1;
continue;
}
idx++;
}
return Optional.of(mgu);
}
} }

View File

@@ -11,76 +11,77 @@ import java.util.stream.Collectors;
/** /**
* Implementation of match derived from unification algorithm. * Implementation of match derived from unification algorithm.
*
* @author Martin Pluemicke * @author Martin Pluemicke
*/ */
public class Match implements IMatch { public class Match implements IMatch {
@Override @Override
//vorne muss das Pattern stehen //vorne muss das Pattern stehen
//A<X> =. A<Integer> ==> True //A<X> =. A<Integer> ==> True
//A<Integer> =. A<X> ==> False //A<Integer> =. A<X> ==> False
public Optional<Unifier> match(ArrayList<UnifyPair> termsList) { public Optional<Unifier> match(ArrayList<UnifyPair> termsList) {
// Start with the identity unifier. Substitutions will be added later.
Unifier mgu = Unifier.identity();
// Apply rules while possible
int idx = 0;
while(idx < termsList.size()) {
UnifyPair pair = termsList.get(idx);
UnifyType rhsType = pair.getRhsType();
UnifyType lhsType = pair.getLhsType();
TypeParams rhsTypeParams = rhsType.getTypeParams();
TypeParams lhsTypeParams = lhsType.getTypeParams();
// REDUCE - Rule
if(!(rhsType instanceof PlaceholderType) && !(lhsType instanceof PlaceholderType)) {
Set<UnifyPair> result = new HashSet<>();
// f<...> = g<...> with f != g are not unifiable
if(!rhsType.getName().equals(lhsType.getName()))
return Optional.empty(); // conflict
// f<t1,...,tn> = f<s1,...,sm> are not unifiable
if(rhsTypeParams.size() != lhsTypeParams.size())
return Optional.empty(); // conflict
// f = g is not unifiable (cannot be f = f because erase rule would have been applied)
//if(rhsTypeParams.size() == 0)
//return Optional.empty();
// Unpack the arguments
for(int i = 0; i < rhsTypeParams.size(); i++)
result.add(new UnifyPair(lhsTypeParams.get(i), rhsTypeParams.get(i), PairOperator.EQUALSDOT));
termsList.remove(idx);
termsList.addAll(result);
continue;
}
// DELETE - Rule
if(pair.getRhsType().equals(pair.getLhsType())) {
termsList.remove(idx);
continue;
}
// SWAP - Rule // Start with the identity unifier. Substitutions will be added later.
if(!(lhsType instanceof PlaceholderType) && (rhsType instanceof PlaceholderType)) { Unifier mgu = Unifier.identity();
return Optional.empty(); // conflict
} // Apply rules while possible
int idx = 0;
// OCCURS-CHECK while (idx < termsList.size()) {
//deleted UnifyPair pair = termsList.get(idx);
UnifyType rhsType = pair.getRhsType();
// SUBST - Rule UnifyType lhsType = pair.getLhsType();
if(lhsType instanceof PlaceholderType) { TypeParams rhsTypeParams = rhsType.getTypeParams();
mgu.add((PlaceholderType) lhsType, rhsType); TypeParams lhsTypeParams = lhsType.getTypeParams();
termsList = termsList.stream().map(mgu::applyleft).collect(Collectors.toCollection(ArrayList::new));
idx = idx+1 == termsList.size() ? 0 : idx+1; // REDUCE - Rule
continue; if (!(rhsType instanceof PlaceholderType) && !(lhsType instanceof PlaceholderType)) {
} Set<UnifyPair> result = new HashSet<>();
idx++; // f<...> = g<...> with f != g are not unifiable
} if (!rhsType.getName().equals(lhsType.getName()))
return Optional.empty(); // conflict
return Optional.of(mgu); // f<t1,...,tn> = f<s1,...,sm> are not unifiable
} if (rhsTypeParams.size() != lhsTypeParams.size())
} return Optional.empty(); // conflict
// f = g is not unifiable (cannot be f = f because erase rule would have been applied)
//if(rhsTypeParams.size() == 0)
//return Optional.empty();
// Unpack the arguments
for (int i = 0; i < rhsTypeParams.size(); i++)
result.add(new UnifyPair(lhsTypeParams.get(i), rhsTypeParams.get(i), PairOperator.EQUALSDOT));
termsList.remove(idx);
termsList.addAll(result);
continue;
}
// DELETE - Rule
if (pair.getRhsType().equals(pair.getLhsType())) {
termsList.remove(idx);
continue;
}
// SWAP - Rule
if (!(lhsType instanceof PlaceholderType) && (rhsType instanceof PlaceholderType)) {
return Optional.empty(); // conflict
}
// OCCURS-CHECK
//deleted
// SUBST - Rule
if (lhsType instanceof PlaceholderType) {
mgu.add((PlaceholderType) lhsType, rhsType);
termsList = termsList.stream().map(mgu::applyLeft).collect(Collectors.toCollection(ArrayList::new));
idx = idx + 1 == termsList.size() ? 0 : idx + 1;
continue;
}
idx++;
}
return Optional.of(mgu);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -10,90 +10,80 @@ import java.util.Set;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
public class TypeUnify { public class TypeUnify {
public static Writer statistics;
/**
* unify parallel ohne result modell
* @param undConstrains
* @param oderConstraints
* @param fc
* @param logFile
* @param log
* @return
*/
public Set<Set<UnifyPair>> unify(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModelParallel resultModel, UnifyTaskModelParallel taskModel) {
ForkJoinPool pool = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
taskModel.setPool(pool);
resultModel.setPool(pool);
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, new WriterActiveObject(logFile, pool), log, resultModel, pool);
pool.invoke(unifyTask);
Set<Set<UnifyPair>> res = unifyTask.join();
return res;
}
/**
* unify asynchron mit Rückgabe UnifyResultModel, ohne dass alle results gesammelt sind
* @param undConstrains
* @param oderConstraints
* @param fc
* @param logFile
* @param log
* @return
*/
public UnifyResultModelParallel unifyAsync(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModelParallel resultModel, UnifyTaskModelParallel taskModel) {
ForkJoinPool pool = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
taskModel.setPool(pool);
resultModel.setPool(pool);
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, new WriterActiveObject(logFile, pool), log, resultModel, pool);
pool.invoke(unifyTask);
return resultModel;
}
/**
* unify parallel mit Rückgabe UnifyResultModel nachdem alle results gesammelt sind
* @param undConstrains
* @param oderConstraints
* @param fc
* @param logFile
* @param log
* @return
*/
public UnifyResultModelParallel unifyParallel(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModelParallel resultModel, UnifyTaskModelParallel taskModel) {
ForkJoinPool pool = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
taskModel.setPool(pool);
resultModel.setPool(pool);
TypeUnifyTask unifyTask = //new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, usedTasks);
new TypeUnifyTask(undConstrains, oderConstraints, fc, true, new WriterActiveObject(logFile, pool), log, resultModel, pool, statistics);
pool.invoke(unifyTask); public static Writer statistics;
unifyTask.join();
return resultModel; /**
} * Unify parallel without result model
*/
/* public Set<Set<UnifyPair>> unify(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModelParallel resultModel, UnifyTaskModelParallel taskModel) {
public Set<Set<UnifyPair>> unifySequential(Set<UnifyPair> eq, IFiniteClosure fc, FileWriter logFile, Boolean log) { ForkJoinPool pool = new ForkJoinPool(
TypeUnifyTask unifyTask = new TypeUnifyTask(eq, fc, false, logFile, log); Runtime.getRuntime().availableProcessors(),
Set<Set<UnifyPair>> res = unifyTask.compute(); ForkJoinPool.defaultForkJoinWorkerThreadFactory,
return res; null,
} true
*/ );
taskModel.setPool(pool);
/** resultModel.setPool(pool);
* unify sequentiell mit oderconstraints TypeUnifyTask unifyTask = new TypeUnifyTask(
* @param undConstrains undConstrains,
* @param oderConstraints oderConstraints,
* @param fc fc,
* @param logFile true,
* @param log new WriterActiveObject(logFile, pool),
* @return log,
*/ resultModel,
public Set<Set<UnifyPair>> unifyOderConstraints(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModelParallel resultModel, UnifyTaskModelParallel taskModel) { pool
resultModel.setPool(ForkJoinPool.commonPool()); );
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, false, new WriterActiveObject(logFile, ForkJoinPool.commonPool()), log, resultModel, ForkJoinPool.commonPool()); pool.invoke(unifyTask);
unifyTask.statisticsFile = statistics; return unifyTask.join();
Set<Set<UnifyPair>> res = unifyTask.compute(); }
return res;
} /**
* Unify parallel returning UnifyResultModel after gathering all results
*/
public void unifyParallel(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModelParallel resultModel, UnifyTaskModelParallel taskModel) {
ForkJoinPool pool = new ForkJoinPool(
Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null,
true
);
taskModel.setPool(pool);
resultModel.setPool(pool);
TypeUnifyTask unifyTask = new TypeUnifyTask(
undConstrains,
oderConstraints,
fc,
true,
new WriterActiveObject(logFile, pool),
log,
resultModel,
pool,
statistics
);
pool.invoke(unifyTask);
unifyTask.join();
}
/**
* Unify sequential with oder-constraints
*/
public Set<Set<UnifyPair>> unifyOderConstraints(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModelParallel resultModel) {
resultModel.setPool(ForkJoinPool.commonPool());
TypeUnifyTask unifyTask = new TypeUnifyTask(
undConstrains,
oderConstraints,
fc,
false,
new WriterActiveObject(logFile, ForkJoinPool.commonPool()),
log,
resultModel,
ForkJoinPool.commonPool()
);
TypeUnifyTask.statisticsFile = statistics;
return unifyTask.compute();
}
} }

View File

@@ -4,54 +4,43 @@ import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import java.io.Writer;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
public class TypeUnify2Task extends TypeUnifyTask { public class TypeUnify2Task extends TypeUnifyTask {
Set<Set<UnifyPair>> setToFlatten;
Set<UnifyPair> methodSignatureConstraintUebergabe;
//statistics Set<Set<UnifyPair>> setToFlatten;
TypeUnify2Task(Set<Set<UnifyPair>> setToFlatten, Set<UnifyPair> eq, Set<UnifyPair> methodSignatureConstraintUebergabe;
List<Set<Constraint<UnifyPair>>> oderConstraints,
Set<UnifyPair> nextSetElement, public TypeUnify2Task(Set<Set<UnifyPair>> setToFlatten, Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, Set<UnifyPair> nextSetElement, IFiniteClosure fc, boolean parallel, WriterActiveObject logFile, Boolean log, UnifyResultModelParallel urm, Set<UnifyPair> methodSignatureConstraintUebergabe, ForkJoinPool pool) {
IFiniteClosure fc, boolean parallel, WriterActiveObject logFile, Boolean log, UnifyResultModelParallel urm, super(eq, oderConstraints, fc, parallel, logFile, log, urm, pool);
Set<UnifyPair> methodSignatureConstraintUebergabe, ForkJoinPool pool, Writer statistics) { this.setToFlatten = setToFlatten;
this(setToFlatten, eq, oderConstraints, nextSetElement, fc, parallel, logFile, log, urm, methodSignatureConstraintUebergabe, pool ); this.nextSetElement = nextSetElement;
this.methodSignatureConstraintUebergabe = methodSignatureConstraintUebergabe;
} }
public TypeUnify2Task(Set<Set<UnifyPair>> setToFlatten, Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, Set<UnifyPair> nextSetElement, IFiniteClosure fc, boolean parallel, WriterActiveObject logFile, Boolean log, UnifyResultModelParallel urm, Set<UnifyPair> methodSignatureConstraintUebergabe, ForkJoinPool pool) { Set<UnifyPair> getNextSetElement() {
super(eq, oderConstraints, fc, parallel, logFile, log, urm, pool); return nextSetElement;
this.setToFlatten = setToFlatten; }
this.nextSetElement = nextSetElement;
this.methodSignatureConstraintUebergabe = methodSignatureConstraintUebergabe; @Override
} protected Set<Set<UnifyPair>> compute() {
Set<Set<UnifyPair>> res = unify2(setToFlatten, eq, oderConstraintsField, fc, parallel, methodSignatureConstraintUebergabe);
Set<UnifyPair> getNextSetElement() {
return nextSetElement;
}
@Override
protected Set<Set<UnifyPair>> compute() {
Set<Set<UnifyPair>> res = unify2(setToFlatten, eq, oderConstraintsField, fc, parallel, methodSignatureConstraintUebergabe);
/*if (isUndefinedPairSetSet(res)) { /*if (isUndefinedPairSetSet(res)) {
return new HashSet<>(); } return new HashSet<>(); }
else else
*/ */
//writeLog("xxx"); //writeLog("xxx");
//noOfThread--; //noOfThread--;
return res; return res;
} }
public void closeLogFile() { public void closeLogFile() {
if(parallel){ if (parallel) {
logFile.close(); logFile.close();
}else{ } else {
logFile.closeNonThreaded(); logFile.closeNonThreaded();
} }
} }
} }

View File

@@ -32,43 +32,34 @@ import java.util.stream.Collectors;
*/ */
public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> { public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+"/test/logFiles/log" geschrieben werden soll?
/**
* Element, das aus dem nextSet den Gleichunen dieses Threads hinzugefuegt wurde
*/
Set<UnifyPair> nextSetElement;
/**
* Fuer die Threads
*/
protected UnifyResultModelParallel urm;
private static int totalnoOfThread = 0;
int thNo;
public static final String rootDirectory = System.getProperty("user.dir") + "/test/logFiles/"; public static final String rootDirectory = System.getProperty("user.dir") + "/test/logFiles/";
static Writer statisticsFile = new NullWriter();
private static int totalNoOfThreads = 0;
/*
* Thread related
*/
protected UnifyResultModelParallel unifyResultModel;
protected WriterActiveObject logFile; protected WriterActiveObject logFile;
protected ForkJoinPool pool; protected ForkJoinPool pool;
/** /**
* The implementation of the standard unify that will be used during the unification * The implementation of the standard unify that will be used during the unification
*/ */
protected IUnify stdUnify = new MartelliMontanariUnify(); protected IUnify stdUnify = new MartelliMontanariUnify();
/** /**
* The implementation of the rules that will be used during the unification. * The implementation of the rules that will be used during the unification.
*/ */
protected IRuleSet rules; protected IRuleSet rules;
protected Set<UnifyPair> eq; //und-constraints protected Set<UnifyPair> eq; //und-constraints
protected List<Set<Constraint<UnifyPair>>> oderConstraintsField; protected List<Set<Constraint<UnifyPair>>> oderConstraintsField;
protected IFiniteClosure fc; protected IFiniteClosure fc;
protected boolean parallel; protected boolean parallel;
//gibt an ob ein Log-File nach System.getProperty("user.dir")+"/test/logFiles/log" geschrieben werden soll?
static Writer statisticsFile = new NullWriter(); Boolean log = true;
/**
* Element that was added to the equations of this thread from the nextSet
*/
Set<UnifyPair> nextSetElement;
int threadNumber;
public TypeUnifyTask() { public TypeUnifyTask() {
rules = new RuleSet(); rules = new RuleSet();
@@ -77,7 +68,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
//statistics //statistics
public TypeUnifyTask(Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, WriterActiveObject logFile, Boolean log, UnifyResultModelParallel urm, ForkJoinPool pool, Writer statisticsFile) { public TypeUnifyTask(Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, WriterActiveObject logFile, Boolean log, UnifyResultModelParallel urm, ForkJoinPool pool, Writer statisticsFile) {
this(eq, oderConstraints, fc, parallel, logFile, log, urm, pool); this(eq, oderConstraints, fc, parallel, logFile, log, urm, pool);
this.statisticsFile = statisticsFile; TypeUnifyTask.statisticsFile = statisticsFile;
} }
public TypeUnifyTask(Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, WriterActiveObject logFile, Boolean log, UnifyResultModelParallel urm, ForkJoinPool pool) { public TypeUnifyTask(Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, WriterActiveObject logFile, Boolean log, UnifyResultModelParallel urm, ForkJoinPool pool) {
@@ -89,12 +80,12 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
this.log = log; this.log = log;
this.pool = pool; this.pool = pool;
totalnoOfThread++; totalNoOfThreads++;
thNo = totalnoOfThread; threadNumber = totalNoOfThreads;
writeLog("thNo2 " + thNo); writeLog("thNo2 " + threadNumber);
try { try {
if (log) { if (log) {
this.logFile = new WriterActiveObject(new FileWriter(System.getProperty("user.dir") + "/logFiles/" + "Thread_" + thNo), pool); this.logFile = new WriterActiveObject(new FileWriter(System.getProperty("user.dir") + "/logFiles/" + "Thread_" + threadNumber), pool);
} else { } else {
this.logFile = new WriterActiveObject(new OutputStreamWriter(new NullOutputStream()), pool); this.logFile = new WriterActiveObject(new OutputStreamWriter(new NullOutputStream()), pool);
} }
@@ -102,18 +93,18 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
System.err.println("log-File nicht vorhanden"); System.err.println("log-File nicht vorhanden");
} }
rules = new RuleSet(logFile); rules = new RuleSet(logFile);
this.urm = urm; this.unifyResultModel = urm;
} }
protected Set<Set<UnifyPair>> compute() { protected Set<Set<UnifyPair>> compute() {
Set<UnifyPair> neweq = new HashSet<>(eq); Set<UnifyPair> neweq = new HashSet<>(eq);
/* 1-elementige Oder-Constraints werden in und-Constraints umgewandelt */ /* 1-elementige Oder-Constraints werden in und-Constraints umgewandelt */
oderConstraintsField.stream() oderConstraintsField.stream()
.filter(x -> x.size() == 1) .filter(x -> x.size() == 1)
.map(y -> y.stream().findFirst().get()).forEach(neweq::addAll); .map(y -> y.stream().findFirst().get()).forEach(neweq::addAll);
ArrayList<Set<Constraint<UnifyPair>>> remainingOderconstraints = oderConstraintsField.stream() ArrayList<Set<Constraint<UnifyPair>>> remainingOderconstraints = oderConstraintsField.stream()
.filter(x -> x.size() > 1) .filter(x -> x.size() > 1)
.collect(Collectors.toCollection(ArrayList::new)); .collect(Collectors.toCollection(ArrayList::new));
Set<Set<UnifyPair>> res = unify(neweq, remainingOderconstraints, fc, parallel, new HashSet<>()); Set<Set<UnifyPair>> res = unify(neweq, remainingOderconstraints, fc, parallel, new HashSet<>());
if (parallel) { if (parallel) {
@@ -142,7 +133,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
* ? extends ? extends Theta rausfiltern * ? extends ? extends Theta rausfiltern
*/ */
Set<UnifyPair> doubleExt = eq.stream().filter(UnifyPair::wrongWildcard).peek(UnifyPair::setUndefinedPair) Set<UnifyPair> doubleExt = eq.stream().filter(UnifyPair::wrongWildcard).peek(UnifyPair::setUndefinedPair)
.collect(Collectors.toCollection(HashSet::new)); .collect(Collectors.toCollection(HashSet::new));
if (!doubleExt.isEmpty()) { if (!doubleExt.isEmpty()) {
Set<Set<UnifyPair>> ret = new HashSet<>(); Set<Set<UnifyPair>> ret = new HashSet<>();
ret.add(doubleExt); ret.add(doubleExt);
@@ -154,13 +145,13 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
*/ */
Set<UnifyPair> ocurrPairs = eq.stream().filter(x -> { Set<UnifyPair> ocurrPairs = eq.stream().filter(x -> {
UnifyType lhs, rhs; UnifyType lhs, rhs;
return (lhs = x.getLhsType()) instanceof PlaceholderType return (lhs = x.getLhsType()) instanceof PlaceholderType
&& !((rhs = x.getRhsType()) instanceof PlaceholderType) && !((rhs = x.getRhsType()) instanceof PlaceholderType)
&& rhs.getTypeParams().occurs((PlaceholderType) lhs); && rhs.getTypeParams().occurs((PlaceholderType) lhs);
}) })
.peek(UnifyPair::setUndefinedPair) .peek(UnifyPair::setUndefinedPair)
.collect(Collectors.toCollection(HashSet::new)); .collect(Collectors.toCollection(HashSet::new));
writeLog("ocurrPairs: " + ocurrPairs); writeLog("ocurrPairs: " + ocurrPairs);
if (!ocurrPairs.isEmpty()) { if (!ocurrPairs.isEmpty()) {
Set<Set<UnifyPair>> ret = new HashSet<>(); Set<Set<UnifyPair>> ret = new HashSet<>();
@@ -213,8 +204,8 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
// Add the set of [a =. Theta | (a=. Theta) in Eq2'] // Add the set of [a =. Theta | (a=. Theta) in Eq2']
//TODO: Occurscheck anwenden als Fehler identifizieren //TODO: Occurscheck anwenden als Fehler identifizieren
Set<UnifyPair> bufferSet = eq2s.stream() Set<UnifyPair> bufferSet = eq2s.stream()
.filter(x -> x.getPairOp() == PairOperator.EQUALSDOT && x.getLhsType() instanceof PlaceholderType) .filter(x -> x.getPairOp() == PairOperator.EQUALSDOT && x.getLhsType() instanceof PlaceholderType)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
if (!bufferSet.isEmpty()) { // Do not add empty sets or the cartesian product will always be empty. if (!bufferSet.isEmpty()) { // Do not add empty sets or the cartesian product will always be empty.
Set<Set<UnifyPair>> wrap = new HashSet<>(); Set<Set<UnifyPair>> wrap = new HashSet<>();
@@ -274,7 +265,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
{// sequentiell (Step 6b is included) {// sequentiell (Step 6b is included)
if (eqPrime.equals(eq) && eqPrimePrime.isEmpty() if (eqPrime.equals(eq) && eqPrimePrime.isEmpty()
&& oderConstraints.isEmpty()) { //PL 2017-09-29 //(!eqPrimePrime.isPresent()) auskommentiert und durch && oderConstraints.isEmpty()) { //PL 2017-09-29 //(!eqPrimePrime.isPresent()) auskommentiert und durch
//PL 2017-09-29 dies ersetzt //(!eqPrimePrime.isPresent()) //PL 2017-09-29 dies ersetzt //(!eqPrimePrime.isPresent())
//PL 2018-05-18 beide Bedingungen muessen gelten, da eqPrime Veränderungen in allem ausser subst //PL 2018-05-18 beide Bedingungen muessen gelten, da eqPrime Veränderungen in allem ausser subst
//eqPrimePrime Veraenderungen in subst repraesentieren. //eqPrimePrime Veraenderungen in subst repraesentieren.
@@ -289,18 +280,18 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
//Substitutionen in methodcontraintsets werdne ausgeführt //Substitutionen in methodcontraintsets werdne ausgeführt
eqPrimePrimeSet = eqPrimePrimeSet.stream().map( eqPrimePrimeSet = eqPrimePrimeSet.stream().map(
x -> { x -> {
Optional<Set<UnifyPair>> help = rules.subst(x); Optional<Set<UnifyPair>> help = rules.subst(x);
return help.isPresent() ? return help.isPresent() ?
help.get() : help.get() :
x; x;
}).collect(Collectors.toSet()); }).collect(Collectors.toSet());
/* /*
* Ende * Ende
*/ */
urm.notify(eqPrimePrimeSet); unifyResultModel.notify(eqPrimePrimeSet);
writeStatistics("Result: " + eqPrimePrimeSet); writeStatistics("Result: " + eqPrimePrimeSet);
} }
} else if (eqPrimePrime.isPresent()) { } else if (eqPrimePrime.isPresent()) {
@@ -341,8 +332,8 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
//oneElems: Alle 1-elementigen Mengen, die nur ein Paar //oneElems: Alle 1-elementigen Mengen, die nur ein Paar
//a <. theta, theta <. a oder a =. theta enthalten //a <. theta, theta <. a oder a =. theta enthalten
Set<Set<UnifyPair>> oneElems = topLevelSets.stream() Set<Set<UnifyPair>> oneElems = topLevelSets.stream()
.filter(x -> x.size() == 1) .filter(x -> x.size() == 1)
.map(y -> y.stream().findFirst().get()).collect(Collectors.toSet()); .map(y -> y.stream().findFirst().get()).collect(Collectors.toSet());
//optNextSet: Eine mehrelementige Menge, wenn vorhanden //optNextSet: Eine mehrelementige Menge, wenn vorhanden
Optional<Set<? extends Set<UnifyPair>>> optNextSet = topLevelSets.stream().filter(x -> x.size() > 1).findAny(); Optional<Set<? extends Set<UnifyPair>>> optNextSet = topLevelSets.stream().filter(x -> x.size() > 1).findAny();
@@ -374,15 +365,15 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
} }
if (sameBase) { //angefuegt PL 2020-02-30 if (sameBase) { //angefuegt PL 2020-02-30
Optional<Integer> xi = nextSetasList.stream().map(x -> x.stream().filter(y -> (y.getLhsType() instanceof PlaceholderType && !(y.getRhsType() instanceof PlaceholderType))) Optional<Integer> xi = nextSetasList.stream().map(x -> x.stream().filter(y -> (y.getLhsType() instanceof PlaceholderType && !(y.getRhsType() instanceof PlaceholderType)))
.filter(z -> ((PlaceholderType) z.getLhsType()).getVariance() != 0) .filter(z -> ((PlaceholderType) z.getLhsType()).getVariance() != 0)
.map(c -> ((PlaceholderType) c.getLhsType()).getVariance()) .map(c -> ((PlaceholderType) c.getLhsType()).getVariance())
.reduce((a, b) -> { .reduce((a, b) -> {
if (a == b) return a; if (a == b) return a;
else return 0; else return 0;
})) //2 kommt insbesondere bei Oder-Constraints vor })) //2 kommt insbesondere bei Oder-Constraints vor
.filter(d -> d.isPresent()) .filter(d -> d.isPresent())
.map(e -> e.get()) .map(e -> e.get())
.findAny(); .findAny();
if (xi.isPresent()) { if (xi.isPresent()) {
variance = xi.get(); variance = xi.get();
} }
@@ -396,19 +387,19 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
//Varianz-Bestimmung Oder-Constraints //Varianz-Bestimmung Oder-Constraints
if (oderConstraint) { if (oderConstraint) {
Optional<Integer> optVariance = Optional<Integer> optVariance =
nextSetasList nextSetasList
.getFirst() .getFirst()
.stream() .stream()
.filter(x -> x.getGroundBasePair().getLhsType() instanceof PlaceholderType && .filter(x -> x.getGroundBasePair().getLhsType() instanceof PlaceholderType &&
!(x.getRhsType() instanceof PlaceholderType) && !(x.getRhsType() instanceof PlaceholderType) &&
x.getPairOp() == PairOperator.EQUALSDOT) x.getPairOp() == PairOperator.EQUALSDOT)
.map(x -> .map(x ->
((PlaceholderType) x.getGroundBasePair().getLhsType()).getVariance()) ((PlaceholderType) x.getGroundBasePair().getLhsType()).getVariance())
.reduce((n, m) -> { .reduce((n, m) -> {
if ((n == 0) && (m == 0)) return 0; if ((n == 0) && (m == 0)) return 0;
else if (n != 0) return n; //es muss mindestens eine Variance != 0 sein else if (n != 0) return n; //es muss mindestens eine Variance != 0 sein
else return m; else return m;
}); });
//Fuer Operatorenaufrufe wird variance auf 2 gesetzt. //Fuer Operatorenaufrufe wird variance auf 2 gesetzt.
//da kein Receiver existiert also kein x.getGroundBasePair().getLhsType() instanceof PlaceholderType //da kein Receiver existiert also kein x.getGroundBasePair().getLhsType() instanceof PlaceholderType
//Bei Varianz = 2 werden alle Elemente des Kartesischen Produkts abgearbeitet //Bei Varianz = 2 werden alle Elemente des Kartesischen Produkts abgearbeitet
@@ -457,7 +448,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
Set<Set<UnifyPair>> newElemsOrig = new HashSet<>(elems); Set<Set<UnifyPair>> newElemsOrig = new HashSet<>(elems);
List<Set<Constraint<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints); List<Set<Constraint<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints);
newElemsOrig.add(a); newElemsOrig.add(a);
TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, urm, methodSignatureConstraint, this.pool); TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, unifyResultModel, methodSignatureConstraint, this.pool);
forkOrig.fork(); forkOrig.fork();
while (!nextSetasList.isEmpty()) { while (!nextSetasList.isEmpty()) {
@@ -471,14 +462,14 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
Set<Set<UnifyPair>> newElems = new HashSet<>(elems); Set<Set<UnifyPair>> newElems = new HashSet<>(elems);
List<Set<Constraint<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints); List<Set<Constraint<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints);
newElems.add(nSaL); newElems.add(nSaL);
TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, urm, new HashSet<>(methodSignatureConstraint), this.pool); TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, unifyResultModel, new HashSet<>(methodSignatureConstraint), this.pool);
forks.add(fork); forks.add(fork);
fork.fork(); fork.fork();
} }
res = forkOrig.join(); res = forkOrig.join();
forks.forEach(x -> writeLog("wait: " + x.thNo)); forks.forEach(x -> writeLog("wait: " + x.threadNumber));
for (TypeUnify2Task fork : forks) { for (TypeUnify2Task fork : forks) {
Set<Set<UnifyPair>> fork_res = fork.join(); Set<Set<UnifyPair>> fork_res = fork.join();
add_res.add(fork_res); add_res.add(fork_res);
@@ -494,7 +485,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
List<Set<Constraint<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints); List<Set<Constraint<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints);
newElemsOrig.add(a); newElemsOrig.add(a);
TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, urm, new HashSet<>(methodSignatureConstraint), this.pool); TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, unifyResultModel, new HashSet<>(methodSignatureConstraint), this.pool);
forkOrig.fork(); forkOrig.fork();
while (!nextSetasList.isEmpty()) { while (!nextSetasList.isEmpty()) {
@@ -507,21 +498,21 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
Set<Set<UnifyPair>> newElems = new HashSet<>(elems); Set<Set<UnifyPair>> newElems = new HashSet<>(elems);
List<Set<Constraint<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints); List<Set<Constraint<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints);
newElems.add(nSaL); newElems.add(nSaL);
TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, urm, new HashSet<>(methodSignatureConstraint), this.pool); TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, unifyResultModel, new HashSet<>(methodSignatureConstraint), this.pool);
forks.add(fork); forks.add(fork);
fork.fork(); fork.fork();
} }
writeLog("wait " + forkOrig.thNo); writeLog("wait " + forkOrig.threadNumber);
res = forkOrig.join(); res = forkOrig.join();
writeLog("JoinOrig " + Integer.valueOf(forkOrig.thNo).toString()); writeLog("JoinOrig " + Integer.valueOf(forkOrig.threadNumber).toString());
forks.forEach(x -> writeLog("wait: " + x.thNo)); forks.forEach(x -> writeLog("wait: " + x.threadNumber));
for (TypeUnify2Task fork : forks) { for (TypeUnify2Task fork : forks) {
Set<Set<UnifyPair>> fork_res = fork.join(); Set<Set<UnifyPair>> fork_res = fork.join();
writeLog("Join " + Integer.valueOf(fork.thNo).toString()); writeLog("Join " + Integer.valueOf(fork.threadNumber).toString());
add_res.add(fork_res); add_res.add(fork_res);
if (!isUndefinedPairSetSet(fork_res)) { if (!isUndefinedPairSetSet(fork_res)) {
aParDef.add(fork.getNextSetElement()); aParDef.add(fork.getNextSetElement());
@@ -536,7 +527,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
List<Set<Constraint<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints); List<Set<Constraint<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints);
newElemsOrig.add(a); newElemsOrig.add(a);
TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, urm, new HashSet<>(methodSignatureConstraint), this.pool); TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, unifyResultModel, new HashSet<>(methodSignatureConstraint), this.pool);
forkOrig.fork(); forkOrig.fork();
while (!nextSetasList.isEmpty()) { while (!nextSetasList.isEmpty()) {
@@ -545,21 +536,21 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
Set<Set<UnifyPair>> newElems = new HashSet<>(elems); Set<Set<UnifyPair>> newElems = new HashSet<>(elems);
List<Set<Constraint<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints); List<Set<Constraint<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints);
newElems.add(nSaL); newElems.add(nSaL);
TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, urm, methodSignatureConstraint, this.pool); TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, unifyResultModel, methodSignatureConstraint, this.pool);
forks.add(fork); forks.add(fork);
fork.fork(); fork.fork();
} }
writeLog("wait " + forkOrig.thNo); writeLog("wait " + forkOrig.threadNumber);
res = forkOrig.join(); res = forkOrig.join();
writeLog("JoinOrig " + Integer.valueOf(forkOrig.thNo).toString()); writeLog("JoinOrig " + Integer.valueOf(forkOrig.threadNumber).toString());
forks.forEach(x -> writeLog("wait: " + x.thNo)); forks.forEach(x -> writeLog("wait: " + x.threadNumber));
for (TypeUnify2Task fork : forks) { for (TypeUnify2Task fork : forks) {
Set<Set<UnifyPair>> fork_res = fork.join(); Set<Set<UnifyPair>> fork_res = fork.join();
writeLog("Join " + Integer.valueOf(fork.thNo).toString()); writeLog("Join " + Integer.valueOf(fork.threadNumber).toString());
add_res.add(fork_res); add_res.add(fork_res);
} }
} else {//parallel = false oder MaxNoOfThreads ist erreicht, sequentiell weiterarbeiten } else {//parallel = false oder MaxNoOfThreads ist erreicht, sequentiell weiterarbeiten
@@ -578,8 +569,8 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
result = res; result = res;
} else { } else {
if ((isUndefinedPairSetSet(res) && isUndefinedPairSetSet(result)) if ((isUndefinedPairSetSet(res) && isUndefinedPairSetSet(result))
|| (!isUndefinedPairSetSet(res) && !isUndefinedPairSetSet(result)) || (!isUndefinedPairSetSet(res) && !isUndefinedPairSetSet(result))
|| result.isEmpty()) { || result.isEmpty()) {
result.addAll(res); result.addAll(res);
} }
} }
@@ -591,8 +582,8 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
result = par_res; result = par_res;
} else { } else {
if ((isUndefinedPairSetSet(par_res) && isUndefinedPairSetSet(result)) if ((isUndefinedPairSetSet(par_res) && isUndefinedPairSetSet(result))
|| (!isUndefinedPairSetSet(par_res) && !isUndefinedPairSetSet(result)) || (!isUndefinedPairSetSet(par_res) && !isUndefinedPairSetSet(result))
|| result.isEmpty()) { || result.isEmpty()) {
result.addAll(par_res); result.addAll(par_res);
} }
} }
@@ -602,47 +593,43 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
if (isUndefinedPairSetSet(res) && aParDef.isEmpty()) { if (isUndefinedPairSetSet(res) && aParDef.isEmpty()) {
int nofstred; int nofstred;
Set<UnifyPair> abhSubst = res.stream() Set<UnifyPair> abhSubst = res.stream()
.map(b -> .map(b ->
b.stream() b.stream()
.map(x -> x.getAllSubstitutions()) .map(x -> x.getAllSubstitutions())
.reduce((y, z) -> { .reduce((y, z) -> {
y.addAll(z); y.addAll(z);
return y; return y;
}).get()) }).get())
.reduce((y, z) -> { .reduce((y, z) -> {
y.addAll(z); y.addAll(z);
return y; return y;
}).get(); }).get();
abhSubst.addAll( abhSubst.addAll(
res.stream() res.stream()
.map(b -> .map(b ->
b.stream() b.stream()
.map(x -> x.getThisAndAllBases()) //getAllBases durch getThisAndAllBases ersetzt, weil auch im UnifyPair selbst schon ein Fehler liegen kann. .map(UnifyPair::getThisAndAllBases) //getAllBases durch getThisAndAllBases ersetzt, weil auch im UnifyPair selbst schon ein Fehler liegen kann.
.reduce((y, z) -> {
y.addAll(z);
return y;
}).get())
.reduce((y, z) -> { .reduce((y, z) -> {
y.addAll(z); y.addAll(z);
return y; return y;
}).get() }).get())
.reduce((y, z) -> {
y.addAll(z);
return y;
}).get()
); );
Set<UnifyPair> b = a;//effective final a Set<UnifyPair> b = a;
Set<UnifyPair> durchschnitt = abhSubst.stream() Set<UnifyPair> durchschnitt = abhSubst.stream()
.filter(x -> b.contains(x)) .filter(x -> b.contains(x))
.collect(Collectors.toCollection(HashSet::new)); .collect(Collectors.toCollection(HashSet::new));
int len = nextSetasList.size();
nofstred = nextSetasList.size(); writeLog(
"res (undef): " + res + "\n" +
writeLog("res (undef): " + res.toString() + "\n" + "abhSubst: " + abhSubst + "\n" +
"abhSubst: " + abhSubst.toString() + "\n" + "Durchschnitt: " + durchschnitt + "\n" +
"Durchschnitt: " + durchschnitt.toString() + "\n" + "nextSet: " + nextSet + "\n" +
"nextSet: " + nextSet.toString() + "\n" + "nextSetasList: " + nextSetasList + "\n"
"nextSetasList: " + nextSetasList.toString() + "\n" + );
"Number first erased Elements (undef): " + (len - nofstred) + "\n" +
"Number second erased Elements (undef): " + (nofstred - nextSetasList.size()) + "\n" +
"Number erased Elements (undef): " + (len - nextSetasList.size()));
} }
} }
return result; return result;
@@ -856,31 +843,31 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
while (eq2sprimeit.hasNext()) {// alle mit Variance != 0 nach vorne schieben while (eq2sprimeit.hasNext()) {// alle mit Variance != 0 nach vorne schieben
UnifyPair up = eq2sprimeit.next(); UnifyPair up = eq2sprimeit.next();
if ((up.getLhsType() instanceof PlaceholderType && if ((up.getLhsType() instanceof PlaceholderType &&
((PlaceholderType) up.getLhsType()).getVariance() == 1 && ((PlaceholderType) up.getLhsType()).getVariance() == 1 &&
!((PlaceholderType) up.getLhsType()).isInnerType()) || !((PlaceholderType) up.getLhsType()).isInnerType()) ||
(up.getRhsType() instanceof PlaceholderType && (up.getRhsType() instanceof PlaceholderType &&
((PlaceholderType) up.getRhsType()).getVariance() == -1) && ((PlaceholderType) up.getRhsType()).getVariance() == -1) &&
!((PlaceholderType) up.getRhsType()).isInnerType()) { !((PlaceholderType) up.getRhsType()).isInnerType()) {
eq2sAsListFst.add(up); eq2sAsListFst.add(up);
eq2s.remove(up); eq2s.remove(up);
} else if ((up.getLhsType() instanceof PlaceholderType && ((PlaceholderType) up.getLhsType()).getVariance() == 1 && ((PlaceholderType) up.getLhsType()).isInnerType()) } else if ((up.getLhsType() instanceof PlaceholderType && ((PlaceholderType) up.getLhsType()).getVariance() == 1 && ((PlaceholderType) up.getLhsType()).isInnerType())
|| (up.getRhsType() instanceof PlaceholderType && ((PlaceholderType) up.getRhsType()).getVariance() == -1) && ((PlaceholderType) up.getRhsType()).isInnerType()) { || (up.getRhsType() instanceof PlaceholderType && ((PlaceholderType) up.getRhsType()).getVariance() == -1) && ((PlaceholderType) up.getRhsType()).isInnerType()) {
eq2sAsListSnd.add(up); eq2sAsListSnd.add(up);
eq2s.remove(up); eq2s.remove(up);
} else if ((up.getLhsType() instanceof PlaceholderType && } else if ((up.getLhsType() instanceof PlaceholderType &&
((PlaceholderType) up.getLhsType()).getVariance() == -1 && ((PlaceholderType) up.getLhsType()).getVariance() == -1 &&
!((PlaceholderType) up.getLhsType()).isInnerType()) || !((PlaceholderType) up.getLhsType()).isInnerType()) ||
(up.getRhsType() instanceof PlaceholderType && (up.getRhsType() instanceof PlaceholderType &&
((PlaceholderType) up.getRhsType()).getVariance() == -1) && ((PlaceholderType) up.getRhsType()).getVariance() == -1) &&
!((PlaceholderType) up.getRhsType()).isInnerType()) { !((PlaceholderType) up.getRhsType()).isInnerType()) {
eq2sAsListThird.add(up); eq2sAsListThird.add(up);
eq2s.remove(up); eq2s.remove(up);
} else if ((up.getLhsType() instanceof PlaceholderType && ((PlaceholderType) up.getLhsType()).getVariance() == -1 && ((PlaceholderType) up.getLhsType()).isInnerType()) } else if ((up.getLhsType() instanceof PlaceholderType && ((PlaceholderType) up.getLhsType()).getVariance() == -1 && ((PlaceholderType) up.getLhsType()).isInnerType())
|| (up.getRhsType() instanceof PlaceholderType && ((PlaceholderType) up.getRhsType()).getVariance() == 1) && ((PlaceholderType) up.getRhsType()).isInnerType()) { || (up.getRhsType() instanceof PlaceholderType && ((PlaceholderType) up.getRhsType()).getVariance() == 1) && ((PlaceholderType) up.getRhsType()).isInnerType()) {
eq2sAsListFourth.add(up); eq2sAsListFourth.add(up);
eq2s.remove(up); eq2s.remove(up);
} else if ((up.getLhsType() instanceof PlaceholderType && ((PlaceholderType) up.getLhsType()).isInnerType()) } else if ((up.getLhsType() instanceof PlaceholderType && ((PlaceholderType) up.getLhsType()).isInnerType())
|| (up.getRhsType() instanceof PlaceholderType && ((PlaceholderType) up.getRhsType()).isInnerType())) { || (up.getRhsType() instanceof PlaceholderType && ((PlaceholderType) up.getRhsType()).isInnerType())) {
eq2sAsListBack.add(up); eq2sAsListBack.add(up);
eq2s.remove(up); eq2s.remove(up);
} }
@@ -888,14 +875,14 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
//if (eq2sAsListFst.isEmpty()) //if (eq2sAsListFst.isEmpty())
{ {
List<Set<Constraint<UnifyPair>>> oderConstraintsVariance = oderConstraintsOutput.stream() //Alle Elemente rauswerfen, die Variance 0 haben oder keine TPH in LHS oder RHS sind List<Set<Constraint<UnifyPair>>> oderConstraintsVariance = oderConstraintsOutput.stream() //Alle Elemente rauswerfen, die Variance 0 haben oder keine TPH in LHS oder RHS sind
.filter(x -> x.stream() .filter(x -> x.stream()
.anyMatch(y -> .anyMatch(y ->
y.stream().anyMatch(z -> ((z.getLhsType() instanceof PlaceholderType) y.stream().anyMatch(z -> ((z.getLhsType() instanceof PlaceholderType)
&& (((PlaceholderType) (z.getLhsType())).getVariance() != 0)) && (((PlaceholderType) (z.getLhsType())).getVariance() != 0))
|| ((z.getRhsType() instanceof PlaceholderType) || ((z.getRhsType() instanceof PlaceholderType)
&& (((PlaceholderType) (z.getRhsType())).getVariance() != 0)) && (((PlaceholderType) (z.getRhsType())).getVariance() != 0))
) )
)).collect(Collectors.toList()); )).collect(Collectors.toList());
if (!oderConstraintsVariance.isEmpty()) { if (!oderConstraintsVariance.isEmpty()) {
Set<Constraint<UnifyPair>> ret = oderConstraintsVariance.get(0); Set<Constraint<UnifyPair>> ret = oderConstraintsVariance.get(0);
oderConstraintsOutput.remove(ret); oderConstraintsOutput.remove(ret);
@@ -904,15 +891,15 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
//Alle wildcard Faelle rausfiltern bei not wildcardable //Alle wildcard Faelle rausfiltern bei not wildcardable
ret = ret.stream().filter(x -> { ret = ret.stream().filter(x -> {
Optional<UnifyPair> optElem; Optional<UnifyPair> optElem;
return !((optElem = x.stream().filter(y -> (y.getLhsType()) instanceof PlaceholderType return !((optElem = x.stream().filter(y -> (y.getLhsType()) instanceof PlaceholderType
&& !((PlaceholderType) y.getLhsType()).isWildcardable() && !((PlaceholderType) y.getLhsType()).isWildcardable()
&& y.getPairOp() == PairOperator.EQUALSDOT && y.getPairOp() == PairOperator.EQUALSDOT
&& !(y.getRhsType() instanceof PlaceholderType)) && !(y.getRhsType() instanceof PlaceholderType))
.findAny()).isPresent() .findAny()).isPresent()
&& optElem.get().getRhsType() instanceof ExtendsType); && optElem.get().getRhsType() instanceof ExtendsType);
}) })
.collect(Collectors.toSet()); .collect(Collectors.toSet());
ret.stream().forEach(x -> x.stream().forEach(y -> { ret.stream().forEach(x -> x.stream().forEach(y -> {
Set<UnifyPair> x_new = new HashSet<>(x); //PL 2020-03-18: y selbst darf nicht in die Substitutionen Set<UnifyPair> x_new = new HashSet<>(x); //PL 2020-03-18: y selbst darf nicht in die Substitutionen
x_new.remove(y); x_new.remove(y);
@@ -923,10 +910,10 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
} }
} }
writeLog("eq2s: " + eq2s.toString() + "\n" + writeLog("eq2s: " + eq2s + "\n" +
"eq2sAsListFst: " + eq2sAsListFst.toString() + "\n" + "eq2sAsListFst: " + eq2sAsListFst + "\n" +
"eq2sAsListSnd: " + eq2sAsListSnd.toString() + "\n" + "eq2sAsListSnd: " + eq2sAsListSnd + "\n" +
"eq2sAsListBack: " + eq2sAsListBack.toString()); "eq2sAsListBack: " + eq2sAsListBack);
eq2sAsList.addAll(eq2sAsListFst); eq2sAsList.addAll(eq2sAsListFst);
eq2sAsList.addAll(eq2sAsListSnd); eq2sAsList.addAll(eq2sAsListSnd);
@@ -945,15 +932,15 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
//Alle wildcard Faelle rausfiltern bei not wildcardable //Alle wildcard Faelle rausfiltern bei not wildcardable
ret = ret.stream().filter(x -> { ret = ret.stream().filter(x -> {
Optional<UnifyPair> optElem; Optional<UnifyPair> optElem;
return !((optElem = x.stream().filter(y -> (y.getLhsType()) instanceof PlaceholderType return !((optElem = x.stream().filter(y -> (y.getLhsType()) instanceof PlaceholderType
&& !((PlaceholderType) y.getLhsType()).isWildcardable() && !((PlaceholderType) y.getLhsType()).isWildcardable()
&& y.getPairOp() == PairOperator.EQUALSDOT && y.getPairOp() == PairOperator.EQUALSDOT
&& !(y.getRhsType() instanceof PlaceholderType)) && !(y.getRhsType() instanceof PlaceholderType))
.findAny()).isPresent() .findAny()).isPresent()
&& optElem.get().getRhsType() instanceof ExtendsType); && optElem.get().getRhsType() instanceof ExtendsType);
}) })
.collect(Collectors.toSet()); .collect(Collectors.toSet());
ret.stream().forEach(x -> x.stream().forEach(y -> { ret.stream().forEach(x -> x.stream().forEach(y -> {
Set<UnifyPair> x_new = new HashSet<>(x); //PL 2020-03-18: y selbst darf nicht in die Substitutionen Set<UnifyPair> x_new = new HashSet<>(x); //PL 2020-03-18: y selbst darf nicht in die Substitutionen
@@ -1157,7 +1144,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
// Filter empty sets or sets that only contain an empty set. // Filter empty sets or sets that only contain an empty set.
return result.stream().map(x -> x.stream().filter(y -> !y.isEmpty()).collect(Collectors.toCollection(HashSet::new))) return result.stream().map(x -> x.stream().filter(y -> !y.isEmpty()).collect(Collectors.toCollection(HashSet::new)))
.filter(x -> !x.isEmpty()).collect(Collectors.toCollection(HashSet::new)); .filter(x -> !x.isEmpty()).collect(Collectors.toCollection(HashSet::new));
} }
//TODO: Wenn Theta' nicht im FC muss ein Fehler produziert werden PL 18-04-20 //TODO: Wenn Theta' nicht im FC muss ein Fehler produziert werden PL 18-04-20
@@ -1208,12 +1195,12 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
return aa; return aa;
}; };
HashMap<PlaceholderType, PlaceholderType> hm = x.getInvolvedPlaceholderTypes().stream() HashMap<PlaceholderType, PlaceholderType> hm = x.getInvolvedPlaceholderTypes().stream()
.reduce(new HashMap<>(), .reduce(new HashMap<>(),
(aa, b) -> { (aa, b) -> {
aa.put(b, PlaceholderType.freshPlaceholder()); aa.put(b, PlaceholderType.freshPlaceholder());
return aa; return aa;
}, combiner); }, combiner);
return x.accept(new freshPlaceholder(), hm); return x.accept(new FreshPlaceholder(), hm);
}).collect(Collectors.toCollection(HashSet::new)); }).collect(Collectors.toCollection(HashSet::new));
IMatch match = new Match(); IMatch match = new Match();
@@ -1228,7 +1215,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
if ((match.match(ml)).isEmpty()) { if ((match.match(ml)).isEmpty()) {
thetaQs.remove(c); thetaQs.remove(c);
} }
writeLog("thetaQs von " + c + ": " + thetaQs.toString()); writeLog("thetaQs von " + c + ": " + thetaQs);
//Set<UnifyType> thetaQs = fc.getChildren(c).stream().collect(Collectors.toCollection(HashSet::new)); //Set<UnifyType> thetaQs = fc.getChildren(c).stream().collect(Collectors.toCollection(HashSet::new));
//thetaQs.add(thetaPrime); //PL 18-02-05 wieder geloescht //thetaQs.add(thetaPrime); //PL 18-02-05 wieder geloescht
//PL 2017-10-03: War auskommentiert habe ich wieder einkommentiert, //PL 2017-10-03: War auskommentiert habe ich wieder einkommentiert,
@@ -1252,7 +1239,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
for (TypeParams tp : permuteParams(candidateParams)) for (TypeParams tp : permuteParams(candidateParams))
thetaQPrimes.add(c.setTypeParams(tp)); thetaQPrimes.add(c.setTypeParams(tp));
} }
writeLog("thetaQPrimes von " + c + ": " + thetaQPrimes.toString()); writeLog("thetaQPrimes von " + c + ": " + thetaQPrimes);
for (UnifyType tqp : thetaQPrimes) {//PL 2020-03-08 umbauen in der Schleife wird nur unifizierbarer Typ gesucht break am Ende for (UnifyType tqp : thetaQPrimes) {//PL 2020-03-08 umbauen in der Schleife wird nur unifizierbarer Typ gesucht break am Ende
Collection<PlaceholderType> tphs = tqp.getInvolvedPlaceholderTypes(); Collection<PlaceholderType> tphs = tqp.getInvolvedPlaceholderTypes();
Optional<Unifier> opt = stdUnify.unify(tqp, thetaPrime); Optional<Unifier> opt = stdUnify.unify(tqp, thetaPrime);
@@ -1265,9 +1252,9 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
for (Entry<PlaceholderType, UnifyType> sigma : unifier) { for (Entry<PlaceholderType, UnifyType> sigma : unifier) {
if (!tphs.contains(sigma.getKey())) {//eingefuegt PL 2019-02-02 Bug 127 if (!tphs.contains(sigma.getKey())) {//eingefuegt PL 2019-02-02 Bug 127
substitutionSet.add(new UnifyPair(sigma.getKey(), sigma.getValue(), PairOperator.EQUALSDOT, substitutionSet.add(new UnifyPair(sigma.getKey(), sigma.getValue(), PairOperator.EQUALSDOT,
//TODO: nochmals ueberlegen ob hier pair.getSubstitution() korrekt ist, oder ob leere Menge hin müsste //TODO: nochmals ueberlegen ob hier pair.getSubstitution() korrekt ist, oder ob leere Menge hin müsste
//alle folgenden New UnifyPair ebenfalls ueberpruefen PL 2018-04-19 //alle folgenden New UnifyPair ebenfalls ueberpruefen PL 2018-04-19
pair.getSubstitution(), pair)); pair.getSubstitution(), pair));
} }
} }
//List<UnifyType> freshTphs = new ArrayList<>(); PL 18-02-06 in die For-Schleife verschoben //List<UnifyType> freshTphs = new ArrayList<>(); PL 18-02-06 in die For-Schleife verschoben
@@ -1279,14 +1266,14 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
//eingefuegt PL 2018-03-29 Anfang ? ext. theta hinzufuegen //eingefuegt PL 2018-03-29 Anfang ? ext. theta hinzufuegen
if (a.isWildcardable()) { if (a.isWildcardable()) {
Set<UnifyType> smaller_ext = smaller.stream().filter(x -> !(x instanceof ExtendsType) && !(x instanceof SuperType)) Set<UnifyType> smaller_ext = smaller.stream().filter(x -> !(x instanceof ExtendsType) && !(x instanceof SuperType))
.map(x -> { .map(x -> {
//BinaryOperator<HashMap<PlaceholderType,PlaceholderType>> combiner = (aa,b) -> { aa.putAll(b); return aa;}; //Variablenumbenennung rausgenommen //BinaryOperator<HashMap<PlaceholderType,PlaceholderType>> combiner = (aa,b) -> { aa.putAll(b); return aa;}; //Variablenumbenennung rausgenommen
//HashMap<PlaceholderType,PlaceholderType> hm = x.getInvolvedPlaceholderTypes().stream() //Variablen muessen wahrscheinlich erhalten bleiben //HashMap<PlaceholderType,PlaceholderType> hm = x.getInvolvedPlaceholderTypes().stream() //Variablen muessen wahrscheinlich erhalten bleiben
// .reduce(new HashMap<PlaceholderType,PlaceholderType>(), // .reduce(new HashMap<PlaceholderType,PlaceholderType>(),
// (aa, b)-> { aa.put(b,PlaceholderType.freshPlaceholder()); return aa; }, combiner); // (aa, b)-> { aa.put(b,PlaceholderType.freshPlaceholder()); return aa; }, combiner);
return new ExtendsType(x); return new ExtendsType(x);
})//.accept(new freshPlaceholder(), hm));} })//.accept(new freshPlaceholder(), hm));}
.collect(Collectors.toCollection(HashSet::new)); .collect(Collectors.toCollection(HashSet::new));
smaller.addAll(smaller_ext); smaller.addAll(smaller_ext);
} }
//eingefuegt PL 2018-03-29 Ende ? ext. theta hinzufuegen //eingefuegt PL 2018-03-29 Ende ? ext. theta hinzufuegen
@@ -1305,13 +1292,13 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
UnifyPair up = new UnifyPair(a, theta, PairOperator.EQUALSDOT, pair.getSubstitution(), pair); UnifyPair up = new UnifyPair(a, theta, PairOperator.EQUALSDOT, pair.getSubstitution(), pair);
//TODO PL 2019-01-24: upit.next() ist nicht unbedingt ein PlaceholderType -> Visitor erledigt //TODO PL 2019-01-24: upit.next() ist nicht unbedingt ein PlaceholderType -> Visitor erledigt
for (UnifyType unifyType : up.getRhsType().getTypeParams()) for (UnifyType unifyType : up.getRhsType().getTypeParams())
unifyType.accept(new distributeVariance(), a.getVariance());//((PlaceholderType)upit.next()).setVariance(a.getVariance()); unifyType.accept(new DistributeVariance(), a.getVariance());//((PlaceholderType)upit.next()).setVariance(a.getVariance());
resultPrime.add(up); resultPrime.add(up);
} else { } else {
UnifyPair up = new UnifyPair(a, theta.setTypeParams(new TypeParams(freshTphs.toArray(new UnifyType[0]))), PairOperator.EQUALSDOT, pair.getSubstitution(), pair); UnifyPair up = new UnifyPair(a, theta.setTypeParams(new TypeParams(freshTphs.toArray(new UnifyType[0]))), PairOperator.EQUALSDOT, pair.getSubstitution(), pair);
//TODO PL 2019-01-24: upit.next() ist nicht unbedingt ein PlaceholderType -> Visitor erledigt //TODO PL 2019-01-24: upit.next() ist nicht unbedingt ein PlaceholderType -> Visitor erledigt
for (UnifyType unifyType : up.getRhsType().getTypeParams()) for (UnifyType unifyType : up.getRhsType().getTypeParams())
unifyType.accept(new distributeVariance(), a.getVariance()); //((PlaceholderType)upit.next()).setVariance(a.getVariance()); unifyType.accept(new DistributeVariance(), a.getVariance()); //((PlaceholderType)upit.next()).setVariance(a.getVariance());
resultPrime.add(up); resultPrime.add(up);
} }
resultPrime.addAll(substitutionSet); resultPrime.addAll(substitutionSet);
@@ -1323,7 +1310,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
} }
} }
} }
writeLog("result von " + pair + ": " + result.toString()); writeLog("result von " + pair + ": " + result);
return result; return result;
} }
@@ -1337,7 +1324,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
PlaceholderType aPrime = PlaceholderType.freshPlaceholder(); PlaceholderType aPrime = PlaceholderType.freshPlaceholder();
aPrime.setVariance(a.getVariance()); aPrime.setVariance(a.getVariance());
aPrime.disableWildcardtable(); aPrime.disableWildcardable();
UnifyType extAPrime = new ExtendsType(aPrime); UnifyType extAPrime = new ExtendsType(aPrime);
UnifyType thetaPrime = extThetaPrime.getExtendedType(); UnifyType thetaPrime = extThetaPrime.getExtendedType();
Set<UnifyPair> resultPrime = new HashSet<>(); Set<UnifyPair> resultPrime = new HashSet<>();
@@ -1363,11 +1350,11 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
PlaceholderType aPrime = PlaceholderType.freshPlaceholder(); PlaceholderType aPrime = PlaceholderType.freshPlaceholder();
aPrime.setVariance(a.getVariance()); aPrime.setVariance(a.getVariance());
aPrime.disableWildcardtable(); aPrime.disableWildcardable();
UnifyType supAPrime = new SuperType(aPrime); UnifyType supAPrime = new SuperType(aPrime);
UnifyType thetaPrime = subThetaPrime.getSuperedType(); UnifyType thetaPrime = subThetaPrime.getSuperedType();
Set<UnifyPair> resultPrime = new HashSet<>(); Set<UnifyPair> resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(thetaPrime, a, PairOperator.SMALLERDOT, pair.getSubstitution(), pair, pair.getfBounded())); resultPrime.add(new UnifyPair(thetaPrime, a, PairOperator.SMALLERDOT, pair.getSubstitution(), pair, pair.getFBounded()));
result.add(resultPrime); result.add(resultPrime);
//writeLog(resultPrime.toString()); //writeLog(resultPrime.toString());
@@ -1399,18 +1386,18 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
//fc.setLogTrue(); //fc.setLogTrue();
//writeLog("FBOUNDED: " + pair.getfBounded()); //writeLog("FBOUNDED: " + pair.getfBounded());
//writeLog("Pair: " + pair); //writeLog("Pair: " + pair);
Set<UnifyType> greater = fc.greater(theta, pair.getfBounded()); Set<UnifyType> greater = fc.greater(theta, pair.getFBounded());
//writeLog("GREATER: " + greater + pair + "THETA: " + theta + "FBOUNDED: " + pair.getfBounded() + " "); //writeLog("GREATER: " + greater + pair + "THETA: " + theta + "FBOUNDED: " + pair.getfBounded() + " ");
if (a.isWildcardable()) { if (a.isWildcardable()) {
Set<UnifyType> greater_ext = greater.stream().filter(x -> !(x instanceof ExtendsType) && !(x instanceof SuperType)) Set<UnifyType> greater_ext = greater.stream().filter(x -> !(x instanceof ExtendsType) && !(x instanceof SuperType))
.map(x -> { .map(x -> {
//BinaryOperator<HashMap<PlaceholderType,PlaceholderType>> combiner = (aa,b) -> { aa.putAll(b); return aa;}; //Variablenumbenennung rausgenommen //BinaryOperator<HashMap<PlaceholderType,PlaceholderType>> combiner = (aa,b) -> { aa.putAll(b); return aa;}; //Variablenumbenennung rausgenommen
//HashMap<PlaceholderType,PlaceholderType> hm = x.getInvolvedPlaceholderTypes().stream() //Variablen muessen wahrscheinlich erhalten bleiben //HashMap<PlaceholderType,PlaceholderType> hm = x.getInvolvedPlaceholderTypes().stream() //Variablen muessen wahrscheinlich erhalten bleiben
// .reduce(new HashMap<PlaceholderType,PlaceholderType>(), // .reduce(new HashMap<PlaceholderType,PlaceholderType>(),
// (aa, b)-> { aa.put(b,PlaceholderType.freshPlaceholder()); return aa; }, combiner); // (aa, b)-> { aa.put(b,PlaceholderType.freshPlaceholder()); return aa; }, combiner);
return new SuperType(x); return new SuperType(x);
})//.accept(new freshPlaceholder(), hm));} })//.accept(new freshPlaceholder(), hm));}
.collect(Collectors.toCollection(HashSet::new)); .collect(Collectors.toCollection(HashSet::new));
greater.addAll(greater_ext); greater.addAll(greater_ext);
} }
//eingefuegt PL 2019-01-03 ENDE //eingefuegt PL 2019-01-03 ENDE
@@ -1424,7 +1411,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
for (int i = 0; !allGen && i < freshTphs.length; i++) { for (int i = 0; !allGen && i < freshTphs.length; i++) {
freshTphs[i] = PlaceholderType.freshPlaceholder(); freshTphs[i] = PlaceholderType.freshPlaceholder();
((PlaceholderType) freshTphs[i]).setVariance(a.getVariance()); ((PlaceholderType) freshTphs[i]).setVariance(a.getVariance());
Set<UnifyType> fBounded = new HashSet<>(pair.getfBounded()); //PL 2019-01-09 new HashSet eingefuegt Set<UnifyType> fBounded = new HashSet<>(pair.getFBounded()); //PL 2019-01-09 new HashSet eingefuegt
int i_ef = i; int i_ef = i;
BiFunction<Boolean, UnifyType, Boolean> f = (x, y) -> BiFunction<Boolean, UnifyType, Boolean> f = (x, y) ->
@@ -1473,10 +1460,10 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
PlaceholderType freshTph = PlaceholderType.freshPlaceholder(); PlaceholderType freshTph = PlaceholderType.freshPlaceholder();
freshTph.setVariance(a.getVariance()); freshTph.setVariance(a.getVariance());
freshTph.disableWildcardtable(); freshTph.disableWildcardable();
resultPrime = new HashSet<>(); resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(a, new ExtendsType(freshTph), PairOperator.EQUALSDOT, pair.getSubstitution(), pair)); resultPrime.add(new UnifyPair(a, new ExtendsType(freshTph), PairOperator.EQUALSDOT, pair.getSubstitution(), pair));
resultPrime.add(new UnifyPair(theta, freshTph, PairOperator.SMALLERDOT, pair.getSubstitution(), pair, pair.getfBounded())); resultPrime.add(new UnifyPair(theta, freshTph, PairOperator.SMALLERDOT, pair.getSubstitution(), pair, pair.getFBounded()));
result.add(resultPrime); result.add(resultPrime);
//writeLog("resultPrime: " + resultPrime.toString()); //writeLog("resultPrime: " + resultPrime.toString());
@@ -1528,14 +1515,14 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
void writeLog(String str) { void writeLog(String str) {
if (log) { if (log) {
if (parallel) { if (parallel) {
logFile.write("Thread no.:" + thNo + "\n" logFile.write("Thread no.:" + threadNumber + "\n"
+ "parallel:" + parallel + "\n" + "parallel:" + parallel + "\n"
+ str + "\n\n" + str + "\n\n"
); );
} else { } else {
logFile.writeNonThreaded("Thread no.:" + thNo + "\n" logFile.writeNonThreaded("Thread no.:" + threadNumber + "\n"
+ "parallel:" + parallel + "\n" + "parallel:" + parallel + "\n"
+ str + "\n\n" + str + "\n\n"
); );
} }
} }
@@ -1543,11 +1530,11 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
void writeStatistics(String str) { void writeStatistics(String str) {
try { try {
statisticsFile.write("Thread No. " + thNo + ": " + str + "\n"); statisticsFile.write("Thread No. " + threadNumber + ": " + str + "\n");
statisticsFile.flush(); statisticsFile.flush();
} catch (IOException e) { } catch (IOException e) {
System.err.println("kein StatisticsFile"); System.err.println("kein StatisticsFile");
} }
} }
} }

View File

@@ -1,18 +0,0 @@
package de.dhbwstuttgart.typeinference.unify;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import java.util.List;
public class UnifyResultEvent {
private List<ResultSet> newTypeResult;
public UnifyResultEvent(List<ResultSet> newTypeResult) {
this.newTypeResult = newTypeResult;
}
public List<ResultSet> getNewTypeResult() {
return newTypeResult;
}
}

View File

@@ -1,7 +0,0 @@
package de.dhbwstuttgart.typeinference.unify;
public interface UnifyResultListener {
void onNewTypeResultFound(UnifyResultEvent evt);
}

View File

@@ -1,21 +0,0 @@
package de.dhbwstuttgart.typeinference.unify;
import java.util.ArrayList;
import java.util.List;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
public class UnifyResultListenerImpl implements UnifyResultListener {
List<ResultSet> results = new ArrayList<>();
public synchronized void onNewTypeResultFound(UnifyResultEvent evt) {
results.addAll(evt.getNewTypeResult());
}
public List<ResultSet> getResults() {
return results;
}
}

View File

@@ -1,55 +0,0 @@
package de.dhbwstuttgart.typeinference.unify;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import java.util.*;
import java.util.stream.Collectors;
public class UnifyResultModel {
ConstraintSet<de.dhbwstuttgart.typeinference.constraints.Pair> cons;
IFiniteClosure fc;
public UnifyResultModel(ConstraintSet<de.dhbwstuttgart.typeinference.constraints.Pair> cons,
IFiniteClosure fc) {
this.cons = cons;
this.fc = fc;
}
private List<UnifyResultListener> listeners = new ArrayList<>();
public void addUnifyResultListener(UnifyResultListener listenerToAdd) {
listeners.add(listenerToAdd);
}
public void removeUnifyResultListener(UnifyResultListener listenerToRemove) {
listeners.remove(listenerToRemove);
}
public void notify(Set<Set<UnifyPair>> eqPrimePrimeSet) {
Set<Set<UnifyPair>> eqPrimePrimeSetRet = eqPrimePrimeSet.stream().map(x -> {
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> {
if (y.getPairOp() == PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT);
return y; //alle Paare a <.? b erden durch a =. b ersetzt
}).collect(Collectors.toCollection(HashSet::new)));
if (res.isPresent()) {//wenn subst ein Erg liefert wurde was veraendert
return new TypeUnifyTask().applyTypeUnificationRules(res.get(), fc);
}
else return x; //wenn nichts veraendert wurde wird x zurueckgegeben
}).collect(Collectors.toCollection(HashSet::new));
List<ResultSet> newResult = eqPrimePrimeSetRet.stream().map(unifyPairs ->
new ResultSet(UnifyTypeFactory.convert(unifyPairs, de.dhbwstuttgart.typeinference.constraints.Pair.generateTPHMap(cons))))
.collect(Collectors.toList());
UnifyResultEvent evt = new UnifyResultEvent(newResult);
for (UnifyResultListener listener : listeners) {
listener.onNewTypeResultFound(evt);
}
}
}

View File

@@ -1,57 +1,54 @@
package de.dhbwstuttgart.typeinference.unify; package de.dhbwstuttgart.typeinference.unify;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory; import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.typeinference.TypeInferenceHelper;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import java.util.*; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class UnifyResultModelParallel { public class UnifyResultModelParallel {
private final ConstraintSet<Pair> cons;
private final IFiniteClosure fc;
private final List<ResultSet> results = new ArrayList<>();
private ForkJoinPool pool; private ForkJoinPool pool;
private ConstraintSet<Pair> cons;
private IFiniteClosure fc;
private List<UnifyResultListener> listeners = new ArrayList<>();
public UnifyResultModelParallel(ConstraintSet<Pair> cons, IFiniteClosure fc){ public UnifyResultModelParallel(ConstraintSet<Pair> cons, IFiniteClosure fc) {
this.cons = cons; this.cons = cons;
this.fc = fc; this.fc = fc;
} }
public void setPool(ForkJoinPool pool){ public void setPool(ForkJoinPool pool) {
this.pool = pool; this.pool = pool;
} }
public void addUnifyResultListener(UnifyResultListener listenerToAdd) {
listeners.add(listenerToAdd);
}
public void removeUnifyResultListener(UnifyResultListener listenerToRemove) {
listeners.remove(listenerToRemove);
}
public void notify(Set<Set<UnifyPair>> eqPrimePrimeSet){
pool.execute(()->{
Set<Set<UnifyPair>> eqPrimePrimeSetRet = eqPrimePrimeSet.stream().map(x -> {
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> {
if (y.getPairOp() == PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT);
return y; //alle Paare a <.? b erden durch a =. b ersetzt
}).collect(Collectors.toCollection(HashSet::new)));
if (res.isPresent()) {//wenn subst ein Erg liefert wurde was veraendert
return new TypeUnifyTask().applyTypeUnificationRules(res.get(), fc);
}
else return x; //wenn nichts veraendert wurde wird x zurueckgegeben
}).collect(Collectors.toCollection(HashSet::new));
List<ResultSet> newResult = eqPrimePrimeSetRet.stream().map(unifyPairs ->
new ResultSet(UnifyTypeFactory.convert(unifyPairs, de.dhbwstuttgart.typeinference.constraints.Pair.generateTPHMap(cons))))
.collect(Collectors.toList());
UnifyResultEvent evt = new UnifyResultEvent(newResult);
for (UnifyResultListener listener : listeners) { public synchronized void onNewTypeResultFound(List<ResultSet> result) {
listener.onNewTypeResultFound(evt); results.addAll(result);
} }
public List<ResultSet> getResults() {
return results;
}
public void notify(Set<Set<UnifyPair>> eqPrimePrimeSet) {
pool.execute(() -> {
Set<Set<UnifyPair>> eqPrimePrimeSetRet =
TypeInferenceHelper.resolveSubstitutions(new HashSet<>(eqPrimePrimeSet), fc);
List<ResultSet> newResult = eqPrimePrimeSetRet.stream().map(unifyPairs ->
new ResultSet(UnifyTypeFactory.convert(unifyPairs, de.dhbwstuttgart.typeinference.constraints.Pair.generateTPHMap(cons))))
.collect(Collectors.toList());
// TODO: this is a synchronized call, can we find a way around this?
this.onNewTypeResultFound(newResult);
}); });
} }
} }

View File

@@ -5,12 +5,12 @@ import java.util.concurrent.ForkJoinPool;
public class UnifyTaskModelParallel { public class UnifyTaskModelParallel {
private ForkJoinPool pool; private ForkJoinPool pool;
public void setPool(ForkJoinPool pool){ public void setPool(ForkJoinPool pool) {
this.pool = pool; this.pool = pool;
} }
public void cancel(){ public void cancel() {
if(this.pool != null) { if (this.pool != null) {
this.pool.shutdown(); this.pool.shutdown();
} }
} }

View File

@@ -0,0 +1,40 @@
package de.dhbwstuttgart.typeinference.unify;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
import de.dhbwstuttgart.typeinference.unify.model.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Collectors;
public class VisitUnifyTypeVisitor<T> implements UnifyTypeVisitor<T> {
public ReferenceType visit(ReferenceType refty, T ht) {
return new ReferenceType(refty.getName(),
new TypeParams(
Arrays.stream(refty.getTypeParams().get())
.map(x -> x.accept(this, ht))
.collect(Collectors.toCollection(ArrayList::new))));
}
public PlaceholderType visit(PlaceholderType phty, T ht) {
return phty;
}
public FunNType visit(FunNType funnty, T ht) {
return FunNType.getFunNType(
new TypeParams(
Arrays.stream(funnty.getTypeParams().get())
.map(x -> x.accept(this, ht))
.collect(Collectors.toCollection(ArrayList::new)))
);
}
public SuperType visit(SuperType suty, T ht) {
return new SuperType(suty.getWildcardedType().accept(this, ht));
}
public ExtendsType visit(ExtendsType extty, T ht) {
return new ExtendsType(extty.getWildcardedType().accept(this, ht));
}
}

View File

@@ -5,48 +5,54 @@ import java.io.Writer;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
public class WriterActiveObject { public class WriterActiveObject {
private Writer writer;
private ForkJoinPool pool;
public WriterActiveObject(Writer writer, ForkJoinPool pool){ private final Writer writer;
private final ForkJoinPool pool;
public WriterActiveObject(Writer writer, ForkJoinPool pool) {
this.writer = writer; this.writer = writer;
this.pool = pool; this.pool = pool;
} }
public void close(){ public void write(String message) {
pool.execute(()->{ pool.execute(() -> {
try {
writer.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
});
}
public void write(String message){
pool.execute(()->{
try { try {
writer.write(message); writer.write(message);
// TODO: do something against this flush(). Writing to disk is slooooooow
writer.flush(); writer.flush();
} catch (IOException e) { } catch (IOException e) {
// TODO: why is here a random error conversion down to a runtimeException?
throw new RuntimeException(e); throw new RuntimeException(e);
} }
}); });
} }
public void writeNonThreaded(String message){ public void writeNonThreaded(String message) {
try { try {
writer.write(message); writer.write(message);
// TODO: do something against this flush(). Writing to disk is slooooooow
writer.flush(); writer.flush();
} catch (IOException e) { } catch (IOException e) {
// TODO: why is here a random error conversion down to a runtimeException?
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
public void closeNonThreaded(){ public void close() {
pool.execute(() -> {
try {
writer.close();
} catch (IOException e) {
System.err.println(e.getMessage());
}
});
}
public void closeNonThreaded() {
try { try {
writer.close(); writer.close();
} catch (IOException e) { } catch (IOException e) {
// TODO: why is here a random error conversion down to a runtimeException?
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }

View File

@@ -1,54 +0,0 @@
package de.dhbwstuttgart.typeinference.unify;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import de.dhbwstuttgart.typeinference.unify.model.FunNType;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
public class distributeVariance extends visitUnifyTypeVisitor<Integer> {
public static int inverseVariance(int variance) {
Integer ret = 0;
if (variance == 1) {
ret = -1;
}
if (variance == -1) {
ret = 1;
}
return ret;
}
@Override
public PlaceholderType visit(PlaceholderType phty, Integer ht) {
if (ht != 0) {
if (phty.getVariance() == 0) {
phty.setVariance(ht);
}
//PL 2018-05-17 urspruengliche Variance nicht veraendern
//else if (phty.getVariance() != ht) {
// phty.setVariance(0);
//}
}
return phty;
}
public FunNType visit(FunNType funnty, Integer ht) {
List<UnifyType> param = new ArrayList<>(funnty.getTypeParams().get().length);
param.addAll(Arrays.asList(funnty.getTypeParams().get()));
UnifyType resultType = param.remove(param.size()-1);
Integer htInverse = inverseVariance(ht);
param = param.stream()
.map(x -> x.accept(this, htInverse))
.collect(Collectors.toCollection(ArrayList::new));
param.add(resultType.accept(this, ht));
return FunNType.getFunNType(new TypeParams(param));
}
}

View File

@@ -1,15 +0,0 @@
package de.dhbwstuttgart.typeinference.unify;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import java.util.HashMap;
public class freshPlaceholder extends visitUnifyTypeVisitor<HashMap<PlaceholderType,PlaceholderType>> {
@Override
public PlaceholderType visit(PlaceholderType phty, HashMap<PlaceholderType,PlaceholderType> ht) {
return ht.get(phty);
}
}

View File

@@ -6,58 +6,71 @@ import java.util.Optional;
import java.util.Set; import java.util.Set;
/** /**
*
* @author Florian Steurer * @author Florian Steurer
*/ */
public interface IFiniteClosure { public interface IFiniteClosure {
public void setLogTrue();
/**
* Returns all types of the finite closure that are subtypes of the argument.
* @return The set of subtypes of the argument.
*/
public Set<UnifyType> smaller(UnifyType type, Set<UnifyType> fBounded);
/**
* Returns all types of the finite closure that are supertypes of the argument.
* @return The set of supertypes of the argument.
*/
public Set<UnifyType> greater(UnifyType type, Set<UnifyType> fBounded);
/** void setLogTrue();
* Wo passt Type rein?
* @param type
* @return
*/
public Set<UnifyType> grArg(UnifyType type, Set<UnifyType> fBounded);
/**
* Was passt in Type rein?
* @param type
* @return
*/
public Set<UnifyType> smArg(UnifyType type, Set<UnifyType> fBounded);
public Set<UnifyType> grArg(ReferenceType type, Set<UnifyType> fBounded);
public Set<UnifyType> smArg(ReferenceType type, Set<UnifyType> fBounded);
public Set<UnifyType> grArg(ExtendsType type, Set<UnifyType> fBounded);
public Set<UnifyType> smArg(ExtendsType type, Set<UnifyType> fBounded);
public Set<UnifyType> grArg(SuperType type, Set<UnifyType> fBounded);
public Set<UnifyType> smArg(SuperType type, Set<UnifyType> fBounded);
public Set<UnifyType> grArg(PlaceholderType type, Set<UnifyType> fBounded); /**
public Set<UnifyType> smArg(PlaceholderType type, Set<UnifyType> fBounded); * Returns all types of the finite closure that are subtypes of the argument.
*
* @return The set of subtypes of the argument.
*/
Set<UnifyType> smaller(UnifyType type, Set<UnifyType> fBounded);
public Set<UnifyType> grArg(FunNType type, Set<UnifyType> fBounded); /**
public Set<UnifyType> smArg(FunNType type, Set<UnifyType> fBounded); * Returns all types of the finite closure that are supertypes of the argument.
*
* @return The set of supertypes of the argument.
*/
Set<UnifyType> greater(UnifyType type, Set<UnifyType> fBounded);
public Set<UnifyPair> getPairs(); /**
public Optional<UnifyType> getLeftHandedType(String typeName); * Wo passt Type rein?
public Set<UnifyType> getAncestors(UnifyType t); *
public Set<UnifyType> getChildren(UnifyType t); * @param type
public Set<UnifyType> getAllTypesByName(String typeName); * @return
*/
Set<UnifyType> grArg(UnifyType type, Set<UnifyType> fBounded);
public int compare(UnifyType rhsType, UnifyType rhsType2, PairOperator pairop); /**
* Was passt in Type rein?
*
* @param type
* @return
*/
Set<UnifyType> smArg(UnifyType type, Set<UnifyType> fBounded);
Set<UnifyType> grArg(ReferenceType type, Set<UnifyType> fBounded);
Set<UnifyType> smArg(ReferenceType type, Set<UnifyType> fBounded);
Set<UnifyType> grArg(ExtendsType type, Set<UnifyType> fBounded);
Set<UnifyType> smArg(ExtendsType type, Set<UnifyType> fBounded);
Set<UnifyType> grArg(SuperType type, Set<UnifyType> fBounded);
Set<UnifyType> smArg(SuperType type, Set<UnifyType> fBounded);
Set<UnifyType> grArg(PlaceholderType type, Set<UnifyType> fBounded);
Set<UnifyType> smArg(PlaceholderType type, Set<UnifyType> fBounded);
Set<UnifyType> grArg(FunNType type, Set<UnifyType> fBounded);
Set<UnifyType> smArg(FunNType type, Set<UnifyType> fBounded);
Set<UnifyPair> getPairs();
Optional<UnifyType> getLeftHandedType(String typeName);
Set<UnifyType> getAncestors(UnifyType t);
Set<UnifyType> getChildren(UnifyType t);
Set<UnifyType> getAllTypesByName(String typeName);
int compare(UnifyType rhsType, UnifyType rhsType2, PairOperator pairOp);
} }

View File

@@ -8,18 +8,20 @@ import java.util.Optional;
/** /**
* Match * Match
*
* @author Martin Pluemicke * @author Martin Pluemicke
* abgeleitet aus IUnify.java * abgeleitet aus IUnify.java
*/ */
public interface IMatch { public interface IMatch {
/**
* Finds the most general matcher sigma of the set {t1 =. t1',...,tn =. tn'} so that
* sigma(t1) = t1' , ... sigma(tn) = tn'.
* @param terms The set of terms to be matched
* @return An optional of the most general matcher if it exists or an empty optional if there is no matcher.
*/
public Optional<Unifier> match(ArrayList<UnifyPair> termsList);
} /**
* Finds the most general matcher sigma of the set {t1 =. t1',...,tn =. tn'} so that
* sigma(t1) = t1' , ... sigma(tn) = tn'.
*
* @param termsList The set of terms to be matched
* @return An optional of the most general matcher if it exists or an empty optional if there is no matcher.
*/
Optional<Unifier> match(ArrayList<UnifyPair> termsList);
}

View File

@@ -9,95 +9,115 @@ import java.util.Set;
/** /**
* Contains the inference rules that are applied to the set Eq. * Contains the inference rules that are applied to the set Eq.
*
* @author Florian Steurer * @author Florian Steurer
*/ */
public interface IRuleSet { public interface IRuleSet {
public Optional<UnifyPair> reduceUp(UnifyPair pair); Optional<UnifyPair> reduceUp(UnifyPair pair);
public Optional<UnifyPair> reduceLow(UnifyPair pair);
public Optional<UnifyPair> reduceUpLow(UnifyPair pair); Optional<UnifyPair> reduceLow(UnifyPair pair);
public Optional<Set<UnifyPair>> reduceExt(UnifyPair pair, IFiniteClosure fc);
public Optional<Set<UnifyPair>> reduceSup(UnifyPair pair, IFiniteClosure fc); Optional<UnifyPair> reduceUpLow(UnifyPair pair);
public Optional<Set<UnifyPair>> reduceEq(UnifyPair pair);
public Optional<Set<UnifyPair>> reduce1(UnifyPair pair, IFiniteClosure fc); Optional<Set<UnifyPair>> reduceExt(UnifyPair pair, IFiniteClosure fc);
public Optional<Set<UnifyPair>> reduce2(UnifyPair pair);
Optional<Set<UnifyPair>> reduceSup(UnifyPair pair, IFiniteClosure fc);
/*
* Missing Reduce-Rules for Wildcards Optional<Set<UnifyPair>> reduceEq(UnifyPair pair);
*/
public Optional<UnifyPair> reduceWildcardLow(UnifyPair pair); Optional<Set<UnifyPair>> reduce1(UnifyPair pair, IFiniteClosure fc);
public Optional<UnifyPair> reduceWildcardLowRight(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardUp(UnifyPair pair); Optional<Set<UnifyPair>> reduce2(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardUpRight(UnifyPair pair);
/*
* Missing Reduce-Rules for Wildcards
*/
Optional<UnifyPair> reduceWildcardLow(UnifyPair pair);
Optional<UnifyPair> reduceWildcardLowRight(UnifyPair pair);
Optional<UnifyPair> reduceWildcardUp(UnifyPair pair);
Optional<UnifyPair> reduceWildcardUpRight(UnifyPair pair);
/* /*
* vgl. JAVA_BSP/Wildcard6.java * vgl. JAVA_BSP/Wildcard6.java
public Optional<UnifyPair> reduceWildcardLowUp(UnifyPair pair); Optional<UnifyPair> reduceWildcardLowUp(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardUpLow(UnifyPair pair); Optional<UnifyPair> reduceWildcardUpLow(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardLeft(UnifyPair pair); Optional<UnifyPair> reduceWildcardLeft(UnifyPair pair);
*/ */
/* /*
* Additional Rules which replace cases of the cartesian product * Additional Rules which replace cases of the cartesian product
*/ */
/** /**
* Rule that replaces the fourth case of the cartesian product where (a <.? Theta) * Rule that replaces the fourth case of the cartesian product where (a <.? Theta)
*/ */
public Optional<UnifyPair> reduceTph(UnifyPair pair); Optional<UnifyPair> reduceTph(UnifyPair pair);
/** /**
* Rule that replaces the sixth case of the cartesian product where (? ext Theta <.? a) * Rule that replaces the sixth case of the cartesian product where (? ext Theta <.? a)
*/ */
public Optional<Set<UnifyPair>> reduceTphExt(UnifyPair pair); Optional<Set<UnifyPair>> reduceTphExt(UnifyPair pair);
/** /**
* Rule that replaces the fourth case of the cartesian product where (? sup Theta <.? a) * Rule that replaces the fourth case of the cartesian product where (? sup Theta <.? a)
*/ */
public Optional<Set<UnifyPair>> reduceTphSup(UnifyPair pair); Optional<Set<UnifyPair>> reduceTphSup(UnifyPair pair);
/* /*
* FunN Rules * FunN Rules
*/ */
public Optional<Set<UnifyPair>> reduceFunN(UnifyPair pair); Optional<Set<UnifyPair>> reduceFunN(UnifyPair pair);
public Optional<Set<UnifyPair>> greaterFunN(UnifyPair pair);
public Optional<Set<UnifyPair>> smallerFunN(UnifyPair pair); Optional<Set<UnifyPair>> greaterFunN(UnifyPair pair);
/** Optional<Set<UnifyPair>> smallerFunN(UnifyPair pair);
* Checks whether the erase1-Rule applies to the pair.
* @return True if the pair is erasable, false otherwise. /**
*/ * Checks whether the erase1-Rule applies to the pair.
public boolean erase1(UnifyPair pair, IFiniteClosure fc); *
* @return True if the pair is erasable, false otherwise.
/** */
* Checks whether the erase2-Rule applies to the pair. boolean erase1(UnifyPair pair, IFiniteClosure fc);
* @return True if the pair is erasable, false otherwise.
*/ /**
public boolean erase2(UnifyPair pair, IFiniteClosure fc); * Checks whether the erase2-Rule applies to the pair.
*
/** * @return True if the pair is erasable, false otherwise.
* Checks whether the erase3-Rule applies to the pair. */
* @return True if the pair is erasable, false otherwise. boolean erase2(UnifyPair pair, IFiniteClosure fc);
*/
public boolean erase3(UnifyPair pair); /**
* Checks whether the erase3-Rule applies to the pair.
public Optional<UnifyPair> swap(UnifyPair pair); *
* @return True if the pair is erasable, false otherwise.
public Optional<UnifyPair> adapt(UnifyPair pair, IFiniteClosure fc); */
public Optional<UnifyPair> adaptExt(UnifyPair pair, IFiniteClosure fc); boolean erase3(UnifyPair pair);
public Optional<UnifyPair> adaptSup(UnifyPair pair, IFiniteClosure fc);
Optional<UnifyPair> swap(UnifyPair pair);
/**
* Applies the subst-Rule to a set of pairs (usually Eq'). Optional<UnifyPair> adapt(UnifyPair pair, IFiniteClosure fc);
* @param pairs The set of pairs where the subst rule should apply.
* @return An optional of the modified set, if there were any substitutions. An empty optional if there were no substitutions. Optional<UnifyPair> adaptExt(UnifyPair pair, IFiniteClosure fc);
*/
public Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs, List<Set<Constraint<UnifyPair>>> oderConstraints); Optional<UnifyPair> adaptSup(UnifyPair pair, IFiniteClosure fc);
/** /**
* Applies the subst-Rule to a set of pairs (usually Eq'). * Applies the subst-Rule to a set of pairs (usually Eq').
* @param pairs The set of pairs where the subst rule should apply. *
* @return An optional of the modified set, if there were any substitutions. An empty optional if there were no substitutions. * @param pairs The set of pairs where the subst rule should apply.
*/ * @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); */
} Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs, List<Set<Constraint<UnifyPair>>> oderConstraints);
/**
* Applies the subst-Rule to a set of pairs (usually Eq').
*
* @param pairs The set of pairs where the subst rule should apply.
* @return An optional of the modified set, if there were any substitutions. An empty optional if there were no substitutions.
*/
Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs);
}

View File

@@ -5,12 +5,14 @@ import java.util.Set;
/** /**
* Contains operations on sets. * Contains operations on sets.
*
* @author Florian Steurer * @author Florian Steurer
*/ */
public interface ISetOperations { public interface ISetOperations {
/** /**
* Calculates the cartesian product of the sets. * Calculates the cartesian product of the sets.
* @return The cartesian product *
*/ * @return The cartesian product
<B> Set<List<B>> cartesianProduct(List<? extends Set<? extends B>> sets); */
<B> Set<List<B>> cartesianProduct(List<? extends Set<? extends B>> sets);
} }

View File

@@ -10,26 +10,29 @@ import java.util.stream.Collectors;
/** /**
* Standard unification algorithm (e.g. Robinson, Paterson-Wegman, Martelli-Montanari) * Standard unification algorithm (e.g. Robinson, Paterson-Wegman, Martelli-Montanari)
*
* @author Florian Steurer * @author Florian Steurer
*/ */
public interface IUnify { public interface IUnify {
/**
* Finds the most general unifier sigma of the set {t1 =. t1',...,tn =. tn'} so that
* sigma(t1) = sigma(t1') , ... sigma(tn) = sigma(tn').
* @param terms The set of terms to be unified
* @return An optional of the most general unifier if it exists or an empty optional if there is no unifier.
*/
public Optional<Unifier> unify(Set<UnifyType> terms);
/**
* Finds the most general unifier sigma of the set {t1 =. t1',...,tn =. tn'} so that
* sigma(t1) = sigma(t1') , ... sigma(tn) = sigma(tn').
* @param terms The set of terms to be unified
* @return An optional of the most general unifier if it exists or an empty optional if there is no unifier.
*/
default public Optional<Unifier> unify(UnifyType... terms) {
return unify(Arrays.stream(terms).collect(Collectors.toSet()));
}
} /**
* Finds the most general unifier sigma of the set {t1 =. t1',...,tn =. tn'} so that
* sigma(t1) = sigma(t1') , ... sigma(tn) = sigma(tn').
*
* @param terms The set of terms to be unified
* @return An optional of the most general unifier if it exists or an empty optional if there is no unifier.
*/
Optional<Unifier> unify(Set<UnifyType> terms);
/**
* Finds the most general unifier sigma of the set {t1 =. t1',...,tn =. tn'} so that
* sigma(t1) = sigma(t1') , ... sigma(tn) = sigma(tn').
*
* @param terms The set of terms to be unified
* @return An optional of the most general unifier if it exists or an empty optional if there is no unifier.
*/
default Optional<Unifier> unify(UnifyType... terms) {
return unify(Arrays.stream(terms).collect(Collectors.toSet()));
}
}

View File

@@ -4,14 +4,14 @@ import de.dhbwstuttgart.typeinference.unify.model.*;
public interface UnifyTypeVisitor<T> { public interface UnifyTypeVisitor<T> {
public ReferenceType visit(ReferenceType refty, T ht); ReferenceType visit(ReferenceType refty, T ht);
public PlaceholderType visit(PlaceholderType phty, T ht);
public FunNType visit(FunNType funnty, T ht);
public SuperType visit(SuperType suty, T ht);
public ExtendsType visit(ExtendsType extty, T ht);
} PlaceholderType visit(PlaceholderType phty, T ht);
FunNType visit(FunNType funnty, T ht);
SuperType visit(SuperType suty, T ht);
ExtendsType visit(ExtendsType extty, T ht);
}

View File

@@ -6,88 +6,86 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
import java.util.Set; import java.util.Set;
/** /**
* An extends wildcard type "? extends T". * An extends wildcard type "? extends T".
*/ */
public final class ExtendsType extends WildcardType { public final class ExtendsType extends WildcardType {
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
/**
* Creates a new extends wildcard type.
* @param extendedType The extended type e.g. Integer in "? extends Integer"
*/
public ExtendsType(UnifyType extendedType) {
super("? extends " + extendedType.getName(), extendedType);
if (extendedType instanceof ExtendsType) {
System.out.print("");
}
}
/** /**
* The extended type e.g. Integer in "? extends Integer" * Creates a new extends wildcard type.
*/ *
public UnifyType getExtendedType() { * @param extendedType The extended type e.g. Integer in "? extends Integer"
return wildcardedType; */
} public ExtendsType(UnifyType extendedType) {
super("? extends " + extendedType.getName(), extendedType);
/** if (extendedType instanceof ExtendsType) {
* Sets the type parameters of the wildcarded type and returns a new extendstype that extends that type. System.out.print("");
*/ }
@Override }
public UnifyType setTypeParams(TypeParams newTp) {
UnifyType newType = wildcardedType.setTypeParams(newTp);
if(newType == wildcardedType)
return this; // Reduced the amount of objects created
return new ExtendsType(wildcardedType.setTypeParams(newTp));
}
@Override public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
Set<UnifyType> smArg(IFiniteClosure fc, Set<UnifyType> fBounded) { return visitor.visit(this, ht);
return fc.smArg(this, fBounded); }
}
@Override /**
Set<UnifyType> grArg(IFiniteClosure fc, Set<UnifyType> fBounded) { * The extended type e.g. Integer in "? extends Integer"
return fc.grArg(this, fBounded); */
} public UnifyType getExtendedType() {
return wildcardedType;
}
@Override /**
UnifyType apply(Unifier unif) { * Sets the type parameters of the wildcarded type and returns a new extendstype that extends that type.
UnifyType newType = wildcardedType.apply(unif); */
if(newType.hashCode() == wildcardedType.hashCode() && newType.equals(wildcardedType)) @Override
return this; // Reduced the amount of objects created public UnifyType setTypeParams(TypeParams newTp) {
return new ExtendsType(newType); UnifyType newType = wildcardedType.setTypeParams(newTp);
} if (newType == wildcardedType)
return this; // Reduced the amount of objects created
@Override return new ExtendsType(wildcardedType.setTypeParams(newTp));
public int hashCode() { }
/*
* It is important that the prime that is added is different to the prime added in hashCode() of SuperType.
* Otherwise ? extends T and ? super T have the same hashCode() for every Type T.
*/
return wildcardedType.hashCode() + 229;
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof ExtendsType))
return false;
if(obj.hashCode() != this.hashCode())
return false;
ExtendsType other = (ExtendsType) obj;
return other.getWildcardedType().equals(wildcardedType);
}
@Override
public String toString() {
return "? extends " + wildcardedType;
}
@Override
} Set<UnifyType> smArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.smArg(this, fBounded);
}
@Override
Set<UnifyType> grArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.grArg(this, fBounded);
}
@Override
UnifyType apply(Unifier unifier) {
UnifyType newType = wildcardedType.apply(unifier);
if (newType.hashCode() == wildcardedType.hashCode() && newType.equals(wildcardedType))
return this; // Reduced the amount of objects created
return new ExtendsType(newType);
}
@Override
public int hashCode() {
/*
* It is important that the prime that is added is different to the prime added in hashCode() of SuperType.
* Otherwise ? extends T and ? super T have the same hashCode() for every Type T.
*/
return wildcardedType.hashCode() + 229;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ExtendsType other))
return false;
if (obj.hashCode() != this.hashCode())
return false;
return other.getWildcardedType().equals(wildcardedType);
}
@Override
public String toString() {
return "? extends " + wildcardedType;
}
}

View File

@@ -5,98 +5,99 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import java.util.Set; import java.util.Set;
/** /**
* A real function type in java. * A real function type in java.
*
* @author Florian Steurer * @author Florian Steurer
*/ */
public class FunNType extends UnifyType { public class FunNType extends UnifyType {
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) { /**
return visitor.visit(this, ht); * Creates a FunN-Type with the specified TypeParameters.
} */
protected FunNType(TypeParams p) {
/** super("Fun" + (p.size() - 1) + "$$", p);
* Creates a FunN-Type with the specified TypeParameters. }
*/
protected FunNType(TypeParams p) {
super("Fun"+(p.size()-1)+"$$", p);
}
/** /**
* Creates a new FunNType. * Creates a new FunNType.
* @param tp The parameters of the type. *
* @return A FunNType. * @param tp The parameters of the type.
* @throws IllegalArgumentException is thrown when there are to few type parameters or there are wildcard-types. * @return A FunNType.
*/ * @throws IllegalArgumentException is thrown when there are to few type parameters or there are wildcard-types.
public static FunNType getFunNType(TypeParams tp) throws IllegalArgumentException { */
if(tp.size() == 0) public static FunNType getFunNType(TypeParams tp) throws IllegalArgumentException {
throw new IllegalArgumentException("FunNTypes need at least one type parameter"); if (tp.size() == 0)
for(UnifyType t : tp) throw new IllegalArgumentException("FunNTypes need at least one type parameter");
if(t instanceof WildcardType) for (UnifyType t : tp)
throw new IllegalArgumentException("Invalid TypeParams for a FunNType: " + tp); if (t instanceof WildcardType)
return new FunNType(tp); throw new IllegalArgumentException("Invalid TypeParams for a FunNType: " + tp);
} return new FunNType(tp);
}
/**
* Returns the degree of the function type, e.g. 2 for FunN<Integer, Integer, Integer>.
*/
public int getN() {
return typeParams.size()-1;
}
@Override
public UnifyType setTypeParams(TypeParams newTp) {
if(newTp.hashCode() == typeParams.hashCode() && newTp.equals(typeParams))
return this;
return getFunNType(newTp);
}
@Override
Set<UnifyType> smArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.smArg(this, fBounded);
}
@Override public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
Set<UnifyType> grArg(IFiniteClosure fc, Set<UnifyType> fBounded) { return visitor.visit(this, ht);
return fc.grArg(this, fBounded); }
}
@Override
UnifyType apply(Unifier unif) {
// TODO this bypasses the validation of the type parameters.
// Wildcard types can be unified into FunNTypes.
TypeParams newParams = typeParams.apply(unif);
if(newParams.hashCode() == typeParams.hashCode() && newParams.equals(typeParams))
return this;
return new FunNType(newParams);
}
@Override /**
public Boolean wrongWildcard() { * Returns the degree of the function type, e.g. 2 for FunN<Integer, Integer, Integer>.
return (new ArrayList<UnifyType>(Arrays.asList(getTypeParams() */
.get())).stream().filter(x -> (x instanceof WildcardType)).findFirst().isPresent()); public int getN() {
} return typeParams.size() - 1;
}
@Override
public int hashCode() { @Override
return 181 + typeParams.hashCode(); public UnifyType setTypeParams(TypeParams newTp) {
} if (newTp.hashCode() == typeParams.hashCode() && newTp.equals(typeParams))
return this;
return getFunNType(newTp);
@Override }
public boolean equals(Object obj) {
if(!(obj instanceof FunNType)) @Override
return false; Set<UnifyType> smArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.smArg(this, fBounded);
if(obj.hashCode() != this.hashCode()) }
return false;
@Override
FunNType other = (FunNType) obj; Set<UnifyType> grArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.grArg(this, fBounded);
}
@Override
UnifyType apply(Unifier unifier) {
// TODO this bypasses the validation of the type parameters.
// Wildcard types can be unified into FunNTypes.
TypeParams newParams = typeParams.apply(unifier);
if (newParams.hashCode() == typeParams.hashCode() && newParams.equals(typeParams))
return this;
return new FunNType(newParams);
}
@Override
public Boolean wrongWildcard() {
List<UnifyType> typeParamList = new ArrayList<>(Arrays.asList(getTypeParams().get()));
return typeParamList.stream().anyMatch(x -> (x instanceof WildcardType));
}
@Override
public int hashCode() {
return 181 + typeParams.hashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof FunNType other))
return false;
if (obj.hashCode() != this.hashCode())
return false;
return other.getTypeParams().equals(typeParams);
}
return other.getTypeParams().equals(typeParams);
}
} }

View File

@@ -6,113 +6,114 @@ import java.util.stream.Collectors;
/** /**
* A node of a directed graph. * A node of a directed graph.
* @author Florian Steurer
* *
* @param <T> The type of the content of the node. * @param <T> The type of the content of the node.
* @author Florian Steurer
*/ */
class Node<T> { class Node<T> {
/** /**
* The content of the node. * The content of the node.
*/ */
private T content; private final T content;
/** /**
* The set of predecessors * The set of predecessors
*/ */
private HashSet<Node<T>> predecessors = new HashSet<>(); private final HashSet<Node<T>> predecessors = new HashSet<>();
/** /**
* The set of descendants * The set of descendants
*/ */
private HashSet<Node<T>> descendants = new HashSet<>(); private final HashSet<Node<T>> descendants = new HashSet<>();
/** /**
* Creates a node containing the specified content. * Creates a node containing the specified content.
*/ */
public Node(T content) { public Node(T content) {
this.content = content; this.content = content;
} }
/** /**
* Adds a directed edge from this node to the descendant (this -> descendant) * Adds a directed edge from this node to the descendant (this -> descendant)
*/ */
public void addDescendant(Node<T> descendant) { public void addDescendant(Node<T> descendant) {
if(descendants.contains(descendant)) if (descendants.contains(descendant))
return; return;
descendants.add(descendant); descendants.add(descendant);
descendant.addPredecessor(this); descendant.addPredecessor(this);
} }
/** /**
* Adds some directed edges from this node to the descendant (this -> descendant) * Adds some directed edges from this node to the descendant (this -> descendant)
*/ */
public void addAllDescendant(Set<Node<T>> allDescendants) { public void addAllDescendant(Set<Node<T>> allDescendants) {
for(Node<T> descendant: allDescendants) { for (Node<T> descendant : allDescendants) {
addDescendant(descendant); addDescendant(descendant);
} }
} }
/** /**
* Adds a directed edge from the predecessor to this node (predecessor -> this) * Adds a directed edge from the predecessor to this node (predecessor -> this)
*/ */
public void addPredecessor(Node<T> predecessor) { public void addPredecessor(Node<T> predecessor) {
if(predecessors.contains(predecessor)) if (predecessors.contains(predecessor))
return; return;
predecessors.add(predecessor); predecessors.add(predecessor);
predecessor.addDescendant(this); predecessor.addDescendant(this);
} }
/** /**
* Adds some directed edges from the predecessor to this node (predecessor -> this) * Adds some directed edges from the predecessor to this node (predecessor -> this)
*/ */
public void addAllPredecessor(Set<Node<T>> allPredecessors) { public void addAllPredecessor(Set<Node<T>> allPredecessors) {
for(Node<T> predecessor: allPredecessors) { for (Node<T> predecessor : allPredecessors) {
addPredecessor(predecessor); addPredecessor(predecessor);
} }
} }
/** /**
* The content of this node. * @return The content of this node.
*/ */
public T getContent() { public T getContent() {
return content; return content;
} }
/** /**
* Returns all predecessors (nodes that have a directed edge to this node) * @return All predecessors (nodes that have a directed edge to this node)
*/ */
public Set<Node<T>> getPredecessors() { public Set<Node<T>> getPredecessors() {
return predecessors; return predecessors;
} }
/** /**
* Returns all descendants. All nodes M, where there is a edge from this node to the node M. * @return All nodes M, where there is an edge from this node to the node M.
* @return */
*/ public Set<Node<T>> getDescendants() {
public Set<Node<T>> getDescendants() { return descendants;
return descendants; }
}
/**
/** * @return The content of all descendants.
* Retrieves the content of all descendants. */
*/ public Set<T> getContentOfDescendants() {
public Set<T> getContentOfDescendants() { return descendants.stream().map(Node::getContent).collect(Collectors.toSet());
return descendants.stream().map(x -> x.getContent()).collect(Collectors.toSet()); }
}
/**
/** * @return The content of all predecessors.
* Retrieves the content of all predecessors. */
*/ public Set<T> getContentOfPredecessors() {
public Set<T> getContentOfPredecessors() { return predecessors.stream().map(Node::getContent).collect(Collectors.toSet());
return predecessors.stream().map(x -> x.getContent()).collect(Collectors.toSet()); }
}
@Override
@Override public String toString() {
public String toString() { return
return "Elem: Node(" + content.toString() + ")\nPrec: " + getContentOfPredecessors().toString() "Elem: Node(" + content.toString() + ")\n" +
+ "\nDesc: " + getContentOfDescendants().toString() + "\n\n"; "Prec: " + getContentOfPredecessors().toString() + "\n" +
} "Desc: " + getContentOfDescendants().toString() + "\n\n";
}
} }

View File

@@ -1,85 +0,0 @@
package de.dhbwstuttgart.typeinference.unify.model;
import java.util.*;
public abstract class OrderingExtend<T> extends com.google.common.collect.Ordering<T> {
public List<T> maxElements(Iterable<T> iterable) {
ArrayList<T> ret = new ArrayList<>();
while (iterable.iterator().hasNext()) {
Set<T> believe = new HashSet<>();
T max = max(iterable);
ret.add(max);
Iterator<T> it = iterable.iterator();
while (it.hasNext()) {
T elem = it.next();
if (!(compare(max, elem) == 1) && !max.equals(elem)) {
believe.add(elem);
}
}
iterable = believe;
}
return ret;
}
public List<T> minElements(Iterable<T> iterable) {
ArrayList<T> ret = new ArrayList<>();
while (iterable.iterator().hasNext()) {
Set<T> believe = new HashSet<>();
T min = min(iterable);
ret.add(min);
Iterator<T> it = iterable.iterator();
while (it.hasNext()) {
T elem = it.next();
if (!(compare(min, elem) == -1) && !min.equals(elem)) {
believe.add(elem);
}
}
iterable = believe;
}
return ret;
}
public List<T> smallerEqThan(T elem, Iterable<T> iterable) {
List<T> ret = smallerThan(elem, iterable);
ret.add(elem);
return ret;
}
public List<T> smallerThan(T elem, Iterable<T> iterable) {
ArrayList<T> ret = new ArrayList<>();
Iterator<T> it = iterable.iterator();
while (it.hasNext()) {
T itElem = it.next();
if (!itElem.equals(elem) && compare(elem, itElem) == 1) {
ret.add(itElem);
}
}
return ret;
}
public List<T> greaterEqThan(T elem, Iterable<T> iterable) {
List<T> ret = greaterThan(elem, iterable);
ret.add(elem);
return ret;
}
public List<T> greaterThan(T elem, Iterable<T> iterable) {
ArrayList<T> ret = new ArrayList<>();
Iterator<T> it = iterable.iterator();
while (it.hasNext()) {
T itElem = it.next();
if (!itElem.equals(elem) && (compare(elem, itElem) == -1)) {
ret.add(itElem);
}
}
return ret;
}
}

View File

@@ -1,446 +0,0 @@
package de.dhbwstuttgart.typeinference.unify.model;
import de.dhbwstuttgart.typeinference.unify.Match;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.util.Pair;
import java.io.IOException;
import java.util.*;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class OrderingUnifyPair extends OrderingExtend<Set<UnifyPair>> {
protected IFiniteClosure fc;
public OrderingUnifyPair(IFiniteClosure fc) {
this.fc = fc;
}
/*
* vergleicht Paare (a =. Theta) und (a =. Theta')
* in dem compare(Theta, Theta') aufgerufen wird.
*/
public int compareEq (UnifyPair left, UnifyPair right) {
try {
//if (left.getRhsType() instanceof WildcardType || right.getRhsType() instanceof WildcardType) {//PL 2019-01-12 ausgetauscht
if (((PlaceholderType)left.getLhsType()).isInnerType() && ((PlaceholderType)right.getLhsType()).isInnerType()) {
return fc.compare(left.getRhsType(), right.getRhsType(), PairOperator.SMALLERDOTWC);
}
else {
return fc.compare(left.getRhsType(), right.getRhsType(), PairOperator.SMALLERDOT);
}}
catch (ClassCastException e) {
try {
((FiniteClosure)fc).logFile.write("ClassCastException: " + left.toString() + " " + left.getGroundBasePair() + "\n\n");
((FiniteClosure)fc).logFile.flush();
}
catch (IOException ie) {
}
return -99;
}
}
/*
public int compareEq (UnifyPair left, UnifyPair right) {
if (left == null || right == null)
System.out.println("Fehler");
if (left.getLhsType() instanceof PlaceholderType) {
return fc.compare(left.getRhsType(), right.getRhsType(), left.getPairOp());
}
else {
return fc.compare(left.getLhsType(), right.getLhsType(), left.getPairOp());
}
}
*/
public Pair<Integer,Set<UnifyPair>> compare (UnifyType left, UnifyType right) {
UnifyPair up;
if (left instanceof WildcardType || right instanceof WildcardType) {
up = new UnifyPair(left, right, PairOperator.SMALLERDOTWC);
if (((left instanceof ExtendsType)
&& (((ExtendsType)left).getExtendedType().getName().equals("java.util.Vector"))
&& (((ReferenceType)((ExtendsType)left).getExtendedType()).getTypeParams().iterator().next() instanceof ExtendsType)) ||
((right instanceof ExtendsType)
&& (((ExtendsType)right).getExtendedType().getName().equals("java.util.Vector"))
&& (((ReferenceType)((ExtendsType)right).getExtendedType()).getTypeParams().iterator().next() instanceof ExtendsType)))
{
System.out.println("");
}
if (((right instanceof SuperType) && (((SuperType)right).getSuperedType().getName().equals("java.lang.Object")))
||((left instanceof SuperType) && (((SuperType)left).getSuperedType().getName().equals("java.lang.Object"))))
{
System.out.println("");
}
}
else {
up = new UnifyPair(left, right, PairOperator.SMALLERDOT);
}
TypeUnifyTask unifyTask = new TypeUnifyTask();
HashSet<UnifyPair> hs = new HashSet<>();
hs.add(up);
Set<UnifyPair> smallerRes = unifyTask.applyTypeUnificationRules(hs, fc);
long smallerLen = smallerRes.stream().filter(x -> !(x.getLhsType() instanceof PlaceholderType && x.getRhsType() instanceof PlaceholderType)).count();
if (smallerLen == 0) return new Pair<>(-1, smallerRes);
else {
if (left instanceof WildcardType || right instanceof WildcardType) {
up = new UnifyPair(right, left, PairOperator.SMALLERDOTWC);
if (((left instanceof ExtendsType)
&& (((ExtendsType)left).getExtendedType().getName().equals("java.util.Vector"))
&& (((ReferenceType)((ExtendsType)left).getExtendedType()).getTypeParams().iterator().next() instanceof ExtendsType)) ||
((right instanceof ExtendsType)
&& (((ExtendsType)right).getExtendedType().getName().equals("java.util.Vector"))
&& (((ReferenceType)((ExtendsType)right).getExtendedType()).getTypeParams().iterator().next() instanceof ExtendsType)))
{
System.out.println("");
}
if (right instanceof SuperType)
{
System.out.println("");
}
}
else {
up = new UnifyPair(right, left, PairOperator.SMALLERDOT);
}
//TypeUnifyTask unifyTask = new TypeUnifyTask();
hs = new HashSet<>();
hs.add(up);
Set<UnifyPair> greaterRes = unifyTask.applyTypeUnificationRules(hs, fc);
long greaterLen = greaterRes.stream().filter(x -> !(x.getLhsType() instanceof PlaceholderType && x.getRhsType() instanceof PlaceholderType)).count();
if (greaterLen == 0) return new Pair<>(1, greaterRes);
else return new Pair<>(0, new HashSet<>());
}
}
/* TODO muss noch verifiziert werden PL 2018-03-21
* (non-Javadoc)
* fuehrt zu Fehlern bei Arrays.sort (contract nicht erfuellt)
* @see com.google.common.collect.Ordering#compare(java.lang.Object, java.lang.Object)
*/
public int compare (Set<UnifyPair> leftpara, Set<UnifyPair> rightpara) {
Set<UnifyPair> left = new HashSet<>(leftpara);
Set<UnifyPair> right = new HashSet<>(rightpara);
/*
//pairop = PairOperator.SMALLERDOTWC;
List<UnifyType> al = new ArrayList<>();
PlaceholderType xx = PlaceholderType.freshPlaceholder();
al.add(xx);
UnifyType t1 = new ExtendsType(new ReferenceType("Vector", new TypeParams(al)));
//PlaceholderType yy =new PlaceholderType("yy");
List<UnifyType> alr = new ArrayList<>();
UnifyType exx = new ExtendsType(xx);
alr.add(exx);
UnifyType t2 = new ExtendsType(new ReferenceType("Vector", new TypeParams(alr)));
PlaceholderType a = PlaceholderType.freshPlaceholder();
a.setInnerType(true);
UnifyPair p1 = new UnifyPair(a, t1, PairOperator.SMALLERDOTWC);
PlaceholderType b = PlaceholderType.freshPlaceholder();
b.setInnerType(true);
UnifyPair p2 = new UnifyPair(b, t2, PairOperator.SMALLERDOTWC);
List<UnifyType> al3 = new ArrayList<>();
al3.add(a);
List<UnifyType> al4 = new ArrayList<>();
al4.add(b);
UnifyPair p3 = new UnifyPair(new PlaceholderType("c"), new ReferenceType("Vector", new TypeParams(al3)), PairOperator.EQUALSDOT);
UnifyPair p4 = new UnifyPair(new PlaceholderType("c"), new ReferenceType("Vector", new TypeParams(al4)), PairOperator.EQUALSDOT);
right = new HashSet<>();
right.add(p1);
right.add(p3);
left = new HashSet<>();
left.add(p2);
left.add(p4);
*/
Set<UnifyPair> lefteq = left.stream()
.filter(x -> (x.getLhsType() instanceof PlaceholderType && x.getPairOp() == PairOperator.EQUALSDOT))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> righteq = right.stream()
.filter(x -> (x.getLhsType() instanceof PlaceholderType && x.getPairOp() == PairOperator.EQUALSDOT))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> leftle = left.stream()
.filter(x -> ((x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)
&& x.getPairOp() == PairOperator.SMALLERDOT))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> rightle = right.stream()
.filter(x -> ((x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)
&& x.getPairOp() == PairOperator.SMALLERDOT))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> leftlewc = left.stream()
.filter(x -> ((x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)
&& x.getPairOp() == PairOperator.SMALLERDOTWC))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> rightlewc = right.stream()
.filter(x -> ((x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)
&& x.getPairOp() == PairOperator.SMALLERDOTWC))
.collect(Collectors.toCollection(HashSet::new));
//System.out.println(left.toString());
//Fall 2
//if (lefteq.iterator().next().getLhsType().getName().equals("AJO")) {
// System.out.print("");
//}
//ODER-CONSTRAINT
Set<UnifyPair> leftBase = left.stream().map(x -> x.getGroundBasePair()).collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> rightBase = right.stream().map(x -> x.getGroundBasePair()).collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> lefteqOder = left.stream()
.filter(x -> { UnifyPair y = x.getGroundBasePair();
/*try {
((FiniteClosure)fc).logFile.write("leftBase: " + leftBase.toString() +"\n");
((FiniteClosure)fc).logFile.write("rightBase: " + rightBase.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("left: " + left.toString() +"\n");
((FiniteClosure)fc).logFile.write("right: " + right.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("y: " + y.toString() +"\n");
((FiniteClosure)fc).logFile.write("y.getLhsType() : " + y.getLhsType() .toString() +"\n\n");
((FiniteClosure)fc).logFile.write("y.getRhsType(): " + y.getRhsType().toString() +"\n");
((FiniteClosure)fc).logFile.write("x.getPairOp(): " + x.getPairOp().toString() +"\n\n");
}
catch (IOException ie) {
} */
return (y.getLhsType() instanceof PlaceholderType &&
!(y.getRhsType() instanceof PlaceholderType) &&
x.getPairOp() == PairOperator.EQUALSDOT);})
.collect(Collectors.toCollection(HashSet::new));
left.removeAll(lefteqOder);
Set<UnifyPair> righteqOder = right.stream()
.filter(x -> { UnifyPair y = x.getGroundBasePair();
return (y.getLhsType() instanceof PlaceholderType &&
!(y.getRhsType() instanceof PlaceholderType) &&
x.getPairOp() == PairOperator.EQUALSDOT);})
.collect(Collectors.toCollection(HashSet::new));
right.removeAll(righteqOder);
Set<UnifyPair> lefteqRet = left.stream()
.filter(x -> { UnifyPair y = x.getGroundBasePair();
return (y.getRhsType() instanceof PlaceholderType &&
((PlaceholderType)y.getRhsType()).getOrCons() == (byte)-1);})
.collect(Collectors.toCollection(HashSet::new));
left.removeAll(lefteqRet);
Set<UnifyPair> righteqRet = right.stream()
.filter(x -> { UnifyPair y = x.getGroundBasePair();
return (y.getRhsType() instanceof PlaceholderType &&
((PlaceholderType)y.getRhsType()).getOrCons() == (byte)-1);})
.collect(Collectors.toCollection(HashSet::new));
right.removeAll(righteqRet);
Set<UnifyPair> leftleOder = left.stream()
.filter(x -> (x.getPairOp() == PairOperator.SMALLERDOT))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> rightleOder = right.stream()
.filter(x -> (x.getPairOp() == PairOperator.SMALLERDOT))
.collect(Collectors.toCollection(HashSet::new));
/*
synchronized(this) {
try {
((FiniteClosure)fc).logFile.write("leftBase: " + leftBase.toString() +"\n");
((FiniteClosure)fc).logFile.write("rightBase: " + rightBase.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("left: " + left.toString() +"\n");
((FiniteClosure)fc).logFile.write("right: " + right.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("lefteqOder: " + lefteqOder.toString() +"\n");
((FiniteClosure)fc).logFile.write("righteqOder: " + righteqOder.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("lefteqRet: " + lefteqRet.toString() +"\n");
((FiniteClosure)fc).logFile.write("righteqRet: " + righteqRet.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("leftleOder: " + leftleOder.toString() +"\n");
((FiniteClosure)fc).logFile.write("rightleOder: " + rightleOder.toString() +"\n\n");
((FiniteClosure)fc).logFile.flush();
}
catch (IOException ie) {
}
}
*/
Integer compareEq;
if (lefteqOder.size() == 1 && righteqOder.size() == 1 && lefteqRet.size() == 1 && righteqRet.size() == 1) {
Match m = new Match();
if ((compareEq = compareEq(lefteqOder.iterator().next().getGroundBasePair(), righteqOder.iterator().next().getGroundBasePair())) == -1) {
ArrayList<UnifyPair> matchList =
rightleOder.stream().map(x -> {
UnifyPair leftElem = leftleOder.stream()
.filter(y -> y.getGroundBasePair().getLhsType().equals(x.getGroundBasePair().getLhsType()))
.findAny().get();
return new UnifyPair(x.getRhsType(), leftElem.getRhsType(), PairOperator.EQUALSDOT);})
.collect(Collectors.toCollection(ArrayList::new));
if (m.match(matchList).isPresent()) {
//try { ((FiniteClosure)fc).logFile.write("result1: -1 \n\n"); } catch (IOException ie) {}
return -1;
}
else {
//try { ((FiniteClosure)fc).logFile.write("result1: 0 \n\n"); } catch (IOException ie) {}
return 0;
}
} else if (compareEq == 1) {
ArrayList<UnifyPair> matchList =
leftleOder.stream().map(x -> {
UnifyPair rightElem = rightleOder.stream()
.filter(y ->
y.getGroundBasePair().getLhsType().equals(x.getGroundBasePair().getLhsType()))
.findAny().get();
return new UnifyPair(x.getRhsType(), rightElem.getRhsType(), PairOperator.EQUALSDOT);})
.collect(Collectors.toCollection(ArrayList::new));
if (m.match(matchList).isPresent()) {
//try { ((FiniteClosure)fc).logFile.write("result2: 1 \n\n"); } catch (IOException ie) {}
return 1;
}
else {
//try { ((FiniteClosure)fc).logFile.write("result2: 0 \n\n"); } catch (IOException ie) {}
return 0;
}
} else {
/*
synchronized(this) {
try {
((FiniteClosure)fc).logFile.write("leftBase: " + leftBase.toString() +"\n");
((FiniteClosure)fc).logFile.write("rightBase: " + rightBase.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("left: " + left.toString() +"\n");
((FiniteClosure)fc).logFile.write("right: " + right.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("lefteqOder: " + lefteqOder.toString() +"\n");
((FiniteClosure)fc).logFile.write("righteqOder: " + righteqOder.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("lefteqRet: " + lefteqRet.toString() +"\n");
((FiniteClosure)fc).logFile.write("righteqRet: " + righteqRet.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("leftleOder: " + leftleOder.toString() +"\n");
((FiniteClosure)fc).logFile.write("rightleOder: " + rightleOder.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("result3: 0 \n\n");
((FiniteClosure)fc).logFile.flush();
}
catch (IOException ie) {
}
}
*/
return 0;
}
}
if (lefteq.size() == 1 && lefteq.iterator().next().getRhsType() instanceof ExtendsType && leftle.size() == 1 && righteq.size() == 0 && rightle.size() == 1) {
return 1;
}
//Fall 2
if (lefteq.size() == 0 && leftle.size() == 1 && righteq.size() == 1 && righteq.iterator().next().getRhsType() instanceof ExtendsType && rightle.size() == 1) {
return -1;
}
//Fall 3
if (lefteq.size() == 1 && lefteq.iterator().next().getRhsType() instanceof SuperType && leftle.size() == 1 && righteq.size() == 0 && rightle.size() == 1) {
return -1;
}
//Fall 3
if (lefteq.size() == 0 && leftle.size() == 1 && righteq.size() == 1 && righteq.iterator().next().getRhsType() instanceof SuperType && rightle.size() == 1) {
return 1;
}
//Fall 5
if (lefteq.size() == 1 && leftle.size() == 0 && righteq.size() == 1 && rightle.size() == 1) {
return -1;
}
//Fall 5
if (lefteq.size() == 1 && leftle.size() == 1 && righteq.size() == 1 && rightle.size() == 0) {
return 1;
}
//Fall 5
if (lefteq.size() == 1 && leftle.size() == 1 && righteq.size() == 1 && rightle.size() == 1) {
return 0;
}
// Nur Paare a =. Theta
if (leftle.size() == 0 && rightle.size() == 0 && leftlewc.size() == 0 && rightlewc.size() ==0) {
Stream<UnifyPair> lseq = lefteq.stream(); //left.filter(x -> (x.getLhsType() instanceof PlaceholderType && x.getPairOp() == PairOperator.EQUALSDOT));
Stream<UnifyPair> rseq = righteq.stream(); //right.filter(x -> (x.getLhsType() instanceof PlaceholderType && x.getPairOp() == PairOperator.EQUALSDOT));
BinaryOperator<HashMap<UnifyType,UnifyPair>> combiner = (x,y) -> { x.putAll(y); return x;};
HashMap<UnifyType,UnifyPair> hm = rseq.reduce(new HashMap<UnifyType,UnifyPair>(), (x, y)-> { x.put(y.getLhsType(),y); return x; }, combiner);
lseq = lseq.filter(x -> !(hm.get(x.getLhsType()) == null));//NOCHMALS UEBERPRUEFEN!!!!
lseq = lseq.filter(x -> !x.equals(hm.get(x.getLhsType()))); //Elemente die gleich sind muessen nicht verglichen werden
Optional<Integer> si = lseq.map(x -> compareEq(x, hm.get(x.getLhsType()))).reduce((x,y)-> { if (x == y) return x; else return 0; } );
if (!si.isPresent()) return 0;
else return si.get();
}
//Fall 1 und 4
if (lefteq.size() >= 1 && righteq.size() >= 1 && (leftlewc.size() > 0 || rightlewc.size() > 0)) {
if (lefteq.iterator().next().getLhsType().getName().equals("D"))
System.out.print("");
//Set<PlaceholderType> varsleft = lefteq.stream().map(x -> (PlaceholderType)x.getLhsType()).collect(Collectors.toCollection(HashSet::new));
//Set<PlaceholderType> varsright = righteq.stream().map(x -> (PlaceholderType)x.getLhsType()).collect(Collectors.toCollection(HashSet::new));
//filtern des Paares a = Theta, das durch a <. Thata' generiert wurde (nur im Fall 1 relevant) andere Substitutioen werden rausgefiltert
lefteq.removeIf(x -> (x.getBasePair()!=null) && !(x.getLhsType().getName().equals(x.getBasePair().getLhsType().getName())
||x.getLhsType().getName().equals(x.getBasePair().getRhsType().getName())));//removeIf(x -> !varsright.contains(x.getLhsType()));
righteq.removeIf(x -> (x.getBasePair()!=null) && !(x.getLhsType().getName().equals(x.getBasePair().getLhsType().getName())
||x.getLhsType().getName().equals(x.getBasePair().getRhsType().getName())));//.removeIf(x -> !varsleft.contains(x.getLhsType()));
UnifyPair lseq = lefteq.iterator().next();
UnifyPair rseq = righteq.iterator().next();
if (lseq.getRhsType().getName().equals("Object")) {
if (rseq.getRhsType().getName().equals("Object")) return 0;
else return 1;
}
else {
if (rseq.getRhsType().getName().equals("Object")) return -1;
}
if (leftlewc.size() == rightlewc.size()) {
//TODO: Hier wird bei Wildcards nicht das richtige compare aufgerufen PL 18-04-20
Pair<Integer, Set<UnifyPair>> int_Unifier = compare(lseq.getRhsType(), rseq.getRhsType());
Unifier uni = new Unifier();
int_Unifier.getValue().get().forEach(x -> uni.add((PlaceholderType) x.getLhsType(), x.getRhsType()));
if (!lseq.getRhsType().getName().equals(rseq.getRhsType().getName())
|| leftlewc.size() == 0 || rightlewc.size() == 0) return int_Unifier.getKey();
else {
Set <UnifyPair> lsleuni = leftlewc.stream().map(x -> uni.apply(x)).collect(Collectors.toCollection(HashSet::new));
Set <UnifyPair> rsleuni = rightlewc.stream().map(x -> uni.apply(x)).collect(Collectors.toCollection(HashSet::new));
BinaryOperator<HashMap<UnifyType,UnifyPair>> combiner = (x,y) -> { x.putAll(y); return x;};
HashMap<UnifyType,UnifyPair> hm;
Optional<Integer> si;
//1. Fall
if (leftlewc.iterator().next().getLhsType() instanceof PlaceholderType) {
hm = rsleuni.stream().reduce(new HashMap<UnifyType,UnifyPair>(), (x, y)-> { x.put(y.getLhsType(),y); return x; }, combiner);
Stream<UnifyPair> lslewcstr = lsleuni.stream().filter(x -> !(hm.get(x.getLhsType()) == null));
si = lslewcstr.map(x -> fc.compare(x.getRhsType(), hm.get(x.getLhsType()).getRhsType(), PairOperator.SMALLERDOTWC)).reduce((x,y)-> { if (x == y) return x; else return 0; } );
}
//4. Fall
else {
hm = rsleuni.stream().reduce(new HashMap<UnifyType,UnifyPair>(), (x, y)-> { x.put(y.getRhsType(),y); return x; }, combiner);
Stream<UnifyPair> lslewcstr = lsleuni.stream().filter(x -> !(hm.get(x.getRhsType()) == null));
si = lslewcstr.map(x -> fc.compare(x.getLhsType(), hm.get(x.getRhsType()).getLhsType(), PairOperator.SMALLERDOTWC)).reduce((x,y)-> { if (x == y) return x; else return 0; } );
}
if (!si.isPresent()) return 0;
else return si.get();
}
} else {
if (leftlewc.size() > 0) {
Set<UnifyPair> subst;
subst = leftlewc.stream().map(x -> {
if (x.getLhsType() instanceof PlaceholderType) {
return new UnifyPair(x.getLhsType(), x.getRhsType(), PairOperator.EQUALSDOT);
}
else {
return new UnifyPair(x.getRhsType(), x.getLhsType(), PairOperator.EQUALSDOT);
}}).collect(Collectors.toCollection(HashSet::new));
Unifier uni = new Unifier();
lseq = uni.apply(lseq);
}
else {
Set<UnifyPair> subst;
subst = rightlewc.stream().map(x -> {
if (x.getLhsType() instanceof PlaceholderType) {
return new UnifyPair(x.getLhsType(), x.getRhsType(), PairOperator.EQUALSDOT);
}
else {
return new UnifyPair(x.getRhsType(), x.getLhsType(), PairOperator.EQUALSDOT);
}}).collect(Collectors.toCollection(HashSet::new));
Unifier uni = new Unifier();
subst.stream().forEach(x -> uni.add((PlaceholderType) x.getLhsType(), x.getRhsType()));
rseq = uni.apply(rseq);
}
return compareEq(lseq, rseq);
}
}
return 0;
}
}

View File

@@ -2,48 +2,49 @@ package de.dhbwstuttgart.typeinference.unify.model;
/** /**
* Operators of pairs of the unification. * Operators of pairs of the unification.
*
* @author Florian Steurer * @author Florian Steurer
*/ */
public enum PairOperator { public enum PairOperator {
/** /**
* The smaller operator (T < P) is used to express a subtyping relation between * The smaller operator (T < P) is used to express a subtyping relation between
* T and P for example in the finite closure. It is necessarily true. * T and P for example in the finite closure. It is necessarily true.
*/ */
SMALLER, SMALLER,
/** /**
* The smallerdot operator (T <. P) is used to express a subtyping relation between * The smallerdot operator (T <. P) is used to express a subtyping relation between
* of T and P in a CONSTRAINT during the unification. It is not necessarily true. * of T and P in a CONSTRAINT during the unification. It is not necessarily true.
*/ */
SMALLERDOT, SMALLERDOT,
/** /**
* The smallernedot operator for arguments (T <!=. P) is the same as SMALLERDOT without * The smallernedot operator for arguments (T <!=. P) is the same as SMALLERDOT without
* T == P. It is used for operations + / - / * / < / > / ... with the Supertype Number * T == P. It is used for operations + / - / * / < / > / ... with the Supertype Number
*/ */
SMALLERNEQDOT, SMALLERNEQDOT,
/** /**
* The smallerdot operator for arguments (T <.? P) is used to express that * The smallerdot operator for arguments (T <.? P) is used to express that
* T is an element of smArg(P) (or P is an element of grArg(T)) in a CONSTRAINT * T is an element of smArg(P) (or P is an element of grArg(T)) in a CONSTRAINT
* during the unification. It is not necessarily true. * during the unification. It is not necessarily true.
*/ */
SMALLERDOTWC, SMALLERDOTWC,
/** /**
* The equalsdot operator (T =. P) is used to express that two types during the unification * The equalsdot operator (T =. P) is used to express that two types during the unification
* should be equal. It is not necessarily true. * should be equal. It is not necessarily true.
*/ */
EQUALSDOT; EQUALSDOT;
@Override @Override
public String toString() { public String toString() {
switch (this) { return switch (this) {
case SMALLER: return "<"; case SMALLER -> "<";
case SMALLERDOT: return "<."; case SMALLERDOT -> "<.";
case SMALLERNEQDOT: return "<!=."; case SMALLERNEQDOT -> "<!=.";
case SMALLERDOTWC: return "<.?"; case SMALLERDOTWC -> "<.?";
default: return "=."; // EQUALSDOT default -> "=."; // EQUALSDOT
} };
} }
} }

View File

@@ -10,43 +10,39 @@ import java.util.Set;
/** /**
* An unbounded placeholder type. * An unbounded placeholder type.
*
* @author Florian Steurer * @author Florian Steurer
*/ */
public final class PlaceholderType extends UnifyType{ public final class PlaceholderType extends UnifyType {
/** /**
* Static list containing the names of all existing placeholders. * Static list containing the names of all existing placeholders.
* Used for generating fresh placeholders. * Used for generating fresh placeholders.
*/ */
public static final ArrayList<String> EXISTING_PLACEHOLDERS = new ArrayList<String>(); public static final ArrayList<String> EXISTING_PLACEHOLDERS = new ArrayList<String>();
/** /**
* Prefix of auto-generated placeholder names. * Random number generator used to generate fresh placeholder name.
*/ */
protected static String nextName = "gen_"; private static final Random rnd = new Random(43558747548978L);
/** /**
* Random number generator used to generate fresh placeholder name. * True if this object was auto-generated, false if this object was user-generated.
*/ */
protected static Random rnd = new Random(43558747548978L); private final boolean IsGenerated;
/**
* True if this object was auto-generated, false if this object was user-generated. /**
*/ * Defines, if a WildcardType can be assigned to this PlaceholderType
private final boolean IsGenerated; */
private boolean canBeWildcard = true;
/** /**
* isWildcardable gibt an, ob ein Wildcardtyp dem PlaceholderType zugeordnet werden darf * Defines, if this type is used inside a type constructor
*/ */
private boolean wildcardable = true; private boolean innerType = false;
/** /**
* is innerType gibt an, ob der Type des PlaceholderType innerhalb eines Typkonstruktorsverwendet wird
*/
private boolean innerType = false;
/**
* variance shows the variance of the pair * variance shows the variance of the pair
* -1: contravariant * -1: contravariant
* 1 covariant * 1 covariant
@@ -54,153 +50,152 @@ public final class PlaceholderType extends UnifyType{
* PL 2018-03-21 * PL 2018-03-21
*/ */
private int variance = 0; private int variance = 0;
/* /*
* Fuer Oder-Constraints: * For Oder-Constraints:
* orCons = 1: Receiver * orCons = 1: Receiver
* orCons = 0: Argument oder kein Oder-Constraint * orCons = 0: Argument oder kein Oder-Constraint
* orCons = -1: RetType * orCons = -1: RetType
*/ */
private byte orCons = 0; private byte orCons = 0;
/**
* Creates a new placeholder type with the specified name.
*/
public PlaceholderType(String name) {
super(name, new TypeParams());
EXISTING_PLACEHOLDERS.add(name); // Add to list of existing placeholder names
IsGenerated = false; // This type is user generated
}
/**
* Creates a new placeholdertype
* @param isGenerated true if this placeholder is auto-generated, false if it is user-generated.
*/
public PlaceholderType(String name, boolean isGenerated) {
super(name, new TypeParams());
EXISTING_PLACEHOLDERS.add(name); // Add to list of existing placeholder names
IsGenerated = isGenerated;
}
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
/**
* Creates a fresh placeholder type with a name that does so far not exist.
* A user could later instantiate a type using the same name that is equivalent to this type.
* @return A fresh placeholder type.
*/
public synchronized static PlaceholderType freshPlaceholder() {
String name = nextName + (char) (rnd.nextInt(22) + 97); // Returns random char between 'a' and 'z'
// Add random chars while the name is in use.
while(EXISTING_PLACEHOLDERS.contains(name)) {
name += (char) (rnd.nextInt(22) + 97); // Returns random char between 'a' and 'z'
}
return new PlaceholderType(name, true);
}
/**
* True if this placeholder is auto-generated, false if it is user-generated.
*/
public boolean isGenerated() {
return IsGenerated;
}
public void setVariance(int v) { /**
variance = v; * Creates a new placeholder type with the specified name.
} */
public PlaceholderType(String name) {
public int getVariance() { super(name, new TypeParams());
return variance; EXISTING_PLACEHOLDERS.add(name); // Add to list of existing placeholder names
} IsGenerated = false; // This type is user generated
}
public void reversVariance() {
if (variance == 1) {
setVariance(-1);
} else {
if (variance == -1) {
setVariance(1);
}}
}
public void setOrCons(byte i) {
orCons = i;
}
public byte getOrCons() {
return orCons;
}
public Boolean isWildcardable() {
return wildcardable;
}
public void disableWildcardtable() {
wildcardable = false;
}
public void enableWildcardtable() {
wildcardable = true;
}
public void setWildcardtable(Boolean wildcardable) {
this.wildcardable = wildcardable;
}
public Boolean isInnerType() {
return innerType;
}
public void setInnerType(Boolean innerType) {
this.innerType = innerType;
}
@Override
Set<UnifyType> smArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.smArg(this, fBounded);
}
@Override /**
Set<UnifyType> grArg(IFiniteClosure fc, Set<UnifyType> fBounded) { * Creates a new placeholdertype
return fc.grArg(this, fBounded); *
} * @param isGenerated true if this placeholder is auto-generated, false if it is user-generated.
*/
@Override public PlaceholderType(String name, boolean isGenerated) {
public UnifyType setTypeParams(TypeParams newTp) { super(name, new TypeParams());
return this; // Placeholders never have params. EXISTING_PLACEHOLDERS.add(name); // Add to list of existing placeholder names
} IsGenerated = isGenerated;
}
@Override
public int hashCode() {
return typeName.hashCode();
}
@Override
UnifyType apply(Unifier unif) {
if(unif.hasSubstitute(this)) {
UnifyType ret = unif.getSubstitute(this);
//PL 2018-05-17 Auskommentierung muesste korrekt sein,
//bereits in JavaTXComplier Variancen gesetzt werden.
//ret.accept(new distributeVariance(), this.getVariance());
return ret;
}
return this;
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof PlaceholderType))
return false;
return ((PlaceholderType) obj).getName().equals(typeName);
}
@Override /**
public Collection<PlaceholderType> getInvolvedPlaceholderTypes() { * Creates a fresh placeholder type with a name that does so far not exist.
ArrayList<PlaceholderType> ret = new ArrayList<>(); * A user could later instantiate a type using the same name that is equivalent to this type.
ret.add(this); *
return ret; * @return A fresh placeholder type.
} */
public synchronized static PlaceholderType freshPlaceholder() {
String name = "gen_" + (char) (rnd.nextInt(22) + 97); // Returns random char between 'a' and 'z'
// Add random chars while the name is in use.
while (EXISTING_PLACEHOLDERS.contains(name)) {
name += (char) (rnd.nextInt(22) + 97); // Returns random char between 'a' and 'z'
}
return new PlaceholderType(name, true);
}
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
/**
* True if this placeholder is auto-generated, false if it is user-generated.
*/
public boolean isGenerated() {
return IsGenerated;
}
public int getVariance() {
return variance;
}
public void setVariance(int v) {
variance = v;
}
public void reversVariance() {
if (variance == 1) {
setVariance(-1);
} else {
if (variance == -1) {
setVariance(1);
}
}
}
public byte getOrCons() {
return orCons;
}
public void setOrCons(byte i) {
orCons = i;
}
public Boolean isWildcardable() {
return canBeWildcard;
}
public void disableWildcardable() {
canBeWildcard = false;
}
public void enableWildcardable() {
canBeWildcard = true;
}
public Boolean isInnerType() {
return innerType;
}
public void setInnerType(Boolean innerType) {
this.innerType = innerType;
}
@Override
Set<UnifyType> smArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.smArg(this, fBounded);
}
@Override
Set<UnifyType> grArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.grArg(this, fBounded);
}
@Override
public UnifyType setTypeParams(TypeParams newTp) {
throw new RuntimeException("Placeholders never have params");
}
@Override
public int hashCode() {
return typeName.hashCode();
}
@Override
UnifyType apply(Unifier unifier) {
if (unifier.hasSubstitute(this)) {
//PL 2018-05-17 Auskommentierung muesste korrekt sein,
//bereits in JavaTXComplier Variancen gesetzt werden.
//ret.accept(new distributeVariance(), this.getVariance());
return unifier.getSubstitute(this);
}
return this;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof PlaceholderType placeholderObj) {
return placeholderObj.getName().equals(typeName);
}
return false;
}
@Override
public Collection<PlaceholderType> getInvolvedPlaceholderTypes() {
ArrayList<PlaceholderType> ret = new ArrayList<>();
ret.add(this);
return ret;
}
} }

View File

@@ -7,93 +7,92 @@ import java.util.Set;
/** /**
* A reference type e.q. Integer or List<T>. * A reference type e.q. Integer or List<T>.
* @author Florian Steurer
* *
* @author Florian Steurer
*/ */
public class ReferenceType extends UnifyType { public class ReferenceType extends UnifyType {
/**
* The buffered hashCode
*/
private final int hashCode;
/**
* gibt an, ob der ReferenceType eine generische Typvariable ist
*/
private final boolean genericTypeVar;
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) { /**
return visitor.visit(this, ht); * The buffered hashCode
} */
private final int hashCode;
public ReferenceType(String name, Boolean genericTypeVar) {
super(name, new TypeParams());
hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode();
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();
genericTypeVar = false;
}
public boolean isGenTypeVar () { /**
return genericTypeVar; * Defines, if the reference type is a generic type variable
} */
private final boolean genericTypeVar;
@Override
Set<UnifyType> smArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.smArg(this, fBounded);
}
@Override public ReferenceType(String name, Boolean genericTypeVar) {
Set<UnifyType> grArg(IFiniteClosure fc, Set<UnifyType> fBounded) { super(name, new TypeParams());
return fc.grArg(this, fBounded); hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode();
} this.genericTypeVar = genericTypeVar;
}
@Override public ReferenceType(String name, UnifyType... params) {
UnifyType apply(Unifier unif) { super(name, new TypeParams(params));
TypeParams newParams = typeParams.apply(unif); hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode();
genericTypeVar = false;
if(newParams.hashCode() == typeParams.hashCode() && newParams.equals(typeParams)) }
return this;
return new ReferenceType(typeName, newParams);
}
@Override
public UnifyType setTypeParams(TypeParams newTp) {
if(newTp.hashCode() == typeParams.hashCode() && newTp.equals(typeParams))
return this; // reduced the amount of objects created
return new ReferenceType(typeName, newTp);
}
@Override
public int hashCode() {
return hashCode;
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof ReferenceType))
return false;
if(obj.hashCode() != this.hashCode())
return false;
ReferenceType other = (ReferenceType) obj;
if(!other.getName().equals(typeName))
return false;
return other.getTypeParams().equals(typeParams); public ReferenceType(String name, TypeParams params) {
} super(name, params);
} hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode();
genericTypeVar = false;
}
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
public boolean isGenTypeVar() {
return genericTypeVar;
}
@Override
Set<UnifyType> smArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.smArg(this, fBounded);
}
@Override
Set<UnifyType> grArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.grArg(this, fBounded);
}
@Override
UnifyType apply(Unifier unifier) {
TypeParams newParams = typeParams.apply(unifier);
if (newParams.hashCode() == typeParams.hashCode() && newParams.equals(typeParams))
return this;
return new ReferenceType(typeName, newParams);
}
@Override
public UnifyType setTypeParams(TypeParams newTp) {
if (newTp.hashCode() == typeParams.hashCode() && newTp.equals(typeParams)) {
// reduced the amount of objects created by reusing this instance
return this;
}
return new ReferenceType(typeName, newTp);
}
@Override
public int hashCode() {
return hashCode;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ReferenceType referenceObj))
return false;
if (obj.hashCode() != this.hashCode())
return false;
if (!referenceObj.getName().equals(typeName))
return false;
return referenceObj.getTypeParams().equals(typeParams);
}
}

Some files were not shown because too many files have changed in this diff Show More