Compare commits
5 Commits
classloade
...
unify-Part
Author | SHA1 | Date | |
---|---|---|---|
|
d33335a6d9 | ||
|
25b1d3e62d | ||
|
85a15cb256 | ||
|
0c03c2fbc8 | ||
|
c8daa665f6 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -23,6 +23,3 @@ bin
|
||||
|
||||
#
|
||||
manually/
|
||||
|
||||
logFiles/**
|
||||
!logFiles/.gitkeep
|
||||
|
@@ -1,22 +0,0 @@
|
||||
Repositories: Branches: JavaCompilerCore: simplyRes
|
||||
JavaCompilerPlugin: copy_libs
|
||||
JavaCompilerCore > mvn install -Dskip.test=true
|
||||
|
||||
[INFO] Installing /Users/pl/workspace_oxygen/JavaCompilerCore/target/JavaTXcompiler-0.2.jar to /Users/pl/.m2/repository/de/dhbwstuttgart/JavaTXcompiler/0.2/JavaTXcompiler-0.2.jar
|
||||
[INFO] Installing /Users/pl/workspace_oxygen/JavaCompilerCore/pom.xml to /Users/pl/.m2/repository/de/dhbwstuttgart/JavaTXcompiler/0.2/JavaTXcompiler-0.2.pom
|
||||
[INFO] Installing /Users/pl/workspace_oxygen/JavaCompilerCore/target/JavaTXcompiler-0.2-jar-with-dependencies.jar to /Users/pl/.m2/repository/de/dhbwstuttgart/JavaTXcompiler/0.2/JavaTXcompiler-0.2-jar-with-dependencies.jar
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
[INFO] BUILD SUCCESS
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
[INFO] Total time: 23.279 s
|
||||
[INFO] Finished at: 2019-09-17T09:31:30+02:00
|
||||
[INFO] -------------------------------------
|
||||
|
||||
JavaCompilerCore > cd target
|
||||
|
||||
JavaCompilerCore/target > cp JavaTXcompiler-0.2.jar ../../Plugin_JCC/JavaCompilerPlugin/bundles/JavaCompilerPlugin.Plugin/lib/JavaTXcompiler.jar
|
||||
|
||||
Im Eclipse: Plugin_JCC/JavaCompilerPlugin> mvn install
|
||||
|
||||
Plugin_JCC/JavaCompilerPlugin/releng/JavaCompilerPlugin.Update/target > cp JavaCompilerPlugin.Update-0.1.0-SNAPSHOT.zip ~/webdav/public_html/javatx/javatx_XXXXXX.zip
|
||||
|
@@ -1,19 +0,0 @@
|
||||
# JavaTXCompiler Klasse
|
||||
* Konstruktor hat einen weiteren Parameter
|
||||
* contextPath
|
||||
* Arrays aus URLs (file-urls)
|
||||
* Parameter ist Optional
|
||||
* wird er gesetzt, so werden Classfiles aus den übergebenen Pfaden geladen
|
||||
* die übergebenen Pfade müssen dabei die Source-Roots sein
|
||||
* Beispiel:
|
||||
`import de.test.Klasse;`
|
||||
* `Klasse.class` liegt in `output/de/test/Klasse.class`
|
||||
* dann muss contextpath auf `output` gesetzt werden
|
||||
* wird der Parameter nicht übergeben, so wird der Sourceroot auf das Verzeichnis gesetzt, in dem der Compiler ausgeführt wird
|
||||
* dies ist das Verhalten vom javac Compiler
|
||||
|
||||
* generateBytecode - Methode hat neuen Parameter: path
|
||||
* wird hier null übergeben, so wird die class-File in den gleichen Ordner wie die übergebene .jav File geschrieben
|
||||
* wird hier ein Pfad übergeben, so gilt dieser als output root.
|
||||
* Klassen werden in outputRoot/package/name/KlassenName.class geschrieben
|
||||
|
@@ -1,25 +0,0 @@
|
||||
\documentclass{article}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\section{Generics sind notwendig}
|
||||
Generics können nicht ignoriert werden.
|
||||
Folgender Fall ist Typisierbar:
|
||||
|
||||
\begin{program}
|
||||
<T> T m1(T x){
|
||||
return m2(x);
|
||||
}
|
||||
|
||||
m2(x){
|
||||
m1(1);
|
||||
m2("Test");
|
||||
return m1(x);
|
||||
}
|
||||
\end{program}
|
||||
|
||||
Beim weglassen des Generics T wäre es aber nicht mehr möglich.
|
||||
Dann erhält jeder Constraint, welcher in Verbindung mit der Methode m1 steht
|
||||
den selben TPH.
|
||||
|
||||
\end{document}
|
26
pom.xml
26
pom.xml
@@ -7,14 +7,14 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<artifactId>JavaTXcompiler</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<version>0.2</version>
|
||||
<version>0.1</version>
|
||||
<name>JavaTXcompiler</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<version>4.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -55,14 +55,6 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<finalName>${project.artifactId}-${project.version}</finalName>
|
||||
<testOutputDirectory>target/test-classes</testOutputDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.0.0-M3</version>
|
||||
<configuration>
|
||||
<skipTests>true</skipTests>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4-maven-plugin</artifactId>
|
||||
@@ -110,11 +102,6 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>de.dhbwstuttgart.core.ConsoleInterface</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
@@ -132,7 +119,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<!-- specify your depencies here -->
|
||||
<!-- groupId:artifactId:version -->
|
||||
<artifact>
|
||||
<id>de.dhbwstuttgart:JavaTXcompiler:0.2</id>
|
||||
<id>de.dhbwstuttgart:JavaTXcompiler:0.1</id>
|
||||
</artifact>
|
||||
<artifact>
|
||||
<id>org.reflections:reflections:0.9.11</id>
|
||||
@@ -151,6 +138,10 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- plugin> <groupId>org.eclipse.tycho</groupId> <artifactId>tycho-p2-repository-plugin</artifactId>
|
||||
<version>${tycho.version}</version> <executions> <execution> <phase>package</phase>
|
||||
<goals> <goal>archive-repository</goal> </goals> </execution> </executions>
|
||||
</plugin -->
|
||||
</plugins>
|
||||
</build>
|
||||
<pluginRepositories>
|
||||
@@ -169,7 +160,6 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<tycho.version>0.23.0</tycho.version>
|
||||
<mainClass>de.dhbwstuttgart.core.ConsoleInterface</mainClass>
|
||||
</properties>
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
@@ -179,3 +169,5 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
</project>
|
||||
|
||||
|
||||
|
@@ -61,7 +61,7 @@ public class ArgumentVisitor implements StatementVisitor {
|
||||
assign.accept(bytecodeGenMethod);
|
||||
|
||||
if(argListMethCall.get(0))
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(assign.getType()));
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(assign.getType()));
|
||||
argListMethCall.remove(0);
|
||||
}
|
||||
|
||||
@@ -70,9 +70,9 @@ public class ArgumentVisitor implements StatementVisitor {
|
||||
binary.accept(bytecodeGenMethod);
|
||||
|
||||
if(argListMethCall.get(0)) {
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(binary.getType()));
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(binary.getType()));
|
||||
} else {
|
||||
bytecodeGenMethod.doBoxing(bytecodeGenMethod.getResolver().getResolvedType(binary.getType()));
|
||||
bytecodeGenMethod.doBoxing(bytecodeGenMethod.getResolvedType(binary.getType()));
|
||||
}
|
||||
argListMethCall.remove(0);
|
||||
}
|
||||
@@ -88,7 +88,7 @@ public class ArgumentVisitor implements StatementVisitor {
|
||||
castExpr.accept(bytecodeGenMethod);
|
||||
|
||||
if(argListMethCall.get(0))
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(castExpr.getType()));
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(castExpr.getType()));
|
||||
argListMethCall.remove(0);
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ public class ArgumentVisitor implements StatementVisitor {
|
||||
fieldVar.accept(bytecodeGenMethod);
|
||||
|
||||
if(argListMethCall.get(0))
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(fieldVar.getType()));
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(fieldVar.getType()));
|
||||
argListMethCall.remove(0);
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ public class ArgumentVisitor implements StatementVisitor {
|
||||
instanceOf.accept(bytecodeGenMethod);
|
||||
|
||||
if(argListMethCall.get(0))
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(instanceOf.getType()));
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(instanceOf.getType()));
|
||||
argListMethCall.remove(0);
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ public class ArgumentVisitor implements StatementVisitor {
|
||||
localVar.accept(bytecodeGenMethod);
|
||||
if(!bytecodeGenMethod.isBinaryExp) {
|
||||
if(argListMethCall.get(0))
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(localVar.getType()));
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(localVar.getType()));
|
||||
}
|
||||
argListMethCall.remove(0);
|
||||
}
|
||||
@@ -149,7 +149,7 @@ public class ArgumentVisitor implements StatementVisitor {
|
||||
methodCall.accept(bytecodeGenMethod);
|
||||
|
||||
if(argListMethCall.get(0))
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(methodCall.getType()));
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(methodCall.getType()));
|
||||
argListMethCall.remove(0);
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ public class ArgumentVisitor implements StatementVisitor {
|
||||
methodCall.accept(bytecodeGenMethod);
|
||||
|
||||
if(argListMethCall.get(0))
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(methodCall.getType()));
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(methodCall.getType()));
|
||||
argListMethCall.remove(0);
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ public class ArgumentVisitor implements StatementVisitor {
|
||||
aThis.accept(bytecodeGenMethod);
|
||||
|
||||
if(argListMethCall.get(0))
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(aThis.getType()));
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(aThis.getType()));
|
||||
argListMethCall.remove(0);
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ public class ArgumentVisitor implements StatementVisitor {
|
||||
unaryExpr.accept(bytecodeGenMethod);
|
||||
|
||||
if(argListMethCall.get(0))
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(unaryExpr.getType()));
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(unaryExpr.getType()));
|
||||
argListMethCall.remove(0);
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ public class ArgumentVisitor implements StatementVisitor {
|
||||
literal.accept(bytecodeGenMethod);
|
||||
|
||||
if(argListMethCall.get(0))
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(literal.getType()));
|
||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(literal.getType()));
|
||||
argListMethCall.remove(0);
|
||||
}
|
||||
|
||||
|
@@ -1,96 +1,61 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Optional;
|
||||
|
||||
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.Exception.BytecodeGeneratorError;
|
||||
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
|
||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||
import de.dhbwstuttgart.bytecode.signature.Signature;
|
||||
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
|
||||
import de.dhbwstuttgart.bytecode.signature.TypeToString;
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericGenratorResultForSourceFile;
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResult;
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResultForClass;
|
||||
import de.dhbwstuttgart.bytecode.utilities.MethodUtility;
|
||||
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
||||
import de.dhbwstuttgart.bytecode.utilities.NormalConstructor;
|
||||
import de.dhbwstuttgart.bytecode.utilities.NormalMethod;
|
||||
import de.dhbwstuttgart.bytecode.utilities.Resolver;
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.bytecode.utilities.Simplify;
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.Constructor;
|
||||
import de.dhbwstuttgart.syntaxtree.Field;
|
||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.ParameterList;
|
||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Assign;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.AssignToField;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Block;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.CastExpr;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.DoStmt;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.EmptyStmt;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.ExpressionReceiver;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.FieldVar;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.ForStmt;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.IfStmt;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.InstanceOf;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Literal;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.NewArray;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.NewClass;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Return;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.ReturnVoid;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.StaticClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Super;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.SuperCall;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.This;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.WhileStmt;
|
||||
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.typeinference.result.GenericInsertPair;
|
||||
import de.dhbwstuttgart.typeinference.result.ResolvedType;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultPair;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
|
||||
public class BytecodeGen implements ASTVisitor {
|
||||
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||
ClassWriter cw =new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
|
||||
|
||||
String type;
|
||||
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric THISTYPE = null;
|
||||
private JavaClassName className;
|
||||
private String pkgName;
|
||||
String className;
|
||||
private boolean isInterface;
|
||||
private Collection<ResultSet> listOfResultSets;
|
||||
private List<ResultSet> listOfResultSets;
|
||||
private ResultSet resultSet;
|
||||
private SourceFile sf;
|
||||
private File path;
|
||||
private String path;
|
||||
|
||||
private Optional<Constructor> fieldInitializations;
|
||||
|
||||
@@ -98,127 +63,140 @@ public class BytecodeGen implements ASTVisitor {
|
||||
|
||||
private String superClass;
|
||||
|
||||
private List<String> tphsClass;
|
||||
private ArrayList<TypePlaceholder> tphsClass;
|
||||
|
||||
// stores parameter, local vars and the next index on the local variable table,
|
||||
// which use for aload_i, astore_i,...
|
||||
// stores parameter, local vars and the next index on the local variable table, which use for aload_i, astore_i,...
|
||||
HashMap<String, Integer> paramsAndLocals = new HashMap<>();
|
||||
// stores generics and their bounds of class
|
||||
HashMap<String, String> genericsAndBounds = new HashMap<>();
|
||||
|
||||
private int constructorPos = 0;
|
||||
|
||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes = new HashMap<>();
|
||||
private final TPHExtractor tphExtractor = new TPHExtractor();
|
||||
private final ArrayList<GenericInsertPair> commonPairs = new ArrayList<>();
|
||||
|
||||
HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes = new HashMap<>();
|
||||
byte[] bytecode;
|
||||
HashMap<JavaClassName, byte[]> classFiles;
|
||||
HashMap<String,byte[]> classFiles;
|
||||
|
||||
private final ArrayList<String> methodNameAndParamsT = new ArrayList<>();
|
||||
private final ArrayList<String> fieldNameAndParamsT = new ArrayList<>();
|
||||
ArrayList<String> methodNameAndParamsT = new ArrayList<>();
|
||||
|
||||
private final ArrayList<String> fieldNameSignature = new ArrayList<>();
|
||||
|
||||
private List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles;
|
||||
private GenericsGeneratorResultForClass generatedGenerics;
|
||||
|
||||
private Resolver resolver;
|
||||
private final DirectoryClassLoader classLoader;
|
||||
|
||||
public BytecodeGen(HashMap<JavaClassName, byte[]> classFiles, Collection<ResultSet> listOfResultSets, List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles, SourceFile sf,
|
||||
File path, DirectoryClassLoader classLoader) {
|
||||
public BytecodeGen(HashMap<String,byte[]> classFiles, List<ResultSet> listOfResultSets,SourceFile sf ,String path) {
|
||||
this.classFiles = classFiles;
|
||||
this.listOfResultSets = listOfResultSets;
|
||||
this.simplifyResultsForAllSourceFiles = simplifyResultsForAllSourceFiles;
|
||||
this.sf = sf;
|
||||
this.path = path;
|
||||
this.pkgName = sf.getPkgName();
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(SourceFile sourceFile) {
|
||||
for (ClassOrInterface cl : sourceFile.getClasses()) {
|
||||
for(ClassOrInterface cl : sourceFile.getClasses()) {
|
||||
System.out.println("in Class: " + cl.getClassName().toString());
|
||||
BytecodeGen classGen = new BytecodeGen(classFiles, listOfResultSets, simplifyResultsForAllSourceFiles, sf, path, classLoader);
|
||||
BytecodeGen classGen = new BytecodeGen(classFiles, listOfResultSets, sf, path);
|
||||
cl.accept(classGen);
|
||||
classGen.writeClass(cl.getClassName());
|
||||
classGen.writeClass(cl.getClassName().toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates the bytecode of the class that was build with the classWriter
|
||||
* {@link #cw} with the class name in the map {@link #classFiles}
|
||||
* Associates the bytecode of the class that was build with the classWriter {@link #cw}
|
||||
* with the class name in the map {@link #classFiles}
|
||||
*
|
||||
* @param name name of the class with which the bytecode is to be associated
|
||||
* @param name name of the class with which the the bytecode is to be associated
|
||||
*/
|
||||
private void writeClass(JavaClassName name) {
|
||||
private void writeClass(String name) {
|
||||
bytecode = cw.toByteArray();
|
||||
classFiles.put(name, bytecode);
|
||||
|
||||
}
|
||||
|
||||
public HashMap<JavaClassName, byte[]> getClassFiles() {
|
||||
public HashMap<String,byte[]> getClassFiles() {
|
||||
return classFiles;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(ClassOrInterface classOrInterface) {
|
||||
|
||||
className = classOrInterface.getClassName();
|
||||
className = classOrInterface.getClassName().toString();
|
||||
|
||||
cw.visitSource(className.getClassName() + ".jav", null);
|
||||
cw.visitSource(className +".jav", null);
|
||||
|
||||
isInterface = (classOrInterface.getModifiers() & 512) == 512;
|
||||
isInterface = (classOrInterface.getModifiers()&512)==512;
|
||||
|
||||
int acc = isInterface ? classOrInterface.getModifiers() + Opcodes.ACC_ABSTRACT
|
||||
: classOrInterface.getModifiers() + Opcodes.ACC_SUPER;
|
||||
int acc = isInterface?classOrInterface.getModifiers()+Opcodes.ACC_ABSTRACT:classOrInterface.getModifiers()+Opcodes.ACC_SUPER;
|
||||
|
||||
fieldInitializations = classOrInterface.getfieldInitializations();
|
||||
|
||||
// resultSet = listOfResultSets.get(0);
|
||||
boolean isConsWithNoParamsVisited = false;
|
||||
boolean isVisited = false;
|
||||
List<ResultSet> listOfResultSetsList = new ArrayList<>(listOfResultSets);
|
||||
generatedGenerics = simplifyResultsForAllSourceFiles.stream().map(sr->sr.getSimplifyResultsByName(className)).findFirst().get();
|
||||
for (int i = 0; i < listOfResultSetsList.size(); i++) {
|
||||
//for (ResultSet rs : listOfResultSets) {
|
||||
for(ResultSet rs : listOfResultSets) {
|
||||
superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor());
|
||||
resultSet = listOfResultSetsList.get(i);
|
||||
resolver = new Resolver(resultSet);
|
||||
// tphExtractor.setResultSet(resultSet);
|
||||
|
||||
resultSet = rs;
|
||||
tphExtractor.setResultSet(resultSet);
|
||||
|
||||
// Nur einmal ausführen!!
|
||||
if (!isVisited) {
|
||||
if(!isVisited) {
|
||||
classOrInterface.accept(tphExtractor);
|
||||
|
||||
getCommonTPHS(tphExtractor);
|
||||
|
||||
tphsClass = new ArrayList<>();
|
||||
for(TypePlaceholder t : tphExtractor.allTPHS.keySet()) {
|
||||
if(!tphExtractor.allTPHS.get(t))
|
||||
tphsClass.add(t);
|
||||
}
|
||||
|
||||
ArrayList<TPHConstraint> consClass = new ArrayList<>();
|
||||
for(TPHConstraint cons : tphExtractor.allCons) {
|
||||
TypePlaceholder right = null;
|
||||
for(TypePlaceholder tph : tphsClass) {
|
||||
if(cons.getLeft().equals(tph.getName())) {
|
||||
|
||||
consClass.add(cons);
|
||||
right = getTPH(cons.getRight());
|
||||
}
|
||||
}
|
||||
if(right != null) {
|
||||
tphsClass.add(right);
|
||||
removeFromMethod(right.getName());
|
||||
right = null;
|
||||
}
|
||||
}
|
||||
String sig = null;
|
||||
/*
|
||||
* if class has generics then creates signature Signature looks like:
|
||||
/* if class has generics then creates signature
|
||||
* Signature looks like:
|
||||
* <E:Ljava/...>Superclass
|
||||
*/
|
||||
if (classOrInterface.getGenerics().iterator().hasNext() || classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<")
|
||||
|| !generatedGenerics.getClassConstraints().isEmpty()) {
|
||||
|
||||
List<GenericsGeneratorResult> consClass = generatedGenerics.getClassConstraints();
|
||||
//
|
||||
Signature signature = new Signature(classOrInterface, genericsAndBounds, consClass);
|
||||
sig = signature.createSignatureForClassOrInterface();
|
||||
if(classOrInterface.getGenerics().iterator().hasNext() || !commonPairs.isEmpty() ||
|
||||
classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<")
|
||||
|| !tphsClass.isEmpty()) {
|
||||
Signature signature = new Signature(classOrInterface, genericsAndBounds,commonPairs,tphsClass, consClass);
|
||||
sig = signature.toString();
|
||||
System.out.println("Signature: => " + sig);
|
||||
}
|
||||
|
||||
cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString().replace(".", "/"), sig,
|
||||
classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()), null);
|
||||
cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString()
|
||||
, sig, classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()), null);
|
||||
|
||||
isVisited = true;
|
||||
}
|
||||
|
||||
for (Field f : classOrInterface.getFieldDecl()) {
|
||||
for(Field f : classOrInterface.getFieldDecl()) {
|
||||
f.accept(this);
|
||||
}
|
||||
|
||||
for (Constructor c : classOrInterface.getConstructors()) {
|
||||
for(Constructor c : classOrInterface.getConstructors()) {
|
||||
// if(!isConsWithNoParamsVisited) {
|
||||
c.accept(this);
|
||||
// }
|
||||
|
||||
// if(!c.getParameterList().iterator().hasNext())
|
||||
// isConsWithNoParamsVisited = true;
|
||||
}
|
||||
|
||||
for (Method m : classOrInterface.getMethods()) {
|
||||
for(Method m : classOrInterface.getMethods()) {
|
||||
m.accept(this);
|
||||
}
|
||||
|
||||
@@ -226,46 +204,94 @@ public class BytecodeGen implements ASTVisitor {
|
||||
|
||||
}
|
||||
|
||||
private void removeFromMethod(String name) {
|
||||
for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
|
||||
ArrayList<String> toRemove = new ArrayList<>();
|
||||
for(String tph : m.getTphs()) {
|
||||
if(tph.equals(name)) {
|
||||
toRemove.add(tph);
|
||||
}
|
||||
}
|
||||
|
||||
if(!toRemove.isEmpty()) {
|
||||
m.getTphs().removeAll(toRemove);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private TypePlaceholder getTPH(String name) {
|
||||
for(TypePlaceholder tph: tphExtractor.allTPHS.keySet()) {
|
||||
if(tph.getName().equals(name))
|
||||
return tph;
|
||||
}
|
||||
throw new NoSuchElementException("TPH "+name +" does not exist");
|
||||
}
|
||||
|
||||
private void getCommonTPHS(TPHExtractor tphExtractor) {
|
||||
// Gemeinsame TPHs
|
||||
ArrayList<TypePlaceholder> cTPHs = new ArrayList<>();
|
||||
// Alle TPHs der Felder speichern
|
||||
for(TypePlaceholder tph : tphExtractor.allTPHS.keySet()) {
|
||||
if(!tphExtractor.allTPHS.get(tph))
|
||||
cTPHs.add(tph);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Constructor field) {
|
||||
System.out.println("ResultSet: ");
|
||||
resultSet.results.forEach(a->{
|
||||
System.out.println(a.getLeft().toString() + " = " + a.getRight().toString());
|
||||
});
|
||||
System.out.println("---------------");
|
||||
|
||||
// stores generics and their bounds of method
|
||||
HashMap<String, String> genericsAndBoundsMethod = new HashMap<>();
|
||||
|
||||
field.getParameterList().accept(this);
|
||||
|
||||
String id = MethodUtility.createID(resolver, field);
|
||||
String methParamTypes = field.name+"%%";
|
||||
|
||||
if (methodNameAndParamsT.contains(id)) {
|
||||
Iterator<FormalParameter> itr = field.getParameterList().iterator();
|
||||
while(itr.hasNext()) {
|
||||
FormalParameter fp = itr.next();
|
||||
methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";";
|
||||
// methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature())+";";
|
||||
}
|
||||
|
||||
if(methodNameAndParamsT.contains(methParamTypes)) {
|
||||
System.out.println("ignore - Method: "+field.name +" , paramsType: "+methParamTypes);
|
||||
return;
|
||||
}
|
||||
methodNameAndParamsT.add(id);
|
||||
System.out.println("Constructor: " + field.name + " , paramsType: " + id);
|
||||
methodNameAndParamsT.add(methParamTypes);
|
||||
System.out.println("Method: "+field.name +" , paramsType: "+methParamTypes);
|
||||
|
||||
String desc = null;
|
||||
boolean hasGen = false;
|
||||
|
||||
for (String paramName : methodParamsAndTypes.keySet()) {
|
||||
for(String paramName : methodParamsAndTypes.keySet()) {
|
||||
String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature());
|
||||
System.out.println(typeOfParam);
|
||||
if (genericsAndBounds.containsKey(typeOfParam) || typeOfParam.contains("$") || typeOfParam.contains("<")) {
|
||||
if(genericsAndBounds.containsKey(typeOfParam) ||typeOfParam.contains("$")
|
||||
|| typeOfParam.contains("<")) {
|
||||
hasGen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
String sig = null;
|
||||
if (hasGen) {
|
||||
List<GenericsGeneratorResult> constraints = generatedGenerics.getClassConstraints();
|
||||
Signature signature = new Signature(genericsAndBounds,
|
||||
methodParamsAndTypes, resultSet, constraints);
|
||||
|
||||
sig = signature.createSignatureForConstructor(field);
|
||||
if(hasGen) {
|
||||
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(field.name, tphExtractor,tphsClass);
|
||||
Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes,resultSet,constraints);
|
||||
sig = signature.toString();
|
||||
}
|
||||
if (field.getParameterList().iterator().hasNext())
|
||||
if(field.getParameterList().iterator().hasNext())
|
||||
System.out.println(field.getParameterList().iterator().next().getType().acceptTV(new TypeToDescriptor()));
|
||||
|
||||
NormalConstructor constructor = new NormalConstructor(field, genericsAndBounds, hasGen);
|
||||
NormalConstructor constructor = new NormalConstructor(field,genericsAndBounds,hasGen);
|
||||
desc = constructor.accept(new DescriptorToString(resultSet));
|
||||
System.out.println("Constructor: " + field.getName() + " Sig: " + sig + " Desc: " + desc);
|
||||
System.out.println("Constructor: " + field.getName() + " Sig: "+ sig + " Desc: " + desc);
|
||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", desc, sig, null);
|
||||
mv.visitCode();
|
||||
|
||||
@@ -273,10 +299,9 @@ public class BytecodeGen implements ASTVisitor {
|
||||
|
||||
constructorPos += 1;
|
||||
|
||||
BytecodeGenMethod gen = new BytecodeGenMethod(className, superClass, resultSet, field, mv, paramsAndLocals, cw,
|
||||
genericsAndBoundsMethod, genericsAndBounds, isInterface, classFiles, sf, path, block, constructorPos, classLoader);
|
||||
if (!field.getParameterList().iterator().hasNext()
|
||||
&& !(field.block.statements.get(field.block.statements.size() - 1) instanceof ReturnVoid)) {
|
||||
BytecodeGenMethod gen = new BytecodeGenMethod(className,superClass,resultSet,field, mv,paramsAndLocals,cw,
|
||||
genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles, sf,path, block, constructorPos);
|
||||
if(!field.getParameterList().iterator().hasNext() && !(field.block.statements.get(field.block.statements.size()-1) instanceof ReturnVoid)) {
|
||||
mv.visitInsn(Opcodes.RETURN);
|
||||
}
|
||||
mv.visitMaxs(0, 0);
|
||||
@@ -285,77 +310,76 @@ public class BytecodeGen implements ASTVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(Method method) {
|
||||
// TODO: check if the method is static => if static then the first param will be
|
||||
// stored in pos 0
|
||||
// TODO: check if the method is static => if static then the first param will be stored in pos 0
|
||||
// else it will be stored in pos 1 and this will be stored in pos 0
|
||||
String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
|
||||
String id = MethodUtility.createID(resolver, method);
|
||||
|
||||
if (methodNameAndParamsT.contains(id)) {
|
||||
return;
|
||||
}
|
||||
methodNameAndParamsT.add(id);
|
||||
System.out.println("Method: " + method.name + " , paramsType: " + id);
|
||||
// stores generics and their bounds of method
|
||||
HashMap<String, String> genericsAndBoundsMethod = new HashMap<>();
|
||||
|
||||
// String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
|
||||
String methParamTypes = retType+method.name+"%%";
|
||||
method.getParameterList().accept(this);
|
||||
|
||||
Iterator<FormalParameter> itr = method.getParameterList().iterator();
|
||||
while(itr.hasNext()) {
|
||||
FormalParameter fp = itr.next();
|
||||
methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";";
|
||||
// methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature())+";";
|
||||
}
|
||||
|
||||
if(methodNameAndParamsT.contains(methParamTypes)) {
|
||||
return;
|
||||
}
|
||||
methodNameAndParamsT.add(methParamTypes);
|
||||
System.out.println("Method: "+method.name +" , paramsType: "+methParamTypes);
|
||||
// stores generics and their bounds of method
|
||||
HashMap<String, String> genericsAndBoundsMethod = new HashMap<>();
|
||||
String methDesc = null;
|
||||
|
||||
// Method getModifiers() ?
|
||||
int acc = isInterface ? Opcodes.ACC_ABSTRACT : method.modifier;
|
||||
int acc = isInterface?Opcodes.ACC_ABSTRACT:method.modifier;
|
||||
System.out.println(acc);
|
||||
|
||||
/* Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist */
|
||||
boolean hasGenInParameterList = genericsAndBounds.containsKey(retType) || retType.contains("TPH ")
|
||||
|| resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature())
|
||||
.contains("<");
|
||||
/*
|
||||
* Wenn die Rückgabe-Type eine Typ-variable ist, erzeuge direkt die Signature,
|
||||
* wenn nicht, prüfe, ob einer der Parameter Typ-Variable als Typ hat
|
||||
*/
|
||||
if (!hasGenInParameterList) {
|
||||
for (String paramName : methodParamsAndTypes.keySet()) {
|
||||
/*Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist*/
|
||||
boolean hasGenInParameterList = genericsAndBounds.containsKey(retType) || retType.subSequence(0, 4).equals("TPH ") ||
|
||||
resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature()).contains("<");
|
||||
/*Wenn die Rückgabe-Type eine Typ-variable ist, erzeuge direkt die Signature, wenn nicht,
|
||||
* prüfe, ob einer der Parameter Typ-Variable als Typ hat*/
|
||||
if(!hasGenInParameterList) {
|
||||
for(String paramName : methodParamsAndTypes.keySet()) {
|
||||
String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToDescriptor());
|
||||
String sigOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature());
|
||||
if (genericsAndBounds.containsKey(typeOfParam) || typeOfParam.contains("TPH ")
|
||||
|| sigOfParam.contains("<")) {
|
||||
if(genericsAndBounds.containsKey(typeOfParam)||typeOfParam.substring(0, 4).equals("TPH ")||sigOfParam.contains("<")) {
|
||||
hasGenInParameterList = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: Test if the return-type or any of the parameter is a parameterized
|
||||
// type. (VP)
|
||||
// then create the descriptor with the new syntax.
|
||||
//TODO: Test if the return-type or any of the parameter is a parameterized type. (VP)
|
||||
//then create the descriptor with the new syntax.
|
||||
|
||||
String sig = null;
|
||||
/*
|
||||
* method.getGenerics: <....> RT method(..)
|
||||
*/
|
||||
/* method.getGenerics: <....> RT method(..)
|
||||
* */
|
||||
boolean hasGen = method.getGenerics().iterator().hasNext() || hasGenInParameterList;
|
||||
/* if method has generics or return type is TPH, create signature */
|
||||
// zwite operand muss weggelassen werden
|
||||
if (hasGen || resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToString())
|
||||
.equals("TPH")) {
|
||||
|
||||
List<GenericsGeneratorResult> constraints = generatedGenerics.getMethodConstraintsByID(id);
|
||||
List<GenericsGeneratorResult> classConstraints = generatedGenerics.getClassConstraints();
|
||||
Signature signature = new Signature(genericsAndBoundsMethod, genericsAndBounds,
|
||||
methodParamsAndTypes, resultSet, constraints,classConstraints);
|
||||
sig = signature.createSignatureForMethod(method);
|
||||
if(hasGen||resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToString()).equals("TPH")) {
|
||||
System.out.println("ALL CONST: " + tphExtractor.allCons.size());
|
||||
tphExtractor.allCons.forEach(c->System.out.println(c.toString()));
|
||||
System.out.println("----------------");
|
||||
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(method.name, tphExtractor, tphsClass);
|
||||
// ArrayList<GenericInsertPair> pairs = simplifyPairs(method.name,tphExtractor.allPairs,tphExtractor.allCons);
|
||||
Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,methodParamsAndTypes,resultSet,constraints);
|
||||
sig = signature.toString();
|
||||
}
|
||||
System.out.println(method.getName() + " ==> " + sig);
|
||||
NormalMethod meth = new NormalMethod(method, genericsAndBounds, genericsAndBoundsMethod, hasGen);
|
||||
System.out.println(method.getName()+" ==> "+sig);
|
||||
NormalMethod meth = new NormalMethod(method,genericsAndBounds,genericsAndBoundsMethod,hasGen);
|
||||
methDesc = meth.accept(new DescriptorToString(resultSet));
|
||||
|
||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC + acc, method.getName(), methDesc, sig, null);
|
||||
// System.out.println(methDesc);
|
||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC+acc, method.getName(), methDesc, sig, null);
|
||||
|
||||
mv.visitCode();
|
||||
BytecodeGenMethod gen = new BytecodeGenMethod(className, superClass, resultSet, method, mv, paramsAndLocals, cw,
|
||||
genericsAndBoundsMethod, genericsAndBounds, isInterface, classFiles, sf, path, classLoader);
|
||||
BytecodeGenMethod gen = new BytecodeGenMethod(className,superClass,resultSet,method, mv,paramsAndLocals,cw,
|
||||
genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles, sf,path);
|
||||
|
||||
mv.visitMaxs(0, 0);
|
||||
mv.visitEnd();
|
||||
@@ -367,7 +391,7 @@ public class BytecodeGen implements ASTVisitor {
|
||||
methodParamsAndTypes = new HashMap<>();
|
||||
Iterator<FormalParameter> itr = formalParameters.iterator();
|
||||
int i = 1;
|
||||
while (itr.hasNext()) {
|
||||
while(itr.hasNext()) {
|
||||
FormalParameter fp = itr.next();
|
||||
paramsAndLocals.put(fp.getName(), i);
|
||||
methodParamsAndTypes.put(fp.getName(), resultSet.resolveType(fp.getType()).resolvedType);
|
||||
@@ -383,7 +407,7 @@ public class BytecodeGen implements ASTVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(RefType refType) {
|
||||
type = "L" + refType.toString() + ";";
|
||||
type = "L"+refType.toString()+";";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -415,8 +439,7 @@ public class BytecodeGen implements ASTVisitor {
|
||||
public void visit(FieldVar fieldVar) {
|
||||
System.out.println("In FieldVar ---");
|
||||
// cw.newField(fieldVar.receiver.toString(), fieldVar.fieldVarName.toString(), fieldVar.getType().toString());
|
||||
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, fieldVar.fieldVarName, "L" + fieldVar.getType() + ";",
|
||||
null, null);
|
||||
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, fieldVar.fieldVarName, "L"+fieldVar.getType()+";", null, null);
|
||||
fv.visitEnd();
|
||||
}
|
||||
|
||||
@@ -424,30 +447,21 @@ public class BytecodeGen implements ASTVisitor {
|
||||
public void visit(Field field) {
|
||||
System.out.println("In Field ---");
|
||||
String des = "L";
|
||||
if (resultSet.resolveType(field.getType()).resolvedType instanceof TypePlaceholder) {
|
||||
if(resultSet.resolveType(field.getType()).resolvedType instanceof TypePlaceholder) {
|
||||
des += Type.getInternalName(Object.class);
|
||||
} else {
|
||||
des += resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
}
|
||||
des += ";";
|
||||
des +=";";
|
||||
System.out.println(des);
|
||||
String sig = resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToSignature(generatedGenerics.getClassConstraints()));
|
||||
String sig = resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToSignature());
|
||||
System.out.println(sig);
|
||||
if (sig.charAt(sig.length() - 1) != (";").charAt(0)) {
|
||||
sig += ";";
|
||||
if(sig.charAt(sig.length()-1) != (";").charAt(0)) {
|
||||
sig +=";";
|
||||
}
|
||||
String nameAndDesc = field.getName() + "%%" + des;
|
||||
String nameAndSig = field.getName() + "%%" + sig;
|
||||
if (fieldNameAndParamsT.contains(nameAndDesc)) {
|
||||
if (fieldNameSignature.contains(nameAndSig)) {
|
||||
return;
|
||||
}
|
||||
throw new BytecodeGeneratorError("Bytecode generation aborted due to duplicate field name&signature");
|
||||
}
|
||||
fieldNameAndParamsT.add(nameAndDesc);
|
||||
fieldNameSignature.add(nameAndSig);
|
||||
|
||||
cw.visitField(field.modifier, field.getName(), des, sig, null);
|
||||
cw.visitField(field.modifier, field.getName(),
|
||||
des, sig,
|
||||
null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -628,4 +642,5 @@ public class BytecodeGen implements ASTVisitor {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,19 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.Exception;
|
||||
|
||||
/**
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class BytecodeGeneratorError extends RuntimeException {
|
||||
|
||||
/**
|
||||
* @param message
|
||||
*/
|
||||
public BytecodeGeneratorError(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.Exception;
|
||||
|
||||
/**
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class NotFoundException extends Exception {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* @param message
|
||||
*/
|
||||
public NotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.Exception;
|
||||
|
||||
/**
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class NotInCurrentPackageException extends Exception {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* @param message
|
||||
*/
|
||||
public NotInCurrentPackageException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@@ -5,54 +5,31 @@ package de.dhbwstuttgart.bytecode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
||||
import de.dhbwstuttgart.bytecode.utilities.MethodUtility;
|
||||
import de.dhbwstuttgart.bytecode.utilities.Resolver;
|
||||
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.Constructor;
|
||||
import de.dhbwstuttgart.syntaxtree.Field;
|
||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.ParameterList;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl;
|
||||
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.result.GenericInsertPair;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultPair;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
|
||||
/**
|
||||
* @author Fayez Abu Alia
|
||||
*
|
||||
*/
|
||||
public class TPHExtractor extends AbstractASTWalker {
|
||||
public class TPHExtractor extends AbstractASTWalker{
|
||||
// Alle TPHs der Felder werden iKopf der Klasse definiert
|
||||
// alle TPHs der Klasse: (TPH, is in Method?)
|
||||
public final HashMap<String, Boolean> allTPHS = new HashMap<>();
|
||||
public final List<String> tphsClass = new ArrayList<>();
|
||||
final HashMap<TypePlaceholder,Boolean> allTPHS = new HashMap<>();
|
||||
MethodAndTPH methodAndTph;
|
||||
|
||||
Boolean inMethod = false;
|
||||
boolean inLocalOrParamOrReturn = false;
|
||||
|
||||
public final ArrayList<MethodAndTPH> ListOfMethodsAndTph = new ArrayList<>();
|
||||
final ArrayList<ResultPair<TypePlaceholder, TypePlaceholder>> allPairs = new ArrayList<>();
|
||||
final ArrayList<GenericInsertPair> allPairs = new ArrayList<>();
|
||||
public final ArrayList<TPHConstraint> allCons = new ArrayList<>();
|
||||
private ResultSet resultSet;
|
||||
private Resolver resolver;
|
||||
|
||||
public TPHExtractor() {
|
||||
|
||||
@@ -60,164 +37,42 @@ public class TPHExtractor extends AbstractASTWalker {
|
||||
|
||||
public void setResultSet(ResultSet resultSet) {
|
||||
this.resultSet = resultSet;
|
||||
this.resolver = new Resolver(resultSet);
|
||||
}
|
||||
|
||||
public Resolver getResolver() {
|
||||
return resolver;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void visit(ClassOrInterface classOrInterface) {
|
||||
// inMethod = false;
|
||||
// classOrInterface.getfieldInitializations().ifPresent(c->c.block.accept(this));
|
||||
// super.visit(classOrInterface);
|
||||
// inMethod = true;
|
||||
// }
|
||||
@Override
|
||||
public void visit(TypePlaceholder tph) {
|
||||
if (resultSet.resolveType(tph).resolvedType instanceof TypePlaceholder) {
|
||||
if(resultSet.resolveType(tph).resolvedType instanceof TypePlaceholder) {
|
||||
TypePlaceholder resolvedTPH = (TypePlaceholder) resultSet.resolveType(tph).resolvedType;
|
||||
if (inMethod) {
|
||||
if(inMethod)
|
||||
methodAndTph.getTphs().add(resolvedTPH.getName());
|
||||
if (inLocalOrParamOrReturn)
|
||||
methodAndTph.getLocalTphs().add(resolvedTPH.getName());
|
||||
}else {
|
||||
tphsClass.add(resolvedTPH.getName());
|
||||
}
|
||||
|
||||
allTPHS.put(resolvedTPH.getName(), inMethod);
|
||||
// final List<TPHConstraint> cons = new ArrayList<>();
|
||||
// resultSet.resolveType(tph).additionalGenerics.forEach(ag -> {
|
||||
// TPHConstraint con = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS);
|
||||
// cons.add(con);
|
||||
// });
|
||||
//
|
||||
// Map<TPHConstraint, Boolean> visitMap = new HashMap<>();
|
||||
// for(TPHConstraint cc : cons) {
|
||||
// visitMap.put(cc, false);
|
||||
// }
|
||||
//
|
||||
// String left = resolvedTPH.getName();
|
||||
// for (TPHConstraint cc : visitMap.keySet()) {
|
||||
//
|
||||
// if(visitMap.get(cc))
|
||||
// continue;
|
||||
//
|
||||
// if (cc.getLeft().equals(left)) {
|
||||
// allCons.add(cc);
|
||||
// List<TPHConstraint> toVisit = getToVisitCons(cons,cc.getRight(), visitMap);
|
||||
// }
|
||||
// }
|
||||
|
||||
//resultSet.resolveType(tph).getAdditionalGenerics().forEach(ag -> {
|
||||
resultSet.genIns.forEach(ag -> {
|
||||
|
||||
// if (ag.contains(resolvedTPH) /* && ag.TA1.equals(resolvedTPH) */ && !contains(allPairs, ag)) {
|
||||
if (inMethod)
|
||||
allTPHS.put(resolvedTPH,inMethod);
|
||||
resultSet.resolveType(tph).additionalGenerics.forEach(ag ->{
|
||||
if(ag.contains(resolvedTPH)&&ag.TA1.equals(resolvedTPH)&&!contains(allPairs,ag)) {
|
||||
if(inMethod)
|
||||
methodAndTph.getPairs().add(ag);
|
||||
allPairs.add(ag);
|
||||
TPHConstraint con = new ExtendsConstraint(ag.getLeft().getName(), ag.getRight().getName());
|
||||
if(!containsConstraint(allCons,con))
|
||||
TPHConstraint con = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS);
|
||||
allCons.add(con);
|
||||
// }
|
||||
}
|
||||
});
|
||||
} else if (resultSet.resolveType(tph).resolvedType instanceof RefType) {
|
||||
RefType rt = (RefType) resultSet.resolveType(tph).resolvedType;
|
||||
rt.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean containsConstraint(ArrayList<TPHConstraint> allCons, TPHConstraint c) {
|
||||
for(TPHConstraint con:allCons) {
|
||||
if(c.getLeft().equals(con.getLeft()) && c.getRight().equals(con.getRight())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private List<TPHConstraint> getToVisitCons(List<TPHConstraint> cons, String right, Map<TPHConstraint, Boolean> visitMap) {
|
||||
List<TPHConstraint> res = new ArrayList<>();
|
||||
for(TPHConstraint cc : cons) {
|
||||
if(cc.getLeft().equals(right)) {
|
||||
res.add(cc);
|
||||
if(visitMap.get(cc))
|
||||
visitMap.replace(cc, false);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(GenericRefType genericRefType) {
|
||||
String name = genericRefType.getParsedName();
|
||||
if (inMethod) {
|
||||
methodAndTph.getTphs().add(name);
|
||||
if (inLocalOrParamOrReturn)
|
||||
methodAndTph.getLocalTphs().add(name);
|
||||
}else {
|
||||
tphsClass.add(name);
|
||||
}
|
||||
allTPHS.put(name, inMethod);
|
||||
}
|
||||
|
||||
private boolean contains(ArrayList<GenericInsertPair> pairs, GenericInsertPair genPair) {
|
||||
for (int i = 0; i < pairs.size(); ++i) {
|
||||
for(int i=0; i<pairs.size();++i) {
|
||||
GenericInsertPair p = pairs.get(i);
|
||||
if (p.TA1.equals(genPair.TA1) && p.TA2.equals(genPair.TA2))
|
||||
if(p.TA1.equals(genPair.TA1) && p.TA2.equals(genPair.TA2))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Method method) {
|
||||
inMethod = true;
|
||||
String id = MethodUtility.createID(resolver,method);
|
||||
methodAndTph = new MethodAndTPH(id);
|
||||
|
||||
inLocalOrParamOrReturn = true;
|
||||
method.getReturnType().accept(this);
|
||||
method.getParameterList().accept(this);
|
||||
inLocalOrParamOrReturn = false;
|
||||
|
||||
if(method.block != null)
|
||||
method.block.accept(this);
|
||||
|
||||
methodAndTph = new MethodAndTPH(method.name);
|
||||
super.visit(method);
|
||||
inMethod = false;
|
||||
ListOfMethodsAndTph.add(methodAndTph);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Constructor cons) {
|
||||
inMethod = false;
|
||||
//super.visit(cons);
|
||||
cons.getParameterList().accept(this);
|
||||
if(cons.block != null)
|
||||
cons.block.accept(this);
|
||||
inMethod = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(LocalVarDecl localVarDecl) {
|
||||
// inLocalOrParamOrReturn = inMethod;
|
||||
super.visit(localVarDecl);
|
||||
// inLocalOrParamOrReturn = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(LocalVar localVar) {
|
||||
// inLocalOrParamOrReturn = inMethod;
|
||||
super.visit(localVar);
|
||||
// inLocalOrParamOrReturn = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ParameterList formalParameters) {
|
||||
inLocalOrParamOrReturn = inMethod;
|
||||
super.visit(formalParameters);
|
||||
inLocalOrParamOrReturn = false;
|
||||
}
|
||||
|
||||
}
|
@@ -2,8 +2,8 @@ package de.dhbwstuttgart.bytecode.constraint;
|
||||
|
||||
public class EqualConstraint extends TPHConstraint {
|
||||
|
||||
public EqualConstraint(String left, String right) {
|
||||
super(left, right, Relation.EQUAL);
|
||||
public EqualConstraint(String left, String right, Relation rel) {
|
||||
super(left, right, rel);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -2,8 +2,8 @@ package de.dhbwstuttgart.bytecode.constraint;
|
||||
|
||||
public class ExtendsConstraint extends TPHConstraint {
|
||||
|
||||
public ExtendsConstraint(String left, String right) {
|
||||
super(left, right, Relation.EXTENDS);
|
||||
public ExtendsConstraint(String left, String right, Relation rel) {
|
||||
super(left, right, rel);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -44,10 +44,6 @@ public class TPHConstraint {
|
||||
return left.equals(tph)||right.equals(tph);
|
||||
}
|
||||
|
||||
public boolean equalConstraint(TPHConstraint constraint) {
|
||||
return rel == constraint.getRel() && left.equals(constraint.getLeft()) && right.equals(constraint.getRight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if(rel == Relation.EXTENDS) {
|
||||
|
@@ -1,29 +1,30 @@
|
||||
package de.dhbwstuttgart.bytecode.descriptor;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.utilities.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
|
||||
import de.dhbwstuttgart.bytecode.utilities.Lambda;
|
||||
import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall;
|
||||
import de.dhbwstuttgart.bytecode.utilities.NormalConstructor;
|
||||
import de.dhbwstuttgart.bytecode.utilities.NormalMethod;
|
||||
import de.dhbwstuttgart.bytecode.utilities.SamMethod;
|
||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
|
||||
public class DescriptorToString implements DescriptorVisitor, CONSTANTS {
|
||||
public class DescriptorToString implements DescriptorVisitor{
|
||||
ResultSet resultSet;
|
||||
|
||||
public DescriptorToString() {
|
||||
}
|
||||
|
||||
public DescriptorToString(ResultSet resultSet) {
|
||||
this.resultSet = resultSet;
|
||||
}
|
||||
|
||||
private String addReturnType(String desc, RefTypeOrTPHOrWildcardOrGeneric returnType, ResultSet resultSet) {
|
||||
if(resultSet.resolveType(returnType).resolvedType.toString().equals(CONSTANTS.VOID)){
|
||||
if(resultSet.resolveType(returnType).resolvedType.toString().equals("void")){
|
||||
desc = desc + ")V";
|
||||
}else {
|
||||
desc = desc + ")" + "L"+resultSet.resolveType(returnType).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
||||
@@ -43,41 +44,30 @@ public class DescriptorToString implements DescriptorVisitor, CONSTANTS {
|
||||
if(method.hasGen()) {
|
||||
String fpDesc = fp.getType().acceptTV(new TypeToDescriptor());
|
||||
if(method.getGenericsAndBoundsMethod().containsKey(fpDesc)) {
|
||||
String bound = getBound(fpDesc, method.getGenericsAndBoundsMethod());
|
||||
desc += "L"+bound+ ";";
|
||||
desc += "L"+method.getGenericsAndBoundsMethod().get(fpDesc)+ ";";
|
||||
}else if(method.getGenericsAndBounds().containsKey(fpDesc)){
|
||||
String bound = getBound(fpDesc, method.getGenericsAndBounds());
|
||||
desc += "L"+bound+ ";";
|
||||
desc += "L"+method.getGenericsAndBounds().get(fpDesc)+ ";";
|
||||
}else {
|
||||
// desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
||||
String resType = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
if(resType.contains(CONSTANTS.TPH)/*resType.subSequence(0, 4).equals("TPH ")*/) {
|
||||
if(resType.subSequence(0, 4).equals("TPH ")) {
|
||||
// Bound ist immer Object
|
||||
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
||||
} else {
|
||||
// TODO::
|
||||
if(method.getGenericsAndBounds().containsKey(resType)) {
|
||||
String bound = getBound(resType, method.getGenericsAndBounds());
|
||||
desc += "L"+bound+ ";";
|
||||
}else if(method.getGenericsAndBoundsMethod().containsKey(resType)) {
|
||||
String bound = getBound(resType, method.getGenericsAndBoundsMethod());
|
||||
desc += "L"+bound+ ";";
|
||||
} else {
|
||||
desc += "L"+resType+ ";";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//TODO: generate a class java%% ... %%
|
||||
else if(resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()).contains(CONSTANTS.ANGLEBRACKET)){
|
||||
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "$$").replace(CONSTANTS.ANGLEBRACKET, "$$$").replace(">", "$$$")+ ";";
|
||||
else if(resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()).contains("<")){
|
||||
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "$$").replace("<", "$$$").replace(">", "$$$")+ ";";
|
||||
}
|
||||
else {
|
||||
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
||||
}
|
||||
}
|
||||
|
||||
if(resultSet.resolveType(method.getReturnType()).resolvedType.toString().equals(CONSTANTS.VOID)) {
|
||||
if(resultSet.resolveType(method.getReturnType()).resolvedType.toString().equals("void")) {
|
||||
desc += ")V";
|
||||
}else {
|
||||
if(method.hasGen()) {
|
||||
@@ -88,21 +78,11 @@ public class DescriptorToString implements DescriptorVisitor, CONSTANTS {
|
||||
desc += ")L"+method.getGenericsAndBounds().get(ret)+ ";";
|
||||
}else {
|
||||
String resType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
if(resType.contains(CONSTANTS.TPH)/*resType.subSequence(0, 4).equals("TPH ")*/) {
|
||||
if(resType.subSequence(0, 4).equals("TPH ")) {
|
||||
// desc += ")" + "L"+method.getGenericsAndBoundsMethod().get(resType.substring(4)+"$")+ ";";
|
||||
desc += ")" + "L"+Type.getInternalName(Object.class)+ ";";
|
||||
} else {
|
||||
// TODO::
|
||||
if(method.getGenericsAndBounds().containsKey(resType)) {
|
||||
String bound = getBound(resType, method.getGenericsAndBounds());
|
||||
desc += ")L"+bound+ ";";
|
||||
}else if(method.getGenericsAndBoundsMethod().containsKey(resType)) {
|
||||
String bound = getBound(resType, method.getGenericsAndBoundsMethod());
|
||||
desc += ")L"+bound+ ";";
|
||||
} else {
|
||||
desc += ")L"+resType+ ";";
|
||||
}
|
||||
// desc += ")" + "L"+resType+ ";";
|
||||
desc += ")" + "L"+resType+ ";";
|
||||
}
|
||||
}
|
||||
}else {
|
||||
@@ -113,15 +93,6 @@ public class DescriptorToString implements DescriptorVisitor, CONSTANTS {
|
||||
return desc;
|
||||
}
|
||||
|
||||
private String getBound(String fpDesc, HashMap<String, String> genericsAndBounds) {
|
||||
String start = genericsAndBounds.get(fpDesc);
|
||||
while(genericsAndBounds.containsKey(start)) {
|
||||
start = genericsAndBounds.get(start);
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visit(NormalConstructor constructor) {
|
||||
String desc = "(";
|
||||
@@ -137,7 +108,7 @@ public class DescriptorToString implements DescriptorVisitor, CONSTANTS {
|
||||
}else {
|
||||
// desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
||||
String resType = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
if(resType.subSequence(0, 4).equals(CONSTANTS.TPH)) {
|
||||
if(resType.subSequence(0, 4).equals("TPH ")) {
|
||||
// Bound ist immer Object
|
||||
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
||||
} else {
|
||||
@@ -160,7 +131,7 @@ public class DescriptorToString implements DescriptorVisitor, CONSTANTS {
|
||||
while(itr.hasNext()) {
|
||||
FormalParameter fp = itr.next();
|
||||
String d = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
if(d.contains(CONSTANTS.TPH) ||d.contains(CONSTANTS.ANGLEBRACKET)) {
|
||||
if(d.substring(0, 4).equals("TPH ") ||d.contains("<")) {
|
||||
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
||||
}else {
|
||||
desc = desc + "L"+ d + ";";
|
||||
@@ -169,7 +140,7 @@ public class DescriptorToString implements DescriptorVisitor, CONSTANTS {
|
||||
|
||||
String retType = resultSet.resolveType(lambdaExpression.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
|
||||
if(retType.contains(CONSTANTS.TPH)|| retType.contains(CONSTANTS.ANGLEBRACKET)){
|
||||
if(retType.substring(0, 4).equals("TPH ")|| retType.contains("<")){
|
||||
desc += ")L"+Type.getInternalName(Object.class)+ ";";
|
||||
}else {
|
||||
desc = desc + ")"+"L"+retType+";";
|
||||
@@ -185,7 +156,7 @@ public class DescriptorToString implements DescriptorVisitor, CONSTANTS {
|
||||
RefTypeOrTPHOrWildcardOrGeneric rt = itr.next();
|
||||
String d = resultSet.resolveType(rt).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
|
||||
if(d.contains(CONSTANTS.TPH) ||d.contains(CONSTANTS.ANGLEBRACKET)) {
|
||||
if(d.substring(0, 4).equals("TPH ") ||d.contains("<")) {
|
||||
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
||||
}else {
|
||||
desc += "L"+ d + ";";
|
||||
@@ -194,7 +165,7 @@ public class DescriptorToString implements DescriptorVisitor, CONSTANTS {
|
||||
}
|
||||
String retType = resultSet.resolveType(samMethod.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
|
||||
if(retType.contains(CONSTANTS.TPH)|| retType.contains(CONSTANTS.ANGLEBRACKET)){
|
||||
if(retType.substring(0, 4).equals("TPH ")|| retType.contains("<")){
|
||||
desc += ")L"+Type.getInternalName(Object.class)+ ";";
|
||||
}else {
|
||||
desc = desc + ")"+"L"+retType+";";
|
||||
@@ -208,7 +179,7 @@ public class DescriptorToString implements DescriptorVisitor, CONSTANTS {
|
||||
for(Expression e : methodFromMethodCall.getArgList().getArguments()) {
|
||||
String d = resultSet.resolveType(e.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
|
||||
if(d.contains(CONSTANTS.TPH) ||d.contains(CONSTANTS.ANGLEBRACKET) || methodFromMethodCall.getReceiverName().contains("$$")) {
|
||||
if(d.substring(0, 4).equals("TPH ") ||d.contains("<") || methodFromMethodCall.getReceiverName().contains("$$")) {
|
||||
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
||||
}else {
|
||||
if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(d)) {
|
||||
@@ -223,9 +194,9 @@ public class DescriptorToString implements DescriptorVisitor, CONSTANTS {
|
||||
}
|
||||
String retType = resultSet.resolveType(methodFromMethodCall.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
System.out.println("DescriptorToString retType = " + retType);
|
||||
if(retType.equals(CONSTANTS.VOID)) {
|
||||
if(retType.equals("void")) {
|
||||
desc += ")V";
|
||||
}else if(retType.contains(CONSTANTS.TPH)|| retType.contains(CONSTANTS.ANGLEBRACKET) || methodFromMethodCall.getReceiverName().contains("$$")){
|
||||
}else if(retType.substring(0, 4).equals("TPH ")|| retType.contains("<") || methodFromMethodCall.getReceiverName().contains("$$")){
|
||||
desc += ")L"+Type.getInternalName(Object.class)+ ";";
|
||||
}else {
|
||||
if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(retType)) {
|
||||
@@ -240,20 +211,4 @@ public class DescriptorToString implements DescriptorVisitor, CONSTANTS {
|
||||
return desc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createDescForFunN(ArgumentList argumentList, String returnType) {
|
||||
Iterator<Expression> itr1 = argumentList.getArguments().iterator();
|
||||
String methDesc = "(";
|
||||
while(itr1.hasNext()) {
|
||||
methDesc += "L" + Type.getInternalName(Object.class) + ";";
|
||||
itr1.next();
|
||||
}
|
||||
if (returnType.equals(CONSTANTS.VOID)){
|
||||
methDesc += ")V";
|
||||
} else {
|
||||
methDesc += ")L" + Type.getInternalName(Object.class) + ";";
|
||||
}
|
||||
return methDesc;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -5,13 +5,11 @@ import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall;
|
||||
import de.dhbwstuttgart.bytecode.utilities.NormalConstructor;
|
||||
import de.dhbwstuttgart.bytecode.utilities.NormalMethod;
|
||||
import de.dhbwstuttgart.bytecode.utilities.SamMethod;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
||||
|
||||
public interface DescriptorVisitor {
|
||||
String visit(NormalMethod method);
|
||||
String visit(NormalConstructor constructor);
|
||||
String visit(Lambda lambdaExpression);
|
||||
String visit(SamMethod samMethod);
|
||||
String visit(MethodFromMethodCall methodFromMethodCall);
|
||||
String createDescForFunN(ArgumentList argumentList, String returnType);
|
||||
public String visit(NormalMethod method);
|
||||
public String visit(NormalConstructor constructor);
|
||||
public String visit(Lambda lambdaExpression);
|
||||
public String visit(SamMethod samMethod);
|
||||
public String visit(MethodFromMethodCall methodFromMethodCall);
|
||||
}
|
||||
|
@@ -20,8 +20,7 @@ public class TypeToDescriptor implements TypeVisitor<String>{
|
||||
@Override
|
||||
public String visit(SuperWildcardType superWildcardType) {
|
||||
System.out.println("\nWILDCARD ="+superWildcardType.getInnerType().toString().replace(".", "/"));
|
||||
//return superWildcardType.getInnerType().toString().replace(".", "/");
|
||||
return superWildcardType.getInnerType().acceptTV(new TypeToDescriptor());
|
||||
return superWildcardType.getInnerType().toString().replace(".", "/");
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@@ -33,8 +32,7 @@ public class TypeToDescriptor implements TypeVisitor<String>{
|
||||
@Override
|
||||
public String visit(ExtendsWildcardType extendsWildcardType) {
|
||||
System.out.println("\nWILDCARD extends ="+extendsWildcardType.getInnerType().toString().replace(".", "/"));
|
||||
//return extendsWildcardType.getInnerType().toString().replace(".", "/");
|
||||
return extendsWildcardType.getInnerType().acceptTV(new TypeToDescriptor());
|
||||
return extendsWildcardType.getInnerType().toString().replace(".", "/");
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
@@ -1,53 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.genericsGenerator;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.NameReplacementResult;
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResult;
|
||||
|
||||
/**
|
||||
* This class represents the result of the constraints simplifier.
|
||||
*
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class ConstraintsSimplierResult {
|
||||
private List<GenericsGeneratorResult> genericsGenResults;
|
||||
private List<NameReplacementResult> nameReplacementResults;
|
||||
/**
|
||||
* @param genericsGenResults
|
||||
*/
|
||||
public ConstraintsSimplierResult(List<GenericsGeneratorResult> genericsGenResults,
|
||||
List<NameReplacementResult> nameReplacementResults) {
|
||||
this.genericsGenResults = genericsGenResults;
|
||||
this.setNameReplacementResults(nameReplacementResults);
|
||||
}
|
||||
/**
|
||||
* @return the genericsGenResults
|
||||
*/
|
||||
public List<GenericsGeneratorResult> getGenericsGenResults() {
|
||||
return genericsGenResults;
|
||||
}
|
||||
/**
|
||||
* @param genericsGenResults the genericsGenResults to set
|
||||
*/
|
||||
public void setGenericsGenResults(List<GenericsGeneratorResult> genericsGenResults) {
|
||||
this.genericsGenResults = genericsGenResults;
|
||||
}
|
||||
/**
|
||||
* @return the nameReplacementResults
|
||||
*/
|
||||
public List<NameReplacementResult> getNameReplacementResults() {
|
||||
return nameReplacementResults;
|
||||
}
|
||||
/**
|
||||
* @param nameReplacementResults the nameReplacementResults to set
|
||||
*/
|
||||
public void setNameReplacementResults(List<NameReplacementResult> nameReplacementResults) {
|
||||
this.nameReplacementResults = nameReplacementResults;
|
||||
}
|
||||
|
||||
}
|
@@ -1,137 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.genericsGenerator;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.TPHExtractor;
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.*;
|
||||
|
||||
/**
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class ConstraintsSimplifier {
|
||||
public static ConstraintsSimplierResult simplifyConstraints(final TPHExtractor tphExtractor, final List<GenericsGeneratorResult> genericsGeneratorResults, final List<String> tphsClass) {
|
||||
|
||||
List<TPHConstraint> allCons = tphExtractor.allCons;
|
||||
List<TPHConstraint> equalCons = new ArrayList<>();
|
||||
|
||||
/* Step 1 */
|
||||
List<ConstraintsWithSameLeftSide> foundCons = GenericsGeneratorUtility.findConstraintsWithLeftSameLeftSide(allCons);
|
||||
if(!foundCons.isEmpty()) {
|
||||
List<TPHConstraint> equalCons2 = new ArrayList<>();
|
||||
GenericsGeneratorUtility.simplifyConstraintsWithSameLeftSide(foundCons,tphExtractor,tphsClass,equalCons2);
|
||||
equalCons.addAll(equalCons2);
|
||||
}
|
||||
|
||||
// if(!simpleCycles.isEmpty()) {
|
||||
// handleSimpleCycles(allCons, simpleCycles,tphExtractor);
|
||||
// equalCons.addAll(GenericsGeneratorUtility.getEqualConstraints(allCons));
|
||||
// }
|
||||
//
|
||||
List<Cycle> cycles = findCycles(allCons);
|
||||
|
||||
if(!cycles.isEmpty()) {
|
||||
handleCycle(genericsGeneratorResults, allCons, cycles,tphExtractor);
|
||||
}
|
||||
/* The right hand side of equal constraint is the new name in name replacement result */
|
||||
List<NameReplacementResult> nameReplacementResults = GenericsGeneratorUtility.createNameReplacementResultsFromEqualConstraints(equalCons);
|
||||
getEqualsFromNameReplacementResults(genericsGeneratorResults,nameReplacementResults);
|
||||
ConstraintsSimplierResult result = new ConstraintsSimplierResult(genericsGeneratorResults, nameReplacementResults);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void getEqualsFromNameReplacementResults(List<GenericsGeneratorResult> genericsGeneratorResults,
|
||||
List<NameReplacementResult> nameReplacementResults) {
|
||||
genericsGeneratorResults.forEach(g->{
|
||||
String tph = g.getConstraint().getLeft();
|
||||
if (!nameReplacementResults.isEmpty()) {
|
||||
collectAllEquals(nameReplacementResults, g, tph);
|
||||
}
|
||||
|
||||
if (!nameReplacementResults.isEmpty()) {
|
||||
collectAllEquals(nameReplacementResults, g);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private static void collectAllEquals(List<NameReplacementResult> nameReplacementResults, GenericsGeneratorResult g) {
|
||||
Set<String> equalsTPHs = g.getEqualsTPHs();
|
||||
Set<String> tphsToAdd = getAllEqualTphs(equalsTPHs, nameReplacementResults);
|
||||
while (!tphsToAdd.isEmpty()){
|
||||
equalsTPHs.addAll(tphsToAdd);
|
||||
tphsToAdd = getAllEqualTphs(equalsTPHs, nameReplacementResults);
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<String> getAllEqualTphs(Set<String> equalsTPHs, List<NameReplacementResult> nameReplacementResults) {
|
||||
Set<String> tphsToAdd = new HashSet<>();
|
||||
equalsTPHs.forEach(e->{
|
||||
collectAllEquals(nameReplacementResults, tphsToAdd,e);
|
||||
});
|
||||
return tphsToAdd;
|
||||
}
|
||||
|
||||
public static void collectAllEquals(List<NameReplacementResult> nameReplacementResults, Set<String> tphsToAdd,
|
||||
String tph) {
|
||||
List<NameReplacementResult> toRemoveList = new ArrayList<>();
|
||||
Optional<NameReplacementResult> nameReplacementResult = nameReplacementResults.stream().filter(n->n.getName().equals(tph)).findFirst();
|
||||
nameReplacementResult.ifPresent(toRemove->{
|
||||
tphsToAdd.addAll(toRemove.getOldNames());
|
||||
toRemoveList.add(toRemove);
|
||||
});
|
||||
if(!toRemoveList.isEmpty()){
|
||||
nameReplacementResults.remove(toRemoveList.get(0));
|
||||
toRemoveList.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nameReplacementResults
|
||||
* @param g
|
||||
* @param tph
|
||||
*/
|
||||
public static void collectAllEquals(List<NameReplacementResult> nameReplacementResults, GenericsGeneratorResult g,
|
||||
String tph) {
|
||||
List<NameReplacementResult> toRemoveList = new ArrayList<>();
|
||||
Optional<NameReplacementResult> nameReplacementResult = nameReplacementResults.stream().filter(n->n.getName().equals(tph)).findFirst();
|
||||
nameReplacementResult.ifPresent(toRemove->{
|
||||
g.getEqualsTPHs().addAll(toRemove.getOldNames());
|
||||
toRemoveList.add(toRemove);
|
||||
});
|
||||
if(!toRemoveList.isEmpty()){
|
||||
nameReplacementResults.remove(toRemoveList.get(0));
|
||||
toRemoveList.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param genericsGeneratorResults
|
||||
* @param allCons
|
||||
* @param cycles
|
||||
* @param tphExtractor
|
||||
*/
|
||||
public static void handleCycle(List<GenericsGeneratorResult> genericsGeneratorResults,
|
||||
List<TPHConstraint> allCons, List<Cycle> cycles, TPHExtractor tphExtractor) {
|
||||
GenericsGeneratorUtility.modifyRelationForConstraintsInCycle(cycles);
|
||||
List<NameReplacementResult> nameReplacementResults = GenericsGeneratorUtility.substituteTPHSFormCycle(allCons, cycles,tphExtractor);
|
||||
GenericsGeneratorUtility.createResults(genericsGeneratorResults,nameReplacementResults);
|
||||
GenericsGeneratorUtility.removeEqualConstraints(allCons);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param allCons
|
||||
* @return
|
||||
*/
|
||||
public static List<Cycle> findCycles(List<TPHConstraint> allCons) {
|
||||
/* find all cycles */
|
||||
CyclesFinder cyclesFinder = new CyclesFinder(allCons);
|
||||
List<Cycle> cycles = cyclesFinder.findCycles();
|
||||
return cycles;
|
||||
}
|
||||
|
||||
}
|
@@ -1,106 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.genericsGenerator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.Cycle;
|
||||
|
||||
/**
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class CyclesFinder {
|
||||
private final List<TPHConstraint> allCons;
|
||||
|
||||
public CyclesFinder(List<TPHConstraint> allCons) {
|
||||
this.allCons = allCons;
|
||||
}
|
||||
|
||||
public List<Cycle> findCycles() {
|
||||
List<TPHConstraint> vistedConstraints = new ArrayList<>(allCons.size());
|
||||
List<Cycle> cycles = new ArrayList<>();
|
||||
for (TPHConstraint constraint : allCons) {
|
||||
if(constraint.getRel()==Relation.EQUAL)
|
||||
continue;
|
||||
if (!vistedConstraints.contains(constraint)) {
|
||||
vistedConstraints.add(constraint);
|
||||
checkConstraint(constraint, vistedConstraints, cycles);
|
||||
}
|
||||
}
|
||||
return cycles;
|
||||
}
|
||||
|
||||
private void checkConstraint(TPHConstraint constraint, List<TPHConstraint> vistedConstraints,
|
||||
List<Cycle> cycles) {
|
||||
List<String> tphsInRelation = new LinkedList<>();
|
||||
List<TPHConstraint> maybeCycle = new ArrayList<>();
|
||||
maybeCycle.add(constraint);
|
||||
tphsInRelation.add(constraint.getLeft());
|
||||
tphsInRelation.add(constraint.getRight());
|
||||
Optional<TPHConstraint> nextConstraint = getConstraintInRelation(tphsInRelation, maybeCycle);
|
||||
while (nextConstraint.isPresent()) {
|
||||
if(containsInLongCycle(nextConstraint.get(), cycles)) {
|
||||
break;
|
||||
}
|
||||
if (isCycle(tphsInRelation)) {
|
||||
addAllToVisitedConstraints(vistedConstraints, maybeCycle);
|
||||
Cycle cycle = new Cycle(maybeCycle);
|
||||
cycles.add(cycle);
|
||||
return;
|
||||
}
|
||||
nextConstraint = getConstraintInRelation(tphsInRelation, maybeCycle);
|
||||
}
|
||||
|
||||
// addAllToVisitedConstraints(vistedConstraints, maybeCycle);
|
||||
}
|
||||
|
||||
private boolean containsInLongCycle(TPHConstraint c, List<Cycle> cycles) {
|
||||
for(Cycle cycle : cycles) {
|
||||
if(cycle.containConstraint(c))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addAllToVisitedConstraints(List<TPHConstraint> vistedConstraints, List<TPHConstraint> maybeCycle) {
|
||||
for (TPHConstraint con : maybeCycle) {
|
||||
if (!vistedConstraints.contains(con))
|
||||
vistedConstraints.add(con);
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<TPHConstraint> getConstraintInRelation(List<String> tphsInRelation,
|
||||
List<TPHConstraint> maybeCycle) {
|
||||
TPHConstraint constraint = getConstraintByLeftSide(tphsInRelation.get(tphsInRelation.size()-1),maybeCycle);
|
||||
Optional<TPHConstraint> nextConstraint = Optional.ofNullable(constraint);
|
||||
if(nextConstraint.isPresent()) {
|
||||
maybeCycle.add(constraint);
|
||||
tphsInRelation.add(constraint.getRight());
|
||||
}
|
||||
return nextConstraint;
|
||||
}
|
||||
|
||||
private TPHConstraint getConstraintByLeftSide(String left, List<TPHConstraint> maybeCycle) {
|
||||
for(TPHConstraint constraint : allCons) {
|
||||
if(constraint.getRel()==Relation.EQUAL)
|
||||
continue;
|
||||
if(maybeCycle.contains(constraint))
|
||||
continue;
|
||||
if(constraint.getLeft().equals(left))
|
||||
return constraint;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isCycle(List<String> tphsInRelation) {
|
||||
return tphsInRelation.get(0).equals(tphsInRelation.get(tphsInRelation.size() - 1));
|
||||
}
|
||||
|
||||
}
|
@@ -1,675 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.genericsGenerator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.TPHExtractor;
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericGenratorResultForSourceFile;
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResultForClass;
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.MethodAndConstraints;
|
||||
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
||||
import de.dhbwstuttgart.bytecode.utilities.MethodUtility;
|
||||
import de.dhbwstuttgart.bytecode.utilities.Resolver;
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.Constructor;
|
||||
import de.dhbwstuttgart.syntaxtree.Field;
|
||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.ParameterList;
|
||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Assign;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.AssignToField;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Block;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.CastExpr;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.DoStmt;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.EmptyStmt;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.ExpressionReceiver;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.FieldVar;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.ForStmt;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.IfStmt;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.InstanceOf;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Literal;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.NewArray;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.NewClass;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Return;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.ReturnVoid;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.StaticClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Super;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.SuperCall;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.This;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.WhileStmt;
|
||||
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
|
||||
/**
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class GeneratedGenericsFinder implements ASTVisitor {
|
||||
private final TPHExtractor tphExtractor = new TPHExtractor();
|
||||
private Collection<ResultSet> listOfResultSets;
|
||||
private SourceFile sf;
|
||||
private List<String> tphsClass;
|
||||
private GenericGenratorResultForSourceFile generatedGenericsForSF;
|
||||
private ResultSet resultSet;
|
||||
private final List<String> methodNameAndParamsT = new ArrayList<>();
|
||||
|
||||
private String pkgName;
|
||||
private JavaClassName className;
|
||||
private Resolver resolver;
|
||||
|
||||
/**
|
||||
* @param sf
|
||||
* @param listOfResultSets
|
||||
*/
|
||||
public GeneratedGenericsFinder(SourceFile sf, Collection<ResultSet> listOfResultSets) {
|
||||
this.sf = sf;
|
||||
this.listOfResultSets = listOfResultSets;
|
||||
}
|
||||
|
||||
public GenericGenratorResultForSourceFile findGeneratedGenerics() {
|
||||
sf.accept(this);
|
||||
return generatedGenericsForSF;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.
|
||||
* SourceFile)
|
||||
*/
|
||||
@Override
|
||||
public void visit(SourceFile sourceFile) {
|
||||
pkgName = sf.getPkgName();
|
||||
generatedGenericsForSF = new GenericGenratorResultForSourceFile(pkgName);
|
||||
for (ClassOrInterface cl : sourceFile.getClasses()) {
|
||||
cl.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.
|
||||
* ClassOrInterface)
|
||||
*/
|
||||
@Override
|
||||
public void visit(ClassOrInterface classOrInterface) {
|
||||
className = classOrInterface.getClassName();
|
||||
List<ResultSet> listOfResultSetsList = new ArrayList<>(listOfResultSets);
|
||||
|
||||
boolean isVisited = false;
|
||||
|
||||
ConstraintsSimplierResult simplifiedConstraints = null;
|
||||
GenericsGeneratorResultForClass ggResult = null;
|
||||
|
||||
for (int i = 0; i < listOfResultSetsList.size(); i++) {
|
||||
resultSet = listOfResultSetsList.get(i);
|
||||
tphExtractor.setResultSet(resultSet);
|
||||
resolver = new Resolver(resultSet);
|
||||
classOrInterface.accept(tphExtractor);
|
||||
tphsClass = tphExtractor.tphsClass;
|
||||
simplifiedConstraints = GenericsGenerator.simplifyConstraints(tphExtractor, tphsClass);
|
||||
if(!isVisited) {
|
||||
ggResult = GenericsGenerator.generateConstraints(className, tphExtractor, tphsClass,simplifiedConstraints);
|
||||
isVisited = true;
|
||||
}
|
||||
|
||||
for(Method m : classOrInterface.getMethods()) {
|
||||
addMethodConstraints(simplifiedConstraints, ggResult, m);
|
||||
|
||||
}
|
||||
|
||||
if(ggResult != null)
|
||||
generatedGenericsForSF.addGenericGeneratorResultClass(ggResult);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param simplifiedConstraints
|
||||
* @param ggResult
|
||||
* @param m
|
||||
*/
|
||||
public void addMethodConstraints(ConstraintsSimplierResult simplifiedConstraints,
|
||||
GenericsGeneratorResultForClass ggResult, Method m) {
|
||||
String id = MethodUtility.createID(resolver, m);
|
||||
boolean isInGGResult = (ggResult != null) && ggResult.contains(id);
|
||||
if(methodNameAndParamsT.contains(id) || isInGGResult)
|
||||
return;
|
||||
methodNameAndParamsT.add(id);
|
||||
Optional<MethodAndTPH> methodAndTPH = GenericsGeneratorUtility.getMethodAndTphs(tphExtractor.ListOfMethodsAndTph,id);
|
||||
methodAndTPH.ifPresent(mt->{
|
||||
MethodAndConstraints methodConstraints = GenericsGenerator.generateConstraintsForMethod(tphExtractor.allCons, mt , simplifiedConstraints, tphsClass);
|
||||
ggResult.getMethodsAndTheirConstraints().getMethodsAndConstraints().add(methodConstraints);
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.
|
||||
* Method)
|
||||
*/
|
||||
@Override
|
||||
public void visit(Method method) {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.
|
||||
* ParameterList)
|
||||
*/
|
||||
@Override
|
||||
public void visit(ParameterList formalParameters) {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.
|
||||
* Constructor)
|
||||
*/
|
||||
@Override
|
||||
public void visit(Constructor field) {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.ArgumentList)
|
||||
*/
|
||||
@Override
|
||||
public void visit(ArgumentList argumentList) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.LambdaExpression)
|
||||
*/
|
||||
@Override
|
||||
public void visit(LambdaExpression lambdaExpression) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.Assign)
|
||||
*/
|
||||
@Override
|
||||
public void visit(Assign assign) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.BinaryExpr)
|
||||
*/
|
||||
@Override
|
||||
public void visit(BinaryExpr binary) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.Block)
|
||||
*/
|
||||
@Override
|
||||
public void visit(Block block) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.CastExpr)
|
||||
*/
|
||||
@Override
|
||||
public void visit(CastExpr castExpr) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.EmptyStmt)
|
||||
*/
|
||||
@Override
|
||||
public void visit(EmptyStmt emptyStmt) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.FieldVar)
|
||||
*/
|
||||
@Override
|
||||
public void visit(FieldVar fieldVar) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.ForStmt)
|
||||
*/
|
||||
@Override
|
||||
public void visit(ForStmt forStmt) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.IfStmt)
|
||||
*/
|
||||
@Override
|
||||
public void visit(IfStmt ifStmt) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.InstanceOf)
|
||||
*/
|
||||
@Override
|
||||
public void visit(InstanceOf instanceOf) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.LocalVar)
|
||||
*/
|
||||
@Override
|
||||
public void visit(LocalVar localVar) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.LocalVarDecl)
|
||||
*/
|
||||
@Override
|
||||
public void visit(LocalVarDecl localVarDecl) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.MethodCall)
|
||||
*/
|
||||
@Override
|
||||
public void visit(MethodCall methodCall) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.NewClass)
|
||||
*/
|
||||
@Override
|
||||
public void visit(NewClass methodCall) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.NewArray)
|
||||
*/
|
||||
@Override
|
||||
public void visit(NewArray newArray) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.Return)
|
||||
*/
|
||||
@Override
|
||||
public void visit(Return aReturn) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.ReturnVoid)
|
||||
*/
|
||||
@Override
|
||||
public void visit(ReturnVoid aReturn) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.StaticClassName)
|
||||
*/
|
||||
@Override
|
||||
public void visit(StaticClassName staticClassName) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.Super)
|
||||
*/
|
||||
@Override
|
||||
public void visit(Super aSuper) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.This)
|
||||
*/
|
||||
@Override
|
||||
public void visit(This aThis) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.WhileStmt)
|
||||
*/
|
||||
@Override
|
||||
public void visit(WhileStmt whileStmt) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.DoStmt)
|
||||
*/
|
||||
@Override
|
||||
public void visit(DoStmt whileStmt) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.AssignToField)
|
||||
*/
|
||||
@Override
|
||||
public void visit(AssignToField assignLeftSide) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.parser.
|
||||
* SyntaxTreeGenerator.AssignToLocal)
|
||||
*/
|
||||
@Override
|
||||
public void visit(AssignToLocal assignLeftSide) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.SuperCall)
|
||||
*/
|
||||
@Override
|
||||
public void visit(SuperCall superCall) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.ExpressionReceiver)
|
||||
*/
|
||||
@Override
|
||||
public void visit(ExpressionReceiver expressionReceiver) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.UnaryExpr)
|
||||
*/
|
||||
@Override
|
||||
public void visit(UnaryExpr unaryExpr) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
|
||||
* syntaxtree.statement.Literal)
|
||||
*/
|
||||
@Override
|
||||
public void visit(Literal literal) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.
|
||||
* GenericTypeVar)
|
||||
*/
|
||||
@Override
|
||||
public void visit(GenericTypeVar genericTypeVar) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.
|
||||
* FormalParameter)
|
||||
*/
|
||||
@Override
|
||||
public void visit(FormalParameter formalParameter) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.
|
||||
* GenericDeclarationList)
|
||||
*/
|
||||
@Override
|
||||
public void visit(GenericDeclarationList genericTypeVars) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.
|
||||
* Field)
|
||||
*/
|
||||
@Override
|
||||
public void visit(Field field) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.type
|
||||
* .RefType)
|
||||
*/
|
||||
@Override
|
||||
public void visit(RefType refType) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.type
|
||||
* .SuperWildcardType)
|
||||
*/
|
||||
@Override
|
||||
public void visit(SuperWildcardType superWildcardType) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.type
|
||||
* .TypePlaceholder)
|
||||
*/
|
||||
@Override
|
||||
public void visit(TypePlaceholder typePlaceholder) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.type
|
||||
* .ExtendsWildcardType)
|
||||
*/
|
||||
@Override
|
||||
public void visit(ExtendsWildcardType extendsWildcardType) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.type
|
||||
* .GenericRefType)
|
||||
*/
|
||||
@Override
|
||||
public void visit(GenericRefType genericRefType) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -1,256 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.genericsGenerator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.*;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.TPHExtractor;
|
||||
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
||||
|
||||
/**
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class GenericsGenerator {
|
||||
/*TODO: When generating generics for a class if we have the following:
|
||||
tphClass < tphMeth1 < tphMeth2
|
||||
then we have to convert tphMeth1, tphMeth2 to tph class and generate the following
|
||||
class constraints: tphClass < tphMeth1, tphMeth1 < tphMeth2, tphMeth2 < Object
|
||||
*/
|
||||
|
||||
public static GenericsGeneratorResultForClass generateConstraints(final JavaClassName className, final TPHExtractor tphExtractor,
|
||||
final List<String> tphsClass, final ConstraintsSimplierResult simplifiedConstraints) {
|
||||
|
||||
List<GenericsGeneratorResult> classConstraints = generateConstraintsForClass(tphExtractor,
|
||||
simplifiedConstraints, tphsClass);
|
||||
// GenericGeneratorResultsForAllMethods methodsAndConstraints = generateConstraintsForAllMethods(tphExtractor,
|
||||
// simplifiedConstraints, tphsClass);
|
||||
GenericGeneratorResultsForAllMethods methodsAndConstraints = new GenericGeneratorResultsForAllMethods(new ArrayList<>());
|
||||
|
||||
return new GenericsGeneratorResultForClass(className, classConstraints, methodsAndConstraints);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param tphExtractor
|
||||
* @param tphsClass
|
||||
* @return
|
||||
*/
|
||||
public static ConstraintsSimplierResult simplifyConstraints(final TPHExtractor tphExtractor,
|
||||
final List<String> tphsClass) {
|
||||
final List<GenericsGeneratorResult> genericsGeneratorResults = new ArrayList<>();
|
||||
|
||||
ConstraintsSimplierResult simplifiedConstraints = ConstraintsSimplifier.simplifyConstraints(tphExtractor,
|
||||
genericsGeneratorResults, tphsClass);
|
||||
return simplifiedConstraints;
|
||||
}
|
||||
|
||||
|
||||
private static List<GenericsGeneratorResult> generateConstraintsForClass(final TPHExtractor tphExtractor,
|
||||
final ConstraintsSimplierResult simplifiedConstraints, final List<String> tphsClass) {
|
||||
final List<GenericsGeneratorResult> constraints = new ArrayList<>();
|
||||
|
||||
if (tphsClass.isEmpty())
|
||||
return constraints;
|
||||
|
||||
final List<TPHConstraint> allCons = tphExtractor.allCons;
|
||||
|
||||
final Set<String> visitedTPHs = new HashSet<>();
|
||||
|
||||
final List<String> methodTPHs = tphExtractor.ListOfMethodsAndTph.stream().map(m -> m.getLocalTphs())
|
||||
.flatMap(l -> l.stream()).collect(Collectors.toList());
|
||||
|
||||
createConstraintsForClassTphs(simplifiedConstraints, tphsClass, constraints, allCons, visitedTPHs, methodTPHs);
|
||||
|
||||
GenericsGeneratorUtility.addTPHsToClassTPHs(constraints, tphsClass);
|
||||
GenericsGeneratorUtility.removeClassTPHsFromMethodTPHs(tphsClass, tphExtractor);
|
||||
|
||||
generateGGConstraintsForTPH(tphsClass, constraints, simplifiedConstraints);
|
||||
|
||||
return constraints;
|
||||
}
|
||||
|
||||
private static void createConstraintsForClassTphs(ConstraintsSimplierResult simplifiedConstraints, List<String> tphsClass, List<GenericsGeneratorResult> constraints, List<TPHConstraint> allCons, Set<String> visitedTPHs, List<String> methodTPHs) {
|
||||
List<String> classAndMethodTphs = new ArrayList<>(tphsClass);
|
||||
classAndMethodTphs.addAll(methodTPHs);
|
||||
|
||||
for (String tph : tphsClass) {
|
||||
|
||||
if (visitedTPHs.contains(tph))
|
||||
continue;
|
||||
|
||||
final LinkedList<String> tphsInRel = GenericsGeneratorUtility
|
||||
.createLinkedListForTPHsInRelationClass(allCons, tphsClass, methodTPHs, visitedTPHs, tph);
|
||||
|
||||
generateConstraintsForClassFromList(tphsInRel,simplifiedConstraints,classAndMethodTphs,constraints);
|
||||
}
|
||||
}
|
||||
|
||||
private static void generateConstraintsForClassFromList(LinkedList<String> tphsInRel, ConstraintsSimplierResult simplifiedConstraints, List<String> classAndMethodTphs, List<GenericsGeneratorResult> constraints) {
|
||||
|
||||
if(tphsInRel.isEmpty())
|
||||
return;
|
||||
|
||||
List<GenericsGeneratorResult> resultConstraints = new ArrayList<>();
|
||||
String subType = tphsInRel.getFirst();
|
||||
String superType = GenericsGeneratorUtility.getNextClassTph(classAndMethodTphs, tphsInRel);
|
||||
|
||||
int idxOfSuper = tphsInRel.indexOf(superType);
|
||||
int size = tphsInRel.size();
|
||||
while (size > 2 && idxOfSuper < size-1){
|
||||
GenericsGeneratorResult genericsGeneratorResult = getGenericsGeneratorResultForClass(simplifiedConstraints, subType, superType);
|
||||
constraints.add(genericsGeneratorResult);
|
||||
|
||||
tphsInRel = new LinkedList<>(tphsInRel.subList(idxOfSuper, size));
|
||||
subType = tphsInRel.getFirst();
|
||||
superType = GenericsGeneratorUtility.getNextClassTph(classAndMethodTphs, tphsInRel);
|
||||
|
||||
idxOfSuper = tphsInRel.indexOf(superType);
|
||||
size = tphsInRel.size();
|
||||
}
|
||||
GenericsGeneratorResult genericsGeneratorResult = getGenericsGeneratorResultForClass(simplifiedConstraints, subType, superType);
|
||||
constraints.add(genericsGeneratorResult);
|
||||
}
|
||||
|
||||
private static GenericsGeneratorResult getGenericsGeneratorResultForClass(ConstraintsSimplierResult simplifiedConstraints, String subType, String superType) {
|
||||
TPHConstraint constraint = new ExtendsConstraint(subType, superType);
|
||||
|
||||
Set<String> equalSet = GenericsGeneratorUtility
|
||||
.createEqualSet(simplifiedConstraints.getNameReplacementResults(), subType);
|
||||
|
||||
return new GenericsGeneratorResult(constraint, equalSet);
|
||||
}
|
||||
/* TODO Remove this methoda*/
|
||||
private static GenericsGeneratorResult generateGGResultForClass(LinkedList<String> tphsInRel,
|
||||
ConstraintsSimplierResult simplifiedConstraints, List<String> tphsClass) {
|
||||
String subType = tphsInRel.getFirst();
|
||||
|
||||
String superType = GenericsGeneratorUtility.getNextClassTph(tphsClass, tphsInRel);
|
||||
|
||||
TPHConstraint constraint = new ExtendsConstraint(subType, superType);
|
||||
|
||||
Set<String> equalSet = GenericsGeneratorUtility
|
||||
.createEqualSet(simplifiedConstraints.getNameReplacementResults(), subType);
|
||||
|
||||
return new GenericsGeneratorResult(constraint, equalSet);
|
||||
}
|
||||
|
||||
private static GenericGeneratorResultsForAllMethods generateConstraintsForAllMethods(
|
||||
final TPHExtractor tphExtractor, ConstraintsSimplierResult simplifiedConstraints, List<String> tphsClass) {
|
||||
|
||||
final List<MethodAndConstraints> methodsAndConstraints = new ArrayList<>();
|
||||
final GenericGeneratorResultsForAllMethods results = new GenericGeneratorResultsForAllMethods(
|
||||
methodsAndConstraints);
|
||||
tphExtractor.ListOfMethodsAndTph.forEach(m -> {
|
||||
MethodAndConstraints methAndCons = generateConstraintsForMethod(tphExtractor.allCons, m,
|
||||
simplifiedConstraints, tphsClass);
|
||||
methodsAndConstraints.add(methAndCons);
|
||||
});
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public static MethodAndConstraints generateConstraintsForMethod(final List<TPHConstraint> allCons,
|
||||
final MethodAndTPH m, final ConstraintsSimplierResult simplifiedConstraints, List<String> tphsClass) {
|
||||
final List<String> localTphs = m.getLocalTphs();
|
||||
|
||||
List<GenericsGeneratorResult> constraints = new ArrayList<>();
|
||||
MethodAndConstraints result = new MethodAndConstraints(m.getId(), constraints);
|
||||
|
||||
if (localTphs.isEmpty())
|
||||
return result;
|
||||
|
||||
if (localTphs.size() == 1 && tphsClass.isEmpty()) {
|
||||
generateGGConstraintsForTPH(localTphs, constraints, simplifiedConstraints);
|
||||
return result;
|
||||
}
|
||||
|
||||
final Set<String> visitedTPHs = new HashSet<>();
|
||||
|
||||
for (String tph : localTphs) {
|
||||
|
||||
if (visitedTPHs.contains(tph))
|
||||
continue;
|
||||
|
||||
final LinkedList<String> tphsInRel = GenericsGeneratorUtility.createLinkedListForTPHsInRelation(allCons,
|
||||
localTphs, tphsClass, visitedTPHs, tph);
|
||||
if (!tphsInRel.isEmpty()) {
|
||||
GenericsGeneratorUtility.removeNotLocalTphs(tphsInRel, localTphs, tphsClass);
|
||||
if (!GenericsGeneratorUtility.isInResult(tphsInRel.getFirst(), constraints)) {
|
||||
GenericsGeneratorResult constraint = generateGGResult(tphsInRel, simplifiedConstraints);
|
||||
constraints.add(constraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
generateGGConstraintsForTPH(localTphs, constraints, simplifiedConstraints);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void generateGGConstraintsForTPH(List<String> localTphs,
|
||||
final List<GenericsGeneratorResult> constraints, final ConstraintsSimplierResult simplifiedConstraints) {
|
||||
|
||||
localTphs.forEach(tph -> {
|
||||
boolean isInSimplifiedConstraints = GenericsGeneratorUtility.isTPHInGenericGeneratorResult(simplifiedConstraints.getGenericsGenResults(), tph);
|
||||
if (isInSimplifiedConstraints) {
|
||||
GenericsGeneratorResult ggResult = GenericsGeneratorUtility.getGenericGeneratorResult(simplifiedConstraints.getGenericsGenResults(), tph).get();
|
||||
// GenericsGeneratorUtility.removeGenericGeneratorResult(simplifiedConstraints.getGenericsGenResults(),ggResult);
|
||||
constraints.add(ggResult);
|
||||
} else {
|
||||
boolean isInConstraints = GenericsGeneratorUtility.isTPHInGenericGeneratorResult(constraints, tph);
|
||||
|
||||
if (!isInConstraints) {
|
||||
GenericsGeneratorResult ggResult = generateGGResult(tph, simplifiedConstraints.getNameReplacementResults());
|
||||
constraints.add(ggResult);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private static GenericsGeneratorResult generateGGResult(String tph,
|
||||
List<NameReplacementResult> nameReplacementResults) {
|
||||
String superType = Type.getInternalName(Object.class);
|
||||
TPHConstraint constraint = new ExtendsConstraint(tph, superType);
|
||||
Set<String> equalSet = GenericsGeneratorUtility.createEqualSet(nameReplacementResults, tph);
|
||||
|
||||
return new GenericsGeneratorResult(constraint, equalSet);
|
||||
}
|
||||
|
||||
private static GenericsGeneratorResult generateGGResult(final LinkedList<String> tphsInRel,
|
||||
final ConstraintsSimplierResult simplifiedConstraints) {
|
||||
|
||||
String subType = tphsInRel.getFirst();
|
||||
|
||||
if (tphsInRel.size() == 1) {
|
||||
Optional<GenericsGeneratorResult> constraintFromSimplifiedCon = simplifiedConstraints
|
||||
.getGenericsGenResults().stream().filter(g -> g.getConstraint().getLeft().equals(subType))
|
||||
.findFirst();
|
||||
if (constraintFromSimplifiedCon.isPresent())
|
||||
return constraintFromSimplifiedCon.get();
|
||||
}
|
||||
|
||||
String superType = tphsInRel.size() > 1 ? tphsInRel.getLast() : Type.getInternalName(Object.class);
|
||||
|
||||
TPHConstraint constraint = new ExtendsConstraint(subType, superType);
|
||||
|
||||
Set<String> equalSet = GenericsGeneratorUtility
|
||||
.createEqualSet(simplifiedConstraints.getNameReplacementResults(), subType);
|
||||
|
||||
return new GenericsGeneratorResult(constraint, equalSet);
|
||||
}
|
||||
|
||||
}
|
@@ -1,571 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.genericsGenerator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.*;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.TPHExtractor;
|
||||
import de.dhbwstuttgart.bytecode.constraint.EqualConstraint;
|
||||
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||
import de.dhbwstuttgart.bytecode.utilities.ConstraintsFinder;
|
||||
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
||||
import de.dhbwstuttgart.bytecode.utilities.NameReplacer;
|
||||
|
||||
/**
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class GenericsGeneratorUtility {
|
||||
/**
|
||||
* Returns a list of type placeholders names of a specified method
|
||||
*
|
||||
* @param methodID The id of the method ReturnTypeMethodName(ParameterTypes)
|
||||
* @param listOfMethodsAndTph List of all methods
|
||||
* @return a list of type placehoders names
|
||||
*/
|
||||
public static List<String> getMethodTPHS(String methodID, ArrayList<MethodAndTPH> listOfMethodsAndTph) {
|
||||
return listOfMethodsAndTph.stream().filter(mt->mt.getId().equals(methodID)).findAny().get().getTphs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reverse constraint of a specified constraint which is given by its left and right
|
||||
* side
|
||||
*
|
||||
* @param allCons List of all constraints
|
||||
* @param left The left side of the given constraint
|
||||
* @param right The right side of the given constraint
|
||||
* @return An Optional object which contains the reverse constraint if it is exist
|
||||
*/
|
||||
public static Optional<TPHConstraint> getReverseConstraint(List<TPHConstraint> allCons, String left, String right) {
|
||||
return allCons.stream().filter(c->{
|
||||
return c.getRight().equals(left) && c.getLeft().equals(right);
|
||||
}).findAny();
|
||||
}
|
||||
|
||||
/**
|
||||
* Substitutes the old name by the new name in all constraints
|
||||
*
|
||||
* @param allCons List of all constraints
|
||||
* @param oldName The name to be replaced
|
||||
* @param newName The new name
|
||||
*/
|
||||
public static void substituteTPH(List<TPHConstraint> allCons, String oldName, String newName) {
|
||||
allCons.stream()
|
||||
.filter(c->c.getRel()==Relation.EXTENDS)
|
||||
.forEach(c->{
|
||||
if(c.getLeft().equals(oldName))
|
||||
c.setLeft(newName);
|
||||
if(c.getRight().equals(oldName))
|
||||
c.setRight(newName);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public static List<ConstraintsWithSameLeftSide> findConstraintsWithLeftSameLeftSide(List<TPHConstraint> allCons) {
|
||||
// finder looks for constraints that have the same left hand side
|
||||
// and put them in a list
|
||||
ConstraintsFinder finder = new ConstraintsFinder(allCons);
|
||||
List<ConstraintsWithSameLeftSide> foundCons = finder.findConstraints();
|
||||
return foundCons;
|
||||
}
|
||||
|
||||
public static void simplifyConstraintsWithSameLeftSide(List<ConstraintsWithSameLeftSide> consWithSameLeftSide,
|
||||
List<TPHConstraint> allCons, List<String> methodTPHS) {
|
||||
List<TPHConstraint> eqCons = new ArrayList<>();
|
||||
|
||||
for (ConstraintsWithSameLeftSide list : consWithSameLeftSide) {
|
||||
NameReplacementResult replRes = modifyNames(allCons, methodTPHS, list);
|
||||
createEqualConstraintsForNames(replRes.getName(), replRes.getOldNames(),eqCons);
|
||||
|
||||
for (TPHConstraint c : allCons) {
|
||||
if (c.getRel() == Relation.EQUAL && replRes.getName().equals(c.getRight())) {
|
||||
eqCons.add(c);
|
||||
}
|
||||
}
|
||||
updateEqualCons(replRes, eqCons);
|
||||
|
||||
TPHConstraint c = list.getConstraints().get(0);
|
||||
allCons.removeAll(list.getConstraints());
|
||||
allCons.add(c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void simplifyConstraintsWithSameLeftSide(List<ConstraintsWithSameLeftSide> consWithSameLeftSide,
|
||||
TPHExtractor tphExtractor, List<String> tphsClass, List<TPHConstraint> equalCons) {
|
||||
List<TPHConstraint> allCons = tphExtractor.allCons;
|
||||
|
||||
for (ConstraintsWithSameLeftSide list : consWithSameLeftSide) {
|
||||
if(!stillWithSameLeftSide(list))
|
||||
continue;
|
||||
NameReplacementResult replRes = modifyNames(allCons, list, tphExtractor.ListOfMethodsAndTph,tphsClass);
|
||||
createEqualConstraintsForNames(replRes.getName(), replRes.getOldNames(),equalCons);
|
||||
|
||||
for (TPHConstraint c : allCons) {
|
||||
if (c.getRel() == Relation.EQUAL && replRes.getName().equals(c.getRight())) {
|
||||
equalCons.add(c);
|
||||
}
|
||||
}
|
||||
updateEqualCons(replRes, equalCons);
|
||||
|
||||
TPHConstraint c = list.getConstraints().get(0);
|
||||
allCons.removeAll(list.getConstraints());
|
||||
removeConstraintsWithSameLeftAndRightSide(allCons);
|
||||
allCons.add(c);
|
||||
removeDuplicate(allCons);
|
||||
}
|
||||
consWithSameLeftSide.clear();
|
||||
consWithSameLeftSide = findConstraintsWithLeftSameLeftSide(allCons);
|
||||
if(!consWithSameLeftSide.isEmpty())
|
||||
simplifyConstraintsWithSameLeftSide(consWithSameLeftSide,tphExtractor,tphsClass,equalCons);
|
||||
|
||||
}
|
||||
|
||||
private static void removeDuplicate(List<TPHConstraint> allCons) {
|
||||
List<TPHConstraint> visited = new ArrayList<>();
|
||||
List<Integer> toRemove = new ArrayList<>();
|
||||
checkForDuplicate(allCons, visited, toRemove);
|
||||
removeConstraintsByIndex(allCons, toRemove);
|
||||
}
|
||||
|
||||
private static void removeConstraintsByIndex(List<TPHConstraint> allCons, List<Integer> toRemove) {
|
||||
for(int index : toRemove)
|
||||
allCons.remove(index);
|
||||
}
|
||||
|
||||
private static void checkForDuplicate(List<TPHConstraint> allCons, List<TPHConstraint> visited, List<Integer> toRemove) {
|
||||
for(int i = 0;i<allCons.size();++i){
|
||||
markConstraintIfDuplicate(allCons, visited, toRemove, i);
|
||||
}
|
||||
}
|
||||
|
||||
private static void markConstraintIfDuplicate(List<TPHConstraint> allCons, List<TPHConstraint> visited, List<Integer> toRemove, int i) {
|
||||
TPHConstraint constraint = allCons.get(i);
|
||||
if(containsInList(visited,constraint.getLeft(),constraint.getRight())){
|
||||
toRemove.add(i);
|
||||
} else {
|
||||
visited.add(constraint);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean containsInList(List<TPHConstraint> allConstraints, String left, String right) {
|
||||
for(TPHConstraint constraint : allConstraints)
|
||||
if(constraint.getLeft().equals(left) && constraint.getRight().equals(right))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void addNewConstraintsWithSameLeftSide(ConstraintsWithSameLeftSide constraintsWithSameLeftSide, List<TPHConstraint> allCons) {
|
||||
allCons.forEach(c->{
|
||||
if (constraintsWithSameLeftSide.getConstraints().get(0).getLeft().equals(c.getLeft())){
|
||||
if(!constraintsWithSameLeftSide.getConstraints().contains(c))
|
||||
constraintsWithSameLeftSide.getConstraints().add(c);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void checkForNewConstraintsWithSameLeftSide(List<ConstraintsWithSameLeftSide> consWithSameLeftSide, List<TPHConstraint> allCons) {
|
||||
allCons.forEach(c->{
|
||||
Optional<ConstraintsWithSameLeftSide> constraintsWithSameLeftSide = getConstraintsWithSameLeftSide(consWithSameLeftSide, c.getLeft());
|
||||
constraintsWithSameLeftSide.ifPresent(cls->{
|
||||
if(!cls.getConstraints().contains(c))
|
||||
cls.getConstraints().add(c);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private static Optional<ConstraintsWithSameLeftSide> getConstraintsWithSameLeftSide(List<ConstraintsWithSameLeftSide> consWithSameLeftSide, String left) {
|
||||
return consWithSameLeftSide.stream().filter(csl->isContainedInConsWithLeftSide(csl,left)).findAny();
|
||||
}
|
||||
|
||||
private static boolean isContainedInConsWithLeftSide(ConstraintsWithSameLeftSide csl, String left) {
|
||||
return csl.getConstraints().get(0).getLeft().equals(left);
|
||||
}
|
||||
|
||||
private static boolean stillWithSameLeftSide(ConstraintsWithSameLeftSide constraints) {
|
||||
removeUnvalidConstraints(constraints);
|
||||
return constraints.getConstraints().size()>1;
|
||||
}
|
||||
|
||||
private static void removeUnvalidConstraints(ConstraintsWithSameLeftSide constraints) {
|
||||
List<TPHConstraint> toRemove = new ArrayList<>();
|
||||
constraints.getConstraints().forEach(c->{
|
||||
if(c.getLeft().equals(c.getRight()))
|
||||
toRemove.add(c);
|
||||
});
|
||||
if(!toRemove.isEmpty())
|
||||
constraints.getConstraints().removeAll(toRemove);
|
||||
}
|
||||
|
||||
private static void removeConstraintsWithSameLeftAndRightSide(List<TPHConstraint> allCons) {
|
||||
List<TPHConstraint> toRemove = new ArrayList<>();
|
||||
allCons.forEach(c->{
|
||||
if(c.getLeft().equals(c.getRight()))
|
||||
toRemove.add(c);
|
||||
});
|
||||
allCons.removeAll(toRemove);
|
||||
}
|
||||
|
||||
private static void createEqualConstraintsForNames(String name, List<String> equalNames, List<TPHConstraint> eqCons) {
|
||||
// create an equal constraint for each value in repres
|
||||
for (String eName : equalNames) {
|
||||
EqualConstraint ec = new EqualConstraint(eName, name);
|
||||
eqCons.add(ec);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param allCons
|
||||
* @param methodTPHS
|
||||
* @param list
|
||||
* @return
|
||||
*/
|
||||
public static NameReplacementResult modifyNames(List<TPHConstraint> allCons, List<String> methodTPHS,
|
||||
ConstraintsWithSameLeftSide list) {
|
||||
// generate a new name and replace the right hand side for each constraint
|
||||
// in list with the new name
|
||||
NameReplacer replacer = new NameReplacer(list.getConstraints(), allCons, methodTPHS);
|
||||
// new name -> [all old names]
|
||||
NameReplacementResult replRes = replacer.replaceNames();
|
||||
return replRes;
|
||||
}
|
||||
|
||||
public static NameReplacementResult modifyNames(List<TPHConstraint> allCons, ConstraintsWithSameLeftSide list, List<MethodAndTPH> methodAndTPHs, List<String> tphsClass) {
|
||||
// generate a new name and replace the right hand side for each constraint
|
||||
// in list with the new name
|
||||
NameReplacer replacer = new NameReplacer(list.getConstraints(), allCons, methodAndTPHs, tphsClass);
|
||||
// new name -> [all old names]
|
||||
NameReplacementResult replRes = replacer.replaceNames();
|
||||
return replRes;
|
||||
}
|
||||
|
||||
public static void updateEqualCons(NameReplacementResult nameReplacementResult, List<TPHConstraint> eqCons) {
|
||||
List<String> oldNames = nameReplacementResult.getOldNames();
|
||||
String newName = nameReplacementResult.getName();
|
||||
for (TPHConstraint c : eqCons) {
|
||||
// if(oldNames.contains(c.getLeft()))
|
||||
// c.setLeft(newName);
|
||||
if (oldNames.contains(c.getRight()))
|
||||
c.setRight(newName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void modifyRelationForConstraintsInCycle(List<Cycle> cycles) {
|
||||
cycles.stream().map(lc->lc.getConstraints()).flatMap(e->e.stream()).forEach(c->c.setRel(Relation.EQUAL));
|
||||
}
|
||||
|
||||
public static List<NameReplacementResult> substituteTPHSFormCycle(List<TPHConstraint> allCons, List<Cycle> cycles, TPHExtractor tphExtractor) {
|
||||
List<NameReplacementResult> results = new ArrayList<>();
|
||||
cycles.forEach(lc->{
|
||||
Set<String> names = getNamesFromCycle(lc);
|
||||
String newName = names.stream().findFirst().get();
|
||||
|
||||
List<String> equalNames = new ArrayList<>(names);
|
||||
|
||||
Stream<ArrayList<String>> tphsOfMethods = tphExtractor.ListOfMethodsAndTph.stream().map(m->m.getTphs());
|
||||
Stream<ArrayList<String>> localTphsOfMethods = tphExtractor.ListOfMethodsAndTph.stream().map(m->m.getLocalTphs());
|
||||
|
||||
replaceOldNames(newName, equalNames, tphsOfMethods);
|
||||
replaceOldNames(newName, equalNames, localTphsOfMethods);
|
||||
|
||||
NameReplacementResult res = new NameReplacementResult(newName, equalNames);
|
||||
results.add(res);
|
||||
substituteAll(allCons,names,newName);
|
||||
});
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param newName
|
||||
* @param names
|
||||
* @param tphsOfMethods
|
||||
*/
|
||||
public static void replaceOldNames(final String newName, final List<String> names, Stream<ArrayList<String>> tphsOfMethods) {
|
||||
tphsOfMethods.forEach(tphsMethod->{
|
||||
if(tphsMethod.removeAll(names))
|
||||
tphsMethod.add(newName);
|
||||
});
|
||||
}
|
||||
|
||||
public static void substituteAll(List<TPHConstraint> allCons, Set<String> names, String newName) {
|
||||
allCons.stream()
|
||||
.filter(c-> c.getRel()==Relation.EXTENDS)
|
||||
.forEach(c->{
|
||||
if(names.contains(c.getLeft())) {
|
||||
c.setLeft(newName);
|
||||
} else if(names.contains(c.getRight())) {
|
||||
c.setRight(newName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Set<String> getNamesFromCycle(Cycle lc) {
|
||||
Set<String> names = new HashSet<>();
|
||||
lc.getConstraints().forEach(c->names.add(c.getLeft()));
|
||||
return names;
|
||||
}
|
||||
|
||||
public static void createResults(List<GenericsGeneratorResult> genericsGeneratorResults,
|
||||
List<NameReplacementResult> nameReplacementResults) {
|
||||
nameReplacementResults.forEach(n->{
|
||||
Set<String> equals = new HashSet<>(n.getOldNames());
|
||||
TPHConstraint cons = new ExtendsConstraint(n.getName(), Type.getInternalName(Object.class));
|
||||
GenericsGeneratorResult ggRes = new GenericsGeneratorResult(cons, equals);
|
||||
genericsGeneratorResults.add(ggRes);
|
||||
});
|
||||
}
|
||||
|
||||
public static void removeEqualConstraints(List<TPHConstraint> allCons) {
|
||||
List<TPHConstraint> equalConstraints = getEqualConstraints(allCons);
|
||||
allCons.removeAll(equalConstraints);
|
||||
}
|
||||
|
||||
public static List<TPHConstraint> getEqualConstraints(List<TPHConstraint> allCons) {
|
||||
return allCons.stream().filter(c->c.getRel()==Relation.EQUAL).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<NameReplacementResult> createNameReplacementResultsFromEqualConstraints(
|
||||
List<TPHConstraint> equalCons) {
|
||||
List<NameReplacementResult> nameReplacementResults = new ArrayList<>();
|
||||
equalCons.forEach(c->{
|
||||
if(isInNameReplacementResults(nameReplacementResults,c.getRight())) {
|
||||
getNameReplacementByName(nameReplacementResults,c.getRight()).getOldNames().add(c.getLeft());
|
||||
} else {
|
||||
List<String> oldNames = new ArrayList<>();
|
||||
oldNames.add(c.getLeft());
|
||||
NameReplacementResult nrRes = new NameReplacementResult(c.getRight(), oldNames);
|
||||
nameReplacementResults.add(nrRes);
|
||||
}
|
||||
});
|
||||
return nameReplacementResults;
|
||||
}
|
||||
|
||||
private static NameReplacementResult getNameReplacementByName(List<NameReplacementResult> nameReplacementResults,
|
||||
String name) {
|
||||
return nameReplacementResults.stream().filter(n->n.getName().equals(name)).findFirst().get();
|
||||
}
|
||||
|
||||
public static boolean isInNameReplacementResults(List<NameReplacementResult> nameReplacementResults,String name){
|
||||
if(nameReplacementResults.isEmpty())
|
||||
return false;
|
||||
return nameReplacementResults.stream().map(r->r.getName()).filter(n->name.equals(n)).findFirst().isPresent();
|
||||
}
|
||||
|
||||
public static Optional<TPHConstraint> getConstraintByLeftSide(List<TPHConstraint> allCons, String tph) {
|
||||
return allCons.stream().filter(c->c.getLeft().equals(tph)).findFirst();
|
||||
}
|
||||
|
||||
public static Optional<TPHConstraint> getConstraintByRightSide(List<TPHConstraint> allCons, String tph) {
|
||||
return allCons.stream().filter(c->c.getRight().equals(tph)).findFirst();
|
||||
}
|
||||
|
||||
public static boolean isTPHInGenericGeneratorResult(final List<GenericsGeneratorResult> constraints, final String tph) {
|
||||
return constraints.stream().filter(g->g.getConstraint().getLeft().equals(tph)).findFirst().isPresent();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param allCons
|
||||
* @param tphsMethod
|
||||
* @param tphsClass
|
||||
* @param visitedTPHs
|
||||
* @param tph
|
||||
* @return
|
||||
*/
|
||||
public static LinkedList<String> createLinkedListForTPHsInRelation(final List<TPHConstraint> allCons,
|
||||
List<String> tphsMethod, List<String> tphsClass, final Set<String> visitedTPHs, String tph) {
|
||||
|
||||
final LinkedList<String> tphsInRel = new LinkedList<>();
|
||||
List<String> tphsList = new ArrayList<>(tphsMethod);
|
||||
tphsList.addAll(tphsClass);
|
||||
|
||||
boolean isNextSuperTypeFound = findNextSuperTyp(allCons,tphsList ,visitedTPHs, tph, tphsInRel);
|
||||
if(!isNextSuperTypeFound)
|
||||
findNextSubType(allCons, tphsList,visitedTPHs, tph, tphsInRel);
|
||||
return tphsInRel;
|
||||
}
|
||||
|
||||
public static boolean findNextSubType(List<TPHConstraint> allCons, List<String> tphsList, Set<String> visitedTPHs, String tph,
|
||||
LinkedList<String> tphsInRel) {
|
||||
Optional<TPHConstraint> con = getConstraintByRightSide(allCons, tph);
|
||||
while (con.isPresent()) {
|
||||
String left = con.get().getLeft();
|
||||
String right = con.get().getRight();
|
||||
|
||||
addTPHsToListFromLeft(tphsInRel, left, right);
|
||||
markAsVisited(visitedTPHs, left);
|
||||
|
||||
if(tphsList.contains(left))
|
||||
return true;
|
||||
|
||||
con = getConstraintByRightSide(allCons, left);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void addTPHsToListFromLeft(LinkedList<String> tphsInRel, String left, String right) {
|
||||
if (tphsInRel.isEmpty())
|
||||
tphsInRel.add(right);
|
||||
|
||||
tphsInRel.addFirst(left);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param allCons
|
||||
* @param tphsList
|
||||
* @param visitedTPHs
|
||||
* @param tph
|
||||
* @param tphsInRel
|
||||
* @return
|
||||
*/
|
||||
public static boolean findNextSuperTyp(final List<TPHConstraint> allCons, List<String> tphsList, final Set<String> visitedTPHs, String tph,
|
||||
final LinkedList<String> tphsInRel) {
|
||||
Optional<TPHConstraint> con = getConstraintByLeftSide(allCons, tph);
|
||||
|
||||
markAsVisited(visitedTPHs, tph);
|
||||
|
||||
while (con.isPresent()) {
|
||||
String left = con.get().getLeft();
|
||||
String right = con.get().getRight();
|
||||
addTPHsToList(tphsInRel, left, right);
|
||||
|
||||
if(tphsList.contains(right))
|
||||
return true;
|
||||
|
||||
markAsVisited(visitedTPHs, right);
|
||||
|
||||
con = getConstraintByLeftSide(allCons, right);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void markAsVisited(Set<String> visitedTPHs, String left) {
|
||||
visitedTPHs.add(left);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param visitedTPHs
|
||||
* @param right
|
||||
* @param left
|
||||
*/
|
||||
public static void markAsVisited(final Set<String> visitedTPHs, String left, String right) {
|
||||
visitedTPHs.add(left);
|
||||
visitedTPHs.add(right);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tphsInRel
|
||||
* @param right
|
||||
* @param left
|
||||
*/
|
||||
public static void addTPHsToList(final LinkedList<String> tphsInRel, String left, String right) {
|
||||
if (tphsInRel.isEmpty())
|
||||
tphsInRel.add(left);
|
||||
tphsInRel.add(right);
|
||||
}
|
||||
|
||||
public static void removeNotLocalTphs(final LinkedList<String> tphsInRel, final List<String> localTphs,
|
||||
List<String> tphsClass) {
|
||||
|
||||
while (!localTphs.contains(tphsInRel.peek())) {
|
||||
tphsInRel.removeFirst();
|
||||
}
|
||||
|
||||
String last = tphsInRel.peekLast();
|
||||
while (!localTphs.contains(last) && !tphsClass.contains(last)) {
|
||||
tphsInRel.removeLast();
|
||||
last = tphsInRel.peekLast();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nameReplacementResults
|
||||
* @param subType
|
||||
* @return
|
||||
*/
|
||||
public static Set<String> createEqualSet(final List<NameReplacementResult> nameReplacementResults, String subType) {
|
||||
Optional<NameReplacementResult> equals = nameReplacementResults.stream()
|
||||
.filter(n -> n.getName().equals(subType)).findFirst();
|
||||
|
||||
Set<String> equalSet = equals.isPresent() ? new HashSet<>(equals.get().getOldNames()) : new HashSet<>();
|
||||
return equalSet;
|
||||
}
|
||||
|
||||
public static String getNextClassTph(List<String> tphsClass, LinkedList<String> tphsInRel) {
|
||||
|
||||
for(int i = 1;i<tphsInRel.size();++i) {
|
||||
String next = tphsInRel.get(i);
|
||||
if(tphsClass.contains(next))
|
||||
return next;
|
||||
}
|
||||
|
||||
return tphsInRel.getLast();
|
||||
}
|
||||
|
||||
public static void addTPHsToClassTPHs(final List<GenericsGeneratorResult> constraints, final List<String> tphsClass) {
|
||||
|
||||
List<String> lefts = constraints.stream().map(r->r.getConstraint()).map(c->c.getLeft()).collect(Collectors.toList());
|
||||
List<String> rights = constraints.stream().map(r->r.getConstraint()).map(c->c.getRight()).collect(Collectors.toList());
|
||||
List<String> leftsAndRights = new ArrayList<>(lefts);
|
||||
leftsAndRights.addAll(rights);
|
||||
List<String> shouldBeClassTphs = leftsAndRights.stream().distinct().collect(Collectors.toList());
|
||||
|
||||
for(String tph : shouldBeClassTphs) {
|
||||
if(!tphsClass.contains(tph))
|
||||
tphsClass.add(tph);
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeClassTPHsFromMethodTPHs(List<String> tphsClass, TPHExtractor tphExtractor) {
|
||||
|
||||
tphExtractor.ListOfMethodsAndTph.stream().map(m->m.getTphs()).forEach(tphs->{
|
||||
tphs.removeAll(tphsClass);
|
||||
});
|
||||
|
||||
tphExtractor.ListOfMethodsAndTph.stream().map(m->m.getLocalTphs()).forEach(tphs->{
|
||||
tphs.removeAll(tphsClass);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public static LinkedList<String> createLinkedListForTPHsInRelationClass(List<TPHConstraint> allCons,
|
||||
List<String> tphsClass, List<String> methodTPHs, Set<String> visitedTPHs, String tph) {
|
||||
final LinkedList<String> tphsInRel = new LinkedList<>();
|
||||
|
||||
boolean isNextSuperTypeFound = findNextSuperTyp(allCons,tphsClass ,visitedTPHs, tph, tphsInRel);
|
||||
if(!tphsInRel.isEmpty() && !isNextSuperTypeFound && !methodTPHs.contains(tphsInRel.getLast()))
|
||||
findNextSubType(allCons, tphsClass,visitedTPHs, tph, tphsInRel);
|
||||
return tphsInRel;
|
||||
}
|
||||
|
||||
public static boolean isInResult(String first, List<GenericsGeneratorResult> constraints) {
|
||||
return constraints.stream().map(r->r.getConstraint()).filter(c->c.getLeft().equals(first)).findFirst().isPresent();
|
||||
}
|
||||
|
||||
public static Optional<GenericsGeneratorResult> getGenericGeneratorResult(List<GenericsGeneratorResult> list,
|
||||
String tph) {
|
||||
return list.stream().filter(g->g.getConstraint().getLeft().equals(tph)).findFirst();
|
||||
}
|
||||
|
||||
public static void removeGenericGeneratorResult(List<GenericsGeneratorResult> genericsGenResults,
|
||||
GenericsGeneratorResult ggResult) {
|
||||
genericsGenResults.remove(ggResult);
|
||||
}
|
||||
|
||||
public static Optional<MethodAndTPH> getMethodAndTphs(ArrayList<MethodAndTPH> listOfMethodsAndTph, String id) {
|
||||
return listOfMethodsAndTph.stream().filter(m->m.getId().equals(id)).findFirst();
|
||||
}
|
||||
}
|
@@ -1,35 +0,0 @@
|
||||
package de.dhbwstuttgart.bytecode.genericsGeneratorTypes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||
|
||||
public class ConstraintsWithSameLeftSide {
|
||||
private List<TPHConstraint> constraints;
|
||||
|
||||
/**
|
||||
* @param constraints
|
||||
*/
|
||||
public ConstraintsWithSameLeftSide(List<TPHConstraint> constraints) {
|
||||
this.constraints = constraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the constraints
|
||||
*/
|
||||
public List<TPHConstraint> getConstraints() {
|
||||
return constraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param constraints the constraints to set
|
||||
*/
|
||||
public void setConstraints(List<TPHConstraint> constraints) {
|
||||
this.constraints = constraints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[" + constraints.toString() + "]";
|
||||
}
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.genericsGeneratorTypes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||
|
||||
/**
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class Cycle {
|
||||
private final List<TPHConstraint> constraints;
|
||||
|
||||
/**
|
||||
* @param constraints
|
||||
*/
|
||||
public Cycle(List<TPHConstraint> constraints) {
|
||||
this.constraints = constraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the constraints
|
||||
*/
|
||||
public List<TPHConstraint> getConstraints() {
|
||||
return constraints;
|
||||
}
|
||||
|
||||
public boolean containConstraint(TPHConstraint constraint) {
|
||||
for(TPHConstraint c : constraints) {
|
||||
if(c.equalConstraint(constraint))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
constraints.forEach(c->sb.append(c.getLeft()+" -> "));
|
||||
sb.append(constraints.get(constraints.size()-1).getRight());
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.genericsGeneratorTypes;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class GenericGeneratorResultsForAllMethods {
|
||||
private final List<MethodAndConstraints> methodsAndConstraints;
|
||||
|
||||
public GenericGeneratorResultsForAllMethods() {
|
||||
this(Collections.emptyList());
|
||||
}
|
||||
/**
|
||||
* @param methodsAndConstraints
|
||||
*/
|
||||
public GenericGeneratorResultsForAllMethods(List<MethodAndConstraints> methodsAndConstraints) {
|
||||
this.methodsAndConstraints = methodsAndConstraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the methodsAndConstraints
|
||||
*/
|
||||
public List<MethodAndConstraints> getMethodsAndConstraints() {
|
||||
return methodsAndConstraints;
|
||||
}
|
||||
|
||||
}
|
@@ -1,53 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.genericsGeneratorTypes;
|
||||
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* The simplify results of a source file (package)
|
||||
*
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class GenericGenratorResultForSourceFile {
|
||||
private String pkgName;
|
||||
private final List<GenericsGeneratorResultForClass> genericGeneratorResultForAllClasses = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* @param pkgName
|
||||
*/
|
||||
public GenericGenratorResultForSourceFile(String pkgName) {
|
||||
this.pkgName = pkgName;
|
||||
}
|
||||
|
||||
public List<GenericsGeneratorResultForClass> getGenericGeneratorResultForAllClasses() {
|
||||
return genericGeneratorResultForAllClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the simplify results of a class to simplifyResForSF
|
||||
*
|
||||
* @param sResClass simplify results of a class to added
|
||||
*/
|
||||
public void addGenericGeneratorResultClass(GenericsGeneratorResultForClass sResClass) {
|
||||
genericGeneratorResultForAllClasses.add(sResClass);
|
||||
}
|
||||
|
||||
public GenericsGeneratorResultForClass getSimplifyResultsByName(JavaClassName name) {
|
||||
|
||||
if (this.pkgName.equals(name.getPackageName())) {
|
||||
return genericGeneratorResultForAllClasses.stream()
|
||||
.filter(sr -> sr.getClassName().equals(name))
|
||||
.findAny()
|
||||
.orElseThrow(() -> new NoSuchElementException(
|
||||
"Simplify results for the class " + pkgName + "." + name + " are not found"));
|
||||
}
|
||||
throw new NoSuchElementException("Simplify results for the class " + pkgName + "." + name + " are not found");
|
||||
}
|
||||
}
|
@@ -1,55 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.genericsGeneratorTypes;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||
|
||||
/**
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class GenericsGeneratorResult {
|
||||
private TPHConstraint constraint;
|
||||
/**
|
||||
* contains the names of all type placeholders which are equals to the left side of
|
||||
* the constraint {@link #constraint}.
|
||||
*/
|
||||
private Set<String> equalsTPHs;
|
||||
/**
|
||||
* @param constraint
|
||||
* @param equalsTPHs
|
||||
*/
|
||||
public GenericsGeneratorResult(TPHConstraint constraint, Set<String> equalsTPHs) {
|
||||
this.constraint = constraint;
|
||||
this.equalsTPHs = equalsTPHs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the constraint
|
||||
*/
|
||||
public TPHConstraint getConstraint() {
|
||||
return constraint;
|
||||
}
|
||||
/**
|
||||
* @param constraint the constraint to set
|
||||
*/
|
||||
public void setConstraint(TPHConstraint constraint) {
|
||||
this.constraint = constraint;
|
||||
}
|
||||
/**
|
||||
* @return the equalsTPHs
|
||||
*/
|
||||
public Set<String> getEqualsTPHs() {
|
||||
return equalsTPHs;
|
||||
}
|
||||
/**
|
||||
* @param equalsTPHs the equalsTPHs to set
|
||||
*/
|
||||
public void setEqualsTPHs(Set<String> equalsTPHs) {
|
||||
this.equalsTPHs = equalsTPHs;
|
||||
}
|
||||
|
||||
}
|
@@ -1,69 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.genericsGeneratorTypes;
|
||||
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class GenericsGeneratorResultForClass {
|
||||
private final JavaClassName className;
|
||||
private final List<GenericsGeneratorResult> classConstraints;
|
||||
private final GenericGeneratorResultsForAllMethods methodsAndTheirConstraints;
|
||||
|
||||
public GenericsGeneratorResultForClass(JavaClassName className) {
|
||||
this(className, Collections.emptyList(), new GenericGeneratorResultsForAllMethods());
|
||||
}
|
||||
/**
|
||||
* @param className
|
||||
* @param classConstraints
|
||||
* @param methodsAndTheirConstraints
|
||||
*/
|
||||
public GenericsGeneratorResultForClass(JavaClassName className, List<GenericsGeneratorResult> classConstraints,
|
||||
GenericGeneratorResultsForAllMethods methodsAndTheirConstraints) {
|
||||
this.className = className;
|
||||
this.classConstraints = classConstraints;
|
||||
this.methodsAndTheirConstraints = methodsAndTheirConstraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the className
|
||||
*/
|
||||
public JavaClassName getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the classConstraints
|
||||
*/
|
||||
public List<GenericsGeneratorResult> getClassConstraints() {
|
||||
return classConstraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the methodsAndTheirConstraints
|
||||
*/
|
||||
public GenericGeneratorResultsForAllMethods getMethodsAndTheirConstraints() {
|
||||
return methodsAndTheirConstraints;
|
||||
}
|
||||
|
||||
public boolean contains(String id) {
|
||||
return methodsAndTheirConstraints.getMethodsAndConstraints().stream().map(mc -> mc.getMethodID())
|
||||
.anyMatch(i -> i.equals(id));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public List<GenericsGeneratorResult> getMethodConstraintsByID(String id) {
|
||||
return methodsAndTheirConstraints.getMethodsAndConstraints().stream().filter(mc -> mc.getMethodID().equals(id))
|
||||
.findFirst().get().getConstraints();
|
||||
}
|
||||
|
||||
}
|
@@ -1,36 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.genericsGeneratorTypes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class MethodAndConstraints {
|
||||
private final String methodID;
|
||||
private final List<GenericsGeneratorResult> constraints;
|
||||
/**
|
||||
* @param methodID
|
||||
* @param constraints
|
||||
*/
|
||||
public MethodAndConstraints(String methodID, List<GenericsGeneratorResult> constraints) {
|
||||
this.methodID = methodID;
|
||||
this.constraints = constraints;
|
||||
}
|
||||
/**
|
||||
* @return the methodID
|
||||
*/
|
||||
public String getMethodID() {
|
||||
return methodID;
|
||||
}
|
||||
/**
|
||||
* @return the constraints
|
||||
*/
|
||||
public List<GenericsGeneratorResult> getConstraints() {
|
||||
return constraints;
|
||||
}
|
||||
|
||||
}
|
@@ -1,49 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.genericsGeneratorTypes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class NameReplacementResult {
|
||||
private String name;
|
||||
private List<String> oldNames;
|
||||
/**
|
||||
* @param name
|
||||
* @param oldNames
|
||||
*/
|
||||
public NameReplacementResult(String name, List<String> oldNames) {
|
||||
this.name = name;
|
||||
this.oldNames = oldNames;
|
||||
}
|
||||
/**
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
/**
|
||||
* @param name the name to set
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
/**
|
||||
* @return the oldNames
|
||||
*/
|
||||
public List<String> getOldNames() {
|
||||
return oldNames;
|
||||
}
|
||||
/**
|
||||
* @param oldNames the oldNames to set
|
||||
*/
|
||||
public void setOldNames(List<String> oldNames) {
|
||||
this.oldNames = oldNames;
|
||||
};
|
||||
|
||||
|
||||
}
|
@@ -1,379 +1,469 @@
|
||||
package de.dhbwstuttgart.bytecode.signature;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.signature.SignatureVisitor;
|
||||
import org.objectweb.asm.signature.SignatureWriter;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResult;
|
||||
import de.dhbwstuttgart.bytecode.utilities.Simplify;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.Constructor;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
||||
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.syntaxtree.type.WildcardType;
|
||||
import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
|
||||
import de.dhbwstuttgart.typeinference.result.ResolvedType;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
|
||||
public class Signature {
|
||||
private static final char SUPER_CHAR = '-';
|
||||
private static final char EXTENDS_CHAR = '+';
|
||||
private static final String SPECIAL_CHAR_FOR_FUN = "$$";
|
||||
private static final String SPECIAL_CHAR = "$";
|
||||
private ClassOrInterface classOrInterface;
|
||||
private HashMap<String, String> genericsAndBounds;
|
||||
private HashMap<String, String> genericsAndBoundsMethod;
|
||||
private final SignatureWriter sw = new SignatureWriter();;
|
||||
private SignatureWriter sw;
|
||||
private Constructor constructor;
|
||||
private Method method;
|
||||
private HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes;
|
||||
private HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes;
|
||||
private ResultSet resultSet;
|
||||
private Map<TPHConstraint, Set<String>> methodConstraints;
|
||||
private List<GenericsGeneratorResult> consClass;
|
||||
private List<GenericsGeneratorResult> constraints;
|
||||
private ArrayList<GenericInsertPair> commonPairs;
|
||||
private HashMap<TPHConstraint,HashSet<String>> methodConstraints;
|
||||
private ArrayList<TypePlaceholder> tphsClass;
|
||||
private ArrayList<TPHConstraint> consClass;
|
||||
|
||||
// public Signature(ClassOrInterface classOrInterface, HashMap<String, String> genericsAndBounds,
|
||||
// List<TPHConstraint> consClass) {
|
||||
// this.classOrInterface = classOrInterface;
|
||||
// this.genericsAndBounds = genericsAndBounds;
|
||||
// this.consClass = consClass;
|
||||
// sw = new SignatureWriter();
|
||||
// createSignatureForClassOrInterface();
|
||||
// }
|
||||
public Signature(ClassOrInterface classOrInterface, HashMap<String, String> genericsAndBounds,
|
||||
ArrayList<GenericInsertPair> commonPairs, ArrayList<TypePlaceholder> tphsClass, ArrayList<TPHConstraint> consClass) {
|
||||
this.classOrInterface = classOrInterface;
|
||||
this.genericsAndBounds = genericsAndBounds;
|
||||
this.commonPairs = commonPairs;
|
||||
this.tphsClass = tphsClass;
|
||||
this.consClass = consClass;
|
||||
sw = new SignatureWriter();
|
||||
createSignatureForClassOrInterface();
|
||||
}
|
||||
|
||||
public Signature(HashMap<String, String> genericsAndBounds,
|
||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes, ResultSet resultSet,
|
||||
List<GenericsGeneratorResult> constraints) {
|
||||
//this.constructor = constructor;
|
||||
public Signature(Constructor constructor, HashMap<String, String> genericsAndBounds,
|
||||
HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes,ResultSet resultSet,
|
||||
HashMap<TPHConstraint,HashSet<String>> methodConstraints) {
|
||||
this.constructor = constructor;
|
||||
this.genericsAndBounds = genericsAndBounds;
|
||||
this.methodParamsAndTypes = methodParamsAndTypes;
|
||||
this.resultSet = resultSet;
|
||||
this.constraints = constraints;
|
||||
this.methodConstraints = methodConstraints;
|
||||
sw = new SignatureWriter();
|
||||
createSignatureForConsOrMethod(this.constructor,true);
|
||||
}
|
||||
|
||||
public Signature(int numberOfParams) {
|
||||
createSignatureForFunN(numberOfParams);
|
||||
}
|
||||
|
||||
public Signature(int numberOfParams, String to, String[] paramTypes) {
|
||||
createSignatureForFunN(numberOfParams, to, paramTypes);
|
||||
}
|
||||
|
||||
public Signature(ClassOrInterface classOrInterface, HashMap<String, String> genericsAndBounds,
|
||||
List<GenericsGeneratorResult> consClass) {
|
||||
this.classOrInterface = classOrInterface;
|
||||
this.genericsAndBounds = genericsAndBounds;
|
||||
this.consClass = consClass;
|
||||
}
|
||||
|
||||
public Signature(HashMap<String, String> genericsAndBoundsMethod,
|
||||
HashMap<String, String> genericsAndBounds,
|
||||
public Signature(Method method, HashMap<String, String> genericsAndBoundsMethod,HashMap<String, String> genericsAndBounds,
|
||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes, ResultSet resultSet,
|
||||
List<GenericsGeneratorResult> constraints,List<GenericsGeneratorResult> consClass) {
|
||||
HashMap<TPHConstraint,HashSet<String>> methodConstraints) {
|
||||
this.method = method;
|
||||
this.genericsAndBoundsMethod = genericsAndBoundsMethod;
|
||||
this.genericsAndBounds = genericsAndBounds;
|
||||
this.methodParamsAndTypes = methodParamsAndTypes;
|
||||
this.resultSet = resultSet;
|
||||
this.constraints = constraints;
|
||||
this.consClass = consClass;
|
||||
this.methodConstraints = methodConstraints;
|
||||
sw = new SignatureWriter();
|
||||
createSignatureForConsOrMethod(this.method,false);
|
||||
}
|
||||
|
||||
public String createSignatureForConstructor(Constructor constructor) {
|
||||
visitParams();
|
||||
sw.visitReturnType().visitBaseType('V');
|
||||
return sw.toString();
|
||||
public Signature(LambdaExpression lambdaExpression,int numberOfParams) {
|
||||
sw = new SignatureWriter();
|
||||
createSignatureForFunN(lambdaExpression, numberOfParams);
|
||||
}
|
||||
|
||||
public String createSignatureForMethod(Method method) {
|
||||
defineGenerics(method);
|
||||
private void createSignatureForFunN(LambdaExpression lambdaExpression, int numberOfParams) {
|
||||
|
||||
String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
|
||||
|
||||
visitParams();
|
||||
visitReturnType(method, ret);
|
||||
return sw.toString();
|
||||
// sw.visitClassBound().visitEnd();
|
||||
for(int i = 0;i<numberOfParams;i++) {
|
||||
int j = i+1;
|
||||
sw.visitFormalTypeParameter("T"+ j);
|
||||
// getBounds von Params
|
||||
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
||||
sw.visitClassBound().visitEnd();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param method
|
||||
* @param ret
|
||||
*/
|
||||
private void visitReturnType(Method method, String ret) {
|
||||
if (ret.equals("V")) {
|
||||
sw.visitReturnType().visitBaseType('V');
|
||||
} else {
|
||||
RefTypeOrTPHOrWildcardOrGeneric returnType = method.getReturnType();
|
||||
SignatureVisitor sv = sw.visitReturnType();
|
||||
doVisitParamsOrReturn(returnType, sv);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private void visitParams() {
|
||||
for (String paramName : methodParamsAndTypes.keySet()) {
|
||||
RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName);
|
||||
SignatureVisitor sv = sw.visitParameterType();
|
||||
doVisitParamsOrReturn(t, sv);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param method
|
||||
*/
|
||||
private void defineGenerics(Method method) {
|
||||
method.getGenerics().forEach(g -> {
|
||||
visitTypeVarsAndTheirBounds(g, genericsAndBoundsMethod);
|
||||
});
|
||||
defineGenericsFromConstraints(constraints,genericsAndBoundsMethod);
|
||||
}
|
||||
|
||||
private void createSignatureForFunN(int numberOfParams, String to, String[] paramTypes) {
|
||||
defineTypeVariablesForParametersOfFunN(numberOfParams);
|
||||
|
||||
sw.visitFormalTypeParameter("R");
|
||||
visitClassBound(to);
|
||||
// TODO: prüfe ob Return-Type = void,
|
||||
sw.visitSuperclass().visitClassType(Type.getInternalName(Object.class));
|
||||
sw.visitEnd();
|
||||
|
||||
}
|
||||
|
||||
private void createSignatureForFunN(int numberOfParams) {
|
||||
|
||||
defineTypeVariablesForParametersOfFunN(numberOfParams);
|
||||
|
||||
sw.visitFormalTypeParameter("R");
|
||||
// getBounds vom Return-Type
|
||||
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
||||
sw.visitClassBound().visitEnd();
|
||||
// TODO: prüfe ob Return-Type = void,
|
||||
sw.visitSuperclass().visitClassType(Type.getInternalName(Object.class));
|
||||
sw.visitSuperclass().visitClassType(Type.getInternalName(Object.class));;
|
||||
sw.visitEnd();
|
||||
}
|
||||
|
||||
private void defineTypeVariablesForParametersOfFunN(int numberOfParams) {
|
||||
for (int i = 0; i < numberOfParams; i++) {
|
||||
int j = i + 1;
|
||||
sw.visitFormalTypeParameter("T" + j);
|
||||
// getBounds von Params
|
||||
/**
|
||||
* Creates signature for a method or constructor with @see {@link SignatureWriter}
|
||||
* Signature looks like:
|
||||
* <typevaliables (K:Ljava/lang/Object "Bounds")>(params L.. OR T.. Or basistape)ReturnType
|
||||
*
|
||||
* @param method method or constructor
|
||||
* @param isConstructor true if constructor
|
||||
*/
|
||||
private void createSignatureForConsOrMethod(Method method, boolean isConstructor) {
|
||||
Iterator<? extends GenericTypeVar> itr = method.getGenerics().iterator();
|
||||
// visits all formal type parameter and visits their bounds <T:...;B:...;...>
|
||||
while(itr.hasNext()) {
|
||||
System.out.println("HAS GENERICS!!");
|
||||
GenericTypeVar g = itr.next();
|
||||
getBoundsOfTypeVar(g,genericsAndBoundsMethod);
|
||||
}
|
||||
|
||||
// Wenn die RückgabeType eine TPH ist, wird als generic behandelt
|
||||
// z.B: Type = TPH K => wird eine Formal Type Parameter K$ erzeugt und Bound = Object
|
||||
if(!isConstructor) {
|
||||
String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
|
||||
ArrayList<TPHConstraint> allConsBeforeSimplify = new ArrayList<>();
|
||||
|
||||
HashMap<TPHConstraint,HashSet<String>> allConstraints = new HashMap<>();
|
||||
|
||||
if(ret.contains("<")) {
|
||||
allConsBeforeSimplify = getAllConstraints((RefType) resultSet.resolveType(method.getReturnType()).resolvedType);
|
||||
}
|
||||
|
||||
for(String paramName : methodParamsAndTypes.keySet()) {
|
||||
RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName);
|
||||
String pT = t.acceptTV(new TypeToSignature());
|
||||
|
||||
if(pT.contains("<"))
|
||||
allConsBeforeSimplify = getAllConstraints((RefType) t);
|
||||
}
|
||||
boolean doSimplify = false;
|
||||
if(!allConsBeforeSimplify.isEmpty()) {
|
||||
addConstraintsToMap(allConstraints,allConsBeforeSimplify);
|
||||
doSimplify = true;
|
||||
}
|
||||
createTypeVars(allConstraints, doSimplify);
|
||||
|
||||
if(!ret.equals("V")) {
|
||||
if(ret.contains("$") && !ret.contains("$$") && !ret.contains("<")) {
|
||||
if(genericsAndBounds.containsKey(ret)) {
|
||||
genericsAndBoundsMethod.put(ret.substring(1), genericsAndBounds.get(ret.substring(1)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// visit each method-parameter to create the signature
|
||||
for(String paramName : methodParamsAndTypes.keySet()) {
|
||||
RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName);
|
||||
// parameter type deswegen ist true
|
||||
doVisitParamsOrReturn(t,true);
|
||||
}
|
||||
if(isConstructor ||
|
||||
resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature()).equals("V")) {
|
||||
sw.visitReturnType().visitBaseType('V');
|
||||
}else {
|
||||
RefTypeOrTPHOrWildcardOrGeneric returnType = method.getReturnType();
|
||||
// return type deswegen ist false
|
||||
doVisitParamsOrReturn(returnType, false);
|
||||
}
|
||||
// sw.visitEnd();
|
||||
}
|
||||
|
||||
private void addConstraintsToMap(HashMap<TPHConstraint, HashSet<String>> allConstraints,
|
||||
ArrayList<TPHConstraint> allConsBeforeSimplify) {
|
||||
for(TPHConstraint tphCons : allConsBeforeSimplify) {
|
||||
allConstraints.put(tphCons, null);
|
||||
}
|
||||
}
|
||||
|
||||
private String getEqualTPH(HashMap<TPHConstraint, HashSet<String>> methodConstraints, String tph) {
|
||||
for(TPHConstraint cons : methodConstraints.keySet()) {
|
||||
if(methodConstraints.get(cons) != null) {
|
||||
if(methodConstraints.get(cons).contains(tph)) {
|
||||
return cons.getLeft();
|
||||
}
|
||||
}
|
||||
}
|
||||
return tph;
|
||||
}
|
||||
|
||||
private void createTypeVars(HashMap<TPHConstraint, HashSet<String>> allConstraints, boolean doSimplify) {
|
||||
allConstraints.putAll(methodConstraints);
|
||||
|
||||
HashMap<TPHConstraint, HashSet<String>> simplifiedConstraints;
|
||||
if(doSimplify) {
|
||||
simplifiedConstraints = Simplify.simplifyContraints(allConstraints);
|
||||
}else {
|
||||
simplifiedConstraints = allConstraints;
|
||||
}
|
||||
|
||||
for(TPHConstraint cons : simplifiedConstraints.keySet()) {
|
||||
// need subst.
|
||||
String sub = cons.getLeft()+"$";
|
||||
if(!genericsAndBoundsMethod.containsKey(sub) && !genericsAndBounds.containsKey(sub)) {
|
||||
sw.visitFormalTypeParameter(sub);
|
||||
String bound = cons.getRight();
|
||||
if(bound.equals(Type.getInternalName(Object.class))) {
|
||||
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
||||
sw.visitClassBound().visitEnd();
|
||||
genericsAndBoundsMethod.put(sub, bound);
|
||||
} else {
|
||||
String boundName = bound+"$";
|
||||
sw.visitClassBound().visitTypeVariable(boundName);
|
||||
genericsAndBoundsMethod.put(sub, boundName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayList<TPHConstraint> getAllConstraints(RefType ref) {
|
||||
final ArrayList<TPHConstraint> res = new ArrayList<>();
|
||||
for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) {
|
||||
ResolvedType resType;
|
||||
if(p instanceof WildcardType) {
|
||||
resType = resultSet.resolveType(((WildcardType) p).getInnerType());
|
||||
}else {
|
||||
resType = resultSet.resolveType(p);
|
||||
}
|
||||
|
||||
RefTypeOrTPHOrWildcardOrGeneric resolved = resType.resolvedType;
|
||||
if(resolved instanceof TypePlaceholder) {
|
||||
resType.additionalGenerics.forEach(ag ->{
|
||||
TPHConstraint constr = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS);
|
||||
if(!contains(res,constr)) {
|
||||
res.add(constr);
|
||||
}
|
||||
});
|
||||
}
|
||||
if(resolved instanceof WildcardType) {
|
||||
WildcardType resWC = (WildcardType) resolved;
|
||||
ResolvedType resType2 = resultSet.resolveType(resWC.getInnerType());
|
||||
if(resType2.resolvedType instanceof TypePlaceholder) {
|
||||
resType2.additionalGenerics.forEach(ag ->{
|
||||
TPHConstraint constr = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS);
|
||||
if(!contains(res,constr)) {
|
||||
res.add(constr);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
System.out.println("RES GIP === " + res.size());
|
||||
return res;
|
||||
}
|
||||
private boolean contains(ArrayList<TPHConstraint> constraints, TPHConstraint constr) {
|
||||
for(int i=0; i<constraints.size();++i) {
|
||||
TPHConstraint p = constraints.get(i);
|
||||
if(constr.getLeft().equals(p.getLeft()) && constr.getRight().equals(p.getRight()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits parameter type or return type with {@link SignatureVisitor} to create
|
||||
* the method signature
|
||||
*
|
||||
* @param t type of parameter or return type
|
||||
* @param sv true if t is type of parameter
|
||||
* @param isParameterType true if t is type of parameter
|
||||
*/
|
||||
private void doVisitParamsOrReturn(RefTypeOrTPHOrWildcardOrGeneric t, SignatureVisitor sv) {
|
||||
private void doVisitParamsOrReturn(RefTypeOrTPHOrWildcardOrGeneric t, boolean isParameterType) {
|
||||
String type = t.acceptTV(new TypeToString());
|
||||
|
||||
SignatureVisitor sv;
|
||||
if(isParameterType) {
|
||||
sv = sw.visitParameterType();
|
||||
}
|
||||
else {
|
||||
sv = sw.visitReturnType();
|
||||
}
|
||||
switch (type) {
|
||||
case "RT":
|
||||
String sig = t.acceptTV(new TypeToSignature(constraints));
|
||||
String sig = t.acceptTV(new TypeToSignature());
|
||||
sv.visitClassType(sig.substring(1, sig.length()));
|
||||
break;
|
||||
case "GRT":
|
||||
GenericRefType g = (GenericRefType) t;
|
||||
sv.visitTypeVariable(g.acceptTV(new TypeToSignature(constraints)));
|
||||
sv.visitTypeVariable(g.acceptTV(new TypeToSignature()).substring(1));
|
||||
break;
|
||||
case "TPH":
|
||||
RefTypeOrTPHOrWildcardOrGeneric r = resultSet.resolveType(t).resolvedType;
|
||||
// der Fall wenn der Typ eine Interface ist, muss betrachtet werden
|
||||
// der Fall wenn die Type eine Interface ist, muss betrachtet werden
|
||||
// Deswegen muss in ResutSet noch enthalten werden, ob die Type eine
|
||||
// Interface oder eine Klasse ist.
|
||||
|
||||
// das braucht man nicht es reicht: sv.visitTypeVariable(r.acceptTV(new
|
||||
// TypeToSignature())
|
||||
// das braucht man nicht es reicht: sv.visitTypeVariable(r.acceptTV(new TypeToSignature())
|
||||
//
|
||||
String sig2 = r.acceptTV(new TypeToSignature(constraints));
|
||||
if (r instanceof GenericRefType) {
|
||||
sv.visitTypeVariable(sig2);
|
||||
} else if (!(r instanceof TypePlaceholder)) {
|
||||
if (sig2.contains(SPECIAL_CHAR_FOR_FUN)) {
|
||||
sv.visitInterface().visitClassType(sig2.substring(1));
|
||||
String sig2 = r.acceptTV(new TypeToSignature());
|
||||
String eqTPH = getEqualTPH(methodConstraints, sig2.substring(1, sig2.length()-1))+"$";
|
||||
if(!(r instanceof TypePlaceholder)) {
|
||||
if(sig2.contains("$$")) {
|
||||
System.out.println(" Signature FUN$$: "+r);
|
||||
sv.visitInterface().visitClassType(sig2.substring(1, sig2.length()));
|
||||
} else {
|
||||
// Kann zwischen GenericRefType und RefType nicht unterscheiden
|
||||
// Deswegen wird immer geprüft, ob der Name in Generic Maps liegt
|
||||
String n = sig2.substring(1, sig2.length() - 1);
|
||||
// if(genericsAndBoundsMethod.containsKey(n) || genericsAndBounds.containsKey(n)) {
|
||||
// sv.visitTypeVariable(n);
|
||||
// } else {
|
||||
sv.visitClassType(n);
|
||||
sv.visitEnd();
|
||||
// }
|
||||
// sv.visitClassType(n);
|
||||
sv.visitClassType(sig2.substring(1, sig2.length()));
|
||||
}
|
||||
|
||||
} else {
|
||||
String realName = sig2.substring(1, sig2.length() - 1);
|
||||
String toVisit = realName+SPECIAL_CHAR;
|
||||
if(!genericsAndBounds.containsKey(toVisit)) {
|
||||
Optional<GenericsGeneratorResult> equalTPH = getEqualTPHFromClassConstraints(consClass, realName);
|
||||
if(equalTPH.isPresent()){
|
||||
toVisit = equalTPH.get().getConstraint().getLeft() + SPECIAL_CHAR;
|
||||
} else {
|
||||
toVisit = getEqualTPH(constraints, realName) + SPECIAL_CHAR;
|
||||
}
|
||||
}
|
||||
sv.visitTypeVariable(toVisit);
|
||||
System.out.println(r.getClass()+" Signature TPH: "+r.acceptTV(new TypeToSignature()));
|
||||
sv.visitTypeVariable(eqTPH);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "SWC":
|
||||
System.out.println("SWC---Signature");
|
||||
SuperWildcardType swc = (SuperWildcardType) t;
|
||||
String sigInner = swc.getInnerType().acceptTV(new TypeToSignature(constraints));
|
||||
int length = sigInner.length();
|
||||
visitWildCard(sv, sigInner, length, swc.getInnerType(), SUPER_CHAR);
|
||||
String sigInner = swc.getInnerType().acceptTV(new TypeToSignature());
|
||||
if(swc.getInnerType() instanceof TypePlaceholder) {
|
||||
sv.visitTypeArgument('-').visitTypeVariable(sigInner.substring(1, sigInner.length()));
|
||||
} else if(swc.getInnerType() instanceof RefType) {
|
||||
if(sigInner.contains("$$")) {
|
||||
sv.visitTypeArgument('-').visitInterface().visitClassType(sigInner.substring(1,sigInner.length()));
|
||||
}else {
|
||||
sv.visitTypeArgument('-').visitClassType(sigInner.substring(1,sigInner.length()));
|
||||
}
|
||||
}else {
|
||||
sv.visitTypeArgument('-').visitTypeVariable(sigInner.substring(1));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "EWC":
|
||||
System.out.println("EWC---Signature");
|
||||
ExtendsWildcardType ewc = (ExtendsWildcardType) t;
|
||||
String esigInner = ewc.getInnerType().acceptTV(new TypeToSignature(constraints));
|
||||
int lengthEWCSig = esigInner.length();
|
||||
visitWildCard(sv, esigInner, lengthEWCSig, ewc.getInnerType(), EXTENDS_CHAR);
|
||||
String esigInner = ewc.getInnerType().acceptTV(new TypeToSignature());
|
||||
System.out.println(esigInner);
|
||||
if(ewc.getInnerType() instanceof TypePlaceholder) {
|
||||
sv.visitTypeArgument('+').visitTypeVariable(esigInner.substring(1, esigInner.length()));
|
||||
} else if(ewc.getInnerType() instanceof RefType) {
|
||||
if(esigInner.contains("$$")) {
|
||||
sv.visitTypeArgument('+').visitInterface().visitClassType(esigInner.substring(1,esigInner.length()));
|
||||
}else {
|
||||
// sv.visitClassType(esigInner.substring(1,esigInner.length()));
|
||||
sv.visitTypeArgument('+').visitClassType(esigInner.substring(1,esigInner.length()));
|
||||
}
|
||||
}else {
|
||||
sv.visitTypeArgument('+').visitTypeVariable(esigInner.substring(1));
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
// if (!sv)
|
||||
// sv.visitBaseType('V');
|
||||
if(!isParameterType)
|
||||
sv.visitBaseType('V');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void visitWildCard(SignatureVisitor sv, String sigInner, int length, RefTypeOrTPHOrWildcardOrGeneric innerType, char superOrExtendsChar) {
|
||||
if (innerType instanceof TypePlaceholder) {
|
||||
sv.visitTypeArgument(superOrExtendsChar).visitTypeVariable(sigInner.substring(1, length));
|
||||
} else if (innerType instanceof RefType) {
|
||||
checkInnerSignatureOfWildCard(sv, sigInner, length, superOrExtendsChar);
|
||||
} else {
|
||||
sv.visitTypeArgument(superOrExtendsChar).visitTypeVariable(sigInner.substring(1));
|
||||
}
|
||||
}
|
||||
|
||||
private void checkInnerSignatureOfWildCard(SignatureVisitor sv, String sigInner, int length, char superOrExtendsChar) {
|
||||
if (sigInner.contains(SPECIAL_CHAR_FOR_FUN)) {
|
||||
sv.visitTypeArgument(superOrExtendsChar).visitInterface().visitClassType(sigInner.substring(1, length));
|
||||
} else {
|
||||
sv.visitTypeArgument(superOrExtendsChar).visitClassType(sigInner.substring(1, length));
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<GenericsGeneratorResult> getEqualTPHFromClassConstraints(List<GenericsGeneratorResult> consClass, String tph) {
|
||||
return consClass.stream()
|
||||
.filter(c -> c.getConstraint().getLeft().equals(tph) || c.getEqualsTPHs().contains(tph))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
private String getEqualTPH(List<GenericsGeneratorResult> constraints2, String tph) {
|
||||
return constraints2.stream()
|
||||
.filter(c -> c.getConstraint().getLeft().equals(tph) || c.getEqualsTPHs().contains(tph))
|
||||
.findFirst().get().getConstraint().getLeft();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates signature for class or interface with {@link SignatureWriter}
|
||||
* Signature looks like: <typevaliables (K:Ljava/lang/Object
|
||||
* "Bounds")>superclass
|
||||
* Signature looks like:
|
||||
* <typevaliables (K:Ljava/lang/Object "Bounds")>superclass
|
||||
*/
|
||||
public String createSignatureForClassOrInterface() {
|
||||
defineTypeVariablesForClassOrInterface();
|
||||
|
||||
defineGenericsFromConstraints(consClass,genericsAndBounds);
|
||||
|
||||
String sClass = classOrInterface.getSuperClass().acceptTV(new TypeToSignature());
|
||||
sw.visitSuperclass().visitClassType(sClass.substring(1, sClass.length() - 1));
|
||||
sw.visitEnd();
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
private void defineTypeVariablesForClassOrInterface() {
|
||||
private void createSignatureForClassOrInterface() {
|
||||
Iterator<GenericTypeVar> itr = classOrInterface.getGenerics().iterator();
|
||||
|
||||
while (itr.hasNext()) {
|
||||
while(itr.hasNext()) {
|
||||
GenericTypeVar g = itr.next();
|
||||
visitTypeVarsAndTheirBounds(g, genericsAndBounds);
|
||||
}
|
||||
getBoundsOfTypeVar(g,genericsAndBounds);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param genericsAndBounds2
|
||||
*
|
||||
*/
|
||||
private void defineGenericsFromConstraints(List<GenericsGeneratorResult> constraints, HashMap<String,String> genericsAndBounds2) {
|
||||
constraints.forEach(c -> {
|
||||
String typeVariable = c.getConstraint().getLeft() + SPECIAL_CHAR;
|
||||
sw.visitFormalTypeParameter(typeVariable);
|
||||
if(!consClass.isEmpty()) {
|
||||
ArrayList<String> types = new ArrayList<>();
|
||||
ArrayList<String> superTypes = new ArrayList<>();
|
||||
|
||||
String bound = c.getConstraint().getRight();
|
||||
bound = checkBound(bound);
|
||||
genericsAndBounds2.put(typeVariable, bound);
|
||||
});
|
||||
for(TPHConstraint cons : consClass) {
|
||||
types.add(cons.getLeft());
|
||||
superTypes.add(cons.getRight());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bound
|
||||
* @return
|
||||
*/
|
||||
private String checkBound(String bound) {
|
||||
if (bound.equals(Type.getInternalName(Object.class))) {
|
||||
visitClassBound(bound);
|
||||
} else {
|
||||
bound += SPECIAL_CHAR;
|
||||
for(TPHConstraint cons : consClass) {
|
||||
String t = cons.getLeft()+"$";
|
||||
String bound = cons.getRight()+"$";
|
||||
sw.visitFormalTypeParameter(t);
|
||||
sw.visitClassBound().visitTypeVariable(bound);
|
||||
}
|
||||
return bound;
|
||||
genericsAndBounds.put(t, bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bound
|
||||
*/
|
||||
private void visitClassBound(String bound) {
|
||||
for(TPHConstraint cons : consClass) {
|
||||
if(!types.contains(cons.getRight())) {
|
||||
String t = cons.getRight()+"$";
|
||||
String bound = Type.getInternalName(Object.class);
|
||||
sw.visitFormalTypeParameter(t);
|
||||
sw.visitClassBound().visitClassType(bound);
|
||||
genericsAndBounds.put(t, bound);
|
||||
sw.visitClassBound().visitEnd();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*if(!commonPairs.isEmpty()) {
|
||||
ArrayList<TypePlaceholder> types = new ArrayList<>();
|
||||
ArrayList<TypePlaceholder> superTypes = new ArrayList<>();
|
||||
|
||||
for(GenericInsertPair p : commonPairs) {
|
||||
types.add(p.TA1);
|
||||
superTypes.add(p.TA2);
|
||||
}
|
||||
|
||||
for(GenericInsertPair p : commonPairs) {
|
||||
String t = p.TA1.getName()+"$";
|
||||
String bound = p.TA2.getName()+"$";
|
||||
sw.visitFormalTypeParameter(t);
|
||||
sw.visitClassBound().visitTypeVariable(bound);
|
||||
genericsAndBounds.put(t, bound);
|
||||
}
|
||||
|
||||
for(GenericInsertPair p : commonPairs) {
|
||||
if(!types.contains(p.TA2)) {
|
||||
String t = p.TA2.getName()+"$";
|
||||
String bound = Type.getInternalName(Object.class);
|
||||
sw.visitFormalTypeParameter(t);
|
||||
sw.visitClassBound().visitClassType(bound);
|
||||
genericsAndBounds.put(t, bound);
|
||||
sw.visitClassBound().visitEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
for(TypePlaceholder t : tphsClass) {
|
||||
String n = t.getName()+"$";
|
||||
String bound = Type.getInternalName(Object.class);
|
||||
sw.visitFormalTypeParameter(n);
|
||||
sw.visitClassBound().visitClassType(bound);
|
||||
genericsAndBounds.put(n, bound);
|
||||
sw.visitClassBound().visitEnd();
|
||||
}*/
|
||||
String sClass = classOrInterface.getSuperClass().acceptTV(new TypeToSignature());
|
||||
sw.visitSuperclass().visitClassType(sClass.substring(1, sClass.length()-1));
|
||||
sw.visitEnd();
|
||||
}
|
||||
/**
|
||||
* Get bounds of type variable
|
||||
*
|
||||
* @param g type variable
|
||||
* @param genAndBounds
|
||||
*/
|
||||
private void visitTypeVarsAndTheirBounds(GenericTypeVar g, HashMap<String, String> genAndBounds) {
|
||||
private void getBoundsOfTypeVar(GenericTypeVar g, HashMap<String, String> genAndBounds) {
|
||||
sw.visitFormalTypeParameter(g.getName());
|
||||
|
||||
Iterator<? extends RefTypeOrTPHOrWildcardOrGeneric> bItr = g.getBounds().iterator();
|
||||
while (bItr.hasNext()) {
|
||||
RefTypeOrTPHOrWildcardOrGeneric b = bItr.next();
|
||||
while(bItr.hasNext()) {
|
||||
RefTypeOrTPHOrWildcardOrGeneric b =bItr.next();
|
||||
String boundDesc = b.acceptTV(new TypeToDescriptor());
|
||||
// System.out.println("GetBounds: " + boundDesc);
|
||||
// Ensure that <...> extends java.lang.Object OR ...
|
||||
if (b instanceof GenericRefType) {
|
||||
sw.visitClassBound().visitTypeVariable(boundDesc);
|
||||
} else {
|
||||
visitClassBound(boundDesc);
|
||||
}
|
||||
sw.visitClassBound().visitClassType(boundDesc);
|
||||
genAndBounds.put(g.getName(), boundDesc);
|
||||
}
|
||||
sw.visitClassBound().visitEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if(sw == null)
|
||||
return super.toString();
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,11 +1,8 @@
|
||||
package de.dhbwstuttgart.bytecode.signature;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResult;
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
@@ -15,15 +12,6 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypeVisitor;
|
||||
|
||||
public class TypeToSignature implements TypeVisitor<String> {
|
||||
private List<GenericsGeneratorResult> constraints;
|
||||
|
||||
public TypeToSignature() {
|
||||
this.constraints = new ArrayList<>();
|
||||
}
|
||||
|
||||
public TypeToSignature(List<GenericsGeneratorResult> constraints) {
|
||||
this.constraints = constraints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visit(RefType refType) {
|
||||
@@ -45,7 +33,7 @@ public class TypeToSignature implements TypeVisitor<String> {
|
||||
// } else {
|
||||
// params += "L"+param.toString().replace(".", "/");
|
||||
// }
|
||||
params += param.acceptTV(new TypeToSignature(constraints));
|
||||
params += param.acceptTV(new TypeToSignature());
|
||||
|
||||
if(param instanceof TypePlaceholder)
|
||||
params += ";";
|
||||
@@ -60,7 +48,7 @@ public class TypeToSignature implements TypeVisitor<String> {
|
||||
@Override
|
||||
public String visit(SuperWildcardType superWildcardType) {
|
||||
// throw new NotImplementedException();
|
||||
String sig = "-" + superWildcardType.getInnerType().acceptTV(new TypeToSignature(constraints));
|
||||
String sig = "-" + superWildcardType.getInnerType().acceptTV(new TypeToSignature());
|
||||
if(superWildcardType.getInnerType() instanceof TypePlaceholder)
|
||||
sig += ";";
|
||||
return sig;
|
||||
@@ -69,21 +57,13 @@ public class TypeToSignature implements TypeVisitor<String> {
|
||||
@Override
|
||||
public String visit(TypePlaceholder typePlaceholder) {
|
||||
// return typePlaceholder.toString().replace(".", "/");
|
||||
String name = typePlaceholder.getName();
|
||||
|
||||
if(!constraints.isEmpty()){
|
||||
Optional<GenericsGeneratorResult> equalName = getEqualTPHFromClassConstraints(constraints, name);
|
||||
if(equalName.isPresent())
|
||||
name = equalName.get().getConstraint().getLeft();
|
||||
}
|
||||
|
||||
return "T" + name + "$";
|
||||
return "T" + typePlaceholder.getName() + "$";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visit(ExtendsWildcardType extendsWildcardType) {
|
||||
// throw new NotImplementedException();
|
||||
String sig = "+" + extendsWildcardType.getInnerType().acceptTV(new TypeToSignature(constraints));
|
||||
String sig = "+" + extendsWildcardType.getInnerType().acceptTV(new TypeToSignature());
|
||||
if(extendsWildcardType.getInnerType() instanceof TypePlaceholder)
|
||||
sig += ";";
|
||||
return sig;
|
||||
@@ -94,9 +74,4 @@ public class TypeToSignature implements TypeVisitor<String> {
|
||||
return genericRefType.getParsedName().replace(".", "/");
|
||||
}
|
||||
|
||||
private Optional<GenericsGeneratorResult> getEqualTPHFromClassConstraints(List<GenericsGeneratorResult> listOfConstraints, String tph) {
|
||||
return listOfConstraints.stream()
|
||||
.filter(c -> c.getConstraint().getLeft().equals(tph) || c.getEqualsTPHs().contains(tph))
|
||||
.findFirst();
|
||||
}
|
||||
}
|
||||
|
@@ -1,50 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.simplifyRes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* The simplify results of a source file (package)
|
||||
*
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class GenericGenratorResultForSourceFile {
|
||||
private String pkgName;
|
||||
private final List<GenericsGeneratorResultForClass> genericGeneratorResultForAllClasses = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* @param pkgName
|
||||
*/
|
||||
public GenericGenratorResultForSourceFile(String pkgName) {
|
||||
this.pkgName = pkgName;
|
||||
}
|
||||
|
||||
public List<GenericsGeneratorResultForClass> getGenericGeneratorResultForAllClasses() {
|
||||
return genericGeneratorResultForAllClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the simplify results of a class to simplifyResForSF
|
||||
*
|
||||
* @param sResClass simplify results of a class to added
|
||||
*/
|
||||
public void addGenericGeneratorResultClass(GenericsGeneratorResultForClass sResClass) {
|
||||
genericGeneratorResultForAllClasses.add(sResClass);
|
||||
}
|
||||
|
||||
public GenericsGeneratorResultForClass getSimplifyResultsByName(String pkgName, String name) {
|
||||
for (int i = 0; i < genericGeneratorResultForAllClasses.size(); i++) {
|
||||
GenericsGeneratorResultForClass genericsGeneratorResult = genericGeneratorResultForAllClasses.get(i);
|
||||
if (genericsGeneratorResult.getClassName().equals(name)) {
|
||||
return genericsGeneratorResult;
|
||||
}
|
||||
}
|
||||
|
||||
return new GenericsGeneratorResultForClass(name);
|
||||
}
|
||||
}
|
@@ -1,75 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.simplifyRes;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericGeneratorResultsForAllMethods;
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResult;
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.MethodAndConstraints;
|
||||
|
||||
/**
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class GenericsGeneratorResultForClass {
|
||||
private final String className;
|
||||
private final List<GenericsGeneratorResult> classConstraints;
|
||||
private final GenericGeneratorResultsForAllMethods methodsAndTheirConstraints;
|
||||
|
||||
public GenericsGeneratorResultForClass(String className) {
|
||||
this(className, Collections.emptyList(), new GenericGeneratorResultsForAllMethods());
|
||||
}
|
||||
/**
|
||||
* @param className
|
||||
* @param classConstraints
|
||||
* @param methodsAndTheirConstraints
|
||||
*/
|
||||
public GenericsGeneratorResultForClass(String className, List<GenericsGeneratorResult> classConstraints,
|
||||
GenericGeneratorResultsForAllMethods methodsAndTheirConstraints) {
|
||||
this.className = className;
|
||||
this.classConstraints = classConstraints;
|
||||
this.methodsAndTheirConstraints = methodsAndTheirConstraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the className
|
||||
*/
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the classConstraints
|
||||
*/
|
||||
public List<GenericsGeneratorResult> getClassConstraints() {
|
||||
return classConstraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the methodsAndTheirConstraints
|
||||
*/
|
||||
public GenericGeneratorResultsForAllMethods getMethodsAndTheirConstraints() {
|
||||
return methodsAndTheirConstraints;
|
||||
}
|
||||
|
||||
public boolean contains(String id) {
|
||||
return methodsAndTheirConstraints.getMethodsAndConstraints().stream().map(mc -> mc.getMethodID())
|
||||
.anyMatch(i -> i.equals(id));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public List<GenericsGeneratorResult> getMethodConstraintsByID(String id) {
|
||||
java.util.Optional<MethodAndConstraints> methodAndConstraints = methodsAndTheirConstraints.getMethodsAndConstraints().stream().filter(mc -> mc.getMethodID().equals(id))
|
||||
.findFirst();
|
||||
|
||||
return methodAndConstraints.isPresent() ? methodAndConstraints.get().getConstraints() : Collections.emptyList();
|
||||
}
|
||||
|
||||
}
|
@@ -1,94 +0,0 @@
|
||||
package de.dhbwstuttgart.bytecode.utilities;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.signature.Signature;
|
||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.signature.SignatureVisitor;
|
||||
import org.objectweb.asm.signature.SignatureWriter;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class ByteCodeForFunNGenerator {
|
||||
|
||||
public static void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc, File path) {
|
||||
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||
|
||||
SignatureWriter methSig = new SignatureWriter();
|
||||
|
||||
int numberOfParams = 0;
|
||||
SignatureVisitor paramVisitor = methSig.visitParameterType();
|
||||
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
||||
while (itr.hasNext()) {
|
||||
numberOfParams++;
|
||||
// getBounds
|
||||
paramVisitor.visitTypeVariable(CONSTANTS.T + numberOfParams);
|
||||
itr.next();
|
||||
}
|
||||
methSig.visitReturnType().visitTypeVariable(CONSTANTS.R);
|
||||
// ")"+lam.getReturn.getBounds
|
||||
Signature sig = new Signature(numberOfParams);
|
||||
String name = CONSTANTS.FUN + numberOfParams + CONSTANTS.$$;
|
||||
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
|
||||
Type.getInternalName(Object.class), null);
|
||||
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "apply", methDesc,
|
||||
methSig.toString(), null);
|
||||
mvApply.visitEnd();
|
||||
writeClassFile(classWriter.toByteArray(), name, path);
|
||||
}
|
||||
|
||||
public static void generateBCForFunN(ArgumentList argumentList, String methDesc, File path) {
|
||||
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||
|
||||
SignatureWriter methSig = new SignatureWriter();
|
||||
|
||||
int numberOfParams = 0;
|
||||
SignatureVisitor paramVisitor = methSig.visitParameterType();
|
||||
Iterator<Expression> itr1 = argumentList.getArguments().iterator();
|
||||
|
||||
while(itr1.hasNext()) {
|
||||
numberOfParams++;
|
||||
// getBounds
|
||||
paramVisitor.visitTypeVariable(CONSTANTS.T + numberOfParams);
|
||||
itr1.next();
|
||||
}
|
||||
|
||||
methSig.visitReturnType().visitTypeVariable(CONSTANTS.R);
|
||||
// ")"+lam.getReturn.getBounds
|
||||
Signature sig = new Signature(numberOfParams);
|
||||
String name = CONSTANTS.FUN + numberOfParams + CONSTANTS.$$;
|
||||
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
|
||||
Type.getInternalName(Object.class), null);
|
||||
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "apply", methDesc,
|
||||
methSig.toString(), null);
|
||||
mvApply.visitEnd();
|
||||
writeClassFile(classWriter.toByteArray(), name, path);
|
||||
}
|
||||
|
||||
|
||||
public static void writeClassFile(byte[] bytecode, String name, File path) {
|
||||
FileOutputStream output;
|
||||
try {
|
||||
System.out.println("generating " + name + ".class file...");
|
||||
output = new FileOutputStream(
|
||||
new File(path , name + CONSTANTS.EXTENSIONCLASS));
|
||||
output.write(bytecode);
|
||||
output.close();
|
||||
System.out.println(name + ".class file generated");
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
package de.dhbwstuttgart.bytecode.utilities;
|
||||
|
||||
public interface CONSTANTS {
|
||||
|
||||
String VOID = "void";
|
||||
String TPH = "TPH ";
|
||||
String ANGLEBRACKET = "<";
|
||||
String FUN = "Fun";
|
||||
String EXTENSIONCLASS = ".class";
|
||||
String $$ = "$$";
|
||||
String T = "T";
|
||||
String R = "R";
|
||||
String DESUGAREDMETHODNAME = "lambda$new$";
|
||||
String REFTYPE_BYTE = "java/lang/Byte";
|
||||
String REFTYPE_SHORT = "java/lang/Short";
|
||||
String REFTYPE_INTEGER = "java/lang/Integer";
|
||||
String REFTYPE_LONG = "java/lang/Long";
|
||||
String REFTYPE_DOUBLE = "java/lang/Double";
|
||||
String REFTYPE_FLOAT = "java/lang/Float";
|
||||
String REFTYPE_STRING = "java/lang/String";
|
||||
String TO_STRING = "toString";
|
||||
}
|
@@ -1,53 +0,0 @@
|
||||
package de.dhbwstuttgart.bytecode.utilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.ConstraintsWithSameLeftSide;
|
||||
|
||||
public class ConstraintsFinder {
|
||||
private List<TPHConstraint> allConstaints;
|
||||
|
||||
public ConstraintsFinder(List<TPHConstraint> allConstaints) {
|
||||
this.allConstaints = allConstaints;
|
||||
}
|
||||
|
||||
public List<ConstraintsWithSameLeftSide> findConstraints() {
|
||||
List<ConstraintsWithSameLeftSide> result = new ArrayList<>();
|
||||
|
||||
List<TPHConstraint> visitedCons = new ArrayList<>();
|
||||
for(TPHConstraint c : allConstaints) {
|
||||
if(c.getRel() == Relation.EXTENDS) {
|
||||
// get constraints with the same left side
|
||||
List<TPHConstraint> cons = getConstraints(c,visitedCons);
|
||||
if(cons.size()>1) {
|
||||
ConstraintsWithSameLeftSide consWithSameLeftSide = new ConstraintsWithSameLeftSide(cons);
|
||||
result.add(consWithSameLeftSide);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<TPHConstraint> getConstraints(TPHConstraint c, List<TPHConstraint> visitedCons) {
|
||||
List<TPHConstraint> res = new ArrayList<>();
|
||||
for(TPHConstraint cons : allConstaints) {
|
||||
if(!isVisited(cons,visitedCons) && cons.getLeft().equals(c.getLeft())) {
|
||||
res.add(cons);
|
||||
visitedCons.add(cons);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private boolean isVisited(TPHConstraint cons, List<TPHConstraint> visitedCons) {
|
||||
for(TPHConstraint c : visitedCons) {
|
||||
if(c.getLeft().equals(cons.getLeft()) && c.getRight().equals(cons.getRight()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
package de.dhbwstuttgart.bytecode.utilities;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -18,8 +19,7 @@ public class KindOfLambda implements StatementVisitor{
|
||||
private boolean isInstanceCapturingLambda = false;
|
||||
private List<RefTypeOrTPHOrWildcardOrGeneric> argumentList = new ArrayList<>();
|
||||
private ArrayList<String> usedVars = new ArrayList<>();
|
||||
private ArrayList<String> varsFromInnerLambdas = new ArrayList<>();
|
||||
private boolean thisUsed = false;
|
||||
private boolean hasThis = false;
|
||||
private ArrayList<String> definedLocals = new ArrayList<>();
|
||||
|
||||
public KindOfLambda(LambdaExpression lambdaExpression) {
|
||||
@@ -40,20 +40,19 @@ public class KindOfLambda implements StatementVisitor{
|
||||
return argumentList;
|
||||
}
|
||||
|
||||
public boolean isThisUsed() {
|
||||
return thisUsed;
|
||||
public boolean isHasThis() {
|
||||
return hasThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ArgumentList argumentList) {
|
||||
argumentList.getArguments().forEach(a->a.accept(this));
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(LambdaExpression lambdaExpression) {
|
||||
lambdaExpression.params.getFormalparalist().forEach(p->varsFromInnerLambdas.add(p.getName()));
|
||||
lambdaExpression.methodBody.accept(this);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -112,11 +111,9 @@ public class KindOfLambda implements StatementVisitor{
|
||||
|
||||
@Override
|
||||
public void visit(LocalVar localVar) {
|
||||
boolean addVar = !contain(params, localVar.name) && !definedLocals.contains(localVar.name) &&
|
||||
!varsFromInnerLambdas.contains(localVar.name) && !usedVars.contains(localVar.name);
|
||||
if(addVar) {
|
||||
if(!contain(params, localVar.name) && !definedLocals.contains(localVar.name)) {
|
||||
argumentList.add(localVar.getType());
|
||||
if(thisUsed) {
|
||||
if(hasThis) {
|
||||
usedVars.add(1, localVar.name);
|
||||
} else {
|
||||
usedVars.add(0, localVar.name);
|
||||
@@ -144,13 +141,12 @@ public class KindOfLambda implements StatementVisitor{
|
||||
@Override
|
||||
public void visit(MethodCall methodCall) {
|
||||
methodCall.receiver.accept(this);
|
||||
methodCall.arglist.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(NewClass methodCall) {
|
||||
methodCall.receiver.accept(this);
|
||||
methodCall.arglist.accept(this);
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -194,8 +190,8 @@ public class KindOfLambda implements StatementVisitor{
|
||||
|
||||
@Override
|
||||
public void visit(This aThis) {
|
||||
if(!thisUsed) {
|
||||
thisUsed = true;
|
||||
if(!hasThis) {
|
||||
hasThis = true;
|
||||
this.argumentList.add(0,aThis.getType());
|
||||
}
|
||||
if(!isInstanceCapturingLambda) {
|
||||
|
@@ -2,41 +2,28 @@ package de.dhbwstuttgart.bytecode.utilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultPair;
|
||||
|
||||
public class MethodAndTPH {
|
||||
|
||||
private String id;
|
||||
private String name;
|
||||
private final ArrayList<String> tphs = new ArrayList<>();
|
||||
//private final ArrayList<GenericInsertPair> pairs = new ArrayList<>();
|
||||
private final ArrayList<ResultPair<TypePlaceholder, TypePlaceholder>> pairs = new ArrayList<>();
|
||||
// tphs of local variables and parameters
|
||||
private final ArrayList<String> localTphs = new ArrayList<>();
|
||||
private final ArrayList<GenericInsertPair> pairs = new ArrayList<>();
|
||||
|
||||
public MethodAndTPH(String name) {
|
||||
this.id = name;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public ArrayList<String> getTphs() {
|
||||
return tphs;
|
||||
}
|
||||
|
||||
// public ArrayList<GenericInsertPair> getPairs(){
|
||||
// return pairs;
|
||||
// }
|
||||
public ArrayList<ResultPair<TypePlaceholder, TypePlaceholder>> getPairs(){
|
||||
public ArrayList<GenericInsertPair> getPairs(){
|
||||
return pairs;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public ArrayList<String> getLocalTphs() {
|
||||
return localTphs;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,244 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.utilities;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.Exception.NotInCurrentPackageException;
|
||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
|
||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import javassist.NotFoundException;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class MethodCallHelper {
|
||||
private MethodCall methCall;
|
||||
private SourceFile sourceFile;
|
||||
private ResultSet resultSet;
|
||||
private File path;
|
||||
|
||||
/**
|
||||
* @param methCall
|
||||
* @param sourceFile
|
||||
* @param resultSet
|
||||
* @param path TODO
|
||||
*/
|
||||
public MethodCallHelper(MethodCall methCall, SourceFile sourceFile, ResultSet resultSet, File path) {
|
||||
this.methCall = methCall;
|
||||
this.sourceFile = sourceFile;
|
||||
this.resultSet = resultSet;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||
return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
}
|
||||
|
||||
public boolean isInCurrPkg(String className) {
|
||||
for (ClassOrInterface cl : sourceFile.KlassenVektor) {
|
||||
if (className.equals(cl.getClassName().toString()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getSuperClass(String className) throws NotInCurrentPackageException {
|
||||
|
||||
for (ClassOrInterface cl : sourceFile.getClasses()) {
|
||||
if (className.equals(cl.getClassName().toString())) {
|
||||
return cl.getSuperClass().getName().toString();
|
||||
}
|
||||
}
|
||||
throw new NotInCurrentPackageException("Class " + className + " is not in the current package.");
|
||||
}
|
||||
|
||||
public ClassOrInterface getClassFromCurrPkg(String className) throws NotInCurrentPackageException {
|
||||
for (ClassOrInterface cl : sourceFile.KlassenVektor) {
|
||||
if (className.equals(cl.getClassName().toString()))
|
||||
return cl;
|
||||
}
|
||||
throw new NotInCurrentPackageException("Class of " + className + " is not in the current package.");
|
||||
}
|
||||
|
||||
public String getDesc(String className) throws NotInCurrentPackageException, NotFoundException {
|
||||
String name = methCall.name;
|
||||
ClassOrInterface clazz = getClassFromCurrPkg(className);
|
||||
String retType = getResolvedType(methCall.getType());
|
||||
ArrayList<String> params = getTypes(methCall.arglist.getArguments());
|
||||
|
||||
Map<String, String> genAndBoundsClass = getGenericsAndBounds(clazz.getGenerics());
|
||||
modifyGenAndBounds(genAndBoundsClass);
|
||||
for (Method m : clazz.getMethods()) {
|
||||
if (name.equals(m.getName()) && retType.equals(getResolvedType(m.getReturnType()))) {
|
||||
ArrayList<String> paramsOfM = getTypes(m.getParameterList());
|
||||
if(areEquals(params,paramsOfM)) {
|
||||
Map<String, String> genAndBoundsMethod = getGenericsAndBoundsMethod(m.getGenerics());
|
||||
modifyGenAndBounds(genAndBoundsMethod);
|
||||
boolean hasGen = hasGen(m, genAndBoundsClass);
|
||||
NormalMethod nm = new NormalMethod(m, (HashMap<String, String>) genAndBoundsClass,
|
||||
(HashMap<String, String>) genAndBoundsMethod, hasGen);
|
||||
return nm.accept(new DescriptorToString(resultSet));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotFoundException("Method " + name + " is not found");
|
||||
}
|
||||
|
||||
private boolean areEquals(ArrayList<String> params, ArrayList<String> paramsOfM) {
|
||||
if(params.size() != paramsOfM.size())
|
||||
return false;
|
||||
|
||||
for(String t : params) {
|
||||
for(String t2 : paramsOfM) {
|
||||
if(!t.equals(t2))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private ArrayList<String> getTypes(ParameterList parameterList) {
|
||||
Iterator<FormalParameter> itr = parameterList.iterator();
|
||||
ArrayList<String> typeList = new ArrayList<>();
|
||||
while (itr.hasNext()) {
|
||||
FormalParameter fp = itr.next();
|
||||
String t = getResolvedType(fp.getType());
|
||||
typeList.add(t);
|
||||
}
|
||||
|
||||
return typeList;
|
||||
}
|
||||
|
||||
private ArrayList<String> getTypes(List<Expression> arguments) {
|
||||
ArrayList<String> types = new ArrayList<>();
|
||||
for(int i = 0; i<arguments.size(); ++i) {
|
||||
String t = getResolvedType(arguments.get(i).getType());
|
||||
types.add(t);
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
private boolean hasGen(Method m, Map<String, String> genericsAndBounds) {
|
||||
String retType = resultSet.resolveType(m.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
|
||||
/*Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist*/
|
||||
boolean hasGenInParameterList = genericsAndBounds.containsKey(retType) || retType.contains("TPH ") || retType.contains("<");
|
||||
|
||||
Map<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes = new HashMap<>();
|
||||
Iterator<FormalParameter> itr = m.getParameterList().iterator();
|
||||
while(itr.hasNext()) {
|
||||
FormalParameter fp = itr.next();
|
||||
methodParamsAndTypes.put(fp.getName(), resultSet.resolveType(fp.getType()).resolvedType);
|
||||
}
|
||||
/*Wenn die Rückgabe-Type eine Typ-variable ist, erzeuge direkt die Signature, wenn nicht,
|
||||
* prüfe, ob einer der Parameter Typ-Variable als Typ hat*/
|
||||
if(!hasGenInParameterList) {
|
||||
for(String paramName : methodParamsAndTypes.keySet()) {
|
||||
String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToDescriptor());
|
||||
String sigOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature());
|
||||
if(genericsAndBounds.containsKey(typeOfParam)||typeOfParam.contains("TPH ")||sigOfParam.contains("<")) {
|
||||
hasGenInParameterList = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return m.getGenerics().iterator().hasNext() || hasGenInParameterList;
|
||||
}
|
||||
|
||||
private Map<String, String> getGenericsAndBoundsMethod(Iterable<? extends GenericTypeVar> generics) {
|
||||
Map<String, String> genAndBounds = new HashMap<>();
|
||||
Iterator<? extends GenericTypeVar> itr = generics.iterator();
|
||||
while (itr.hasNext()) {
|
||||
GenericTypeVar gtv = itr.next();
|
||||
getBoundsOfTypeVar(gtv, genAndBounds);
|
||||
}
|
||||
return genAndBounds;
|
||||
}
|
||||
|
||||
private void modifyGenAndBounds(Map<String, String> genAndBoundsClass) {
|
||||
List<String> visited = new ArrayList<>(genAndBoundsClass.size());
|
||||
Map<String, String> toReplace = new HashMap<>();
|
||||
for (String tv : genAndBoundsClass.keySet()) {
|
||||
|
||||
if (visited.contains(tv))
|
||||
continue;
|
||||
|
||||
List<String> types = new LinkedList<>();
|
||||
String bound = genAndBoundsClass.get(tv);
|
||||
types.add(tv);
|
||||
visited.add(tv);
|
||||
boolean doReplace = false;
|
||||
while (genAndBoundsClass.keySet().contains(bound)) {
|
||||
doReplace = true;
|
||||
types.add(bound);
|
||||
visited.add(bound);
|
||||
bound = genAndBoundsClass.get(bound);
|
||||
}
|
||||
|
||||
if (doReplace) {
|
||||
for (String tt : types) {
|
||||
toReplace.put(tt, bound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String key : toReplace.keySet()) {
|
||||
genAndBoundsClass.replace(key, toReplace.get(key));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Map<String, String> getGenericsAndBounds(GenericDeclarationList generics) {
|
||||
Map<String, String> genAndBounds = new HashMap<>();
|
||||
Iterator<GenericTypeVar> itr = generics.iterator();
|
||||
while (itr.hasNext()) {
|
||||
GenericTypeVar gtv = itr.next();
|
||||
getBoundsOfTypeVar(gtv, genAndBounds);
|
||||
}
|
||||
return genAndBounds;
|
||||
}
|
||||
|
||||
private void getBoundsOfTypeVar(GenericTypeVar g, Map<String, String> genAndBounds) {
|
||||
|
||||
Iterator<? extends RefTypeOrTPHOrWildcardOrGeneric> bItr = g.getBounds().iterator();
|
||||
while (bItr.hasNext()) {
|
||||
RefTypeOrTPHOrWildcardOrGeneric b = bItr.next();
|
||||
String boundDesc = b.acceptTV(new TypeToDescriptor());
|
||||
genAndBounds.put(g.getName(), boundDesc);
|
||||
}
|
||||
}
|
||||
|
||||
public void generateBCForFunN(String methodDescriptor) {
|
||||
ByteCodeForFunNGenerator.generateBCForFunN(methCall.arglist,methodDescriptor,path);
|
||||
}
|
||||
|
||||
public String getDescriptorOfApplyMethod(String methodCallType) {
|
||||
return new DescriptorToString().createDescForFunN(methCall.arglist, methodCallType);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param methodCall
|
||||
*/
|
||||
public void createCheckCast(MethodCall methodCall, MethodVisitor mv) {
|
||||
String checkCast = getResolvedType(methodCall.getType());
|
||||
if(!checkCast.contains("TPH ")) {
|
||||
int pos = checkCast.length();
|
||||
if(checkCast.contains("<"))
|
||||
pos = checkCast.indexOf("<");
|
||||
mv.visitTypeInsn(Opcodes.CHECKCAST,checkCast.substring(0,pos));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -23,7 +23,6 @@ public class MethodFromMethodCall {
|
||||
this.genericsAndBounds = genericsAndBounds;
|
||||
}
|
||||
|
||||
|
||||
public ArgumentList getArgList() {
|
||||
return argList;
|
||||
}
|
||||
|
@@ -1,34 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.utilities;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
|
||||
/**
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class MethodUtility {
|
||||
/**
|
||||
* Creates an ID for a method
|
||||
*
|
||||
* @param resolver type Resolver
|
||||
* @param method for which the ID will be generated
|
||||
* @return ID for the given method.
|
||||
* ID = ReturntypeMethodname(Parametertypes)
|
||||
*/
|
||||
public static String createID(Resolver resolver, Method method) {
|
||||
String id = resolver.getResolvedType(method.getReturnType()) + method.name + "(";
|
||||
Iterator<FormalParameter> itr = method.getParameterList().iterator();
|
||||
while (itr.hasNext()) {
|
||||
FormalParameter fp = itr.next();
|
||||
id += resolver.getResolvedType(fp.getType());
|
||||
}
|
||||
id += ")";
|
||||
return id;
|
||||
}
|
||||
}
|
@@ -1,145 +0,0 @@
|
||||
package de.dhbwstuttgart.bytecode.utilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.NameReplacementResult;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
||||
|
||||
public class NameReplacer {
|
||||
//TODO rename
|
||||
private List<TPHConstraint> constraints;
|
||||
private List<TPHConstraint> allConstraints;
|
||||
private List<MethodAndTPH> methodAndTPHs;
|
||||
// TODO rename into tphClass
|
||||
private List<String> tphs;
|
||||
private List<String> localTphs;
|
||||
|
||||
public NameReplacer(List<TPHConstraint> constraints, List<TPHConstraint> allConstraints,List<String> tphs, ArrayList<String> localTphs) {
|
||||
super();
|
||||
this.constraints = constraints;
|
||||
this.allConstraints = allConstraints;
|
||||
this.tphs = tphs;
|
||||
this.localTphs = localTphs;
|
||||
}
|
||||
|
||||
public NameReplacer(List<TPHConstraint> constraints, List<TPHConstraint> allConstraints,List<String> tphs) {
|
||||
super();
|
||||
this.constraints = constraints;
|
||||
this.allConstraints = allConstraints;
|
||||
this.tphs = tphs;
|
||||
}
|
||||
|
||||
public NameReplacer(List<TPHConstraint> constraints, List<TPHConstraint> allConstraints) {
|
||||
this.constraints = constraints;
|
||||
this.allConstraints = allConstraints;
|
||||
}
|
||||
|
||||
public NameReplacer(List<TPHConstraint> constraints, List<TPHConstraint> allConstraints, List<MethodAndTPH> methodAndTPHs,
|
||||
List<String> tphsClass) {
|
||||
this.constraints = constraints;
|
||||
this.allConstraints = allConstraints;
|
||||
this.methodAndTPHs = methodAndTPHs;
|
||||
this.tphs = tphsClass;
|
||||
}
|
||||
|
||||
public NameReplacementResult replaceNames() {
|
||||
String newName = NameGenerator.makeNewName();
|
||||
List<String> names = new ArrayList<>();
|
||||
substituteRightSidesWithNewName(newName, names);
|
||||
|
||||
substituteNamesInAllConstraints(newName, names);
|
||||
Stream<ArrayList<String>> tphsOfMethods = methodAndTPHs.stream().map(m->m.getTphs());
|
||||
Stream<ArrayList<String>> localTphsOfMethods = methodAndTPHs.stream().map(m->m.getLocalTphs());
|
||||
|
||||
replaceOldNames(newName, names, tphsOfMethods);
|
||||
replaceOldNames(newName, names, localTphsOfMethods);
|
||||
|
||||
if(tphs.removeAll(names))
|
||||
tphs.add(newName);
|
||||
|
||||
NameReplacementResult res = new NameReplacementResult(newName, names);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param newName
|
||||
* @param names
|
||||
* @param tphsOfMethods
|
||||
*/
|
||||
public void replaceOldNames(final String newName, final List<String> names, Stream<ArrayList<String>> tphsOfMethods) {
|
||||
tphsOfMethods.forEach(tphsMethod->{
|
||||
if(tphsMethod.removeAll(names))
|
||||
tphsMethod.add(newName);
|
||||
});
|
||||
}
|
||||
|
||||
public NameReplacementResult replaceNamesLocal() {
|
||||
String newName = NameGenerator.makeNewName();
|
||||
List<String> names = new ArrayList<>();
|
||||
substituteRightSidesWithNewName(newName, names);
|
||||
|
||||
substituteNamesInAllConstraints(newName, names);
|
||||
|
||||
tphs.removeAll(names);
|
||||
tphs.add(newName);
|
||||
|
||||
NameReplacementResult res = new NameReplacementResult(newName, names);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param newName
|
||||
* @param names
|
||||
*/
|
||||
public void substituteNamesInAllConstraints(String newName, List<String> names) {
|
||||
for(TPHConstraint cons : allConstraints) {
|
||||
if(names.contains(cons.getLeft()))
|
||||
cons.setLeft(newName);
|
||||
if(names.contains(cons.getRight()))
|
||||
cons.setRight(newName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param newName
|
||||
* @param names
|
||||
*/
|
||||
public void substituteRightSidesWithNewName(String newName, List<String> names) {
|
||||
for(TPHConstraint cons : constraints) {
|
||||
names.add(cons.getRight());
|
||||
cons.setRight(newName);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, List<String>> replaceNamesWithLocals() {
|
||||
String newName = NameGenerator.makeNewName();
|
||||
ArrayList<String> names = new ArrayList<>();
|
||||
for(TPHConstraint cons : constraints) {
|
||||
names.add(cons.getRight());
|
||||
cons.setRight(newName);
|
||||
}
|
||||
|
||||
for(TPHConstraint cons : allConstraints) {
|
||||
if(names.contains(cons.getLeft()))
|
||||
cons.setLeft(newName);
|
||||
if(names.contains(cons.getRight()))
|
||||
cons.setRight(newName);
|
||||
}
|
||||
|
||||
tphs.removeAll(names);
|
||||
tphs.add(newName);
|
||||
localTphs.removeAll(names);
|
||||
localTphs.add(newName);
|
||||
|
||||
HashMap<String, List<String>> res = new HashMap<>();
|
||||
res.put(newName, names);
|
||||
return res;
|
||||
}
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.utilities;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
|
||||
/**
|
||||
* @author fayez
|
||||
*
|
||||
*/
|
||||
public class Resolver {
|
||||
|
||||
private ResultSet resultSet;
|
||||
|
||||
/**
|
||||
* @param resultSet
|
||||
*/
|
||||
public Resolver(ResultSet resultSet) {
|
||||
this.resultSet = resultSet;
|
||||
}
|
||||
|
||||
public String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||
return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
}
|
||||
}
|
651
src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java
Normal file
651
src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java
Normal file
@@ -0,0 +1,651 @@
|
||||
package de.dhbwstuttgart.bytecode.utilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.TPHExtractor;
|
||||
import de.dhbwstuttgart.bytecode.constraint.EqualConstraint;
|
||||
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
|
||||
public class Simplify {
|
||||
|
||||
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraints(String name, TPHExtractor tphExtractor, ArrayList<TypePlaceholder> tphsClass) {
|
||||
// 1. check if there are any simple cycles like L<R and R<L:
|
||||
// a) yes => set L=R and:
|
||||
// * remove both constraints
|
||||
// * substitute L with R in all constraint
|
||||
// b)no => go to next step
|
||||
// 2. check the result of step 1 if there are any equal-constraints like L=R, M=R ..
|
||||
// a) yes => put all such TPhs in a map and define "key-Cons"
|
||||
// -- key-Cons = TPH < Object --
|
||||
// put this Constraint and the
|
||||
// b) no
|
||||
// 3. is
|
||||
|
||||
// all constraints that will be simplified
|
||||
ArrayList<TPHConstraint> allCons = tphExtractor.allCons;
|
||||
ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
|
||||
|
||||
// step 1:
|
||||
for(TPHConstraint c : allCons) {
|
||||
|
||||
String left = c.getLeft();
|
||||
String right = c.getRight();
|
||||
if(c.getRel() == Relation.EXTENDS) {
|
||||
TPHConstraint revCon = getReverseConstraint(allCons,left,right);
|
||||
if(revCon != null) {
|
||||
revCon.setRel(Relation.EQUAL);
|
||||
// the reverse constraint is removed because
|
||||
// otherwise there is the same constraint twice
|
||||
// (e.g. A<B and B<A => A=B and B=A)
|
||||
consToRemove.add(revCon);
|
||||
c.setRel(Relation.EQUAL);
|
||||
substituteTPH(allCons,left, right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println();
|
||||
System.out.println("NEW ALL CONST: " + allCons.size());
|
||||
allCons.forEach(c->System.out.println(c.toString()));
|
||||
System.out.println("----------------");
|
||||
allCons.removeAll(consToRemove);
|
||||
consToRemove = new ArrayList<>();
|
||||
|
||||
int size = allCons.size();
|
||||
|
||||
System.out.println("AFTER DELETE ALL CONST: " + allCons.size());
|
||||
allCons.forEach(c->System.out.println(c.toString()));
|
||||
System.out.println("----------------");
|
||||
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
|
||||
|
||||
// check if there is any long cycle (e.g. A<B<C<A)
|
||||
|
||||
// to save all types that are in relation
|
||||
LinkedList<String> allTypes = new LinkedList<>();
|
||||
// we will put all constraints which are in the cycle, in this ArrayList.
|
||||
// Later these contraints will be converted to equal-constraints
|
||||
ArrayList<TPHConstraint> constraints = new ArrayList<>(size);
|
||||
int visited = 0;
|
||||
|
||||
// contains all constraints
|
||||
HashMap<String,String> ss1 = new HashMap<>();
|
||||
|
||||
for(TPHConstraint constr : allCons) {
|
||||
ss1.put(constr.getLeft(), constr.getRight());
|
||||
}
|
||||
|
||||
for(TPHConstraint c : allCons) {
|
||||
|
||||
if(visited >= size)
|
||||
break;
|
||||
// Only extends-constraints will be checked
|
||||
if(c.getRel() == Relation.EXTENDS) {
|
||||
++visited;
|
||||
|
||||
String left = c.getLeft();
|
||||
String right = c.getRight();
|
||||
// put the types in linked list
|
||||
allTypes.add(left);
|
||||
allTypes.add(right);
|
||||
|
||||
constraints.add(c);
|
||||
|
||||
boolean isCycle = false;
|
||||
|
||||
// iterate through the map to check if there is a cycle
|
||||
while(ss1.containsKey(right)) {
|
||||
++visited;
|
||||
String oldRight = right;
|
||||
right = ss1.get(right);
|
||||
|
||||
TPHConstraint toAdd = getConstraint(oldRight, right, allCons);
|
||||
|
||||
if(toAdd != null)
|
||||
constraints.add(toAdd);
|
||||
|
||||
if(left.equals(right)) {
|
||||
isCycle = true;
|
||||
break;
|
||||
}
|
||||
|
||||
allTypes.add(right);
|
||||
}
|
||||
|
||||
if(isCycle) {
|
||||
// convert all constraints to equal constraints
|
||||
setAllEqual(constraints);
|
||||
// these constraints will be removed from allCons
|
||||
consToRemove.addAll(constraints);
|
||||
// all equal types will be substitute with one type
|
||||
substituteAllTPH(allCons,constraints,left);
|
||||
|
||||
HashSet<String> eq = new HashSet<>();
|
||||
// put all equal types in a set
|
||||
for(String t:allTypes) {
|
||||
eq.add(t);
|
||||
}
|
||||
// generate a new constraint (left < Object)
|
||||
TPHConstraint constraint = new ExtendsConstraint(left, Type.getInternalName(Object.class), Relation.EXTENDS);
|
||||
// put the generated constraint and its equal set into result set
|
||||
result.put(constraint, eq);
|
||||
constraints.clear();
|
||||
}
|
||||
allTypes.clear();
|
||||
}
|
||||
}
|
||||
// build an equal set that contains all types
|
||||
// which are equal and for each equal constraint put left side and right side
|
||||
// in this set Then generate a constraint type < Object and put it
|
||||
// with the equal set into the result.
|
||||
for(TPHConstraint c : allCons) {
|
||||
if(c.getRel()==Relation.EQUAL) {
|
||||
if(!isTPHInResEqual(result, c.getLeft())) {
|
||||
HashSet<String> equalTPHs = getEqualsTPHs(result, c);
|
||||
TPHConstraint constraint = getKeyConstraint(result,c);
|
||||
equalTPHs.add(c.getLeft());
|
||||
equalTPHs.add(c.getRight());
|
||||
result.put(constraint, equalTPHs);
|
||||
}
|
||||
consToRemove.add(c);
|
||||
size--;
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Step 2 Result: ");
|
||||
result.forEach((c,hs)->{
|
||||
System.out.print(c.toString() + " -> ");
|
||||
hs.forEach(s->{
|
||||
System.out.print(s + ", ");
|
||||
});
|
||||
System.out.println();
|
||||
});
|
||||
System.out.println("----------------");
|
||||
// remove all equal-constraints
|
||||
allCons.removeAll(consToRemove);
|
||||
// add all generated constraints to allCons
|
||||
allCons.addAll(result.keySet());
|
||||
|
||||
if(!allCons.isEmpty() && allCons.size()<2) {
|
||||
TPHConstraint cons = allCons.get(0);
|
||||
if(!result.containsKey(cons)) {
|
||||
result.put(cons, null);
|
||||
result.put(new ExtendsConstraint(cons.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
size += result.keySet().size();
|
||||
// all constraints which have Object on the right side will
|
||||
// be ignored, because they are simplified and can not be changed.
|
||||
for(TPHConstraint c : allCons) {
|
||||
if(c.getRight().equals(Type.getInternalName(Object.class)))
|
||||
size--;
|
||||
}
|
||||
// get all tph of the method
|
||||
ArrayList<String> methodTphs = new ArrayList<>();
|
||||
for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
|
||||
if(m.getName().equals(name)) {
|
||||
methodTphs = m.getTphs();
|
||||
break;
|
||||
}
|
||||
}
|
||||
// check if there are multiple constraint with the same left side.
|
||||
// if yes => check if the super type in the method, if not
|
||||
// then ignore it.
|
||||
HashMap<String, String> subAndSuper = new HashMap<>();
|
||||
ArrayList<TPHConstraint> eqCons = new ArrayList<>();
|
||||
for(TPHConstraint c : allCons) {
|
||||
if(subAndSuper.containsKey(c.getLeft())) {
|
||||
LinkedList<String> all = new LinkedList<>();
|
||||
all.add(c.getLeft());
|
||||
String sup =c.getRight();
|
||||
all.add(sup);
|
||||
HashMap<String, String> ss = new HashMap<>();
|
||||
for(TPHConstraint constr : allCons) {
|
||||
ss.put(constr.getLeft(), constr.getRight());
|
||||
}
|
||||
while(ss.containsKey(sup)) {
|
||||
sup = ss.get(sup);
|
||||
all.add(sup);
|
||||
}
|
||||
if(!containTPH(methodTphs, all.getLast()))
|
||||
continue;
|
||||
}
|
||||
if(subAndSuper.containsKey(c.getLeft())) {
|
||||
System.out.println(c.getLeft());
|
||||
String r = c.getRight();
|
||||
String r2 = subAndSuper.get(c.getLeft());
|
||||
EqualConstraint eq = new EqualConstraint(r2, r, Relation.EQUAL);
|
||||
eqCons.add(eq);
|
||||
substituteInMap(subAndSuper,eqCons,allCons,r,r2);
|
||||
}
|
||||
subAndSuper.put(c.getLeft(), c.getRight());
|
||||
}
|
||||
|
||||
System.out.println("SAME LEFT SIDE: ");
|
||||
subAndSuper.forEach((c,hs)->{
|
||||
if(c!=null) {
|
||||
System.out.print(c+ " -> " + hs);
|
||||
|
||||
}
|
||||
|
||||
|
||||
System.out.println();
|
||||
});
|
||||
System.out.println("----------------");
|
||||
int numOfVisitedPairs = 0;
|
||||
for(String sub : subAndSuper.keySet()) {
|
||||
if(isTPHInConstraint(result,sub))
|
||||
continue;
|
||||
|
||||
if(!containTPH(methodTphs,sub))
|
||||
continue;
|
||||
|
||||
if(numOfVisitedPairs>=size)
|
||||
break;
|
||||
LinkedList<String> tphInRel = new LinkedList<>();
|
||||
tphInRel.add(sub);
|
||||
String superT = subAndSuper.get(sub);
|
||||
tphInRel.add(superT);
|
||||
|
||||
numOfVisitedPairs++;
|
||||
while(subAndSuper.containsKey(superT)) {
|
||||
superT = subAndSuper.get(superT);
|
||||
if(tphInRel.contains(superT)) {
|
||||
break;
|
||||
}
|
||||
tphInRel.add(superT);
|
||||
numOfVisitedPairs++;
|
||||
}
|
||||
|
||||
// Subtype
|
||||
String subTphRes = tphInRel.getFirst();
|
||||
// Die größte Supertype
|
||||
String superTphRes = tphInRel.getLast();
|
||||
|
||||
// if there is any constraint X < subTph, then
|
||||
// add X at the beginning of the list.
|
||||
while(subAndSuper.containsValue(subTphRes)) {
|
||||
for(String tph : subAndSuper.keySet()) {
|
||||
if(containTPH(methodTphs,tph) && subAndSuper.get(tph).equals(subTphRes)) {
|
||||
subTphRes = tph;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(subTphRes.equals(tphInRel.getFirst())) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(isTPHInConstraint(result, subTphRes))
|
||||
break;
|
||||
|
||||
tphInRel.addFirst(subTphRes);
|
||||
numOfVisitedPairs++;
|
||||
}
|
||||
|
||||
subTphRes = tphInRel.getFirst();
|
||||
// if the last type in the list not a type in method-types
|
||||
// then find the last type in front of this type, which is
|
||||
// a type in method-types
|
||||
int i = 2;
|
||||
while(!containTPH(methodTphs,superTphRes) && (tphInRel.size()-i) >0) {
|
||||
superTphRes = tphInRel.get(tphInRel.size()-i);
|
||||
i++;
|
||||
}
|
||||
|
||||
if(!containTPH(methodTphs, superTphRes)) {
|
||||
HashSet<String> equals = getEqualsTphsFromEqualCons(eqCons,superTphRes);
|
||||
if(classTPHSContainsTPH(tphsClass,superTphRes)) {
|
||||
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals);
|
||||
} else {
|
||||
result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), equals);
|
||||
}
|
||||
|
||||
} else {
|
||||
HashSet<String> equals = getEqualsTphsFromEqualCons(eqCons,subTphRes);
|
||||
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals);
|
||||
if(!isTPHInConstraint(result, superTphRes) && !isTphInEqualSet(result,superTphRes)) {
|
||||
HashSet<String> equals2 = getEqualsTphsFromEqualCons(eqCons,superTphRes);
|
||||
result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), equals2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(String tph : methodTphs) {
|
||||
if(!isTPHInConstraint(result, tph) && !isTphInEqualSet(result,tph)) {
|
||||
HashSet<String> equals = getEqualsTphsFromEqualCons(eqCons,tph);
|
||||
result.put(new ExtendsConstraint(tph, Type.getInternalName(Object.class), Relation.EXTENDS), equals);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("EndResult: ");
|
||||
result.forEach((c,hs)->{
|
||||
if(c!=null) {
|
||||
System.out.print(c.toString() + " -> ");
|
||||
if(hs == null) {
|
||||
System.out.print(" [] ");
|
||||
}else {
|
||||
hs.forEach(s->{
|
||||
System.out.print(s + ", ");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
System.out.println();
|
||||
});
|
||||
System.out.println("----------------");
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean classTPHSContainsTPH(ArrayList<TypePlaceholder> tphsClass, String superTphRes) {
|
||||
for(TypePlaceholder tph : tphsClass) {
|
||||
if(tph.getName().equals(superTphRes))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isTphInEqualSet(HashMap<TPHConstraint, HashSet<String>> result, String tph) {
|
||||
for(HashSet<String> hs: result.values()) {
|
||||
if(hs.contains(tph))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static HashSet<String> getEqualsTphsFromEqualCons(ArrayList<TPHConstraint> eqCons, String tph) {
|
||||
HashSet<String> ee = new HashSet<>();
|
||||
for(TPHConstraint c : eqCons) {
|
||||
if(c.getLeft().equals(tph))
|
||||
ee.add(c.getRight());
|
||||
if(c.getRight().equals(tph))
|
||||
ee.add(c.getLeft());
|
||||
}
|
||||
return ee;
|
||||
}
|
||||
|
||||
private static void substituteInMap(HashMap<String, String> subAndSuper, ArrayList<TPHConstraint> allCons,ArrayList<TPHConstraint> eqCons, String toSubs,
|
||||
String tph) {
|
||||
substituteTPH(allCons, toSubs, tph);
|
||||
if(subAndSuper.containsKey(toSubs) && subAndSuper.containsKey(tph)) {
|
||||
toSubs = subAndSuper.remove(toSubs);
|
||||
EqualConstraint eq = new EqualConstraint(subAndSuper.get(tph), toSubs, Relation.EQUAL);
|
||||
eqCons.add(eq);
|
||||
substituteInMap(subAndSuper, allCons,eqCons,toSubs, subAndSuper.get(tph));
|
||||
} else if(subAndSuper.containsKey(toSubs) && !subAndSuper.containsKey(tph)) {
|
||||
String val = subAndSuper.remove(toSubs);
|
||||
subAndSuper.put(tph, val);
|
||||
} else {
|
||||
for(String k : subAndSuper.keySet()) {
|
||||
subAndSuper.replace(k, toSubs, tph);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static TPHConstraint getConstraint(String oldRight, String right, ArrayList<TPHConstraint> allCons) {
|
||||
for(TPHConstraint c : allCons) {
|
||||
if(c.getLeft().equals(oldRight) && c.getRight().equals(right))
|
||||
return c;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isTPHInResEqual(HashMap<TPHConstraint, HashSet<String>> result, String left) {
|
||||
for(HashSet<String> eq : result.values()) {
|
||||
if(eq.contains(left)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void substituteAllTPH(ArrayList<TPHConstraint> allCons, ArrayList<TPHConstraint> constraints,
|
||||
String first) {
|
||||
for(TPHConstraint c : allCons) {
|
||||
for(TPHConstraint c2 : constraints) {
|
||||
if(c.getRel() == Relation.EXTENDS) {
|
||||
if(c2.getLeft().equals(c.getLeft()) || c2.getRight().equals(c.getLeft()))
|
||||
c.setLeft(first);
|
||||
if(c2.getLeft().equals(c.getRight()) || c2.getRight().equals(c.getRight()))
|
||||
c.setRight(first);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void setAllEqual(ArrayList<TPHConstraint> constraints) {
|
||||
for(TPHConstraint c:constraints) {
|
||||
c.setRel(Relation.EQUAL);
|
||||
}
|
||||
}
|
||||
|
||||
public static HashMap<TPHConstraint, HashSet<String>> simplifyContraints(HashMap<TPHConstraint, HashSet<String>> allConstraints) {
|
||||
// 1. check if there are any cycles like L<R and R<L:
|
||||
// a) yes => set L=R and:
|
||||
// * remove both constraints
|
||||
// * substitute L with R in all constraint
|
||||
// b)no => go to next step
|
||||
// 2. check the result of step 1 if there are any equal-constraints like L=R, M=R ..
|
||||
// a) yes => put all such TPhs in a map and define "key-Cons"
|
||||
// -- key-Cons = TPH < Object --
|
||||
// put this Constraint and the
|
||||
// b) no
|
||||
// 3. is
|
||||
ArrayList<TPHConstraint> allCons = new ArrayList<>();
|
||||
for(TPHConstraint tphCons : allConstraints.keySet()) {
|
||||
allCons.add(tphCons);
|
||||
}
|
||||
ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
|
||||
// step 1:
|
||||
for(TPHConstraint c : allCons) {
|
||||
|
||||
String left = c.getLeft();
|
||||
String right = c.getRight();
|
||||
if(c.getRel() == Relation.EXTENDS) {
|
||||
TPHConstraint revCon = getReverseConstraint(allCons,left,right);
|
||||
if(revCon != null) {
|
||||
revCon.setRel(Relation.EQUAL);
|
||||
consToRemove.add(revCon);
|
||||
c.setRel(Relation.EQUAL);
|
||||
substituteTPH(allCons,left, right);
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
System.out.println("NEW ALL CONST: " + allCons.size());
|
||||
allCons.forEach(c->System.out.println(c.toString()));
|
||||
System.out.println("----------------");
|
||||
allCons.removeAll(consToRemove);
|
||||
consToRemove = new ArrayList<>();
|
||||
|
||||
// int size = allCons.size();
|
||||
|
||||
System.out.println("AFTER DELETE ALL CONST: " + allCons.size());
|
||||
allCons.forEach(c->System.out.println(c.toString()));
|
||||
System.out.println("----------------");
|
||||
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
|
||||
|
||||
for(TPHConstraint c : allCons) {
|
||||
if(c.getRel()==Relation.EQUAL) {
|
||||
HashSet<String> equalTPHs = getEqualsTPHs(result, c);
|
||||
TPHConstraint constraint = getKeyConstraint(result,c);
|
||||
equalTPHs.add(c.getLeft());
|
||||
equalTPHs.add(c.getRight());
|
||||
result.put(constraint, equalTPHs);
|
||||
consToRemove.add(c);
|
||||
// size--;
|
||||
}
|
||||
}
|
||||
System.out.println("Step 2 Result: ");
|
||||
result.forEach((c,hs)->{
|
||||
System.out.print(c.toString() + " -> ");
|
||||
hs.forEach(s->{
|
||||
System.out.print(s + ", ");
|
||||
});
|
||||
System.out.println();
|
||||
});
|
||||
System.out.println("----------------");
|
||||
allCons.removeAll(consToRemove);
|
||||
allCons.addAll(result.keySet());
|
||||
|
||||
if(!allCons.isEmpty() && allCons.size()<2) {
|
||||
|
||||
if(!result.containsKey(allCons.get(0)))
|
||||
result.put(allCons.get(0), null);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// size += result.keySet().size();
|
||||
|
||||
// for(TPHConstraint c : allCons) {
|
||||
// if(c.getRight().equals(Type.getInternalName(Object.class)))
|
||||
// size--;
|
||||
// }
|
||||
|
||||
HashMap<String, String> subAndSuper = new HashMap<>();
|
||||
|
||||
for(TPHConstraint c : allCons) {
|
||||
subAndSuper.put(c.getLeft(), c.getRight());
|
||||
}
|
||||
|
||||
// int numOfVisitedPairs = 0;
|
||||
for(String sub : subAndSuper.keySet()) {
|
||||
if(isTPHInConstraint(result,sub))
|
||||
continue;
|
||||
|
||||
// if(numOfVisitedPairs>=size)
|
||||
// break;
|
||||
|
||||
LinkedList<String> tphInRel = new LinkedList<>();
|
||||
tphInRel.add(sub);
|
||||
String superT = subAndSuper.get(sub);
|
||||
tphInRel.add(superT);
|
||||
|
||||
// numOfVisitedPairs++;
|
||||
while(subAndSuper.containsKey(superT)) {
|
||||
superT = subAndSuper.get(superT);
|
||||
if(tphInRel.contains(superT)) {
|
||||
break;
|
||||
}
|
||||
tphInRel.add(superT);
|
||||
// numOfVisitedPairs++;
|
||||
}
|
||||
|
||||
// Subtype
|
||||
String subTphRes = tphInRel.getFirst();
|
||||
// Die größte Supertype
|
||||
String superTphRes = tphInRel.getLast();
|
||||
|
||||
while(subAndSuper.containsValue(subTphRes)) {
|
||||
for(String tph : subAndSuper.keySet()) {
|
||||
if(subAndSuper.get(tph).equals(subTphRes)) {
|
||||
subTphRes = tph;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(subTphRes.equals(tphInRel.getFirst())) {
|
||||
break;
|
||||
}
|
||||
tphInRel.addFirst(subTphRes);
|
||||
// numOfVisitedPairs++;
|
||||
}
|
||||
|
||||
subTphRes = tphInRel.getFirst();
|
||||
|
||||
int i = 2;
|
||||
while(superTphRes.equals(Type.getInternalName(Object.class)) && (tphInRel.size()-i) >0) {
|
||||
superTphRes = tphInRel.get(tphInRel.size()-i);
|
||||
i++;
|
||||
}
|
||||
if(superTphRes.equals(Type.getInternalName(Object.class))) {
|
||||
result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
||||
} else {
|
||||
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), null);
|
||||
result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
||||
}
|
||||
|
||||
}
|
||||
System.out.println("EndResult: ");
|
||||
result.forEach((c,hs)->{
|
||||
if(c!=null) {
|
||||
System.out.print(c.toString() + " -> ");
|
||||
if(hs == null) {
|
||||
System.out.print(" [] ");
|
||||
}else {
|
||||
hs.forEach(s->{
|
||||
System.out.print(s + ", ");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
System.out.println();
|
||||
});
|
||||
System.out.println("----------------");
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void substituteTPH(ArrayList<TPHConstraint> allCons,String left ,String right) {
|
||||
allCons.forEach(c->{
|
||||
if(c.getRel() == Relation.EXTENDS) {
|
||||
if(c.getLeft().equals(left))
|
||||
c.setLeft(right);
|
||||
if(c.getRight().equals(left))
|
||||
c.setRight(right);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static TPHConstraint getReverseConstraint(ArrayList<TPHConstraint> allCons, String left, String right) {
|
||||
for(TPHConstraint c : allCons) {
|
||||
if(c.getLeft().equals(right) && c.getRight().equals(left)){
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isTPHInConstraint(HashMap<TPHConstraint, HashSet<String>> result, String sub) {
|
||||
for(TPHConstraint c : result.keySet()) {
|
||||
if(c.getLeft().equals(sub))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean containTPH(ArrayList<String> methodTphs, String sub) {
|
||||
for(String tph : methodTphs) {
|
||||
if(tph.equals(sub))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static TPHConstraint getKeyConstraint(HashMap<TPHConstraint, HashSet<String>> result, TPHConstraint toFind) {
|
||||
for(TPHConstraint c : result.keySet()) {
|
||||
if(c.containTPH(toFind.getLeft()) || c.containTPH(toFind.getRight()))
|
||||
return c;
|
||||
}
|
||||
return new ExtendsConstraint(toFind.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS);
|
||||
}
|
||||
|
||||
private static HashSet<String> getEqualsTPHs(HashMap<TPHConstraint,HashSet<String>> result, TPHConstraint toFind) {
|
||||
for(TPHConstraint c : result.keySet()) {
|
||||
if(c.containTPH(toFind.getLeft()) || c.containTPH(toFind.getRight()))
|
||||
return result.get(c);
|
||||
}
|
||||
return new HashSet<>();
|
||||
}
|
||||
}
|
@@ -2,7 +2,6 @@ package de.dhbwstuttgart.core;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -10,29 +9,8 @@ public class ConsoleInterface {
|
||||
private static final String directory = System.getProperty("user.dir");
|
||||
|
||||
public static void main(String[] args) throws IOException, ClassNotFoundException {
|
||||
List<File> input = new ArrayList<>();
|
||||
List<File> classpath = new ArrayList<>();
|
||||
String outputPath = null;
|
||||
Iterator<String> it = Arrays.asList(args).iterator();
|
||||
while(it.hasNext()){
|
||||
String arg = it.next();
|
||||
if(arg.equals("-d")){
|
||||
outputPath = it.next();
|
||||
}else if(arg.startsWith("-d")) {
|
||||
outputPath = arg.substring(2);
|
||||
}else if(arg.equals("-cp") || arg.equals("-classpath")){
|
||||
String[] cps = it.next().split(":");
|
||||
for(String cp : cps){
|
||||
classpath.add(new File(cp));
|
||||
}
|
||||
}else{
|
||||
input.add(new File(arg));
|
||||
}
|
||||
}
|
||||
JavaTXCompiler compiler = new JavaTXCompiler(input, classpath);
|
||||
List<File> input = Arrays.asList(args).stream().map((s -> new File(s))).collect(Collectors.toList());
|
||||
JavaTXCompiler compiler = new JavaTXCompiler(input);
|
||||
compiler.typeInference();
|
||||
compiler.generateBytecode(outputPath);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -4,12 +4,18 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.*;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
import org.reflections.Reflections;
|
||||
import org.reflections.scanners.ResourcesScanner;
|
||||
import org.reflections.scanners.SubTypesScanner;
|
||||
import org.reflections.util.ClasspathHelper;
|
||||
import org.reflections.util.ConfigurationBuilder;
|
||||
import org.reflections.util.FilterBuilder;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.parser.JavaTXParser;
|
||||
@@ -43,7 +49,8 @@ public class CompilationEnvironment {
|
||||
*
|
||||
*/
|
||||
//String bootClassPath = System.getProperty("sun.boot.class.path");
|
||||
// DirectoryClassLoader cl = DirectoryClassLoader.getPlatformClassLoader();
|
||||
// ClassLoader cl = ClassLoader.getPlatformClassLoader();
|
||||
ClassLoader cl = ClassLoader.getSystemClassLoader();
|
||||
String bootClassPath = System.getProperty("java.class.path");
|
||||
librarys = new ArrayList<>();
|
||||
for(String path : bootClassPath.split(File.pathSeparator)) {
|
||||
@@ -60,44 +67,13 @@ public class CompilationEnvironment {
|
||||
this.packageCrawler = new PackageCrawler(librarys);
|
||||
}
|
||||
|
||||
public JavaClassRegistry getRegistry(File forSourceFile, DirectoryClassLoader classLoader) throws ClassNotFoundException, IOException {
|
||||
public JavaClassRegistry getRegistry(File forSourceFile) throws ClassNotFoundException, IOException {
|
||||
Map<String, Integer> allNames;
|
||||
CompilationUnitContext tree = JavaTXParser.parse(forSourceFile);
|
||||
allNames = GatherNames.getNames(tree, packageCrawler, classLoader);
|
||||
for(Class c : loadDefaultPackageClasses(forSourceFile, classLoader)){
|
||||
allNames.put(c.getName(), c.getTypeParameters().length);
|
||||
}
|
||||
allNames = GatherNames.getNames(tree, packageCrawler);
|
||||
return new JavaClassRegistry(allNames);
|
||||
}
|
||||
|
||||
public static List<Class> loadDefaultPackageClasses(File forSourceFile, DirectoryClassLoader classLoader) throws IOException, ClassNotFoundException {
|
||||
List<Class> ret = new ArrayList<>();
|
||||
String packageName = getPackageName(JavaTXParser.parse(forSourceFile));
|
||||
//Set classLoader to include default package for this specific source file
|
||||
File dir = new File(forSourceFile.getAbsoluteFile().getParent());
|
||||
String dirPath = dir.toString() + "/";
|
||||
if(packageName.length()>0)dirPath = dirPath.substring(0,dirPath.length() - packageName.length());
|
||||
String path = dirPath;
|
||||
ArrayList<File> defaultPath = Lists.newArrayList(new File(path));
|
||||
classLoader = new DirectoryClassLoader(defaultPath, classLoader);
|
||||
//Gather all names in the default package for this source file (classes that are imported by default)
|
||||
File [] files = dir.listFiles((dir1, name) -> name.endsWith(".class"));
|
||||
if(files != null)for (File classFile : files) {
|
||||
String className = classFile.getName().substring(0,classFile.getName().length()-6);
|
||||
ret.add(classLoader.loadClass(packageName + className));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static String getPackageName(CompilationUnitContext forTree){
|
||||
String packageName = "";
|
||||
if(forTree.packageDeclaration() != null && forTree.packageDeclaration().Identifier() != null)
|
||||
for(TerminalNode subPackage : forTree.packageDeclaration().Identifier()){
|
||||
packageName += subPackage.toString() + ".";
|
||||
}
|
||||
return packageName;
|
||||
}
|
||||
|
||||
public List<ClassOrInterface> getAllAvailableClasses() {
|
||||
List<ClassOrInterface> ret = new ArrayList<>();
|
||||
for(Class c : new PackageCrawler(librarys).getAllAvailableClasses()){
|
||||
|
@@ -1,45 +0,0 @@
|
||||
package de.dhbwstuttgart.environment;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class DirectoryClassLoader {
|
||||
private final URLClassLoader classLoader;
|
||||
|
||||
public DirectoryClassLoader(File directory, java.lang.ClassLoader parent) {
|
||||
classLoader = new URLClassLoader(generateURLArray(dirToURL(directory)), parent);
|
||||
}
|
||||
|
||||
public DirectoryClassLoader(List<File> directory, java.lang.ClassLoader parent) {
|
||||
classLoader = new URLClassLoader(directory.stream().map(DirectoryClassLoader::dirToURL).collect(Collectors.toList()).toArray(new URL[0]), parent);
|
||||
}
|
||||
|
||||
public DirectoryClassLoader(File directory, DirectoryClassLoader parent) {
|
||||
classLoader = new URLClassLoader(generateURLArray(dirToURL(directory)), parent.classLoader);
|
||||
}
|
||||
|
||||
public DirectoryClassLoader(List<File> directory, DirectoryClassLoader parent) {
|
||||
classLoader = new URLClassLoader(directory.stream().map(DirectoryClassLoader::dirToURL).collect(Collectors.toList()).toArray(new URL[0]), parent.classLoader);
|
||||
}
|
||||
|
||||
private static URL[] generateURLArray(URL url) {
|
||||
return new URL[]{url};
|
||||
}
|
||||
|
||||
private static URL dirToURL(File url){
|
||||
if(!url.isDirectory())throw new RuntimeException(url.toString() + " is not a directory");
|
||||
try {
|
||||
return url.toURI().toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Class loadClass(String className) throws ClassNotFoundException {
|
||||
return classLoader.loadClass(className);
|
||||
}
|
||||
}
|
@@ -26,11 +26,11 @@ public class PackageCrawler {
|
||||
|
||||
public Set<Class<?>> getClassesInPackage(String packageName){
|
||||
/*
|
||||
List<DirectoryClassLoader> classLoadersList = new LinkedList<DirectoryClassLoader>();
|
||||
List<ClassLoader> classLoadersList = new LinkedList<ClassLoader>();
|
||||
classLoadersList.add(Thread.currentThread().getContextClassLoader());
|
||||
classLoadersList.add(ClasspathHelper.staticClassLoader());
|
||||
classLoadersList.add(Thread.currentThread().getContextClassLoader().getParent());
|
||||
classLoadersList.add(DirectoryClassLoader.getSystemClassLoader());
|
||||
classLoadersList.add(ClassLoader.getSystemClassLoader());
|
||||
String bootClassPath = System.getProperty("sun.boot.class.path");
|
||||
ArrayList<URL> urlList = new ArrayList<>();
|
||||
for(String path : bootClassPath.split(";")) {
|
||||
@@ -41,7 +41,7 @@ public class PackageCrawler {
|
||||
}
|
||||
}
|
||||
URL[] urls = urlList.toArray(new URL[0]);
|
||||
classLoadersList.add(new URLClassLoader(urls, DirectoryClassLoader.getSystemClassLoader()));
|
||||
classLoadersList.add(new URLClassLoader(urls, ClassLoader.getSystemClassLoader()));
|
||||
*/
|
||||
Reflections reflections = new Reflections(new ConfigurationBuilder()
|
||||
.setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner())
|
||||
|
@@ -1,6 +1,5 @@
|
||||
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
|
||||
|
||||
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
@@ -23,16 +22,16 @@ public class FCGenerator {
|
||||
*
|
||||
* @param availableClasses - Alle geparsten Klassen
|
||||
*/
|
||||
public static Set<UnifyPair> toUnifyFC(Collection<ClassOrInterface> availableClasses, DirectoryClassLoader classLoader) throws ClassNotFoundException {
|
||||
return toFC(availableClasses, classLoader).stream().map(t -> UnifyTypeFactory.convert(t)).collect(Collectors.toSet());
|
||||
public static Set<UnifyPair> toUnifyFC(Collection<ClassOrInterface> availableClasses) throws ClassNotFoundException {
|
||||
return toFC(availableClasses).stream().map(t -> UnifyTypeFactory.convert(t)).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public static Set<Pair> toFC(Collection<ClassOrInterface> availableClasses, DirectoryClassLoader classLoader) throws ClassNotFoundException {
|
||||
public static Set<Pair> toFC(Collection<ClassOrInterface> availableClasses) throws ClassNotFoundException {
|
||||
HashSet<Pair> pairs = new HashSet<>();
|
||||
//PL 2018-09-18: gtvs vor die for-Schleife gezogen, damit immer die gleichen Typeplaceholder eingesetzt werden.
|
||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>();
|
||||
for(ClassOrInterface cly : availableClasses){
|
||||
pairs.addAll(getSuperTypes(cly, availableClasses, gtvs, classLoader));
|
||||
pairs.addAll(getSuperTypes(cly, availableClasses, gtvs));
|
||||
}
|
||||
return pairs;
|
||||
}
|
||||
@@ -49,8 +48,8 @@ public class FCGenerator {
|
||||
* @param forType
|
||||
* @return
|
||||
*/
|
||||
private static List<Pair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses, DirectoryClassLoader classLoader) throws ClassNotFoundException {
|
||||
return getSuperTypes(forType, availableClasses, new HashMap<>(), classLoader);
|
||||
private static List<Pair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses) throws ClassNotFoundException {
|
||||
return getSuperTypes(forType, availableClasses, new HashMap<>());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +61,7 @@ public class FCGenerator {
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
private static List<Pair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses,
|
||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs, DirectoryClassLoader classLoader) throws ClassNotFoundException {
|
||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs) throws ClassNotFoundException {
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
//Die GTVs, die in forType hinzukommen:
|
||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> newGTVs = new HashMap<>();
|
||||
@@ -87,7 +86,7 @@ public class FCGenerator {
|
||||
ClassOrInterface superClass;
|
||||
if(!hasSuperclass.isPresent()) //Wenn es die Klasse in den available Klasses nicht gibt wird sie im Classpath gesucht. Ansonsten Exception
|
||||
{
|
||||
superClass = ASTFactory.createClass(classLoader.loadClass(superType.getName().toString()));
|
||||
superClass = ASTFactory.createClass(ClassLoader.getSystemClassLoader().loadClass(superType.getName().toString()));
|
||||
}else{
|
||||
superClass = hasSuperclass.get();
|
||||
}
|
||||
@@ -121,7 +120,7 @@ public class FCGenerator {
|
||||
if(superClass.getClassName().equals(ASTFactory.createObjectClass().getClassName())){
|
||||
superTypes = Arrays.asList(new Pair(ASTFactory.createObjectType(), ASTFactory.createObjectType(), PairOperator.SMALLER));
|
||||
}else{
|
||||
superTypes = getSuperTypes(superClass, availableClasses, newGTVs, classLoader);
|
||||
superTypes = getSuperTypes(superClass, availableClasses, newGTVs);
|
||||
}
|
||||
|
||||
retList.add(ret);
|
||||
|
@@ -17,7 +17,6 @@ import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class StatementGenerator {
|
||||
|
||||
@@ -210,12 +209,7 @@ public class StatementGenerator {
|
||||
}else throw new NotImplementedException();
|
||||
|
||||
ArgumentList argumentList = convert(methodInvocationContext.argumentList());
|
||||
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = argumentList.getArguments().stream()
|
||||
.map(x -> TypePlaceholder.fresh(methodInvocationContext.getStart()))
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
MethodCall ret = new MethodCall(TypePlaceholder.fresh(methodInvocationContext.getStart()),
|
||||
getReceiver(receiver), name, argumentList, TypePlaceholder.fresh(methodInvocationContext.getStart()),
|
||||
argTypes, methodInvocationContext.getStart());
|
||||
MethodCall ret = new MethodCall(TypePlaceholder.fresh(methodInvocationContext.getStart()), getReceiver(receiver), name, argumentList, methodInvocationContext.getStart());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -285,24 +279,9 @@ public class StatementGenerator {
|
||||
}
|
||||
|
||||
|
||||
private Statement convert(Java8Parser.ClassInstanceCreationExpressionContext newExpression) {
|
||||
Java8Parser.TypeArgumentsContext genericArgs = null;
|
||||
if(newExpression.expressionName()!= null)throw new NotImplementedException();
|
||||
if(newExpression.typeArgumentsOrDiamond()!= null){
|
||||
if(newExpression.typeArgumentsOrDiamond().typeArguments()!=null){
|
||||
genericArgs = newExpression.typeArgumentsOrDiamond().typeArguments();
|
||||
}
|
||||
}
|
||||
if(newExpression.typeArguments()!= null)throw new NotImplementedException();
|
||||
|
||||
TerminalNode identifier = newExpression.Identifier(0);
|
||||
RefType newClass = (RefType) TypeGenerator.convertTypeName(identifier.getText(),genericArgs,identifier.getSymbol(),reg,generics);
|
||||
|
||||
ArgumentList args = convert(newExpression.argumentList());
|
||||
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = args.getArguments().stream()
|
||||
.map(x -> TypePlaceholder.fresh(newExpression.getStart()))
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
return new NewClass(newClass, args, null, argTypes, newExpression.getStart());
|
||||
private Statement convert(Java8Parser.ClassInstanceCreationExpressionContext stmt) {
|
||||
//TODO
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Statement convert(Java8Parser.PreIncrementExpressionContext stmt) {
|
||||
@@ -788,11 +767,7 @@ public class StatementGenerator {
|
||||
}else {
|
||||
Java8Parser.MethodInvocation_lf_primaryContext ctxt = e.methodInvocation_lf_primary();
|
||||
String methodName = ctxt.Identifier().toString();
|
||||
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = ctxt.argumentList().expression().stream()
|
||||
.map(x -> TypePlaceholder.fresh(e.getStart()))
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
return new MethodCall(TypePlaceholder.fresh(e.getStart()), getReceiver(expr), methodName,
|
||||
convert(ctxt.argumentList()), TypePlaceholder.fresh(e.getStart()), argTypes, e.getStart());
|
||||
return new MethodCall(TypePlaceholder.fresh(e.getStart()), getReceiver(expr), methodName, convert(ctxt.argumentList()), e.getStart());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -846,10 +821,7 @@ public class StatementGenerator {
|
||||
RefType newClass = (RefType) TypeGenerator.convertTypeName(identifier.getText(),genericArgs,identifier.getSymbol(),reg,generics);
|
||||
|
||||
ArgumentList args = convert(newExpression.argumentList());
|
||||
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = args.getArguments().stream()
|
||||
.map(x -> TypePlaceholder.fresh(newExpression.getStart()))
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
return new NewClass(newClass, args, null, argTypes, newExpression.getStart());
|
||||
return new NewClass(newClass, args, newExpression.getStart());
|
||||
}
|
||||
|
||||
private Expression convert(Java8Parser.LiteralContext literal) {
|
||||
@@ -907,12 +879,7 @@ public class StatementGenerator {
|
||||
}
|
||||
|
||||
ArgumentList argumentList = convert(methodInvocationContext.argumentList());
|
||||
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = argumentList.getArguments().stream()
|
||||
.map(x -> TypePlaceholder.fresh(methodInvocationContext.getStart()))
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
MethodCall ret = new MethodCall(TypePlaceholder.fresh(methodInvocationContext.getStart()),
|
||||
getReceiver(receiver), name, argumentList, TypePlaceholder.fresh(methodInvocationContext.getStart()),
|
||||
argTypes, methodInvocationContext.getStart());
|
||||
MethodCall ret = new MethodCall(TypePlaceholder.fresh(methodInvocationContext.getStart()), getReceiver(receiver), name, argumentList, methodInvocationContext.getStart());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,5 @@
|
||||
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
|
||||
|
||||
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
||||
import de.dhbwstuttgart.environment.PackageCrawler;
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import java.lang.ClassNotFoundException;
|
||||
@@ -20,7 +19,6 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.URL;
|
||||
import java.sql.Ref;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -37,7 +35,7 @@ public class SyntaxTreeGenerator{
|
||||
Set<JavaClassName> imports = new HashSet();
|
||||
private Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields = new HashMap<>(); //PL 2018-11-01 fields eingefuegt, damit die fields immer die gleiche TPH bekommen
|
||||
|
||||
List<Statement> fieldInitializations = new ArrayList<>(); //PL 2019-10-23: Muss für jede Klasse neu initilisiert werden
|
||||
List<Statement> fieldInitializations = new ArrayList<>();
|
||||
|
||||
public SyntaxTreeGenerator(JavaClassRegistry reg, GenericsRegistry globalGenerics){
|
||||
//Die Generics müssen während des Bauens des AST erstellt werden,
|
||||
@@ -76,10 +74,10 @@ public class SyntaxTreeGenerator{
|
||||
return ret;
|
||||
}
|
||||
|
||||
public SourceFile convert(Java8Parser.CompilationUnitContext ctx, PackageCrawler packageCrawler, DirectoryClassLoader classLoader) throws ClassNotFoundException{
|
||||
public SourceFile convert(Java8Parser.CompilationUnitContext ctx, PackageCrawler packageCrawler) throws ClassNotFoundException{
|
||||
if(ctx.packageDeclaration()!=null)this.pkgName = convert(ctx.packageDeclaration());
|
||||
List<ClassOrInterface> classes = new ArrayList<>();
|
||||
Map<String, Integer> imports = GatherNames.getImports(ctx, packageCrawler, classLoader);
|
||||
Map<String, Integer> imports = GatherNames.getImports(ctx, packageCrawler);
|
||||
this.imports = imports.keySet().stream().map(name -> reg.getName(name)).collect(Collectors.toSet());
|
||||
for(Java8Parser.TypeDeclarationContext typeDecl : ctx.typeDeclaration()){
|
||||
ClassOrInterface newClass;
|
||||
@@ -161,7 +159,6 @@ public class SyntaxTreeGenerator{
|
||||
|
||||
private ClassOrInterface convertClass(Java8Parser.ClassDeclarationContext ctx) {
|
||||
ClassOrInterface newClass;
|
||||
fieldInitializations = new ArrayList<>(); //PL 2019-10-22: muss für jede Klasse neu initilisiert werden
|
||||
if(ctx.normalClassDeclaration() != null){
|
||||
newClass = convertNormal(ctx.normalClassDeclaration());
|
||||
}
|
||||
|
@@ -3,37 +3,31 @@ package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.exceptions.TypeinferenceException;
|
||||
import de.dhbwstuttgart.parser.antlr.Java8Parser;
|
||||
import de.dhbwstuttgart.parser.antlr.Java8Parser.UnannClassType_lfno_unannClassOrInterfaceTypeContext;
|
||||
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
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 org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class TypeGenerator {
|
||||
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(Java8Parser.UnannClassOrInterfaceTypeContext unannClassOrInterfaceTypeContext, JavaClassRegistry reg, GenericsRegistry generics) {
|
||||
Java8Parser.TypeArgumentsContext arguments=null;
|
||||
/* PL 2019-03-19 auskommentiert ANFANG
|
||||
Java8Parser.TypeArgumentsContext arguments;
|
||||
if(unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType() != null){
|
||||
arguments = unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType().typeArguments();
|
||||
}else{// if(unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType() != null){
|
||||
arguments = unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType().unannClassType_lfno_unannClassOrInterfaceType().typeArguments();
|
||||
}
|
||||
PL 2019-03-19 auskommentiert ENDE */
|
||||
/**
|
||||
* Problem sind hier die verschachtelten Typen mit verschachtelten Typargumenten
|
||||
* Beispiel: Typ<String>.InnererTyp<Integer>
|
||||
@@ -41,28 +35,6 @@ public class TypeGenerator {
|
||||
String name = unannClassOrInterfaceTypeContext.getText();
|
||||
if(name.contains("<")){
|
||||
name = name.split("<")[0]; //Der Typ ist alles vor den ersten Argumenten
|
||||
/* Fuer Debug-Zwecke
|
||||
unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType();
|
||||
unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType().getText();
|
||||
//unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType().unannClassType_lfno_unannClassOrInterfaceType().typeArguments();
|
||||
//UnannClassType_lfno_unannClassOrInterfaceTypeContext
|
||||
unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType(0);
|
||||
unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType(0).getText();
|
||||
unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType(1);
|
||||
unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType(1).getText();
|
||||
unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType().getText();
|
||||
//unannClassOrInterfaceTypeContext.unannInterfaceType_lf_unannClassOrInterfaceType();
|
||||
//unannClassOrInterfaceTypeContext.unannInterfaceType_lf_unannClassOrInterfaceType(0).getText();
|
||||
//unannClassOrInterfaceTypeContext.unannInterfaceType_lf_unannClassOrInterfaceType(1).getText();
|
||||
//unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType().getText();
|
||||
*/
|
||||
int lastElement = new ArrayList<>(unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType()).size()-1;
|
||||
if (lastElement >=0) {//qualifizierter Name z.B.: java.util.Vector
|
||||
arguments = unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType(lastElement).typeArguments();
|
||||
}
|
||||
else { //unqualifizierter Name z.B.: Vector
|
||||
arguments = unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType().typeArguments();
|
||||
}
|
||||
}
|
||||
return convertTypeName(name, arguments, unannClassOrInterfaceTypeContext.getStart(), reg, generics);
|
||||
}
|
||||
@@ -161,35 +133,18 @@ public class TypeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(Java8Parser.WildcardContext wildcardContext, JavaClassRegistry reg, GenericsRegistry generics) {
|
||||
if(wildcardContext.wildcardBounds() != null){
|
||||
if(wildcardContext.wildcardBounds().getText().substring(0, 7).equals("extends")){
|
||||
return new ExtendsWildcardType(convert(wildcardContext.wildcardBounds().referenceType(), reg, generics), wildcardContext.getStart());
|
||||
}else{
|
||||
return new SuperWildcardType(convert(wildcardContext.wildcardBounds().referenceType(), reg, generics), wildcardContext.getStart());
|
||||
}
|
||||
}else{
|
||||
throw new NotImplementedException(); //Wildcard ohne Bound
|
||||
}
|
||||
}
|
||||
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric convertTypeName(String name, Token offset, JavaClassRegistry reg, GenericsRegistry generics){
|
||||
return convertTypeName(name, null, offset, reg, generics);
|
||||
}
|
||||
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric convertTypeName(
|
||||
String name, Java8Parser.TypeArgumentsContext typeArguments, Token offset, JavaClassRegistry reg, GenericsRegistry generics){
|
||||
if(!reg.contains(name)){ //Dann könnte es ein generischer Type oder ein FunN$$-Type sein
|
||||
if(!reg.contains(name)){ //Dann könnte es ein Generische Type sein
|
||||
if(generics.contains(name)){
|
||||
return new GenericRefType(name, offset);
|
||||
}else{
|
||||
Pattern p = Pattern.compile("Fun(\\d+)[$][$]");
|
||||
Matcher m = p.matcher(name);
|
||||
if (m.matches()) {//es ist FunN$$-Type
|
||||
return new RefType(new JavaClassName(name), convert(typeArguments, reg, generics), offset);
|
||||
} else {
|
||||
throw new TypeinferenceException("Der Typ "+ name + " ist nicht vorhanden",offset);
|
||||
}}
|
||||
}
|
||||
}
|
||||
if(typeArguments == null){
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
@@ -207,7 +162,7 @@ public class TypeGenerator {
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
|
||||
for(Java8Parser.TypeArgumentContext arg : typeArguments.typeArgumentList().typeArgument()){
|
||||
if(arg.wildcard() != null){
|
||||
ret.add(convert(arg.wildcard(), reg, generics));
|
||||
throw new NotImplementedException();
|
||||
}else{
|
||||
ret.add(convert(arg.referenceType(), reg, generics));
|
||||
}
|
||||
|
@@ -1,14 +1,13 @@
|
||||
package de.dhbwstuttgart.parser.scope;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
||||
import de.dhbwstuttgart.parser.antlr.Java8BaseListener;
|
||||
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
|
||||
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
|
||||
import de.dhbwstuttgart.environment.PackageCrawler;
|
||||
@@ -16,7 +15,7 @@ import de.dhbwstuttgart.parser.antlr.Java8Parser;
|
||||
|
||||
public class GatherNames {
|
||||
|
||||
public static Map<String, Integer> getNames(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages, DirectoryClassLoader classLoader) throws ClassNotFoundException{
|
||||
public static Map<String, Integer> getNames(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException{
|
||||
Map<String, Integer> ret = new HashMap<>();
|
||||
String pkgName = getPackageName(ctx);
|
||||
String nameString = "";
|
||||
@@ -65,12 +64,14 @@ public class GatherNames {
|
||||
}
|
||||
}
|
||||
}
|
||||
ret.putAll(getImports(ctx, packages, classLoader));
|
||||
ret.putAll(getImports(ctx, packages));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static Map<String, Integer> getImports(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages, DirectoryClassLoader classLoader) throws ClassNotFoundException {
|
||||
|
||||
public static Map<String, Integer> getImports(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException {
|
||||
Map<String, Integer> ret = new HashMap<>();
|
||||
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
|
||||
//ret.putAll(packages.getClassNames("java.lang"));
|
||||
for(Java8Parser.ImportDeclarationContext importDeclCtx : ctx.importDeclaration()){
|
||||
if(importDeclCtx.singleTypeImportDeclaration() != null){
|
||||
|
@@ -84,15 +84,7 @@ public class JavaClassName {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return (packageName!=null ? packageName.toString() + "." : "") + name;
|
||||
}
|
||||
|
||||
public String getPackageName() {
|
||||
return (packageName!=null ? packageName.toString() : "");
|
||||
}
|
||||
|
||||
public String getClassName(){
|
||||
return name;
|
||||
return (packageName!=null ? packageName.toString() : "") + name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,9 +130,6 @@ class PackageName{
|
||||
String ret = "";
|
||||
if(names == null)return "";
|
||||
for(String n : names)ret+=n+".";
|
||||
if (ret != null && ret.length() > 0 && ret.charAt(ret.length() - 1) == '.') {
|
||||
ret = ret.substring(0, ret.length() - 1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,5 @@
|
||||
package de.dhbwstuttgart.sat.asp.writer;
|
||||
|
||||
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.FCGenerator;
|
||||
import de.dhbwstuttgart.sat.asp.ASPStringConverter;
|
||||
@@ -17,9 +16,9 @@ import java.util.*;
|
||||
|
||||
public class ASPFactory implements TypeVisitor<String>{
|
||||
|
||||
public static String generateASP(ConstraintSet<Pair> constraints, Collection<ClassOrInterface> fcClasses, DirectoryClassLoader classLoader) throws ClassNotFoundException{
|
||||
public static String generateASP(ConstraintSet<Pair> constraints, Collection<ClassOrInterface> fcClasses) throws ClassNotFoundException{
|
||||
ASPFactory factory = new ASPFactory();
|
||||
factory.convertFC(fcClasses, classLoader);
|
||||
factory.convertFC(fcClasses);
|
||||
List<Constraint<Pair>> constraints1 = constraints.cartesianProduct().iterator().next();
|
||||
for(Constraint<Pair> constraint : constraints1){
|
||||
for(Pair p : constraint){
|
||||
@@ -33,8 +32,8 @@ public class ASPFactory implements TypeVisitor<String>{
|
||||
ASPWriter writer = new ASPWriter();
|
||||
boolean isFCType = false;
|
||||
|
||||
private void convertFC(Collection<ClassOrInterface> classes, DirectoryClassLoader classLoader) throws ClassNotFoundException {
|
||||
Set<Pair> fc = FCGenerator.toFC(classes, classLoader);
|
||||
private void convertFC(Collection<ClassOrInterface> classes) throws ClassNotFoundException {
|
||||
Set<Pair> fc = FCGenerator.toFC(classes);
|
||||
isFCType = true;
|
||||
for(Pair fcp : fc){
|
||||
convertPair(fcp);
|
||||
|
@@ -1,6 +1,5 @@
|
||||
package de.dhbwstuttgart.sat.asp.writer;
|
||||
|
||||
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.FCGenerator;
|
||||
import de.dhbwstuttgart.sat.asp.ASPStringConverter;
|
||||
@@ -56,9 +55,9 @@ public class ASPGencayFactory implements TypeVisitor<String> {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static String generateASP(ConstraintSet<Pair> constraints, Collection<ClassOrInterface> fcClasses, DirectoryClassLoader classLoader) throws ClassNotFoundException{
|
||||
public static String generateASP(ConstraintSet<Pair> constraints, Collection<ClassOrInterface> fcClasses) throws ClassNotFoundException{
|
||||
ASPGencayFactory factory = new ASPGencayFactory();
|
||||
factory.convertFC(fcClasses, classLoader);
|
||||
factory.convertFC(fcClasses);
|
||||
List<Constraint<Pair>> constraints1 = constraints.cartesianProduct().iterator().next();
|
||||
for(Constraint<Pair> constraint : constraints1){
|
||||
for(Pair p : constraint){
|
||||
@@ -70,8 +69,8 @@ public class ASPGencayFactory implements TypeVisitor<String> {
|
||||
return factory.writer.getASPFile();
|
||||
}
|
||||
|
||||
private void convertFC(Collection<ClassOrInterface> classes, DirectoryClassLoader classLoader) throws ClassNotFoundException {
|
||||
Set<Pair> fc = FCGenerator.toFC(classes, classLoader);
|
||||
private void convertFC(Collection<ClassOrInterface> classes) throws ClassNotFoundException {
|
||||
Set<Pair> fc = FCGenerator.toFC(classes);
|
||||
isFCType = true;
|
||||
for(Pair fcp : fc){
|
||||
generateTheta((RefType) fcp.TA1);
|
||||
|
@@ -80,9 +80,6 @@ public abstract class AbstractASTWalker implements ASTVisitor{
|
||||
for(Field f : classOrInterface.getFieldDecl()){
|
||||
f.accept(this);
|
||||
}
|
||||
for(Constructor c : classOrInterface.getConstructors()){
|
||||
c.accept(this);
|
||||
}
|
||||
for(Method m : classOrInterface.getMethods()){
|
||||
m.accept(this);
|
||||
}
|
||||
|
@@ -34,7 +34,6 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
|
||||
private List<RefType> implementedInterfaces;
|
||||
private List<Constructor> constructors;
|
||||
|
||||
|
||||
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters,
|
||||
RefType superClass, Boolean isInterface, List<RefType> implementedInterfaces, Token offset){
|
||||
super(offset);
|
||||
@@ -51,23 +50,6 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
|
||||
this.constructors = constructors;
|
||||
}
|
||||
|
||||
/* erzeugt fuer Fields, Konstruktoren und Methoden neue ArrayList-Objekte
|
||||
* alle anderen Datenobjekte werden nur kopiert.
|
||||
*/
|
||||
public ClassOrInterface(ClassOrInterface cl){
|
||||
super(cl.getOffset());
|
||||
this.modifiers = cl.modifiers;
|
||||
this.name = cl.name;
|
||||
this.fields = new ArrayList<>(cl.fields);
|
||||
this.fieldInitializations= cl.fieldInitializations;
|
||||
this.genericClassParameters = cl.genericClassParameters;
|
||||
this.superClass = cl.superClass;
|
||||
this.isInterface = cl.isInterface;
|
||||
this.implementedInterfaces = cl.implementedInterfaces;
|
||||
this.methods = new ArrayList<>(cl.methods);
|
||||
this.constructors = new ArrayList<>(cl.constructors);
|
||||
}
|
||||
|
||||
// Gets class name
|
||||
public JavaClassName getClassName(){
|
||||
return this.name;
|
||||
|
@@ -27,7 +27,7 @@ public class Constructor extends Method {
|
||||
*/
|
||||
protected static Block prepareBlock(Block constructorBlock /*, List<Statement> fieldInitializations new ArrayList<>() geloescht PL 2018-11-24 */){
|
||||
List<Statement> statements = constructorBlock.getStatements();
|
||||
statements.add(0, new SuperCall(null, null, constructorBlock.getOffset()));
|
||||
statements.add(0, new SuperCall(constructorBlock.getOffset()));
|
||||
/* statements.addAll(fieldInitializations); geloescht PL 2018-11-24 */
|
||||
return new Block(statements, constructorBlock.getOffset());
|
||||
}
|
||||
|
@@ -2,10 +2,6 @@ package de.dhbwstuttgart.syntaxtree;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -20,20 +16,10 @@ public class GenericDeclarationList extends SyntaxTreeNode implements Iterable<G
|
||||
private Token offsetOfLastElement;
|
||||
private List<GenericTypeVar> gtvs = new ArrayList<>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public GenericDeclarationList(Iterable<? extends GenericTypeVar> values, Token endOffset) {
|
||||
super(endOffset);
|
||||
gtvs = isListOfGenericTypeVar(values) ? (List<GenericTypeVar>)values : Lists.newArrayList(values);
|
||||
this.offsetOfLastElement = endOffset;
|
||||
}
|
||||
|
||||
public GenericDeclarationList(ArrayList<GenericTypeVar> values, Token endOffset) {
|
||||
public GenericDeclarationList(List<GenericTypeVar> values, Token endOffset) {
|
||||
super(endOffset);
|
||||
gtvs = values;
|
||||
this.offsetOfLastElement = endOffset; }
|
||||
|
||||
private boolean isListOfGenericTypeVar(Iterable<? extends GenericTypeVar> values) {
|
||||
return values instanceof List && ((List<?>)values).size() > 0 && ((List<?>)values).get(0) instanceof GenericTypeVar;
|
||||
this.offsetOfLastElement = endOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -26,13 +26,6 @@ public class SourceFile extends SyntaxTreeNode{
|
||||
this.imports = imports;
|
||||
}
|
||||
|
||||
public SourceFile(SourceFile sf) {
|
||||
super(new NullToken());
|
||||
this.KlassenVektor = new ArrayList<>(sf.KlassenVektor);
|
||||
this.imports = new HashSet<>(sf.imports);
|
||||
}
|
||||
|
||||
|
||||
public String getPkgName(){
|
||||
return this.pkgName;
|
||||
}
|
||||
|
@@ -70,7 +70,7 @@ public class ASTFactory {
|
||||
}
|
||||
|
||||
private static Field createField(java.lang.reflect.Field field, JavaClassName jreClass) {
|
||||
return new Field(field.getName(), createType(field.getGenericType()), field.getModifiers(), new NullToken());
|
||||
return new Field(field.getName(), createType(field.getType()), field.getModifiers(), new NullToken());
|
||||
}
|
||||
|
||||
//private static RefType createType(Class classType) {
|
||||
@@ -189,11 +189,11 @@ public class ASTFactory {
|
||||
|
||||
public static de.dhbwstuttgart.syntaxtree.GenericTypeVar createGeneric(TypeVariable jreTypeVar, String jreTVName, Class context, String parentMethod){
|
||||
JavaClassName parentClass = new JavaClassName(context.getName());
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> genericBounds = new ArrayList<>();
|
||||
List<RefType> genericBounds = new ArrayList<>();
|
||||
java.lang.reflect.Type[] bounds = jreTypeVar.getBounds();
|
||||
if(bounds.length > 0){
|
||||
for(java.lang.reflect.Type bound : bounds){
|
||||
genericBounds.add(createType(bound));
|
||||
genericBounds.add((RefType) createType(bound));
|
||||
}
|
||||
}
|
||||
return new de.dhbwstuttgart.syntaxtree.GenericTypeVar(jreTVName, genericBounds, new NullToken(), new NullToken());
|
||||
|
@@ -1,13 +1,11 @@
|
||||
package de.dhbwstuttgart.syntaxtree.factory;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
@@ -32,7 +30,7 @@ public class UnifyTypeFactory {
|
||||
|
||||
private static ArrayList<PlaceholderType> PLACEHOLDERS = new ArrayList<>();
|
||||
|
||||
public static FiniteClosure generateFC(List<ClassOrInterface> fromClasses, Writer logFile, DirectoryClassLoader classLoader) throws ClassNotFoundException {
|
||||
public static FiniteClosure generateFC(List<ClassOrInterface> fromClasses, FileWriter logFile) throws ClassNotFoundException {
|
||||
/*
|
||||
Die transitive Hülle muss funktionieren.
|
||||
Man darf schreiben List<A> extends AL<A>
|
||||
@@ -43,7 +41,7 @@ public class UnifyTypeFactory {
|
||||
Generell dürfen sie immer die gleichen Namen haben.
|
||||
TODO: die transitive Hülle bilden
|
||||
*/
|
||||
return new FiniteClosure(FCGenerator.toUnifyFC(fromClasses, classLoader), logFile);
|
||||
return new FiniteClosure(FCGenerator.toUnifyFC(fromClasses), logFile);
|
||||
}
|
||||
|
||||
public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr){
|
||||
@@ -69,6 +67,9 @@ public class UnifyTypeFactory {
|
||||
public static UnifyType convert(RefTypeOrTPHOrWildcardOrGeneric t, Boolean innerType){
|
||||
if(t instanceof GenericRefType){
|
||||
return UnifyTypeFactory.convert((GenericRefType)t, innerType);
|
||||
}else
|
||||
if(t instanceof FunN){
|
||||
return UnifyTypeFactory.convert((FunN)t, innerType);
|
||||
}else if(t instanceof TypePlaceholder){
|
||||
return UnifyTypeFactory.convert((TypePlaceholder)t, innerType);
|
||||
}else if(t instanceof ExtendsWildcardType){
|
||||
@@ -84,13 +85,13 @@ public class UnifyTypeFactory {
|
||||
|
||||
public static UnifyType convert(RefType t, Boolean innerType){
|
||||
//Check if it is a FunN Type:
|
||||
Pattern p = Pattern.compile("Fun(\\d+)[$][$]");
|
||||
Pattern p = Pattern.compile("Fun(\\d+)");
|
||||
Matcher m = p.matcher(t.getName().toString());
|
||||
boolean b = m.matches();
|
||||
if(b){
|
||||
Integer N = Integer.valueOf(m.group(1));
|
||||
if((N + 1) == t.getParaList().size()){
|
||||
return convertFunN(t.getParaList(), false);
|
||||
return convert(new FunN(t.getParaList()), false);
|
||||
}
|
||||
}
|
||||
UnifyType ret;
|
||||
@@ -101,16 +102,16 @@ public class UnifyTypeFactory {
|
||||
}
|
||||
ret = new ReferenceType(t.getName().toString(),new TypeParams(params));
|
||||
}else{
|
||||
ret = new ReferenceType(t.getName().toString(), false);
|
||||
ret = new ReferenceType(t.getName().toString());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static UnifyType convertFunN(List<RefTypeOrTPHOrWildcardOrGeneric> paraList, Boolean innerType){
|
||||
public static UnifyType convert(FunN t, Boolean innerType){
|
||||
UnifyType ret;
|
||||
List<UnifyType> params = new ArrayList<>();
|
||||
if(paraList != null && paraList.size() > 0){
|
||||
for(RefTypeOrTPHOrWildcardOrGeneric pT : paraList){
|
||||
if(t.getParaList() != null && t.getParaList().size() > 0){
|
||||
for(RefTypeOrTPHOrWildcardOrGeneric pT : t.getParaList()){
|
||||
params.add(UnifyTypeFactory.convert(pT, false));
|
||||
}
|
||||
}
|
||||
@@ -123,7 +124,6 @@ public class UnifyTypeFactory {
|
||||
System.out.println("XXX"+innerType);
|
||||
}
|
||||
PlaceholderType ntph = new PlaceholderType(tph.getName());
|
||||
ntph.setVariance(tph.getVariance());
|
||||
int in = PLACEHOLDERS.indexOf(ntph);
|
||||
if (in == -1) {
|
||||
PLACEHOLDERS.add(ntph);
|
||||
@@ -138,7 +138,7 @@ public class UnifyTypeFactory {
|
||||
}
|
||||
|
||||
public static UnifyType convert(GenericRefType t, Boolean innerType){
|
||||
return new ReferenceType(t.getParsedName(), true);
|
||||
return new ReferenceType(t.getParsedName());
|
||||
}
|
||||
|
||||
public static UnifyType convert(WildcardType t, Boolean innerType){
|
||||
@@ -224,21 +224,18 @@ public class UnifyTypeFactory {
|
||||
return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, (RefType) tr);
|
||||
}else if(tr instanceof WildcardType){
|
||||
return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, (WildcardType) tr);
|
||||
}else if(tr instanceof GenericRefType){
|
||||
return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, (GenericRefType) tr);
|
||||
}else throw new NotImplementedException();
|
||||
}else throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(ReferenceType t, Map<String,TypePlaceholder> tphs) {
|
||||
if(JavaClassName.Void.equals(t.getName()))return new Void(new NullToken());
|
||||
if (t.isGenTypeVar()) return new GenericRefType(t.getName(),new NullToken());
|
||||
RefType ret = new RefType(new JavaClassName(t.getName()),convert(t.getTypeParams(), tphs),new NullToken());
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(FunNType t, Map<String,TypePlaceholder> tphs) {
|
||||
RefType ret = new RefType(new JavaClassName(t.getName()), convert(t.getTypeParams(), tphs), new NullToken());
|
||||
RefType ret = new RefType(new JavaClassName(t.getName()+"$$"), convert(t.getTypeParams(), tphs), new NullToken());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@@ -21,24 +21,13 @@ public class MethodCall extends Statement
|
||||
{
|
||||
public final String name;
|
||||
public final Receiver receiver;
|
||||
|
||||
public final ArgumentList arglist;
|
||||
|
||||
/*
|
||||
* noetig fuer Bytecodegenerierung
|
||||
*/
|
||||
public RefTypeOrTPHOrWildcardOrGeneric receiverType;
|
||||
public final ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes;
|
||||
|
||||
|
||||
public MethodCall(RefTypeOrTPHOrWildcardOrGeneric retType, Receiver receiver, String methodName, ArgumentList argumentList,
|
||||
RefTypeOrTPHOrWildcardOrGeneric receiverType, ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes, Token offset){
|
||||
public MethodCall(RefTypeOrTPHOrWildcardOrGeneric retType, Receiver receiver, String methodName, ArgumentList argumentList, Token offset){
|
||||
super(retType,offset);
|
||||
this.arglist = argumentList;
|
||||
this.name = methodName;
|
||||
this.receiver = receiver;
|
||||
this.receiverType = receiverType;
|
||||
this.argTypes = argTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -29,10 +29,8 @@ public class NewClass extends MethodCall
|
||||
* @param args Argumente mit denen der New-Call aufgerufen wurde
|
||||
* @param start
|
||||
*/
|
||||
public NewClass(RefType newClass, ArgumentList args, RefTypeOrTPHOrWildcardOrGeneric receiverType,
|
||||
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes, Token start) {
|
||||
super(newClass, new ExpressionReceiver(new EmptyStmt(start)), newClass.getName().toString(),
|
||||
args, receiverType, argTypes, start);
|
||||
public NewClass(RefType newClass, ArgumentList args, Token start) {
|
||||
super(newClass, new ExpressionReceiver(new EmptyStmt(start)), newClass.getName().toString(), args, start);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -2,7 +2,6 @@ package de.dhbwstuttgart.syntaxtree.statement;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
@@ -13,14 +12,12 @@ import java.util.ArrayList;
|
||||
|
||||
public class SuperCall extends MethodCall
|
||||
{
|
||||
public SuperCall(RefTypeOrTPHOrWildcardOrGeneric receiverType,
|
||||
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes, Token offset){
|
||||
this(new ArgumentList(new ArrayList<Expression>(), offset), receiverType, argTypes, offset);
|
||||
public SuperCall(Token offset){
|
||||
this(new ArgumentList(new ArrayList<Expression>(), offset),offset);
|
||||
}
|
||||
|
||||
public SuperCall(ArgumentList argumentList, RefTypeOrTPHOrWildcardOrGeneric receiverType,
|
||||
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes, Token offset){
|
||||
super(new Void(offset), new ExpressionReceiver(new This(offset)), "<init>", argumentList, receiverType, argTypes, offset);
|
||||
public SuperCall(ArgumentList argumentList, Token offset){
|
||||
super(new Void(offset), new ExpressionReceiver(new This(offset)), "<init>", argumentList, offset);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -19,8 +19,4 @@ public class This extends Expression
|
||||
public void accept(StatementVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "this: "+ this.getType();
|
||||
}
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ public class ThisCall extends MethodCall
|
||||
{
|
||||
public ThisCall(Receiver receiver, ArgumentList arglist, int offset)
|
||||
{
|
||||
super(null, null, null, null, null, null, null);
|
||||
super(null, null, null, null, null);
|
||||
|
||||
}
|
||||
|
||||
|
41
src/main/java/de/dhbwstuttgart/syntaxtree/type/FunN.java
Normal file
41
src/main/java/de/dhbwstuttgart/syntaxtree/type/FunN.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package de.dhbwstuttgart.syntaxtree.type;
|
||||
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @see Spezifikation "Complete Typeinference in Java 8" von Martin Plümicke
|
||||
* "interface FunN<R,T1, T2, ... ,TN> { R apply(T1 arg1, T2 arg2, ... , TN argN); }"
|
||||
* @author A10023 - Andreas Stadelmeier
|
||||
*
|
||||
* Bemerkung:
|
||||
* FunN ist ein RefType. Der RefType ist nicht mit einem FunNInterface verbunden.
|
||||
*
|
||||
*/
|
||||
public class FunN extends RefType {
|
||||
/**
|
||||
* @author Andreas Stadelmeier, a10023
|
||||
* Benötigt für den Typinferenzalgorithmus für Java 8
|
||||
* Generiert einen RefType auf eine FunN<R,T1,...,TN> - Klasse.
|
||||
* @param params
|
||||
* @return
|
||||
*/
|
||||
public FunN(List<RefTypeOrTPHOrWildcardOrGeneric> params) {
|
||||
super(new JavaClassName("Fun"+(params.size()-1)), params, new NullToken());
|
||||
}
|
||||
|
||||
/**
|
||||
* Spezieller Konstruktor um eine FunN ohne Returntype zu generieren
|
||||
|
||||
protected FunN(List<? extends Type> list){
|
||||
super("",0);
|
||||
if(list==null)throw new NullPointerException();
|
||||
setT(list);
|
||||
this.name = new JavaClassName("Fun"+list.size());//getName();
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
@@ -19,11 +19,6 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
|
||||
{
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* wird bisher nicht genutzt
|
||||
* setVariance muss ggf. auskommentiert werden.
|
||||
*/
|
||||
int variance = 0;
|
||||
|
||||
|
||||
/**
|
||||
@@ -74,16 +69,6 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
|
||||
return name;
|
||||
}
|
||||
|
||||
/* wird bisher nicht genutzt
|
||||
public void setVariance(int variance) {
|
||||
this.variance= variance;
|
||||
}
|
||||
*/
|
||||
|
||||
public int getVariance() {
|
||||
return this.variance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ASTVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
|
@@ -1,24 +1,22 @@
|
||||
package de.dhbwstuttgart.typedeployment;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.statement.This;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultPair;
|
||||
|
||||
public class TypeInsert {
|
||||
/**
|
||||
* point wird hauptsächlich zur Anzeige einer Annotation im Eclipse-plugin benutzt.
|
||||
*/
|
||||
public final TypeInsertPoint point;
|
||||
Set<TypeInsertPoint> inserts;
|
||||
ResultPair<?, ?> resultPair;
|
||||
|
||||
public TypeInsert(TypeInsertPoint point, Set<TypeInsertPoint> additionalPoints, ResultPair<?, ?> resultPair){
|
||||
public TypeInsert(TypeInsertPoint point, Set<TypeInsertPoint> additionalPoints){
|
||||
this.point = point;
|
||||
inserts = additionalPoints;
|
||||
this.resultPair = resultPair;
|
||||
}
|
||||
|
||||
public String insert(String intoSource){
|
||||
@@ -36,10 +34,6 @@ public class TypeInsert {
|
||||
return point.getInsertString();
|
||||
}
|
||||
|
||||
public ResultPair<?, ?> getResultPair() {
|
||||
return this.resultPair;
|
||||
}
|
||||
|
||||
/* PL 2018-06-18
|
||||
* Zwei TypeInsert's sind gleich, wenn ihre point's und ihre inserts' gleich sind
|
||||
* eingefuegt damit man TypeReplaceMarker vergleichen kann
|
||||
@@ -54,11 +48,6 @@ public class TypeInsert {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public Set<TypeInsertPoint> getAdditionalPoints() {
|
||||
return this.inserts;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return point.toString();
|
||||
}
|
||||
|
@@ -1,18 +1,9 @@
|
||||
package de.dhbwstuttgart.typedeployment;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericGenratorResultForSourceFile;
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResult;
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResultForClass;
|
||||
import de.dhbwstuttgart.bytecode.utilities.MethodUtility;
|
||||
import de.dhbwstuttgart.bytecode.utilities.Resolver;
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
import de.dhbwstuttgart.typeinference.result.*;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -31,98 +22,68 @@ import java.util.*;
|
||||
*/
|
||||
public class TypeInsertFactory {
|
||||
|
||||
private static List<ResultSet> newResults;
|
||||
|
||||
public static Set<TypeInsert> createTypeInsertPoints(SourceFile forSourcefile, ResultSet withResults, List<ResultSet> newResults){
|
||||
TypeInsertFactory.newResults = newResults;
|
||||
public static Set<TypeInsert> createTypeInsertPoints(SourceFile forSourcefile, ResultSet withResults){
|
||||
return new TypeInsertPlacer().getTypeInserts(forSourcefile, withResults);
|
||||
}
|
||||
|
||||
public static TypeInsert createInsertPoints(RefTypeOrTPHOrWildcardOrGeneric type, Token offset, ClassOrInterface cl, Method m,
|
||||
ResultSet resultSet) {
|
||||
|
||||
try {
|
||||
ResolvedType resolvedType = resultSet.resolveType(type);
|
||||
TypeInsertPoint insertPoint = new TypeInsertPoint(offset,
|
||||
new TypeToInsertString(resolvedType.resolvedType).insert);
|
||||
List<GenericGenratorResultForSourceFile> simplifyResults = JavaTXCompiler.INSTANCE.getGeneratedGenericResultsForAllSourceFiles(newResults);
|
||||
for (GenericGenratorResultForSourceFile simplifyResultsEntries : simplifyResults) {
|
||||
GenericsGeneratorResultForClass genericResultsForClass = simplifyResultsEntries.getSimplifyResultsByName(cl.getClassName());
|
||||
return new TypeInsert(insertPoint, createGenericInsert(genericResultsForClass, cl, m, resultSet, offset), resolvedType.getResultPair());
|
||||
return new TypeInsert(insertPoint, new HashSet<>(Arrays.asList(createGenericInsert(resolvedType.additionalGenerics, cl, m))));
|
||||
}
|
||||
|
||||
return new TypeInsert(insertPoint, new HashSet<>(), resolvedType.getResultPair());
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
private static TypeInsertPoint createGenericInsert(Set<GenericInsertPair> toInsert, ClassOrInterface cl, Method m){
|
||||
//Momentan wird Methode ignoriert. Parameter werden immer als Klassenparameter angefügt:
|
||||
//Offset zum Einstzen bestimmen:
|
||||
Token offset;
|
||||
String insert = "";
|
||||
String end;
|
||||
if(cl.getGenerics().iterator().hasNext()){
|
||||
//offset = cl.getGenerics().iterator().next().getOffset();
|
||||
offset = cl.getGenerics().getOffset();
|
||||
end=",";
|
||||
}else{
|
||||
offset = cl.getGenerics().getOffset();
|
||||
insert += "<";
|
||||
end = ">";
|
||||
}
|
||||
|
||||
//Alle einzusetzenden Generics und deren Bounds bestimmen:
|
||||
HashMap<TypePlaceholder, HashSet<TypePlaceholder>> genericsAndBounds = new HashMap<>();
|
||||
for(GenericInsertPair p : toInsert){
|
||||
if(!genericsAndBounds.containsKey(p.TA1)){
|
||||
genericsAndBounds.put((TypePlaceholder) p.TA1, new HashSet<>());
|
||||
}
|
||||
if(p.TA2 != null){
|
||||
genericsAndBounds.get(p.TA1).add((TypePlaceholder) p.TA2);
|
||||
if(!genericsAndBounds.containsKey(p.TA2)){
|
||||
genericsAndBounds.put((TypePlaceholder) p.TA2, new HashSet<>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static synchronized Set<TypeInsertPoint> createGenericInsert(GenericsGeneratorResultForClass genericResult, ClassOrInterface cl, Method m, ResultSet resultSet, Token mOffset){
|
||||
Set<TypeInsertPoint> result = createGenericClassInserts(genericResult, cl);
|
||||
|
||||
for (Method method : cl.getMethods()) {
|
||||
Resolver resolver = new Resolver(resultSet);
|
||||
List<GenericsGeneratorResult> methodConstraints = genericResult.getMethodConstraintsByID(MethodUtility.createID(resolver, method));
|
||||
result.addAll(createMethodConstraints(method, methodConstraints, mOffset));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Set<TypeInsertPoint> createMethodConstraints(Method method, List<GenericsGeneratorResult> constraints, Token mOffset) {
|
||||
Set<TypeInsertPoint> result = new HashSet<>();
|
||||
Token offset = mOffset;
|
||||
|
||||
if (constraints.size() == 0) {
|
||||
result.add(new TypeInsertPoint(offset, ""));
|
||||
return result;
|
||||
}
|
||||
|
||||
String insert = " <";
|
||||
|
||||
for (GenericsGeneratorResult genericInsertConstraint : constraints) {
|
||||
if (genericInsertConstraint.getConstraint().getRight().equals(Type.getInternalName(Object.class))) {
|
||||
insert += genericInsertConstraint.getConstraint().getLeft();
|
||||
} else {
|
||||
insert += genericInsertConstraint.getConstraint().getLeft() + " extends " + genericInsertConstraint.getConstraint().getRight() + ", ";
|
||||
//String zum Einsetzen (Generics mit bounds) generieren:
|
||||
Iterator<TypePlaceholder> it = genericsAndBounds.keySet().iterator();
|
||||
if(! it.hasNext())return new TypeInsertPoint(offset, "");
|
||||
while(it.hasNext()){
|
||||
TypePlaceholder tph = it.next();
|
||||
insert += tph.getName();
|
||||
Set<TypePlaceholder> bounds = genericsAndBounds.get(tph);
|
||||
if(bounds.size() > 0){
|
||||
insert += " extends ";
|
||||
Iterator<TypePlaceholder> boundIt = bounds.iterator();
|
||||
while(boundIt.hasNext()){
|
||||
TypePlaceholder bound = boundIt.next();
|
||||
insert += bound.getName();
|
||||
if(boundIt.hasNext())insert += " & ";
|
||||
}
|
||||
}
|
||||
|
||||
insert = insert.substring(0, insert.length() -2);
|
||||
insert += ">";
|
||||
|
||||
result.add(new TypeInsertPoint(offset, insert));
|
||||
return result;
|
||||
if(it.hasNext())insert+=",";
|
||||
}
|
||||
|
||||
private static Set<TypeInsertPoint> createGenericClassInserts(GenericsGeneratorResultForClass genericResult, ClassOrInterface cl) {
|
||||
Set<TypeInsertPoint> result = new HashSet<>();
|
||||
Token offset = cl.getGenerics().getOffset();
|
||||
|
||||
List<GenericsGeneratorResult> classConstraints = genericResult.getClassConstraints();
|
||||
|
||||
if (classConstraints.size() == 0) {
|
||||
result.add(new TypeInsertPoint(offset, ""));
|
||||
return result;
|
||||
}
|
||||
|
||||
String insert = " <";
|
||||
|
||||
for (GenericsGeneratorResult genericInsertConstraint : classConstraints) {
|
||||
if (genericInsertConstraint.getConstraint().getRight().equals(Type.getInternalName(Object.class))) {
|
||||
insert += genericInsertConstraint.getConstraint().getLeft();
|
||||
} else {
|
||||
insert += genericInsertConstraint.getConstraint().getLeft() + " extends " + genericInsertConstraint.getConstraint().getRight() + ", ";
|
||||
}
|
||||
}
|
||||
|
||||
insert = insert.substring(0, insert.length() -2);
|
||||
insert += ">";
|
||||
|
||||
result.add(new TypeInsertPoint(offset, insert));
|
||||
|
||||
return result;
|
||||
return new TypeInsertPoint(offset, insert + end);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,12 +1,13 @@
|
||||
package de.dhbwstuttgart.typedeployment;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.JavaInternalExpression;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class TypeInsertPlacer extends AbstractASTWalker{
|
||||
|
@@ -4,15 +4,12 @@ import org.antlr.v4.runtime.Token;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class TypeInsertPoint {
|
||||
public Token point;
|
||||
public final Token point;
|
||||
private String insertString;
|
||||
private int extraOffset = 0;
|
||||
|
||||
public TypeInsertPoint(Token point, String toInsert){
|
||||
this.point = point;
|
||||
@@ -24,21 +21,13 @@ public class TypeInsertPoint {
|
||||
//token.point.getLine() != point.getLine() && token.point.getCharPositionInLine() <= point.getCharPositionInLine()))
|
||||
token.point.getStartIndex() <= point.getStartIndex()))
|
||||
.mapToInt((typeInsertPoint -> typeInsertPoint.insertString.length())).sum();
|
||||
return new StringBuilder(intoSource).insert(point.getStartIndex()+offset+extraOffset, insertString).toString();
|
||||
return new StringBuilder(intoSource).insert(point.getStartIndex()+offset, insertString).toString();
|
||||
}
|
||||
|
||||
public String getInsertString() {
|
||||
return insertString;
|
||||
}
|
||||
|
||||
public void addExtraOffset(int toAdd) {
|
||||
this.extraOffset += toAdd;
|
||||
}
|
||||
|
||||
public int getPositionInCode() {
|
||||
return point.getStartIndex() + extraOffset;
|
||||
}
|
||||
|
||||
/* PL 2018-06-19
|
||||
* Zwei TypeInsertPoint's sind gleich, wenn ihre point's gleich sind
|
||||
* eingefuegt damit man TypeReplaceMarker vergleichen kann
|
||||
@@ -54,10 +43,6 @@ public class TypeInsertPoint {
|
||||
}
|
||||
}
|
||||
|
||||
public Set<TypeInsertPoint> getAdditionalPoints() {
|
||||
return this.getAdditionalPoints();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return point.toString() + " " + insertString.toString();
|
||||
}
|
||||
|
@@ -21,7 +21,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())), new ArrayList<>(), Optional.empty() /* eingefuegt PL 2018-11-24 */,
|
||||
createMethods(funNParams), new ArrayList<>(), createGenerics(funNParams),
|
||||
ASTFactory.createObjectType(), true, new ArrayList<>(), new NullToken());
|
||||
|
||||
|
@@ -1,10 +1,10 @@
|
||||
package de.dhbwstuttgart.typeinference.assumptions;
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.TypeScope;
|
||||
import de.dhbwstuttgart.syntaxtree.type.FunN;
|
||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
@@ -63,7 +63,7 @@ public class MethodAssumption extends Assumption{
|
||||
}
|
||||
RefTypeOrTPHOrWildcardOrGeneric receiverType;
|
||||
if(receiver instanceof FunNClass){
|
||||
receiverType = new RefType(new JavaClassName(receiver.getClassName().toString()+"$$"), params, new NullToken()); // new FunN(params);
|
||||
receiverType = new FunN(params);
|
||||
}else{
|
||||
receiverType = new RefType(receiver.getClassName(), params, new NullToken());
|
||||
}
|
||||
|
@@ -6,7 +6,6 @@ import de.dhbwstuttgart.typeinference.unify.GuavaSetOperations;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -30,10 +29,7 @@ public class ConstraintSet<A> {
|
||||
|
||||
@Override
|
||||
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);
|
||||
//cartesianProduct().toString();
|
||||
return cartesianProduct().toString();
|
||||
}
|
||||
|
||||
public Set<List<Constraint<A>>> cartesianProduct(){
|
||||
|
@@ -23,9 +23,4 @@ public class GenericInsertPair {
|
||||
if(TA2.equals(additionalTPH))return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GenIns(" + TA1.toString() + " < " + TA2.toString() + ")";
|
||||
}
|
||||
}
|
||||
|
@@ -21,9 +21,4 @@ public class PairTPHequalRefTypeOrWildcardType extends ResultPair{
|
||||
public void accept(ResultPairVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + left.toString() + " = " + right.toString() + ")";
|
||||
}
|
||||
}
|
||||
|
@@ -20,9 +20,4 @@ public class PairTPHsmallerTPH extends ResultPair{
|
||||
public void accept(ResultPairVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + left.toString() + " < " + right.toString() + ")";
|
||||
}
|
||||
}
|
||||
|
@@ -7,21 +7,11 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import java.util.Set;
|
||||
|
||||
public class ResolvedType{
|
||||
private ResultPair<?, ?> resultPair;
|
||||
|
||||
public final RefTypeOrTPHOrWildcardOrGeneric resolvedType;
|
||||
//public final Set<GenericInsertPair> additionalGenerics;
|
||||
public final Set<GenericInsertPair> additionalGenerics;
|
||||
|
||||
public ResolvedType(RefTypeOrTPHOrWildcardOrGeneric resolvedType, Set<GenericInsertPair> additionalGenerics){
|
||||
this.resolvedType = resolvedType;
|
||||
//this.additionalGenerics = additionalGenerics;
|
||||
}
|
||||
|
||||
public void setResultPair(ResultPair<?, ?> resultPair) {
|
||||
this.resultPair = resultPair;
|
||||
}
|
||||
|
||||
public ResultPair<?, ?> getResultPair() {
|
||||
return resultPair;
|
||||
this.additionalGenerics = additionalGenerics;
|
||||
}
|
||||
}
|
||||
|
@@ -27,36 +27,4 @@ public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B ext
|
||||
public String toString() {
|
||||
return "(" + left.toString() + ", " + right.toString() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((left == null) ? 0 : left.getOffset().hashCode());
|
||||
result = prime * result + ((right == null) ? 0 : right.getOffset().hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
ResultPair<?,?> other = (ResultPair<?,?>) obj;
|
||||
if (left == null) {
|
||||
if (other.left != null)
|
||||
return false;
|
||||
} else if (!left.getOffset().equals(other.left.getOffset()))
|
||||
return false;
|
||||
if (right == null) {
|
||||
if (other.right != null)
|
||||
return false;
|
||||
} else if (!right.getOffset().equals(other.right.getOffset()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,68 +1,38 @@
|
||||
package de.dhbwstuttgart.typeinference.result;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
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){
|
||||
this.results = set;
|
||||
this.genIns = new HashSet<>();
|
||||
results.forEach(x -> { if (x instanceof PairTPHsmallerTPH) { this.genIns.add(x);}} );
|
||||
}
|
||||
|
||||
public boolean contains(ResultPair toCheck) {
|
||||
return this.results.contains(toCheck);
|
||||
}
|
||||
|
||||
public void remove(ResultPair toCheck) {
|
||||
results.remove(toCheck);
|
||||
public ResultSet(Set<ResultPair> results){
|
||||
this.results = results;
|
||||
}
|
||||
|
||||
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 RefType){
|
||||
RelatedTypeWalker related = new RelatedTypeWalker(null, this);
|
||||
type.accept(related);
|
||||
return new ResolvedType(type, related.relatedTPHs);
|
||||
} else {
|
||||
}else{
|
||||
throw new NotImplementedException();
|
||||
//return new ResolvedType(type,new HashSet<>());
|
||||
}
|
||||
}
|
||||
|
||||
//TODO Beim Einsetzen eines Generics, müssen die new und Methodenaufrufe verändert werden
|
||||
|
||||
public String toString() {
|
||||
return results.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof ResultSet) {
|
||||
ResultSet other = (ResultSet)o;
|
||||
return this.results.equals(other.results);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return results.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
class Resolver implements ResultSetVisitor {
|
||||
@@ -70,7 +40,6 @@ class Resolver implements ResultSetVisitor {
|
||||
private TypePlaceholder toResolve;
|
||||
private RefTypeOrTPHOrWildcardOrGeneric resolved;
|
||||
private final Set<GenericInsertPair> additionalTPHs = new HashSet<>();
|
||||
private ResultPair<?,?> currentPair;
|
||||
|
||||
public Resolver(ResultSet resultPairs){
|
||||
this.result = resultPairs;
|
||||
@@ -80,28 +49,23 @@ class Resolver implements ResultSetVisitor {
|
||||
toResolve = tph;
|
||||
resolved = null;
|
||||
System.out.println(tph.toString());
|
||||
for(ResultPair<?,?> resultPair : result.results) {
|
||||
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){
|
||||
currentPair = resultPair;
|
||||
for(ResultPair resultPair : result.results){
|
||||
resultPair.accept(this);
|
||||
}
|
||||
if(resolved==null){//TPH kommt nicht im Result vor:
|
||||
resolved = tph;
|
||||
}
|
||||
|
||||
ResolvedType result = new ResolvedType(resolved, additionalTPHs);//resolved;
|
||||
result.setResultPair(currentPair);
|
||||
return result;
|
||||
return new ResolvedType(resolved, additionalTPHs);//resolved;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(PairTPHsmallerTPH p) {
|
||||
currentPair = p;
|
||||
if(p.left.equals(toResolve)){
|
||||
additionalTPHs.add(new GenericInsertPair(p.left, p.right));
|
||||
additionalTPHs.addAll(new RelatedTypeWalker(p.right, result).relatedTPHs);
|
||||
@@ -112,7 +76,6 @@ class Resolver implements ResultSetVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(PairTPHequalRefTypeOrWildcardType p) {
|
||||
currentPair = p;
|
||||
if(p.left.equals(toResolve)){
|
||||
resolved = p.right;
|
||||
RelatedTypeWalker related = new RelatedTypeWalker(null, result);
|
||||
@@ -158,7 +121,6 @@ class Resolver implements ResultSetVisitor {
|
||||
/**
|
||||
* Sucht aus dem Result Set den Sub/supertyp für einen TPH
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
class TPHResolver implements ResultSetVisitor {
|
||||
|
||||
private final TypePlaceholder tph;
|
||||
@@ -227,7 +189,6 @@ class TPHResolver implements ResultSetVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
class RelatedTypeWalker implements ResultSetVisitor {
|
||||
|
||||
final Set<GenericInsertPair> relatedTPHs = new HashSet<>();
|
||||
|
@@ -46,7 +46,7 @@ public class TYPE {
|
||||
/*
|
||||
TODO: Hier eine Information erstellen nur mit den importierte Klassen einer einzigen SourceFile
|
||||
private TypeInferenceInformation getTypeInferenceInformation(sourceFile) {
|
||||
DirectoryClassLoader classLoader = DirectoryClassLoader.getSystemClassLoader();
|
||||
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
|
||||
Set<ClassOrInterface> classes = new HashSet<>();
|
||||
|
||||
for(SourceFile sourceFile : sfs){
|
||||
|
@@ -17,7 +17,6 @@ import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
|
||||
import de.dhbwstuttgart.typeinference.constraints.*;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -66,9 +65,7 @@ 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),
|
||||
PairOperator.EQUALSDOT));
|
||||
new FunN(lambdaParams),PairOperator.EQUALSDOT));
|
||||
constraintsSet.addUndConstraint(
|
||||
new Pair(lambdaExpression.getReturnType(),
|
||||
tphRetType,PairOperator.EQUALSDOT));
|
||||
@@ -160,12 +157,10 @@ public class TYPEStmt implements StatementVisitor{
|
||||
}
|
||||
|
||||
@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)
|
||||
public void visit(MethodCall methodCall) {
|
||||
methodCall.receiver.accept(this);
|
||||
//Overloading:
|
||||
Set<Constraint<Pair>> methodConstraints = new HashSet<>();
|
||||
Set<Constraint> methodConstraints = new HashSet<>();
|
||||
for(MethodAssumption m : this.getMethods(methodCall.name, methodCall.arglist, info)){
|
||||
GenericsResolver resolver = getResolverInstance();
|
||||
methodConstraints.add(generateConstraint(methodCall, m, info, resolver));
|
||||
@@ -225,8 +220,6 @@ public class TYPEStmt implements StatementVisitor{
|
||||
}
|
||||
|
||||
@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)
|
||||
public void visit(BinaryExpr binary) {
|
||||
binary.lexpr.accept(this);
|
||||
binary.rexpr.accept(this);
|
||||
@@ -234,7 +227,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
binary.operation.equals(BinaryExpr.Operator.MUL)||
|
||||
binary.operation.equals(BinaryExpr.Operator.MOD)||
|
||||
binary.operation.equals(BinaryExpr.Operator.ADD)||
|
||||
binary.operation.equals(BinaryExpr.Operator.SUB)) {
|
||||
binary.operation.equals(BinaryExpr.Operator.SUB)){
|
||||
Set<Constraint<Pair>> numericAdditionOrStringConcatenation = new HashSet<>();
|
||||
|
||||
// TODO PL 2018-11-06
|
||||
@@ -253,7 +246,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
numeric = new Constraint<>();
|
||||
numeric.add(new Pair(binary.lexpr.getType(), bytee, PairOperator.SMALLERDOT));
|
||||
numeric.add(new Pair(binary.rexpr.getType(), bytee, PairOperator.SMALLERDOT));
|
||||
numeric.add(new Pair(binary.getType(), integer, PairOperator.EQUALSDOT));
|
||||
numeric.add(new Pair(binary.getType(), integer, PairOperator.SMALLERDOT));
|
||||
numericAdditionOrStringConcatenation.add(numeric);
|
||||
}
|
||||
//PL eingefuegt 2018-07-17
|
||||
@@ -261,7 +254,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
numeric = new Constraint<>();
|
||||
numeric.add(new Pair(binary.lexpr.getType(), shortt, PairOperator.SMALLERDOT));
|
||||
numeric.add(new Pair(binary.rexpr.getType(), shortt, PairOperator.SMALLERDOT));
|
||||
numeric.add(new Pair(binary.getType(), integer, PairOperator.EQUALSDOT));
|
||||
numeric.add(new Pair(binary.getType(), integer, PairOperator.SMALLERDOT));
|
||||
numericAdditionOrStringConcatenation.add(numeric);
|
||||
}
|
||||
//PL eingefuegt 2018-07-17
|
||||
@@ -269,7 +262,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
numeric = new Constraint<>();
|
||||
numeric.add(new Pair(binary.lexpr.getType(), integer, PairOperator.SMALLERDOT));
|
||||
numeric.add(new Pair(binary.rexpr.getType(), integer, PairOperator.SMALLERDOT));
|
||||
numeric.add(new Pair(integer, binary.getType(), PairOperator.EQUALSDOT));
|
||||
numeric.add(new Pair(integer, binary.getType(), PairOperator.SMALLERDOT));
|
||||
numericAdditionOrStringConcatenation.add(numeric);
|
||||
}
|
||||
//PL eingefuegt 2018-07-17
|
||||
@@ -277,7 +270,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
numeric = new Constraint<>();
|
||||
numeric.add(new Pair(binary.lexpr.getType(), longg, PairOperator.SMALLERDOT));
|
||||
numeric.add(new Pair(binary.rexpr.getType(), longg, PairOperator.SMALLERDOT));
|
||||
numeric.add(new Pair(longg, binary.getType(), PairOperator.EQUALSDOT));
|
||||
numeric.add(new Pair(longg, binary.getType(), PairOperator.SMALLERDOT));
|
||||
numericAdditionOrStringConcatenation.add(numeric);
|
||||
}
|
||||
//PL eingefuegt 2018-07-17
|
||||
@@ -285,7 +278,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
numeric = new Constraint<>();
|
||||
numeric.add(new Pair(binary.lexpr.getType(), floatt, PairOperator.SMALLERDOT));
|
||||
numeric.add(new Pair(binary.rexpr.getType(), floatt, PairOperator.SMALLERDOT));
|
||||
numeric.add(new Pair(floatt, binary.getType(), PairOperator.EQUALSDOT));
|
||||
numeric.add(new Pair(floatt, binary.getType(), PairOperator.SMALLERDOT));
|
||||
numericAdditionOrStringConcatenation.add(numeric);
|
||||
}
|
||||
//PL eingefuegt 2018-07-17
|
||||
@@ -293,7 +286,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
numeric = new Constraint<>();
|
||||
numeric.add(new Pair(binary.lexpr.getType(), doublee, PairOperator.SMALLERDOT));
|
||||
numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT));
|
||||
numeric.add(new Pair(doublee, binary.getType(), PairOperator.EQUALSDOT));
|
||||
numeric.add(new Pair(doublee, binary.getType(), PairOperator.SMALLERDOT));
|
||||
numericAdditionOrStringConcatenation.add(numeric);
|
||||
}
|
||||
/* PL auskommentiert Anfang 2018-07-17
|
||||
@@ -317,9 +310,6 @@ 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());
|
||||
}
|
||||
constraintsSet.addOderConstraint(numericAdditionOrStringConcatenation);
|
||||
}else if(binary.operation.equals(BinaryExpr.Operator.LESSEQUAL) ||
|
||||
binary.operation.equals(BinaryExpr.Operator.BIGGEREQUAL) ||
|
||||
@@ -363,11 +353,10 @@ public class TYPEStmt implements StatementVisitor{
|
||||
//***ACHTUNG: Moeglicherweise oder und und-Contraint falsch
|
||||
*/
|
||||
//Testeise eingefuegt PL 2018-05-24
|
||||
//Hier sollte evtl. noch importe angefragt werden PL 2019-05-07
|
||||
constraintsSet.addUndConstraint(new Pair(binary.lexpr.getType(), number, PairOperator.SMALLERNEQDOT));
|
||||
constraintsSet.addUndConstraint(new Pair(binary.rexpr.getType(), number, PairOperator.SMALLERNEQDOT));
|
||||
//Rückgabetyp ist Boolean
|
||||
constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT));
|
||||
constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.SMALLERDOT));
|
||||
|
||||
//auskommentiert PL 2018-05-24
|
||||
//constraintsSet.addUndConstraint(new Pair(binary.lexpr.getType(), number, PairOperator.SMALLERDOT));
|
||||
@@ -379,7 +368,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
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));
|
||||
constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.SMALLERDOT));
|
||||
}else{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
@@ -560,7 +549,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
|
||||
protected Constraint<Pair> generateConstraint(MethodCall forMethod, MethodAssumption assumption,
|
||||
TypeInferenceBlockInformation info, GenericsResolver resolver){
|
||||
Constraint<Pair> methodConstraint = new Constraint<>();
|
||||
Constraint methodConstraint = new Constraint();
|
||||
ClassOrInterface receiverCl = assumption.getReceiver();
|
||||
/*
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
@@ -574,13 +563,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
|
||||
RefTypeOrTPHOrWildcardOrGeneric retType = assumption.getReceiverType(resolver);
|
||||
methodConstraint.add(new Pair(forMethod.receiver.getType(), retType,
|
||||
PairOperator.EQUALSDOT));//PL 2020-03-17 SMALLERDOT in EQUALSDOT umgewandelt, weil alle geerbten Methoden in den jeweilen Klassen enthalten sind.
|
||||
|
||||
//Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ANFANG
|
||||
//methodConstraint.add(new Pair(forMethod.receiverType, retType,
|
||||
// PairOperator.EQUALSDOT));
|
||||
//Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ENDE
|
||||
|
||||
PairOperator.SMALLERDOT));
|
||||
methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(),
|
||||
PairOperator.EQUALSDOT));
|
||||
methodConstraint.addAll(generateParameterConstraints(forMethod, assumption, info, resolver));
|
||||
@@ -595,10 +578,6 @@ public class TYPEStmt implements StatementVisitor{
|
||||
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
|
||||
// ret.add(new Pair(foMethod.argTypes.get(i), assType, PairOperator.EQUALSDOT));
|
||||
//Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ENDE
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -681,11 +660,8 @@ public class TYPEStmt implements StatementVisitor{
|
||||
protected Constraint<Pair> generateConstructorConstraint(NewClass forConstructor, MethodAssumption assumption,
|
||||
TypeInferenceBlockInformation info, GenericsResolver resolver){
|
||||
Constraint 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(),
|
||||
PairOperator.SMALLERDOT));
|
||||
//WELCHEN SINN MACHT DIESER CONSTRAINT???
|
||||
methodConstraint.addAll(generateParameterConstraints(forConstructor, assumption, info, resolver));
|
||||
return methodConstraint;
|
||||
}
|
||||
|
@@ -22,7 +22,6 @@ import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
|
||||
public class Match implements IMatch {
|
||||
|
||||
@Override
|
||||
//vorne muss das Pattern stehen
|
||||
//A<X> =. A<Integer> ==> True
|
||||
//A<Integer> =. A<X> ==> False
|
||||
public Optional<Unifier> match(ArrayList<UnifyPair> termsList) {
|
||||
|
@@ -0,0 +1,132 @@
|
||||
package de.dhbwstuttgart.typeinference.unify;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
|
||||
import com.google.common.collect.Ordering;
|
||||
|
||||
public class PartialOrderSet<E, F extends Ordering<E>> implements Set<E> {
|
||||
|
||||
//HashSet<E> hs = new HashSet<>();
|
||||
List<E> ve = new LinkedList<>();//new Vector<>();
|
||||
F ordering;
|
||||
|
||||
PartialOrderSet(F ordering) {
|
||||
this.ordering= ordering;
|
||||
}
|
||||
|
||||
PartialOrderSet(F ordering, Set<E> s) {
|
||||
this.ordering= ordering;
|
||||
this.addAll(s);
|
||||
}
|
||||
|
||||
PartialOrderSet(PartialOrderSet<E, F> pos) {
|
||||
this.ordering= pos.ordering;
|
||||
this.ve = new LinkedList<>(pos.ve);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return ve.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return ve.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return ve.contains(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return ve.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
return ve.toArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(T[] a) {
|
||||
return ve.toArray(a);
|
||||
}
|
||||
|
||||
public ArrayList<E> toArrayList() {
|
||||
return new ArrayList<>(ve);
|
||||
}
|
||||
|
||||
public List<E> toList() {
|
||||
return new LinkedList<>(ve);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(E e) {
|
||||
if (this.contains(e)) {
|
||||
return false;
|
||||
}
|
||||
//hs.add(e);
|
||||
for(int i = 0; i< ve.size(); i++) {
|
||||
if (ordering.compare(e, ve.get(i)) == -1) {
|
||||
ve.add(i,e);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
ve.add(e);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
//hs.remove(o);
|
||||
return ve.remove(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
return ve.containsAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends E> c) {
|
||||
Boolean ret = false;
|
||||
Iterator<? extends E> cit = c.iterator();
|
||||
while(cit.hasNext()) {
|
||||
Boolean retnew = this.add(cit.next());
|
||||
ret = ret || retnew;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
//hs.retainAll(c);
|
||||
return ve.retainAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
//hs.removeAll(c);
|
||||
return ve.removeAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
//hs.clear();
|
||||
ve.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ve.toString();
|
||||
}
|
||||
}
|
@@ -4,12 +4,10 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
@@ -30,7 +28,6 @@ import de.dhbwstuttgart.typeinference.unify.distributeVariance;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* Implementation of the type inference rules.
|
||||
@@ -39,13 +36,13 @@ import java.io.Writer;
|
||||
*/
|
||||
public class RuleSet implements IRuleSet{
|
||||
|
||||
Writer logFile;
|
||||
FileWriter logFile;
|
||||
|
||||
public RuleSet() {
|
||||
super();
|
||||
}
|
||||
|
||||
RuleSet(Writer logFile) {
|
||||
RuleSet(FileWriter logFile) {
|
||||
this.logFile = logFile;
|
||||
}
|
||||
|
||||
@@ -622,12 +619,8 @@ public class RuleSet implements IRuleSet{
|
||||
return succ ? permutation : new int[0];
|
||||
}
|
||||
|
||||
public Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs) {
|
||||
return subst(pairs, new ArrayList<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs, List<Set<Set<UnifyPair>>> oderConstraints) {
|
||||
public Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs) {
|
||||
HashMap<UnifyType, Integer> typeMap = new HashMap<>();
|
||||
|
||||
Stack<UnifyType> occuringTypes = new Stack<>();
|
||||
@@ -667,35 +660,13 @@ public class RuleSet implements IRuleSet{
|
||||
if(lhsType != null
|
||||
//&& !((rhsType = pair.getRhsType()) instanceof PlaceholderType) //PL geloescht am 2017-09-29 Begründung: auch Typvariablen muessen ersetzt werden.
|
||||
&& typeMap.get(lhsType) > 1 // The type occurs in more pairs in the set than just the recent pair.
|
||||
&& !rhsType.getTypeParams().occurs(lhsType)
|
||||
&& !((rhsType instanceof WildcardType) && ((WildcardType)rhsType).getWildcardedType().equals(lhsType))) //PL eigefuegt 2018-02-18
|
||||
{
|
||||
&& !rhsType.getTypeParams().occurs(lhsType)) {
|
||||
Unifier uni = new Unifier(lhsType, rhsType);
|
||||
result = result.stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(ArrayList::new));
|
||||
result1 = result1.stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(LinkedList::new));
|
||||
|
||||
Function<? super Set<UnifyPair>,? extends HashSet<UnifyPair>> applyUni = b -> b.stream().map(
|
||||
x -> uni.apply(pair,x)).collect(Collectors.toCollection(HashSet::new));
|
||||
List<Set<Set<UnifyPair>>> oderConstraintsRet = new ArrayList<>();
|
||||
for(Set<Set<UnifyPair>> oc : oderConstraints) {
|
||||
//Set<Set<UnifyPair>> ocRet = new HashSet<>();
|
||||
//for(Set<UnifyPair> cs : oc) {
|
||||
Set<Set<UnifyPair>> csRet = oc.stream().map(applyUni).collect(Collectors.toCollection(HashSet::new));
|
||||
oderConstraintsRet.add(csRet);
|
||||
//}
|
||||
}
|
||||
oderConstraints.replaceAll(oc -> oc.stream().map(applyUni).collect(Collectors.toCollection(HashSet::new)));
|
||||
/*
|
||||
oderConstraints = oderConstraints.stream().map(
|
||||
a -> a.stream().map(applyUni
|
||||
//b -> b.stream().map(
|
||||
// x -> uni.apply(pair,x)).collect(Collectors.toCollection(HashSet::new) )
|
||||
).collect(Collectors.toCollection(HashSet::new))
|
||||
).collect(Collectors.toList(ArrayList::new));
|
||||
}
|
||||
*/
|
||||
applied = true;
|
||||
}
|
||||
|
||||
result.add(pair);
|
||||
}
|
||||
|
||||
@@ -974,8 +945,6 @@ public class RuleSet implements IRuleSet{
|
||||
|
||||
UnifyType extendedType = ((ExtendsType)lhsType).getExtendedType();
|
||||
|
||||
if (extendedType.equals(rhsType)) return Optional.empty(); //PL 2019-02-18 eingefügt ? extends a <.? a
|
||||
|
||||
boolean isGen = extendedType instanceof PlaceholderType && !((PlaceholderType) extendedType).isGenerated();
|
||||
|
||||
Set<UnifyPair> result = new HashSet<>();
|
||||
@@ -1002,8 +971,6 @@ public class RuleSet implements IRuleSet{
|
||||
|
||||
UnifyType superedType = ((SuperType)lhsType).getSuperedType();
|
||||
|
||||
if (superedType.equals(rhsType)) return Optional.empty(); //PL 2019-02-18 eingefügt ? super a <.? a
|
||||
|
||||
boolean isGen = superedType instanceof PlaceholderType && !((PlaceholderType) superedType).isGenerated();
|
||||
|
||||
Set<UnifyPair> result = new HashSet<>();
|
||||
|
@@ -1,89 +1,47 @@
|
||||
package de.dhbwstuttgart.typeinference.unify;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.OrderingUnifyPair;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
|
||||
public class TypeUnify {
|
||||
|
||||
/**
|
||||
* unify parallel ohne result modell
|
||||
* @param undConstrains
|
||||
* @param oderConstraints
|
||||
* @param fc
|
||||
* @param logFile
|
||||
* @param log
|
||||
* @param cons
|
||||
* @return
|
||||
*/
|
||||
public Set<Set<UnifyPair>> unify(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret, UnifyTaskModel usedTasks) {
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, usedTasks);
|
||||
public Set<Set<UnifyPair>> unify(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, FileWriter logFile, Boolean log, ConstraintSet<Pair> cons) {
|
||||
List<PartialOrderSet<Set<UnifyPair>,OrderingUnifyPair>> oderConstraintsPartial =
|
||||
oderConstraints.stream().map(x -> new PartialOrderSet<Set<UnifyPair>,OrderingUnifyPair>(new OrderingUnifyPair(fc),x)).collect(Collectors.toList());
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraintsPartial, fc, true, logFile, log, 0, new UnifyResultModel(), cons);
|
||||
ForkJoinPool pool = new ForkJoinPool();
|
||||
pool.invoke(unifyTask);
|
||||
Set<Set<UnifyPair>> res = unifyTask.join();
|
||||
try {
|
||||
logFile.write("\nnoShortendElements: " + unifyTask.noShortendElements + "\n");
|
||||
logFile.flush();
|
||||
}
|
||||
catch (IOException e) {
|
||||
System.err.println("no log-File");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* unify asynchron mit Rückgabe UnifyResultModel ohne dass alle results gesammelt sind
|
||||
* @param undConstrains
|
||||
* @param oderConstraints
|
||||
* @param fc
|
||||
* @param logFile
|
||||
* @param log
|
||||
* @param cons
|
||||
* @param ret
|
||||
* @return
|
||||
*/
|
||||
public UnifyResultModel unifyAsync(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret, UnifyTaskModel usedTasks) {
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, usedTasks);
|
||||
public UnifyResultModel unifyAsync(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, FileWriter logFile, Boolean log, ConstraintSet<Pair> cons, UnifyResultModel ret) {
|
||||
List<PartialOrderSet<Set<UnifyPair>,OrderingUnifyPair>> oderConstraintsPartial =
|
||||
oderConstraints.stream().map(x -> new PartialOrderSet<Set<UnifyPair>,OrderingUnifyPair>(new OrderingUnifyPair(fc),x)).collect(Collectors.toList());
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraintsPartial, fc, true, logFile, log, 0, ret, cons);
|
||||
ForkJoinPool pool = new ForkJoinPool();
|
||||
pool.invoke(unifyTask);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* unify parallel mit Rückgabe UnifyResultModel nachdem alle results gesammelt sind
|
||||
* @param undConstrains
|
||||
* @param oderConstraints
|
||||
* @param fc
|
||||
* @param logFile
|
||||
* @param log
|
||||
* @param cons
|
||||
* @param ret
|
||||
* @return
|
||||
*/
|
||||
public UnifyResultModel unifyParallel(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret, UnifyTaskModel usedTasks) {
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, usedTasks);
|
||||
public UnifyResultModel unifyParallel(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, FileWriter logFile, Boolean log, ConstraintSet<Pair> cons, UnifyResultModel ret) {
|
||||
List<PartialOrderSet<Set<UnifyPair>,OrderingUnifyPair>> oderConstraintsPartial =
|
||||
oderConstraints.stream().map(x -> new PartialOrderSet<Set<UnifyPair>,OrderingUnifyPair>(new OrderingUnifyPair(fc),x)).collect(Collectors.toList());
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraintsPartial, fc, true, logFile, log, 0, ret, cons);
|
||||
ForkJoinPool pool = new ForkJoinPool();
|
||||
pool.invoke(unifyTask);
|
||||
Set<Set<UnifyPair>> res = unifyTask.join();
|
||||
try {
|
||||
logFile.write("\nnoShortendElements: " + unifyTask.noShortendElements +"\n");
|
||||
logFile.flush();
|
||||
}
|
||||
catch (IOException e) {
|
||||
System.err.println("no log-File");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -95,26 +53,11 @@ public class TypeUnify {
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* unify sequentiell mit oderconstraints
|
||||
* @param undConstrains
|
||||
* @param oderConstraints
|
||||
* @param fc
|
||||
* @param logFile
|
||||
* @param log
|
||||
* @param cons
|
||||
* @return
|
||||
*/
|
||||
public Set<Set<UnifyPair>> unifyOderConstraints(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret, UnifyTaskModel usedTasks) {
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, false, logFile, log, 0, ret, usedTasks);
|
||||
public Set<Set<UnifyPair>> unifyOderConstraints(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, FileWriter logFile, Boolean log, ConstraintSet<Pair> cons) {
|
||||
List<PartialOrderSet<Set<UnifyPair>,OrderingUnifyPair>> oderConstraintsPartial =
|
||||
oderConstraints.stream().map(x -> new PartialOrderSet<Set<UnifyPair>,OrderingUnifyPair>(new OrderingUnifyPair(fc),x)).collect(Collectors.toList());
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraintsPartial, fc, false, logFile, log, 0, new UnifyResultModel(), cons);
|
||||
Set<Set<UnifyPair>> res = unifyTask.compute();
|
||||
try {
|
||||
logFile.write("\nnoShortendElements: " + unifyTask.noShortendElements +"\n");
|
||||
logFile.flush();
|
||||
}
|
||||
catch (IOException e) {
|
||||
System.err.println("no log-File");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@@ -1,9 +1,6 @@
|
||||
package de.dhbwstuttgart.typeinference.unify;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -12,14 +9,15 @@ import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.OrderingUnifyPair;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
|
||||
public class TypeUnify2Task extends TypeUnifyTask {
|
||||
|
||||
Set<Set<UnifyPair>> setToFlatten;
|
||||
|
||||
public TypeUnify2Task(Set<Set<UnifyPair>> setToFlatten, Set<UnifyPair> eq, List<Set<Set<UnifyPair>>> oderConstraints, Set<UnifyPair> nextSetElement, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm, UnifyTaskModel usedTasks) {
|
||||
super(eq, oderConstraints, fc, parallel, logFile, log, rekTiefe, urm, usedTasks);
|
||||
public TypeUnify2Task(Set<Set<UnifyPair>> setToFlatten, Set<UnifyPair> eq, List<PartialOrderSet<Set<UnifyPair>,OrderingUnifyPair>> oderConstraints, Set<UnifyPair> nextSetElement, IFiniteClosure fc, boolean parallel, FileWriter logFile, Boolean log, int rekTiefe, UnifyResultModel urm, ConstraintSet<Pair> cons) {
|
||||
super(eq, oderConstraints, fc, parallel, logFile, log, rekTiefe, urm, cons);
|
||||
this.setToFlatten = setToFlatten;
|
||||
this.nextSetElement = nextSetElement;
|
||||
}
|
||||
@@ -34,31 +32,12 @@ public class TypeUnify2Task extends TypeUnifyTask {
|
||||
System.out.println("two");
|
||||
}
|
||||
one = true;
|
||||
Set<Set<UnifyPair>> res = unify2(setToFlatten, eq, oderConstraintsField, fc, parallel, rekTiefeField, true);
|
||||
Set<Set<UnifyPair>> res = unify2(setToFlatten, eq, oderConstraintsField, fc, parallel, rekTiefeField);
|
||||
/*if (isUndefinedPairSetSet(res)) {
|
||||
return new HashSet<>(); }
|
||||
else
|
||||
*/
|
||||
//writeLog("xxx");
|
||||
//noOfThread--;
|
||||
synchronized (usedTasks) {
|
||||
if (this.myIsCancelled()) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
else {
|
||||
noOfThread--;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void closeLogFile() {
|
||||
|
||||
try {
|
||||
logFile.close();
|
||||
}
|
||||
catch (IOException ioE) {
|
||||
System.err.println("no log-File" + thNo);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,31 +1,13 @@
|
||||
package de.dhbwstuttgart.typeinference.unify;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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;
|
||||
|
||||
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) {
|
||||
@@ -36,20 +18,7 @@ public class UnifyResultModel {
|
||||
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());
|
||||
public void notify(List<ResultSet> newResult) {
|
||||
UnifyResultEvent evt = new UnifyResultEvent(newResult);
|
||||
|
||||
for (UnifyResultListener listener : listeners) {
|
||||
|
@@ -1,18 +0,0 @@
|
||||
package de.dhbwstuttgart.typeinference.unify;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class UnifyTaskModel {
|
||||
|
||||
ArrayList<TypeUnifyTask> usedTasks = new ArrayList<>();
|
||||
|
||||
public synchronized void add(TypeUnifyTask t) {
|
||||
usedTasks.add(t);
|
||||
}
|
||||
|
||||
public synchronized void cancel() {
|
||||
for(TypeUnifyTask t : usedTasks) {
|
||||
t.myCancel(true);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,6 +1,5 @@
|
||||
package de.dhbwstuttgart.typeinference.unify.interfaces;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -86,13 +85,6 @@ public interface IRuleSet {
|
||||
public Optional<UnifyPair> adaptExt(UnifyPair pair, IFiniteClosure fc);
|
||||
public 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<Set<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.
|
||||
|
@@ -2,7 +2,6 @@ package de.dhbwstuttgart.typeinference.unify.model;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@@ -13,7 +12,6 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.collect.Ordering;
|
||||
@@ -34,7 +32,7 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify;
|
||||
public class FiniteClosure //extends Ordering<UnifyType> //entfernt PL 2018-12-11
|
||||
implements IFiniteClosure {
|
||||
|
||||
Writer logFile;
|
||||
FileWriter logFile;
|
||||
static Boolean log = false;
|
||||
public void setLogTrue() {
|
||||
log = true;
|
||||
@@ -68,7 +66,7 @@ implements IFiniteClosure {
|
||||
/**
|
||||
* Creates a new instance using the inheritance tree defined in the pairs.
|
||||
*/
|
||||
public FiniteClosure(Set<UnifyPair> pairs, Writer logFile) {
|
||||
public FiniteClosure(Set<UnifyPair> pairs, FileWriter logFile) {
|
||||
this.logFile = logFile;
|
||||
this.pairs = new HashSet<>(pairs);
|
||||
inheritanceGraph = new HashMap<UnifyType, Node<UnifyType>>();
|
||||
@@ -658,16 +656,11 @@ implements IFiniteClosure {
|
||||
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)));
|
||||
right = new ReferenceType("Vector", new TypeParams(new ArrayList<>(al)));
|
||||
*/
|
||||
/*
|
||||
List<UnifyType> al = new ArrayList<>();
|
||||
@@ -711,22 +704,15 @@ implements IFiniteClosure {
|
||||
HashSet<UnifyPair> hs = new HashSet<>();
|
||||
hs.add(up);
|
||||
Set<UnifyPair> smallerRes = unifyTask.applyTypeUnificationRules(hs, this);
|
||||
/*
|
||||
//if (left.getName().equals("Matrix") || right.getName().equals("Matrix"))
|
||||
if (left.getName().equals("Matrix") || right.getName().equals("Matrix"))
|
||||
{try {
|
||||
logFile.write("\nsmallerRes: " + smallerRes);//"smallerHash: " + greaterHash.toString());
|
||||
logFile.flush();
|
||||
}
|
||||
catch (IOException e) {
|
||||
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()))
|
||||
);
|
||||
long smallerLen = smallerRes.stream().filter(delFun).count();
|
||||
long smallerLen = smallerRes.stream().filter(x -> !(x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)).count();
|
||||
if (smallerLen == 0) return -1;
|
||||
else {
|
||||
up = new UnifyPair(right, left, pairop);
|
||||
@@ -734,17 +720,15 @@ implements IFiniteClosure {
|
||||
hs = new HashSet<>();
|
||||
hs.add(up);
|
||||
Set<UnifyPair> greaterRes = unifyTask.applyTypeUnificationRules(hs, this);
|
||||
/*
|
||||
//if (left.getName().equals("Matrix") || right.getName().equals("Matrix"))
|
||||
if (left.getName().equals("Matrix") || right.getName().equals("Matrix"))
|
||||
{try {
|
||||
logFile.write("\ngreaterRes: " + greaterRes);//"smallerHash: " + greaterHash.toString());
|
||||
logFile.flush();
|
||||
}
|
||||
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();
|
||||
long greaterLen = greaterRes.stream().filter(x -> !(x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)).count();
|
||||
if (greaterLen == 0) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user