forked from i21017/JavaCompilerCore
Compare commits
3 Commits
c0d8dc4692
...
58c3947167
Author | SHA1 | Date | |
---|---|---|---|
|
58c3947167 | ||
|
2b9a9c2732 | ||
|
79c1a69ea3 |
@@ -1,4 +1,3 @@
|
||||
//PL 2018-12-19: typeInferenceOld nach typeInference uebertragen
|
||||
package de.dhbwstuttgart.core;
|
||||
|
||||
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.scope.GenericsRegistry;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.server.SocketClient;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
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.result.ResultSet;
|
||||
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 javax.annotation.Nullable;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
public class JavaTXCompiler {
|
||||
|
||||
//public static JavaTXCompiler INSTANCE;
|
||||
final CompilationEnvironment environment;
|
||||
Boolean useResultModel = true;
|
||||
Optional<String> unificationServer = Optional.empty();
|
||||
@@ -51,18 +43,21 @@ public class JavaTXCompiler {
|
||||
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
|
||||
this(Arrays.asList(sourceFile), null);
|
||||
}
|
||||
|
||||
public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
|
||||
this(sourceFile);
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException {
|
||||
this(sourceFiles, null);
|
||||
}
|
||||
|
||||
public JavaTXCompiler(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 OutputStreamWriter(new NullOutputStream());
|
||||
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
|
||||
contextPath = Lists.newArrayList(new File(System.getProperty("user.dir")));
|
||||
}
|
||||
@@ -73,6 +68,7 @@ public class JavaTXCompiler {
|
||||
}
|
||||
//INSTANCE = this;
|
||||
}
|
||||
|
||||
public JavaTXCompiler(List<File> source, List<File> contextPath, String unificationServer) throws IOException, ClassNotFoundException {
|
||||
this(source, contextPath);
|
||||
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> importedClasses = new ArrayList<>();
|
||||
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
|
||||
for (File forSourceFile : sourceFiles.keySet()){
|
||||
for (File forSourceFile : sourceFiles.keySet()) {
|
||||
for (JavaClassName name : sourceFiles.get(forSourceFile).getImports()) {
|
||||
//TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet
|
||||
ClassOrInterface importedClass = ASTFactory.createClass(
|
||||
classLoader.loadClass(name.toString()));
|
||||
importedClasses.add(importedClass);
|
||||
}
|
||||
for(Class c : CompilationEnvironment.loadDefaultPackageClasses(forSourceFile, classLoader)){
|
||||
for (Class<?> c : CompilationEnvironment.loadDefaultPackageClasses(forSourceFile, classLoader)) {
|
||||
ClassOrInterface importedClass = ASTFactory.createClass(c);
|
||||
importedClasses.add(importedClass);
|
||||
}
|
||||
@@ -120,38 +118,33 @@ public class JavaTXCompiler {
|
||||
ClassOrInterface superclass = null;
|
||||
if (cl.getSuperClass().getName().equals(new JavaClassName("java.lang.Object"))) {
|
||||
superclass = objectClass;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Optional<ClassOrInterface> optSuperclass =
|
||||
importedClasses.stream().filter(x -> x.getClassName().equals(
|
||||
cl.getSuperClass().getName())).findFirst();
|
||||
if (optSuperclass.isPresent()) {
|
||||
superclass = optSuperclass.get();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
optSuperclass =
|
||||
sf.KlassenVektor.stream().filter(x -> x.getClassName().equals(
|
||||
cl.getSuperClass().getName())).findFirst();
|
||||
if (optSuperclass.isPresent()) {
|
||||
superclass = optSuperclass.get();
|
||||
addMethods(sf, superclass, importedClasses, objectClass);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
//throw new ClassNotFoundException("");
|
||||
}
|
||||
}
|
||||
}
|
||||
Iterator<RefTypeOrTPHOrWildcardOrGeneric> paraIt= cl.getSuperClass().getParaList().iterator();
|
||||
Iterator<RefTypeOrTPHOrWildcardOrGeneric> paraIt = cl.getSuperClass().getParaList().iterator();
|
||||
Iterator<GenericTypeVar> tvarVarIt = superclass.getGenerics().iterator();
|
||||
|
||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>();
|
||||
while (paraIt.hasNext()) {
|
||||
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
|
||||
while(methodIt.hasNext()) {
|
||||
Method m = methodIt.next();
|
||||
for (Method m : superclass.getMethods()) {
|
||||
ParameterList newParaList = new ParameterList(
|
||||
m.getParameterList()
|
||||
.getFormalparalist()
|
||||
@@ -160,7 +153,7 @@ public class JavaTXCompiler {
|
||||
.collect(Collectors.toCollection(ArrayList::new)), m.getParameterList().getOffset());
|
||||
cl.getMethods().add(new Method(m.modifier, m.name, m.getReturnType().acceptTV(new TypeExchanger(gtvs)), newParaList, m.block,
|
||||
//new GenericDeclarationList(newGenericsList, ((GenericDeclarationList)m.getGenerics()).getOffset()),
|
||||
(GenericDeclarationList)m.getGenerics(),
|
||||
(GenericDeclarationList) m.getGenerics(),
|
||||
m.getOffset(), true));
|
||||
}
|
||||
|
||||
@@ -169,31 +162,11 @@ public class JavaTXCompiler {
|
||||
}
|
||||
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
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<>();
|
||||
for (JavaClassName name : forSourceFile.getImports()) {
|
||||
@@ -319,11 +292,10 @@ public class JavaTXCompiler {
|
||||
* ResultSet(UnifyTypeFactory.convert(unifyPairs,
|
||||
* generateTPHMap(cons))))).collect(Collectors.toList()); }
|
||||
*/
|
||||
|
||||
/**
|
||||
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine
|
||||
* Variance !=0 hat auf alle Typvariablen in Theta.
|
||||
*
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* private void varianceInheritance(Set<UnifyPair> eq) { Set<PlaceholderType>
|
||||
@@ -350,45 +322,6 @@ public class JavaTXCompiler {
|
||||
* 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 {
|
||||
|
||||
/*
|
||||
@@ -399,7 +332,7 @@ public class JavaTXCompiler {
|
||||
SourceFile sf = sourceFiles.get(f);
|
||||
allClasses.addAll(getAvailableClasses(sf));
|
||||
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...
|
||||
logFile = log ? new FileWriter(System.getProperty("user.dir") + "/logFiles/" + "log_" + sourceFiles.keySet().iterator().next().getName())
|
||||
: new OutputStreamWriter(new NullOutputStream());
|
||||
}
|
||||
catch (IOException ioException) {
|
||||
} catch (IOException ioException) {
|
||||
System.err.println("IO Exception: " + ioException.getMessage());
|
||||
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
|
||||
*/
|
||||
public void generateBytecode(String path) throws ClassNotFoundException, IOException {
|
||||
if(path != null)
|
||||
if (path != null)
|
||||
generateBytecode(new File(path));
|
||||
else
|
||||
generateBytecode();
|
||||
@@ -461,7 +393,7 @@ public class JavaTXCompiler {
|
||||
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
|
||||
public Map<File, List<GenericsResult>> getGeneratedGenerics() {
|
||||
@@ -473,15 +405,14 @@ public class JavaTXCompiler {
|
||||
* @param typeinferenceResult
|
||||
* @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()) {
|
||||
HashMap<JavaClassName, byte[]> classFiles = new HashMap<>();
|
||||
SourceFile sf = sourceFiles.get(f);
|
||||
File path;
|
||||
if(outputPath == null){
|
||||
if (outputPath == null) {
|
||||
path = f.getParentFile(); //Set path to path of the parsed .jav file
|
||||
}else{
|
||||
path = new File(outputPath ,sf.getPkgName().replace(".","/")); //add package path to root path
|
||||
} else {
|
||||
path = new File(outputPath, sf.getPkgName().replace(".", "/")); //add package path to root path
|
||||
}
|
||||
|
||||
var converter = new ASTToTargetAST(typeinferenceResult, sf, classLoader);
|
||||
@@ -521,31 +452,30 @@ public class JavaTXCompiler {
|
||||
}
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
private static class TypeExchanger implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric>{
|
||||
private static class TypeExchanger implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric> {
|
||||
|
||||
private final HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs;
|
||||
|
||||
TypeExchanger(HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs){
|
||||
TypeExchanger(HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs) {
|
||||
this.gtvs = gtvs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){
|
||||
for (RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()) {
|
||||
params.add(param.acceptTV(this));
|
||||
}
|
||||
RefTypeOrTPHOrWildcardOrGeneric ret = new RefType(refType.getName(), params, new NullToken());
|
||||
return ret;
|
||||
return new RefType(refType.getName(), params, new NullToken());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(SuperWildcardType superWildcardType) {
|
||||
SuperWildcardType ret = new SuperWildcardType(superWildcardType.getInnerType().acceptTV(this), superWildcardType.getOffset());
|
||||
return ret;
|
||||
return new SuperWildcardType(superWildcardType.getInnerType().acceptTV(this), superWildcardType.getOffset());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -555,14 +485,13 @@ public class JavaTXCompiler {
|
||||
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(ExtendsWildcardType extendsWildcardType) {
|
||||
ExtendsWildcardType ret = new ExtendsWildcardType(extendsWildcardType.getInnerType().acceptTV(this), extendsWildcardType.getOffset());
|
||||
return ret;
|
||||
return new ExtendsWildcardType(extendsWildcardType.getInnerType().acceptTV(this), extendsWildcardType.getOffset());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) {
|
||||
if(! gtvs.containsKey(genericRefType.getParsedName()))
|
||||
throw new DebugException("Dieser Fall darf nicht auftreten");
|
||||
if (!gtvs.containsKey(genericRefType.getParsedName()))
|
||||
throw new DebugException("Cannot visit unknown generic type variable!");
|
||||
return gtvs.get(genericRefType.getParsedName());
|
||||
}
|
||||
|
||||
|
@@ -1,26 +1,21 @@
|
||||
package de.dhbwstuttgart.server;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.dhbwstuttgart.server.packet.ErrorPacket;
|
||||
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.server.packet.*;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||
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.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.java_websocket.client.WebSocketClient;
|
||||
import org.java_websocket.enums.ReadyState;
|
||||
import org.java_websocket.handshake.ServerHandshake;
|
||||
|
||||
|
||||
/**
|
||||
|
@@ -1,24 +1,21 @@
|
||||
package de.dhbwstuttgart.server;
|
||||
|
||||
import de.dhbwstuttgart.server.packet.IPacket;
|
||||
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.server.packet.*;
|
||||
import de.dhbwstuttgart.typeinference.TypeInference;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
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.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.java_websocket.WebSocket;
|
||||
import org.java_websocket.handshake.ClientHandshake;
|
||||
import org.java_websocket.server.WebSocketServer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SocketServer extends WebSocketServer {
|
||||
|
||||
|
@@ -7,7 +7,6 @@ package de.dhbwstuttgart.server.packet;
|
||||
* - Have only serializable public properties (or disable them via jackson annotations)
|
||||
* A packet should have, for easy usage and consisteny:
|
||||
* - a static create() method
|
||||
*
|
||||
*/
|
||||
public interface IPacket {
|
||||
|
||||
|
@@ -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.
|
||||
* 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 MessagePacket messagePacket = null;
|
||||
|
@@ -3,6 +3,7 @@ package de.dhbwstuttgart.server.packet;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.SerializedResultSet;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
|
@@ -3,6 +3,7 @@ package de.dhbwstuttgart.server.packet.dataContainers;
|
||||
import de.dhbwstuttgart.server.packet.IPacket;
|
||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
||||
|
@@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import de.dhbwstuttgart.server.packet.IPacket;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
@@ -4,13 +4,8 @@ import de.dhbwstuttgart.server.packet.IPacket;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Serializable container of
|
||||
|
@@ -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.SerializedPairTPHsmallerTPH;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.typeinference.result.PairNoResult;
|
||||
import de.dhbwstuttgart.typeinference.result.PairTPHEqualTPH;
|
||||
import de.dhbwstuttgart.typeinference.result.PairTPHequalRefTypeOrWildcardType;
|
||||
import de.dhbwstuttgart.typeinference.result.PairTPHsmallerTPH;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultPair;
|
||||
import de.dhbwstuttgart.typeinference.result.*;
|
||||
|
||||
/**
|
||||
* Serializable container of
|
||||
|
@@ -2,6 +2,7 @@ package de.dhbwstuttgart.server.packet.dataContainers;
|
||||
|
||||
import de.dhbwstuttgart.server.packet.IPacket;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
||||
|
@@ -3,19 +3,9 @@ package de.dhbwstuttgart.server.packet.dataContainers;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import de.dhbwstuttgart.server.packet.IPacket;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.token.SerializedExtendsWildcardType;
|
||||
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.server.packet.dataContainers.token.*;
|
||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
|
||||
/**
|
||||
* Serializable container of
|
||||
|
@@ -4,11 +4,8 @@ import de.dhbwstuttgart.server.packet.IPacket;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Serializable container of
|
||||
|
@@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import de.dhbwstuttgart.server.packet.IPacket;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
||||
|
@@ -3,17 +3,8 @@ package de.dhbwstuttgart.server.packet.dataContainers;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import de.dhbwstuttgart.server.packet.IPacket;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.unifyType.SerializedExtendsType;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.unifyType.SerializedFunNType;
|
||||
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;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.unifyType.*;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.*;
|
||||
|
||||
/**
|
||||
* Serializable container of
|
||||
|
@@ -6,6 +6,7 @@ import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.server.packet.IPacket;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.SerializedTokenWrapper;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
|
@@ -4,6 +4,7 @@ import de.dhbwstuttgart.server.packet.IPacket;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.SerializedUnifyTypeWrapper;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.FunNType;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
|
@@ -5,6 +5,7 @@ import de.dhbwstuttgart.server.packet.IPacket;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.SerializedUnifyTypeWrapper;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
|
@@ -3,6 +3,7 @@ package de.dhbwstuttgart.server.packet.dataContainers.unifyType;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.SerializedUnifyTypeWrapper;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
|
@@ -182,7 +182,7 @@ public class UnifyTypeFactory {
|
||||
if (lhs.getName().equals("AQ")) {
|
||||
System.out.println("");
|
||||
}
|
||||
((PlaceholderType)rhs).enableWildcardtable();
|
||||
((PlaceholderType)rhs).enableWildcardable();
|
||||
}
|
||||
|
||||
if (((rhs = ret.getLhsType()) instanceof PlaceholderType)
|
||||
@@ -191,7 +191,7 @@ public class UnifyTypeFactory {
|
||||
if (rhs.getName().equals("AQ")) {
|
||||
System.out.println("");
|
||||
}
|
||||
((PlaceholderType)lhs).enableWildcardtable();
|
||||
((PlaceholderType)lhs).enableWildcardable();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@@ -1,6 +1,5 @@
|
||||
package de.dhbwstuttgart.typeinference;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.dhbwstuttgart.server.SocketClient;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
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.Pair;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import de.dhbwstuttgart.typeinference.unify.RuleSet;
|
||||
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.UnifyTaskModelParallel;
|
||||
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.UnifyPair;
|
||||
import org.apache.commons.io.output.NullOutputStream;
|
||||
import org.apache.commons.io.output.NullWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
@@ -27,8 +24,6 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
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
|
||||
@@ -64,115 +59,31 @@ public class TypeInference {
|
||||
this.statisticFileWriter = statisticFileWriter;
|
||||
}
|
||||
|
||||
public UnifyResultModelParallel executeAsync(
|
||||
UnifyResultListener resultListener
|
||||
) throws ClassNotFoundException, IOException {
|
||||
|
||||
// generate finite closure
|
||||
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFileWriter, classLoader);
|
||||
logFileWriter.write("FC:\\" + finiteClosure.toString() + "\n");
|
||||
System.out.println(finiteClosure);
|
||||
|
||||
// generate unifyConstraints
|
||||
ConstraintSet<UnifyPair> unifyConstraints = TypeInferenceHelper.constraintsToUnifyConstraints(constraints);
|
||||
logFileWriter.write("\nUnify_distributeInnerVars: " + unifyConstraints.toString());
|
||||
|
||||
TypeUnify unify = new TypeUnify();
|
||||
TypeUnify.statistics = statisticFileWriter;
|
||||
|
||||
Set<String> paraTypeVarNames = new HashSet<>();
|
||||
paraTypeVarNames.addAll(TypeInferenceHelper.methodParaTypeVarNames(allClasses));
|
||||
paraTypeVarNames.addAll(TypeInferenceHelper.constructorParaTypeVarNames(allClasses));
|
||||
|
||||
Set<String> returnAndFieldTypeVarNames = new HashSet<>();
|
||||
returnAndFieldTypeVarNames.addAll(TypeInferenceHelper.returnTypeVarNames(allClasses));
|
||||
returnAndFieldTypeVarNames.addAll(TypeInferenceHelper.fieldTypeVarNames(allClasses));
|
||||
|
||||
|
||||
public static List<ResultSet> executeWithoutContext(
|
||||
IFiniteClosure finiteClosure,
|
||||
ConstraintSet<Pair> constraints,
|
||||
ConstraintSet<UnifyPair> unifyConstraints
|
||||
) {
|
||||
UnifyResultModelParallel urm = new UnifyResultModelParallel(constraints, finiteClosure);
|
||||
urm.addUnifyResultListener(resultListener);
|
||||
TypeUnify.statistics = new NullWriter();
|
||||
|
||||
unifyConstraints = unifyConstraints.map(x -> {
|
||||
// Hier muss ueberlegt werden, ob
|
||||
// 1. alle Argument- und Retuntyp-Variablen in allen UnifyPairs
|
||||
// mit disableWildcardtable() werden.
|
||||
// 2. alle Typvariablen mit Argument- oder Retuntyp-Variablen
|
||||
// in Beziehung auch auf disableWildcardtable() gesetzt werden muessen
|
||||
// PL 2018-04-23
|
||||
if ((x.getLhsType() instanceof PlaceholderType)) {
|
||||
if (paraTypeVarNames.contains(x.getLhsType().getName())) {
|
||||
((PlaceholderType) x.getLhsType()).setVariance((byte) 1);
|
||||
((PlaceholderType) x.getLhsType()).disableWildcardtable();
|
||||
}
|
||||
if (returnAndFieldTypeVarNames.contains(x.getLhsType().getName())) {
|
||||
((PlaceholderType) x.getLhsType()).setVariance((byte) -1);
|
||||
((PlaceholderType) x.getLhsType()).disableWildcardtable();
|
||||
}
|
||||
}
|
||||
if ((x.getRhsType() instanceof PlaceholderType)) {
|
||||
if (paraTypeVarNames.contains(x.getRhsType().getName())) {
|
||||
((PlaceholderType) x.getRhsType()).setVariance((byte) 1);
|
||||
((PlaceholderType) x.getRhsType()).disableWildcardtable();
|
||||
}
|
||||
if (returnAndFieldTypeVarNames.contains(x.getRhsType().getName())) {
|
||||
((PlaceholderType) x.getRhsType()).setVariance((byte) -1);
|
||||
((PlaceholderType) x.getRhsType()).disableWildcardtable();
|
||||
}
|
||||
}
|
||||
return x;// HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE
|
||||
// JEWEILS ANDERE SEITE
|
||||
});
|
||||
Set<PlaceholderType> varianceTPHold;
|
||||
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||
varianceTPH = TypeInferenceHelper.varianceInheritanceConstraintSet(unifyConstraints);
|
||||
|
||||
/*
|
||||
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL
|
||||
* 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen
|
||||
* //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH);
|
||||
* varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y
|
||||
* -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType()
|
||||
* instanceof PlaceholderType)) { if
|
||||
* (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
|
||||
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) {
|
||||
* ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType(
|
||||
* )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0
|
||||
* && ((PlaceholderType)y.getRhsType()).getVariance() != 0) {
|
||||
* ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType(
|
||||
* )).getVariance()); } } return y; } ); } while
|
||||
* (!varianceTPHold.equals(varianceTPH));
|
||||
*/
|
||||
|
||||
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
|
||||
// logFileWriter, log);
|
||||
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
|
||||
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyConstraints.getOderConstraints()/*.stream().map(x -> {
|
||||
Set<Set<UnifyPair>> ret = new HashSet<>();
|
||||
for (Constraint<UnifyPair> y : x) {
|
||||
ret.add(new HashSet<>(y));
|
||||
}
|
||||
return ret;
|
||||
}).collect(Collectors.toCollection(ArrayList::new))*/;
|
||||
|
||||
UnifyTaskModelParallel usedTasks = new UnifyTaskModelParallel();
|
||||
|
||||
unify.unifyAsync(
|
||||
(new TypeUnify()).unifyParallel(
|
||||
unifyConstraints.getUndConstraints(),
|
||||
oderConstraints,
|
||||
unifyConstraints.getOderConstraints(),
|
||||
finiteClosure,
|
||||
logFileWriter,
|
||||
shouldLog,
|
||||
new OutputStreamWriter(new NullOutputStream()),
|
||||
false,
|
||||
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 {
|
||||
// generate finite closure
|
||||
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFileWriter, classLoader);
|
||||
logFileWriter.write("FC:\\" + finiteClosure.toString() + "\n");
|
||||
logFileWriter.write("FC:\\" + finiteClosure + "\n");
|
||||
System.out.println(finiteClosure);
|
||||
|
||||
// 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
|
||||
//und die Typen der Rückgabewerte immer rechts stehen
|
||||
|
||||
/*
|
||||
unifyCons.getOderConstraints().forEach(z -> z.forEach(y -> y.forEach(x -> {
|
||||
if ((x.getLhsType() instanceof PlaceholderType) && x.getPairOp().compareTo(PairOperator.SMALLERDOT) == 0) {
|
||||
((PlaceholderType) x.getLhsType()).setVariance((byte)1);
|
||||
}
|
||||
else if ((x.getRhsType() instanceof PlaceholderType) && x.getPairOp().compareTo(PairOperator.EQUALSDOT) == 0) {
|
||||
((PlaceholderType) x.getRhsType()).setVariance((byte)-1);
|
||||
}
|
||||
})));
|
||||
*/
|
||||
|
||||
System.out.println("Unify nach Oder-Constraints-Anpassung:" + unifyConstraints.toString());
|
||||
Set<PlaceholderType> varianceTPHold;
|
||||
Set<PlaceholderType> varianceTPH = TypeInferenceHelper.varianceInheritanceConstraintSet(unifyConstraints);
|
||||
@@ -228,17 +128,8 @@ public class TypeInference {
|
||||
* (!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();
|
||||
|
||||
List<ResultSet> results;
|
||||
@@ -262,8 +153,7 @@ public class TypeInference {
|
||||
unify,
|
||||
unifyConstraints,
|
||||
oderConstraints,
|
||||
finiteClosure,
|
||||
usedTasks
|
||||
finiteClosure
|
||||
);
|
||||
}
|
||||
|
||||
@@ -280,9 +170,7 @@ public class TypeInference {
|
||||
TypeUnify unify,
|
||||
ConstraintSet<UnifyPair> unifyCons,
|
||||
List<Set<Constraint<UnifyPair>>> oderConstraints,
|
||||
IFiniteClosure finiteClosure,
|
||||
UnifyTaskModelParallel taskModel
|
||||
|
||||
IFiniteClosure finiteClosure
|
||||
) throws IOException {
|
||||
Set<Set<UnifyPair>> result = unify.unifyOderConstraints(
|
||||
unifyCons.getUndConstraints(),
|
||||
@@ -290,29 +178,14 @@ public class TypeInference {
|
||||
finiteClosure,
|
||||
logFileWriter,
|
||||
shouldLog,
|
||||
new UnifyResultModelParallel(constraints, finiteClosure),
|
||||
taskModel
|
||||
new UnifyResultModelParallel(constraints, finiteClosure)
|
||||
);
|
||||
System.out.println("RESULT: " + result);
|
||||
logFileWriter.write("RES: " + result.toString() + "\n");
|
||||
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("Constraints for Generated Generics: " + " ???");
|
||||
logFileWriter.write("RES_FINAL: " + results.toString() + "\n");
|
||||
@@ -332,40 +205,22 @@ public class TypeInference {
|
||||
UnifyTaskModelParallel taskModel
|
||||
) throws IOException {
|
||||
UnifyResultModelParallel urm = new UnifyResultModelParallel(constraints, finiteClosure);
|
||||
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
|
||||
urm.addUnifyResultListener(li);
|
||||
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFileWriter, shouldLog, urm,
|
||||
taskModel);
|
||||
System.out.println("RESULT Final: " + li.getResults());
|
||||
unify.unifyParallel(
|
||||
unifyCons.getUndConstraints(),
|
||||
oderConstraints,
|
||||
finiteClosure,
|
||||
logFileWriter,
|
||||
shouldLog,
|
||||
urm,
|
||||
taskModel
|
||||
);
|
||||
System.out.println("RESULT Final: " + urm.getResults());
|
||||
System.out.println("Constraints for Generated Generics: " + " ???");
|
||||
logFileWriter.write("RES_FINAL: " + li.getResults().toString() + "\n");
|
||||
logFileWriter.write("RESULT_FINAL: " + urm.getResults().toString() + "\n");
|
||||
logFileWriter.flush();
|
||||
statisticFileWriter.close();
|
||||
return li.getResults();
|
||||
}
|
||||
|
||||
public static List<ResultSet> executeWithoutContext(
|
||||
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();
|
||||
return urm.getResults();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -5,23 +5,43 @@ import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
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.UnifyPair;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
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 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) {
|
||||
ConstraintSet<UnifyPair> unifyConstraints = UnifyTypeFactory.convert(constraints);
|
||||
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
|
||||
@@ -35,9 +55,8 @@ public class TypeInferenceHelper {
|
||||
return x;
|
||||
};
|
||||
System.out.println("Unify:" + unifyConstraints.toString());
|
||||
unifyConstraints = unifyConstraints.map(distributeInnerVars);
|
||||
|
||||
return unifyConstraints;
|
||||
return unifyConstraints.map(distributeInnerVars);
|
||||
}
|
||||
|
||||
public static ConstraintSet<UnifyPair> makeFixedPlaceholdersNonWildcardable(
|
||||
@@ -55,25 +74,25 @@ public class TypeInferenceHelper {
|
||||
if ((x.getLhsType() instanceof PlaceholderType)) {
|
||||
if (paraTypeVarNames.contains(x.getLhsType().getName())) {
|
||||
((PlaceholderType) x.getLhsType()).setVariance((byte) 1);
|
||||
((PlaceholderType) x.getLhsType()).disableWildcardtable();
|
||||
((PlaceholderType) x.getLhsType()).disableWildcardable();
|
||||
}
|
||||
if (returnAndFieldTypeVarNames.contains(x.getLhsType().getName())) {
|
||||
((PlaceholderType) x.getLhsType()).setVariance((byte) -1);
|
||||
((PlaceholderType) x.getLhsType()).disableWildcardtable();
|
||||
((PlaceholderType) x.getLhsType()).disableWildcardable();
|
||||
}
|
||||
}
|
||||
if ((x.getRhsType() instanceof PlaceholderType)) {
|
||||
if (paraTypeVarNames.contains(x.getRhsType().getName())) {
|
||||
((PlaceholderType) x.getRhsType()).setVariance((byte) 1);
|
||||
((PlaceholderType) x.getRhsType()).disableWildcardtable();
|
||||
((PlaceholderType) x.getRhsType()).disableWildcardable();
|
||||
}
|
||||
if (returnAndFieldTypeVarNames.contains(x.getRhsType().getName())) {
|
||||
((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
|
||||
// JEWEILS ANDERE SEITE
|
||||
// Hier die jeweils rechte bzw. linke Seite auf die gleiche Varianz setzen, wie die jeweils andere Seite
|
||||
return x;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -89,7 +108,7 @@ public class TypeInferenceHelper {
|
||||
}, (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
})).reduce(new HashSet<String>(), (a, b) -> {
|
||||
})).reduce(new HashSet<>(), (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
});
|
||||
@@ -107,7 +126,7 @@ public class TypeInferenceHelper {
|
||||
}, (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
})).reduce(new HashSet<String>(), (a, b) -> {
|
||||
})).reduce(new HashSet<>(), (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
});
|
||||
@@ -138,8 +157,6 @@ public class TypeInferenceHelper {
|
||||
/**
|
||||
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine
|
||||
* Variance !=0 hat auf alle Typvariablen in Theta.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public static Set<PlaceholderType> varianceInheritanceConstraintSet(ConstraintSet<UnifyPair> cons) {
|
||||
Set<UnifyPair> eq = cons.getAll();
|
||||
@@ -162,7 +179,7 @@ public class TypeInferenceHelper {
|
||||
ArrayList<PlaceholderType> phSetVariance = new ArrayList<>(phSet);
|
||||
phSetVariance.removeIf(x -> (x.getVariance() == 0));
|
||||
while (!phSetVariance.isEmpty()) {
|
||||
PlaceholderType a = phSetVariance.remove(0);
|
||||
PlaceholderType a = phSetVariance.removeFirst();
|
||||
usedTPH.add(a);
|
||||
// HashMap<PlaceholderType,Integer> ht = new HashMap<>();
|
||||
// ht.put(a, a.getVariance());
|
||||
@@ -171,8 +188,8 @@ public class TypeInferenceHelper {
|
||||
// ((PlaceholderType)x.getLhsType()).equals(a)));
|
||||
// durch if-Abfrage im foreach geloest
|
||||
cons.forEach(x -> {
|
||||
if (x.getLhsType() instanceof PlaceholderType && ((PlaceholderType) x.getLhsType()).equals(a)) {
|
||||
x.getRhsType().accept(new distributeVariance(), a.getVariance());
|
||||
if (x.getLhsType() instanceof PlaceholderType && x.getLhsType().equals(a)) {
|
||||
x.getRhsType().accept(new DistributeVariance(), a.getVariance());
|
||||
}
|
||||
});
|
||||
// ` eq1 = new HashSet<>(eq);
|
||||
@@ -180,8 +197,8 @@ public class TypeInferenceHelper {
|
||||
// ((PlaceholderType)x.getRhsType()).equals(a)));
|
||||
// durch if-Abfrage im foreach geloest
|
||||
cons.forEach(x -> {
|
||||
if (x.getRhsType() instanceof PlaceholderType && ((PlaceholderType) x.getRhsType()).equals(a)) {
|
||||
x.getLhsType().accept(new distributeVariance(), a.getVariance());
|
||||
if (x.getRhsType() instanceof PlaceholderType && x.getRhsType().equals(a)) {
|
||||
x.getLhsType().accept(new DistributeVariance(), a.getVariance());
|
||||
}
|
||||
});
|
||||
phSetVariance = new ArrayList<>(phSet); // macht vermutlich keinen Sinn PL 2018-10-18, doch, es koennen neue
|
||||
|
@@ -1,6 +1,5 @@
|
||||
package de.dhbwstuttgart.typeinference.assumptions;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
@@ -13,13 +12,13 @@ import de.dhbwstuttgart.typeinference.constraints.GenericsResolver;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FieldAssumption extends Assumption{
|
||||
private ClassOrInterface receiverClass;
|
||||
private RefTypeOrTPHOrWildcardOrGeneric type;
|
||||
private String name;
|
||||
public class FieldAssumption extends Assumption {
|
||||
private final ClassOrInterface receiverClass;
|
||||
private final RefTypeOrTPHOrWildcardOrGeneric type;
|
||||
private final String name;
|
||||
|
||||
public FieldAssumption(String fieldName, ClassOrInterface receiverType,
|
||||
RefTypeOrTPHOrWildcardOrGeneric type, TypeScope scope){
|
||||
RefTypeOrTPHOrWildcardOrGeneric type, TypeScope scope) {
|
||||
super(scope);
|
||||
this.type = type;
|
||||
this.receiverClass = receiverType;
|
||||
@@ -36,7 +35,7 @@ public class FieldAssumption extends Assumption{
|
||||
|
||||
public RefTypeOrTPHOrWildcardOrGeneric getReceiverType(GenericsResolver resolver) {
|
||||
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
|
||||
GenericRefType genericRefType =
|
||||
new GenericRefType(gtv.getName()
|
||||
|
@@ -7,13 +7,7 @@ import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
||||
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.List;
|
||||
@@ -21,7 +15,7 @@ import java.util.Optional;
|
||||
|
||||
public class FunNClass extends ClassOrInterface {
|
||||
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),
|
||||
ASTFactory.createObjectType(), true, new ArrayList<>(), new NullToken());
|
||||
|
||||
@@ -31,7 +25,7 @@ public class FunNClass extends ClassOrInterface {
|
||||
private static GenericDeclarationList createGenerics(List<GenericRefType> funNParams) {
|
||||
//PL 2018-06-22: so geaendert, dass generierte Generics den Namen der funParams entsprechen.
|
||||
List<GenericTypeVar> generics = new ArrayList<>();
|
||||
for(GenericRefType param : funNParams){
|
||||
for (GenericRefType param : funNParams) {
|
||||
generics.add(new GenericTypeVar(param.getParsedName(),//NameGenerator.makeNewName(),
|
||||
new ArrayList<>(), new NullToken(), new NullToken()));
|
||||
}
|
||||
|
@@ -13,14 +13,14 @@ import de.dhbwstuttgart.typeinference.constraints.GenericsResolver;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MethodAssumption extends Assumption{
|
||||
private ClassOrInterface receiver;
|
||||
private RefTypeOrTPHOrWildcardOrGeneric retType;
|
||||
List<? extends RefTypeOrTPHOrWildcardOrGeneric> params;
|
||||
public class MethodAssumption extends Assumption {
|
||||
private final Boolean isInherited;
|
||||
List<? extends RefTypeOrTPHOrWildcardOrGeneric> params;
|
||||
private final ClassOrInterface receiver;
|
||||
private final 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);
|
||||
this.receiver = receiver;
|
||||
this.retType = retType;
|
||||
@@ -28,14 +28,7 @@ public class MethodAssumption extends Assumption{
|
||||
this.isInherited = isInherited;
|
||||
}
|
||||
|
||||
/*
|
||||
public RefType getReceiverType() {
|
||||
|
||||
return receiver;
|
||||
}
|
||||
*/
|
||||
|
||||
public ClassOrInterface getReceiver(){
|
||||
public ClassOrInterface getReceiver() {
|
||||
return receiver;
|
||||
}
|
||||
|
||||
@@ -43,7 +36,7 @@ public class MethodAssumption extends Assumption{
|
||||
return retType;
|
||||
}
|
||||
|
||||
public List<? extends RefTypeOrTPHOrWildcardOrGeneric> getArgTypes(){
|
||||
public List<? extends RefTypeOrTPHOrWildcardOrGeneric> getArgTypes() {
|
||||
return params;
|
||||
}
|
||||
|
||||
@@ -53,28 +46,24 @@ public class MethodAssumption extends Assumption{
|
||||
|
||||
public List<RefTypeOrTPHOrWildcardOrGeneric> getArgTypes(GenericsResolver resolver) {
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
|
||||
for(RefTypeOrTPHOrWildcardOrGeneric param : params){
|
||||
for (RefTypeOrTPHOrWildcardOrGeneric param : params) {
|
||||
param = resolver.resolve(param);
|
||||
ret.add(param);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param resolver
|
||||
* @return
|
||||
*/
|
||||
|
||||
public RefTypeOrTPHOrWildcardOrGeneric getReceiverType(GenericsResolver resolver) {
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
for(GenericTypeVar gtv : receiver.getGenerics()){
|
||||
for (GenericTypeVar gtv : receiver.getGenerics()) {
|
||||
//Die Generics werden alle zu TPHs umgewandelt.
|
||||
params.add(resolver.resolve(new GenericRefType(gtv.getName(), new NullToken())));
|
||||
}
|
||||
RefTypeOrTPHOrWildcardOrGeneric receiverType;
|
||||
if(receiver instanceof FunNClass){
|
||||
receiverType = new RefType(new JavaClassName(receiver.getClassName().toString()+"$$"), params, new NullToken()); // new FunN(params);
|
||||
}else{
|
||||
if (receiver instanceof FunNClass) {
|
||||
receiverType = new RefType(new JavaClassName(receiver.getClassName().toString() + "$$"), params, new NullToken()); // new FunN(params);
|
||||
} else {
|
||||
receiverType = new RefType(receiver.getClassName(), params, new NullToken());
|
||||
}
|
||||
|
||||
|
@@ -1,22 +1,13 @@
|
||||
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.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.TypeScope;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class TypeInferenceBlockInformation extends TypeInferenceInformation {
|
||||
private TypeScope methodContext;
|
||||
private ClassOrInterface currentClass;
|
||||
private final TypeScope methodContext;
|
||||
private final ClassOrInterface currentClass;
|
||||
|
||||
public TypeInferenceBlockInformation(Collection<ClassOrInterface> availableClasses,
|
||||
ClassOrInterface currentClass, TypeScope methodContext) {
|
||||
@@ -24,12 +15,15 @@ public class TypeInferenceBlockInformation extends TypeInferenceInformation {
|
||||
this.methodContext = new TypeScopeContainer(currentClass, methodContext);
|
||||
this.currentClass = currentClass;
|
||||
}
|
||||
|
||||
public TypeInferenceBlockInformation(TypeInferenceBlockInformation oldScope, TypeScope newScope) {
|
||||
this(oldScope.getAvailableClasses(), oldScope.currentClass, new TypeScopeContainer(oldScope.methodContext, newScope));
|
||||
}
|
||||
|
||||
public ClassOrInterface getCurrentClass() {
|
||||
return currentClass;
|
||||
}
|
||||
|
||||
public TypeScope getCurrentTypeScope() {
|
||||
return methodContext;
|
||||
}
|
||||
|
@@ -1,20 +1,15 @@
|
||||
package de.dhbwstuttgart.typeinference.assumptions;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.Field;
|
||||
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 de.dhbwstuttgart.typeinference.constraints.Constraint;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/*
|
||||
Anmerkung:
|
||||
@@ -27,25 +22,25 @@ Zweiteres hat den Vorteil, dass bei der Entwicklung leichter Dinge hinzugefügt
|
||||
Die ganze Logik steckt in dieser Klasse.
|
||||
*/
|
||||
public class TypeInferenceInformation {
|
||||
private Collection<ClassOrInterface> classes;
|
||||
private final Collection<ClassOrInterface> classes;
|
||||
|
||||
public TypeInferenceInformation(Collection<ClassOrInterface> availableClasses){
|
||||
public TypeInferenceInformation(Collection<ClassOrInterface> availableClasses) {
|
||||
classes = availableClasses;
|
||||
}
|
||||
|
||||
public RefTypeOrTPHOrWildcardOrGeneric checkGTV(RefTypeOrTPHOrWildcardOrGeneric type){
|
||||
if(type instanceof GenericRefType){
|
||||
public RefTypeOrTPHOrWildcardOrGeneric checkGTV(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||
if (type instanceof GenericRefType) {
|
||||
return TypePlaceholder.fresh(new NullToken());
|
||||
}else{
|
||||
} else {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
public List<FieldAssumption> getFields(String name){
|
||||
public List<FieldAssumption> getFields(String name) {
|
||||
List<FieldAssumption> ret = new ArrayList<>();
|
||||
for(ClassOrInterface cl : classes){
|
||||
for(Field m : cl.getFieldDecl()){
|
||||
if(m.getName().equals(name)){
|
||||
for (ClassOrInterface cl : classes) {
|
||||
for (Field m : cl.getFieldDecl()) {
|
||||
if (m.getName().equals(name)) {
|
||||
|
||||
ret.add(new FieldAssumption(name, cl, m.getType(), new TypeScopeContainer(cl, m)));
|
||||
}
|
||||
|
@@ -12,7 +12,8 @@ import java.util.stream.Collectors;
|
||||
public class TypeScopeContainer implements TypeScope {
|
||||
ArrayList<TypeScope> scopes = new ArrayList<>();
|
||||
Stack<RefTypeOrTPHOrWildcardOrGeneric> types = new Stack<>();
|
||||
public TypeScopeContainer(TypeScope scope1, TypeScope scope2){
|
||||
|
||||
public TypeScopeContainer(TypeScope scope1, TypeScope scope2) {
|
||||
scopes.add(scope1);
|
||||
scopes.add(scope2);
|
||||
types.push(scope1.getReturnType());
|
||||
|
@@ -1,21 +1,16 @@
|
||||
package de.dhbwstuttgart.typeinference.constraints;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class Constraint<A> extends HashSet<A> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Boolean isInherited = false;//wird nur für die Method-Constraints benoetigt
|
||||
|
||||
/*
|
||||
* wird verwendet um bei der Codegenerierung die richtige Methoden - Signatur
|
||||
* auszuwaehlen
|
||||
*/
|
||||
/*private*/ Set<A> methodSignatureConstraint = new HashSet<>();
|
||||
|
||||
private Boolean isInherited = false;//wird nur für die Method-Constraints benoetigt
|
||||
private Constraint<A> extendConstraint = null;
|
||||
|
||||
public Constraint() {
|
||||
@@ -59,7 +54,7 @@ public class Constraint<A> extends HashSet<A> {
|
||||
public String toString() {
|
||||
return super.toString() + "\nisInherited = " + isInherited
|
||||
//" + extendsContraint: " + (extendConstraint != null ? extendConstraint.toStringBase() : "null" )
|
||||
+ "\n" ;
|
||||
+ "\n";
|
||||
}
|
||||
|
||||
public String toStringBase() {
|
||||
|
@@ -1,9 +1,7 @@
|
||||
package de.dhbwstuttgart.typeinference.constraints;
|
||||
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.unify.GuavaSetOperations;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BinaryOperator;
|
||||
@@ -15,7 +13,7 @@ public class ConstraintSet<A> {
|
||||
Constraint<A> undConstraints = new Constraint<>();
|
||||
List<Set<Constraint<A>>> oderConstraints = new ArrayList<>();
|
||||
|
||||
public void addUndConstraint(A p){
|
||||
public void addUndConstraint(A p) {
|
||||
undConstraints.add(p);
|
||||
}
|
||||
|
||||
@@ -23,11 +21,11 @@ public class ConstraintSet<A> {
|
||||
oderConstraints.add(methodConstraints);
|
||||
}
|
||||
|
||||
public void addAllUndConstraint(Constraint<A> allUndConstraints){
|
||||
public void addAllUndConstraint(Constraint<A> allUndConstraints) {
|
||||
undConstraints.addAll(allUndConstraints);
|
||||
}
|
||||
|
||||
public void addAllOderConstraint(List<Set<Constraint<A>>> allOderConstraints){
|
||||
public void addAllOderConstraint(List<Set<Constraint<A>>> allOderConstraints) {
|
||||
this.oderConstraints.addAll(allOderConstraints);
|
||||
}
|
||||
|
||||
@@ -37,14 +35,14 @@ public class ConstraintSet<A> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
BinaryOperator<String> b = (x,y) -> x+y;
|
||||
public String toString() {
|
||||
BinaryOperator<String> b = (x, y) -> x + y;
|
||||
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();
|
||||
}
|
||||
|
||||
public Set<List<Constraint<A>>> cartesianProduct(){
|
||||
public Set<List<Constraint<A>>> cartesianProduct() {
|
||||
Set<Constraint<A>> toAdd = new HashSet<>();
|
||||
toAdd.add(undConstraints);
|
||||
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) {
|
||||
Hashtable<Constraint<A>,Constraint<B>> CSA2CSB = new Hashtable<>();
|
||||
Hashtable<Constraint<A>, Constraint<B>> CSA2CSB = new Hashtable<>();
|
||||
ConstraintSet<B> ret = new ConstraintSet<>();
|
||||
ret.undConstraints = undConstraints.stream().map(o).collect(Collectors.toCollection(Constraint<B>::new));
|
||||
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(
|
||||
oderConstraint.parallelStream().map((Constraint<A> as) -> {
|
||||
|
||||
Constraint<B> newConst = as.stream()
|
||||
.map(o)
|
||||
.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.getmethodSignatureConstraint().stream().map(o).collect(Collectors.toCollection(HashSet::new)))
|
||||
: () -> new Constraint<B> (as.isInherited())
|
||||
: () -> new Constraint<B>(as.isInherited())
|
||||
));
|
||||
|
||||
//CSA2CSB.put(as, newConst);
|
||||
@@ -101,18 +99,18 @@ public class ConstraintSet<A> {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void forEach (Consumer<? super A> c) {
|
||||
public void forEach(Consumer<? super A> c) {
|
||||
undConstraints.stream().forEach(c);
|
||||
for(Set<Constraint<A>> oderConstraint : oderConstraints){
|
||||
for (Set<Constraint<A>> oderConstraint : oderConstraints) {
|
||||
oderConstraint.parallelStream().forEach((Constraint<A> as) ->
|
||||
as.stream().forEach(c));
|
||||
}
|
||||
}
|
||||
|
||||
public Set<A> getAll () {
|
||||
public Set<A> getAll() {
|
||||
Set<A> ret = new HashSet<>();
|
||||
ret.addAll(undConstraints);
|
||||
for(Set<Constraint<A>> oderConstraint : oderConstraints){
|
||||
for (Set<Constraint<A>> oderConstraint : oderConstraints) {
|
||||
oderConstraint.parallelStream().forEach((Constraint<A> as) -> ret.addAll(as));
|
||||
}
|
||||
return ret;
|
||||
|
@@ -1,14 +1,11 @@
|
||||
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.TypePlaceholder;
|
||||
|
||||
/**
|
||||
* Wird für Generics benötigt
|
||||
* TODO: Erklörung!
|
||||
*/
|
||||
public interface GenericsResolver {
|
||||
public RefTypeOrTPHOrWildcardOrGeneric resolve(RefTypeOrTPHOrWildcardOrGeneric generic);
|
||||
RefTypeOrTPHOrWildcardOrGeneric resolve(RefTypeOrTPHOrWildcardOrGeneric generic);
|
||||
}
|
||||
|
@@ -1,15 +1,15 @@
|
||||
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.TypePlaceholder;
|
||||
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 TA2;
|
||||
|
||||
@@ -17,42 +17,52 @@ public class Pair implements Serializable
|
||||
private Boolean noUnification = false;
|
||||
|
||||
|
||||
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2 )
|
||||
{
|
||||
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2) {
|
||||
this.TA1 = TA1;
|
||||
this.TA2 = TA2;
|
||||
if(TA1 == null || TA2 == null)
|
||||
if (TA1 == null || TA2 == null)
|
||||
throw new NullPointerException();
|
||||
eOperator = PairOperator.SMALLER;
|
||||
}
|
||||
|
||||
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp)
|
||||
{
|
||||
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp) {
|
||||
// Konstruktor
|
||||
this(TA1,TA2);
|
||||
this(TA1, TA2);
|
||||
this.eOperator = eOp;
|
||||
}
|
||||
|
||||
|
||||
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp, Boolean noUnification)
|
||||
{
|
||||
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp, Boolean noUnification) {
|
||||
// Konstruktor
|
||||
this(TA1,TA2);
|
||||
this(TA1, TA2);
|
||||
this.eOperator = eOp;
|
||||
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
|
||||
String strElement1 = "NULL";
|
||||
String strElement2 = "NULL";
|
||||
String Operator = "<.";
|
||||
|
||||
if( TA1 != null )
|
||||
if (TA1 != null)
|
||||
strElement1 = TA1.toString();
|
||||
|
||||
if( TA2 != null )
|
||||
if (TA2 != null)
|
||||
strElement2 = TA2.toString();
|
||||
|
||||
/* PL ausskommentiert 2018-05-24
|
||||
@@ -71,16 +81,16 @@ public class Pair implements Serializable
|
||||
|
||||
/**
|
||||
* <br/>Author: J�rg B�uerle
|
||||
*
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
public boolean equals(Object obj) {
|
||||
boolean ret = true;
|
||||
ret &= (obj instanceof Pair);
|
||||
if(!ret)return ret;
|
||||
ret &= ((Pair)obj).TA1.equals(this.TA1);
|
||||
ret &= ((Pair)obj).TA2.equals(this.TA2);
|
||||
if (!ret) return ret;
|
||||
ret &= ((Pair) obj).TA1.equals(this.TA1);
|
||||
ret &= ((Pair) obj).TA2.equals(this.TA2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -88,8 +98,7 @@ public class Pair implements Serializable
|
||||
* Author: Arne Lüdtke<br/>
|
||||
* Abfrage, ob Operator vom Typ Equal ist.
|
||||
*/
|
||||
public boolean OperatorEqual()
|
||||
{
|
||||
public boolean OperatorEqual() {
|
||||
return eOperator == PairOperator.EQUALSDOT;
|
||||
}
|
||||
|
||||
@@ -97,8 +106,7 @@ public class Pair implements Serializable
|
||||
* Author: Arne Lüdtke<br/>
|
||||
* Abfrage, ob Operator vom Typ Smaller ist.
|
||||
*/
|
||||
public boolean OperatorSmaller()
|
||||
{
|
||||
public boolean OperatorSmaller() {
|
||||
return eOperator == PairOperator.SMALLER;
|
||||
}
|
||||
|
||||
@@ -106,8 +114,7 @@ public class Pair implements Serializable
|
||||
* Author: Arne Lüdtke<br/>
|
||||
* Abfrage, ob Operator vom Typ SmallerExtends ist.
|
||||
*/
|
||||
public boolean OperatorSmallerExtends()
|
||||
{
|
||||
public boolean OperatorSmallerExtends() {
|
||||
return eOperator == PairOperator.SMALLERDOTWC;
|
||||
}
|
||||
|
||||
@@ -115,28 +122,12 @@ public class Pair implements Serializable
|
||||
* Author: Arne Lüdtke<br/>
|
||||
* Gibt den Operator zurück.
|
||||
*/
|
||||
public PairOperator GetOperator()
|
||||
{
|
||||
public PairOperator GetOperator() {
|
||||
return eOperator;
|
||||
}
|
||||
|
||||
public boolean OperatorSmallerDot() {
|
||||
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
|
||||
|
@@ -1,6 +1,5 @@
|
||||
package de.dhbwstuttgart.typeinference.result;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
|
||||
@@ -13,15 +12,9 @@ public class GenericInsertPair {
|
||||
TA2 = superType;
|
||||
}
|
||||
|
||||
public GenericInsertPair(Pair pair) {
|
||||
TA1 = (TypePlaceholder) pair.TA1;
|
||||
TA2 = (TypePlaceholder) pair.TA2;
|
||||
}
|
||||
|
||||
public boolean contains(TypePlaceholder additionalTPH) {
|
||||
if(TA1.equals(additionalTPH))return true;
|
||||
if(TA2.equals(additionalTPH))return true;
|
||||
return false;
|
||||
if (TA1.equals(additionalTPH)) return true;
|
||||
return TA2.equals(additionalTPH);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -2,24 +2,15 @@ package de.dhbwstuttgart.typeinference.result;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
|
||||
/**
|
||||
* enthaelt alle Paare, die in einem Ergebnis nicht vorkommen koennen
|
||||
* sie sind noetig fuer origPairs in PairTPHsmallerTPH, da hier auch
|
||||
* Paare vorkommen koennen die keine Result sind (z.B. bei FunN$$)
|
||||
* Contains all pairs, that cannot be in a result.
|
||||
* They are required for origPairs in PairTPHsmallerTPH, because there can
|
||||
* be pairs as well, that are no results (e.g. FunN$$)
|
||||
*/
|
||||
public class PairNoResult extends ResultPair<RefTypeOrTPHOrWildcardOrGeneric, RefTypeOrTPHOrWildcardOrGeneric>{
|
||||
//public final TypePlaceholder left;
|
||||
//public final TypePlaceholder right;
|
||||
public class PairNoResult extends ResultPair<RefTypeOrTPHOrWildcardOrGeneric, RefTypeOrTPHOrWildcardOrGeneric> {
|
||||
|
||||
/*
|
||||
* urspruengliches Paar aus diesem dieses Resultpair erzeugt wurde
|
||||
* wichtig fuer generated Generics
|
||||
*/
|
||||
ResultPair origPair;
|
||||
|
||||
public PairNoResult(RefTypeOrTPHOrWildcardOrGeneric left, RefTypeOrTPHOrWildcardOrGeneric right){
|
||||
public PairNoResult(RefTypeOrTPHOrWildcardOrGeneric left, RefTypeOrTPHOrWildcardOrGeneric right) {
|
||||
super(left, right);
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,5 @@
|
||||
package de.dhbwstuttgart.typeinference.result;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
|
||||
public class PairTPHEqualTPH extends ResultPair<TypePlaceholder, TypePlaceholder> {
|
||||
|
@@ -1,17 +1,16 @@
|
||||
package de.dhbwstuttgart.typeinference.result;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
|
||||
/**
|
||||
* Steht für A =. RefType
|
||||
*/
|
||||
public class PairTPHequalRefTypeOrWildcardType extends ResultPair{
|
||||
public class PairTPHequalRefTypeOrWildcardType extends ResultPair<TypePlaceholder, RefTypeOrTPHOrWildcardOrGeneric> {
|
||||
public final TypePlaceholder left;
|
||||
public final RefTypeOrTPHOrWildcardOrGeneric right;
|
||||
|
||||
public PairTPHequalRefTypeOrWildcardType(TypePlaceholder left, RefTypeOrTPHOrWildcardOrGeneric right){
|
||||
public PairTPHequalRefTypeOrWildcardType(TypePlaceholder left, RefTypeOrTPHOrWildcardOrGeneric right) {
|
||||
super(left, right);
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
|
@@ -6,23 +6,26 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
/**
|
||||
* Steht für: A <. B
|
||||
*/
|
||||
public class PairTPHsmallerTPH extends ResultPair{
|
||||
public class PairTPHsmallerTPH extends ResultPair<TypePlaceholder, TypePlaceholder> {
|
||||
public final TypePlaceholder left;
|
||||
public final TypePlaceholder right;
|
||||
|
||||
/*
|
||||
* urspruengliches Paar aus diesem dieses Resultpair erzeugt wurde
|
||||
* wichtig fuer generated Generics
|
||||
/**
|
||||
* the original pair from which this result pair was generated. Important for 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);
|
||||
this.left = left;
|
||||
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.origPair = origPair;
|
||||
}
|
||||
|
@@ -1,27 +1,20 @@
|
||||
package de.dhbwstuttgart.typeinference.result;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class ResolvedType{
|
||||
public class ResolvedType {
|
||||
public final RefTypeOrTPHOrWildcardOrGeneric resolvedType;
|
||||
private ResultPair<?, ?> resultPair;
|
||||
|
||||
public final RefTypeOrTPHOrWildcardOrGeneric resolvedType;
|
||||
//public final Set<GenericInsertPair> additionalGenerics;
|
||||
|
||||
public ResolvedType(RefTypeOrTPHOrWildcardOrGeneric resolvedType, Set<GenericInsertPair> additionalGenerics){
|
||||
public ResolvedType(RefTypeOrTPHOrWildcardOrGeneric resolvedType) {
|
||||
this.resolvedType = resolvedType;
|
||||
//this.additionalGenerics = additionalGenerics;
|
||||
}
|
||||
|
||||
public void setResultPair(ResultPair<?, ?> resultPair) {
|
||||
this.resultPair = resultPair;
|
||||
}
|
||||
|
||||
public ResultPair<?, ?> getResultPair() {
|
||||
return resultPair;
|
||||
}
|
||||
|
||||
public void setResultPair(ResultPair<?, ?> resultPair) {
|
||||
this.resultPair = resultPair;
|
||||
}
|
||||
}
|
||||
|
@@ -5,17 +5,17 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
/**
|
||||
* 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 B right;
|
||||
|
||||
public abstract void accept(ResultPairVisitor visitor);
|
||||
|
||||
public ResultPair(A left, B right){
|
||||
public ResultPair(A left, B right) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
public abstract void accept(ResultPairVisitor visitor);
|
||||
|
||||
public A getLeft() {
|
||||
return left;
|
||||
}
|
||||
@@ -45,18 +45,15 @@ public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B ext
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
ResultPair<?,?> other = (ResultPair<?,?>) obj;
|
||||
ResultPair<?, ?> other = (ResultPair<?, ?>) obj;
|
||||
if (left == null) {
|
||||
if (other.left != null)
|
||||
return false;
|
||||
} else if (!left.getOffset().equals(other.left.getOffset()))
|
||||
return false;
|
||||
if (right == null) {
|
||||
if (other.right != null)
|
||||
return false;
|
||||
} else if (!right.getOffset().equals(other.right.getOffset()))
|
||||
return false;
|
||||
return true;
|
||||
return other.right == null;
|
||||
} else return right.getOffset().equals(other.right.getOffset());
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -2,7 +2,9 @@ package de.dhbwstuttgart.typeinference.result;
|
||||
|
||||
public interface ResultPairVisitor {
|
||||
void visit(PairTPHsmallerTPH p);
|
||||
|
||||
void visit(PairTPHequalRefTypeOrWildcardType p);
|
||||
|
||||
void visit(PairTPHEqualTPH p);
|
||||
|
||||
//bisher nicht umgesetzt
|
||||
|
@@ -1,26 +1,25 @@
|
||||
package de.dhbwstuttgart.typeinference.result;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
|
||||
import java.util.HashSet;
|
||||
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")
|
||||
public class ResultSet {
|
||||
|
||||
public final Set<ResultPair> results;
|
||||
public Set<ResultPair<TypePlaceholder, TypePlaceholder>> genIns;
|
||||
|
||||
public ResultSet(Set<ResultPair> set){
|
||||
public ResultSet(Set<ResultPair> set) {
|
||||
this.results = set;
|
||||
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) {
|
||||
@@ -32,13 +31,13 @@ public class ResultSet {
|
||||
}
|
||||
|
||||
public ResolvedType resolveType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||
if(type instanceof TypePlaceholder)
|
||||
return new Resolver(this).resolve((TypePlaceholder)type);
|
||||
if(type instanceof GenericRefType)return new ResolvedType(type, new HashSet<>());
|
||||
if(type instanceof RefType) {
|
||||
if (type instanceof TypePlaceholder)
|
||||
return new Resolver(this).resolve((TypePlaceholder) type);
|
||||
if (type instanceof GenericRefType) return new ResolvedType(type);
|
||||
if (type instanceof RefType) {
|
||||
RelatedTypeWalker related = new RelatedTypeWalker(null, this);
|
||||
type.accept(related);
|
||||
return new ResolvedType(type, related.relatedTPHs);
|
||||
return new ResolvedType(type);
|
||||
} else {
|
||||
throw new NotImplementedException();
|
||||
//return new ResolvedType(type,new HashSet<>());
|
||||
@@ -51,8 +50,7 @@ public class ResultSet {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof ResultSet) {
|
||||
ResultSet other = (ResultSet)o;
|
||||
if (o instanceof ResultSet other) {
|
||||
return this.results.equals(other.results);
|
||||
} else {
|
||||
return false;
|
||||
@@ -67,34 +65,34 @@ public class ResultSet {
|
||||
|
||||
class Resolver implements ResultSetVisitor {
|
||||
private final ResultSet result;
|
||||
private final Set<GenericInsertPair> additionalTPHs = new HashSet<>();
|
||||
private TypePlaceholder toResolve;
|
||||
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;
|
||||
}
|
||||
|
||||
public ResolvedType resolve(TypePlaceholder tph){
|
||||
public ResolvedType resolve(TypePlaceholder tph) {
|
||||
toResolve = tph;
|
||||
resolved = null;
|
||||
System.out.println(tph.toString());
|
||||
for(ResultPair<?,?> resultPair : result.results) {
|
||||
if(resultPair instanceof PairTPHEqualTPH && ((PairTPHEqualTPH) resultPair).getLeft().equals(toResolve)){
|
||||
for (ResultPair<?, ?> resultPair : result.results) {
|
||||
if (resultPair instanceof PairTPHEqualTPH && ((PairTPHEqualTPH) resultPair).getLeft().equals(toResolve)) {
|
||||
currentPair = resultPair;
|
||||
return resolve(((PairTPHEqualTPH) resultPair).getRight());
|
||||
}
|
||||
}
|
||||
for(ResultPair<?,?> resultPair : result.results){
|
||||
for (ResultPair<?, ?> resultPair : result.results) {
|
||||
currentPair = resultPair;
|
||||
resultPair.accept(this);
|
||||
}
|
||||
if(resolved==null){//TPH kommt nicht im Result vor:
|
||||
if (resolved == null) {//TPH kommt nicht im Result vor:
|
||||
resolved = tph;
|
||||
}
|
||||
|
||||
ResolvedType result = new ResolvedType(resolved, additionalTPHs);//resolved;
|
||||
ResolvedType result = new ResolvedType(resolved); //resolved;
|
||||
result.setResultPair(currentPair);
|
||||
return result;
|
||||
}
|
||||
@@ -102,18 +100,18 @@ class Resolver implements ResultSetVisitor {
|
||||
@Override
|
||||
public void visit(PairTPHsmallerTPH p) {
|
||||
currentPair = p;
|
||||
if(p.left.equals(toResolve)){
|
||||
if (p.left.equals(toResolve)) {
|
||||
additionalTPHs.add(new GenericInsertPair(p.left, p.right));
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(PairTPHequalRefTypeOrWildcardType p) {
|
||||
currentPair = p;
|
||||
if(p.left.equals(toResolve)){
|
||||
if (p.left.equals(toResolve)) {
|
||||
resolved = p.right;
|
||||
RelatedTypeWalker related = new RelatedTypeWalker(null, result);
|
||||
p.right.accept(related);
|
||||
@@ -152,7 +150,6 @@ class Resolver implements ResultSetVisitor {
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,23 +159,23 @@ class Resolver implements ResultSetVisitor {
|
||||
class TPHResolver implements ResultSetVisitor {
|
||||
|
||||
private final TypePlaceholder tph;
|
||||
Set<GenericInsertPair> resolved = new HashSet<>();
|
||||
private final ResultSet resultSet;
|
||||
Set<GenericInsertPair> resolved = new HashSet<>();
|
||||
|
||||
TPHResolver(TypePlaceholder tph, ResultSet resultSet){
|
||||
TPHResolver(TypePlaceholder tph, ResultSet resultSet) {
|
||||
this.resultSet = resultSet;
|
||||
this.tph = tph;
|
||||
for(ResultPair p : resultSet.results){
|
||||
for (ResultPair p : resultSet.results) {
|
||||
p.accept(this);
|
||||
}
|
||||
if(resolved.size() == 0){
|
||||
if (resolved.isEmpty()) {
|
||||
resolved.add(new GenericInsertPair(tph, null));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -186,10 +183,10 @@ class TPHResolver implements ResultSetVisitor {
|
||||
@Override
|
||||
public void visit(PairTPHequalRefTypeOrWildcardType p) {
|
||||
TypePlaceholder otherSide = null;
|
||||
if(p.right.equals(tph)){
|
||||
if (p.right.equals(tph)) {
|
||||
otherSide = p.left;
|
||||
}
|
||||
if(otherSide != null){
|
||||
if (otherSide != null) {
|
||||
Set<ResultPair> newResultSet = new HashSet<>(this.resultSet.results);
|
||||
newResultSet.remove(p);
|
||||
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
|
||||
*
|
||||
* @param start - kann null sein, wenn der Walker für einen RefType benutzt wird
|
||||
* @param resultSet
|
||||
*/
|
||||
RelatedTypeWalker(TypePlaceholder start, ResultSet resultSet){
|
||||
RelatedTypeWalker(TypePlaceholder start, ResultSet resultSet) {
|
||||
this.toResolve = start;
|
||||
this.resultSet = resultSet;
|
||||
int resolved = 0;
|
||||
do{
|
||||
do {
|
||||
resolved = relatedTPHs.size();
|
||||
for(ResultPair p : resultSet.results){
|
||||
for (ResultPair p : resultSet.results) {
|
||||
p.accept(this);
|
||||
p.accept(this);
|
||||
}
|
||||
}while(resolved - relatedTPHs.size() > 0);
|
||||
} while (resolved - relatedTPHs.size() > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
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 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 RelatedTypeWalker(p.left, resultSet).relatedTPHs);
|
||||
}
|
||||
@@ -266,7 +264,7 @@ class RelatedTypeWalker implements ResultSetVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(PairTPHequalRefTypeOrWildcardType p) {
|
||||
if(p.getLeft().equals(toResolve)){
|
||||
if (p.getLeft().equals(toResolve)) {
|
||||
p.getRight().accept(this);
|
||||
}
|
||||
}
|
||||
@@ -283,7 +281,7 @@ class RelatedTypeWalker implements ResultSetVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(RefType refType) {
|
||||
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){
|
||||
for (RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()) {
|
||||
param.accept(this);
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@ package de.dhbwstuttgart.typeinference.result;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
|
||||
public interface ResultSetVisitor extends ResultPairVisitor{
|
||||
public interface ResultSetVisitor extends ResultPairVisitor {
|
||||
|
||||
void visit(RefType refType);
|
||||
|
||||
|
@@ -1,6 +1,5 @@
|
||||
package de.dhbwstuttgart.typeinference.typeAlgo;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
import de.dhbwstuttgart.typeinference.constraints.GenericsResolver;
|
||||
|
||||
@@ -9,9 +8,9 @@ import java.util.HashMap;
|
||||
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<>();
|
||||
|
||||
@@ -23,11 +22,10 @@ public class GenericsResolverSameName implements GenericsResolver, TypeVisitor<R
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){
|
||||
for (RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()) {
|
||||
params.add(param.acceptTV(this));
|
||||
}
|
||||
RefType ret = new RefType(refType.getName(), params, refType.getOffset());
|
||||
return ret;
|
||||
return new RefType(refType.getName(), params, refType.getOffset());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,7 +46,7 @@ public class GenericsResolverSameName implements GenericsResolver, TypeVisitor<R
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) {
|
||||
String name = genericRefType.getParsedName();
|
||||
if(!map.containsKey(name)){
|
||||
if (!map.containsKey(name)) {
|
||||
map.put(name, TypePlaceholder.fresh(genericRefType.getOffset()));
|
||||
}
|
||||
return map.get(name);
|
||||
|
@@ -1,46 +1,45 @@
|
||||
package de.dhbwstuttgart.typeinference.typeAlgo;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.Constructor;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
|
||||
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 {
|
||||
|
||||
private final Collection<SourceFile> sfs;
|
||||
private final TypeInferenceInformation typeInferenceInformation;
|
||||
|
||||
public TYPE(Collection<SourceFile> sourceFiles, Collection<ClassOrInterface> allAvailableClasses){
|
||||
public TYPE(Collection<SourceFile> sourceFiles, Collection<ClassOrInterface> allAvailableClasses) {
|
||||
sfs = sourceFiles;
|
||||
this.typeInferenceInformation = new TypeInferenceInformation(allAvailableClasses);
|
||||
}
|
||||
|
||||
public ConstraintSet getConstraints() {
|
||||
ConstraintSet ret = new ConstraintSet();
|
||||
for(SourceFile sf : sfs)
|
||||
public ConstraintSet<Pair> getConstraints() {
|
||||
ConstraintSet<Pair> ret = new ConstraintSet<>();
|
||||
for (SourceFile sf : sfs)
|
||||
for (ClassOrInterface cl : sf.KlassenVektor) {
|
||||
ret.addAll(getConstraintsClass(cl ,typeInferenceInformation));
|
||||
ret.addAll(getConstraintsClass(cl, typeInferenceInformation));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private ConstraintSet getConstraintsClass(ClassOrInterface cl, TypeInferenceInformation info) {
|
||||
ConstraintSet ret = new ConstraintSet();
|
||||
ConstraintSet methConstrains;
|
||||
for(Method m : cl.getMethods()){
|
||||
ret.addAll(methConstrains = getConstraintsMethod(m,info, cl));
|
||||
private ConstraintSet<Pair> getConstraintsClass(ClassOrInterface cl, TypeInferenceInformation info) {
|
||||
ConstraintSet<Pair> ret = new ConstraintSet<>();
|
||||
|
||||
for (Method m : cl.getMethods()) {
|
||||
ConstraintSet<Pair> methConstrains = getConstraintsMethod(m, info, cl);
|
||||
ret.addAll(methConstrains);
|
||||
m.constraints.addAll(methConstrains);
|
||||
}
|
||||
for(Constructor m : cl.getConstructors()){
|
||||
ret.addAll(getConstraintsConstructor(m,info, cl));
|
||||
for (Constructor m : cl.getConstructors()) {
|
||||
ret.addAll(getConstraintsConstructor(m, info, cl));
|
||||
}
|
||||
if (cl.getfieldInitializations().isPresent()) {
|
||||
ret.addAll(getConstraintsConstructor(cl.getfieldInitializations().get(), info, cl));
|
||||
@@ -69,19 +68,19 @@ public class TYPE {
|
||||
}
|
||||
*/
|
||||
|
||||
private ConstraintSet getConstraintsMethod(Method m, TypeInferenceInformation info, ClassOrInterface currentClass) {
|
||||
if(m.block == null)return new ConstraintSet(); //Abstrakte Methoden generieren keine Constraints
|
||||
private ConstraintSet<Pair> getConstraintsMethod(Method m, TypeInferenceInformation info, ClassOrInterface currentClass) {
|
||||
if (m.block == null) return new ConstraintSet<>(); //Abstrakte Methoden generieren keine Constraints
|
||||
TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m);
|
||||
TYPEStmt methodScope = new TYPEStmt(blockInfo);
|
||||
m.block.accept(methodScope);
|
||||
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);
|
||||
TYPEStmt methodScope = new TYPEStmt(blockInfo);
|
||||
//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());
|
||||
return ret;
|
||||
}
|
||||
|
@@ -11,43 +11,47 @@ import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.FunNClass;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
|
||||
import de.dhbwstuttgart.typeinference.constraints.*;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
||||
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.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.Stream;
|
||||
|
||||
public class TYPEStmt implements StatementVisitor{
|
||||
public class TYPEStmt implements StatementVisitor {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public ConstraintSet getConstraints() {
|
||||
return constraintsSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt einen neuen GenericResolver
|
||||
* Die Idee dieser Datenstruktur ist es, GTVs einen eindeutigen TPH zuzuweisen.
|
||||
* Bei Methodenaufrufen oder anderen Zugriffen, bei denen alle benutzten GTVs jeweils einen einheitlichen TPH bekommen müssen
|
||||
* kann diese Klasse eingesetzt werden. Wichtig ist, dass hierfür jeweils eine frische Instanz benutzt wird.
|
||||
* @return
|
||||
* Creates a new GenericsResolver
|
||||
* The idea behind this data-structure is to assign a unique TPH to GTVs.
|
||||
* On method calls or other accesses where all used GTVs must get a unique TPH, this class can be used.
|
||||
* It is important to always use a fresh instance for that.
|
||||
*/
|
||||
private static GenericsResolver getResolverInstance(){
|
||||
private static GenericsResolver getResolverInstance() {
|
||||
return new GenericsResolverSameName();
|
||||
}
|
||||
|
||||
@@ -55,9 +59,72 @@ public class TYPEStmt implements StatementVisitor{
|
||||
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
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -70,12 +137,11 @@ public class TYPEStmt implements StatementVisitor{
|
||||
//lambdaParams.add(0,tphRetType);
|
||||
constraintsSet.addUndConstraint(
|
||||
new Pair(lambdaExpression.getType(),
|
||||
new RefType(new JavaClassName("Fun"+(lambdaParams.size()-1)+"$$"), lambdaParams, new NullToken()),
|
||||
//new FunN(lambdaParams),
|
||||
new RefType(new JavaClassName("Fun" + (lambdaParams.size() - 1) + "$$"), lambdaParams, new NullToken()),
|
||||
PairOperator.EQUALSDOT));
|
||||
constraintsSet.addUndConstraint(
|
||||
new Pair(lambdaExpression.getReturnType(),
|
||||
tphRetType,PairOperator.EQUALSDOT));
|
||||
tphRetType, PairOperator.EQUALSDOT));
|
||||
|
||||
//Constraints des Bodys generieren:
|
||||
TYPEStmt lambdaScope = new TYPEStmt(new TypeInferenceBlockInformation(info, lambdaExpression));
|
||||
@@ -93,7 +159,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
|
||||
@Override
|
||||
public void visit(Block block) {
|
||||
for(Statement stmt : block.getStatements()){
|
||||
for (Statement stmt : block.getStatements()) {
|
||||
stmt.accept(this);
|
||||
}
|
||||
}
|
||||
@@ -111,17 +177,17 @@ public class TYPEStmt implements StatementVisitor{
|
||||
@Override
|
||||
public void visit(FieldVar fieldVar) {
|
||||
fieldVar.receiver.accept(this);
|
||||
Set<Constraint> oderConstraints = new HashSet<>();
|
||||
for(FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)){
|
||||
Constraint constraint = new Constraint();
|
||||
Set<Constraint<Pair>> oderConstraints = new HashSet<>();
|
||||
for (FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)) {
|
||||
Constraint<Pair> constraint = new Constraint<>();
|
||||
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.getType(), fieldAssumption.getType(resolver), PairOperator.EQUALSDOT));
|
||||
oderConstraints.add(constraint);
|
||||
}
|
||||
if(oderConstraints.size() == 0)
|
||||
throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset());
|
||||
if (oderConstraints.isEmpty())
|
||||
throw new TypeinferenceException("Kein Feld " + fieldVar.fieldVarName + " gefunden", fieldVar.getOffset());
|
||||
constraintsSet.addOderConstraint(oderConstraints);
|
||||
}
|
||||
|
||||
@@ -141,7 +207,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
ifStmt.then_block.accept(this);
|
||||
//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));
|
||||
if(ifStmt.else_block != null){
|
||||
if (ifStmt.else_block != null) {
|
||||
ifStmt.else_block.accept(this);
|
||||
constraintsSet.addUndConstraint(new Pair(ifStmt.else_block.getType(), ifStmt.getType(), PairOperator.SMALLERDOT));
|
||||
}
|
||||
@@ -155,23 +221,23 @@ public class TYPEStmt implements StatementVisitor{
|
||||
|
||||
@Override
|
||||
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
|
||||
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
|
||||
//Es wird in OderConstraints davon ausgegangen dass die Bedingungen für die Typen der Argumente links stehen
|
||||
//und die Typen der Rückgabewerte immer rechts stehen (vgl. JavaTXCompiler)
|
||||
// In oder-constraints it is assumed, that the conditions for the argument types are placed left
|
||||
// and the types of the return values are placed right (see JavaTXCompiler)
|
||||
public void visit(MethodCall methodCall) {
|
||||
|
||||
methodCall.receiver.accept(this);
|
||||
//Overloading:
|
||||
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();
|
||||
Set<Constraint<Pair>> oneMethodConstraints = generateConstraint(methodCall, m, info, resolver);
|
||||
methodConstraints.addAll(oneMethodConstraints);
|
||||
@@ -189,8 +255,8 @@ public class TYPEStmt implements StatementVisitor{
|
||||
methodConstraints.add(extendsOneMethodConstraint);
|
||||
*/
|
||||
}
|
||||
if(methodConstraints.size()<1){
|
||||
throw new TypeinferenceException("Methode "+methodCall.name+" ist nicht vorhanden!",methodCall.getOffset());
|
||||
if (methodConstraints.isEmpty()) {
|
||||
throw new TypeinferenceException("Methode " + methodCall.name + " ist nicht vorhanden!", methodCall.getOffset());
|
||||
}
|
||||
constraintsSet.addOderConstraint(methodConstraints);
|
||||
}
|
||||
@@ -198,12 +264,12 @@ public class TYPEStmt implements StatementVisitor{
|
||||
@Override
|
||||
public void visit(NewClass methodCall) {
|
||||
//Overloading:
|
||||
Set<Constraint> methodConstraints = new HashSet<>();
|
||||
for(MethodAssumption m : this.getConstructors(info, (RefType) methodCall.getType(), methodCall.getArgumentList())){
|
||||
Set<Constraint<Pair>> methodConstraints = new HashSet<>();
|
||||
for (MethodAssumption m : this.getConstructors(info, (RefType) methodCall.getType(), methodCall.getArgumentList())) {
|
||||
methodConstraints.add(generateConstructorConstraint(methodCall, m, info, getResolverInstance()));
|
||||
}
|
||||
if(methodConstraints.size()<1){
|
||||
throw new TypeinferenceException("Konstruktor in Klasse "+methodCall.getType().toString()+" ist nicht vorhanden!",methodCall.getOffset());
|
||||
if (methodConstraints.isEmpty()) {
|
||||
throw new TypeinferenceException("Konstruktor in Klasse " + methodCall.getType().toString() + " ist nicht vorhanden!", methodCall.getOffset());
|
||||
}
|
||||
constraintsSet.addOderConstraint(methodConstraints);
|
||||
}
|
||||
@@ -218,57 +284,47 @@ public class TYPEStmt implements StatementVisitor{
|
||||
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
|
||||
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.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
|
||||
//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));
|
||||
//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));
|
||||
}else{
|
||||
} else {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
//Es wird in OderConstraints davon ausgegangen dass die Bedingungen für die Typen der Argumente links stehen
|
||||
//und die Typen der Rückgabewerte immer rechts stehen (vgl. JavaTXCompiler)
|
||||
// In oder-constraints it is assumed, that the conditions for the argument types are placed left
|
||||
// and the types of the return values are placed right (see JavaTXCompiler)
|
||||
public void visit(BinaryExpr binary) {
|
||||
binary.lexpr.accept(this);
|
||||
binary.rexpr.accept(this);
|
||||
if(binary.operation.equals(BinaryExpr.Operator.DIV) ||
|
||||
binary.operation.equals(BinaryExpr.Operator.MUL)||
|
||||
binary.operation.equals(BinaryExpr.Operator.MOD)||
|
||||
binary.operation.equals(BinaryExpr.Operator.ADD)||
|
||||
if (binary.operation.equals(BinaryExpr.Operator.DIV) ||
|
||||
binary.operation.equals(BinaryExpr.Operator.MUL) ||
|
||||
binary.operation.equals(BinaryExpr.Operator.MOD) ||
|
||||
binary.operation.equals(BinaryExpr.Operator.ADD) ||
|
||||
binary.operation.equals(BinaryExpr.Operator.SUB)) {
|
||||
Set<Constraint<Pair>> numericAdditionOrStringConcatenation = new HashSet<>();
|
||||
|
||||
// TODO PL 2018-11-06
|
||||
// TODO PL 2018-11-06
|
||||
|
||||
// Auf importierte Typen einschraenken
|
||||
// pruefen, ob Typen richtig bestimmt werden.
|
||||
|
||||
|
||||
|
||||
//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
|
||||
//Expression muss zu Numeric Convertierbar sein. also von Numeric erben
|
||||
Constraint<Pair> numeric;
|
||||
//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.add(new Pair(binary.lexpr.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);
|
||||
}
|
||||
//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.add(new Pair(binary.lexpr.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);
|
||||
}
|
||||
//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.add(new Pair(binary.lexpr.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);
|
||||
}
|
||||
//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.add(new Pair(binary.lexpr.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);
|
||||
}
|
||||
//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.add(new Pair(binary.lexpr.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);
|
||||
}
|
||||
//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.add(new Pair(binary.lexpr.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);
|
||||
* 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)
|
||||
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<>();
|
||||
stringConcat.add(new Pair(binary.lexpr.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);
|
||||
}
|
||||
}
|
||||
if(numericAdditionOrStringConcatenation.size()<1){
|
||||
throw new TypeinferenceException("Kein Typ für " + binary.operation.toString() + " vorhanden", binary.getOffset());
|
||||
if (numericAdditionOrStringConcatenation.isEmpty()) {
|
||||
throw new TypeinferenceException("Kein Typ für " + binary.operation + " vorhanden", binary.getOffset());
|
||||
}
|
||||
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.BIGGERTHAN) ||
|
||||
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));
|
||||
//Rückgabetyp ist Boolean
|
||||
//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
|
||||
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
|
||||
constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT));
|
||||
}else{
|
||||
} else {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Literal literal) {
|
||||
//Nothing to do here. Literale erzeugen keine Constraints
|
||||
//PL 2018-06-23 Sie haben einen Typ. Der muesste hier eingefuegt werden
|
||||
//wie hier fuer double gezeigt. Im Momment auskommentiert, weil zu wenige Literaltypen
|
||||
//PL 2018-06-23 Literale haben einen Typ. Der muesste hier eingefuegt werden
|
||||
//wie hier fuer double gezeigt. Im Moment auskommentiert, weil zu wenige Literaltypen
|
||||
//funktionieren
|
||||
if (literal.value instanceof Short) {
|
||||
constraintsSet.addUndConstraint(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT));
|
||||
@@ -431,63 +486,58 @@ public class TYPEStmt implements StatementVisitor{
|
||||
return;
|
||||
}
|
||||
if (literal.value instanceof Integer) {
|
||||
//constraintsSet.addUndConstraint(new Pair(literal.getType(),integer, PairOperator.EQUALSDOT));
|
||||
// /*
|
||||
HashSet<JavaClassName> clNames = info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new));
|
||||
Set<Constraint> oderConstraints = new HashSet<>();
|
||||
Constraint constraint = new Constraint();
|
||||
HashSet<JavaClassName> clNames = info.getAvailableClasses().stream().map(ClassOrInterface::getClassName).collect(Collectors.toCollection(HashSet::new));
|
||||
Set<Constraint<Pair>> oderConstraints = new HashSet<>();
|
||||
Constraint<Pair> constraint = new Constraint<>();
|
||||
constraint.add(new Pair(literal.getType(), integer, PairOperator.EQUALSDOT));
|
||||
oderConstraints.add(constraint);
|
||||
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Double")).findAny().isPresent()) {
|
||||
constraint = new Constraint();
|
||||
if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Double"))) {
|
||||
constraint = new Constraint<>();
|
||||
constraint.add(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT));
|
||||
oderConstraints.add(constraint);
|
||||
}
|
||||
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Long")).findAny().isPresent()) {
|
||||
constraint = new Constraint();
|
||||
if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Long"))) {
|
||||
constraint = new Constraint<>();
|
||||
constraint.add(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT));
|
||||
oderConstraints.add(constraint);
|
||||
}
|
||||
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Float")).findAny().isPresent()) {
|
||||
constraint = new Constraint();
|
||||
if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Float"))) {
|
||||
constraint = new Constraint<>();
|
||||
constraint.add(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT));
|
||||
oderConstraints.add(constraint);
|
||||
}
|
||||
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Short")).findAny().isPresent()) {
|
||||
constraint = new Constraint();
|
||||
if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Short"))) {
|
||||
constraint = new Constraint<>();
|
||||
constraint.add(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT));
|
||||
oderConstraints.add(constraint);
|
||||
}
|
||||
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Byte")).findAny().isPresent()) {
|
||||
constraint = new Constraint();
|
||||
if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Byte"))) {
|
||||
constraint = new Constraint<>();
|
||||
constraint.add(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT));
|
||||
oderConstraints.add(constraint);
|
||||
}
|
||||
constraintsSet.addOderConstraint(oderConstraints);
|
||||
// */
|
||||
return;
|
||||
}
|
||||
if (literal.value instanceof Short) {
|
||||
constraintsSet.addUndConstraint(new Pair(literal.getType(),shortt, PairOperator.EQUALSDOT));
|
||||
constraintsSet.addUndConstraint(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT));
|
||||
return;
|
||||
}
|
||||
if (literal.value instanceof Byte) {
|
||||
constraintsSet.addUndConstraint(new Pair(literal.getType(),bytee, PairOperator.EQUALSDOT));
|
||||
constraintsSet.addUndConstraint(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT));
|
||||
return;
|
||||
}
|
||||
if (literal.value instanceof Float) {
|
||||
constraintsSet.addUndConstraint(new Pair(literal.getType(),floatt, PairOperator.EQUALSDOT));
|
||||
constraintsSet.addUndConstraint(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT));
|
||||
return;
|
||||
}
|
||||
if (literal.value instanceof String) {
|
||||
constraintsSet.addUndConstraint(new Pair(literal.getType(),string, PairOperator.EQUALSDOT));
|
||||
constraintsSet.addUndConstraint(new Pair(literal.getType(), string, PairOperator.EQUALSDOT));
|
||||
return;
|
||||
}
|
||||
if (literal.value instanceof Boolean) {
|
||||
constraintsSet.addUndConstraint(new Pair(literal.getType(),bool, PairOperator.EQUALSDOT));
|
||||
return;
|
||||
}
|
||||
else {
|
||||
constraintsSet.addUndConstraint(new Pair(literal.getType(), bool, PairOperator.EQUALSDOT));
|
||||
} else {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -495,7 +545,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
@Override
|
||||
public void visit(Return returnExpr) {
|
||||
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
|
||||
@@ -518,7 +568,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
//Im Falle von this, müssen die Generics in der Klasse als RefTypes behandelt werden.
|
||||
ClassOrInterface currentClass = info.getCurrentClass();
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
for(GenericTypeVar gtv : currentClass.getGenerics()){
|
||||
for (GenericTypeVar gtv : currentClass.getGenerics()) {
|
||||
params.add(new GenericRefType(gtv.getName(), 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));
|
||||
}
|
||||
|
||||
private static TypeScope createNullTypeScope() {
|
||||
return new TypeScope() {
|
||||
@Override
|
||||
public Iterable<? extends GenericTypeVar> getGenerics() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WhileStmt whileStmt) {
|
||||
RefType booleanType = new RefType(ASTFactory.createClass(java.lang.Boolean.class).getClassName(), new NullToken());
|
||||
//Expression inferieren:
|
||||
// Infer expression:
|
||||
whileStmt.expr.accept(this);
|
||||
//Expression muss boolean sein:
|
||||
// Expression must be boolean:
|
||||
constraintsSet.addUndConstraint(new Pair(whileStmt.expr.getType(), booleanType, PairOperator.EQUALSDOT));
|
||||
//LoopBlock inferieren:
|
||||
// Infer loopBlock:
|
||||
whileStmt.loopBlock.accept(this);
|
||||
}
|
||||
|
||||
@@ -556,6 +592,10 @@ public class TYPEStmt implements StatementVisitor{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/*
|
||||
METHOD CALL Section:
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void visit(AssignToField assignLeftSide) {
|
||||
//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
|
||||
}
|
||||
|
||||
/*
|
||||
METHOD CALL Section:
|
||||
*/
|
||||
|
||||
protected Set<Constraint<Pair>> generateConstraint(MethodCall forMethod, MethodAssumption assumption,
|
||||
TypeInferenceBlockInformation info, GenericsResolver resolver){
|
||||
TypeInferenceBlockInformation info, GenericsResolver resolver) {
|
||||
Constraint<Pair> methodConstraint, extendsMethodConstraint;
|
||||
methodConstraint = new Constraint<>(assumption.isInherited());
|
||||
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);
|
||||
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));
|
||||
//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);
|
||||
|
||||
@@ -639,13 +664,12 @@ public class TYPEStmt implements StatementVisitor{
|
||||
protected Set<Pair> generateParameterConstraints(MethodCall foMethod, MethodAssumption assumption,
|
||||
TypeInferenceBlockInformation info, GenericsResolver resolver) {
|
||||
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);
|
||||
RefTypeOrTPHOrWildcardOrGeneric argType = foMethod.arglist.getArguments().get(i).getType();
|
||||
RefTypeOrTPHOrWildcardOrGeneric assType = assumption.getArgTypes(resolver).get(i);
|
||||
|
||||
|
||||
|
||||
ret.add(new Pair(argType, assType, PairOperator.SMALLERDOT));
|
||||
|
||||
//Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ANFANG
|
||||
@@ -655,12 +679,11 @@ public class TYPEStmt implements StatementVisitor{
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
protected Set<Pair> generatemethodSignatureConstraint(MethodCall foMethod, MethodAssumption assumption,
|
||||
TypeInferenceBlockInformation info, GenericsResolver resolver) {
|
||||
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)
|
||||
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)
|
||||
System.out.println(foMethod.name);
|
||||
ret.add(new Pair(foMethod.signature.get(foMethod.signature.size()-1), assumption.getReturnType(), PairOperator.EQUALSDOT));
|
||||
ret.add(new Pair(foMethod.signature.get(foMethod.signature.size() - 1), assumption.getReturnType(), PairOperator.EQUALSDOT));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static List<MethodAssumption> getMethods(String name, int numArgs, TypeInferenceBlockInformation info) {
|
||||
public List<MethodAssumption> getConstructors(TypeInferenceBlockInformation info, RefType ofType, ArgumentList argList) {
|
||||
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 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()){
|
||||
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(),
|
||||
info), createTypeScope(cl, m), m.isInherited));
|
||||
}
|
||||
@@ -748,8 +712,8 @@ public class TYPEStmt implements StatementVisitor{
|
||||
}
|
||||
|
||||
protected Constraint<Pair> generateConstructorConstraint(NewClass forConstructor, MethodAssumption assumption,
|
||||
TypeInferenceBlockInformation info, GenericsResolver resolver){
|
||||
Constraint methodConstraint = new Constraint();
|
||||
TypeInferenceBlockInformation info, GenericsResolver resolver) {
|
||||
Constraint<Pair> methodConstraint = new Constraint<>();
|
||||
//WELCHEN SINN MACHT DIESER CONSTRAINT???
|
||||
//Ist er nicht immer classname <. classname und damit redundant?
|
||||
methodConstraint.add(new Pair(assumption.getReturnType(resolver), forConstructor.getType(),
|
||||
|
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -1,16 +1,15 @@
|
||||
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.Set;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.unify.interfaces.ISetOperations;
|
||||
|
||||
/**
|
||||
* Implements set operations using google guava.
|
||||
* @author DH10STF
|
||||
*
|
||||
* @author DH10STF
|
||||
*/
|
||||
public class GuavaSetOperations implements ISetOperations {
|
||||
|
||||
|
@@ -1,22 +1,14 @@
|
||||
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.model.PairOperator;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.Unifier;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Implementation of the Martelli-Montanari unification algorithm.
|
||||
*
|
||||
* @author Florian Steurer
|
||||
*/
|
||||
public class MartelliMontanariUnify implements IUnify {
|
||||
@@ -24,7 +16,7 @@ public class MartelliMontanariUnify implements IUnify {
|
||||
@Override
|
||||
public Optional<Unifier> unify(Set<UnifyType> terms) {
|
||||
// Sets with less than 2 terms are trivially unified
|
||||
if(terms.size() < 2)
|
||||
if (terms.size() < 2)
|
||||
return Optional.of(Unifier.identity());
|
||||
|
||||
// For the the set of terms {t1,...,tn},
|
||||
@@ -32,7 +24,7 @@ public class MartelliMontanariUnify implements IUnify {
|
||||
ArrayList<UnifyPair> termsList = new ArrayList<UnifyPair>();
|
||||
Iterator<UnifyType> iter = terms.iterator();
|
||||
UnifyType prev = iter.next();
|
||||
while(iter.hasNext()) {
|
||||
while (iter.hasNext()) {
|
||||
UnifyType next = iter.next();
|
||||
termsList.add(new UnifyPair(prev, next, PairOperator.EQUALSDOT));
|
||||
prev = next;
|
||||
@@ -43,7 +35,7 @@ public class MartelliMontanariUnify implements IUnify {
|
||||
|
||||
// Apply rules while possible
|
||||
int idx = 0;
|
||||
while(idx < termsList.size()) {
|
||||
while (idx < termsList.size()) {
|
||||
UnifyPair pair = termsList.get(idx);
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
@@ -51,21 +43,21 @@ public class MartelliMontanariUnify implements IUnify {
|
||||
TypeParams lhsTypeParams = lhsType.getTypeParams();
|
||||
|
||||
// REDUCE - Rule
|
||||
if(!(rhsType instanceof PlaceholderType) && !(lhsType instanceof PlaceholderType)) {
|
||||
if (!(rhsType instanceof PlaceholderType) && !(lhsType instanceof PlaceholderType)) {
|
||||
Set<UnifyPair> result = new HashSet<>();
|
||||
|
||||
// f<...> = g<...> with f != g are not unifiable
|
||||
if(!rhsType.getName().equals(lhsType.getName()))
|
||||
if (!rhsType.getName().equals(lhsType.getName()))
|
||||
return Optional.empty(); // conflict
|
||||
// f<t1,...,tn> = f<s1,...,sm> are not unifiable
|
||||
if(rhsTypeParams.size() != lhsTypeParams.size())
|
||||
if (rhsTypeParams.size() != lhsTypeParams.size())
|
||||
return Optional.empty(); // conflict
|
||||
// f = g is not unifiable (cannot be f = f because erase rule would have been applied)
|
||||
//if(rhsTypeParams.size() == 0)
|
||||
//return Optional.empty();
|
||||
|
||||
// Unpack the arguments
|
||||
for(int i = 0; i < rhsTypeParams.size(); i++)
|
||||
for (int i = 0; i < rhsTypeParams.size(); i++)
|
||||
result.add(new UnifyPair(rhsTypeParams.get(i), lhsTypeParams.get(i), PairOperator.EQUALSDOT));
|
||||
|
||||
termsList.remove(idx);
|
||||
@@ -74,29 +66,29 @@ public class MartelliMontanariUnify implements IUnify {
|
||||
}
|
||||
|
||||
// DELETE - Rule
|
||||
if(pair.getRhsType().equals(pair.getLhsType())) {
|
||||
if (pair.getRhsType().equals(pair.getLhsType())) {
|
||||
termsList.remove(idx);
|
||||
continue;
|
||||
}
|
||||
|
||||
// SWAP - Rule
|
||||
if(!(lhsType instanceof PlaceholderType) && (rhsType instanceof PlaceholderType)) {
|
||||
if (!(lhsType instanceof PlaceholderType) && (rhsType instanceof PlaceholderType)) {
|
||||
termsList.remove(idx);
|
||||
termsList.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT));
|
||||
continue;
|
||||
}
|
||||
|
||||
// OCCURS-CHECK
|
||||
if(pair.getLhsType() instanceof PlaceholderType
|
||||
if (pair.getLhsType() instanceof PlaceholderType
|
||||
&& pair.getRhsType().getTypeParams().occurs((PlaceholderType) pair.getLhsType()))
|
||||
return Optional.empty();
|
||||
|
||||
// SUBST - Rule
|
||||
if(lhsType instanceof PlaceholderType) {
|
||||
if (lhsType instanceof PlaceholderType) {
|
||||
mgu.add((PlaceholderType) lhsType, rhsType);
|
||||
//PL 2018-04-01 nach checken, ob es richtig ist, dass keine Substitutionen uebergeben werden muessen.
|
||||
termsList = termsList.stream().map(x -> mgu.apply(x)).collect(Collectors.toCollection(ArrayList::new));
|
||||
idx = idx+1 == termsList.size() ? 0 : idx+1;
|
||||
idx = idx + 1 == termsList.size() ? 0 : idx + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@@ -11,6 +11,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Implementation of match derived from unification algorithm.
|
||||
*
|
||||
* @author Martin Pluemicke
|
||||
*/
|
||||
public class Match implements IMatch {
|
||||
@@ -26,7 +27,7 @@ public class Match implements IMatch {
|
||||
|
||||
// Apply rules while possible
|
||||
int idx = 0;
|
||||
while(idx < termsList.size()) {
|
||||
while (idx < termsList.size()) {
|
||||
UnifyPair pair = termsList.get(idx);
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
@@ -34,21 +35,21 @@ public class Match implements IMatch {
|
||||
TypeParams lhsTypeParams = lhsType.getTypeParams();
|
||||
|
||||
// REDUCE - Rule
|
||||
if(!(rhsType instanceof PlaceholderType) && !(lhsType instanceof PlaceholderType)) {
|
||||
if (!(rhsType instanceof PlaceholderType) && !(lhsType instanceof PlaceholderType)) {
|
||||
Set<UnifyPair> result = new HashSet<>();
|
||||
|
||||
// f<...> = g<...> with f != g are not unifiable
|
||||
if(!rhsType.getName().equals(lhsType.getName()))
|
||||
if (!rhsType.getName().equals(lhsType.getName()))
|
||||
return Optional.empty(); // conflict
|
||||
// f<t1,...,tn> = f<s1,...,sm> are not unifiable
|
||||
if(rhsTypeParams.size() != lhsTypeParams.size())
|
||||
if (rhsTypeParams.size() != lhsTypeParams.size())
|
||||
return Optional.empty(); // conflict
|
||||
// f = g is not unifiable (cannot be f = f because erase rule would have been applied)
|
||||
//if(rhsTypeParams.size() == 0)
|
||||
//return Optional.empty();
|
||||
|
||||
// Unpack the arguments
|
||||
for(int i = 0; i < rhsTypeParams.size(); i++)
|
||||
for (int i = 0; i < rhsTypeParams.size(); i++)
|
||||
result.add(new UnifyPair(lhsTypeParams.get(i), rhsTypeParams.get(i), PairOperator.EQUALSDOT));
|
||||
|
||||
termsList.remove(idx);
|
||||
@@ -57,13 +58,13 @@ public class Match implements IMatch {
|
||||
}
|
||||
|
||||
// DELETE - Rule
|
||||
if(pair.getRhsType().equals(pair.getLhsType())) {
|
||||
if (pair.getRhsType().equals(pair.getLhsType())) {
|
||||
termsList.remove(idx);
|
||||
continue;
|
||||
}
|
||||
|
||||
// SWAP - Rule
|
||||
if(!(lhsType instanceof PlaceholderType) && (rhsType instanceof PlaceholderType)) {
|
||||
if (!(lhsType instanceof PlaceholderType) && (rhsType instanceof PlaceholderType)) {
|
||||
return Optional.empty(); // conflict
|
||||
}
|
||||
|
||||
@@ -71,10 +72,10 @@ public class Match implements IMatch {
|
||||
//deleted
|
||||
|
||||
// SUBST - Rule
|
||||
if(lhsType instanceof PlaceholderType) {
|
||||
if (lhsType instanceof PlaceholderType) {
|
||||
mgu.add((PlaceholderType) lhsType, rhsType);
|
||||
termsList = termsList.stream().map(mgu::applyleft).collect(Collectors.toCollection(ArrayList::new));
|
||||
idx = idx+1 == termsList.size() ? 0 : idx+1;
|
||||
termsList = termsList.stream().map(mgu::applyLeft).collect(Collectors.toCollection(ArrayList::new));
|
||||
idx = idx + 1 == termsList.size() ? 0 : idx + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -12,88 +12,78 @@ import java.util.concurrent.ForkJoinPool;
|
||||
public class TypeUnify {
|
||||
|
||||
public static Writer statistics;
|
||||
|
||||
/**
|
||||
* unify parallel ohne result modell
|
||||
* @param undConstrains
|
||||
* @param oderConstraints
|
||||
* @param fc
|
||||
* @param logFile
|
||||
* @param log
|
||||
* @return
|
||||
* Unify parallel without result model
|
||||
*/
|
||||
public Set<Set<UnifyPair>> unify(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModelParallel resultModel, UnifyTaskModelParallel taskModel) {
|
||||
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);
|
||||
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);
|
||||
Set<Set<UnifyPair>> res = unifyTask.join();
|
||||
return res;
|
||||
return unifyTask.join();
|
||||
}
|
||||
|
||||
/**
|
||||
* unify asynchron mit Rückgabe UnifyResultModel, ohne dass alle results gesammelt sind
|
||||
* @param undConstrains
|
||||
* @param oderConstraints
|
||||
* @param fc
|
||||
* @param logFile
|
||||
* @param log
|
||||
* @return
|
||||
* Unify parallel returning UnifyResultModel after gathering all results
|
||||
*/
|
||||
public UnifyResultModelParallel unifyAsync(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModelParallel resultModel, UnifyTaskModelParallel taskModel) {
|
||||
ForkJoinPool pool = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
|
||||
public void unifyParallel(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModelParallel resultModel, UnifyTaskModelParallel taskModel) {
|
||||
ForkJoinPool pool = new ForkJoinPool(
|
||||
Runtime.getRuntime().availableProcessors(),
|
||||
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
|
||||
null,
|
||||
true
|
||||
);
|
||||
taskModel.setPool(pool);
|
||||
resultModel.setPool(pool);
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, new WriterActiveObject(logFile, pool), log, resultModel, pool);
|
||||
pool.invoke(unifyTask);
|
||||
return resultModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* unify parallel mit Rückgabe UnifyResultModel nachdem alle results gesammelt sind
|
||||
* @param undConstrains
|
||||
* @param oderConstraints
|
||||
* @param fc
|
||||
* @param logFile
|
||||
* @param log
|
||||
* @return
|
||||
*/
|
||||
public UnifyResultModelParallel unifyParallel(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModelParallel resultModel, UnifyTaskModelParallel taskModel) {
|
||||
ForkJoinPool pool = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
|
||||
taskModel.setPool(pool);
|
||||
resultModel.setPool(pool);
|
||||
TypeUnifyTask unifyTask = //new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, usedTasks);
|
||||
new TypeUnifyTask(undConstrains, oderConstraints, fc, true, new WriterActiveObject(logFile, pool), log, resultModel, pool, statistics);
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(
|
||||
undConstrains,
|
||||
oderConstraints,
|
||||
fc,
|
||||
true,
|
||||
new WriterActiveObject(logFile, pool),
|
||||
log,
|
||||
resultModel,
|
||||
pool,
|
||||
statistics
|
||||
);
|
||||
|
||||
pool.invoke(unifyTask);
|
||||
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
|
||||
* @param undConstrains
|
||||
* @param oderConstraints
|
||||
* @param fc
|
||||
* @param logFile
|
||||
* @param log
|
||||
* @return
|
||||
* Unify sequential with oder-constraints
|
||||
*/
|
||||
public Set<Set<UnifyPair>> unifyOderConstraints(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModelParallel resultModel, 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());
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, false, new WriterActiveObject(logFile, ForkJoinPool.commonPool()), log, resultModel, ForkJoinPool.commonPool());
|
||||
unifyTask.statisticsFile = statistics;
|
||||
Set<Set<UnifyPair>> res = unifyTask.compute();
|
||||
return res;
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(
|
||||
undConstrains,
|
||||
oderConstraints,
|
||||
fc,
|
||||
false,
|
||||
new WriterActiveObject(logFile, ForkJoinPool.commonPool()),
|
||||
log,
|
||||
resultModel,
|
||||
ForkJoinPool.commonPool()
|
||||
);
|
||||
TypeUnifyTask.statisticsFile = statistics;
|
||||
return unifyTask.compute();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -4,7 +4,6 @@ import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
@@ -14,16 +13,6 @@ public class TypeUnify2Task extends TypeUnifyTask {
|
||||
Set<Set<UnifyPair>> setToFlatten;
|
||||
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) {
|
||||
super(eq, oderConstraints, fc, parallel, logFile, log, urm, pool);
|
||||
this.setToFlatten = setToFlatten;
|
||||
@@ -48,9 +37,9 @@ public class TypeUnify2Task extends TypeUnifyTask {
|
||||
}
|
||||
|
||||
public void closeLogFile() {
|
||||
if(parallel){
|
||||
if (parallel) {
|
||||
logFile.close();
|
||||
}else{
|
||||
} else {
|
||||
logFile.closeNonThreaded();
|
||||
}
|
||||
}
|
||||
|
@@ -32,43 +32,34 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
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/";
|
||||
static Writer statisticsFile = new NullWriter();
|
||||
private static int totalNoOfThreads = 0;
|
||||
/*
|
||||
* Thread related
|
||||
*/
|
||||
protected UnifyResultModelParallel unifyResultModel;
|
||||
protected WriterActiveObject logFile;
|
||||
protected ForkJoinPool pool;
|
||||
|
||||
/**
|
||||
* The implementation of the standard unify that will be used during the unification
|
||||
*/
|
||||
protected IUnify stdUnify = new MartelliMontanariUnify();
|
||||
|
||||
/**
|
||||
* The implementation of the rules that will be used during the unification.
|
||||
*/
|
||||
protected IRuleSet rules;
|
||||
|
||||
protected Set<UnifyPair> eq; //und-constraints
|
||||
|
||||
protected List<Set<Constraint<UnifyPair>>> oderConstraintsField;
|
||||
|
||||
protected IFiniteClosure fc;
|
||||
|
||||
protected boolean parallel;
|
||||
|
||||
static Writer statisticsFile = new NullWriter();
|
||||
//gibt an ob ein Log-File nach System.getProperty("user.dir")+"/test/logFiles/log" geschrieben werden soll?
|
||||
Boolean log = true;
|
||||
/**
|
||||
* Element that was added to the equations of this thread from the nextSet
|
||||
*/
|
||||
Set<UnifyPair> nextSetElement;
|
||||
int threadNumber;
|
||||
|
||||
public TypeUnifyTask() {
|
||||
rules = new RuleSet();
|
||||
@@ -77,7 +68,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
//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) {
|
||||
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) {
|
||||
@@ -89,12 +80,12 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
this.log = log;
|
||||
this.pool = pool;
|
||||
|
||||
totalnoOfThread++;
|
||||
thNo = totalnoOfThread;
|
||||
writeLog("thNo2 " + thNo);
|
||||
totalNoOfThreads++;
|
||||
threadNumber = totalNoOfThreads;
|
||||
writeLog("thNo2 " + threadNumber);
|
||||
try {
|
||||
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 {
|
||||
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");
|
||||
}
|
||||
rules = new RuleSet(logFile);
|
||||
this.urm = urm;
|
||||
this.unifyResultModel = urm;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
} else if (eqPrimePrime.isPresent()) {
|
||||
@@ -457,7 +448,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
Set<Set<UnifyPair>> newElemsOrig = new HashSet<>(elems);
|
||||
List<Set<Constraint<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints);
|
||||
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();
|
||||
|
||||
while (!nextSetasList.isEmpty()) {
|
||||
@@ -471,14 +462,14 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
Set<Set<UnifyPair>> newElems = new HashSet<>(elems);
|
||||
List<Set<Constraint<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints);
|
||||
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);
|
||||
fork.fork();
|
||||
}
|
||||
|
||||
res = forkOrig.join();
|
||||
|
||||
forks.forEach(x -> writeLog("wait: " + x.thNo));
|
||||
forks.forEach(x -> writeLog("wait: " + x.threadNumber));
|
||||
for (TypeUnify2Task fork : forks) {
|
||||
Set<Set<UnifyPair>> fork_res = fork.join();
|
||||
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);
|
||||
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();
|
||||
|
||||
while (!nextSetasList.isEmpty()) {
|
||||
@@ -507,21 +498,21 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
Set<Set<UnifyPair>> newElems = new HashSet<>(elems);
|
||||
List<Set<Constraint<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints);
|
||||
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);
|
||||
fork.fork();
|
||||
}
|
||||
|
||||
writeLog("wait " + forkOrig.thNo);
|
||||
writeLog("wait " + forkOrig.threadNumber);
|
||||
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) {
|
||||
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);
|
||||
if (!isUndefinedPairSetSet(fork_res)) {
|
||||
aParDef.add(fork.getNextSetElement());
|
||||
@@ -536,7 +527,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
List<Set<Constraint<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints);
|
||||
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();
|
||||
|
||||
while (!nextSetasList.isEmpty()) {
|
||||
@@ -545,21 +536,21 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
Set<Set<UnifyPair>> newElems = new HashSet<>(elems);
|
||||
List<Set<Constraint<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints);
|
||||
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);
|
||||
fork.fork();
|
||||
}
|
||||
|
||||
writeLog("wait " + forkOrig.thNo);
|
||||
writeLog("wait " + forkOrig.threadNumber);
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
} else {//parallel = false oder MaxNoOfThreads ist erreicht, sequentiell weiterarbeiten
|
||||
@@ -617,7 +608,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
res.stream()
|
||||
.map(b ->
|
||||
b.stream()
|
||||
.map(x -> x.getThisAndAllBases()) //getAllBases durch getThisAndAllBases ersetzt, weil auch im UnifyPair selbst schon ein Fehler liegen kann.
|
||||
.map(UnifyPair::getThisAndAllBases) //getAllBases durch getThisAndAllBases ersetzt, weil auch im UnifyPair selbst schon ein Fehler liegen kann.
|
||||
.reduce((y, z) -> {
|
||||
y.addAll(z);
|
||||
return y;
|
||||
@@ -627,22 +618,18 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
return y;
|
||||
}).get()
|
||||
);
|
||||
Set<UnifyPair> b = a;//effective final a
|
||||
Set<UnifyPair> b = a;
|
||||
Set<UnifyPair> durchschnitt = abhSubst.stream()
|
||||
.filter(x -> b.contains(x))
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
int len = nextSetasList.size();
|
||||
|
||||
nofstred = nextSetasList.size();
|
||||
|
||||
writeLog("res (undef): " + res.toString() + "\n" +
|
||||
"abhSubst: " + abhSubst.toString() + "\n" +
|
||||
"Durchschnitt: " + durchschnitt.toString() + "\n" +
|
||||
"nextSet: " + nextSet.toString() + "\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()));
|
||||
writeLog(
|
||||
"res (undef): " + res + "\n" +
|
||||
"abhSubst: " + abhSubst + "\n" +
|
||||
"Durchschnitt: " + durchschnitt + "\n" +
|
||||
"nextSet: " + nextSet + "\n" +
|
||||
"nextSetasList: " + nextSetasList + "\n"
|
||||
);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -923,10 +910,10 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
}
|
||||
}
|
||||
|
||||
writeLog("eq2s: " + eq2s.toString() + "\n" +
|
||||
"eq2sAsListFst: " + eq2sAsListFst.toString() + "\n" +
|
||||
"eq2sAsListSnd: " + eq2sAsListSnd.toString() + "\n" +
|
||||
"eq2sAsListBack: " + eq2sAsListBack.toString());
|
||||
writeLog("eq2s: " + eq2s + "\n" +
|
||||
"eq2sAsListFst: " + eq2sAsListFst + "\n" +
|
||||
"eq2sAsListSnd: " + eq2sAsListSnd + "\n" +
|
||||
"eq2sAsListBack: " + eq2sAsListBack);
|
||||
|
||||
eq2sAsList.addAll(eq2sAsListFst);
|
||||
eq2sAsList.addAll(eq2sAsListSnd);
|
||||
@@ -1213,7 +1200,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
aa.put(b, PlaceholderType.freshPlaceholder());
|
||||
return aa;
|
||||
}, combiner);
|
||||
return x.accept(new freshPlaceholder(), hm);
|
||||
return x.accept(new FreshPlaceholder(), hm);
|
||||
}).collect(Collectors.toCollection(HashSet::new));
|
||||
|
||||
IMatch match = new Match();
|
||||
@@ -1228,7 +1215,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
if ((match.match(ml)).isEmpty()) {
|
||||
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));
|
||||
//thetaQs.add(thetaPrime); //PL 18-02-05 wieder geloescht
|
||||
//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))
|
||||
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
|
||||
Collection<PlaceholderType> tphs = tqp.getInvolvedPlaceholderTypes();
|
||||
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);
|
||||
//TODO PL 2019-01-24: upit.next() ist nicht unbedingt ein PlaceholderType -> Visitor erledigt
|
||||
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);
|
||||
} else {
|
||||
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
|
||||
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.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;
|
||||
}
|
||||
|
||||
@@ -1337,7 +1324,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
|
||||
PlaceholderType aPrime = PlaceholderType.freshPlaceholder();
|
||||
aPrime.setVariance(a.getVariance());
|
||||
aPrime.disableWildcardtable();
|
||||
aPrime.disableWildcardable();
|
||||
UnifyType extAPrime = new ExtendsType(aPrime);
|
||||
UnifyType thetaPrime = extThetaPrime.getExtendedType();
|
||||
Set<UnifyPair> resultPrime = new HashSet<>();
|
||||
@@ -1363,11 +1350,11 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
|
||||
PlaceholderType aPrime = PlaceholderType.freshPlaceholder();
|
||||
aPrime.setVariance(a.getVariance());
|
||||
aPrime.disableWildcardtable();
|
||||
aPrime.disableWildcardable();
|
||||
UnifyType supAPrime = new SuperType(aPrime);
|
||||
UnifyType thetaPrime = subThetaPrime.getSuperedType();
|
||||
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);
|
||||
//writeLog(resultPrime.toString());
|
||||
|
||||
@@ -1399,7 +1386,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
//fc.setLogTrue();
|
||||
//writeLog("FBOUNDED: " + pair.getfBounded());
|
||||
//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() + " ");
|
||||
if (a.isWildcardable()) {
|
||||
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++) {
|
||||
freshTphs[i] = PlaceholderType.freshPlaceholder();
|
||||
((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;
|
||||
BiFunction<Boolean, UnifyType, Boolean> f = (x, y) ->
|
||||
@@ -1473,10 +1460,10 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
PlaceholderType freshTph = PlaceholderType.freshPlaceholder();
|
||||
|
||||
freshTph.setVariance(a.getVariance());
|
||||
freshTph.disableWildcardtable();
|
||||
freshTph.disableWildcardable();
|
||||
resultPrime = new HashSet<>();
|
||||
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);
|
||||
//writeLog("resultPrime: " + resultPrime.toString());
|
||||
|
||||
@@ -1528,12 +1515,12 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
void writeLog(String str) {
|
||||
if (log) {
|
||||
if (parallel) {
|
||||
logFile.write("Thread no.:" + thNo + "\n"
|
||||
logFile.write("Thread no.:" + threadNumber + "\n"
|
||||
+ "parallel:" + parallel + "\n"
|
||||
+ str + "\n\n"
|
||||
);
|
||||
} else {
|
||||
logFile.writeNonThreaded("Thread no.:" + thNo + "\n"
|
||||
logFile.writeNonThreaded("Thread no.:" + threadNumber + "\n"
|
||||
+ "parallel:" + parallel + "\n"
|
||||
+ str + "\n\n"
|
||||
);
|
||||
@@ -1543,7 +1530,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
|
||||
void writeStatistics(String str) {
|
||||
try {
|
||||
statisticsFile.write("Thread No. " + thNo + ": " + str + "\n");
|
||||
statisticsFile.write("Thread No. " + threadNumber + ": " + str + "\n");
|
||||
statisticsFile.flush();
|
||||
|
||||
} catch (IOException e) {
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -1,7 +0,0 @@
|
||||
package de.dhbwstuttgart.typeinference.unify;
|
||||
|
||||
public interface UnifyResultListener {
|
||||
|
||||
void onNewTypeResultFound(UnifyResultEvent evt);
|
||||
|
||||
}
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,57 +1,54 @@
|
||||
package de.dhbwstuttgart.typeinference.unify;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
|
||||
import de.dhbwstuttgart.typeinference.TypeInferenceHelper;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
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.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class UnifyResultModelParallel {
|
||||
private final ConstraintSet<Pair> cons;
|
||||
private final IFiniteClosure fc;
|
||||
private final List<ResultSet> results = new ArrayList<>();
|
||||
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.fc = fc;
|
||||
}
|
||||
|
||||
public void setPool(ForkJoinPool pool){
|
||||
public void setPool(ForkJoinPool 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(()->{
|
||||
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));
|
||||
|
||||
public void notify(Set<Set<UnifyPair>> eqPrimePrimeSet) {
|
||||
pool.execute(() -> {
|
||||
Set<Set<UnifyPair>> eqPrimePrimeSetRet =
|
||||
TypeInferenceHelper.resolveSubstitutions(new HashSet<>(eqPrimePrimeSet), fc);
|
||||
|
||||
List<ResultSet> newResult = eqPrimePrimeSetRet.stream().map(unifyPairs ->
|
||||
new ResultSet(UnifyTypeFactory.convert(unifyPairs, de.dhbwstuttgart.typeinference.constraints.Pair.generateTPHMap(cons))))
|
||||
.collect(Collectors.toList());
|
||||
UnifyResultEvent evt = new UnifyResultEvent(newResult);
|
||||
|
||||
for (UnifyResultListener listener : listeners) {
|
||||
listener.onNewTypeResultFound(evt);
|
||||
}
|
||||
// TODO: this is a synchronized call, can we find a way around this?
|
||||
this.onNewTypeResultFound(newResult);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -5,12 +5,12 @@ import java.util.concurrent.ForkJoinPool;
|
||||
public class UnifyTaskModelParallel {
|
||||
private ForkJoinPool pool;
|
||||
|
||||
public void setPool(ForkJoinPool pool){
|
||||
public void setPool(ForkJoinPool pool) {
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
public void cancel(){
|
||||
if(this.pool != null) {
|
||||
public void cancel() {
|
||||
if (this.pool != null) {
|
||||
this.pool.shutdown();
|
||||
}
|
||||
}
|
||||
|
@@ -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));
|
||||
}
|
||||
}
|
@@ -5,48 +5,54 @@ import java.io.Writer;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
|
||||
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.pool = pool;
|
||||
}
|
||||
|
||||
public void close(){
|
||||
pool.execute(()->{
|
||||
try {
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void write(String message){
|
||||
pool.execute(()->{
|
||||
public void write(String message) {
|
||||
pool.execute(() -> {
|
||||
try {
|
||||
writer.write(message);
|
||||
// TODO: do something against this flush(). Writing to disk is slooooooow
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
// TODO: why is here a random error conversion down to a runtimeException?
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void writeNonThreaded(String message){
|
||||
public void writeNonThreaded(String message) {
|
||||
try {
|
||||
writer.write(message);
|
||||
// TODO: do something against this flush(). Writing to disk is slooooooow
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
// TODO: why is here a random error conversion down to a runtimeException?
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void closeNonThreaded(){
|
||||
public void close() {
|
||||
pool.execute(() -> {
|
||||
try {
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
System.err.println(e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void closeNonThreaded() {
|
||||
try {
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
// TODO: why is here a random error conversion down to a runtimeException?
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -6,58 +6,71 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Florian Steurer
|
||||
*/
|
||||
public interface IFiniteClosure {
|
||||
|
||||
public void setLogTrue();
|
||||
void setLogTrue();
|
||||
|
||||
/**
|
||||
* Returns all types of the finite closure that are subtypes of the argument.
|
||||
*
|
||||
* @return The set of subtypes of the argument.
|
||||
*/
|
||||
public Set<UnifyType> smaller(UnifyType type, Set<UnifyType> fBounded);
|
||||
Set<UnifyType> smaller(UnifyType type, Set<UnifyType> fBounded);
|
||||
|
||||
/**
|
||||
* Returns all types of the finite closure that are supertypes of the argument.
|
||||
*
|
||||
* @return The set of supertypes of the argument.
|
||||
*/
|
||||
public Set<UnifyType> greater(UnifyType type, Set<UnifyType> fBounded);
|
||||
Set<UnifyType> greater(UnifyType type, Set<UnifyType> fBounded);
|
||||
|
||||
/**
|
||||
* Wo passt Type rein?
|
||||
*
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
public Set<UnifyType> grArg(UnifyType type, Set<UnifyType> fBounded);
|
||||
Set<UnifyType> grArg(UnifyType type, Set<UnifyType> fBounded);
|
||||
|
||||
/**
|
||||
* Was passt in Type rein?
|
||||
*
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
public Set<UnifyType> smArg(UnifyType type, Set<UnifyType> fBounded);
|
||||
Set<UnifyType> smArg(UnifyType type, Set<UnifyType> fBounded);
|
||||
|
||||
public Set<UnifyType> grArg(ReferenceType type, Set<UnifyType> fBounded);
|
||||
public Set<UnifyType> smArg(ReferenceType type, Set<UnifyType> fBounded);
|
||||
Set<UnifyType> grArg(ReferenceType type, Set<UnifyType> fBounded);
|
||||
|
||||
public Set<UnifyType> grArg(ExtendsType type, Set<UnifyType> fBounded);
|
||||
public Set<UnifyType> smArg(ExtendsType type, Set<UnifyType> fBounded);
|
||||
Set<UnifyType> smArg(ReferenceType type, Set<UnifyType> fBounded);
|
||||
|
||||
public Set<UnifyType> grArg(SuperType type, Set<UnifyType> fBounded);
|
||||
public Set<UnifyType> smArg(SuperType type, Set<UnifyType> fBounded);
|
||||
Set<UnifyType> grArg(ExtendsType type, Set<UnifyType> fBounded);
|
||||
|
||||
public Set<UnifyType> grArg(PlaceholderType type, Set<UnifyType> fBounded);
|
||||
public Set<UnifyType> smArg(PlaceholderType type, Set<UnifyType> fBounded);
|
||||
Set<UnifyType> smArg(ExtendsType type, Set<UnifyType> fBounded);
|
||||
|
||||
public Set<UnifyType> grArg(FunNType type, Set<UnifyType> fBounded);
|
||||
public Set<UnifyType> smArg(FunNType type, Set<UnifyType> fBounded);
|
||||
Set<UnifyType> grArg(SuperType type, Set<UnifyType> fBounded);
|
||||
|
||||
public Set<UnifyPair> getPairs();
|
||||
public Optional<UnifyType> getLeftHandedType(String typeName);
|
||||
public Set<UnifyType> getAncestors(UnifyType t);
|
||||
public Set<UnifyType> getChildren(UnifyType t);
|
||||
public Set<UnifyType> getAllTypesByName(String typeName);
|
||||
Set<UnifyType> smArg(SuperType type, Set<UnifyType> fBounded);
|
||||
|
||||
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);
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@ import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Match
|
||||
*
|
||||
* @author Martin Pluemicke
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
public Optional<Unifier> match(ArrayList<UnifyPair> termsList);
|
||||
Optional<Unifier> match(ArrayList<UnifyPair> termsList);
|
||||
|
||||
|
||||
}
|
@@ -9,32 +9,43 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* Contains the inference rules that are applied to the set Eq.
|
||||
*
|
||||
* @author Florian Steurer
|
||||
*/
|
||||
public interface IRuleSet {
|
||||
|
||||
public Optional<UnifyPair> reduceUp(UnifyPair pair);
|
||||
public Optional<UnifyPair> reduceLow(UnifyPair pair);
|
||||
public Optional<UnifyPair> reduceUpLow(UnifyPair pair);
|
||||
public Optional<Set<UnifyPair>> reduceExt(UnifyPair pair, IFiniteClosure fc);
|
||||
public Optional<Set<UnifyPair>> reduceSup(UnifyPair pair, IFiniteClosure fc);
|
||||
public Optional<Set<UnifyPair>> reduceEq(UnifyPair pair);
|
||||
public Optional<Set<UnifyPair>> reduce1(UnifyPair pair, IFiniteClosure fc);
|
||||
public Optional<Set<UnifyPair>> reduce2(UnifyPair pair);
|
||||
Optional<UnifyPair> reduceUp(UnifyPair pair);
|
||||
|
||||
Optional<UnifyPair> reduceLow(UnifyPair pair);
|
||||
|
||||
Optional<UnifyPair> reduceUpLow(UnifyPair pair);
|
||||
|
||||
Optional<Set<UnifyPair>> reduceExt(UnifyPair pair, IFiniteClosure fc);
|
||||
|
||||
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
|
||||
*/
|
||||
public Optional<UnifyPair> reduceWildcardLow(UnifyPair pair);
|
||||
public Optional<UnifyPair> reduceWildcardLowRight(UnifyPair pair);
|
||||
public Optional<UnifyPair> reduceWildcardUp(UnifyPair pair);
|
||||
public Optional<UnifyPair> reduceWildcardUpRight(UnifyPair pair);
|
||||
Optional<UnifyPair> reduceWildcardLow(UnifyPair pair);
|
||||
|
||||
Optional<UnifyPair> reduceWildcardLowRight(UnifyPair pair);
|
||||
|
||||
Optional<UnifyPair> reduceWildcardUp(UnifyPair pair);
|
||||
|
||||
Optional<UnifyPair> reduceWildcardUpRight(UnifyPair pair);
|
||||
|
||||
/*
|
||||
* vgl. JAVA_BSP/Wildcard6.java
|
||||
public Optional<UnifyPair> reduceWildcardLowUp(UnifyPair pair);
|
||||
public Optional<UnifyPair> reduceWildcardUpLow(UnifyPair pair);
|
||||
public Optional<UnifyPair> reduceWildcardLeft(UnifyPair pair);
|
||||
Optional<UnifyPair> reduceWildcardLowUp(UnifyPair pair);
|
||||
Optional<UnifyPair> reduceWildcardUpLow(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)
|
||||
*/
|
||||
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)
|
||||
*/
|
||||
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)
|
||||
*/
|
||||
public Optional<Set<UnifyPair>> reduceTphSup(UnifyPair pair);
|
||||
Optional<Set<UnifyPair>> reduceTphSup(UnifyPair pair);
|
||||
|
||||
/*
|
||||
* FunN Rules
|
||||
*/
|
||||
public Optional<Set<UnifyPair>> reduceFunN(UnifyPair pair);
|
||||
public Optional<Set<UnifyPair>> greaterFunN(UnifyPair pair);
|
||||
public Optional<Set<UnifyPair>> smallerFunN(UnifyPair pair);
|
||||
Optional<Set<UnifyPair>> reduceFunN(UnifyPair pair);
|
||||
|
||||
Optional<Set<UnifyPair>> greaterFunN(UnifyPair pair);
|
||||
|
||||
Optional<Set<UnifyPair>> smallerFunN(UnifyPair pair);
|
||||
|
||||
/**
|
||||
* Checks whether the erase1-Rule applies to the pair.
|
||||
*
|
||||
* @return True if the pair is erasable, false otherwise.
|
||||
*/
|
||||
public boolean erase1(UnifyPair pair, IFiniteClosure fc);
|
||||
boolean erase1(UnifyPair pair, IFiniteClosure fc);
|
||||
|
||||
/**
|
||||
* Checks whether the erase2-Rule applies to the pair.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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);
|
||||
public Optional<UnifyPair> adaptExt(UnifyPair pair, IFiniteClosure fc);
|
||||
public Optional<UnifyPair> adaptSup(UnifyPair pair, IFiniteClosure fc);
|
||||
Optional<UnifyPair> adapt(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').
|
||||
*
|
||||
* @param pairs The set of pairs where the subst rule should apply.
|
||||
* @return An optional of the modified set, if there were any substitutions. An empty optional if there were no substitutions.
|
||||
*/
|
||||
public Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs, 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').
|
||||
*
|
||||
* @param pairs The set of pairs where the subst rule should apply.
|
||||
* @return An optional of the modified set, if there were any substitutions. An empty optional if there were no substitutions.
|
||||
*/
|
||||
public Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs);
|
||||
Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs);
|
||||
}
|
@@ -5,11 +5,13 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* Contains operations on sets.
|
||||
*
|
||||
* @author Florian Steurer
|
||||
*/
|
||||
public interface ISetOperations {
|
||||
/**
|
||||
* Calculates the cartesian product of the sets.
|
||||
*
|
||||
* @return The cartesian product
|
||||
*/
|
||||
<B> Set<List<B>> cartesianProduct(List<? extends Set<? extends B>> sets);
|
||||
|
@@ -10,6 +10,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Standard unification algorithm (e.g. Robinson, Paterson-Wegman, Martelli-Montanari)
|
||||
*
|
||||
* @author Florian Steurer
|
||||
*/
|
||||
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
|
||||
* sigma(t1) = sigma(t1') , ... sigma(tn) = sigma(tn').
|
||||
*
|
||||
* @param terms The set of terms to be unified
|
||||
* @return An optional of the most general unifier if it exists or an empty optional if there is no unifier.
|
||||
*/
|
||||
public Optional<Unifier> unify(Set<UnifyType> terms);
|
||||
Optional<Unifier> unify(Set<UnifyType> terms);
|
||||
|
||||
/**
|
||||
* Finds the most general unifier sigma of the set {t1 =. t1',...,tn =. tn'} so that
|
||||
* sigma(t1) = sigma(t1') , ... sigma(tn) = sigma(tn').
|
||||
*
|
||||
* @param terms The set of terms to be unified
|
||||
* @return An optional of the most general unifier if it exists or an empty optional if there is no unifier.
|
||||
*/
|
||||
default public Optional<Unifier> unify(UnifyType... terms) {
|
||||
default Optional<Unifier> unify(UnifyType... terms) {
|
||||
return unify(Arrays.stream(terms).collect(Collectors.toSet()));
|
||||
}
|
||||
|
||||
|
@@ -4,14 +4,14 @@ import de.dhbwstuttgart.typeinference.unify.model.*;
|
||||
|
||||
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);
|
||||
|
||||
}
|
@@ -10,12 +10,9 @@ import java.util.Set;
|
||||
*/
|
||||
public final class ExtendsType extends WildcardType {
|
||||
|
||||
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
|
||||
return visitor.visit(this, ht);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new extends wildcard type.
|
||||
*
|
||||
* @param extendedType The extended type e.g. Integer in "? extends Integer"
|
||||
*/
|
||||
public ExtendsType(UnifyType extendedType) {
|
||||
@@ -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"
|
||||
*/
|
||||
@@ -38,7 +39,7 @@ public final class ExtendsType extends WildcardType {
|
||||
@Override
|
||||
public UnifyType setTypeParams(TypeParams newTp) {
|
||||
UnifyType newType = wildcardedType.setTypeParams(newTp);
|
||||
if(newType == wildcardedType)
|
||||
if (newType == wildcardedType)
|
||||
return this; // Reduced the amount of objects created
|
||||
return new ExtendsType(wildcardedType.setTypeParams(newTp));
|
||||
}
|
||||
@@ -54,9 +55,9 @@ public final class ExtendsType extends WildcardType {
|
||||
}
|
||||
|
||||
@Override
|
||||
UnifyType apply(Unifier unif) {
|
||||
UnifyType newType = wildcardedType.apply(unif);
|
||||
if(newType.hashCode() == wildcardedType.hashCode() && newType.equals(wildcardedType))
|
||||
UnifyType apply(Unifier unifier) {
|
||||
UnifyType newType = wildcardedType.apply(unifier);
|
||||
if (newType.hashCode() == wildcardedType.hashCode() && newType.equals(wildcardedType))
|
||||
return this; // Reduced the amount of objects created
|
||||
return new ExtendsType(newType);
|
||||
}
|
||||
@@ -72,15 +73,12 @@ public final class ExtendsType extends WildcardType {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof ExtendsType))
|
||||
if (!(obj instanceof ExtendsType other))
|
||||
return false;
|
||||
|
||||
if(obj.hashCode() != this.hashCode())
|
||||
if (obj.hashCode() != this.hashCode())
|
||||
return false;
|
||||
|
||||
ExtendsType other = (ExtendsType) obj;
|
||||
|
||||
|
||||
return other.getWildcardedType().equals(wildcardedType);
|
||||
}
|
||||
|
||||
|
@@ -14,39 +14,31 @@ import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* The finite closure for the type unification
|
||||
*
|
||||
* @author Florian Steurer
|
||||
*/
|
||||
public class FiniteClosure //extends Ordering<UnifyType> //entfernt PL 2018-12-11
|
||||
implements IFiniteClosure {
|
||||
public class FiniteClosure implements IFiniteClosure {
|
||||
|
||||
Writer logFile;
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
private HashMap<String, Set<Node<UnifyType>>> strInheritanceGraph;
|
||||
|
||||
|
||||
private final HashMap<String, Set<Node<UnifyType>>> strInheritanceGraph;
|
||||
/**
|
||||
* 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<>();
|
||||
|
||||
/**
|
||||
* 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<>();
|
||||
|
||||
@@ -56,23 +48,12 @@ implements IFiniteClosure {
|
||||
public FiniteClosure(Set<UnifyPair> pairs, Writer logFile) {
|
||||
this.logFile = logFile;
|
||||
this.pairs = new HashSet<>(pairs);
|
||||
inheritanceGraph = new HashMap<UnifyType, Node<UnifyType>>();
|
||||
inheritanceGraph = new HashMap<>();
|
||||
|
||||
// Build the transitive closure of the inheritance tree
|
||||
for(UnifyPair pair : pairs) {
|
||||
for (UnifyPair pair : pairs) {
|
||||
|
||||
/*
|
||||
try {
|
||||
logFile.write("Pair: " + pair + "\n");
|
||||
logFile.flush();
|
||||
}
|
||||
catch (IOException e) {
|
||||
System.err.println("no LogFile");
|
||||
}
|
||||
*/
|
||||
|
||||
if(pair.getPairOp() != PairOperator.SMALLER)
|
||||
continue;
|
||||
if (pair.getPairOp() != PairOperator.SMALLER) continue;
|
||||
|
||||
//VERSUCH PL 18-02-06
|
||||
//koennte ggf. die FC reduzieren
|
||||
@@ -80,12 +61,12 @@ implements IFiniteClosure {
|
||||
//if (!pair.getLhsType().getTypeParams().arePlaceholders()
|
||||
// && !pair.getRhsType().getTypeParams().arePlaceholders())
|
||||
// continue;
|
||||
;
|
||||
|
||||
// Add nodes if not already in the graph
|
||||
if(!inheritanceGraph.containsKey(pair.getLhsType()))
|
||||
inheritanceGraph.put(pair.getLhsType(), new Node<UnifyType>(pair.getLhsType()));
|
||||
if(!inheritanceGraph.containsKey(pair.getRhsType()))
|
||||
inheritanceGraph.put(pair.getRhsType(), new Node<UnifyType>(pair.getRhsType()));
|
||||
if (!inheritanceGraph.containsKey(pair.getLhsType()))
|
||||
inheritanceGraph.put(pair.getLhsType(), new Node<>(pair.getLhsType()));
|
||||
if (!inheritanceGraph.containsKey(pair.getRhsType()))
|
||||
inheritanceGraph.put(pair.getRhsType(), new Node<>(pair.getRhsType()));
|
||||
|
||||
Node<UnifyType> childNode = inheritanceGraph.get(pair.getLhsType());
|
||||
Node<UnifyType> parentNode = inheritanceGraph.get(pair.getRhsType());
|
||||
@@ -94,38 +75,40 @@ implements IFiniteClosure {
|
||||
parentNode.addDescendant(childNode);
|
||||
|
||||
// Add edges to build the transitive closure
|
||||
parentNode.getPredecessors().stream().forEach(x -> x.addDescendant(childNode));
|
||||
childNode.getDescendants().stream().forEach(x -> x.addPredecessor(parentNode));
|
||||
parentNode.getPredecessors().forEach(x -> x.addDescendant(childNode));
|
||||
childNode.getDescendants().forEach(x -> x.addPredecessor(parentNode));
|
||||
|
||||
//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());};
|
||||
if (y.getPredecessors().contains(childNode)) { y.addPredecessor(parentNode); y.addAllPredecessor(parentNode.getPredecessors());};} );
|
||||
this.inheritanceGraph.forEach((x, y) -> {
|
||||
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
|
||||
strInheritanceGraph = new HashMap<>();
|
||||
for(UnifyType key : inheritanceGraph.keySet()) {
|
||||
if(!strInheritanceGraph.containsKey(key.getName()))
|
||||
for (UnifyType key : inheritanceGraph.keySet()) {
|
||||
if (!strInheritanceGraph.containsKey(key.getName())) {
|
||||
strInheritanceGraph.put(key.getName(), new HashSet<>());
|
||||
}
|
||||
|
||||
strInheritanceGraph.get(key.getName()).add(inheritanceGraph.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
void testSmaller() {
|
||||
UnifyType tq1, tq2, tq3;
|
||||
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<>());
|
||||
public void setLogTrue() {
|
||||
log = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all types of the finite closure that are subtypes of the argument.
|
||||
*
|
||||
* @return The set of subtypes of the argument.
|
||||
*/
|
||||
@Override
|
||||
@@ -133,14 +116,12 @@ implements IFiniteClosure {
|
||||
|
||||
Set<UnifyType> ret;
|
||||
if ((ret = smallerHash.get(new hashKeyType(type))) != null) {
|
||||
//System.out.println(greaterHash);
|
||||
return new HashSet<>(ret);
|
||||
}
|
||||
|
||||
if(type instanceof FunNType)
|
||||
return computeSmallerFunN((FunNType) type, fBounded);
|
||||
if (type instanceof FunNType) 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));
|
||||
Set<UnifyType> result = computeSmaller(ts);
|
||||
smallerHash.put(new hashKeyType(type), result);
|
||||
@@ -158,63 +139,61 @@ implements IFiniteClosure {
|
||||
/**
|
||||
* Computes the smaller functions for every type except FunNTypes.
|
||||
*/
|
||||
private Set<UnifyType> computeSmaller(Set<Pair<UnifyType,Set<UnifyType>>> types) {
|
||||
Set<Pair<UnifyType,Set<UnifyType>>> result = new HashSet<>();
|
||||
private Set<UnifyType> computeSmaller(Set<Pair<UnifyType, Set<UnifyType>>> types) {
|
||||
Set<Pair<UnifyType, Set<UnifyType>>> result = new HashSet<>();
|
||||
|
||||
//PL 18-02-05 Unifier durch Matcher ersetzt
|
||||
//IUnify unify = new MartelliMontanariUnify();
|
||||
Match match = new Match();
|
||||
|
||||
for(Pair<UnifyType,Set<UnifyType>> pt : types) {
|
||||
for (Pair<UnifyType, Set<UnifyType>> pt : types) {
|
||||
UnifyType t = pt.getKey();
|
||||
Set<UnifyType> fBounded = pt.getValue().get();
|
||||
|
||||
// if T = T' then T <* T'
|
||||
try {
|
||||
result.add(new Pair<>(t, fBounded));
|
||||
}
|
||||
catch (StackOverflowError e) {
|
||||
System.out.println("");
|
||||
}
|
||||
|
||||
// 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<>();
|
||||
for (int i = 0; i < t.getTypeParams().size(); i++)
|
||||
paramCandidates.add(smArg(t.getTypeParams().get(i), fBounded));
|
||||
permuteParams(paramCandidates).forEach(x -> result.add(new Pair<>(t.setTypeParams(x), fBounded)));
|
||||
}
|
||||
|
||||
if(!strInheritanceGraph.containsKey(t.getName()))
|
||||
continue;
|
||||
if (!strInheritanceGraph.containsKey(t.getName())) continue;
|
||||
|
||||
// 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>)
|
||||
//]
|
||||
for(Node<UnifyType> candidate : candidates) {
|
||||
// ]
|
||||
|
||||
for (Node<UnifyType> candidate : candidates) {
|
||||
UnifyType theta2 = candidate.getContent();
|
||||
//PL 18-02-05 Unifier durch Matcher ersetzt ANFANG
|
||||
ArrayList<UnifyPair> termList= new ArrayList<UnifyPair>();
|
||||
termList.add(new UnifyPair(theta2,t, PairOperator.EQUALSDOT));
|
||||
ArrayList<UnifyPair> termList = new ArrayList<UnifyPair>();
|
||||
termList.add(new UnifyPair(theta2, t, PairOperator.EQUALSDOT));
|
||||
Optional<Unifier> optSigma = match.match(termList);
|
||||
//PL 18-02-05 Unifier durch Matcher ersetzt ENDE
|
||||
if(!optSigma.isPresent())
|
||||
continue;
|
||||
if (optSigma.isEmpty()) continue;
|
||||
|
||||
Unifier sigma = optSigma.get();
|
||||
sigma.swapPlaceholderSubstitutions(t.getTypeParams());
|
||||
|
||||
Set<UnifyType> theta1Set = candidate.getContentOfDescendants();
|
||||
|
||||
for(UnifyType theta1 : theta1Set)
|
||||
for (UnifyType theta1 : theta1Set)
|
||||
result.add(new Pair<>(theta1.apply(sigma), fBounded));
|
||||
}
|
||||
}
|
||||
|
||||
HashSet<UnifyType> resut = result.stream().map(x -> x.getKey()).collect(Collectors.toCollection(HashSet::new));
|
||||
if(resut.equals(types.stream().map(x -> x.getKey()).collect(Collectors.toCollection(HashSet::new))))
|
||||
return resut;
|
||||
HashSet<UnifyType> resultKeys = result.stream().map(Pair::getKey).collect(Collectors.toCollection(HashSet::new));
|
||||
if (resultKeys.equals(types.stream().map(Pair::getKey).collect(Collectors.toCollection(HashSet::new)))) {
|
||||
return resultKeys;
|
||||
}
|
||||
|
||||
return computeSmaller(result);
|
||||
}
|
||||
|
||||
@@ -231,8 +210,9 @@ implements IFiniteClosure {
|
||||
// it is enough to permute the params with the values of greater / smaller.
|
||||
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
||||
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<>()));
|
||||
}
|
||||
|
||||
permuteParams(paramCandidates).forEach(x -> result.add(type.setTypeParams(x)));
|
||||
return result;
|
||||
@@ -240,6 +220,7 @@ implements IFiniteClosure {
|
||||
|
||||
/**
|
||||
* Returns all types of the finite closure that are supertypes of the argument.
|
||||
*
|
||||
* @return The set of supertypes of the argument.
|
||||
*/
|
||||
@Override
|
||||
@@ -248,25 +229,21 @@ implements IFiniteClosure {
|
||||
|
||||
Set<UnifyType> ret;
|
||||
if ((ret = greaterHash.get(new hashKeyType(type))) != null) {
|
||||
//System.out.println(greaterHash);
|
||||
return new HashSet<>(ret);
|
||||
}
|
||||
|
||||
|
||||
if(type instanceof FunNType) {
|
||||
if (type instanceof FunNType) {
|
||||
return computeGreaterFunN((FunNType) type, fBounded);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
|
||||
// if T = T' then T <=* T'
|
||||
result.add(type);
|
||||
if(!strInheritanceGraph.containsKey(type.getName()))
|
||||
return result;
|
||||
if (!strInheritanceGraph.containsKey(type.getName())) return result;
|
||||
|
||||
// if T <* T' then sigma(T) <* sigma(T')
|
||||
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();
|
||||
|
||||
//PL 18-04-05 Unifier durch Matcher ersetzt ANFANG
|
||||
ArrayList<UnifyPair> termList= new ArrayList<UnifyPair>();
|
||||
termList.add(new UnifyPair(theta1,type, PairOperator.EQUALSDOT));
|
||||
ArrayList<UnifyPair> termList = new ArrayList<UnifyPair>();
|
||||
termList.add(new UnifyPair(theta1, type, PairOperator.EQUALSDOT));
|
||||
Optional<Unifier> optSigma = match.match(termList);
|
||||
//PL 18-04-05 Unifier durch Matcher ersetzt ENDE
|
||||
if(!optSigma.isPresent()) {
|
||||
if (optSigma.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
Unifier sigma = optSigma.get();
|
||||
@@ -299,7 +276,7 @@ implements IFiniteClosure {
|
||||
fBoundedNew.add(theta1);
|
||||
Set<UnifyType> theta2Set = candidate.getContentOfPredecessors();
|
||||
//System.out.println("");
|
||||
for(UnifyType theta2 : theta2Set) {
|
||||
for (UnifyType theta2 : theta2Set) {
|
||||
result.add(theta2.apply(sigma));
|
||||
PairResultFBounded.add(new Pair<>(theta2.apply(sigma), fBoundedNew));
|
||||
}
|
||||
@@ -313,35 +290,33 @@ implements IFiniteClosure {
|
||||
System.err.println("no LogFile");
|
||||
}
|
||||
*/
|
||||
for(Pair<UnifyType,Set<UnifyType>> pt : PairResultFBounded) {
|
||||
for (Pair<UnifyType, Set<UnifyType>> pt : PairResultFBounded) {
|
||||
UnifyType t = pt.getKey();
|
||||
Set<UnifyType> lfBounded = pt.getValue().get();
|
||||
|
||||
// if C<...> <* C<...> then ... (third case in definition of <*)
|
||||
//TypeParams typeparams = t.getTypeParams();
|
||||
if(t.getTypeParams().size() > 0) {
|
||||
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) ->
|
||||
{
|
||||
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));
|
||||
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 (lfBounded.stream().reduce(false,f,bo)) {
|
||||
BinaryOperator<Boolean> bo = (a, b) -> (a || b);
|
||||
if (lfBounded.stream().reduce(false, f, bo)) {
|
||||
//F-Bounded Endlosrekursion
|
||||
HashSet<UnifyType> res = new HashSet<UnifyType>();
|
||||
paramCandidates.add(res);
|
||||
}
|
||||
else {
|
||||
paramCandidates.add(grArg(t.getTypeParams().get(i), new HashSet<>(fBounded) ));
|
||||
} else {
|
||||
paramCandidates.add(grArg(t.getTypeParams().get(i), new HashSet<>(fBounded)));
|
||||
}
|
||||
}
|
||||
permuteParams(paramCandidates).forEach(x -> result.add(t.setTypeParams(x)));
|
||||
@@ -361,96 +336,6 @@ implements IFiniteClosure {
|
||||
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
|
||||
*/
|
||||
@@ -481,7 +366,7 @@ implements IFiniteClosure {
|
||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||
result.add(type);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -558,7 +443,7 @@ implements IFiniteClosure {
|
||||
result.add(type);
|
||||
UnifyType t = type.getSuperedType();
|
||||
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 -> {
|
||||
result.add(new SuperType(x));
|
||||
result.add(x);
|
||||
@@ -575,18 +460,16 @@ implements IFiniteClosure {
|
||||
|
||||
@Override
|
||||
public Set<UnifyType> getAllTypesByName(String typeName) {
|
||||
if(!strInheritanceGraph.containsKey(typeName))
|
||||
return new HashSet<>();
|
||||
return strInheritanceGraph.get(typeName).stream().map(x -> x.getContent()).collect(Collectors.toCollection(HashSet::new));
|
||||
if (!strInheritanceGraph.containsKey(typeName)) return new HashSet<>();
|
||||
return strInheritanceGraph.get(typeName).stream().map(Node::getContent).collect(Collectors.toCollection(HashSet::new));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<UnifyType> getLeftHandedType(String typeName) {
|
||||
if(!strInheritanceGraph.containsKey(typeName))
|
||||
return Optional.empty();
|
||||
if (!strInheritanceGraph.containsKey(typeName)) return Optional.empty();
|
||||
|
||||
for(UnifyPair pair : pairs)
|
||||
if(pair.getLhsType().getName().equals(typeName) && pair.getLhsType().typeParams.arePlaceholders())
|
||||
for (UnifyPair pair : pairs)
|
||||
if (pair.getLhsType().getName().equals(typeName) && pair.getLhsType().typeParams.arePlaceholders())
|
||||
return Optional.of(pair.getLhsType());
|
||||
|
||||
return Optional.empty();
|
||||
@@ -594,8 +477,7 @@ implements IFiniteClosure {
|
||||
|
||||
@Override
|
||||
public Set<UnifyType> getAncestors(UnifyType t) {
|
||||
if(!inheritanceGraph.containsKey(t))
|
||||
return new HashSet<>();
|
||||
if (!inheritanceGraph.containsKey(t)) return new HashSet<>();
|
||||
Set<UnifyType> result = inheritanceGraph.get(t).getContentOfPredecessors();
|
||||
result.add(t);
|
||||
return result;
|
||||
@@ -603,8 +485,7 @@ implements IFiniteClosure {
|
||||
|
||||
@Override
|
||||
public Set<UnifyType> getChildren(UnifyType t) {
|
||||
if(!inheritanceGraph.containsKey(t))
|
||||
return new HashSet<>();
|
||||
if (!inheritanceGraph.containsKey(t)) return new HashSet<>();
|
||||
Set<UnifyType> result = inheritanceGraph.get(t).getContentOfDescendants();
|
||||
result.add(t);
|
||||
return result;
|
||||
@@ -612,6 +493,7 @@ implements IFiniteClosure {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* @param candidates The length of the list determines the number of type params. Each set
|
||||
* contains the candidates for the corresponding position.
|
||||
* @param idx Idx for the current permutatiton.
|
||||
@@ -630,84 +513,44 @@ implements IFiniteClosure {
|
||||
* @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) {
|
||||
if(candidates.size() == idx) {
|
||||
if (candidates.size() == idx) {
|
||||
result.add(new TypeParams(Arrays.copyOf(current, current.length)));
|
||||
return;
|
||||
}
|
||||
|
||||
Set<UnifyType> localCandidates = candidates.get(idx);
|
||||
|
||||
for(UnifyType t : localCandidates) {
|
||||
for (UnifyType t : localCandidates) {
|
||||
current[idx] = t;
|
||||
permuteParams(candidates, idx+1, result, current);
|
||||
permuteParams(candidates, idx + 1, result, current);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
public String toString() {
|
||||
return this.inheritanceGraph.toString();
|
||||
}
|
||||
|
||||
/* entfernt PL 2018-12-11
|
||||
public int compare (UnifyType left, UnifyType right) {
|
||||
return compare(left, right, PairOperator.SMALLERDOT);
|
||||
}
|
||||
*/
|
||||
public int compare(UnifyType left, UnifyType right, PairOperator pairOp) {
|
||||
|
||||
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
|
||||
UnifyType ex;
|
||||
if (left instanceof PlaceholderType) {
|
||||
if ((right instanceof WildcardType)
|
||||
&& ((ex = ((WildcardType)right).wildcardedType) instanceof PlaceholderType)
|
||||
&& ((PlaceholderType)left).getName().equals(((PlaceholderType)ex).getName())) {// a <.? ? extends a oder a <.? ? super a
|
||||
if ((right instanceof WildcardType) && ((ex = ((WildcardType) right).wildcardedType) instanceof PlaceholderType) && left.getName().equals(ex.getName())) {// a <.? ? extends a oder a <.? ? super a
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
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
|
||||
&& ((ex = ((WildcardType)left).wildcardedType) instanceof PlaceholderType)
|
||||
&& ((PlaceholderType)right).getName().equals(((PlaceholderType)ex).getName())) {// ? extends a <. a oder ? super a <. a
|
||||
&& ((ex = ((WildcardType) left).wildcardedType) instanceof PlaceholderType) && right.getName().equals(ex.getName())) {// ? extends a <. a oder ? super a <. a
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
UnifyPair up = new UnifyPair(left, right, pairop);
|
||||
UnifyPair up = new UnifyPair(left, right, pairOp);
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask();
|
||||
HashSet<UnifyPair> hs = new HashSet<>();
|
||||
hs.add(up);
|
||||
@@ -722,15 +565,12 @@ implements IFiniteClosure {
|
||||
System.err.println("no LogFile");}}
|
||||
*/
|
||||
//Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok.
|
||||
Predicate<UnifyPair> delFun = x -> !((x.getLhsType() instanceof PlaceholderType ||
|
||||
x.getRhsType() instanceof PlaceholderType)
|
||||
&& !((x.getLhsType() instanceof WildcardType) && //? extends/super a <.? a
|
||||
((WildcardType)x.getLhsType()).getWildcardedType().equals(x.getRhsType()))
|
||||
);
|
||||
Predicate<UnifyPair> delFun = x -> !((x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType) && !((x.getLhsType() instanceof WildcardType) && //? extends/super a <.? a
|
||||
((WildcardType) x.getLhsType()).getWildcardedType().equals(x.getRhsType())));
|
||||
long smallerLen = smallerRes.stream().filter(delFun).count();
|
||||
if (smallerLen == 0) return -1;
|
||||
else {
|
||||
up = new UnifyPair(right, left, pairop);
|
||||
up = new UnifyPair(right, left, pairOp);
|
||||
//TypeUnifyTask unifyTask = new TypeUnifyTask();
|
||||
hs = new HashSet<>();
|
||||
hs.add(up);
|
||||
@@ -744,6 +584,7 @@ implements IFiniteClosure {
|
||||
catch (IOException e) {
|
||||
System.err.println("no LogFile");}}
|
||||
*/
|
||||
|
||||
//Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok.
|
||||
long greaterLen = greaterRes.stream().filter(delFun).count();
|
||||
if (greaterLen == 0) return 1;
|
||||
|
@@ -5,50 +5,53 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A real function type in java.
|
||||
*
|
||||
* @author Florian Steurer
|
||||
*/
|
||||
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) {
|
||||
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>.
|
||||
*/
|
||||
public int getN() {
|
||||
return typeParams.size()-1;
|
||||
return typeParams.size() - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnifyType setTypeParams(TypeParams newTp) {
|
||||
if(newTp.hashCode() == typeParams.hashCode() && newTp.equals(typeParams))
|
||||
if (newTp.hashCode() == typeParams.hashCode() && newTp.equals(typeParams))
|
||||
return this;
|
||||
return getFunNType(newTp);
|
||||
}
|
||||
@@ -64,11 +67,11 @@ public class FunNType extends UnifyType {
|
||||
}
|
||||
|
||||
@Override
|
||||
UnifyType apply(Unifier unif) {
|
||||
UnifyType apply(Unifier unifier) {
|
||||
// TODO this bypasses the validation of the type parameters.
|
||||
// Wildcard types can be unified into FunNTypes.
|
||||
TypeParams newParams = typeParams.apply(unif);
|
||||
if(newParams.hashCode() == typeParams.hashCode() && newParams.equals(typeParams))
|
||||
TypeParams newParams = typeParams.apply(unifier);
|
||||
if (newParams.hashCode() == typeParams.hashCode() && newParams.equals(typeParams))
|
||||
return this;
|
||||
|
||||
return new FunNType(newParams);
|
||||
@@ -76,8 +79,8 @@ public class FunNType extends UnifyType {
|
||||
|
||||
@Override
|
||||
public Boolean wrongWildcard() {
|
||||
return (new ArrayList<UnifyType>(Arrays.asList(getTypeParams()
|
||||
.get())).stream().filter(x -> (x instanceof WildcardType)).findFirst().isPresent());
|
||||
List<UnifyType> typeParamList = new ArrayList<>(Arrays.asList(getTypeParams().get()));
|
||||
return typeParamList.stream().anyMatch(x -> (x instanceof WildcardType));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -88,14 +91,12 @@ public class FunNType extends UnifyType {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof FunNType))
|
||||
if (!(obj instanceof FunNType other))
|
||||
return false;
|
||||
|
||||
if(obj.hashCode() != this.hashCode())
|
||||
if (obj.hashCode() != this.hashCode())
|
||||
return false;
|
||||
|
||||
FunNType other = (FunNType) obj;
|
||||
|
||||
return other.getTypeParams().equals(typeParams);
|
||||
}
|
||||
|
||||
|
@@ -6,26 +6,26 @@ import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* A node of a directed graph.
|
||||
* @author Florian Steurer
|
||||
*
|
||||
* @param <T> The type of the content of the node.
|
||||
* @author Florian Steurer
|
||||
*/
|
||||
class Node<T> {
|
||||
|
||||
/**
|
||||
* The content of the node.
|
||||
*/
|
||||
private T content;
|
||||
private final T content;
|
||||
|
||||
/**
|
||||
* The set of predecessors
|
||||
*/
|
||||
private HashSet<Node<T>> predecessors = new HashSet<>();
|
||||
private final HashSet<Node<T>> predecessors = new HashSet<>();
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -38,7 +38,7 @@ class Node<T> {
|
||||
* Adds a directed edge from this node to the descendant (this -> descendant)
|
||||
*/
|
||||
public void addDescendant(Node<T> descendant) {
|
||||
if(descendants.contains(descendant))
|
||||
if (descendants.contains(descendant))
|
||||
return;
|
||||
|
||||
descendants.add(descendant);
|
||||
@@ -49,7 +49,7 @@ class Node<T> {
|
||||
* Adds some directed edges from this node to the descendant (this -> descendant)
|
||||
*/
|
||||
public void addAllDescendant(Set<Node<T>> allDescendants) {
|
||||
for(Node<T> descendant: allDescendants) {
|
||||
for (Node<T> descendant : allDescendants) {
|
||||
addDescendant(descendant);
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ class Node<T> {
|
||||
* Adds a directed edge from the predecessor to this node (predecessor -> this)
|
||||
*/
|
||||
public void addPredecessor(Node<T> predecessor) {
|
||||
if(predecessors.contains(predecessor))
|
||||
if (predecessors.contains(predecessor))
|
||||
return;
|
||||
|
||||
predecessors.add(predecessor);
|
||||
@@ -69,50 +69,51 @@ class Node<T> {
|
||||
* Adds some directed edges from the predecessor to this node (predecessor -> this)
|
||||
*/
|
||||
public void addAllPredecessor(Set<Node<T>> allPredecessors) {
|
||||
for(Node<T> predecessor: allPredecessors) {
|
||||
for (Node<T> predecessor : allPredecessors) {
|
||||
addPredecessor(predecessor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The content of this node.
|
||||
* @return The content of this node.
|
||||
*/
|
||||
public T getContent() {
|
||||
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() {
|
||||
return predecessors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all descendants. All nodes M, where there is a edge from this node to the node M.
|
||||
* @return
|
||||
* @return All nodes M, where there is an edge from this node to the node M.
|
||||
*/
|
||||
public Set<Node<T>> getDescendants() {
|
||||
return descendants;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the content of all descendants.
|
||||
* @return The content of all descendants.
|
||||
*/
|
||||
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() {
|
||||
return predecessors.stream().map(x -> x.getContent()).collect(Collectors.toSet());
|
||||
return predecessors.stream().map(Node::getContent).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Elem: Node(" + content.toString() + ")\nPrec: " + getContentOfPredecessors().toString()
|
||||
+ "\nDesc: " + getContentOfDescendants().toString() + "\n\n";
|
||||
return
|
||||
"Elem: Node(" + content.toString() + ")\n" +
|
||||
"Prec: " + getContentOfPredecessors().toString() + "\n" +
|
||||
"Desc: " + getContentOfDescendants().toString() + "\n\n";
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -2,6 +2,7 @@ package de.dhbwstuttgart.typeinference.unify.model;
|
||||
|
||||
/**
|
||||
* Operators of pairs of the unification.
|
||||
*
|
||||
* @author Florian Steurer
|
||||
*/
|
||||
public enum PairOperator {
|
||||
@@ -38,12 +39,12 @@ public enum PairOperator {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
switch (this) {
|
||||
case SMALLER: return "<";
|
||||
case SMALLERDOT: return "<.";
|
||||
case SMALLERNEQDOT: return "<!=.";
|
||||
case SMALLERDOTWC: return "<.?";
|
||||
default: return "=."; // EQUALSDOT
|
||||
}
|
||||
return switch (this) {
|
||||
case SMALLER -> "<";
|
||||
case SMALLERDOT -> "<.";
|
||||
case SMALLERNEQDOT -> "<!=.";
|
||||
case SMALLERDOTWC -> "<.?";
|
||||
default -> "=."; // EQUALSDOT
|
||||
};
|
||||
}
|
||||
}
|
@@ -10,9 +10,10 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* An unbounded placeholder type.
|
||||
*
|
||||
* @author Florian Steurer
|
||||
*/
|
||||
public final class PlaceholderType extends UnifyType{
|
||||
public final class PlaceholderType extends UnifyType {
|
||||
|
||||
/**
|
||||
* 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>();
|
||||
|
||||
/**
|
||||
* Prefix of auto-generated placeholder names.
|
||||
*/
|
||||
protected static String nextName = "gen_";
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -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;
|
||||
|
||||
@@ -56,7 +52,7 @@ public final class PlaceholderType extends UnifyType{
|
||||
private int variance = 0;
|
||||
|
||||
/*
|
||||
* Fuer Oder-Constraints:
|
||||
* For Oder-Constraints:
|
||||
* orCons = 1: Receiver
|
||||
* orCons = 0: Argument oder kein Oder-Constraint
|
||||
* orCons = -1: RetType
|
||||
@@ -74,6 +70,7 @@ public final class PlaceholderType extends UnifyType{
|
||||
|
||||
/**
|
||||
* Creates a new placeholdertype
|
||||
*
|
||||
* @param isGenerated true if this placeholder is auto-generated, false if it is user-generated.
|
||||
*/
|
||||
public PlaceholderType(String name, boolean isGenerated) {
|
||||
@@ -82,24 +79,24 @@ public final class PlaceholderType extends UnifyType{
|
||||
IsGenerated = isGenerated;
|
||||
}
|
||||
|
||||
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
|
||||
return visitor.visit(this, ht);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fresh placeholder type with a name that does so far not exist.
|
||||
* A user could later instantiate a type using the same name that is equivalent to this type.
|
||||
*
|
||||
* @return A fresh placeholder type.
|
||||
*/
|
||||
public synchronized static PlaceholderType freshPlaceholder() {
|
||||
String name = nextName + (char) (rnd.nextInt(22) + 97); // Returns random char between 'a' and 'z'
|
||||
String name = "gen_" + (char) (rnd.nextInt(22) + 97); // Returns random char between 'a' and 'z'
|
||||
// Add random chars while the name is in use.
|
||||
while(EXISTING_PLACEHOLDERS.contains(name)) {
|
||||
while (EXISTING_PLACEHOLDERS.contains(name)) {
|
||||
name += (char) (rnd.nextInt(22) + 97); // Returns random char between 'a' and 'z'
|
||||
}
|
||||
return new PlaceholderType(name, true);
|
||||
}
|
||||
|
||||
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
|
||||
return visitor.visit(this, ht);
|
||||
}
|
||||
|
||||
/**
|
||||
* True if this placeholder is auto-generated, false if it is user-generated.
|
||||
@@ -108,44 +105,42 @@ public final class PlaceholderType extends UnifyType{
|
||||
return IsGenerated;
|
||||
}
|
||||
|
||||
public void setVariance(int v) {
|
||||
variance = v;
|
||||
}
|
||||
|
||||
public int getVariance() {
|
||||
return variance;
|
||||
}
|
||||
|
||||
public void setVariance(int v) {
|
||||
variance = v;
|
||||
}
|
||||
|
||||
public void reversVariance() {
|
||||
if (variance == 1) {
|
||||
setVariance(-1);
|
||||
} else {
|
||||
if (variance == -1) {
|
||||
setVariance(1);
|
||||
}}
|
||||
}
|
||||
|
||||
public void setOrCons(byte i) {
|
||||
orCons = i;
|
||||
}
|
||||
}
|
||||
|
||||
public byte getOrCons() {
|
||||
return orCons;
|
||||
}
|
||||
|
||||
public void setOrCons(byte i) {
|
||||
orCons = i;
|
||||
}
|
||||
|
||||
public Boolean isWildcardable() {
|
||||
return wildcardable;
|
||||
}
|
||||
public void disableWildcardtable() {
|
||||
wildcardable = false;
|
||||
return canBeWildcard;
|
||||
}
|
||||
|
||||
public void enableWildcardtable() {
|
||||
wildcardable = true;
|
||||
public void disableWildcardable() {
|
||||
canBeWildcard = false;
|
||||
}
|
||||
|
||||
public void setWildcardtable(Boolean wildcardable) {
|
||||
this.wildcardable = wildcardable;
|
||||
public void enableWildcardable() {
|
||||
canBeWildcard = true;
|
||||
}
|
||||
|
||||
public Boolean isInnerType() {
|
||||
@@ -168,7 +163,7 @@ public final class PlaceholderType extends UnifyType{
|
||||
|
||||
@Override
|
||||
public UnifyType setTypeParams(TypeParams newTp) {
|
||||
return this; // Placeholders never have params.
|
||||
throw new RuntimeException("Placeholders never have params");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -177,23 +172,23 @@ public final class PlaceholderType extends UnifyType{
|
||||
}
|
||||
|
||||
@Override
|
||||
UnifyType apply(Unifier unif) {
|
||||
if(unif.hasSubstitute(this)) {
|
||||
UnifyType ret = unif.getSubstitute(this);
|
||||
UnifyType apply(Unifier unifier) {
|
||||
if (unifier.hasSubstitute(this)) {
|
||||
//PL 2018-05-17 Auskommentierung muesste korrekt sein,
|
||||
//bereits in JavaTXComplier Variancen gesetzt werden.
|
||||
//ret.accept(new distributeVariance(), this.getVariance());
|
||||
return ret;
|
||||
return unifier.getSubstitute(this);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof PlaceholderType))
|
||||
return false;
|
||||
if (obj instanceof PlaceholderType placeholderObj) {
|
||||
return placeholderObj.getName().equals(typeName);
|
||||
}
|
||||
|
||||
return ((PlaceholderType) obj).getName().equals(typeName);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -7,8 +7,8 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* A reference type e.q. Integer or List<T>.
|
||||
* @author Florian Steurer
|
||||
*
|
||||
* @author Florian Steurer
|
||||
*/
|
||||
public class ReferenceType extends UnifyType {
|
||||
|
||||
@@ -18,15 +18,10 @@ public class ReferenceType extends UnifyType {
|
||||
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;
|
||||
|
||||
|
||||
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
|
||||
return visitor.visit(this, ht);
|
||||
}
|
||||
|
||||
public ReferenceType(String name, Boolean genericTypeVar) {
|
||||
super(name, new TypeParams());
|
||||
hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode();
|
||||
@@ -45,7 +40,11 @@ public class ReferenceType extends UnifyType {
|
||||
genericTypeVar = false;
|
||||
}
|
||||
|
||||
public boolean isGenTypeVar () {
|
||||
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
|
||||
return visitor.visit(this, ht);
|
||||
}
|
||||
|
||||
public boolean isGenTypeVar() {
|
||||
return genericTypeVar;
|
||||
}
|
||||
|
||||
@@ -60,10 +59,10 @@ public class ReferenceType extends UnifyType {
|
||||
}
|
||||
|
||||
@Override
|
||||
UnifyType apply(Unifier unif) {
|
||||
TypeParams newParams = typeParams.apply(unif);
|
||||
UnifyType apply(Unifier unifier) {
|
||||
TypeParams newParams = typeParams.apply(unifier);
|
||||
|
||||
if(newParams.hashCode() == typeParams.hashCode() && newParams.equals(typeParams))
|
||||
if (newParams.hashCode() == typeParams.hashCode() && newParams.equals(typeParams))
|
||||
return this;
|
||||
|
||||
return new ReferenceType(typeName, newParams);
|
||||
@@ -71,8 +70,10 @@ public class ReferenceType extends UnifyType {
|
||||
|
||||
@Override
|
||||
public UnifyType setTypeParams(TypeParams newTp) {
|
||||
if(newTp.hashCode() == typeParams.hashCode() && newTp.equals(typeParams))
|
||||
return this; // reduced the amount of objects created
|
||||
if (newTp.hashCode() == typeParams.hashCode() && newTp.equals(typeParams)) {
|
||||
// reduced the amount of objects created by reusing this instance
|
||||
return this;
|
||||
}
|
||||
return new ReferenceType(typeName, newTp);
|
||||
}
|
||||
|
||||
@@ -83,17 +84,15 @@ public class ReferenceType extends UnifyType {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof ReferenceType))
|
||||
if (!(obj instanceof ReferenceType referenceObj))
|
||||
return false;
|
||||
|
||||
if(obj.hashCode() != this.hashCode())
|
||||
if (obj.hashCode() != this.hashCode())
|
||||
return false;
|
||||
|
||||
ReferenceType other = (ReferenceType) obj;
|
||||
|
||||
if(!other.getName().equals(typeName))
|
||||
if (!referenceObj.getName().equals(typeName))
|
||||
return false;
|
||||
|
||||
return other.getTypeParams().equals(typeParams);
|
||||
return referenceObj.getTypeParams().equals(typeParams);
|
||||
}
|
||||
}
|
@@ -7,22 +7,24 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* A super wildcard type e.g. ? super Integer.
|
||||
*
|
||||
* @author Florian Steurer
|
||||
*/
|
||||
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"
|
||||
*
|
||||
* @param superedType The type that is supered e.g. Integer in "? super Integer"
|
||||
*/
|
||||
public SuperType(UnifyType 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"
|
||||
*/
|
||||
@@ -41,8 +43,10 @@ public final class SuperType extends WildcardType {
|
||||
@Override
|
||||
public UnifyType setTypeParams(TypeParams newTp) {
|
||||
UnifyType newType = wildcardedType.setTypeParams(newTp);
|
||||
if(newType == wildcardedType)
|
||||
return this; // Reduced the amount of objects created
|
||||
if (newType == wildcardedType) {
|
||||
// Reduced the amount of objects created by reusing this instance
|
||||
return this;
|
||||
}
|
||||
return new SuperType(wildcardedType.setTypeParams(newTp));
|
||||
}
|
||||
|
||||
@@ -57,10 +61,12 @@ public final class SuperType extends WildcardType {
|
||||
}
|
||||
|
||||
@Override
|
||||
UnifyType apply(Unifier unif) {
|
||||
UnifyType newType = wildcardedType.apply(unif);
|
||||
if(newType.hashCode() == wildcardedType.hashCode() && newType.equals(wildcardedType))
|
||||
return this; // Reduced the amount of objects created
|
||||
UnifyType apply(Unifier unifier) {
|
||||
UnifyType newType = wildcardedType.apply(unifier);
|
||||
if (newType.hashCode() == wildcardedType.hashCode() && newType.equals(wildcardedType)) {
|
||||
// Reduced the amount of objects created by reusing this instance
|
||||
return this;
|
||||
}
|
||||
return new SuperType(newType);
|
||||
}
|
||||
|
||||
@@ -75,13 +81,12 @@ public final class SuperType extends WildcardType {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof SuperType))
|
||||
if (!(obj instanceof SuperType superObj))
|
||||
return false;
|
||||
|
||||
if(obj.hashCode() != this.hashCode())
|
||||
if (obj.hashCode() != this.hashCode())
|
||||
return false;
|
||||
|
||||
SuperType other = (SuperType) obj;
|
||||
return other.getSuperedType().equals(wildcardedType);
|
||||
return superObj.getSuperedType().equals(wildcardedType);
|
||||
}
|
||||
}
|
@@ -5,9 +5,10 @@ import java.util.*;
|
||||
|
||||
/**
|
||||
* The generic or non-generic parameters of a type e.g. <T> for List<T>
|
||||
*
|
||||
* @author Florian Steurer
|
||||
*/
|
||||
public final class TypeParams implements Iterable<UnifyType>{
|
||||
public final class TypeParams implements Iterable<UnifyType> {
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param types The type parameters.
|
||||
*/
|
||||
public TypeParams(List<UnifyType> types){
|
||||
public TypeParams(List<UnifyType> types) {
|
||||
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);
|
||||
if(types.get(i)==null)throw new NullPointerException();
|
||||
if (types.get(i) == null) throw new NullPointerException();
|
||||
}
|
||||
|
||||
// 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.
|
||||
*
|
||||
* @param types The type parameters.
|
||||
*/
|
||||
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() {
|
||||
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.
|
||||
*
|
||||
* @return number of type parameters, always positive (including 0).
|
||||
*/
|
||||
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() {
|
||||
return typeParams.length == 0;
|
||||
@@ -68,6 +72,7 @@ public final class TypeParams implements Iterable<UnifyType>{
|
||||
|
||||
/**
|
||||
* Applies a unifier to every parameter in this object.
|
||||
*
|
||||
* @param unif The applied unifier.
|
||||
* @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.
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
if(!isNew)
|
||||
if (!isNew)
|
||||
return this;
|
||||
return new TypeParams(newParams);
|
||||
}
|
||||
@@ -97,14 +102,14 @@ public final class TypeParams implements Iterable<UnifyType>{
|
||||
* contains t (arbitrary depth of recursion), false otherwise.
|
||||
*/
|
||||
public boolean occurs(PlaceholderType t) {
|
||||
for(UnifyType p : typeParams)
|
||||
if(p instanceof PlaceholderType) {//PL 2018-01-31 dangeling else Problem { ... } eingefuegt.
|
||||
if(p.equals(t))
|
||||
for (UnifyType p : typeParams)
|
||||
if (p instanceof PlaceholderType) {//PL 2018-01-31 dangeling else Problem { ... } eingefuegt.
|
||||
if (p.equals(t))
|
||||
return true;
|
||||
} else {
|
||||
if (p.getTypeParams().occurs(t))
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if(p.getTypeParams().occurs(t))
|
||||
return true; }
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -131,7 +136,7 @@ public final class TypeParams implements Iterable<UnifyType>{
|
||||
// Reduce the creation of new objects for less memory
|
||||
// Reduced the needed instances of TypeParams in the lambda14-Test from
|
||||
// 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;
|
||||
UnifyType[] newparams = Arrays.copyOf(typeParams, typeParams.length);
|
||||
newparams[idx] = t;
|
||||
@@ -150,23 +155,17 @@ public final class TypeParams implements Iterable<UnifyType>{
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof TypeParams))
|
||||
if (!(obj instanceof TypeParams other))
|
||||
return false;
|
||||
|
||||
if(obj.hashCode() != this.hashCode())
|
||||
if (obj.hashCode() != this.hashCode())
|
||||
return false;
|
||||
|
||||
TypeParams other = (TypeParams) obj;
|
||||
|
||||
if(other.size() != this.size())
|
||||
if (other.size() != this.size())
|
||||
return false;
|
||||
|
||||
for(int i = 0; i < this.size(); i++){
|
||||
//if(this.get(i) == null)
|
||||
//System.out.print("s");
|
||||
}
|
||||
for(int i = 0; i < this.size(); i++)
|
||||
if(!(this.get(i).equals(other.get(i))))
|
||||
for (int i = 0; i < this.size(); i++)
|
||||
if (!(this.get(i).equals(other.get(i))))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -174,15 +173,15 @@ public final class TypeParams implements Iterable<UnifyType>{
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String res = "";
|
||||
for(UnifyType t : typeParams)
|
||||
res += t + ",";
|
||||
return "<" + res.substring(0, res.length()-1) + ">";
|
||||
StringBuilder res = new StringBuilder();
|
||||
for (UnifyType t : typeParams)
|
||||
res.append(t).append(",");
|
||||
return "<" + res.substring(0, res.length() - 1) + ">";
|
||||
}
|
||||
|
||||
public Collection<? extends PlaceholderType> getInvolvedPlaceholderTypes() {
|
||||
ArrayList<PlaceholderType> ret = new ArrayList<>();
|
||||
for(UnifyType t : typeParams){
|
||||
for (UnifyType t : typeParams) {
|
||||
ret.addAll(t.getInvolvedPlaceholderTypes());
|
||||
}
|
||||
return ret;
|
||||
|
@@ -9,6 +9,7 @@ import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* A set of substitutions (s -> t) that is an applicable function to types and pairs.
|
||||
*
|
||||
* @author Florian Steurer
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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).
|
||||
* @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) {
|
||||
substitutions.put(source, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Identity function as an "unifier".
|
||||
* Identity function as a "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() {
|
||||
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)
|
||||
* @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) {
|
||||
Unifier tempU = new Unifier(source, target);
|
||||
// Every new substitution must be applied to previously added substitutions
|
||||
// otherwise the unifier needs to be applied multiple times to unify two terms
|
||||
for(PlaceholderType pt : substitutions.keySet())
|
||||
substitutions.put(pt, substitutions.get(pt).apply(tempU));
|
||||
substitutions.replaceAll((p, _) -> substitutions.get(p).apply(tempU));
|
||||
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.
|
||||
*
|
||||
* @return A new pair where the left and right-hand side are applied
|
||||
*/
|
||||
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.
|
||||
* works only for single subsitution
|
||||
* works only for single substitution
|
||||
*
|
||||
* @return A new pair where the left and right-hand side are applied
|
||||
*/
|
||||
public UnifyPair apply(UnifyPair thisAsPair, UnifyPair p) {
|
||||
UnifyType newLhs = this.apply(p.getLhsType());
|
||||
UnifyType newRhs = this.apply(p.getRhsType());
|
||||
//Varianceweitergabe wird nicht benoetigt.
|
||||
//PlaceholderType lhsph = (PlaceholderType)thisAsPair.getLhsType();
|
||||
//if (lhsph.getVariance() != 0) {
|
||||
// if (p.getLhsType().equals(lhsph)) {
|
||||
// if (p.getRhsType() instanceof PlaceholderType) {
|
||||
// ((PlaceholderType)p.getRhsType()).setVariance(lhsph.getVariance());
|
||||
// }
|
||||
// }
|
||||
// if (p.getRhsType().equals(lhsph)) {
|
||||
// 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
|
||||
|
||||
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<>(thisAsPair.getAllSubstitutions());
|
||||
sUniUnifyPair.add(thisAsPair);
|
||||
if (p.getLhsType() instanceof PlaceholderType
|
||||
&& p.getPairOp() == PairOperator.EQUALSDOT
|
||||
) {
|
||||
sUniUnifyPair.add(p); //p could also be substitution
|
||||
}
|
||||
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.
|
||||
*
|
||||
* @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());
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the typevariable t will be substituted if the unifier is applied.
|
||||
* false otherwise.
|
||||
* @return True if the type variable t will be substituted if the unifier is applied. False otherwise.
|
||||
*/
|
||||
public boolean hasSubstitute(PlaceholderType 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) {
|
||||
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() {
|
||||
return substitutions.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Garantuees that if there is a substitutions (a -> b) in this unifier,
|
||||
* a is not an element of the targetParams. Substitutions that do not
|
||||
* Guarantees that if there is a substitutions (a -> b) in this unifier,
|
||||
* then a is not an element of the targetParams. Substitutions that do not
|
||||
* satisfy this condition, are swapped.
|
||||
*/
|
||||
public void swapPlaceholderSubstitutions(Iterable<UnifyType> targetParams) {
|
||||
for(UnifyType tph : targetParams) {
|
||||
if(!(tph instanceof PlaceholderType))
|
||||
for (UnifyType tph : targetParams) {
|
||||
if (!(tph instanceof PlaceholderType))
|
||||
continue;
|
||||
// Swap a substitutions (a -> b) if a is an element of the target params.
|
||||
if(substitutions.containsKey(tph)) {
|
||||
if((substitutions.get(tph) instanceof PlaceholderType)) {
|
||||
PlaceholderType newLhs = (PlaceholderType) substitutions.get(tph);
|
||||
if (substitutions.containsKey(tph)) {
|
||||
if ((substitutions.get(tph) instanceof PlaceholderType newLhs)) {
|
||||
substitutions.remove(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) {
|
||||
for(UnifyType tph : sourceParams) {
|
||||
if(!(tph instanceof PlaceholderType))
|
||||
for (UnifyType tph : sourceParams) {
|
||||
if (!(tph instanceof PlaceholderType))
|
||||
continue;
|
||||
if(substitutions.containsValue(tph)) {
|
||||
if (substitutions.containsValue(tph)) {
|
||||
UnifyType key = substitutions.values().stream().filter(x -> x.equals(tph)).findAny().get();
|
||||
if(key instanceof PlaceholderType) {
|
||||
if (key instanceof PlaceholderType) {
|
||||
PlaceholderType newLhs = (PlaceholderType) tph;
|
||||
substitutions.remove(key);
|
||||
substitutions.put(newLhs, key);
|
||||
@@ -173,10 +164,10 @@ public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<P
|
||||
@Override
|
||||
public String toString() {
|
||||
String result = "{ ";
|
||||
for(Entry<PlaceholderType, UnifyType> entry : substitutions.entrySet())
|
||||
for (Entry<PlaceholderType, UnifyType> entry : substitutions.entrySet())
|
||||
result += "(" + entry.getKey() + " -> " + entry.getValue() + "), ";
|
||||
if(!substitutions.isEmpty())
|
||||
result = result.substring(0, result.length()-2);
|
||||
if (!substitutions.isEmpty())
|
||||
result = result.substring(0, result.length() - 2);
|
||||
result += " }";
|
||||
return result;
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* A pair which contains two types and an operator, e.q. (Integer <. a).
|
||||
*
|
||||
* @author Florian Steurer
|
||||
*/
|
||||
public class UnifyPair {
|
||||
@@ -20,37 +21,32 @@ public class UnifyPair {
|
||||
* The type on the right hand side of the pair.
|
||||
*/
|
||||
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
|
||||
* 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
|
||||
*/
|
||||
private UnifyPair basePair;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
private Set<UnifyType> fBounded = new HashSet<>();
|
||||
|
||||
private final int hashCode;
|
||||
|
||||
/**
|
||||
* Creates a new instance 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 op The operator that determines the relation between the left and right hand side type.
|
||||
@@ -72,33 +68,31 @@ public class UnifyPair {
|
||||
substitution = uni;
|
||||
basePair = base;
|
||||
|
||||
|
||||
// Caching 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) {
|
||||
this(lhs, rhs, op, uni, base);
|
||||
|
||||
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() {
|
||||
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() {
|
||||
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() {
|
||||
return pairOp;
|
||||
@@ -115,6 +109,7 @@ public class UnifyPair {
|
||||
public void setUndefinedPair() {
|
||||
undefinedPair = true;
|
||||
}
|
||||
|
||||
public Set<UnifyPair> getSubstitution() {
|
||||
return new HashSet<>(substitution);
|
||||
}
|
||||
@@ -122,25 +117,26 @@ public class UnifyPair {
|
||||
public UnifyPair getBasePair() {
|
||||
return basePair;
|
||||
}
|
||||
|
||||
public boolean isUndefinedPair() {
|
||||
return undefinedPair;
|
||||
}
|
||||
|
||||
public Set<UnifyPair> getAllSubstitutions () {
|
||||
Set<UnifyPair> ret = new HashSet<>();
|
||||
ret.addAll(new ArrayList<>(getSubstitution()));
|
||||
public Set<UnifyPair> getAllSubstitutions() {
|
||||
Set<UnifyPair> ret = new HashSet<>(new ArrayList<>(getSubstitution()));
|
||||
if (basePair != null) {
|
||||
ret.addAll(new ArrayList<>(basePair.getAllSubstitutions()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Set<UnifyPair> getThisAndAllBases () {
|
||||
public Set<UnifyPair> getThisAndAllBases() {
|
||||
Set<UnifyPair> ret = getAllBases();
|
||||
ret.add(this);
|
||||
return ret;
|
||||
}
|
||||
public Set<UnifyPair> getAllBases () {
|
||||
|
||||
public Set<UnifyPair> getAllBases() {
|
||||
Set<UnifyPair> ret = new HashSet<>();
|
||||
if (basePair != null) {
|
||||
ret.add(getBasePair());
|
||||
@@ -149,65 +145,62 @@ public class UnifyPair {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public UnifyPair getGroundBasePair () {
|
||||
public UnifyPair getGroundBasePair() {
|
||||
if (basePair == null) {
|
||||
return this;
|
||||
}
|
||||
if (basePair.getBasePair() == null) {
|
||||
return basePair;
|
||||
}
|
||||
else {
|
||||
|
||||
return basePair.getGroundBasePair();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wenn in einem Paar bestehend aus 2 Typvariablen eine nicht wildcardtable ist,
|
||||
* so beide auf nicht wildcardtable setzen
|
||||
* if a pair of two type variables contains one that can not be replaced by a wildcard, then both
|
||||
* of them cannot be replaced by a wildcard
|
||||
*/
|
||||
public void disableCondWildcards() {
|
||||
if (lhs instanceof PlaceholderType && rhs instanceof PlaceholderType
|
||||
&& (!((PlaceholderType)lhs).isWildcardable() || !((PlaceholderType)rhs).isWildcardable()))
|
||||
{
|
||||
((PlaceholderType)lhs).disableWildcardtable();
|
||||
((PlaceholderType)rhs).disableWildcardtable();
|
||||
if (!(lhs instanceof PlaceholderType lhsPlaceholder) || !(rhs instanceof PlaceholderType rhsPlaceholder)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!lhsPlaceholder.isWildcardable() || !rhsPlaceholder.isWildcardable()) {
|
||||
lhsPlaceholder.disableWildcardable();
|
||||
rhsPlaceholder.disableWildcardable();
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean wrongWildcard() {
|
||||
return lhs.wrongWildcard() || rhs.wrongWildcard();
|
||||
}
|
||||
|
||||
public Set<UnifyType> getfBounded() {
|
||||
public Set<UnifyType> getFBounded() {
|
||||
return this.fBounded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof UnifyPair))
|
||||
if (!(obj instanceof UnifyPair unifyPairObj))
|
||||
return false;
|
||||
|
||||
if(obj.hashCode() != this.hashCode())
|
||||
if (obj.hashCode() != this.hashCode())
|
||||
return false;
|
||||
|
||||
UnifyPair other = (UnifyPair) obj;
|
||||
|
||||
if (isUndefinedPair()) {
|
||||
if (other.getBasePair() != basePair || (other.getBasePair() == null && basePair == null)) {
|
||||
if (unifyPairObj.getBasePair() != basePair || (unifyPairObj.getBasePair() == null && basePair == null)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!other.getBasePair().equals(basePair) ||
|
||||
!other.getAllSubstitutions().equals(getAllSubstitutions())) {
|
||||
if (!unifyPairObj.getBasePair().equals(basePair) ||
|
||||
!unifyPairObj.getAllSubstitutions().equals(getAllSubstitutions())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return other.getPairOp() == pairOp
|
||||
&& other.getLhsType().equals(lhs)
|
||||
&& other.getRhsType().equals(rhs);
|
||||
return unifyPairObj.getPairOp() == pairOp
|
||||
&& unifyPairObj.getLhsType().equals(lhs)
|
||||
&& unifyPairObj.getRhsType().equals(rhs);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -218,25 +211,17 @@ public class UnifyPair {
|
||||
@Override
|
||||
public String toString() {
|
||||
String ret = "";
|
||||
if (lhs instanceof PlaceholderType) {
|
||||
ret = new Integer(((PlaceholderType)lhs).getVariance()).toString() + " "
|
||||
+ "WC: " + ((PlaceholderType)lhs).isWildcardable()
|
||||
+ ", IT: " + ((PlaceholderType)lhs).isInnerType();
|
||||
if (lhs instanceof PlaceholderType lhsPlaceholder) {
|
||||
ret = lhsPlaceholder.getVariance() + " "
|
||||
+ "WC: " + lhsPlaceholder.isWildcardable() + ", "
|
||||
+ "IT: " + lhsPlaceholder.isInnerType();
|
||||
}
|
||||
if (rhs instanceof PlaceholderType) {
|
||||
ret = ret + ", " + new Integer(((PlaceholderType)rhs).getVariance()).toString() + " "
|
||||
+ "WC: " + ((PlaceholderType)rhs).isWildcardable()
|
||||
+ ", IT: " + ((PlaceholderType)rhs).isInnerType();
|
||||
if (rhs instanceof PlaceholderType rhsPlaceholder) {
|
||||
ret = ret + ", " + rhsPlaceholder.getVariance() + " "
|
||||
+ "WC: " + rhsPlaceholder.isWildcardable() + ", "
|
||||
+ "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;
|
||||
}
|
||||
*/
|
||||
}
|
@@ -9,6 +9,7 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* Represents a java type.
|
||||
*
|
||||
* @author Florian Steurer
|
||||
*/
|
||||
public abstract class UnifyType {
|
||||
@@ -25,12 +26,13 @@ public abstract class UnifyType {
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @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;
|
||||
typeParams = p;
|
||||
typeParams = params;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +40,7 @@ public abstract class UnifyType {
|
||||
|
||||
/**
|
||||
* Returns the name of the type.
|
||||
*
|
||||
* @return The name e.q. List for List<T>, Integer or ? extends Integer
|
||||
*/
|
||||
public String getName() {
|
||||
@@ -46,6 +49,7 @@ public abstract class UnifyType {
|
||||
|
||||
/**
|
||||
* The parameters of the type.
|
||||
*
|
||||
* @return Parameters of the type, e.q. <T> for List<T>.
|
||||
*/
|
||||
public TypeParams getTypeParams() {
|
||||
@@ -54,6 +58,7 @@ public abstract class UnifyType {
|
||||
|
||||
/**
|
||||
* Returns a new type that equals this type except for the type parameters.
|
||||
*
|
||||
* @param newTp The type params of the new type.
|
||||
* @return A new type object.
|
||||
*/
|
||||
@@ -62,6 +67,7 @@ public abstract class UnifyType {
|
||||
/**
|
||||
* Implementation of the visitor-pattern. Returns the set of smArg
|
||||
* by calling the most specific overload in the FC.
|
||||
*
|
||||
* @param fc The FC that is called.
|
||||
* @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
|
||||
* by calling the most specific overload in the FC.
|
||||
*
|
||||
* @param fc The FC that is called.
|
||||
* @return The set that is grArg(this)
|
||||
*/
|
||||
@@ -77,27 +84,26 @@ public abstract class UnifyType {
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
abstract UnifyType apply(Unifier unif);
|
||||
abstract UnifyType apply(Unifier unifier);
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String params = "";
|
||||
if(typeParams.size() != 0) {
|
||||
for(UnifyType param : typeParams)
|
||||
if (typeParams.size() != 0) {
|
||||
for (UnifyType param : typeParams)
|
||||
params += param.toString() + ",";
|
||||
params = "<" + params.substring(0, params.length()-1) + ">";
|
||||
params = "<" + params.substring(0, params.length() - 1) + ">";
|
||||
}
|
||||
|
||||
return typeName + params;
|
||||
}
|
||||
|
||||
public Collection<PlaceholderType> getInvolvedPlaceholderTypes() {
|
||||
ArrayList<PlaceholderType> ret = new ArrayList<>();
|
||||
ret.addAll(typeParams.getInvolvedPlaceholderTypes());
|
||||
return ret;
|
||||
return new ArrayList<>(typeParams.getInvolvedPlaceholderTypes());
|
||||
}
|
||||
|
||||
public Boolean wrongWildcard() {//default
|
||||
@@ -111,7 +117,9 @@ public abstract class UnifyType {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(obj == null)return false;
|
||||
if (!(obj instanceof UnifyType)) {
|
||||
return false;
|
||||
}
|
||||
return this.toString().equals(obj.toString());
|
||||
}
|
||||
}
|
@@ -5,6 +5,7 @@ import java.util.Collection;
|
||||
|
||||
/**
|
||||
* A wildcard type that is either a ExtendsType or a SuperType.
|
||||
*
|
||||
* @author Florian Steurer
|
||||
*/
|
||||
public abstract class WildcardType extends UnifyType {
|
||||
@@ -16,6 +17,7 @@ public abstract class WildcardType extends UnifyType {
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
@@ -26,6 +28,7 @@ public abstract class WildcardType extends UnifyType {
|
||||
|
||||
/**
|
||||
* Returns the wildcarded type, e.q. Integer for ? extends Integer.
|
||||
*
|
||||
* @return The wildcarded type. Never a wildcard type itself.
|
||||
*/
|
||||
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
|
||||
public TypeParams getTypeParams() {
|
||||
@@ -41,7 +44,7 @@ public abstract class WildcardType extends UnifyType {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean wrongWildcard () {//This is an error
|
||||
public Boolean wrongWildcard() {//This is an error
|
||||
return (wildcardedType instanceof WildcardType);
|
||||
}
|
||||
|
||||
@@ -52,21 +55,18 @@ public abstract class WildcardType extends UnifyType {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof WildcardType))
|
||||
if (!(obj instanceof WildcardType wildcardObj))
|
||||
return false;
|
||||
|
||||
if(obj.hashCode() != this.hashCode())
|
||||
if (obj.hashCode() != this.hashCode())
|
||||
return false;
|
||||
|
||||
WildcardType other = (WildcardType) obj;
|
||||
return other.getWildcardedType().equals(wildcardedType);
|
||||
return wildcardObj.getWildcardedType().equals(wildcardedType);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Collection<PlaceholderType> getInvolvedPlaceholderTypes() {
|
||||
ArrayList<PlaceholderType> ret = new ArrayList<>();
|
||||
ret.addAll(wildcardedType.getInvolvedPlaceholderTypes());
|
||||
return ret;
|
||||
return new ArrayList<>(wildcardedType.getInvolvedPlaceholderTypes());
|
||||
}
|
||||
}
|
||||
|
@@ -4,16 +4,14 @@ public class hashKeyType {
|
||||
UnifyType realType;
|
||||
|
||||
hashKeyType(UnifyType realType) {
|
||||
this.realType= realType;
|
||||
this.realType = realType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof hashKeyType) {
|
||||
return realType.equals(((hashKeyType)obj).realType);
|
||||
}
|
||||
else
|
||||
{
|
||||
return realType.equals(((hashKeyType) obj).realType);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@@ -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));
|
||||
}
|
||||
}
|
@@ -2,18 +2,14 @@ package de.dhbwstuttgart.util;
|
||||
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
public void putAll(BiRelation<X,Y> br) {
|
||||
this.addAll(br);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user