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,22 +22,16 @@ 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();
@@ -51,18 +43,21 @@ public class JavaTXCompiler {
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 { public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
this(sourceFile); this(sourceFile);
this.log = log; this.log = log;
} }
public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException { public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException {
this(sourceFiles, null); 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")));
} }
@@ -73,6 +68,7 @@ public class JavaTXCompiler {
} }
//INSTANCE = this; //INSTANCE = this;
} }
public JavaTXCompiler(List<File> source, List<File> contextPath, String unificationServer) throws IOException, ClassNotFoundException { public JavaTXCompiler(List<File> source, List<File> contextPath, String unificationServer) throws IOException, ClassNotFoundException {
this(source, contextPath); this(source, contextPath);
this.unificationServer = unificationServer == null ? Optional.empty() : Optional.of(unificationServer); this.unificationServer = unificationServer == null ? Optional.empty() : Optional.of(unificationServer);
@@ -82,16 +78,18 @@ public class JavaTXCompiler {
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); importedClasses.add(importedClass);
} }
for(Class c : CompilationEnvironment.loadDefaultPackageClasses(forSourceFile, classLoader)){ for (Class<?> c : CompilationEnvironment.loadDefaultPackageClasses(forSourceFile, classLoader)) {
ClassOrInterface importedClass = ASTFactory.createClass(c); ClassOrInterface importedClass = ASTFactory.createClass(c);
importedClasses.add(importedClass); importedClasses.add(importedClass);
} }
@@ -120,38 +118,33 @@ public class JavaTXCompiler {
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 {
else {
optSuperclass = optSuperclass =
sf.KlassenVektor.stream().filter(x -> x.getClassName().equals( sf.KlassenVektor.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();
addMethods(sf, superclass, importedClasses, objectClass); addMethods(sf, superclass, importedClasses, objectClass);
} } else {
else {
//throw new ClassNotFoundException(""); //throw new ClassNotFoundException("");
} }
} }
} }
Iterator<RefTypeOrTPHOrWildcardOrGeneric> paraIt= cl.getSuperClass().getParaList().iterator(); Iterator<RefTypeOrTPHOrWildcardOrGeneric> paraIt = cl.getSuperClass().getParaList().iterator();
Iterator<GenericTypeVar> tvarVarIt = superclass.getGenerics().iterator(); Iterator<GenericTypeVar> tvarVarIt = superclass.getGenerics().iterator();
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>(); HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>();
while (paraIt.hasNext()) { while (paraIt.hasNext()) {
gtvs.put(tvarVarIt.next().getName(), paraIt.next()); gtvs.put(tvarVarIt.next().getName(), paraIt.next());
} }
Iterator<Method> methodIt = superclass.getMethods().iterator();
//TODO: PL 2020-05-06: Hier müssen ueberschriebene Methoden noch rausgefiltert werden //TODO: PL 2020-05-06: Hier müssen ueberschriebene Methoden noch rausgefiltert werden
while(methodIt.hasNext()) { for (Method m : superclass.getMethods()) {
Method m = methodIt.next();
ParameterList newParaList = new ParameterList( ParameterList newParaList = new ParameterList(
m.getParameterList() m.getParameterList()
.getFormalparalist() .getFormalparalist()
@@ -160,7 +153,7 @@ public class JavaTXCompiler {
.collect(Collectors.toCollection(ArrayList::new)), m.getParameterList().getOffset()); .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, 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()), //new GenericDeclarationList(newGenericsList, ((GenericDeclarationList)m.getGenerics()).getOffset()),
(GenericDeclarationList)m.getGenerics(), (GenericDeclarationList) m.getGenerics(),
m.getOffset(), true)); m.getOffset(), true));
} }
@@ -169,31 +162,11 @@ public class JavaTXCompiler {
} }
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 {
// PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal
// hinzugefuegt werden
// List<ClassOrInterface> allClasses = new
// ArrayList<>();//environment.getAllAvailableClasses();
Set<ClassOrInterface> allClasses = new HashSet<>();
/*
* PL 2018-09-19 geloescht werden bereits in typeInference hinzugefuegt for
* (SourceFile sf : sourceFiles.values()) { allClasses.addAll(sf.getClasses());
* }
*/
List<ClassOrInterface> importedClasses = new ArrayList<>(); List<ClassOrInterface> importedClasses = new ArrayList<>();
for (JavaClassName name : forSourceFile.getImports()) { for (JavaClassName name : forSourceFile.getImports()) {
@@ -319,11 +292,10 @@ public class JavaTXCompiler {
* ResultSet(UnifyTypeFactory.convert(unifyPairs, * ResultSet(UnifyTypeFactory.convert(unifyPairs,
* generateTPHMap(cons))))).collect(Collectors.toList()); } * generateTPHMap(cons))))).collect(Collectors.toList()); }
*/ */
/** /**
* 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.
*
*
*/ */
/* /*
* private void varianceInheritance(Set<UnifyPair> eq) { Set<PlaceholderType> * private void varianceInheritance(Set<UnifyPair> eq) { Set<PlaceholderType>
@@ -350,45 +322,6 @@ public class JavaTXCompiler {
* phSetVariance.removeIf(x -> (x.getVariance() == 0 || usedTPH.contains(x))); } * phSetVariance.removeIf(x -> (x.getVariance() == 0 || usedTPH.contains(x))); }
* } * }
*/ */
/**
* TODO: can this be removed?
*
* @param resultListener
* @param logFile
* @return
* @throws ClassNotFoundException
* @throws IOException
*/
public UnifyResultModelParallel typeInferenceAsync(UnifyResultListener resultListener, Writer logFile)
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).collect(Collectors.toList()));
}
/*
* Run the actual type inference process
*/
TypeInference typeInference = new TypeInference(
getConstraints(),
allClasses,
classLoader,
useResultModel,
log,
logFile,
statistics
);
return typeInference.executeAsync(resultListener);
}
public List<ResultSet> typeInference() throws ClassNotFoundException, IOException { public List<ResultSet> typeInference() throws ClassNotFoundException, IOException {
/* /*
@@ -399,7 +332,7 @@ public class JavaTXCompiler {
SourceFile sf = sourceFiles.get(f); SourceFile sf = sourceFiles.get(f);
allClasses.addAll(getAvailableClasses(sf)); allClasses.addAll(getAvailableClasses(sf));
allClasses.addAll(sf.getClasses()); allClasses.addAll(sf.getClasses());
allClasses.addAll(CompilationEnvironment.loadDefaultPackageClasses(f,classLoader).stream().map(ASTFactory::createClass).toList()); allClasses.addAll(CompilationEnvironment.loadDefaultPackageClasses(f, classLoader).stream().map(ASTFactory::createClass).toList());
} }
/* /*
@@ -410,8 +343,7 @@ public class JavaTXCompiler {
// TODO: check if this makes sense and does not only always use the first source file key... // 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()) logFile = log ? new FileWriter(System.getProperty("user.dir") + "/logFiles/" + "log_" + sourceFiles.keySet().iterator().next().getName())
: new OutputStreamWriter(new NullOutputStream()); : new OutputStreamWriter(new NullOutputStream());
} } catch (IOException ioException) {
catch (IOException ioException) {
System.err.println("IO Exception: " + ioException.getMessage()); System.err.println("IO Exception: " + ioException.getMessage());
logFile = new OutputStreamWriter(new NullOutputStream()); logFile = new OutputStreamWriter(new NullOutputStream());
} }
@@ -447,7 +379,7 @@ public class JavaTXCompiler {
* @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();
@@ -461,7 +393,7 @@ public class JavaTXCompiler {
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() {
@@ -473,15 +405,14 @@ public class JavaTXCompiler {
* @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);
@@ -521,31 +452,30 @@ public class JavaTXCompiler {
} }
/* 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
@@ -555,14 +485,13 @@ public class JavaTXCompiler {
@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

@@ -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;
/** /**

View File

@@ -1,24 +1,21 @@
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 org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SocketServer extends WebSocketServer { public class SocketServer extends WebSocketServer {

View File

@@ -7,7 +7,6 @@ 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 {

View File

@@ -16,7 +16,7 @@ public class PacketContainer {
/* /*
* 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;

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;

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;

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;

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

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

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;

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

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

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;

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

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;
/** /**

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;
/** /**

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;
/** /**

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;
/** /**

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;
} }

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
@@ -64,115 +59,31 @@ public class TypeInference {
this.statisticFileWriter = statisticFileWriter; this.statisticFileWriter = statisticFileWriter;
} }
public UnifyResultModelParallel executeAsync( public static List<ResultSet> executeWithoutContext(
UnifyResultListener resultListener IFiniteClosure finiteClosure,
) throws ClassNotFoundException, IOException { ConstraintSet<Pair> constraints,
ConstraintSet<UnifyPair> unifyConstraints
// 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); UnifyResultModelParallel urm = new UnifyResultModelParallel(constraints, finiteClosure);
urm.addUnifyResultListener(resultListener); TypeUnify.statistics = new NullWriter();
unifyConstraints = unifyConstraints.map(x -> { (new TypeUnify()).unifyParallel(
// 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(), unifyConstraints.getUndConstraints(),
oderConstraints, unifyConstraints.getOderConstraints(),
finiteClosure, finiteClosure,
logFileWriter, new OutputStreamWriter(new NullOutputStream()),
shouldLog, false,
urm, urm,
usedTasks new UnifyTaskModelParallel() // TODO: move this to SocketData to cancel the pool once a client disconnects
); );
return urm; return urm.getResults();
} }
public List<ResultSet> execute(Optional<String> remoteServer) throws ClassNotFoundException, IOException { public List<ResultSet> execute(Optional<String> remoteServer) throws ClassNotFoundException, IOException {
// generate finite closure // generate finite closure
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFileWriter, classLoader); IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFileWriter, classLoader);
logFileWriter.write("FC:\\" + finiteClosure.toString() + "\n"); logFileWriter.write("FC:\\" + finiteClosure + "\n");
System.out.println(finiteClosure); System.out.println(finiteClosure);
// generate unifyConstraints // generate unifyConstraints
@@ -196,17 +107,6 @@ public class TypeInference {
//Es wird davon ausgegangen, dass in OderConstraints in Bedingungen für Parameter die Typen der Argumente links stehen //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 //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()); System.out.println("Unify nach Oder-Constraints-Anpassung:" + unifyConstraints.toString());
Set<PlaceholderType> varianceTPHold; Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = TypeInferenceHelper.varianceInheritanceConstraintSet(unifyConstraints); Set<PlaceholderType> varianceTPH = TypeInferenceHelper.varianceInheritanceConstraintSet(unifyConstraints);
@@ -228,17 +128,8 @@ public class TypeInference {
* (!varianceTPHold.equals(varianceTPH)); * (!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))*/;
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyConstraints.getOderConstraints();
UnifyTaskModelParallel usedTasks = new UnifyTaskModelParallel(); UnifyTaskModelParallel usedTasks = new UnifyTaskModelParallel();
List<ResultSet> results; List<ResultSet> results;
@@ -262,8 +153,7 @@ public class TypeInference {
unify, unify,
unifyConstraints, unifyConstraints,
oderConstraints, oderConstraints,
finiteClosure, finiteClosure
usedTasks
); );
} }
@@ -280,9 +170,7 @@ public class TypeInference {
TypeUnify unify, TypeUnify unify,
ConstraintSet<UnifyPair> unifyCons, ConstraintSet<UnifyPair> unifyCons,
List<Set<Constraint<UnifyPair>>> oderConstraints, List<Set<Constraint<UnifyPair>>> oderConstraints,
IFiniteClosure finiteClosure, IFiniteClosure finiteClosure
UnifyTaskModelParallel taskModel
) throws IOException { ) throws IOException {
Set<Set<UnifyPair>> result = unify.unifyOderConstraints( Set<Set<UnifyPair>> result = unify.unifyOderConstraints(
unifyCons.getUndConstraints(), unifyCons.getUndConstraints(),
@@ -290,29 +178,14 @@ public class TypeInference {
finiteClosure, finiteClosure,
logFileWriter, logFileWriter,
shouldLog, shouldLog,
new UnifyResultModelParallel(constraints, finiteClosure), new UnifyResultModelParallel(constraints, finiteClosure)
taskModel
); );
System.out.println("RESULT: " + result); System.out.println("RESULT: " + result);
logFileWriter.write("RES: " + result.toString() + "\n"); logFileWriter.write("RES: " + result.toString() + "\n");
logFileWriter.flush(); logFileWriter.flush();
Set<Set<UnifyPair>> results = new HashSet<>(result); Set<Set<UnifyPair>> results = TypeInferenceHelper.resolveSubstitutions(new HashSet<>(result), finiteClosure);
results = results.stream().map(x -> {
// alle Paare a <.? b erden durch a =. b ersetzt
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("RESULT Final: " + results);
System.out.println("Constraints for Generated Generics: " + " ???"); System.out.println("Constraints for Generated Generics: " + " ???");
logFileWriter.write("RES_FINAL: " + results.toString() + "\n"); logFileWriter.write("RES_FINAL: " + results.toString() + "\n");
@@ -332,40 +205,22 @@ public class TypeInference {
UnifyTaskModelParallel taskModel UnifyTaskModelParallel taskModel
) throws IOException { ) throws IOException {
UnifyResultModelParallel urm = new UnifyResultModelParallel(constraints, finiteClosure); UnifyResultModelParallel urm = new UnifyResultModelParallel(constraints, finiteClosure);
UnifyResultListenerImpl li = new UnifyResultListenerImpl(); unify.unifyParallel(
urm.addUnifyResultListener(li); unifyCons.getUndConstraints(),
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFileWriter, shouldLog, urm, oderConstraints,
taskModel); finiteClosure,
System.out.println("RESULT Final: " + li.getResults()); logFileWriter,
shouldLog,
urm,
taskModel
);
System.out.println("RESULT Final: " + urm.getResults());
System.out.println("Constraints for Generated Generics: " + " ???"); System.out.println("Constraints for Generated Generics: " + " ???");
logFileWriter.write("RES_FINAL: " + li.getResults().toString() + "\n"); logFileWriter.write("RESULT_FINAL: " + urm.getResults().toString() + "\n");
logFileWriter.flush(); logFileWriter.flush();
statisticFileWriter.close(); statisticFileWriter.close();
return li.getResults();
}
public static List<ResultSet> executeWithoutContext( return urm.getResults();
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();
(new TypeUnify()).unifyParallel(
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 li.getResults();
} }
} }

View File

@@ -5,23 +5,43 @@ 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 -> {
@@ -35,9 +55,8 @@ public class TypeInferenceHelper {
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(
@@ -55,25 +74,25 @@ 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;
}); });
} }
@@ -89,7 +108,7 @@ public class TypeInferenceHelper {
}, (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;
}); });
@@ -107,7 +126,7 @@ public class TypeInferenceHelper {
}, (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;
}); });
@@ -138,8 +157,6 @@ public class TypeInferenceHelper {
/** /**
* 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,7 +35,7 @@ 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()

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,7 +15,7 @@ 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());
@@ -31,7 +25,7 @@ public class FunNClass extends ClassOrInterface {
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()));
} }

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,14 +28,7 @@ public class MethodAssumption extends Assumption{
this.isInherited = isInherited; this.isInherited = isInherited;
} }
/* public ClassOrInterface getReceiver() {
public RefType getReceiverType() {
return receiver;
}
*/
public ClassOrInterface getReceiver(){
return receiver; return receiver;
} }
@@ -43,7 +36,7 @@ public class MethodAssumption extends Assumption{
return retType; return retType;
} }
public List<? extends RefTypeOrTPHOrWildcardOrGeneric> getArgTypes(){ public List<? extends RefTypeOrTPHOrWildcardOrGeneric> getArgTypes() {
return params; return params;
} }
@@ -53,28 +46,24 @@ 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());
} }

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());

View File

@@ -1,21 +1,16 @@
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 * wird verwendet um bei der Codegenerierung die richtige Methoden - Signatur
* auszuwaehlen * auszuwaehlen
*/ */
/*private*/ Set<A> methodSignatureConstraint = new HashSet<>(); /*private*/ Set<A> methodSignatureConstraint = new HashSet<>();
private Boolean isInherited = false;//wird nur für die Method-Constraints benoetigt
private Constraint<A> extendConstraint = null; private Constraint<A> extendConstraint = null;
public Constraint() { public Constraint() {
@@ -59,7 +54,7 @@ public class Constraint<A> extends HashSet<A> {
public String toString() { public String toString() {
return super.toString() + "\nisInherited = " + isInherited return super.toString() + "\nisInherited = " + isInherited
//" + extendsContraint: " + (extendConstraint != null ? extendConstraint.toStringBase() : "null" ) //" + extendsContraint: " + (extendConstraint != null ? extendConstraint.toStringBase() : "null" )
+ "\n" ; + "\n";
} }
public String toStringBase() { public String toStringBase() {

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,11 +21,11 @@ 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);
} }
@@ -37,14 +35,14 @@ public class ConstraintSet<A> {
} }
@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<>();
@@ -69,17 +67,17 @@ public class ConstraintSet<A> {
} }
*/ */
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);
@@ -101,18 +99,18 @@ public class ConstraintSet<A> {
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;

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,15 +1,15 @@
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;
@@ -17,42 +17,52 @@ public class Pair implements Serializable
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() static public Map<String, TypePlaceholder> generateTPHMap(ConstraintSet<Pair> constraints) {
{ HashMap<String, TypePlaceholder> ret = new HashMap<>();
constraints.map((Pair p) -> {
if (p.TA1 instanceof TypePlaceholder) {
ret.put(((TypePlaceholder) p.TA1).getName(), (TypePlaceholder) p.TA1);
}
if (p.TA2 instanceof TypePlaceholder) {
ret.put(((TypePlaceholder) p.TA2).getName(), (TypePlaceholder) p.TA2);
}
return null;
});
return ret;
}
public String toString() {
// otth: Gibt ein Paar als String aus --> zum Debuggen und Vergleichen // otth: Gibt ein Paar als String aus --> zum Debuggen und Vergleichen
String strElement1 = "NULL"; String strElement1 = "NULL";
String strElement2 = "NULL"; String strElement2 = "NULL";
String Operator = "<."; String Operator = "<.";
if( TA1 != null ) if (TA1 != null)
strElement1 = TA1.toString(); strElement1 = TA1.toString();
if( TA2 != null ) if (TA2 != null)
strElement2 = TA2.toString(); strElement2 = TA2.toString();
/* PL ausskommentiert 2018-05-24 /* PL ausskommentiert 2018-05-24
@@ -71,16 +81,16 @@ public class Pair implements Serializable
/** /**
* <br/>Author: J�rg B�uerle * <br/>Author: J�rg B�uerle
*
* @param obj * @param obj
* @return * @return
*/ */
public boolean equals(Object obj) public boolean equals(Object obj) {
{
boolean ret = true; boolean ret = true;
ret &= (obj instanceof Pair); ret &= (obj instanceof Pair);
if(!ret)return ret; if (!ret) return ret;
ret &= ((Pair)obj).TA1.equals(this.TA1); ret &= ((Pair) obj).TA1.equals(this.TA1);
ret &= ((Pair)obj).TA2.equals(this.TA2); ret &= ((Pair) obj).TA2.equals(this.TA2);
return ret; return ret;
} }
@@ -88,8 +98,7 @@ public class Pair implements Serializable
* Author: Arne Lüdtke<br/> * Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ Equal ist. * Abfrage, ob Operator vom Typ Equal ist.
*/ */
public boolean OperatorEqual() public boolean OperatorEqual() {
{
return eOperator == PairOperator.EQUALSDOT; return eOperator == PairOperator.EQUALSDOT;
} }
@@ -97,8 +106,7 @@ public class Pair implements Serializable
* Author: Arne Lüdtke<br/> * Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ Smaller ist. * Abfrage, ob Operator vom Typ Smaller ist.
*/ */
public boolean OperatorSmaller() public boolean OperatorSmaller() {
{
return eOperator == PairOperator.SMALLER; return eOperator == PairOperator.SMALLER;
} }
@@ -106,8 +114,7 @@ public class Pair implements Serializable
* Author: Arne Lüdtke<br/> * Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ SmallerExtends ist. * Abfrage, ob Operator vom Typ SmallerExtends ist.
*/ */
public boolean OperatorSmallerExtends() public boolean OperatorSmallerExtends() {
{
return eOperator == PairOperator.SMALLERDOTWC; return eOperator == PairOperator.SMALLERDOTWC;
} }
@@ -115,28 +122,12 @@ public class Pair implements Serializable
* Author: Arne Lüdtke<br/> * Author: Arne Lüdtke<br/>
* Gibt den Operator zurück. * Gibt den Operator zurück.
*/ */
public PairOperator GetOperator() public PairOperator GetOperator() {
{
return eOperator; return eOperator;
} }
public boolean OperatorSmallerDot() { public boolean OperatorSmallerDot() {
return eOperator == PairOperator.SMALLERDOT; return eOperator == PairOperator.SMALLERDOT;
} }
static public Map<String, TypePlaceholder> generateTPHMap(ConstraintSet<Pair> constraints) {
HashMap<String, TypePlaceholder> ret = new HashMap<>();
constraints.map((Pair p) -> {
if (p.TA1 instanceof TypePlaceholder) {
ret.put(((TypePlaceholder) p.TA1).getName(), (TypePlaceholder) p.TA1);
}
if (p.TA2 instanceof TypePlaceholder) {
ret.put(((TypePlaceholder) p.TA2).getName(), (TypePlaceholder) p.TA2);
}
return null;
});
return ret;
}
} }
// ino.end // ino.end

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;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
@@ -13,15 +12,9 @@ public class GenericInsertPair {
TA2 = superType; TA2 = superType;
} }
public GenericInsertPair(Pair pair) {
TA1 = (TypePlaceholder) pair.TA1;
TA2 = (TypePlaceholder) pair.TA2;
}
public boolean contains(TypePlaceholder additionalTPH) { public boolean contains(TypePlaceholder additionalTPH) {
if(TA1.equals(additionalTPH))return true; if (TA1.equals(additionalTPH)) return true;
if(TA2.equals(additionalTPH))return true; return TA2.equals(additionalTPH);
return false;
} }
@Override @Override

View File

@@ -2,24 +2,15 @@ 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;
/* public PairNoResult(RefTypeOrTPHOrWildcardOrGeneric left, RefTypeOrTPHOrWildcardOrGeneric right) {
* urspruengliches Paar aus diesem dieses Resultpair erzeugt wurde
* wichtig fuer generated Generics
*/
ResultPair origPair;
public PairNoResult(RefTypeOrTPHOrWildcardOrGeneric left, RefTypeOrTPHOrWildcardOrGeneric right){
super(left, right); super(left, right);
} }

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;

View File

@@ -6,23 +6,26 @@ 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 * the original pair from which this result pair was generated. Important for generated generics
* wichtig fuer generated Generics
*/ */
ResultPair origPair; ResultPair<? extends RefTypeOrTPHOrWildcardOrGeneric, ? extends RefTypeOrTPHOrWildcardOrGeneric> origPair;
public PairTPHsmallerTPH(TypePlaceholder left, TypePlaceholder right){ 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(
TypePlaceholder left,
TypePlaceholder right,
ResultPair<? extends RefTypeOrTPHOrWildcardOrGeneric, ? extends RefTypeOrTPHOrWildcardOrGeneric> origPair
) {
this(left, right); this(left, right);
this.origPair = origPair; this.origPair = origPair;
} }

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 final RefTypeOrTPHOrWildcardOrGeneric resolvedType;
public class ResolvedType{
private ResultPair<?, ?> resultPair; private ResultPair<?, ?> resultPair;
public final RefTypeOrTPHOrWildcardOrGeneric resolvedType; public ResolvedType(RefTypeOrTPHOrWildcardOrGeneric resolvedType) {
//public final Set<GenericInsertPair> additionalGenerics;
public ResolvedType(RefTypeOrTPHOrWildcardOrGeneric resolvedType, Set<GenericInsertPair> additionalGenerics){
this.resolvedType = resolvedType; this.resolvedType = resolvedType;
//this.additionalGenerics = additionalGenerics;
}
public void setResultPair(ResultPair<?, ?> resultPair) {
this.resultPair = resultPair;
} }
public ResultPair<?, ?> getResultPair() { public ResultPair<?, ?> getResultPair() {
return resultPair; return resultPair;
} }
public void setResultPair(ResultPair<?, ?> 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;
} }
@@ -45,18 +45,15 @@ public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B ext
return false; return false;
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
ResultPair<?,?> other = (ResultPair<?,?>) obj; ResultPair<?, ?> other = (ResultPair<?, ?>) obj;
if (left == null) { if (left == null) {
if (other.left != null) if (other.left != null)
return false; return false;
} else if (!left.getOffset().equals(other.left.getOffset())) } else if (!left.getOffset().equals(other.left.getOffset()))
return false; return false;
if (right == null) { if (right == null) {
if (other.right != null) return other.right == null;
return false; } else return right.getOffset().equals(other.right.getOffset());
} else if (!right.getOffset().equals(other.right.getOffset()))
return false;
return true;
} }
} }

View File

@@ -2,7 +2,9 @@ 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

View File

@@ -1,26 +1,25 @@
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) {
@@ -32,13 +31,13 @@ public class ResultSet {
} }
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<>());
@@ -51,8 +50,7 @@ public class ResultSet {
@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;
@@ -67,34 +65,34 @@ public class ResultSet {
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;
} }
@@ -102,18 +100,18 @@ class Resolver implements ResultSetVisitor {
@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);
@@ -152,7 +150,6 @@ class Resolver implements ResultSetVisitor {
} }
} }
/** /**
@@ -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);
} }
} }

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,9 +8,9 @@ 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<>();
@@ -23,11 +22,10 @@ public class GenericsResolverSameName implements GenericsResolver, TypeVisitor<R
@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,46 +1,45 @@
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));
@@ -69,19 +68,19 @@ public class TYPE {
} }
*/ */
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,9 +59,72 @@ 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);
} }
} }
@@ -70,12 +137,11 @@ public class TYPEStmt implements StatementVisitor{
//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));
@@ -93,7 +159,7 @@ public class TYPEStmt implements StatementVisitor{
@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,23 +221,23 @@ 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);
@@ -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,57 +284,47 @@ 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));
@@ -276,7 +332,7 @@ public class TYPEStmt implements StatementVisitor{
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));
@@ -284,7 +340,7 @@ public class TYPEStmt implements StatementVisitor{
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));
@@ -292,7 +348,7 @@ public class TYPEStmt implements StatementVisitor{
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));
@@ -300,7 +356,7 @@ public class TYPEStmt implements StatementVisitor{
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));
@@ -308,7 +364,7 @@ public class TYPEStmt implements StatementVisitor{
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));
@@ -326,9 +382,9 @@ public class TYPEStmt implements StatementVisitor{
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));
@@ -336,11 +392,11 @@ public class TYPEStmt implements StatementVisitor{
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)) {
@@ -393,22 +449,21 @@ 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));
@@ -431,63 +486,58 @@ public class TYPEStmt implements StatementVisitor{
return; return;
} }
if (literal.value instanceof Integer) { if (literal.value instanceof Integer) {
//constraintsSet.addUndConstraint(new Pair(literal.getType(),integer, PairOperator.EQUALSDOT)); HashSet<JavaClassName> clNames = info.getAvailableClasses().stream().map(ClassOrInterface::getClassName).collect(Collectors.toCollection(HashSet::new));
// /* Set<Constraint<Pair>> oderConstraints = new HashSet<>();
HashSet<JavaClassName> clNames = info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)); Constraint<Pair> constraint = new Constraint<>();
Set<Constraint> oderConstraints = new HashSet<>();
Constraint constraint = new Constraint();
constraint.add(new Pair(literal.getType(), integer, PairOperator.EQUALSDOT)); constraint.add(new Pair(literal.getType(), integer, PairOperator.EQUALSDOT));
oderConstraints.add(constraint); oderConstraints.add(constraint);
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Double")).findAny().isPresent()) { if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Double"))) {
constraint = new Constraint(); constraint = new Constraint<>();
constraint.add(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT)); constraint.add(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT));
oderConstraints.add(constraint); oderConstraints.add(constraint);
} }
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Long")).findAny().isPresent()) { if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Long"))) {
constraint = new Constraint(); constraint = new Constraint<>();
constraint.add(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT)); constraint.add(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT));
oderConstraints.add(constraint); oderConstraints.add(constraint);
} }
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Float")).findAny().isPresent()) { if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Float"))) {
constraint = new Constraint(); constraint = new Constraint<>();
constraint.add(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT)); constraint.add(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT));
oderConstraints.add(constraint); oderConstraints.add(constraint);
} }
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Short")).findAny().isPresent()) { if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Short"))) {
constraint = new Constraint(); constraint = new Constraint<>();
constraint.add(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT)); constraint.add(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT));
oderConstraints.add(constraint); oderConstraints.add(constraint);
} }
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Byte")).findAny().isPresent()) { if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Byte"))) {
constraint = new Constraint(); constraint = new Constraint<>();
constraint.add(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT)); constraint.add(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT));
oderConstraints.add(constraint); oderConstraints.add(constraint);
} }
constraintsSet.addOderConstraint(oderConstraints); constraintsSet.addOderConstraint(oderConstraints);
// */
return; return;
} }
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 String) { if (literal.value instanceof String) {
constraintsSet.addUndConstraint(new Pair(literal.getType(),string, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), string, PairOperator.EQUALSDOT));
return; return;
} }
if (literal.value instanceof Boolean) { if (literal.value instanceof Boolean) {
constraintsSet.addUndConstraint(new Pair(literal.getType(),bool, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), bool, PairOperator.EQUALSDOT));
return; } else {
}
else {
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
@@ -495,7 +545,7 @@ public class TYPEStmt implements StatementVisitor{
@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,7 +568,7 @@ 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());
@@ -526,28 +576,14 @@ public class TYPEStmt implements StatementVisitor{
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,6 +592,10 @@ 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
@@ -573,27 +613,12 @@ 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.
@@ -616,7 +641,7 @@ public class TYPEStmt implements StatementVisitor{
//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);
@@ -639,13 +664,12 @@ 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
@@ -655,12 +679,11 @@ public class TYPEStmt implements StatementVisitor{
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));
@@ -669,75 +692,16 @@ public class TYPEStmt implements StatementVisitor{
//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; return ret;
} }
public static List<MethodAssumption> getMethods(String name, int numArgs, TypeInferenceBlockInformation info) { public List<MethodAssumption> getConstructors(TypeInferenceBlockInformation info, RefType ofType, ArgumentList argList) {
List<MethodAssumption> ret = new ArrayList<>(); List<MethodAssumption> ret = new ArrayList<>();
//TODO: apply Methoden wieder anfügen. Diese könnten möglicherweise auch in den Assumptions auftauchen (überdenken) for (ClassOrInterface cl : info.getAvailableClasses()) {
if(name.equals("apply")){ if (cl.getClassName().equals(ofType.getName())) {
List<GenericRefType> funNParams = new ArrayList<>(); for (Method m : cl.getConstructors()) {
for(int i = 0; i< numArgs + 1 ; i++){ if (m.getParameterList().getFormalparalist().size() == argList.getArguments().size()) {
//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 List<MethodAssumption> getConstructors(TypeInferenceBlockInformation info, RefType ofType, ArgumentList argList){
List<MethodAssumption> ret = new ArrayList<>();
for(ClassOrInterface cl : info.getAvailableClasses()){
if(cl.getClassName().equals(ofType.getName())){
for(Method m : cl.getConstructors()){
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,8 +712,8 @@ 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(),

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,16 +1,15 @@
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 {

View File

@@ -1,22 +1,14 @@
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 {
@@ -24,7 +16,7 @@ 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}, // For the the set of terms {t1,...,tn},
@@ -32,7 +24,7 @@ public class MartelliMontanariUnify implements IUnify {
ArrayList<UnifyPair> termsList = new ArrayList<UnifyPair>(); ArrayList<UnifyPair> termsList = new ArrayList<UnifyPair>();
Iterator<UnifyType> iter = terms.iterator(); Iterator<UnifyType> iter = terms.iterator();
UnifyType prev = iter.next(); UnifyType prev = iter.next();
while(iter.hasNext()) { while (iter.hasNext()) {
UnifyType next = iter.next(); UnifyType next = iter.next();
termsList.add(new UnifyPair(prev, next, PairOperator.EQUALSDOT)); termsList.add(new UnifyPair(prev, next, PairOperator.EQUALSDOT));
prev = next; prev = next;
@@ -43,7 +35,7 @@ public class MartelliMontanariUnify implements IUnify {
// Apply rules while possible // Apply rules while possible
int idx = 0; int idx = 0;
while(idx < termsList.size()) { while (idx < termsList.size()) {
UnifyPair pair = termsList.get(idx); UnifyPair pair = termsList.get(idx);
UnifyType rhsType = pair.getRhsType(); UnifyType rhsType = pair.getRhsType();
UnifyType lhsType = pair.getLhsType(); UnifyType lhsType = pair.getLhsType();
@@ -51,21 +43,21 @@ public class MartelliMontanariUnify implements IUnify {
TypeParams lhsTypeParams = lhsType.getTypeParams(); TypeParams lhsTypeParams = lhsType.getTypeParams();
// REDUCE - Rule // REDUCE - Rule
if(!(rhsType instanceof PlaceholderType) && !(lhsType instanceof PlaceholderType)) { if (!(rhsType instanceof PlaceholderType) && !(lhsType instanceof PlaceholderType)) {
Set<UnifyPair> result = new HashSet<>(); Set<UnifyPair> result = new HashSet<>();
// f<...> = g<...> with f != g are not unifiable // f<...> = g<...> with f != g are not unifiable
if(!rhsType.getName().equals(lhsType.getName())) if (!rhsType.getName().equals(lhsType.getName()))
return Optional.empty(); // conflict return Optional.empty(); // conflict
// f<t1,...,tn> = f<s1,...,sm> are not unifiable // f<t1,...,tn> = f<s1,...,sm> are not unifiable
if(rhsTypeParams.size() != lhsTypeParams.size()) if (rhsTypeParams.size() != lhsTypeParams.size())
return Optional.empty(); // conflict return Optional.empty(); // conflict
// f = g is not unifiable (cannot be f = f because erase rule would have been applied) // f = g is not unifiable (cannot be f = f because erase rule would have been applied)
//if(rhsTypeParams.size() == 0) //if(rhsTypeParams.size() == 0)
//return Optional.empty(); //return Optional.empty();
// Unpack the arguments // Unpack the arguments
for(int i = 0; i < rhsTypeParams.size(); i++) for (int i = 0; i < rhsTypeParams.size(); i++)
result.add(new UnifyPair(rhsTypeParams.get(i), lhsTypeParams.get(i), PairOperator.EQUALSDOT)); result.add(new UnifyPair(rhsTypeParams.get(i), lhsTypeParams.get(i), PairOperator.EQUALSDOT));
termsList.remove(idx); termsList.remove(idx);
@@ -74,29 +66,29 @@ public class MartelliMontanariUnify implements IUnify {
} }
// DELETE - Rule // DELETE - Rule
if(pair.getRhsType().equals(pair.getLhsType())) { if (pair.getRhsType().equals(pair.getLhsType())) {
termsList.remove(idx); termsList.remove(idx);
continue; continue;
} }
// SWAP - Rule // SWAP - Rule
if(!(lhsType instanceof PlaceholderType) && (rhsType instanceof PlaceholderType)) { if (!(lhsType instanceof PlaceholderType) && (rhsType instanceof PlaceholderType)) {
termsList.remove(idx); termsList.remove(idx);
termsList.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT)); termsList.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT));
continue; continue;
} }
// OCCURS-CHECK // OCCURS-CHECK
if(pair.getLhsType() instanceof PlaceholderType if (pair.getLhsType() instanceof PlaceholderType
&& pair.getRhsType().getTypeParams().occurs((PlaceholderType) pair.getLhsType())) && pair.getRhsType().getTypeParams().occurs((PlaceholderType) pair.getLhsType()))
return Optional.empty(); return Optional.empty();
// SUBST - Rule // SUBST - Rule
if(lhsType instanceof PlaceholderType) { if (lhsType instanceof PlaceholderType) {
mgu.add((PlaceholderType) lhsType, rhsType); mgu.add((PlaceholderType) lhsType, rhsType);
//PL 2018-04-01 nach checken, ob es richtig ist, dass keine Substitutionen uebergeben werden muessen. //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)); termsList = termsList.stream().map(x -> mgu.apply(x)).collect(Collectors.toCollection(ArrayList::new));
idx = idx+1 == termsList.size() ? 0 : idx+1; idx = idx + 1 == termsList.size() ? 0 : idx + 1;
continue; continue;
} }

View File

@@ -11,6 +11,7 @@ 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 {
@@ -26,7 +27,7 @@ public class Match implements IMatch {
// Apply rules while possible // Apply rules while possible
int idx = 0; int idx = 0;
while(idx < termsList.size()) { while (idx < termsList.size()) {
UnifyPair pair = termsList.get(idx); UnifyPair pair = termsList.get(idx);
UnifyType rhsType = pair.getRhsType(); UnifyType rhsType = pair.getRhsType();
UnifyType lhsType = pair.getLhsType(); UnifyType lhsType = pair.getLhsType();
@@ -34,21 +35,21 @@ public class Match implements IMatch {
TypeParams lhsTypeParams = lhsType.getTypeParams(); TypeParams lhsTypeParams = lhsType.getTypeParams();
// REDUCE - Rule // REDUCE - Rule
if(!(rhsType instanceof PlaceholderType) && !(lhsType instanceof PlaceholderType)) { if (!(rhsType instanceof PlaceholderType) && !(lhsType instanceof PlaceholderType)) {
Set<UnifyPair> result = new HashSet<>(); Set<UnifyPair> result = new HashSet<>();
// f<...> = g<...> with f != g are not unifiable // f<...> = g<...> with f != g are not unifiable
if(!rhsType.getName().equals(lhsType.getName())) if (!rhsType.getName().equals(lhsType.getName()))
return Optional.empty(); // conflict return Optional.empty(); // conflict
// f<t1,...,tn> = f<s1,...,sm> are not unifiable // f<t1,...,tn> = f<s1,...,sm> are not unifiable
if(rhsTypeParams.size() != lhsTypeParams.size()) if (rhsTypeParams.size() != lhsTypeParams.size())
return Optional.empty(); // conflict return Optional.empty(); // conflict
// f = g is not unifiable (cannot be f = f because erase rule would have been applied) // f = g is not unifiable (cannot be f = f because erase rule would have been applied)
//if(rhsTypeParams.size() == 0) //if(rhsTypeParams.size() == 0)
//return Optional.empty(); //return Optional.empty();
// Unpack the arguments // Unpack the arguments
for(int i = 0; i < rhsTypeParams.size(); i++) for (int i = 0; i < rhsTypeParams.size(); i++)
result.add(new UnifyPair(lhsTypeParams.get(i), rhsTypeParams.get(i), PairOperator.EQUALSDOT)); result.add(new UnifyPair(lhsTypeParams.get(i), rhsTypeParams.get(i), PairOperator.EQUALSDOT));
termsList.remove(idx); termsList.remove(idx);
@@ -57,13 +58,13 @@ public class Match implements IMatch {
} }
// DELETE - Rule // DELETE - Rule
if(pair.getRhsType().equals(pair.getLhsType())) { if (pair.getRhsType().equals(pair.getLhsType())) {
termsList.remove(idx); termsList.remove(idx);
continue; continue;
} }
// SWAP - Rule // SWAP - Rule
if(!(lhsType instanceof PlaceholderType) && (rhsType instanceof PlaceholderType)) { if (!(lhsType instanceof PlaceholderType) && (rhsType instanceof PlaceholderType)) {
return Optional.empty(); // conflict return Optional.empty(); // conflict
} }
@@ -71,10 +72,10 @@ public class Match implements IMatch {
//deleted //deleted
// SUBST - Rule // SUBST - Rule
if(lhsType instanceof PlaceholderType) { if (lhsType instanceof PlaceholderType) {
mgu.add((PlaceholderType) lhsType, rhsType); mgu.add((PlaceholderType) lhsType, rhsType);
termsList = termsList.stream().map(mgu::applyleft).collect(Collectors.toCollection(ArrayList::new)); termsList = termsList.stream().map(mgu::applyLeft).collect(Collectors.toCollection(ArrayList::new));
idx = idx+1 == termsList.size() ? 0 : idx+1; idx = idx + 1 == termsList.size() ? 0 : idx + 1;
continue; continue;
} }

View File

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

View File

@@ -4,7 +4,6 @@ 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;
@@ -14,16 +13,6 @@ public class TypeUnify2Task extends TypeUnifyTask {
Set<Set<UnifyPair>> setToFlatten; Set<Set<UnifyPair>> setToFlatten;
Set<UnifyPair> methodSignatureConstraintUebergabe; Set<UnifyPair> methodSignatureConstraintUebergabe;
//statistics
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, Writer statistics) {
this(setToFlatten, eq, oderConstraints, nextSetElement, fc, parallel, logFile, log, urm, methodSignatureConstraintUebergabe, pool );
}
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) { 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) {
super(eq, oderConstraints, fc, parallel, logFile, log, urm, pool); super(eq, oderConstraints, fc, parallel, logFile, log, urm, pool);
this.setToFlatten = setToFlatten; this.setToFlatten = setToFlatten;
@@ -48,9 +37,9 @@ public class TypeUnify2Task extends TypeUnifyTask {
} }
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,7 +93,7 @@ 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() {
@@ -300,7 +291,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
*/ */
urm.notify(eqPrimePrimeSet); unifyResultModel.notify(eqPrimePrimeSet);
writeStatistics("Result: " + eqPrimePrimeSet); writeStatistics("Result: " + eqPrimePrimeSet);
} }
} else if (eqPrimePrime.isPresent()) { } else if (eqPrimePrime.isPresent()) {
@@ -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
@@ -617,7 +608,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
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) -> { .reduce((y, z) -> {
y.addAll(z); y.addAll(z);
return y; return y;
@@ -627,22 +618,18 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
return y; return y;
}).get() }).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;
@@ -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);
@@ -1213,7 +1200,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
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);
@@ -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,7 +1386,7 @@ 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))
@@ -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,12 +1515,12 @@ 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,7 +1530,7 @@ 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) {

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 synchronized void onNewTypeResultFound(List<ResultSet> result) {
results.addAll(result);
} }
public void removeUnifyResultListener(UnifyResultListener listenerToRemove) {
listeners.remove(listenerToRemove); public List<ResultSet> getResults() {
return results;
} }
public void notify(Set<Set<UnifyPair>> eqPrimePrimeSet){
pool.execute(()->{ public void notify(Set<Set<UnifyPair>> eqPrimePrimeSet) {
Set<Set<UnifyPair>> eqPrimePrimeSetRet = eqPrimePrimeSet.stream().map(x -> { pool.execute(() -> {
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> { Set<Set<UnifyPair>> eqPrimePrimeSetRet =
if (y.getPairOp() == PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT); TypeInferenceHelper.resolveSubstitutions(new HashSet<>(eqPrimePrimeSet), fc);
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 -> List<ResultSet> newResult = eqPrimePrimeSetRet.stream().map(unifyPairs ->
new ResultSet(UnifyTypeFactory.convert(unifyPairs, de.dhbwstuttgart.typeinference.constraints.Pair.generateTPHMap(cons)))) new ResultSet(UnifyTypeFactory.convert(unifyPairs, de.dhbwstuttgart.typeinference.constraints.Pair.generateTPHMap(cons))))
.collect(Collectors.toList()); .collect(Collectors.toList());
UnifyResultEvent evt = new UnifyResultEvent(newResult);
for (UnifyResultListener listener : listeners) { // TODO: this is a synchronized call, can we find a way around this?
listener.onNewTypeResultFound(evt); 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 { try {
writer.close(); writer.close();
} catch (IOException e) { } catch (IOException e) {
System.err.println(e.getMessage());
}
});
}
public void closeNonThreaded() {
try {
writer.close();
} 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(); void setLogTrue();
/** /**
* Returns all types of the finite closure that are subtypes of the argument. * Returns all types of the finite closure that are subtypes of the argument.
*
* @return The set of subtypes of the argument. * @return The set of subtypes of the argument.
*/ */
public Set<UnifyType> smaller(UnifyType type, Set<UnifyType> fBounded); Set<UnifyType> smaller(UnifyType type, Set<UnifyType> fBounded);
/** /**
* Returns all types of the finite closure that are supertypes of the argument. * Returns all types of the finite closure that are supertypes of the argument.
*
* @return The set of supertypes of the argument. * @return The set of supertypes of the argument.
*/ */
public Set<UnifyType> greater(UnifyType type, Set<UnifyType> fBounded); Set<UnifyType> greater(UnifyType type, Set<UnifyType> fBounded);
/** /**
* Wo passt Type rein? * Wo passt Type rein?
*
* @param type * @param type
* @return * @return
*/ */
public Set<UnifyType> grArg(UnifyType type, Set<UnifyType> fBounded); Set<UnifyType> grArg(UnifyType type, Set<UnifyType> fBounded);
/** /**
* Was passt in Type rein? * Was passt in Type rein?
*
* @param type * @param type
* @return * @return
*/ */
public Set<UnifyType> smArg(UnifyType type, Set<UnifyType> fBounded); Set<UnifyType> smArg(UnifyType type, Set<UnifyType> fBounded);
public Set<UnifyType> grArg(ReferenceType type, Set<UnifyType> fBounded); 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); Set<UnifyType> smArg(ReferenceType type, Set<UnifyType> fBounded);
public Set<UnifyType> smArg(ExtendsType type, Set<UnifyType> fBounded);
public Set<UnifyType> grArg(SuperType type, Set<UnifyType> fBounded); Set<UnifyType> grArg(ExtendsType type, Set<UnifyType> fBounded);
public Set<UnifyType> smArg(SuperType type, Set<UnifyType> fBounded);
public Set<UnifyType> grArg(PlaceholderType type, Set<UnifyType> fBounded); Set<UnifyType> smArg(ExtendsType type, Set<UnifyType> fBounded);
public Set<UnifyType> smArg(PlaceholderType type, Set<UnifyType> fBounded);
public Set<UnifyType> grArg(FunNType type, Set<UnifyType> fBounded); Set<UnifyType> grArg(SuperType type, Set<UnifyType> fBounded);
public Set<UnifyType> smArg(FunNType type, Set<UnifyType> fBounded);
public Set<UnifyPair> getPairs(); Set<UnifyType> smArg(SuperType type, Set<UnifyType> fBounded);
public Optional<UnifyType> getLeftHandedType(String typeName);
public Set<UnifyType> getAncestors(UnifyType t);
public Set<UnifyType> getChildren(UnifyType t);
public Set<UnifyType> getAllTypesByName(String typeName);
public int compare(UnifyType rhsType, UnifyType rhsType2, PairOperator pairop); 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,6 +8,7 @@ import java.util.Optional;
/** /**
* Match * Match
*
* @author Martin Pluemicke * @author Martin Pluemicke
* abgeleitet aus IUnify.java * abgeleitet aus IUnify.java
*/ */
@@ -16,10 +17,11 @@ public interface IMatch {
/** /**
* Finds the most general matcher sigma of the set {t1 =. t1',...,tn =. tn'} so that * Finds the most general matcher sigma of the set {t1 =. t1',...,tn =. tn'} so that
* sigma(t1) = t1' , ... sigma(tn) = tn'. * sigma(t1) = t1' , ... sigma(tn) = tn'.
* @param terms The set of terms to be matched *
* @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. * @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); Optional<Unifier> match(ArrayList<UnifyPair> termsList);
} }

View File

@@ -9,32 +9,43 @@ 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);
Optional<Set<UnifyPair>> reduceEq(UnifyPair pair);
Optional<Set<UnifyPair>> reduce1(UnifyPair pair, IFiniteClosure fc);
Optional<Set<UnifyPair>> reduce2(UnifyPair pair);
/* /*
* Missing Reduce-Rules for Wildcards * Missing Reduce-Rules for Wildcards
*/ */
public Optional<UnifyPair> reduceWildcardLow(UnifyPair pair); Optional<UnifyPair> reduceWildcardLow(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardLowRight(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardUp(UnifyPair pair); Optional<UnifyPair> reduceWildcardLowRight(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardUpRight(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);
*/ */
/* /*
@@ -44,60 +55,69 @@ public interface IRuleSet {
/** /**
* 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. * Checks whether the erase1-Rule applies to the pair.
*
* @return True if the pair is erasable, false otherwise. * @return True if the pair is erasable, false otherwise.
*/ */
public boolean erase1(UnifyPair pair, IFiniteClosure fc); boolean erase1(UnifyPair pair, IFiniteClosure fc);
/** /**
* Checks whether the erase2-Rule applies to the pair. * Checks whether the erase2-Rule applies to the pair.
*
* @return True if the pair is erasable, false otherwise. * @return True if the pair is erasable, false otherwise.
*/ */
public boolean erase2(UnifyPair pair, IFiniteClosure fc); boolean erase2(UnifyPair pair, IFiniteClosure fc);
/** /**
* Checks whether the erase3-Rule applies to the pair. * Checks whether the erase3-Rule applies to the pair.
*
* @return True if the pair is erasable, false otherwise. * @return True if the pair is erasable, false otherwise.
*/ */
public boolean erase3(UnifyPair pair); boolean erase3(UnifyPair pair);
public Optional<UnifyPair> swap(UnifyPair pair); Optional<UnifyPair> swap(UnifyPair pair);
public Optional<UnifyPair> adapt(UnifyPair pair, IFiniteClosure fc); Optional<UnifyPair> adapt(UnifyPair pair, IFiniteClosure fc);
public Optional<UnifyPair> adaptExt(UnifyPair pair, IFiniteClosure fc);
public Optional<UnifyPair> adaptSup(UnifyPair pair, IFiniteClosure fc); Optional<UnifyPair> adaptExt(UnifyPair pair, IFiniteClosure fc);
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. * @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. * @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, List<Set<Constraint<UnifyPair>>> oderConstraints); Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs, List<Set<Constraint<UnifyPair>>> oderConstraints);
/** /**
* 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. * @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. * @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);
} }

View File

@@ -5,11 +5,13 @@ 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,6 +10,7 @@ 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 {
@@ -17,18 +18,20 @@ public interface IUnify {
/** /**
* Finds the most general unifier sigma of the set {t1 =. t1',...,tn =. tn'} so that * Finds the most general unifier sigma of the set {t1 =. t1',...,tn =. tn'} so that
* sigma(t1) = sigma(t1') , ... sigma(tn) = sigma(tn'). * sigma(t1) = sigma(t1') , ... sigma(tn) = sigma(tn').
*
* @param terms The set of terms to be unified * @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. * @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); Optional<Unifier> unify(Set<UnifyType> terms);
/** /**
* Finds the most general unifier sigma of the set {t1 =. t1',...,tn =. tn'} so that * Finds the most general unifier sigma of the set {t1 =. t1',...,tn =. tn'} so that
* sigma(t1) = sigma(t1') , ... sigma(tn) = sigma(tn'). * sigma(t1) = sigma(t1') , ... sigma(tn) = sigma(tn').
*
* @param terms The set of terms to be unified * @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. * @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) { default Optional<Unifier> unify(UnifyType... terms) {
return unify(Arrays.stream(terms).collect(Collectors.toSet())); 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); PlaceholderType visit(PlaceholderType phty, T ht);
public FunNType visit(FunNType funnty, T ht); FunNType visit(FunNType funnty, T ht);
public SuperType visit(SuperType suty, T ht); SuperType visit(SuperType suty, T ht);
public ExtendsType visit(ExtendsType extty, T ht); ExtendsType visit(ExtendsType extty, T ht);
} }

View File

@@ -10,12 +10,9 @@ import java.util.Set;
*/ */
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. * Creates a new extends wildcard type.
*
* @param extendedType The extended type e.g. Integer in "? extends Integer" * @param extendedType The extended type e.g. Integer in "? extends Integer"
*/ */
public ExtendsType(UnifyType extendedType) { public ExtendsType(UnifyType extendedType) {
@@ -25,6 +22,10 @@ public final class ExtendsType extends WildcardType {
} }
} }
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
/** /**
* The extended type e.g. Integer in "? extends Integer" * The extended type e.g. Integer in "? extends Integer"
*/ */
@@ -38,7 +39,7 @@ public final class ExtendsType extends WildcardType {
@Override @Override
public UnifyType setTypeParams(TypeParams newTp) { public UnifyType setTypeParams(TypeParams newTp) {
UnifyType newType = wildcardedType.setTypeParams(newTp); UnifyType newType = wildcardedType.setTypeParams(newTp);
if(newType == wildcardedType) if (newType == wildcardedType)
return this; // Reduced the amount of objects created return this; // Reduced the amount of objects created
return new ExtendsType(wildcardedType.setTypeParams(newTp)); return new ExtendsType(wildcardedType.setTypeParams(newTp));
} }
@@ -54,9 +55,9 @@ public final class ExtendsType extends WildcardType {
} }
@Override @Override
UnifyType apply(Unifier unif) { UnifyType apply(Unifier unifier) {
UnifyType newType = wildcardedType.apply(unif); UnifyType newType = wildcardedType.apply(unifier);
if(newType.hashCode() == wildcardedType.hashCode() && newType.equals(wildcardedType)) if (newType.hashCode() == wildcardedType.hashCode() && newType.equals(wildcardedType))
return this; // Reduced the amount of objects created return this; // Reduced the amount of objects created
return new ExtendsType(newType); return new ExtendsType(newType);
} }
@@ -72,15 +73,12 @@ public final class ExtendsType extends WildcardType {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(!(obj instanceof ExtendsType)) if (!(obj instanceof ExtendsType other))
return false; return false;
if(obj.hashCode() != this.hashCode()) if (obj.hashCode() != this.hashCode())
return false; return false;
ExtendsType other = (ExtendsType) obj;
return other.getWildcardedType().equals(wildcardedType); return other.getWildcardedType().equals(wildcardedType);
} }

View File

@@ -14,39 +14,31 @@ import java.util.stream.Collectors;
/** /**
* The finite closure for the type unification * The finite closure for the type unification
*
* @author Florian Steurer * @author Florian Steurer
*/ */
public class FiniteClosure //extends Ordering<UnifyType> //entfernt PL 2018-12-11 public class FiniteClosure implements IFiniteClosure {
implements IFiniteClosure {
Writer logFile;
static Boolean log = false; static Boolean log = false;
public void setLogTrue() {
log = true;
}
/** /**
* A map that maps every type to the node in the inheritance graph that contains that type. * A map that maps every type to the node in the inheritance graph that contains that type.
*/ */
private HashMap<UnifyType, Node<UnifyType>> inheritanceGraph; private final HashMap<UnifyType, Node<UnifyType>> inheritanceGraph;
/** /**
* A map that maps every typename to the nodes of the inheritance graph that contain a type with that name. * A map that maps every typename to the nodes of the inheritance graph that contain a type with that name.
*/ */
private HashMap<String, Set<Node<UnifyType>>> strInheritanceGraph; private final HashMap<String, Set<Node<UnifyType>>> strInheritanceGraph;
/** /**
* The initial pairs of that define the inheritance tree * The initial pairs of that define the inheritance tree
*/ */
private Set<UnifyPair> pairs; private final Set<UnifyPair> pairs;
Writer logFile;
/** /**
* Hastable fuer die greater-Werte, damit sie nicht doppelt berechnet werden muessen * Hashtable for greater-values to prevent them from being calculated twice
*/ */
Hashtable<hashKeyType, Set<UnifyType>> greaterHash = new Hashtable<>(); Hashtable<hashKeyType, Set<UnifyType>> greaterHash = new Hashtable<>();
/** /**
* Hastable fuer die smaller-Werte, damit sie nicht doppelt berechnet werden muessen * Hashtable for smaller-values to prevent them from being calculated twice
*/ */
Hashtable<hashKeyType, Set<UnifyType>> smallerHash = new Hashtable<>(); Hashtable<hashKeyType, Set<UnifyType>> smallerHash = new Hashtable<>();
@@ -56,23 +48,12 @@ implements IFiniteClosure {
public FiniteClosure(Set<UnifyPair> pairs, Writer logFile) { public FiniteClosure(Set<UnifyPair> pairs, Writer logFile) {
this.logFile = logFile; this.logFile = logFile;
this.pairs = new HashSet<>(pairs); this.pairs = new HashSet<>(pairs);
inheritanceGraph = new HashMap<UnifyType, Node<UnifyType>>(); inheritanceGraph = new HashMap<>();
// Build the transitive closure of the inheritance tree // Build the transitive closure of the inheritance tree
for(UnifyPair pair : pairs) { for (UnifyPair pair : pairs) {
/* if (pair.getPairOp() != PairOperator.SMALLER) continue;
try {
logFile.write("Pair: " + pair + "\n");
logFile.flush();
}
catch (IOException e) {
System.err.println("no LogFile");
}
*/
if(pair.getPairOp() != PairOperator.SMALLER)
continue;
//VERSUCH PL 18-02-06 //VERSUCH PL 18-02-06
//koennte ggf. die FC reduzieren //koennte ggf. die FC reduzieren
@@ -80,12 +61,12 @@ implements IFiniteClosure {
//if (!pair.getLhsType().getTypeParams().arePlaceholders() //if (!pair.getLhsType().getTypeParams().arePlaceholders()
// && !pair.getRhsType().getTypeParams().arePlaceholders()) // && !pair.getRhsType().getTypeParams().arePlaceholders())
// continue; // continue;
;
// Add nodes if not already in the graph // Add nodes if not already in the graph
if(!inheritanceGraph.containsKey(pair.getLhsType())) if (!inheritanceGraph.containsKey(pair.getLhsType()))
inheritanceGraph.put(pair.getLhsType(), new Node<UnifyType>(pair.getLhsType())); inheritanceGraph.put(pair.getLhsType(), new Node<>(pair.getLhsType()));
if(!inheritanceGraph.containsKey(pair.getRhsType())) if (!inheritanceGraph.containsKey(pair.getRhsType()))
inheritanceGraph.put(pair.getRhsType(), new Node<UnifyType>(pair.getRhsType())); inheritanceGraph.put(pair.getRhsType(), new Node<>(pair.getRhsType()));
Node<UnifyType> childNode = inheritanceGraph.get(pair.getLhsType()); Node<UnifyType> childNode = inheritanceGraph.get(pair.getLhsType());
Node<UnifyType> parentNode = inheritanceGraph.get(pair.getRhsType()); Node<UnifyType> parentNode = inheritanceGraph.get(pair.getRhsType());
@@ -94,38 +75,40 @@ implements IFiniteClosure {
parentNode.addDescendant(childNode); parentNode.addDescendant(childNode);
// Add edges to build the transitive closure // Add edges to build the transitive closure
parentNode.getPredecessors().stream().forEach(x -> x.addDescendant(childNode)); parentNode.getPredecessors().forEach(x -> x.addDescendant(childNode));
childNode.getDescendants().stream().forEach(x -> x.addPredecessor(parentNode)); childNode.getDescendants().forEach(x -> x.addPredecessor(parentNode));
//PL eingefuegt 2020-05-07 File UnitTest InheritTest.java //PL eingefuegt 2020-05-07 File UnitTest InheritTest.java
this.inheritanceGraph.forEach((x,y) -> { if (y.getDescendants().contains(parentNode)) { y.addDescendant(childNode); y.addAllDescendant(childNode.getDescendants());}; this.inheritanceGraph.forEach((x, y) -> {
if (y.getPredecessors().contains(childNode)) { y.addPredecessor(parentNode); y.addAllPredecessor(parentNode.getPredecessors());};} ); if (y.getDescendants().contains(parentNode)) {
y.addDescendant(childNode);
y.addAllDescendant(childNode.getDescendants());
}
if (y.getPredecessors().contains(childNode)) {
y.addPredecessor(parentNode);
y.addAllPredecessor(parentNode.getPredecessors());
}
});
} }
// Build the alternative representation with strings as keys // Build the alternative representation with strings as keys
strInheritanceGraph = new HashMap<>(); strInheritanceGraph = new HashMap<>();
for(UnifyType key : inheritanceGraph.keySet()) { for (UnifyType key : inheritanceGraph.keySet()) {
if(!strInheritanceGraph.containsKey(key.getName())) if (!strInheritanceGraph.containsKey(key.getName())) {
strInheritanceGraph.put(key.getName(), new HashSet<>()); strInheritanceGraph.put(key.getName(), new HashSet<>());
}
strInheritanceGraph.get(key.getName()).add(inheritanceGraph.get(key)); strInheritanceGraph.get(key.getName()).add(inheritanceGraph.get(key));
} }
} }
void testSmaller() { public void setLogTrue() {
UnifyType tq1, tq2, tq3; log = true;
tq1 = new ExtendsType(PlaceholderType.freshPlaceholder());
List<UnifyType> l1 = new ArrayList<>();
List<UnifyType> l2 = new ArrayList<>();
l1.add(tq1);
tq2 = new ReferenceType("java.util.Vector", new TypeParams(l1));
l2.add(tq2);
tq3 = new ReferenceType("java.util.Vector", new TypeParams(l2));
Set<UnifyType> smaller = smaller(tq3, new HashSet<>());
} }
/** /**
* Returns all types of the finite closure that are subtypes of the argument. * Returns all types of the finite closure that are subtypes of the argument.
*
* @return The set of subtypes of the argument. * @return The set of subtypes of the argument.
*/ */
@Override @Override
@@ -133,14 +116,12 @@ implements IFiniteClosure {
Set<UnifyType> ret; Set<UnifyType> ret;
if ((ret = smallerHash.get(new hashKeyType(type))) != null) { if ((ret = smallerHash.get(new hashKeyType(type))) != null) {
//System.out.println(greaterHash);
return new HashSet<>(ret); return new HashSet<>(ret);
} }
if(type instanceof FunNType) if (type instanceof FunNType) return computeSmallerFunN((FunNType) type, fBounded);
return computeSmallerFunN((FunNType) type, fBounded);
Set<Pair<UnifyType,Set<UnifyType>>> ts = new HashSet<>(); Set<Pair<UnifyType, Set<UnifyType>>> ts = new HashSet<>();
ts.add(new Pair<>(type, fBounded)); ts.add(new Pair<>(type, fBounded));
Set<UnifyType> result = computeSmaller(ts); Set<UnifyType> result = computeSmaller(ts);
smallerHash.put(new hashKeyType(type), result); smallerHash.put(new hashKeyType(type), result);
@@ -158,63 +139,61 @@ implements IFiniteClosure {
/** /**
* Computes the smaller functions for every type except FunNTypes. * Computes the smaller functions for every type except FunNTypes.
*/ */
private Set<UnifyType> computeSmaller(Set<Pair<UnifyType,Set<UnifyType>>> types) { private Set<UnifyType> computeSmaller(Set<Pair<UnifyType, Set<UnifyType>>> types) {
Set<Pair<UnifyType,Set<UnifyType>>> result = new HashSet<>(); Set<Pair<UnifyType, Set<UnifyType>>> result = new HashSet<>();
//PL 18-02-05 Unifier durch Matcher ersetzt //PL 18-02-05 Unifier durch Matcher ersetzt
//IUnify unify = new MartelliMontanariUnify(); //IUnify unify = new MartelliMontanariUnify();
Match match = new Match(); Match match = new Match();
for(Pair<UnifyType,Set<UnifyType>> pt : types) { for (Pair<UnifyType, Set<UnifyType>> pt : types) {
UnifyType t = pt.getKey(); UnifyType t = pt.getKey();
Set<UnifyType> fBounded = pt.getValue().get(); Set<UnifyType> fBounded = pt.getValue().get();
// if T = T' then T <* T' // if T = T' then T <* T'
try {
result.add(new Pair<>(t, fBounded)); result.add(new Pair<>(t, fBounded));
}
catch (StackOverflowError e) {
System.out.println("");
}
// if C<...> <* C<...> then ... (third case in definition of <*) // if C<...> <* C<...> then ... (third case in definition of <*)
if(t.getTypeParams().size() > 0) { if (t.getTypeParams().size() > 0) {
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>(); ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
for (int i = 0; i < t.getTypeParams().size(); i++) for (int i = 0; i < t.getTypeParams().size(); i++)
paramCandidates.add(smArg(t.getTypeParams().get(i), fBounded)); paramCandidates.add(smArg(t.getTypeParams().get(i), fBounded));
permuteParams(paramCandidates).forEach(x -> result.add(new Pair<>(t.setTypeParams(x), fBounded))); permuteParams(paramCandidates).forEach(x -> result.add(new Pair<>(t.setTypeParams(x), fBounded)));
} }
if(!strInheritanceGraph.containsKey(t.getName())) if (!strInheritanceGraph.containsKey(t.getName())) continue;
continue;
// if T <* T' then sigma(T) <* sigma(T') // if T <* T' then sigma(T) <* sigma(T')
Set<Node<UnifyType>> candidates = strInheritanceGraph.get(t.getName()); //cadidates= [???Node(java.util.Vector<java.util.Vector<java.lang.Integer>>)??? Set<Node<UnifyType>> candidates = strInheritanceGraph.get(t.getName());
// candidates = [
// ???Node(java.util.Vector<java.util.Vector<java.lang.Integer>>)???
// , Node(java.util.Vector<gen_hv>) // , Node(java.util.Vector<gen_hv>)
//] // ]
for(Node<UnifyType> candidate : candidates) {
for (Node<UnifyType> candidate : candidates) {
UnifyType theta2 = candidate.getContent(); UnifyType theta2 = candidate.getContent();
//PL 18-02-05 Unifier durch Matcher ersetzt ANFANG //PL 18-02-05 Unifier durch Matcher ersetzt ANFANG
ArrayList<UnifyPair> termList= new ArrayList<UnifyPair>(); ArrayList<UnifyPair> termList = new ArrayList<UnifyPair>();
termList.add(new UnifyPair(theta2,t, PairOperator.EQUALSDOT)); termList.add(new UnifyPair(theta2, t, PairOperator.EQUALSDOT));
Optional<Unifier> optSigma = match.match(termList); Optional<Unifier> optSigma = match.match(termList);
//PL 18-02-05 Unifier durch Matcher ersetzt ENDE //PL 18-02-05 Unifier durch Matcher ersetzt ENDE
if(!optSigma.isPresent()) if (optSigma.isEmpty()) continue;
continue;
Unifier sigma = optSigma.get(); Unifier sigma = optSigma.get();
sigma.swapPlaceholderSubstitutions(t.getTypeParams()); sigma.swapPlaceholderSubstitutions(t.getTypeParams());
Set<UnifyType> theta1Set = candidate.getContentOfDescendants(); Set<UnifyType> theta1Set = candidate.getContentOfDescendants();
for(UnifyType theta1 : theta1Set) for (UnifyType theta1 : theta1Set)
result.add(new Pair<>(theta1.apply(sigma), fBounded)); result.add(new Pair<>(theta1.apply(sigma), fBounded));
} }
} }
HashSet<UnifyType> resut = result.stream().map(x -> x.getKey()).collect(Collectors.toCollection(HashSet::new)); HashSet<UnifyType> resultKeys = result.stream().map(Pair::getKey).collect(Collectors.toCollection(HashSet::new));
if(resut.equals(types.stream().map(x -> x.getKey()).collect(Collectors.toCollection(HashSet::new)))) if (resultKeys.equals(types.stream().map(Pair::getKey).collect(Collectors.toCollection(HashSet::new)))) {
return resut; return resultKeys;
}
return computeSmaller(result); return computeSmaller(result);
} }
@@ -231,8 +210,9 @@ implements IFiniteClosure {
// it is enough to permute the params with the values of greater / smaller. // it is enough to permute the params with the values of greater / smaller.
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>(); ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
paramCandidates.add(smaller(type.getTypeParams().get(0), fBounded)); paramCandidates.add(smaller(type.getTypeParams().get(0), fBounded));
for (int i = 1; i < type.getTypeParams().size(); i++) for (int i = 1; i < type.getTypeParams().size(); i++) {
paramCandidates.add(greater(type.getTypeParams().get(i), new HashSet<>())); paramCandidates.add(greater(type.getTypeParams().get(i), new HashSet<>()));
}
permuteParams(paramCandidates).forEach(x -> result.add(type.setTypeParams(x))); permuteParams(paramCandidates).forEach(x -> result.add(type.setTypeParams(x)));
return result; return result;
@@ -240,6 +220,7 @@ implements IFiniteClosure {
/** /**
* Returns all types of the finite closure that are supertypes of the argument. * Returns all types of the finite closure that are supertypes of the argument.
*
* @return The set of supertypes of the argument. * @return The set of supertypes of the argument.
*/ */
@Override @Override
@@ -248,25 +229,21 @@ implements IFiniteClosure {
Set<UnifyType> ret; Set<UnifyType> ret;
if ((ret = greaterHash.get(new hashKeyType(type))) != null) { if ((ret = greaterHash.get(new hashKeyType(type))) != null) {
//System.out.println(greaterHash);
return new HashSet<>(ret); return new HashSet<>(ret);
} }
if (type instanceof FunNType) {
if(type instanceof FunNType) {
return computeGreaterFunN((FunNType) type, fBounded); return computeGreaterFunN((FunNType) type, fBounded);
} }
Set<UnifyType> result = new HashSet<>(); Set<UnifyType> result = new HashSet<>();
Set<Pair<UnifyType,Set<UnifyType>>> PairResultFBounded = new HashSet<>(); Set<Pair<UnifyType, Set<UnifyType>>> PairResultFBounded = new HashSet<>();
Match match = new Match(); Match match = new Match();
// if T = T' then T <=* T' // if T = T' then T <=* T'
result.add(type); result.add(type);
if(!strInheritanceGraph.containsKey(type.getName())) if (!strInheritanceGraph.containsKey(type.getName())) return result;
return result;
// if T <* T' then sigma(T) <* sigma(T') // if T <* T' then sigma(T) <* sigma(T')
Set<Node<UnifyType>> candidates = strInheritanceGraph.get(type.getName()); Set<Node<UnifyType>> candidates = strInheritanceGraph.get(type.getName());
@@ -281,15 +258,15 @@ implements IFiniteClosure {
} }
*/ */
for(Node<UnifyType> candidate : candidates) { for (Node<UnifyType> candidate : candidates) {
UnifyType theta1 = candidate.getContent(); UnifyType theta1 = candidate.getContent();
//PL 18-04-05 Unifier durch Matcher ersetzt ANFANG //PL 18-04-05 Unifier durch Matcher ersetzt ANFANG
ArrayList<UnifyPair> termList= new ArrayList<UnifyPair>(); ArrayList<UnifyPair> termList = new ArrayList<UnifyPair>();
termList.add(new UnifyPair(theta1,type, PairOperator.EQUALSDOT)); termList.add(new UnifyPair(theta1, type, PairOperator.EQUALSDOT));
Optional<Unifier> optSigma = match.match(termList); Optional<Unifier> optSigma = match.match(termList);
//PL 18-04-05 Unifier durch Matcher ersetzt ENDE //PL 18-04-05 Unifier durch Matcher ersetzt ENDE
if(!optSigma.isPresent()) { if (optSigma.isEmpty()) {
continue; continue;
} }
Unifier sigma = optSigma.get(); Unifier sigma = optSigma.get();
@@ -299,7 +276,7 @@ implements IFiniteClosure {
fBoundedNew.add(theta1); fBoundedNew.add(theta1);
Set<UnifyType> theta2Set = candidate.getContentOfPredecessors(); Set<UnifyType> theta2Set = candidate.getContentOfPredecessors();
//System.out.println(""); //System.out.println("");
for(UnifyType theta2 : theta2Set) { for (UnifyType theta2 : theta2Set) {
result.add(theta2.apply(sigma)); result.add(theta2.apply(sigma));
PairResultFBounded.add(new Pair<>(theta2.apply(sigma), fBoundedNew)); PairResultFBounded.add(new Pair<>(theta2.apply(sigma), fBoundedNew));
} }
@@ -313,35 +290,33 @@ implements IFiniteClosure {
System.err.println("no LogFile"); System.err.println("no LogFile");
} }
*/ */
for(Pair<UnifyType,Set<UnifyType>> pt : PairResultFBounded) { for (Pair<UnifyType, Set<UnifyType>> pt : PairResultFBounded) {
UnifyType t = pt.getKey(); UnifyType t = pt.getKey();
Set<UnifyType> lfBounded = pt.getValue().get(); Set<UnifyType> lfBounded = pt.getValue().get();
// if C<...> <* C<...> then ... (third case in definition of <*) // if C<...> <* C<...> then ... (third case in definition of <*)
//TypeParams typeparams = t.getTypeParams(); //TypeParams typeparams = t.getTypeParams();
if(t.getTypeParams().size() > 0) { if (t.getTypeParams().size() > 0) {
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>(); ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
for (int i = 0; i < t.getTypeParams().size(); i++) { for (int i = 0; i < t.getTypeParams().size(); i++) {
//UnifyType parai = t.getTypeParams().get(i); //UnifyType parai = t.getTypeParams().get(i);
int i_ef = i; int i_ef = i;
BiFunction<Boolean,UnifyType,Boolean> f = (x,y) -> BiFunction<Boolean, UnifyType, Boolean> f = (x, y) -> {
{
ArrayList<UnifyPair> termList = new ArrayList<UnifyPair>(); ArrayList<UnifyPair> termList = new ArrayList<UnifyPair>();
termList.add(new UnifyPair(y,t.getTypeParams().get(i_ef), PairOperator.EQUALSDOT)); termList.add(new UnifyPair(y, t.getTypeParams().get(i_ef), PairOperator.EQUALSDOT));
return ((match.match(termList).isPresent()) || x); return ((match.match(termList).isPresent()) || x);
}; };
//if (parai.getName().equals("java.lang.Integer")) { //if (parai.getName().equals("java.lang.Integer")) {
// System.out.println(""); // System.out.println("");
//} //}
BinaryOperator<Boolean> bo = (a,b) -> (a || b); BinaryOperator<Boolean> bo = (a, b) -> (a || b);
if (lfBounded.stream().reduce(false,f,bo)) { if (lfBounded.stream().reduce(false, f, bo)) {
//F-Bounded Endlosrekursion //F-Bounded Endlosrekursion
HashSet<UnifyType> res = new HashSet<UnifyType>(); HashSet<UnifyType> res = new HashSet<UnifyType>();
paramCandidates.add(res); paramCandidates.add(res);
} } else {
else { paramCandidates.add(grArg(t.getTypeParams().get(i), new HashSet<>(fBounded)));
paramCandidates.add(grArg(t.getTypeParams().get(i), new HashSet<>(fBounded) ));
} }
} }
permuteParams(paramCandidates).forEach(x -> result.add(t.setTypeParams(x))); permuteParams(paramCandidates).forEach(x -> result.add(t.setTypeParams(x)));
@@ -361,96 +336,6 @@ implements IFiniteClosure {
return result; return result;
} }
/* auskommentiert PL 2018-05-24
/**
* Returns all types of the finite closure that are supertypes of the argument.
* @return The set of supertypes of the argument.
*
//@Override
public Set<UnifyType> oldgreater(UnifyType type, Set<UnifyType> fBounded) {
if(type instanceof FunNType)
return computeGreaterFunN((FunNType) type, fBounded);
Set<Pair<UnifyType,Set<UnifyType>>> ts = new HashSet<>();
ts.add(new Pair<>(type, fBounded));
return computeGreater(ts);
}
/**
* Computes the greater function for all types except function types.
*
protected Set<UnifyType> computeGreater(Set<Pair<UnifyType,Set<UnifyType>>> types) {
Set<Pair<UnifyType,Set<UnifyType>>> result = new HashSet<>();
//PL 18-04-05 Unifier durch Matcher ersetzt
//IUnify unify = new MartelliMontanariUnify();
Match match = new Match();
for(Pair<UnifyType,Set<UnifyType>> pt : types) {
UnifyType t = pt.getKey();
Set<UnifyType> fBounded = pt.getValue().get();
// if T = T' then T <=* T'
result.add(pt);
// if C<...> <* C<...> then ... (third case in definition of <*)
if(t.getTypeParams().size() > 0) {
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
for (int i = 0; i < t.getTypeParams().size(); i++) {
UnifyType parai = t.getTypeParams().get(i);
int i_ef = i;
BiFunction<Boolean,UnifyType,Boolean> f = (x,y) ->
{
ArrayList<UnifyPair> termList = new ArrayList<UnifyPair>();
termList.add(new UnifyPair(y,t.getTypeParams().get(i_ef), PairOperator.EQUALSDOT));
return ((match.match(termList).isPresent()) || x);
};
if (parai.getName().equals("java.lang.Integer")) {
System.out.println("");
}
BinaryOperator<Boolean> bo = (a,b) -> (a || b);
if (fBounded.stream().reduce(false,f,bo)) continue; //F-Bounded Endlosrekursion
paramCandidates.add(grArg(t.getTypeParams().get(i), new HashSet<>(fBounded) ));
}
permuteParams(paramCandidates).forEach(x -> result.add(new Pair<>(t.setTypeParams(x), new HashSet<>(fBounded))));
}
if(!strInheritanceGraph.containsKey(t.getName()))
continue;
// if T <* T' then sigma(T) <* sigma(T')
Set<Node<UnifyType>> candidates = strInheritanceGraph.get(t.getName());
for(Node<UnifyType> candidate : candidates) {
UnifyType theta1 = candidate.getContent();
//PL 18-04-05 Unifier durch Matcher ersetzt ANFANG
ArrayList<UnifyPair> termList= new ArrayList<UnifyPair>();
termList.add(new UnifyPair(theta1,t, PairOperator.EQUALSDOT));
Optional<Unifier> optSigma = match.match(termList);
//PL 18-04-05 Unifier durch Matcher ersetzt ENDE
if(!optSigma.isPresent())
continue;
Unifier sigma = optSigma.get();
sigma.swapPlaceholderSubstitutionsReverse(theta1.getTypeParams());
Set<UnifyType> fBoundedNew = new HashSet<>(fBounded);
fBoundedNew.add(theta1);
Set<UnifyType> theta2Set = candidate.getContentOfPredecessors();
for(UnifyType theta2 : theta2Set)
result.add(new Pair<>(theta2.apply(sigma), fBoundedNew));
}
}
HashSet<UnifyType> resut = result.stream().map(x -> x.getKey()).collect(Collectors.toCollection(HashSet::new));
System.out.println(resut);
if(resut.equals(types.stream().map(x -> x.getKey()).collect(Collectors.toCollection(HashSet::new))))
return resut;
return computeGreater(result);
}
*/
/** /**
* Computes the greater function for FunN-Types * Computes the greater function for FunN-Types
*/ */
@@ -481,7 +366,7 @@ implements IFiniteClosure {
Set<UnifyType> result = new HashSet<UnifyType>(); Set<UnifyType> result = new HashSet<UnifyType>();
result.add(type); result.add(type);
smaller(type, fBounded).forEach(x -> result.add(new SuperType(x))); smaller(type, fBounded).forEach(x -> result.add(new SuperType(x)));
greater(type,fBounded).forEach(x -> result.add(new ExtendsType(x))); greater(type, fBounded).forEach(x -> result.add(new ExtendsType(x)));
return result; return result;
} }
@@ -558,7 +443,7 @@ implements IFiniteClosure {
result.add(type); result.add(type);
UnifyType t = type.getSuperedType(); UnifyType t = type.getSuperedType();
result.add(t); result.add(t);
//*** ACHTUNG das koennte FALSCH sein PL 2018-05-23 evtl. HashSet durch smArg durchschleifen // TODO: *** ACHTUNG das koennte FALSCH sein PL 2018-05-23 evtl. HashSet durch smArg durchschleifen
greater(t, fBounded).forEach(x -> { greater(t, fBounded).forEach(x -> {
result.add(new SuperType(x)); result.add(new SuperType(x));
result.add(x); result.add(x);
@@ -575,18 +460,16 @@ implements IFiniteClosure {
@Override @Override
public Set<UnifyType> getAllTypesByName(String typeName) { public Set<UnifyType> getAllTypesByName(String typeName) {
if(!strInheritanceGraph.containsKey(typeName)) if (!strInheritanceGraph.containsKey(typeName)) return new HashSet<>();
return new HashSet<>(); return strInheritanceGraph.get(typeName).stream().map(Node::getContent).collect(Collectors.toCollection(HashSet::new));
return strInheritanceGraph.get(typeName).stream().map(x -> x.getContent()).collect(Collectors.toCollection(HashSet::new));
} }
@Override @Override
public Optional<UnifyType> getLeftHandedType(String typeName) { public Optional<UnifyType> getLeftHandedType(String typeName) {
if(!strInheritanceGraph.containsKey(typeName)) if (!strInheritanceGraph.containsKey(typeName)) return Optional.empty();
return Optional.empty();
for(UnifyPair pair : pairs) for (UnifyPair pair : pairs)
if(pair.getLhsType().getName().equals(typeName) && pair.getLhsType().typeParams.arePlaceholders()) if (pair.getLhsType().getName().equals(typeName) && pair.getLhsType().typeParams.arePlaceholders())
return Optional.of(pair.getLhsType()); return Optional.of(pair.getLhsType());
return Optional.empty(); return Optional.empty();
@@ -594,8 +477,7 @@ implements IFiniteClosure {
@Override @Override
public Set<UnifyType> getAncestors(UnifyType t) { public Set<UnifyType> getAncestors(UnifyType t) {
if(!inheritanceGraph.containsKey(t)) if (!inheritanceGraph.containsKey(t)) return new HashSet<>();
return new HashSet<>();
Set<UnifyType> result = inheritanceGraph.get(t).getContentOfPredecessors(); Set<UnifyType> result = inheritanceGraph.get(t).getContentOfPredecessors();
result.add(t); result.add(t);
return result; return result;
@@ -603,8 +485,7 @@ implements IFiniteClosure {
@Override @Override
public Set<UnifyType> getChildren(UnifyType t) { public Set<UnifyType> getChildren(UnifyType t) {
if(!inheritanceGraph.containsKey(t)) if (!inheritanceGraph.containsKey(t)) return new HashSet<>();
return new HashSet<>();
Set<UnifyType> result = inheritanceGraph.get(t).getContentOfDescendants(); Set<UnifyType> result = inheritanceGraph.get(t).getContentOfDescendants();
result.add(t); result.add(t);
return result; return result;
@@ -612,6 +493,7 @@ implements IFiniteClosure {
/** /**
* Takes a set of candidates for each position and computes all possible permutations. * Takes a set of candidates for each position and computes all possible permutations.
*
* @param candidates The length of the list determines the number of type params. Each set * @param candidates The length of the list determines the number of type params. Each set
* contains the candidates for the corresponding position. * contains the candidates for the corresponding position.
*/ */
@@ -623,6 +505,7 @@ implements IFiniteClosure {
/** /**
* Takes a set of candidates for each position and computes all possible permutations. * Takes a set of candidates for each position and computes all possible permutations.
*
* @param candidates The length of the list determines the number of type params. Each set * @param candidates The length of the list determines the number of type params. Each set
* contains the candidates for the corresponding position. * contains the candidates for the corresponding position.
* @param idx Idx for the current permutatiton. * @param idx Idx for the current permutatiton.
@@ -630,84 +513,44 @@ implements IFiniteClosure {
* @param current The permutation of type params that is currently explored * @param current The permutation of type params that is currently explored
*/ */
protected void permuteParams(ArrayList<Set<UnifyType>> candidates, int idx, Set<TypeParams> result, UnifyType[] current) { protected void permuteParams(ArrayList<Set<UnifyType>> candidates, int idx, Set<TypeParams> result, UnifyType[] current) {
if(candidates.size() == idx) { if (candidates.size() == idx) {
result.add(new TypeParams(Arrays.copyOf(current, current.length))); result.add(new TypeParams(Arrays.copyOf(current, current.length)));
return; return;
} }
Set<UnifyType> localCandidates = candidates.get(idx); Set<UnifyType> localCandidates = candidates.get(idx);
for(UnifyType t : localCandidates) { for (UnifyType t : localCandidates) {
current[idx] = t; current[idx] = t;
permuteParams(candidates, idx+1, result, current); permuteParams(candidates, idx + 1, result, current);
} }
} }
@Override @Override
public String toString(){ public String toString() {
return this.inheritanceGraph.toString(); return this.inheritanceGraph.toString();
} }
/* entfernt PL 2018-12-11 public int compare(UnifyType left, UnifyType right, PairOperator pairOp) {
public int compare (UnifyType left, UnifyType right) {
return compare(left, right, PairOperator.SMALLERDOT);
}
*/
public int compare (UnifyType left, UnifyType right, PairOperator pairop) {
//try {logFile.write("left: "+ left + " right: " + right + " pairop: " + pairop);} catch (IOException ie) {}
if (left.getName().equals("Matrix") || right.getName().equals("Matrix"))
System.out.println("");
/*
pairop = PairOperator.SMALLERDOTWC;
List<UnifyType> al = new ArrayList<>();
PlaceholderType xx =new PlaceholderType("xx");
al.add(xx);
left = new ExtendsType(new ReferenceType("Vector", new TypeParams(al)));
List<UnifyType> alr = new ArrayList<>();
UnifyType exx = new ExtendsType(xx);
alr.add(exx);
right = new ExtendsType(new ReferenceType("Vector", new TypeParams(alr)));
*/
/*
List<UnifyType> al = new ArrayList<>();
PlaceholderType xx =new PlaceholderType("xx");
al.add(xx);
left = new ExtendsType(xx);
right = xx;
*/
/*
List<UnifyType> al = new ArrayList<>();
PlaceholderType xx =new PlaceholderType("xx");
PlaceholderType yy =new PlaceholderType("yy");
al.add(xx);
left = yy;
right = new ExtendsType(xx);
*/
//Die Faelle abfangen, bei den Variablen verglichen werden PL 2018-12-11 //Die Faelle abfangen, bei den Variablen verglichen werden PL 2018-12-11
UnifyType ex; UnifyType ex;
if (left instanceof PlaceholderType) { if (left instanceof PlaceholderType) {
if ((right instanceof WildcardType) if ((right instanceof WildcardType) && ((ex = ((WildcardType) right).wildcardedType) instanceof PlaceholderType) && left.getName().equals(ex.getName())) {// a <.? ? extends a oder a <.? ? super a
&& ((ex = ((WildcardType)right).wildcardedType) instanceof PlaceholderType)
&& ((PlaceholderType)left).getName().equals(((PlaceholderType)ex).getName())) {// a <.? ? extends a oder a <.? ? super a
return -1; return -1;
} } else {
else {
return 0; return 0;
} }
} }
if (right instanceof PlaceholderType) {//&& (left instanceof WildcardType)) {PL geloescht 2019-01-15 analog zu oben if (right instanceof PlaceholderType) {//&& (left instanceof WildcardType)) {PL geloescht 2019-01-15 analog zu oben
if ((left instanceof WildcardType) //PL eingefuegt 2019-01-15 analog zu oben if ((left instanceof WildcardType) //PL eingefuegt 2019-01-15 analog zu oben
&& ((ex = ((WildcardType)left).wildcardedType) instanceof PlaceholderType) && ((ex = ((WildcardType) left).wildcardedType) instanceof PlaceholderType) && right.getName().equals(ex.getName())) {// ? extends a <. a oder ? super a <. a
&& ((PlaceholderType)right).getName().equals(((PlaceholderType)ex).getName())) {// ? extends a <. a oder ? super a <. a
return 1; return 1;
} } else {
else {
return 0; return 0;
} }
} }
UnifyPair up = new UnifyPair(left, right, pairop); UnifyPair up = new UnifyPair(left, right, pairOp);
TypeUnifyTask unifyTask = new TypeUnifyTask(); TypeUnifyTask unifyTask = new TypeUnifyTask();
HashSet<UnifyPair> hs = new HashSet<>(); HashSet<UnifyPair> hs = new HashSet<>();
hs.add(up); hs.add(up);
@@ -722,15 +565,12 @@ implements IFiniteClosure {
System.err.println("no LogFile");}} System.err.println("no LogFile");}}
*/ */
//Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok. //Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok.
Predicate<UnifyPair> delFun = x -> !((x.getLhsType() instanceof PlaceholderType || Predicate<UnifyPair> delFun = x -> !((x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType) && !((x.getLhsType() instanceof WildcardType) && //? extends/super a <.? a
x.getRhsType() instanceof PlaceholderType) ((WildcardType) x.getLhsType()).getWildcardedType().equals(x.getRhsType())));
&& !((x.getLhsType() instanceof WildcardType) && //? extends/super a <.? a
((WildcardType)x.getLhsType()).getWildcardedType().equals(x.getRhsType()))
);
long smallerLen = smallerRes.stream().filter(delFun).count(); long smallerLen = smallerRes.stream().filter(delFun).count();
if (smallerLen == 0) return -1; if (smallerLen == 0) return -1;
else { else {
up = new UnifyPair(right, left, pairop); up = new UnifyPair(right, left, pairOp);
//TypeUnifyTask unifyTask = new TypeUnifyTask(); //TypeUnifyTask unifyTask = new TypeUnifyTask();
hs = new HashSet<>(); hs = new HashSet<>();
hs.add(up); hs.add(up);
@@ -744,6 +584,7 @@ implements IFiniteClosure {
catch (IOException e) { catch (IOException e) {
System.err.println("no LogFile");}} System.err.println("no LogFile");}}
*/ */
//Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok. //Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok.
long greaterLen = greaterRes.stream().filter(delFun).count(); long greaterLen = greaterRes.stream().filter(delFun).count();
if (greaterLen == 0) return 1; if (greaterLen == 0) return 1;

View File

@@ -5,50 +5,53 @@ 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 {
/**
* Creates a FunN-Type with the specified TypeParameters.
*/
protected FunNType(TypeParams p) {
super("Fun" + (p.size() - 1) + "$$", p);
}
/**
* Creates a new FunNType.
*
* @param tp The parameters of the type.
* @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)
throw new IllegalArgumentException("FunNTypes need at least one type parameter");
for (UnifyType t : tp)
if (t instanceof WildcardType)
throw new IllegalArgumentException("Invalid TypeParams for a FunNType: " + tp);
return new FunNType(tp);
}
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) { public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, 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 new FunNType.
* @param tp The parameters of the type.
* @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)
throw new IllegalArgumentException("FunNTypes need at least one type parameter");
for(UnifyType t : tp)
if(t instanceof WildcardType)
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>. * Returns the degree of the function type, e.g. 2 for FunN<Integer, Integer, Integer>.
*/ */
public int getN() { public int getN() {
return typeParams.size()-1; return typeParams.size() - 1;
} }
@Override @Override
public UnifyType setTypeParams(TypeParams newTp) { public UnifyType setTypeParams(TypeParams newTp) {
if(newTp.hashCode() == typeParams.hashCode() && newTp.equals(typeParams)) if (newTp.hashCode() == typeParams.hashCode() && newTp.equals(typeParams))
return this; return this;
return getFunNType(newTp); return getFunNType(newTp);
} }
@@ -64,11 +67,11 @@ public class FunNType extends UnifyType {
} }
@Override @Override
UnifyType apply(Unifier unif) { UnifyType apply(Unifier unifier) {
// TODO this bypasses the validation of the type parameters. // TODO this bypasses the validation of the type parameters.
// Wildcard types can be unified into FunNTypes. // Wildcard types can be unified into FunNTypes.
TypeParams newParams = typeParams.apply(unif); TypeParams newParams = typeParams.apply(unifier);
if(newParams.hashCode() == typeParams.hashCode() && newParams.equals(typeParams)) if (newParams.hashCode() == typeParams.hashCode() && newParams.equals(typeParams))
return this; return this;
return new FunNType(newParams); return new FunNType(newParams);
@@ -76,8 +79,8 @@ public class FunNType extends UnifyType {
@Override @Override
public Boolean wrongWildcard() { public Boolean wrongWildcard() {
return (new ArrayList<UnifyType>(Arrays.asList(getTypeParams() List<UnifyType> typeParamList = new ArrayList<>(Arrays.asList(getTypeParams().get()));
.get())).stream().filter(x -> (x instanceof WildcardType)).findFirst().isPresent()); return typeParamList.stream().anyMatch(x -> (x instanceof WildcardType));
} }
@Override @Override
@@ -88,14 +91,12 @@ public class FunNType extends UnifyType {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(!(obj instanceof FunNType)) if (!(obj instanceof FunNType other))
return false; return false;
if(obj.hashCode() != this.hashCode()) if (obj.hashCode() != this.hashCode())
return false; return false;
FunNType other = (FunNType) obj;
return other.getTypeParams().equals(typeParams); return other.getTypeParams().equals(typeParams);
} }

View File

@@ -6,26 +6,26 @@ 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.
@@ -38,7 +38,7 @@ class Node<T> {
* 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);
@@ -49,7 +49,7 @@ class Node<T> {
* 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);
} }
} }
@@ -58,7 +58,7 @@ class Node<T> {
* 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);
@@ -69,50 +69,51 @@ class Node<T> {
* 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;
} }
/** /**
* Retrieves the content of all descendants. * @return The content of all descendants.
*/ */
public Set<T> getContentOfDescendants() { public Set<T> getContentOfDescendants() {
return descendants.stream().map(x -> x.getContent()).collect(Collectors.toSet()); return descendants.stream().map(Node::getContent).collect(Collectors.toSet());
} }
/** /**
* Retrieves the content of all predecessors. * @return The content of all predecessors.
*/ */
public Set<T> getContentOfPredecessors() { public Set<T> getContentOfPredecessors() {
return predecessors.stream().map(x -> x.getContent()).collect(Collectors.toSet()); return predecessors.stream().map(Node::getContent).collect(Collectors.toSet());
} }
@Override @Override
public String toString() { public String toString() {
return "Elem: Node(" + content.toString() + ")\nPrec: " + getContentOfPredecessors().toString() return
+ "\nDesc: " + getContentOfDescendants().toString() + "\n\n"; "Elem: Node(" + content.toString() + ")\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,6 +2,7 @@ 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 {
@@ -38,12 +39,12 @@ public enum PairOperator {
@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,9 +10,10 @@ 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.
@@ -20,15 +21,10 @@ public final class PlaceholderType extends UnifyType{
*/ */
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.
*/
protected static String nextName = "gen_";
/** /**
* Random number generator used to generate fresh placeholder name. * Random number generator used to generate fresh placeholder name.
*/ */
protected static Random rnd = new Random(43558747548978L); private static final Random rnd = new Random(43558747548978L);
/** /**
* True if this object was auto-generated, false if this object was user-generated. * True if this object was auto-generated, false if this object was user-generated.
@@ -37,12 +33,12 @@ public final class PlaceholderType extends UnifyType{
/** /**
* isWildcardable gibt an, ob ein Wildcardtyp dem PlaceholderType zugeordnet werden darf * Defines, if a WildcardType can be assigned to this PlaceholderType
*/ */
private boolean wildcardable = true; private boolean canBeWildcard = true;
/** /**
* is innerType gibt an, ob der Type des PlaceholderType innerhalb eines Typkonstruktorsverwendet wird * Defines, if this type is used inside a type constructor
*/ */
private boolean innerType = false; private boolean innerType = false;
@@ -56,7 +52,7 @@ public final class PlaceholderType extends UnifyType{
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
@@ -74,6 +70,7 @@ public final class PlaceholderType extends UnifyType{
/** /**
* Creates a new placeholdertype * Creates a new placeholdertype
*
* @param isGenerated true if this placeholder is auto-generated, false if it is user-generated. * @param isGenerated true if this placeholder is auto-generated, false if it is user-generated.
*/ */
public PlaceholderType(String name, boolean isGenerated) { public PlaceholderType(String name, boolean isGenerated) {
@@ -82,24 +79,24 @@ public final class PlaceholderType extends UnifyType{
IsGenerated = isGenerated; 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. * 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. * A user could later instantiate a type using the same name that is equivalent to this type.
*
* @return A fresh placeholder type. * @return A fresh placeholder type.
*/ */
public synchronized static PlaceholderType freshPlaceholder() { public synchronized static PlaceholderType freshPlaceholder() {
String name = nextName + (char) (rnd.nextInt(22) + 97); // Returns random char between 'a' and 'z' String name = "gen_" + (char) (rnd.nextInt(22) + 97); // Returns random char between 'a' and 'z'
// Add random chars while the name is in use. // Add random chars while the name is in use.
while(EXISTING_PLACEHOLDERS.contains(name)) { while (EXISTING_PLACEHOLDERS.contains(name)) {
name += (char) (rnd.nextInt(22) + 97); // Returns random char between 'a' and 'z' name += (char) (rnd.nextInt(22) + 97); // Returns random char between 'a' and 'z'
} }
return new PlaceholderType(name, true); 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. * True if this placeholder is auto-generated, false if it is user-generated.
@@ -108,44 +105,42 @@ public final class PlaceholderType extends UnifyType{
return IsGenerated; return IsGenerated;
} }
public void setVariance(int v) {
variance = v;
}
public int getVariance() { public int getVariance() {
return variance; return variance;
} }
public void setVariance(int v) {
variance = v;
}
public void reversVariance() { public void reversVariance() {
if (variance == 1) { if (variance == 1) {
setVariance(-1); setVariance(-1);
} else { } else {
if (variance == -1) { if (variance == -1) {
setVariance(1); setVariance(1);
}}
} }
}
public void setOrCons(byte i) {
orCons = i;
} }
public byte getOrCons() { public byte getOrCons() {
return orCons; return orCons;
} }
public void setOrCons(byte i) {
orCons = i;
}
public Boolean isWildcardable() { public Boolean isWildcardable() {
return wildcardable; return canBeWildcard;
}
public void disableWildcardtable() {
wildcardable = false;
} }
public void enableWildcardtable() { public void disableWildcardable() {
wildcardable = true; canBeWildcard = false;
} }
public void setWildcardtable(Boolean wildcardable) { public void enableWildcardable() {
this.wildcardable = wildcardable; canBeWildcard = true;
} }
public Boolean isInnerType() { public Boolean isInnerType() {
@@ -168,7 +163,7 @@ public final class PlaceholderType extends UnifyType{
@Override @Override
public UnifyType setTypeParams(TypeParams newTp) { public UnifyType setTypeParams(TypeParams newTp) {
return this; // Placeholders never have params. throw new RuntimeException("Placeholders never have params");
} }
@Override @Override
@@ -177,23 +172,23 @@ public final class PlaceholderType extends UnifyType{
} }
@Override @Override
UnifyType apply(Unifier unif) { UnifyType apply(Unifier unifier) {
if(unif.hasSubstitute(this)) { if (unifier.hasSubstitute(this)) {
UnifyType ret = unif.getSubstitute(this);
//PL 2018-05-17 Auskommentierung muesste korrekt sein, //PL 2018-05-17 Auskommentierung muesste korrekt sein,
//bereits in JavaTXComplier Variancen gesetzt werden. //bereits in JavaTXComplier Variancen gesetzt werden.
//ret.accept(new distributeVariance(), this.getVariance()); //ret.accept(new distributeVariance(), this.getVariance());
return ret; return unifier.getSubstitute(this);
} }
return this; return this;
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(!(obj instanceof PlaceholderType)) if (obj instanceof PlaceholderType placeholderObj) {
return false; return placeholderObj.getName().equals(typeName);
}
return ((PlaceholderType) obj).getName().equals(typeName); return false;
} }

View File

@@ -7,8 +7,8 @@ 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 {
@@ -18,15 +18,10 @@ public class ReferenceType extends UnifyType {
private final int hashCode; private final int hashCode;
/** /**
* gibt an, ob der ReferenceType eine generische Typvariable ist * Defines, if the reference type is a generic type variable
*/ */
private final boolean genericTypeVar; private final boolean genericTypeVar;
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
public ReferenceType(String name, Boolean genericTypeVar) { public ReferenceType(String name, Boolean genericTypeVar) {
super(name, new TypeParams()); super(name, new TypeParams());
hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode(); hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode();
@@ -45,7 +40,11 @@ public class ReferenceType extends UnifyType {
genericTypeVar = false; genericTypeVar = false;
} }
public boolean isGenTypeVar () { public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
public boolean isGenTypeVar() {
return genericTypeVar; return genericTypeVar;
} }
@@ -60,10 +59,10 @@ public class ReferenceType extends UnifyType {
} }
@Override @Override
UnifyType apply(Unifier unif) { UnifyType apply(Unifier unifier) {
TypeParams newParams = typeParams.apply(unif); TypeParams newParams = typeParams.apply(unifier);
if(newParams.hashCode() == typeParams.hashCode() && newParams.equals(typeParams)) if (newParams.hashCode() == typeParams.hashCode() && newParams.equals(typeParams))
return this; return this;
return new ReferenceType(typeName, newParams); return new ReferenceType(typeName, newParams);
@@ -71,8 +70,10 @@ public class ReferenceType extends UnifyType {
@Override @Override
public UnifyType setTypeParams(TypeParams newTp) { public UnifyType setTypeParams(TypeParams newTp) {
if(newTp.hashCode() == typeParams.hashCode() && newTp.equals(typeParams)) if (newTp.hashCode() == typeParams.hashCode() && newTp.equals(typeParams)) {
return this; // reduced the amount of objects created // reduced the amount of objects created by reusing this instance
return this;
}
return new ReferenceType(typeName, newTp); return new ReferenceType(typeName, newTp);
} }
@@ -83,17 +84,15 @@ public class ReferenceType extends UnifyType {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(!(obj instanceof ReferenceType)) if (!(obj instanceof ReferenceType referenceObj))
return false; return false;
if(obj.hashCode() != this.hashCode()) if (obj.hashCode() != this.hashCode())
return false; return false;
ReferenceType other = (ReferenceType) obj; if (!referenceObj.getName().equals(typeName))
if(!other.getName().equals(typeName))
return false; return false;
return other.getTypeParams().equals(typeParams); return referenceObj.getTypeParams().equals(typeParams);
} }
} }

View File

@@ -7,22 +7,24 @@ import java.util.Set;
/** /**
* A super wildcard type e.g. ? super Integer. * A super wildcard type e.g. ? super Integer.
*
* @author Florian Steurer * @author Florian Steurer
*/ */
public final class SuperType extends WildcardType { public final class SuperType extends WildcardType {
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
/** /**
* Creates a new instance "? extends superedType" * Creates a new instance "? extends superedType"
*
* @param superedType The type that is supered e.g. Integer in "? super Integer" * @param superedType The type that is supered e.g. Integer in "? super Integer"
*/ */
public SuperType(UnifyType superedType) { public SuperType(UnifyType superedType) {
super("? super " + superedType.getName(), superedType); super("? super " + superedType.getName(), superedType);
} }
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
/** /**
* The type that is supered e.g. Integer in "? super Integer" * The type that is supered e.g. Integer in "? super Integer"
*/ */
@@ -41,8 +43,10 @@ public final class SuperType extends WildcardType {
@Override @Override
public UnifyType setTypeParams(TypeParams newTp) { public UnifyType setTypeParams(TypeParams newTp) {
UnifyType newType = wildcardedType.setTypeParams(newTp); UnifyType newType = wildcardedType.setTypeParams(newTp);
if(newType == wildcardedType) if (newType == wildcardedType) {
return this; // Reduced the amount of objects created // Reduced the amount of objects created by reusing this instance
return this;
}
return new SuperType(wildcardedType.setTypeParams(newTp)); return new SuperType(wildcardedType.setTypeParams(newTp));
} }
@@ -57,10 +61,12 @@ public final class SuperType extends WildcardType {
} }
@Override @Override
UnifyType apply(Unifier unif) { UnifyType apply(Unifier unifier) {
UnifyType newType = wildcardedType.apply(unif); UnifyType newType = wildcardedType.apply(unifier);
if(newType.hashCode() == wildcardedType.hashCode() && newType.equals(wildcardedType)) if (newType.hashCode() == wildcardedType.hashCode() && newType.equals(wildcardedType)) {
return this; // Reduced the amount of objects created // Reduced the amount of objects created by reusing this instance
return this;
}
return new SuperType(newType); return new SuperType(newType);
} }
@@ -75,13 +81,12 @@ public final class SuperType extends WildcardType {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(!(obj instanceof SuperType)) if (!(obj instanceof SuperType superObj))
return false; return false;
if(obj.hashCode() != this.hashCode()) if (obj.hashCode() != this.hashCode())
return false; return false;
SuperType other = (SuperType) obj; return superObj.getSuperedType().equals(wildcardedType);
return other.getSuperedType().equals(wildcardedType);
} }
} }

View File

@@ -5,9 +5,10 @@ import java.util.*;
/** /**
* The generic or non-generic parameters of a type e.g. <T> for List<T> * The generic or non-generic parameters of a type e.g. <T> for List<T>
*
* @author Florian Steurer * @author Florian Steurer
*/ */
public final class TypeParams implements Iterable<UnifyType>{ public final class TypeParams implements Iterable<UnifyType> {
/** /**
* The array which backs the type parameters. * The array which backs the type parameters.
*/ */
@@ -20,13 +21,14 @@ public final class TypeParams implements Iterable<UnifyType>{
/** /**
* Creates a new set of type parameters. * Creates a new set of type parameters.
*
* @param types The type parameters. * @param types The type parameters.
*/ */
public TypeParams(List<UnifyType> types){ public TypeParams(List<UnifyType> types) {
typeParams = new UnifyType[types.size()]; typeParams = new UnifyType[types.size()];
for(int i=0;i<types.size();i++){ for (int i = 0; i < types.size(); i++) {
typeParams[i] = types.get(i); typeParams[i] = types.get(i);
if(types.get(i)==null)throw new NullPointerException(); if (types.get(i) == null) throw new NullPointerException();
} }
// Hashcode calculation is expensive and must be cached. // Hashcode calculation is expensive and must be cached.
@@ -35,6 +37,7 @@ public final class TypeParams implements Iterable<UnifyType>{
/** /**
* Creates a new set of type parameters. * Creates a new set of type parameters.
*
* @param types The type parameters. * @param types The type parameters.
*/ */
public TypeParams(UnifyType... types) { public TypeParams(UnifyType... types) {
@@ -45,7 +48,7 @@ public final class TypeParams implements Iterable<UnifyType>{
} }
/** /**
* True if every parameter in this object is a placeholder type, false otherwise. * @return True if every parameter in this object is a placeholder type, false otherwise.
*/ */
public boolean arePlaceholders() { public boolean arePlaceholders() {
return Arrays.stream(typeParams).allMatch(x -> x instanceof PlaceholderType); return Arrays.stream(typeParams).allMatch(x -> x instanceof PlaceholderType);
@@ -53,6 +56,7 @@ public final class TypeParams implements Iterable<UnifyType>{
/** /**
* Returns the number of the type parameters in this object. * Returns the number of the type parameters in this object.
*
* @return number of type parameters, always positive (including 0). * @return number of type parameters, always positive (including 0).
*/ */
public int size() { public int size() {
@@ -60,7 +64,7 @@ public final class TypeParams implements Iterable<UnifyType>{
} }
/** /**
* Returns true if this object has size() of zero, false otherwise. * @return true if this object has size() of zero, false otherwise.
*/ */
public boolean empty() { public boolean empty() {
return typeParams.length == 0; return typeParams.length == 0;
@@ -68,6 +72,7 @@ public final class TypeParams implements Iterable<UnifyType>{
/** /**
* Applies a unifier to every parameter in this object. * Applies a unifier to every parameter in this object.
*
* @param unif The applied unifier. * @param unif The applied unifier.
* @return A new type parameter object, where the unifier was applied to every parameter. * @return A new type parameter object, where the unifier was applied to every parameter.
*/ */
@@ -80,14 +85,14 @@ public final class TypeParams implements Iterable<UnifyType>{
// 130.000 to 30.000 without a decrease in speed. // 130.000 to 30.000 without a decrease in speed.
boolean isNew = false; boolean isNew = false;
for(int i = 0; i < typeParams.length; i++) { for (int i = 0; i < typeParams.length; i++) {
UnifyType newType = typeParams[i].apply(unif); UnifyType newType = typeParams[i].apply(unif);
newParams[i] = newType; newParams[i] = newType;
if(!isNew && (newType.hashCode() != typeParams[i].hashCode() || !newType.equals(typeParams[i]))) if (!isNew && (newType.hashCode() != typeParams[i].hashCode() || !newType.equals(typeParams[i])))
isNew = true; isNew = true;
} }
if(!isNew) if (!isNew)
return this; return this;
return new TypeParams(newParams); return new TypeParams(newParams);
} }
@@ -97,14 +102,14 @@ public final class TypeParams implements Iterable<UnifyType>{
* contains t (arbitrary depth of recursion), false otherwise. * contains t (arbitrary depth of recursion), false otherwise.
*/ */
public boolean occurs(PlaceholderType t) { public boolean occurs(PlaceholderType t) {
for(UnifyType p : typeParams) for (UnifyType p : typeParams)
if(p instanceof PlaceholderType) {//PL 2018-01-31 dangeling else Problem { ... } eingefuegt. if (p instanceof PlaceholderType) {//PL 2018-01-31 dangeling else Problem { ... } eingefuegt.
if(p.equals(t)) if (p.equals(t))
return true;
} else {
if (p.getTypeParams().occurs(t))
return true; return true;
} }
else {
if(p.getTypeParams().occurs(t))
return true; }
return false; return false;
} }
@@ -131,7 +136,7 @@ public final class TypeParams implements Iterable<UnifyType>{
// Reduce the creation of new objects for less memory // Reduce the creation of new objects for less memory
// Reduced the needed instances of TypeParams in the lambda14-Test from // Reduced the needed instances of TypeParams in the lambda14-Test from
// 150.000 to 130.000 // 150.000 to 130.000
if(t.hashCode() == typeParams[idx].hashCode() && t.equals(typeParams[idx])) if (t.hashCode() == typeParams[idx].hashCode() && t.equals(typeParams[idx]))
return this; return this;
UnifyType[] newparams = Arrays.copyOf(typeParams, typeParams.length); UnifyType[] newparams = Arrays.copyOf(typeParams, typeParams.length);
newparams[idx] = t; newparams[idx] = t;
@@ -150,23 +155,17 @@ public final class TypeParams implements Iterable<UnifyType>{
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(!(obj instanceof TypeParams)) if (!(obj instanceof TypeParams other))
return false; return false;
if(obj.hashCode() != this.hashCode()) if (obj.hashCode() != this.hashCode())
return false; return false;
TypeParams other = (TypeParams) obj; if (other.size() != this.size())
if(other.size() != this.size())
return false; return false;
for(int i = 0; i < this.size(); i++){ for (int i = 0; i < this.size(); i++)
//if(this.get(i) == null) if (!(this.get(i).equals(other.get(i))))
//System.out.print("s");
}
for(int i = 0; i < this.size(); i++)
if(!(this.get(i).equals(other.get(i))))
return false; return false;
return true; return true;
@@ -174,15 +173,15 @@ public final class TypeParams implements Iterable<UnifyType>{
@Override @Override
public String toString() { public String toString() {
String res = ""; StringBuilder res = new StringBuilder();
for(UnifyType t : typeParams) for (UnifyType t : typeParams)
res += t + ","; res.append(t).append(",");
return "<" + res.substring(0, res.length()-1) + ">"; return "<" + res.substring(0, res.length() - 1) + ">";
} }
public Collection<? extends PlaceholderType> getInvolvedPlaceholderTypes() { public Collection<? extends PlaceholderType> getInvolvedPlaceholderTypes() {
ArrayList<PlaceholderType> ret = new ArrayList<>(); ArrayList<PlaceholderType> ret = new ArrayList<>();
for(UnifyType t : typeParams){ for (UnifyType t : typeParams) {
ret.addAll(t.getInvolvedPlaceholderTypes()); ret.addAll(t.getInvolvedPlaceholderTypes());
} }
return ret; return ret;

View File

@@ -9,6 +9,7 @@ import java.util.function.Function;
/** /**
* A set of substitutions (s -> t) that is an applicable function to types and pairs. * A set of substitutions (s -> t) that is an applicable function to types and pairs.
*
* @author Florian Steurer * @author Florian Steurer
*/ */
public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<PlaceholderType, UnifyType>> { public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<PlaceholderType, UnifyType>> {
@@ -16,26 +17,27 @@ public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<P
/** /**
* The set of substitutions that unify a type-term * The set of substitutions that unify a type-term
*/ */
private HashMap<PlaceholderType, UnifyType> substitutions = new HashMap<>(); private final HashMap<PlaceholderType, UnifyType> substitutions = new HashMap<>();
/** /**
* Creates a new instance with a single substitution (source -> target). * Creates a new instance with a single substitution (source -> target).
* @param The type that is replaced *
* @param The type that replaces * @param source The type that is replaced
* @param target The type that replaces
*/ */
public Unifier(PlaceholderType source, UnifyType target) { public Unifier(PlaceholderType source, UnifyType target) {
substitutions.put(source, target); substitutions.put(source, target);
} }
/** /**
* Identity function as an "unifier". * Identity function as a "unifier".
*/ */
protected Unifier() { protected Unifier() {
} }
/** /**
* Creates an unifier that is the identity function (thus has no substitutions). * Creates a unifier that is the identity function (thus has no substitutions).
*/ */
public static Unifier identity() { public static Unifier identity() {
return new Unifier(); return new Unifier();
@@ -43,15 +45,15 @@ public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<P
/** /**
* Adds a substitution to the unifier from (source -> target) * Adds a substitution to the unifier from (source -> target)
* @param The type that is replaced *
* @param The type that replaces * @param source The type that is replaced
* @param target The type that replaces
*/ */
public void add(PlaceholderType source, UnifyType target) { public void add(PlaceholderType source, UnifyType target) {
Unifier tempU = new Unifier(source, target); Unifier tempU = new Unifier(source, target);
// Every new substitution must be applied to previously added substitutions // Every new substitution must be applied to previously added substitutions
// otherwise the unifier needs to be applied multiple times to unify two terms // otherwise the unifier needs to be applied multiple times to unify two terms
for(PlaceholderType pt : substitutions.keySet()) substitutions.replaceAll((p, _) -> substitutions.get(p).apply(tempU));
substitutions.put(pt, substitutions.get(pt).apply(tempU));
substitutions.put(source, target); substitutions.put(source, target);
} }
@@ -62,6 +64,7 @@ public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<P
/** /**
* Applies the unifier to the two terms of the pair. * Applies the unifier to the two terms of the pair.
*
* @return A new pair where the left and right-hand side are applied * @return A new pair where the left and right-hand side are applied
*/ */
public UnifyPair apply(UnifyPair p) { public UnifyPair apply(UnifyPair p) {
@@ -72,82 +75,70 @@ public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<P
/** /**
* Applies the unifier to the two terms of the pair. * Applies the unifier to the two terms of the pair.
* works only for single subsitution * works only for single substitution
*
* @return A new pair where the left and right-hand side are applied * @return A new pair where the left and right-hand side are applied
*/ */
public UnifyPair apply(UnifyPair thisAsPair, UnifyPair p) { public UnifyPair apply(UnifyPair thisAsPair, UnifyPair p) {
UnifyType newLhs = this.apply(p.getLhsType()); UnifyType newLhs = this.apply(p.getLhsType());
UnifyType newRhs = this.apply(p.getRhsType()); UnifyType newRhs = this.apply(p.getRhsType());
//Varianceweitergabe wird nicht benoetigt.
//PlaceholderType lhsph = (PlaceholderType)thisAsPair.getLhsType(); if (!(p.getLhsType().equals(newLhs)) || !(p.getRhsType().equals(newRhs))) {
//if (lhsph.getVariance() != 0) { //Die Anwendung von this hat was veraendert PL 2018-04-01
// if (p.getLhsType().equals(lhsph)) { Set<UnifyPair> sUniUnifyPair = new HashSet<>(thisAsPair.getAllSubstitutions());
// if (p.getRhsType() instanceof PlaceholderType) { sUniUnifyPair.add(thisAsPair);
// ((PlaceholderType)p.getRhsType()).setVariance(lhsph.getVariance()); if (p.getLhsType() instanceof PlaceholderType
// } && p.getPairOp() == PairOperator.EQUALSDOT
// } ) {
// if (p.getRhsType().equals(lhsph)) { sUniUnifyPair.add(p); //p could also be substitution
// if (p.getLhsType() instanceof PlaceholderType) {
// ((PlaceholderType)p.getLhsType()).setVariance(lhsph.getVariance());
// }
// }
//}
if (!(p.getLhsType().equals(newLhs)) || !(p.getRhsType().equals(newRhs))) {//Die Anwendung von this hat was veraendert PL 2018-04-01
Set<UnifyPair> suniUnifyPair = new HashSet<>();
suniUnifyPair.addAll(thisAsPair.getAllSubstitutions());
suniUnifyPair.add(thisAsPair);
if (p.getLhsType() instanceof PlaceholderType //&& newLhs instanceof PlaceholderType entfernt PL 2018-04-13
&& p.getPairOp() == PairOperator.EQUALSDOT) {
suniUnifyPair.add(p); //p koennte auch subsitution sein
} }
return new UnifyPair(newLhs, newRhs, p.getPairOp(), suniUnifyPair, p); return new UnifyPair(newLhs, newRhs, p.getPairOp(), sUniUnifyPair, p);
} }
return new UnifyPair(newLhs, newRhs, p.getPairOp(), p.getSubstitution(), p.getBasePair(), p.getfBounded()); return new UnifyPair(newLhs, newRhs, p.getPairOp(), p.getSubstitution(), p.getBasePair(), p.getFBounded());
} }
/** /**
* Applies the unifier to the left terms of the pair. * Applies the unifier to the left terms of the pair.
*
* @return A new pair where the left and right-hand side are applied * @return A new pair where the left and right-hand side are applied
*/ */
public UnifyPair applyleft(UnifyPair p) { public UnifyPair applyLeft(UnifyPair p) {
return new UnifyPair(this.apply(p.getLhsType()), p.getRhsType(), p.getPairOp()); return new UnifyPair(this.apply(p.getLhsType()), p.getRhsType(), p.getPairOp());
} }
/** /**
* True if the typevariable t will be substituted if the unifier is applied. * @return True if the type variable t will be substituted if the unifier is applied. False otherwise.
* false otherwise.
*/ */
public boolean hasSubstitute(PlaceholderType t) { public boolean hasSubstitute(PlaceholderType t) {
return substitutions.containsKey(t); return substitutions.containsKey(t);
} }
/** /**
* Returns the type that will replace the typevariable t if the unifier is applied. * @return The type that will replace the type variable t if the unifier is applied.
*/ */
public UnifyType getSubstitute(PlaceholderType t) { public UnifyType getSubstitute(PlaceholderType t) {
return substitutions.get(t); return substitutions.get(t);
} }
/** /**
* The number of substitutions in the unifier. If zero, this is the identity function. * @return The number of substitutions in the unifier. If zero, this is the identity function.
*/ */
public int size() { public int size() {
return substitutions.size(); return substitutions.size();
} }
/** /**
* Garantuees that if there is a substitutions (a -> b) in this unifier, * Guarantees that if there is a substitutions (a -> b) in this unifier,
* a is not an element of the targetParams. Substitutions that do not * then a is not an element of the targetParams. Substitutions that do not
* satisfy this condition, are swapped. * satisfy this condition, are swapped.
*/ */
public void swapPlaceholderSubstitutions(Iterable<UnifyType> targetParams) { public void swapPlaceholderSubstitutions(Iterable<UnifyType> targetParams) {
for(UnifyType tph : targetParams) { for (UnifyType tph : targetParams) {
if(!(tph instanceof PlaceholderType)) if (!(tph instanceof PlaceholderType))
continue; continue;
// Swap a substitutions (a -> b) if a is an element of the target params. // Swap a substitutions (a -> b) if a is an element of the target params.
if(substitutions.containsKey(tph)) { if (substitutions.containsKey(tph)) {
if((substitutions.get(tph) instanceof PlaceholderType)) { if ((substitutions.get(tph) instanceof PlaceholderType newLhs)) {
PlaceholderType newLhs = (PlaceholderType) substitutions.get(tph);
substitutions.remove(tph); substitutions.remove(tph);
substitutions.put(newLhs, tph); substitutions.put(newLhs, tph);
} }
@@ -156,12 +147,12 @@ public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<P
} }
public void swapPlaceholderSubstitutionsReverse(Iterable<UnifyType> sourceParams) { public void swapPlaceholderSubstitutionsReverse(Iterable<UnifyType> sourceParams) {
for(UnifyType tph : sourceParams) { for (UnifyType tph : sourceParams) {
if(!(tph instanceof PlaceholderType)) if (!(tph instanceof PlaceholderType))
continue; continue;
if(substitutions.containsValue(tph)) { if (substitutions.containsValue(tph)) {
UnifyType key = substitutions.values().stream().filter(x -> x.equals(tph)).findAny().get(); UnifyType key = substitutions.values().stream().filter(x -> x.equals(tph)).findAny().get();
if(key instanceof PlaceholderType) { if (key instanceof PlaceholderType) {
PlaceholderType newLhs = (PlaceholderType) tph; PlaceholderType newLhs = (PlaceholderType) tph;
substitutions.remove(key); substitutions.remove(key);
substitutions.put(newLhs, key); substitutions.put(newLhs, key);
@@ -173,10 +164,10 @@ public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<P
@Override @Override
public String toString() { public String toString() {
String result = "{ "; String result = "{ ";
for(Entry<PlaceholderType, UnifyType> entry : substitutions.entrySet()) for (Entry<PlaceholderType, UnifyType> entry : substitutions.entrySet())
result += "(" + entry.getKey() + " -> " + entry.getValue() + "), "; result += "(" + entry.getKey() + " -> " + entry.getValue() + "), ";
if(!substitutions.isEmpty()) if (!substitutions.isEmpty())
result = result.substring(0, result.length()-2); result = result.substring(0, result.length() - 2);
result += " }"; result += " }";
return result; return result;
} }

View File

@@ -7,6 +7,7 @@ import java.util.Set;
/** /**
* A pair which contains two types and an operator, e.q. (Integer <. a). * A pair which contains two types and an operator, e.q. (Integer <. a).
*
* @author Florian Steurer * @author Florian Steurer
*/ */
public class UnifyPair { public class UnifyPair {
@@ -20,37 +21,32 @@ public class UnifyPair {
* The type on the right hand side of the pair. * The type on the right hand side of the pair.
*/ */
private final UnifyType rhs; private final UnifyType rhs;
/**
* The operator that determines the relation between the left and right hand side type.
*/
private PairOperator pairOp;
private boolean undefinedPair = false;
/** /**
* Unifier/substitute that generated this pair * Unifier/substitute that generated this pair
* PL 2018-03-15 * PL 2018-03-15
*/ */
private Set<UnifyPair> substitution; private final Set<UnifyPair> substitution;
private final int hashCode;
/** /**
* Base on which the the unifier is applied * The operator that determines the relation between the left and right hand side type.
*/
private PairOperator pairOp;
private boolean undefinedPair = false;
/**
* Base on which the unifier is applied
* PL 2018-03-15 * PL 2018-03-15
*/ */
private UnifyPair basePair; private UnifyPair basePair;
/** /**
* For pairs a <. Theta generated in the rule reduceTphSup * For pairs a <. Theta generated in the rule reduceTphSup
* to store the f-Bouned Elements to avoid endless recursion * to store the f-Bounded Elements to avoid endless recursion
* PL 2018-03-15 * PL 2018-03-15
*/ */
private Set<UnifyType> fBounded = new HashSet<>(); private Set<UnifyType> fBounded = new HashSet<>();
private final int hashCode;
/** /**
* Creates a new instance of the pair. * Creates a new instance of the pair.
*
* @param lhs The type on the left hand side of the pair. * @param lhs The type on the left hand side of the pair.
* @param rhs The type on the right hand side of the pair. * @param rhs The type on the right hand side of the pair.
* @param op The operator that determines the relation between the left and right hand side type. * @param op The operator that determines the relation between the left and right hand side type.
@@ -72,33 +68,31 @@ public class UnifyPair {
substitution = uni; substitution = uni;
basePair = base; basePair = base;
// Caching hashcode // Caching hashcode
hashCode = 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode(); hashCode = 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode();
} }
public UnifyPair(UnifyType lhs, UnifyType rhs, PairOperator op, Set<UnifyPair> uni, UnifyPair base, Set<UnifyType> fBounded) { public UnifyPair(UnifyType lhs, UnifyType rhs, PairOperator op, Set<UnifyPair> uni, UnifyPair base, Set<UnifyType> fBounded) {
this(lhs, rhs, op, uni, base); this(lhs, rhs, op, uni, base);
this.fBounded = fBounded; this.fBounded = fBounded;
} }
/** /**
* Returns the type on the left hand side of the pair. * @return The type on the left hand side of the pair.
*/ */
public UnifyType getLhsType() { public UnifyType getLhsType() {
return lhs; return lhs;
} }
/** /**
* Returns the type on the right hand side of the pair. * @return The type on the right hand side of the pair.
*/ */
public UnifyType getRhsType() { public UnifyType getRhsType() {
return rhs; return rhs;
} }
/** /**
* Returns the operator that determines the relation between the left and right hand side type. * @return The operator that determines the relation between the left and right hand side type.
*/ */
public PairOperator getPairOp() { public PairOperator getPairOp() {
return pairOp; return pairOp;
@@ -115,6 +109,7 @@ public class UnifyPair {
public void setUndefinedPair() { public void setUndefinedPair() {
undefinedPair = true; undefinedPair = true;
} }
public Set<UnifyPair> getSubstitution() { public Set<UnifyPair> getSubstitution() {
return new HashSet<>(substitution); return new HashSet<>(substitution);
} }
@@ -122,25 +117,26 @@ public class UnifyPair {
public UnifyPair getBasePair() { public UnifyPair getBasePair() {
return basePair; return basePair;
} }
public boolean isUndefinedPair() { public boolean isUndefinedPair() {
return undefinedPair; return undefinedPair;
} }
public Set<UnifyPair> getAllSubstitutions () { public Set<UnifyPair> getAllSubstitutions() {
Set<UnifyPair> ret = new HashSet<>(); Set<UnifyPair> ret = new HashSet<>(new ArrayList<>(getSubstitution()));
ret.addAll(new ArrayList<>(getSubstitution()));
if (basePair != null) { if (basePair != null) {
ret.addAll(new ArrayList<>(basePair.getAllSubstitutions())); ret.addAll(new ArrayList<>(basePair.getAllSubstitutions()));
} }
return ret; return ret;
} }
public Set<UnifyPair> getThisAndAllBases () { public Set<UnifyPair> getThisAndAllBases() {
Set<UnifyPair> ret = getAllBases(); Set<UnifyPair> ret = getAllBases();
ret.add(this); ret.add(this);
return ret; return ret;
} }
public Set<UnifyPair> getAllBases () {
public Set<UnifyPair> getAllBases() {
Set<UnifyPair> ret = new HashSet<>(); Set<UnifyPair> ret = new HashSet<>();
if (basePair != null) { if (basePair != null) {
ret.add(getBasePair()); ret.add(getBasePair());
@@ -149,65 +145,62 @@ public class UnifyPair {
return ret; return ret;
} }
public UnifyPair getGroundBasePair () { public UnifyPair getGroundBasePair() {
if (basePair == null) { if (basePair == null) {
return this; return this;
} }
if (basePair.getBasePair() == null) { if (basePair.getBasePair() == null) {
return basePair; return basePair;
} }
else {
return basePair.getGroundBasePair(); return basePair.getGroundBasePair();
} }
}
/** /**
* wenn in einem Paar bestehend aus 2 Typvariablen eine nicht wildcardtable ist, * if a pair of two type variables contains one that can not be replaced by a wildcard, then both
* so beide auf nicht wildcardtable setzen * of them cannot be replaced by a wildcard
*/ */
public void disableCondWildcards() { public void disableCondWildcards() {
if (lhs instanceof PlaceholderType && rhs instanceof PlaceholderType if (!(lhs instanceof PlaceholderType lhsPlaceholder) || !(rhs instanceof PlaceholderType rhsPlaceholder)) {
&& (!((PlaceholderType)lhs).isWildcardable() || !((PlaceholderType)rhs).isWildcardable())) return;
{
((PlaceholderType)lhs).disableWildcardtable();
((PlaceholderType)rhs).disableWildcardtable();
} }
if (!lhsPlaceholder.isWildcardable() || !rhsPlaceholder.isWildcardable()) {
lhsPlaceholder.disableWildcardable();
rhsPlaceholder.disableWildcardable();
}
} }
public Boolean wrongWildcard() { public Boolean wrongWildcard() {
return lhs.wrongWildcard() || rhs.wrongWildcard(); return lhs.wrongWildcard() || rhs.wrongWildcard();
} }
public Set<UnifyType> getfBounded() { public Set<UnifyType> getFBounded() {
return this.fBounded; return this.fBounded;
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(!(obj instanceof UnifyPair)) if (!(obj instanceof UnifyPair unifyPairObj))
return false; return false;
if(obj.hashCode() != this.hashCode()) if (obj.hashCode() != this.hashCode())
return false; return false;
UnifyPair other = (UnifyPair) obj;
if (isUndefinedPair()) { if (isUndefinedPair()) {
if (other.getBasePair() != basePair || (other.getBasePair() == null && basePair == null)) { if (unifyPairObj.getBasePair() != basePair || (unifyPairObj.getBasePair() == null && basePair == null)) {
return false; return false;
} }
if (!other.getBasePair().equals(basePair) || if (!unifyPairObj.getBasePair().equals(basePair) ||
!other.getAllSubstitutions().equals(getAllSubstitutions())) { !unifyPairObj.getAllSubstitutions().equals(getAllSubstitutions())) {
return false; return false;
} }
} }
return unifyPairObj.getPairOp() == pairOp
return other.getPairOp() == pairOp && unifyPairObj.getLhsType().equals(lhs)
&& other.getLhsType().equals(lhs) && unifyPairObj.getRhsType().equals(rhs);
&& other.getRhsType().equals(rhs);
} }
@Override @Override
@@ -218,25 +211,17 @@ public class UnifyPair {
@Override @Override
public String toString() { public String toString() {
String ret = ""; String ret = "";
if (lhs instanceof PlaceholderType) { if (lhs instanceof PlaceholderType lhsPlaceholder) {
ret = new Integer(((PlaceholderType)lhs).getVariance()).toString() + " " ret = lhsPlaceholder.getVariance() + " "
+ "WC: " + ((PlaceholderType)lhs).isWildcardable() + "WC: " + lhsPlaceholder.isWildcardable() + ", "
+ ", IT: " + ((PlaceholderType)lhs).isInnerType(); + "IT: " + lhsPlaceholder.isInnerType();
} }
if (rhs instanceof PlaceholderType) { if (rhs instanceof PlaceholderType rhsPlaceholder) {
ret = ret + ", " + new Integer(((PlaceholderType)rhs).getVariance()).toString() + " " ret = ret + ", " + rhsPlaceholder.getVariance() + " "
+ "WC: " + ((PlaceholderType)rhs).isWildcardable() + "WC: " + rhsPlaceholder.isWildcardable() + ", "
+ ", IT: " + ((PlaceholderType)rhs).isInnerType(); + "IT: " + rhsPlaceholder.isInnerType();
} }
return "(" + lhs + " " + pairOp + " " + rhs + ", " + ret + ")"; //+ ", [" + getfBounded().toString()+ "])"; return "(" + lhs + " " + pairOp + " " + rhs + ", " + ret + ")";
} }
/*
public List<? extends PlaceholderType> getInvolvedPlaceholderTypes() {
ArrayList<PlaceholderType> ret = new ArrayList<>();
ret.addAll(lhs.getInvolvedPlaceholderTypes());
ret.addAll(rhs.getInvolvedPlaceholderTypes());
return ret;
}
*/
} }

View File

@@ -9,6 +9,7 @@ import java.util.Set;
/** /**
* Represents a java type. * Represents a java type.
*
* @author Florian Steurer * @author Florian Steurer
*/ */
public abstract class UnifyType { public abstract class UnifyType {
@@ -25,12 +26,13 @@ public abstract class UnifyType {
/** /**
* Creates a new instance * Creates a new instance
*
* @param name Name of the type (e.q. List for List<T>, Integer or ? extends Integer) * @param name Name of the type (e.q. List for List<T>, Integer or ? extends Integer)
* @param typeParams Parameters of the type (e.q. <T> for List<T>) * @param params Parameters of the type (e.q. <T> for List<T>)
*/ */
protected UnifyType(String name, TypeParams p) { protected UnifyType(String name, TypeParams params) {
typeName = name; typeName = name;
typeParams = p; typeParams = params;
} }
@@ -38,6 +40,7 @@ public abstract class UnifyType {
/** /**
* Returns the name of the type. * Returns the name of the type.
*
* @return The name e.q. List for List<T>, Integer or ? extends Integer * @return The name e.q. List for List<T>, Integer or ? extends Integer
*/ */
public String getName() { public String getName() {
@@ -46,6 +49,7 @@ public abstract class UnifyType {
/** /**
* The parameters of the type. * The parameters of the type.
*
* @return Parameters of the type, e.q. <T> for List<T>. * @return Parameters of the type, e.q. <T> for List<T>.
*/ */
public TypeParams getTypeParams() { public TypeParams getTypeParams() {
@@ -54,6 +58,7 @@ public abstract class UnifyType {
/** /**
* Returns a new type that equals this type except for the type parameters. * Returns a new type that equals this type except for the type parameters.
*
* @param newTp The type params of the new type. * @param newTp The type params of the new type.
* @return A new type object. * @return A new type object.
*/ */
@@ -62,6 +67,7 @@ public abstract class UnifyType {
/** /**
* Implementation of the visitor-pattern. Returns the set of smArg * Implementation of the visitor-pattern. Returns the set of smArg
* by calling the most specific overload in the FC. * by calling the most specific overload in the FC.
*
* @param fc The FC that is called. * @param fc The FC that is called.
* @return The set that is smArg(this) * @return The set that is smArg(this)
*/ */
@@ -70,6 +76,7 @@ public abstract class UnifyType {
/** /**
* Implementation of the visitor-pattern. Returns the set of grArg * Implementation of the visitor-pattern. Returns the set of grArg
* by calling the most specific overload in the FC. * by calling the most specific overload in the FC.
*
* @param fc The FC that is called. * @param fc The FC that is called.
* @return The set that is grArg(this) * @return The set that is grArg(this)
*/ */
@@ -77,27 +84,26 @@ public abstract class UnifyType {
/** /**
* Applies a unifier to this object. * Applies a unifier to this object.
* @param unif The unifier *
* @param unifier The unifier
* @return A UnifyType, that may or may not be a new object, that has its subtypes substituted. * @return A UnifyType, that may or may not be a new object, that has its subtypes substituted.
*/ */
abstract UnifyType apply(Unifier unif); abstract UnifyType apply(Unifier unifier);
@Override @Override
public String toString() { public String toString() {
String params = ""; String params = "";
if(typeParams.size() != 0) { if (typeParams.size() != 0) {
for(UnifyType param : typeParams) for (UnifyType param : typeParams)
params += param.toString() + ","; params += param.toString() + ",";
params = "<" + params.substring(0, params.length()-1) + ">"; params = "<" + params.substring(0, params.length() - 1) + ">";
} }
return typeName + params; return typeName + params;
} }
public Collection<PlaceholderType> getInvolvedPlaceholderTypes() { public Collection<PlaceholderType> getInvolvedPlaceholderTypes() {
ArrayList<PlaceholderType> ret = new ArrayList<>(); return new ArrayList<>(typeParams.getInvolvedPlaceholderTypes());
ret.addAll(typeParams.getInvolvedPlaceholderTypes());
return ret;
} }
public Boolean wrongWildcard() {//default public Boolean wrongWildcard() {//default
@@ -111,7 +117,9 @@ public abstract class UnifyType {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(obj == null)return false; if (!(obj instanceof UnifyType)) {
return false;
}
return this.toString().equals(obj.toString()); return this.toString().equals(obj.toString());
} }
} }

View File

@@ -5,6 +5,7 @@ import java.util.Collection;
/** /**
* A wildcard type that is either a ExtendsType or a SuperType. * A wildcard type that is either a ExtendsType or a SuperType.
*
* @author Florian Steurer * @author Florian Steurer
*/ */
public abstract class WildcardType extends UnifyType { public abstract class WildcardType extends UnifyType {
@@ -16,6 +17,7 @@ public abstract class WildcardType extends UnifyType {
/** /**
* Creates a new instance. * Creates a new instance.
*
* @param name The name of the type, e.q. ? extends Integer * @param name The name of the type, e.q. ? extends Integer
* @param wildcardedType The wildcarded type, e.q. Integer for ? extends Integer. Never a wildcard type itself. * @param wildcardedType The wildcarded type, e.q. Integer for ? extends Integer. Never a wildcard type itself.
*/ */
@@ -26,6 +28,7 @@ public abstract class WildcardType extends UnifyType {
/** /**
* Returns the wildcarded type, e.q. Integer for ? extends Integer. * Returns the wildcarded type, e.q. Integer for ? extends Integer.
*
* @return The wildcarded type. Never a wildcard type itself. * @return The wildcarded type. Never a wildcard type itself.
*/ */
public UnifyType getWildcardedType() { public UnifyType getWildcardedType() {
@@ -33,7 +36,7 @@ public abstract class WildcardType extends UnifyType {
} }
/** /**
* Returns the type parameters of the WILDCARDED TYPE. * Returns the type parameters of the wildcarded type.
*/ */
@Override @Override
public TypeParams getTypeParams() { public TypeParams getTypeParams() {
@@ -41,7 +44,7 @@ public abstract class WildcardType extends UnifyType {
} }
@Override @Override
public Boolean wrongWildcard () {//This is an error public Boolean wrongWildcard() {//This is an error
return (wildcardedType instanceof WildcardType); return (wildcardedType instanceof WildcardType);
} }
@@ -52,21 +55,18 @@ public abstract class WildcardType extends UnifyType {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(!(obj instanceof WildcardType)) if (!(obj instanceof WildcardType wildcardObj))
return false; return false;
if(obj.hashCode() != this.hashCode()) if (obj.hashCode() != this.hashCode())
return false; return false;
WildcardType other = (WildcardType) obj; return wildcardObj.getWildcardedType().equals(wildcardedType);
return other.getWildcardedType().equals(wildcardedType);
} }
@Override @Override
public Collection<PlaceholderType> getInvolvedPlaceholderTypes() { public Collection<PlaceholderType> getInvolvedPlaceholderTypes() {
ArrayList<PlaceholderType> ret = new ArrayList<>(); return new ArrayList<>(wildcardedType.getInvolvedPlaceholderTypes());
ret.addAll(wildcardedType.getInvolvedPlaceholderTypes());
return ret;
} }
} }

View File

@@ -4,16 +4,14 @@ public class hashKeyType {
UnifyType realType; UnifyType realType;
hashKeyType(UnifyType realType) { hashKeyType(UnifyType realType) {
this.realType= realType; this.realType = realType;
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj instanceof hashKeyType) { if (obj instanceof hashKeyType) {
return realType.equals(((hashKeyType)obj).realType); return realType.equals(((hashKeyType) obj).realType);
} } else {
else
{
return false; return false;
} }
} }

View File

@@ -1,47 +0,0 @@
package de.dhbwstuttgart.typeinference.unify;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.HashMap;
import java.util.stream.Collectors;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
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.TypeParams;
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

@@ -2,18 +2,14 @@ package de.dhbwstuttgart.util;
import java.util.ArrayList; import java.util.ArrayList;
public class BiRelation<X,Y> extends ArrayList<Pair<X,Y>>{ public class BiRelation<X, Y> extends ArrayList<Pair<X, Y>> {
public void put(X x, Y y) { public void put(X x, Y y) {
this.add(new Pair<>(x,y)); this.add(new Pair<>(x, y));
} }
public void put(Pair<X,Y> p) { public void put(Pair<X, Y> p) {
this.add(p); this.add(p);
} }
public void putAll(BiRelation<X,Y> br) {
this.addAll(br);
}
} }