forked from JavaTX/JavaCompilerCore
Compare commits
8 Commits
matrixTest
...
parseSigna
Author | SHA1 | Date | |
---|---|---|---|
|
904bdca2f4 | ||
|
af4db1817a | ||
|
d945947362 | ||
|
a0c25a517d | ||
|
c35577f948 | ||
|
fc7844c6a4 | ||
|
4078239815 | ||
|
39bde24df7 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
CVS
|
||||
bin
|
||||
*.class
|
||||
*.log
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
@@ -14,9 +15,11 @@ bin
|
||||
.classpath
|
||||
*.iml
|
||||
.idea/
|
||||
/target/
|
||||
.DS_Store
|
||||
.project
|
||||
.settings/
|
||||
/target/
|
||||
|
||||
#
|
||||
manually/
|
||||
|
3
Makefile
3
Makefile
@@ -1,3 +0,0 @@
|
||||
NoOptParallel:
|
||||
mvn -DskipTests package
|
||||
cp target/JavaTXcompiler-0.1-jar-with-dependencies.jar target/JavaTXcompiler-0.1-jar-with-dependencies_NoOptParallel.jar
|
4
pom.xml
4
pom.xml
@@ -54,8 +54,8 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<compilerArgs>--enable-preview</compilerArgs>
|
||||
<source>21</source>
|
||||
<target>21</target>
|
||||
<source>19</source>
|
||||
<target>19</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
//import java.util.Vector;
|
||||
import java.util.Vector;
|
||||
import java.lang.Integer;
|
||||
import java.lang.Float;
|
||||
//import java.lang.Byte;
|
||||
@@ -6,11 +6,21 @@ import java.lang.Float;
|
||||
|
||||
public class Scalar extends Vector<Integer> {
|
||||
|
||||
Scalar(v) {
|
||||
Integer i;
|
||||
i = 0;
|
||||
while(i < v.size()) {
|
||||
this.add(v.elementAt(i));
|
||||
i=i+1;
|
||||
}
|
||||
}
|
||||
|
||||
mul(v) {
|
||||
var ret = 0;
|
||||
var i = 0;
|
||||
while(i < size()) {
|
||||
ret = ret + this.elementAt(i) * v.elementAt(i);
|
||||
i = i+1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
11
resources/bytecode/javFiles/TXGenerics.jav
Normal file
11
resources/bytecode/javFiles/TXGenerics.jav
Normal file
@@ -0,0 +1,11 @@
|
||||
import java.lang.String;
|
||||
|
||||
class TXGenerics {
|
||||
a;
|
||||
b;
|
||||
|
||||
test() {
|
||||
var c = new Cycle();
|
||||
c.m(a, b);
|
||||
}
|
||||
}
|
@@ -5,7 +5,7 @@ public class TestContraVariant {
|
||||
x = y;
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
main(x) {
|
||||
return m(x);
|
||||
}
|
||||
|
@@ -1,10 +1,12 @@
|
||||
public class TestTwoCalls {
|
||||
|
||||
// <O> O -> O
|
||||
id(b) {
|
||||
var c = b;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
// <T, S> (S, T) -> T
|
||||
main(x,y) {
|
||||
id(x);
|
||||
return id(y);
|
||||
|
@@ -1000,7 +1000,7 @@ public class Codegen {
|
||||
private void generateConstructor(TargetConstructor constructor) {
|
||||
MethodVisitor mv = cw.visitMethod(constructor.access() | ACC_PUBLIC, "<init>", constructor.getDescriptor(), constructor.getSignature(), null);
|
||||
if (constructor.txGenerics() != null)
|
||||
mv.visitAttribute(new JavaTXSignatureAttribute(cw.newConst(constructor.getTXSignature())));
|
||||
mv.visitAttribute(new JavaTXSignatureAttribute(constructor.getTXSignature()));
|
||||
|
||||
mv.visitCode();
|
||||
var state = new State(null, mv, 1);
|
||||
@@ -1027,7 +1027,7 @@ public class Codegen {
|
||||
// TODO The older codegen has set ACC_PUBLIC for all methods, good for testing but bad for everything else
|
||||
MethodVisitor mv = cw.visitMethod(method.access() | ACC_PUBLIC, method.name(), method.getDescriptor(), method.getSignature(), null);
|
||||
if (method.txSignature() != null) {
|
||||
mv.visitAttribute(new JavaTXSignatureAttribute(cw.newConst(method.getTXSignature())));
|
||||
mv.visitAttribute(new JavaTXSignatureAttribute(method.getTXSignature()));
|
||||
}
|
||||
|
||||
System.out.println(method.getDescriptor());
|
||||
@@ -1044,11 +1044,14 @@ public class Codegen {
|
||||
}
|
||||
|
||||
private static String generateSignature(TargetClass clazz, Set<TargetGeneric> generics) {
|
||||
String ret = "<";
|
||||
for (var generic : generics) {
|
||||
ret += generic.name() + ":" + generic.bound().toDescriptor();
|
||||
String ret = "";
|
||||
if (generics.size() > 0) {
|
||||
ret += "<";
|
||||
for (var generic : generics) {
|
||||
ret += generic.name() + ":" + generic.bound().toDescriptor();
|
||||
}
|
||||
ret += ">";
|
||||
}
|
||||
ret += ">";
|
||||
ret += clazz.superType().toDescriptor();
|
||||
|
||||
return ret;
|
||||
@@ -1060,7 +1063,7 @@ public class Codegen {
|
||||
clazz.implementingInterfaces().stream().map(TargetType::toSignature).toArray(String[]::new)
|
||||
);
|
||||
if (clazz.txGenerics() != null)
|
||||
cw.visitAttribute(new JavaTXSignatureAttribute(cw.newConst(generateSignature(clazz, clazz.txGenerics()))));
|
||||
cw.visitAttribute(new JavaTXSignatureAttribute(generateSignature(clazz, clazz.txGenerics())));
|
||||
|
||||
clazz.fields().forEach(this::generateField);
|
||||
clazz.constructors().forEach(this::generateConstructor);
|
||||
|
@@ -3,10 +3,13 @@ package de.dhbwstuttgart.bytecode;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
public class JavaTXSignatureAttribute extends Attribute {
|
||||
final int signature;
|
||||
public String signature;
|
||||
|
||||
protected JavaTXSignatureAttribute(int signature) {
|
||||
public JavaTXSignatureAttribute() {
|
||||
super("JavaTXSignature");
|
||||
}
|
||||
protected JavaTXSignatureAttribute(String signature) {
|
||||
this();
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
@@ -14,13 +17,14 @@ public class JavaTXSignatureAttribute extends Attribute {
|
||||
protected Attribute read(ClassReader classReader, int offset, int length, char[] charBuffer, int codeAttributeOffset, Label[] labels) {
|
||||
var data = new byte[length];
|
||||
System.arraycopy(classReader.b, offset, data, 0, length);
|
||||
return new JavaTXSignatureAttribute(data[0] << 8 | data[1]);
|
||||
var constantPoolOffset = data[0] << 8 | data[1];
|
||||
return new JavaTXSignatureAttribute((String) classReader.readConst(constantPoolOffset, charBuffer));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ByteVector write(ClassWriter classWriter, byte[] code, int codeLength, int maxStack, int maxLocals) {
|
||||
var data = new ByteVector();
|
||||
data.putShort(this.signature);
|
||||
data.putShort(classWriter.newConst(this.signature));
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
@@ -58,7 +58,6 @@ import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -70,12 +69,11 @@ public class JavaTXCompiler {
|
||||
|
||||
//public static JavaTXCompiler INSTANCE;
|
||||
final CompilationEnvironment environment;
|
||||
Boolean resultmodel = true;
|
||||
Boolean resultmodel = false;
|
||||
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
||||
Boolean log = false; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll?
|
||||
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
||||
private final DirectoryClassLoader classLoader;
|
||||
static Writer statistics;
|
||||
|
||||
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
|
||||
this(Arrays.asList(sourceFile), null);
|
||||
@@ -88,9 +86,6 @@ public class JavaTXCompiler {
|
||||
this(sourceFiles, null);
|
||||
}
|
||||
public JavaTXCompiler(List<File> sources, List<File> contextPath) throws IOException, ClassNotFoundException {
|
||||
//statistics = new FileWriter(new File(System.getProperty("user.dir") + "/" + sources.get(0).getName() + "_"+ new Timestamp(System.currentTimeMillis())));
|
||||
statistics = new OutputStreamWriter(new NullOutputStream());
|
||||
statistics.write("test");
|
||||
if(contextPath == null || contextPath.isEmpty()){
|
||||
//When no contextPaths are given, the working directory is the sources root
|
||||
contextPath = Lists.newArrayList(new File(System.getProperty("user.dir")));
|
||||
@@ -583,7 +578,6 @@ public class JavaTXCompiler {
|
||||
unifyCons = unifyCons.map(distributeInnerVars);
|
||||
logFile.write("\nUnify_distributeInnerVars: " + unifyCons.toString());
|
||||
TypeUnify unify = new TypeUnify();
|
||||
unify.statistics = statistics;
|
||||
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
|
||||
logFile.write("FC:\\" + finiteClosure.toString() + "\n");
|
||||
for (SourceFile sf : this.sourceFiles.values()) {
|
||||
@@ -736,7 +730,6 @@ public class JavaTXCompiler {
|
||||
System.out.println("Constraints for Generated Generics: " + " ???");
|
||||
logFile.write("RES_FINAL: " + li.getResults().toString() + "\n");
|
||||
logFile.flush();
|
||||
statistics.close();
|
||||
return li.getResults();
|
||||
}
|
||||
/* UnifyResultModel End */
|
||||
@@ -772,7 +765,6 @@ public class JavaTXCompiler {
|
||||
} catch (IOException e) {
|
||||
System.err.println("kein LogFile");
|
||||
}
|
||||
statistics.close();
|
||||
return results.stream()
|
||||
.map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons)))))
|
||||
.collect(Collectors.toList());
|
||||
|
@@ -49,4 +49,17 @@ public class GenericDeclarationList extends SyntaxTreeNode implements Iterable<G
|
||||
public String toString() {
|
||||
return this.gtvs.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
GenericDeclarationList that = (GenericDeclarationList) o;
|
||||
return gtvs.equals(that.gtvs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(gtvs);
|
||||
}
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Entspricht einem GenericTypeVar, jedoch mit Bounds
|
||||
@@ -45,7 +46,7 @@ public class GenericTypeVar extends SyntaxTreeNode
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "BoGTV " + this.name;
|
||||
return "BoGTV " + this.name + " " + this.bounds;
|
||||
}
|
||||
|
||||
public String getName(){
|
||||
@@ -61,4 +62,17 @@ public class GenericTypeVar extends SyntaxTreeNode
|
||||
public void accept(ASTVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
GenericTypeVar that = (GenericTypeVar) o;
|
||||
return bounds.equals(that.bounds) && name.equals(that.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(bounds, name);
|
||||
}
|
||||
}
|
||||
|
@@ -1,19 +1,16 @@
|
||||
package de.dhbwstuttgart.syntaxtree.factory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.*;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.bytecode.JavaTXSignatureAttribute;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.GenericContext;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
||||
import de.dhbwstuttgart.syntaxtree.Field;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
@@ -22,7 +19,14 @@ import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Block;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
||||
import de.dhbwstuttgart.syntaxtree.type.WildcardType;
|
||||
import de.dhbwstuttgart.target.tree.type.TargetRefType;
|
||||
import de.dhbwstuttgart.util.Pair;
|
||||
import javassist.bytecode.SignatureAttribute;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.objectweb.asm.*;
|
||||
import org.objectweb.asm.signature.SignatureReader;
|
||||
import org.objectweb.asm.signature.SignatureVisitor;
|
||||
|
||||
/**
|
||||
* Anmerkung:
|
||||
@@ -32,21 +36,76 @@ import org.antlr.v4.runtime.Token;
|
||||
public class ASTFactory {
|
||||
|
||||
public static ClassOrInterface createClass(java.lang.Class jreClass){
|
||||
|
||||
// TODO Inner classes
|
||||
|
||||
var methodSignatures = new HashMap<Pair<String, String>, String>();
|
||||
String classSignature = null;
|
||||
|
||||
// Load class with asm to figure out if there's a JavaTX signature
|
||||
try {
|
||||
var path = jreClass.getName().replace('.', '/') + ".class";
|
||||
var classLoader = jreClass.getClassLoader();
|
||||
if (classLoader != null) {
|
||||
var bytes = IOUtils.toByteArray(Objects.requireNonNull(classLoader.getResourceAsStream(path)));
|
||||
var classReader = new ClassReader(bytes);
|
||||
var classVisitor = new ClassVisitor(Opcodes.ASM7) {
|
||||
String classSignature;
|
||||
@Override
|
||||
public void visitAttribute(Attribute attribute) {
|
||||
if (attribute.type.equals("JavaTXSignature")) {
|
||||
classSignature = ((JavaTXSignatureAttribute) attribute).signature;
|
||||
}
|
||||
super.visitAttribute(attribute);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
|
||||
classSignature = signature;
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
|
||||
|
||||
methodSignatures.put(new Pair<>(name, descriptor), signature);
|
||||
return new MethodVisitor(Opcodes.ASM7) {
|
||||
@Override
|
||||
public void visitAttribute(Attribute attribute) {
|
||||
if (attribute.type.equals("JavaTXSignature")) {
|
||||
methodSignatures.put(new Pair<>(name, descriptor), ((JavaTXSignatureAttribute) attribute).signature);
|
||||
}
|
||||
super.visitAttribute(attribute);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
classReader.accept(classVisitor, new Attribute[]{new JavaTXSignatureAttribute()}, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
|
||||
classSignature = classVisitor.classSignature;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Skip
|
||||
}
|
||||
|
||||
JavaClassName name = new JavaClassName(jreClass.getName());
|
||||
List<Method> methoden = new ArrayList<>();
|
||||
List<de.dhbwstuttgart.syntaxtree.Constructor> konstruktoren = new ArrayList<>();
|
||||
for(java.lang.reflect.Constructor constructor : jreClass.getDeclaredConstructors()){
|
||||
createConstructor(constructor, jreClass).map(c -> konstruktoren.add(c));
|
||||
for(java.lang.reflect.Constructor constructor : jreClass.getConstructors()){
|
||||
var signature = methodSignatures.get(new Pair<>(constructor.getName(), org.objectweb.asm.Type.getConstructorDescriptor(constructor)));
|
||||
createConstructor(constructor, signature, jreClass).map(c -> konstruktoren.add(c));
|
||||
}
|
||||
Set<java.lang.reflect.Method> allMethods = new HashSet<>(Arrays.asList(jreClass.getMethods()));
|
||||
Set<java.lang.reflect.Method> allDeclaredMethods = new HashSet<>(Arrays.asList(jreClass.getDeclaredMethods()));
|
||||
Set<java.lang.reflect.Method> allInheritedMethods = new HashSet<>(allMethods);
|
||||
allInheritedMethods.removeAll(allDeclaredMethods);
|
||||
for(java.lang.reflect.Method method : allDeclaredMethods){
|
||||
methoden.add(createMethod(method, jreClass, false));
|
||||
var signature = methodSignatures.get(new Pair<>(method.getName(), org.objectweb.asm.Type.getMethodDescriptor(method)));
|
||||
methoden.add(createMethod(method, signature, jreClass, false));
|
||||
}
|
||||
for(java.lang.reflect.Method method : allInheritedMethods){
|
||||
methoden.add(createMethod(method, jreClass, true));
|
||||
var signature = methodSignatures.get(new Pair<>(method.getName(), org.objectweb.asm.Type.getMethodDescriptor(method)));
|
||||
methoden.add(createMethod(method, signature, jreClass, true));
|
||||
}
|
||||
List<Field> felder = new ArrayList<>();
|
||||
for(java.lang.reflect.Field field : jreClass.getDeclaredFields()){
|
||||
@@ -72,7 +131,8 @@ public class ASTFactory {
|
||||
for(Type jreInterface : jreClass.getGenericInterfaces()){
|
||||
implementedInterfaces.add((RefType) createType(jreInterface));
|
||||
}
|
||||
GenericDeclarationList genericDeclarationList = createGenerics(jreClass.getTypeParameters(), jreClass, null);
|
||||
|
||||
GenericDeclarationList genericDeclarationList = createGenerics(jreClass.getTypeParameters(), jreClass, null, classSignature);
|
||||
|
||||
Token offset = new NullToken(); //Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde
|
||||
|
||||
@@ -87,7 +147,7 @@ public class ASTFactory {
|
||||
// return createClass(classType).getType();
|
||||
//}
|
||||
|
||||
private static Optional<de.dhbwstuttgart.syntaxtree.Constructor> createConstructor(Constructor constructor, Class inClass) {
|
||||
private static Optional<de.dhbwstuttgart.syntaxtree.Constructor> createConstructor(Constructor constructor, String signature, Class inClass) {
|
||||
String name = constructor.getName();
|
||||
RefTypeOrTPHOrWildcardOrGeneric returnType = createType(inClass);
|
||||
Parameter[] jreParams = constructor.getParameters();
|
||||
@@ -101,7 +161,7 @@ public class ASTFactory {
|
||||
}
|
||||
ParameterList parameterList = new ParameterList(params, new NullToken());
|
||||
Block block = new Block(new ArrayList<Statement>(), new NullToken());
|
||||
GenericDeclarationList gtvDeclarations = createGenerics(constructor.getTypeParameters(), inClass, constructor.getName());
|
||||
GenericDeclarationList gtvDeclarations = createGenerics(constructor.getTypeParameters(), inClass, constructor.getName(), signature);
|
||||
Token offset = new NullToken();
|
||||
int modifier = constructor.getModifiers();
|
||||
|
||||
@@ -112,7 +172,7 @@ public class ASTFactory {
|
||||
return Optional.of(new de.dhbwstuttgart.syntaxtree.Constructor(modifier, name,returnType, parameterList, block, gtvDeclarations, offset /*, new ArrayList<>() geloescht PL 2018-11-24 */));
|
||||
}
|
||||
|
||||
public static Method createMethod(java.lang.reflect.Method jreMethod, java.lang.Class inClass, Boolean isInherited){
|
||||
public static Method createMethod(java.lang.reflect.Method jreMethod, String signature, java.lang.Class inClass, Boolean isInherited){
|
||||
String name = jreMethod.getName();
|
||||
RefTypeOrTPHOrWildcardOrGeneric returnType;
|
||||
Type jreRetType;
|
||||
@@ -133,19 +193,142 @@ public class ASTFactory {
|
||||
}
|
||||
ParameterList parameterList = new ParameterList(params, new NullToken());
|
||||
Block block = new Block(new ArrayList<Statement>(), new NullToken());
|
||||
GenericDeclarationList gtvDeclarations = createGenerics(jreMethod.getTypeParameters(), inClass, jreMethod.getName());
|
||||
GenericDeclarationList gtvDeclarations = createGenerics(jreMethod.getTypeParameters(), inClass, jreMethod.getName(), signature);
|
||||
Token offset = new NullToken();
|
||||
|
||||
return new Method(jreMethod.getModifiers(), name,returnType, parameterList, block, gtvDeclarations, offset, isInherited);
|
||||
}
|
||||
|
||||
public static GenericDeclarationList createGenerics(TypeVariable[] typeParameters, Class context, String methodName){
|
||||
List<de.dhbwstuttgart.syntaxtree.GenericTypeVar> gtvs = new ArrayList<>();
|
||||
for(TypeVariable jreTV : typeParameters){
|
||||
de.dhbwstuttgart.syntaxtree.GenericTypeVar gtv = createGeneric(jreTV, jreTV.getName(), context, methodName);
|
||||
gtvs.add(gtv);
|
||||
public static GenericDeclarationList createGenerics(TypeVariable[] typeParameters, Class context, String methodName, String signature) {
|
||||
if (signature == null) {
|
||||
List<de.dhbwstuttgart.syntaxtree.GenericTypeVar> gtvs = new ArrayList<>();
|
||||
for(TypeVariable jreTV : typeParameters){
|
||||
de.dhbwstuttgart.syntaxtree.GenericTypeVar gtv = createGeneric(jreTV, jreTV.getName(), context, methodName);
|
||||
gtvs.add(gtv);
|
||||
}
|
||||
return new GenericDeclarationList(gtvs, new NullToken());
|
||||
} else {
|
||||
var res = createGenerics(signature);
|
||||
return res;
|
||||
}
|
||||
return new GenericDeclarationList(gtvs,new NullToken());
|
||||
}
|
||||
|
||||
public static GenericDeclarationList createGenerics(String signature) {
|
||||
if (signature == null) return new GenericDeclarationList(new ArrayList<>(), new NullToken());
|
||||
|
||||
var gtvs = new ArrayList<GenericTypeVar>();
|
||||
var signatureVisitor = new SignatureVisitor(Opcodes.ASM7) {
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> bounds = new ArrayList<>();
|
||||
final Stack<RefTypeOrTPHOrWildcardOrGeneric> bound = new Stack<>();
|
||||
final Stack<RefType> classTypes = new Stack<>();
|
||||
|
||||
// All hail the mighty visitor pattern
|
||||
final SignatureVisitor doNothing = new SignatureVisitor(Opcodes.ASM7) {};
|
||||
|
||||
char wildcard = '=';
|
||||
|
||||
@Override
|
||||
public SignatureVisitor visitSuperclass() {
|
||||
return doNothing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SignatureVisitor visitParameterType() {
|
||||
return doNothing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SignatureVisitor visitReturnType() {
|
||||
return doNothing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SignatureVisitor visitExceptionType() {
|
||||
return doNothing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFormalTypeParameter(String name) {
|
||||
bounds = new ArrayList<>();
|
||||
gtvs.add(new GenericTypeVar(name, bounds, new NullToken(), new NullToken()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeVariable(String name) {
|
||||
var refType = new GenericRefType(name, new NullToken());
|
||||
if (classTypes.isEmpty()) {
|
||||
((List<RefTypeOrTPHOrWildcardOrGeneric>) gtvs.get(gtvs.size() - 1).getBounds()).add(refType);
|
||||
} else {
|
||||
pushType(refType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitClassType(String name) {
|
||||
var refType = new RefType(new JavaClassName(name.replaceAll("/", ".")), new ArrayList<>(), new NullToken());
|
||||
classTypes.push(refType);
|
||||
pushType(refType);
|
||||
}
|
||||
|
||||
void pushType(RefTypeOrTPHOrWildcardOrGeneric refType) {
|
||||
if (wildcard == SignatureVisitor.SUPER) {
|
||||
bound.push(new SuperWildcardType(refType, new NullToken()));
|
||||
} else if (wildcard == SignatureVisitor.EXTENDS) {
|
||||
bound.push(new ExtendsWildcardType(refType, new NullToken()));
|
||||
} else {
|
||||
bound.push(refType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SignatureVisitor visitTypeArgument(char wildcard) {
|
||||
this.wildcard = wildcard;
|
||||
return this;
|
||||
}
|
||||
|
||||
boolean equals(RefTypeOrTPHOrWildcardOrGeneric a, RefTypeOrTPHOrWildcardOrGeneric b) {
|
||||
if (b instanceof SuperWildcardType wc)
|
||||
return equals(a, wc.getInnerType());
|
||||
else if (b instanceof ExtendsWildcardType wc)
|
||||
return equals(a, wc.getInnerType());
|
||||
return a == b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
wildcard = '=';
|
||||
var classType = (RefType) classTypes.pop();
|
||||
if (!classTypes.isEmpty()) {
|
||||
var next = classTypes.peek();
|
||||
var par = bound.pop();
|
||||
var toAdd = new ArrayList<RefTypeOrTPHOrWildcardOrGeneric>();
|
||||
while (!equals(next, par)) {
|
||||
toAdd.add(par);
|
||||
par = bound.pop();
|
||||
}
|
||||
var element = par;
|
||||
if (par instanceof WildcardType wc) {
|
||||
element = wc.getInnerType();
|
||||
}
|
||||
Collections.reverse(toAdd);
|
||||
((RefType) element).getParaList().addAll(toAdd);
|
||||
|
||||
bound.push(par);
|
||||
} else {
|
||||
if (bound.peek() != classType) {
|
||||
classType.getParaList().add(bound.pop());
|
||||
bounds.add(classType);
|
||||
} else {
|
||||
bounds.add(bound.pop());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var sr = new SignatureReader(signature);
|
||||
sr.accept(signatureVisitor);
|
||||
|
||||
return new GenericDeclarationList(gtvs, new NullToken());
|
||||
}
|
||||
|
||||
private static RefTypeOrTPHOrWildcardOrGeneric createType(java.lang.reflect.Type type){
|
||||
|
@@ -5,6 +5,8 @@ import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Stellt eine Wildcard mit oberer Grenze dar.
|
||||
* z.B. void test(? extends Number var){..}
|
||||
@@ -54,9 +56,16 @@ public class ExtendsWildcardType extends WildcardType{
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.innerType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ExtendsWildcardType that = (ExtendsWildcardType) o;
|
||||
return that.innerType.equals(this.innerType);
|
||||
}
|
||||
}
|
||||
|
@@ -4,6 +4,8 @@ import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class GenericRefType extends RefTypeOrTPHOrWildcardOrGeneric
|
||||
{
|
||||
private String name;
|
||||
@@ -33,14 +35,20 @@ public class GenericRefType extends RefTypeOrTPHOrWildcardOrGeneric
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
GenericRefType that = (GenericRefType) o;
|
||||
return name.equals(that.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "GTV " + this.name;
|
||||
|
@@ -2,9 +2,12 @@ package de.dhbwstuttgart.syntaxtree.type;
|
||||
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Stellt eine Wildcard mit unterer Grenze dar.
|
||||
* z.B. void test(? super Integer var){..}
|
||||
@@ -65,9 +68,16 @@ public class SuperWildcardType extends WildcardType{
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.innerType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
SuperWildcardType that = (SuperWildcardType) o;
|
||||
return that.innerType.equals(this.innerType);
|
||||
}
|
||||
}
|
||||
|
@@ -16,8 +16,10 @@ import de.dhbwstuttgart.target.tree.expression.TargetExpression;
|
||||
import de.dhbwstuttgart.target.tree.type.*;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import de.dhbwstuttgart.typeinference.result.*;
|
||||
import org.objectweb.asm.Attribute;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -170,7 +172,6 @@ public class ASTToTargetAST {
|
||||
for (var pair : simplifiedConstraints) {
|
||||
if (pair.left.equals(typeVariable) && typeVariables.contains(pair.right)) {
|
||||
addToPairs(result, new PairTPHsmallerTPH(pair.left, equality.getOrDefault(pair.right, pair.right)));
|
||||
typeVariables.add(pair.right);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,7 +197,7 @@ public class ASTToTargetAST {
|
||||
RefTypeOrTPHOrWildcardOrGeneric T2 = superType;
|
||||
if (T2 instanceof TypePlaceholder tph) T2 = equality.getOrDefault(tph, tph);
|
||||
|
||||
System.out.println("T1s: " + T1s + "\nT2: " + T2);
|
||||
System.out.println("T1s: " + T1s + " T2: " + T2);
|
||||
//Ende
|
||||
|
||||
superType = methodCall.receiverType;
|
||||
@@ -211,7 +212,7 @@ public class ASTToTargetAST {
|
||||
var optMethod = findMethod(owner, methodCall.name, methodCall.getArgumentList());
|
||||
if (optMethod.isEmpty()) return;
|
||||
var method = optMethod.get();
|
||||
var generics = generics(owner, method).javaGenerics();
|
||||
var generics = generics(owner, method).txGenerics();
|
||||
|
||||
// transitive and
|
||||
var all = transitiveClosure(generics);
|
||||
@@ -226,24 +227,24 @@ public class ASTToTargetAST {
|
||||
|
||||
// Loop from hell
|
||||
outer:
|
||||
for (var tph : typeVariables) {
|
||||
if (typeVariablesOfClass.contains(tph)) continue;
|
||||
for (var R1 : typeVariables) {
|
||||
if (typeVariablesOfClass.contains(R1)) continue;
|
||||
for (var generic : all) {
|
||||
if (!(generic.getRight() instanceof TypePlaceholder type))
|
||||
continue;
|
||||
|
||||
for (var pair : simplifiedConstraints) {
|
||||
if (!(pair.left.equals(tph) && pair.right.equals(generic.getLeft())))
|
||||
if (!(pair.left.equals(R1) && pair.right.equals(generic.getLeft())))
|
||||
continue;
|
||||
|
||||
for (var tph2 : typeVariables) {
|
||||
for (var R2 : typeVariables) {
|
||||
for (var pair2 : simplifiedConstraints) {
|
||||
if (!(pair2.right.equals(tph2) && pair2.left.equals(type)))
|
||||
if (!(pair2.right.equals(R2) && pair2.left.equals(type)))
|
||||
continue;
|
||||
if (tph.equals(tph2)) continue;
|
||||
if (!T1s.contains(tph) || !tph2.equals(T2)) continue;
|
||||
if (R1.equals(R2)) continue;
|
||||
if (!T1s.contains(R1) || !R2.equals(T2)) continue;
|
||||
|
||||
var newPair = new PairTPHsmallerTPH(tph, tph2);
|
||||
var newPair = new PairTPHsmallerTPH(R1, R2);
|
||||
newPairs.add(newPair);
|
||||
|
||||
if (!containsRelation(result, newPair))
|
||||
@@ -268,7 +269,7 @@ public class ASTToTargetAST {
|
||||
|
||||
@Override
|
||||
public void visit(Assign assign) {
|
||||
superType = assign.lefSide.getType();
|
||||
superType = assign.rightSide.getType();
|
||||
assign.rightSide.accept(this);
|
||||
}
|
||||
|
||||
@@ -521,9 +522,6 @@ public class ASTToTargetAST {
|
||||
super.visit(methodCall);
|
||||
typeVariables.addAll(findTypeVariables(methodCall.getType(), equality));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Assign assign) {}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -554,10 +552,11 @@ public class ASTToTargetAST {
|
||||
methodFindConstraints(owner, method, simplifiedConstraints, txTypeVariables, classGenerics.userDefinedGenerics, txTypeVariablesOfClass, txResult, txEquality);
|
||||
|
||||
{ // Java Generics
|
||||
eliminateTransitives(javaResult);
|
||||
var referenced = new HashSet<TypePlaceholder>();
|
||||
|
||||
eliminateCycles(javaResult, equality, referenced);
|
||||
eliminateInfima(javaResult, equality, referenced);
|
||||
eliminateInfima(javaResult, equality);
|
||||
|
||||
var usedTphs = new HashSet<TypePlaceholder>();
|
||||
// For eliminating inner type variables we need to figure out which ones are actually used
|
||||
@@ -571,11 +570,13 @@ public class ASTToTargetAST {
|
||||
eliminateInnerTypeVariables(referenced, javaResult);
|
||||
equalizeTypeVariables(javaResult, equality);
|
||||
usedTPHsOfMethods.put(method, usedTphs);
|
||||
addMissingObjectBounds(javaResult, genericsOfClass);
|
||||
}
|
||||
{
|
||||
var referenced = new HashSet<TypePlaceholder>();
|
||||
// JavaTX Generics
|
||||
eliminateInfima(txResult, txEquality, referenced);
|
||||
eliminateTransitives(txResult);
|
||||
eliminateInfima(txResult, txEquality);
|
||||
|
||||
for (var param : method.getParameterList().getFormalparalist()) {
|
||||
referenced.addAll(findTypeVariables(param.getType(), txEquality));
|
||||
@@ -584,12 +585,36 @@ public class ASTToTargetAST {
|
||||
referenced.addAll(txTypeVariablesOfClass);
|
||||
|
||||
eliminateInnerTypeVariables(referenced, txResult);
|
||||
addMissingObjectBounds(txResult, txGenericsOfClass);
|
||||
}
|
||||
|
||||
System.out.println(method.name + ": " + txResult + " & " + javaResult);
|
||||
return generics;
|
||||
}
|
||||
|
||||
private void eliminateChain(Set<ResultPair<?, ?>> result, List<TypePlaceholder> chain) {
|
||||
for (var pair : new HashSet<>(result)) {
|
||||
if (pair instanceof PairTPHsmallerTPH ptph && chain.get(chain.size() - 1).equals(ptph.left)) {
|
||||
if (chain.contains(ptph.right)) return;
|
||||
var copy = new ArrayList<>(chain);
|
||||
copy.add(ptph.right);
|
||||
if (copy.size() > 2)
|
||||
result.remove(new PairTPHsmallerTPH(chain.get(0), ptph.right));
|
||||
eliminateChain(result, copy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void eliminateTransitives(Set<ResultPair<?,?>> result) {
|
||||
for (var pair : new HashSet<>(result)) if (pair instanceof PairTPHsmallerTPH ptph) {
|
||||
var first = ptph.left;
|
||||
var chain = new ArrayList<TypePlaceholder>();
|
||||
chain.add(ptph.left);
|
||||
chain.add(ptph.right);
|
||||
eliminateChain(result, chain);
|
||||
}
|
||||
}
|
||||
|
||||
void findAllBounds(RefTypeOrTPHOrWildcardOrGeneric type, Set<ResultPair<?, ?>> generics, Map<TypePlaceholder, TypePlaceholder> equality) {
|
||||
if (type instanceof TypePlaceholder tph) {
|
||||
tph = equality.getOrDefault(tph, tph);
|
||||
@@ -634,34 +659,86 @@ public class ASTToTargetAST {
|
||||
findAllBounds(field.getType(), txResult, txEquality);
|
||||
}
|
||||
|
||||
eliminateTransitives(javaResult);
|
||||
eliminateTransitives(txResult);
|
||||
System.out.println(javaResult);
|
||||
var referenced = new HashSet<TypePlaceholder>();
|
||||
eliminateCycles(javaResult, equality, referenced);
|
||||
eliminateInfima(javaResult, equality, referenced);
|
||||
eliminateInfima(javaResult, equality);
|
||||
var txReferenced = new HashSet<TypePlaceholder>();
|
||||
eliminateInfima(txResult, txEquality, txReferenced);
|
||||
eliminateInfima(txResult, txEquality);
|
||||
|
||||
eliminateInnerTypeVariablesOfClass(classOrInterface, javaResult, equality, referenced);
|
||||
equalizeTypeVariables(javaResult, equality);
|
||||
eliminateInnerTypeVariablesOfClass(classOrInterface, txResult, txEquality, txReferenced);
|
||||
|
||||
addMissingObjectBounds(javaResult, null);
|
||||
addMissingObjectBounds(txResult, null);
|
||||
|
||||
System.out.println("Class " + classOrInterface.getClassName().getClassName() + ": " + txResult + ", " + javaResult);
|
||||
return generics;
|
||||
}
|
||||
|
||||
void addMissingObjectBounds(Set<ResultPair<?,?>> result, Set<ResultPair<?, ?>> filter) {
|
||||
outer: for (var p1 : new HashSet<>(result)) {
|
||||
if (p1 instanceof PairTPHsmallerTPH ptph) {
|
||||
for (var p2 : new HashSet<>(result)) {
|
||||
if (ptph.right.equals(p2.getLeft()))
|
||||
continue outer;
|
||||
}
|
||||
if (filter == null || filter.stream().noneMatch((pair) -> pair.getLeft().equals(ptph.right)))
|
||||
result.add(new PairTPHequalRefTypeOrWildcardType(ptph.right, OBJECT));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void equalizeTypeVariables(Set<ResultPair<?, ?>> input, Map<TypePlaceholder, TypePlaceholder> equality) {
|
||||
System.out.println(input);
|
||||
for (var pair : new HashSet<>(input)) {
|
||||
if (pair instanceof PairTPHsmallerTPH ptph) {
|
||||
System.out.println(pair + " " + ptph.left.getVariance() + " " + ptph.right.getVariance());
|
||||
if (ptph.left.getVariance() == 1 && ptph.right.getVariance() == -1) {
|
||||
addToEquality(equality, ptph.left, ptph.right);
|
||||
input.remove(ptph);
|
||||
for (var pair2 : new HashSet<>(simplifiedConstraints)) {
|
||||
if (pair2.right.equals(ptph.left)) {
|
||||
simplifiedConstraints.remove(pair2);
|
||||
simplifiedConstraints.add(new PairTPHsmallerTPH(pair2.left, ptph.right));
|
||||
var chain = new ArrayList<TypePlaceholder>();
|
||||
chain.add(ptph.left);
|
||||
chain.add(ptph.right);
|
||||
|
||||
outer: while (true) {
|
||||
var added = false;
|
||||
for (var pair2 : input) {
|
||||
if (pair2 instanceof PairTPHsmallerTPH ptph2 && ptph2.left.equals(chain.get(chain.size() - 1))) {
|
||||
if (chain.contains(ptph2.right)) break outer;
|
||||
chain.add(ptph2.right);
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
if (!added) break;
|
||||
}
|
||||
|
||||
var variance = chain.get(0).getVariance();
|
||||
if (variance != 1) continue;
|
||||
var index = 0;
|
||||
for (var tph : chain) {
|
||||
if (variance == 1 && tph.getVariance() == -1) {
|
||||
variance = -1;
|
||||
}
|
||||
if (variance == -1 && tph.getVariance() == 1) {
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
if (variance == 1) continue;
|
||||
|
||||
var start = chain.get(0);
|
||||
var prev = start;
|
||||
for (var i = 1; i < index; i++) {
|
||||
var cur = chain.get(i);
|
||||
addToEquality(equality, cur, start);
|
||||
input.remove(new PairTPHsmallerTPH(prev, chain.get(i)));
|
||||
for (var pair2 : new HashSet<>(input)) {
|
||||
// TODO Maybe this would be unnecessary if we were to add the = constraints later on
|
||||
if (pair2 instanceof PairTPHequalRefTypeOrWildcardType && pair2.getLeft().equals(cur)) {
|
||||
input.remove(pair2);
|
||||
input.add(new PairTPHequalRefTypeOrWildcardType(start, pair2.getRight()));
|
||||
}
|
||||
}
|
||||
prev = chain.get(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -739,6 +816,15 @@ public class ASTToTargetAST {
|
||||
var cycles = findCycles(input);
|
||||
for (var cycle : cycles) {
|
||||
var newTph = TypePlaceholder.fresh(new NullToken());
|
||||
var variance = cycle.get(0).getVariance();
|
||||
for (var tph : cycle) {
|
||||
if (tph.getVariance() != variance) {
|
||||
variance = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
newTph.setVariance(variance);
|
||||
|
||||
referenced.add(newTph);
|
||||
addToPairs(input, new PairTPHequalRefTypeOrWildcardType(newTph, OBJECT));
|
||||
cycle.add(cycle.get(0)); // Make it a complete cycle
|
||||
@@ -752,7 +838,7 @@ public class ASTToTargetAST {
|
||||
}
|
||||
}
|
||||
|
||||
void eliminateInfima(Set<ResultPair<?, ?>> input, Map<TypePlaceholder, TypePlaceholder> equality, Set<TypePlaceholder> referenced) {
|
||||
void eliminateInfima(Set<ResultPair<?, ?>> input, Map<TypePlaceholder, TypePlaceholder> equality) {
|
||||
var foundInfima = false;
|
||||
do {
|
||||
foundInfima = false;
|
||||
@@ -767,7 +853,16 @@ public class ASTToTargetAST {
|
||||
if (infima.size() > 1) {
|
||||
foundInfima = true;
|
||||
var newTph = TypePlaceholder.fresh(new NullToken());
|
||||
referenced.add(newTph);
|
||||
var variance = infima.stream().findFirst().get().right.getVariance();
|
||||
for (var pair : infima) {
|
||||
if (pair.right.getVariance() != variance) {
|
||||
variance = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
newTph.setVariance(variance);
|
||||
|
||||
//referenced.add(newTph);
|
||||
addToPairs(input, new PairTPHsmallerTPH(left, newTph));
|
||||
input.removeAll(infima);
|
||||
for (var infimum : infima) {
|
||||
|
@@ -22,11 +22,15 @@ public record TargetMethod(int access, String name, TargetBlock block, Signature
|
||||
}
|
||||
|
||||
public static String getSignature(Set<TargetGeneric> generics, List<MethodParameter> parameters, TargetType returnType) {
|
||||
String ret = "<";
|
||||
for (var generic : generics) {
|
||||
ret += generic.name() + ":" + generic.bound().toDescriptor();
|
||||
String ret = "";
|
||||
if (generics.size() > 0) {
|
||||
ret += "<";
|
||||
for (var generic : generics) {
|
||||
ret += generic.name() + ":" + generic.bound().toDescriptor();
|
||||
}
|
||||
ret += ">";
|
||||
}
|
||||
ret += ">(";
|
||||
ret += "(";
|
||||
for (var param : parameters) {
|
||||
ret += param.type().toDescriptor();
|
||||
}
|
||||
|
@@ -495,7 +495,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
@Override
|
||||
public void visit(Return returnExpr) {
|
||||
returnExpr.retexpr.accept(this);
|
||||
constraintsSet.addUndConstraint(new Pair(returnExpr.getType(),info.getCurrentTypeScope().getReturnType(), PairOperator.EQUALSDOT));
|
||||
constraintsSet.addUndConstraint(new Pair(returnExpr.getType(),info.getCurrentTypeScope().getReturnType(), PairOperator.SMALLERDOT));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -610,8 +610,8 @@ public class TYPEStmt implements StatementVisitor{
|
||||
//Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ENDE
|
||||
|
||||
|
||||
methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT));
|
||||
extendsMethodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT));
|
||||
methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.SMALLERDOT));
|
||||
extendsMethodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.SMALLERDOT));
|
||||
|
||||
//methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT));
|
||||
//extendsMethodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT));
|
||||
|
@@ -13,7 +13,6 @@ import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
|
||||
@@ -391,51 +390,26 @@ public class RuleSet implements IRuleSet{
|
||||
if((pair.getPairOp() != PairOperator.SMALLERDOT) && (pair.getPairOp() != PairOperator.SMALLERNEQDOT))
|
||||
return false;
|
||||
|
||||
if (pair.getPairOp() == PairOperator.SMALLERNEQDOT) {
|
||||
UnifyType lhs = pair.getLhsType();
|
||||
UnifyType rhs = pair.getRhsType();
|
||||
if (lhs instanceof WildcardType) {
|
||||
lhs = ((WildcardType)lhs).getWildcardedType();
|
||||
}
|
||||
if (rhs instanceof WildcardType) {
|
||||
rhs = ((WildcardType)rhs).getWildcardedType();
|
||||
}
|
||||
|
||||
if (lhs.equals(rhs)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
|
||||
/*
|
||||
* ty <. ? extends ty' is wrong
|
||||
*/
|
||||
if (rhsType instanceof ExtendsType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* ? super ty <. ty' is wrong
|
||||
* except Ty' = Object or ty' = ? super Object
|
||||
*/
|
||||
if ((lhsType instanceof SuperType) &&
|
||||
(!(rhsType.equals(new ReferenceType("java.lang.Object", false)))) &&
|
||||
!(rhsType.equals(new SuperType (new ReferenceType("java.lang.Object", false))))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* ? extends ty <. ty' is equivalent to ty < ty'
|
||||
*/
|
||||
if (lhsType instanceof ExtendsType) {
|
||||
lhsType = ((WildcardType)lhsType).getWildcardedType();
|
||||
}
|
||||
|
||||
/*
|
||||
* ty <. ? super ty' ist equivalent to ty <. ty'
|
||||
*/
|
||||
if (rhsType instanceof SuperType) {
|
||||
rhsType = ((WildcardType)rhsType).getWildcardedType();
|
||||
}
|
||||
|
||||
/*
|
||||
* SMALLERNEQDOT => type must not be equal
|
||||
*/
|
||||
if (pair.getPairOp() == PairOperator.SMALLERNEQDOT && lhsType.equals(rhsType)){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!(lhsType instanceof ReferenceType) && !(lhsType instanceof PlaceholderType))
|
||||
return false;
|
||||
|
||||
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
if(!(rhsType instanceof ReferenceType) && !(rhsType instanceof PlaceholderType))
|
||||
return false;
|
||||
|
||||
|
@@ -18,7 +18,6 @@ import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
|
||||
public class TypeUnify {
|
||||
|
||||
public static Writer statistics;
|
||||
/**
|
||||
* unify parallel ohne result modell
|
||||
* @param undConstrains
|
||||
@@ -74,16 +73,13 @@ public class TypeUnify {
|
||||
* @return
|
||||
*/
|
||||
public UnifyResultModel unifyParallel(Set<UnifyPair> undConstrains, List<Set<Constraint<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);
|
||||
new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, usedTasks, statistics);
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, usedTasks);
|
||||
ForkJoinPool pool = new ForkJoinPool();
|
||||
pool.invoke(unifyTask);
|
||||
Set<Set<UnifyPair>> res = unifyTask.join();
|
||||
try {
|
||||
logFile.write("\nnoShortendElements: " + unifyTask.noShortendElements +"\n");
|
||||
logFile.flush();
|
||||
unifyTask.statistics.write("Backtracking: " + unifyTask.noBacktracking);
|
||||
unifyTask.statistics.write("\nLoops: " + unifyTask.noLoop);
|
||||
}
|
||||
catch (IOException e) {
|
||||
System.err.println("no log-File");
|
||||
@@ -111,7 +107,6 @@ public class TypeUnify {
|
||||
*/
|
||||
public Set<Set<UnifyPair>> unifyOderConstraints(Set<UnifyPair> undConstrains, List<Set<Constraint<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);
|
||||
unifyTask.statistics = statistics;
|
||||
Set<Set<UnifyPair>> res = unifyTask.compute();
|
||||
try {
|
||||
logFile.write("\nnoShortendElements: " + unifyTask.noShortendElements +"\n");
|
||||
|
@@ -19,16 +19,6 @@ public class TypeUnify2Task extends TypeUnifyTask {
|
||||
Set<Set<UnifyPair>> setToFlatten;
|
||||
Set<UnifyPair> methodSignatureConstraintUebergabe;
|
||||
|
||||
//statistics
|
||||
TypeUnify2Task(Set<Set<UnifyPair>> setToFlatten, Set<UnifyPair> eq,
|
||||
List<Set<Constraint<UnifyPair>>> oderConstraints,
|
||||
Set<UnifyPair> nextSetElement,
|
||||
IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm, UnifyTaskModel usedTasks,
|
||||
Set<UnifyPair> methodSignatureConstraintUebergabe, Writer statistics) {
|
||||
this(setToFlatten, eq, oderConstraints, nextSetElement, fc, parallel, logFile, log, rekTiefe, urm, usedTasks, methodSignatureConstraintUebergabe );
|
||||
|
||||
}
|
||||
|
||||
public TypeUnify2Task(Set<Set<UnifyPair>> setToFlatten, Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, Set<UnifyPair> nextSetElement, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm, UnifyTaskModel usedTasks, Set<UnifyPair> methodSignatureConstraintUebergabe) {
|
||||
super(eq, oderConstraints, fc, parallel, logFile, log, rekTiefe, urm, usedTasks);
|
||||
this.setToFlatten = setToFlatten;
|
||||
|
@@ -21,7 +21,6 @@ import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.io.output.NullOutputStream;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.exceptions.TypeinferenceException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
|
||||
@@ -47,7 +46,6 @@ import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.WildcardType;
|
||||
import de.dhbwstuttgart.util.Pair;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.OrderingUnifyPair;
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
@@ -82,7 +80,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
private static int totalnoOfThread = 0;
|
||||
int thNo;
|
||||
protected boolean one = false;
|
||||
Integer MaxNoOfThreads = 128;
|
||||
Integer MaxNoOfThreads = 8;
|
||||
|
||||
public static final String rootDirectory = System.getProperty("user.dir")+"/test/logFiles/";
|
||||
Writer logFile;
|
||||
@@ -127,16 +125,12 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
|
||||
static int noBacktracking;
|
||||
|
||||
static int noLoop;
|
||||
|
||||
static Integer noShortendElements = 0;
|
||||
|
||||
Boolean myIsCanceled = false;
|
||||
|
||||
volatile UnifyTaskModel usedTasks;
|
||||
|
||||
static Writer statistics;
|
||||
|
||||
public TypeUnifyTask() {
|
||||
rules = new RuleSet();
|
||||
}
|
||||
@@ -155,11 +149,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
}
|
||||
*/
|
||||
|
||||
//statistics
|
||||
public TypeUnifyTask(Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm, UnifyTaskModel usedTasks, Writer statistics) {
|
||||
this(eq,oderConstraints, fc, parallel, logFile, log, rekTiefe, urm, usedTasks);
|
||||
this.statistics = statistics;
|
||||
}
|
||||
|
||||
public TypeUnifyTask(Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm, UnifyTaskModel usedTasks) {
|
||||
synchronized (this) {
|
||||
this.eq = eq;
|
||||
@@ -258,7 +248,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
|
||||
protected Set<Set<UnifyPair>> compute() {
|
||||
if (one) {
|
||||
//System.out.println("two");
|
||||
System.out.println("two");
|
||||
}
|
||||
one = true;
|
||||
Set<UnifyPair> neweq = new HashSet<>(eq);
|
||||
@@ -602,7 +592,6 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
|
||||
|
||||
urm.notify(eqPrimePrimeSet);
|
||||
writeStatistics("Result: " + eqPrimePrimeSet.toString());
|
||||
}
|
||||
}
|
||||
else if(eqPrimePrime.isPresent()) {
|
||||
@@ -657,10 +646,6 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
|
||||
//oneElems: Alle 1-elementigen Mengen, die nur ein Paar
|
||||
//a <. theta, theta <. a oder a =. theta enthalten
|
||||
|
||||
//statistics
|
||||
//writeStatistics("\nNumber of Constraints (" + rekTiefe + "): " + topLevelSets.size());
|
||||
|
||||
Set<Set<UnifyPair>> oneElems = new HashSet<>();
|
||||
oneElems.addAll(topLevelSets.stream()
|
||||
.filter(x -> x.size()==1)
|
||||
@@ -678,9 +663,6 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
Set<? extends Set<UnifyPair>> nextSet = optNextSet.get();
|
||||
//writeLog("nextSet: " + nextSet.toString());
|
||||
List<Set<UnifyPair>> nextSetasList =new ArrayList<>(nextSet);
|
||||
|
||||
//writeStatistics(" Start Number of elements ( " /* + nextSetasList.get(0).stream().findFirst().get().getBasePair()*/ +"): (" + rekTiefe + "): " + nextSetasList.size());
|
||||
|
||||
/*
|
||||
try {
|
||||
//List<Set<UnifyPair>>
|
||||
@@ -792,12 +774,8 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
}
|
||||
/* sameEqSet-Bestimmung Ende */
|
||||
|
||||
int hilf = 0;
|
||||
Set<UnifyPair> a = null;
|
||||
while (nextSetasList.size() > 0) {
|
||||
|
||||
//statistics
|
||||
//writeStatistics(" Actual Number of elements( " + nextSetasList.get(0).stream().findFirst().get().getBasePair() +"): (" + rekTiefe + "): " + nextSetasList.size());
|
||||
Set<UnifyPair> a_last = a;
|
||||
|
||||
/* Liste der Faelle für die parallele Verarbeitung
|
||||
@@ -816,8 +794,6 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
|
||||
writeLog("nextSet: " + nextSet.toString());
|
||||
writeLog("nextSetasList: " + nextSetasList.toString());
|
||||
|
||||
/* staistics Nextvar an Hand Varianzbestimmung auskommentieren Anfang
|
||||
if (variance == 1) {
|
||||
a = oup.max(nextSetasList.iterator());
|
||||
nextSetasList.remove(a);
|
||||
@@ -889,10 +865,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
}
|
||||
}
|
||||
}
|
||||
Nextvar an Hand Varianzbestimmung auskommentieren Ende */
|
||||
a = nextSetasList.remove(0); //statisticsList
|
||||
|
||||
//writeStatistics(a.toString());
|
||||
if (oderConstraint) {//Methodconstraints werden abgespeichert für die Bytecodegenerierung von Methodenaufrufen
|
||||
methodSignatureConstraint.addAll(((Constraint<UnifyPair>)a).getmethodSignatureConstraint());
|
||||
//System.out.println("ERSTELLUNG: " +methodSignatureConstraint);
|
||||
@@ -914,13 +887,11 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
/* Wenn bei (a \in theta) \in a zu Widerspruch in oneElems wird
|
||||
* a verworfen und zu nächstem Element von nextSetasList gegangen
|
||||
*/
|
||||
/* statistics sameEq wird nicht betrachtet ANGFANG
|
||||
if (!oderConstraint && !sameEqSet.isEmpty() && !checkNoContradiction(a, sameEqSet, result)) {
|
||||
a = null;
|
||||
noShortendElements++;
|
||||
continue;
|
||||
}
|
||||
statistics sameEq wird nicht betrachtet ENDE */
|
||||
|
||||
/* Wenn parallel gearbeitet wird, wird je nach Varianz ein neuer Thread
|
||||
* gestartet, der parallel weiterarbeitet.
|
||||
@@ -947,22 +918,19 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
writeLog("a in " + variance + " "+ a);
|
||||
writeLog("nextSetasListRest: " + nextSetasListRest.toString());
|
||||
}
|
||||
while (!nextSetasList.isEmpty()) {
|
||||
Set<UnifyPair> nSaL = nextSetasList.remove(0);
|
||||
synchronized (this) { //nextSetasList.remove(nSaL);
|
||||
while (!nextSetasListRest.isEmpty()) {
|
||||
Set<UnifyPair> nSaL = nextSetasListRest.remove(0);
|
||||
synchronized (this) { nextSetasList.remove(nSaL);
|
||||
writeLog("1 RM" + nSaL.toString());
|
||||
}
|
||||
|
||||
if (!oderConstraint) {
|
||||
|
||||
/* statistics sameEq wird nicht betrachtet ANGFANG
|
||||
//ueberpruefung ob zu a =. ty \in nSaL in sameEqSet ein Widerspruch besteht
|
||||
if (!sameEqSet.isEmpty() && !checkNoContradiction(nSaL, sameEqSet, result)) {
|
||||
nSaL = null;
|
||||
noShortendElements++;
|
||||
continue;
|
||||
}
|
||||
statistics sameEq wird nicht betrachtet ENDE */
|
||||
}
|
||||
else {
|
||||
nextSetasListOderConstraints.add(((Constraint<UnifyPair>)nSaL).getExtendConstraint());
|
||||
@@ -1049,21 +1017,19 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
writeLog("a in " + variance + " "+ a);
|
||||
writeLog("nextSetasListRest: " + nextSetasListRest.toString());
|
||||
}
|
||||
while (!nextSetasList.isEmpty()) {
|
||||
Set<UnifyPair> nSaL = nextSetasList.remove(0);
|
||||
synchronized (this) { //nextSetasList.remove(nSaL);
|
||||
while (!nextSetasListRest.isEmpty()) {
|
||||
Set<UnifyPair> nSaL = nextSetasListRest.remove(0);
|
||||
synchronized (this) { nextSetasList.remove(nSaL);
|
||||
writeLog("-1 RM" + nSaL.toString());
|
||||
}
|
||||
|
||||
if (!oderConstraint) {
|
||||
/* statistics sameEq wird nicht betrachtet ANGFANG
|
||||
//ueberpruefung ob zu a =. ty \in nSaL in sameEqSet ein Widerspruch besteht
|
||||
if (!sameEqSet.isEmpty() && !checkNoContradiction(nSaL, sameEqSet, result)) {
|
||||
nSaL = null;
|
||||
noShortendElements++;
|
||||
continue;
|
||||
}
|
||||
statistics sameEq wird nicht betrachtet ENDE */
|
||||
}
|
||||
else {
|
||||
nextSetasListOderConstraints.add(((Constraint<UnifyPair>)nSaL).getExtendConstraint());
|
||||
@@ -1151,9 +1117,9 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
writeLog("a in " + variance + " "+ a);
|
||||
writeLog("nextSetasListRest: " + nextSetasListRest.toString());
|
||||
}
|
||||
while (!nextSetasList.isEmpty()) {
|
||||
Set<UnifyPair> nSaL = nextSetasList.remove(0);
|
||||
//nextSetasList.remove(nSaL); //PL einkommentiert 20-02-03
|
||||
while (!nextSetasListRest.isEmpty()) {
|
||||
Set<UnifyPair> nSaL = nextSetasListRest.remove(0);
|
||||
nextSetasList.remove(nSaL); //PL einkommentiert 20-02-03
|
||||
Set<UnifyPair> newEq = new HashSet<>(eq);
|
||||
Set<Set<UnifyPair>> newElems = new HashSet<>(elems);
|
||||
List<Set<Constraint<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints);
|
||||
@@ -1213,9 +1179,6 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
}}}
|
||||
|
||||
//Ab hier alle parallele Berechnungen wieder zusammengeführt.
|
||||
//if (hilf == 1)
|
||||
//System.out.println();
|
||||
//writeStatistics("Zusammengeführt(" + rekTiefe + "): " + nextSetasList.size());
|
||||
if (oderConstraint) {//Wenn weiteres Element nextSetasList genommen wird, muss die vorherige methodsignatur geloescht werden
|
||||
methodSignatureConstraint.removeAll(((Constraint<UnifyPair>)a).getmethodSignatureConstraint());
|
||||
//System.out.println("REMOVE: " +methodSignatureConstraint);
|
||||
@@ -1229,7 +1192,6 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
|| (!isUndefinedPairSetSet(res) && !isUndefinedPairSetSet(result))
|
||||
|| result.isEmpty()) {
|
||||
|
||||
/* auskommentiert damit alle Lösungen reinkommen ANFANG
|
||||
if ((!result.isEmpty() && !res.isEmpty() && !isUndefinedPairSetSet(res) && !isUndefinedPairSetSet(result)) //korrekte Loesungen aus und-constraints
|
||||
&& (a.stream().map(x-> (x.getBasePair() != null)).reduce(true, (x, y) -> (x && y)))) //bei oder-Constraints nicht ausfuehren
|
||||
{
|
||||
@@ -1251,7 +1213,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
|
||||
//Alle Variablen bestimmen die nicht hinzugefügt wurden in a_last
|
||||
//System.out.println(a_last);
|
||||
if (a_last != null) {
|
||||
|
||||
try {//PL eingefuegt 2019-03-06 da bei map mmer wieder Nullpointer kamen
|
||||
a_last.forEach(x -> {writeLog("a_last_elem:" + x + " basepair: " + x.getBasePair());});//PL 2019-05-13 ins try hinzugefuegt Nullpointer-Exception ist in der Zeile aufgetaucht.
|
||||
List<PlaceholderType> varsLast_a =
|
||||
@@ -1303,11 +1265,9 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
writeLog("NullPointerException: " + a_last.toString());
|
||||
}}
|
||||
}
|
||||
}
|
||||
else
|
||||
auskommentiert damit alle Lösungen reinkommen ANFANG */
|
||||
{
|
||||
else {
|
||||
//alle Fehlerfaelle und alle korrekten Ergebnis jeweils adden
|
||||
writeLog("RES Fst: result: " + result.toString() + " res: " + res.toString());
|
||||
result.addAll(res);
|
||||
@@ -1327,7 +1287,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
//wenn korrektes Ergebnis gefunden alle Fehlerfaelle loeschen
|
||||
result = par_res;
|
||||
if (!par_res.isEmpty() && par_res.iterator().next() instanceof WildcardType) {
|
||||
//System.out.println("");
|
||||
System.out.println("");
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1343,7 +1303,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
//break;
|
||||
}
|
||||
|
||||
/* auskommentiert um alle Max und min Betrachtung auszuschalten ANFANG
|
||||
/* auskommentiert um alle Max und min Betrachtung auszuschalten ANFANG */
|
||||
if (!result.isEmpty() && (!isUndefinedPairSetSet(res) || !aParDef.isEmpty())) {
|
||||
if (nextSetasList.iterator().hasNext() && nextSetasList.iterator().next().stream().filter(x -> x.getLhsType().getName().equals("B")).findFirst().isPresent() && nextSetasList.size()>1)
|
||||
System.out.print("");
|
||||
@@ -1451,7 +1411,6 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
else { if (variance == 0) {
|
||||
writeLog("a: " + rekTiefe + " variance: " + variance + a.toString());
|
||||
if (!oderConstraint) {
|
||||
writeStatistics("break");
|
||||
break;
|
||||
}
|
||||
else {
|
||||
@@ -1480,7 +1439,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
writeLog("a: " + rekTiefe + " variance: " + variance + a.toString());
|
||||
}
|
||||
}
|
||||
auskommentiert um alle Max und min Betrachtung auszuschalten ENDE */
|
||||
/* auskommentiert um alle Max und min Betrachtung auszuschalten ENDE */
|
||||
|
||||
if (isUndefinedPairSetSet(res) && aParDef.isEmpty()) {
|
||||
int nofstred= 0;
|
||||
@@ -1513,9 +1472,8 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
return new Pair<>(su, x.getGroundBasePair());})
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
if (res.size() > 1) {
|
||||
//System.out.println();
|
||||
System.out.println();
|
||||
}
|
||||
/* statistics no erase
|
||||
writeLog("nextSetasList vor filter-Aufruf: " + nextSetasList);
|
||||
if (!oderConstraint) {//PL 2023-02-08 eingefuegt: Bei oderconstraints sind Subststitutionen nicht als Substitutionen in idesem Sinne zu sehen
|
||||
nextSetasList = nextSetasList.stream().filter(x -> {
|
||||
@@ -1528,7 +1486,6 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
}
|
||||
writeLog("nextSetasList nach filter-Aufruf: " + nextSetasList);
|
||||
*/
|
||||
nofstred = nextSetasList.size();
|
||||
//NOCH NICHT korrekt PL 2018-10-12
|
||||
//nextSetasList = nextSetasList.stream().filter(y -> couldBecorrect(reducedUndefResSubstGroundedBasePair, y))
|
||||
@@ -1546,11 +1503,8 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
writeLog("Number of all erased Elements (undef): " + noAllErasedElements.toString());
|
||||
noBacktracking++;
|
||||
writeLog("Number of Backtracking: " + noBacktracking);
|
||||
//writeStatistics("Number of erased elements: " + (len - nextSetasList.size()));
|
||||
//writeStatistics("Number of Backtracking: " + noBacktracking);
|
||||
//System.out.println("");
|
||||
System.out.println("");
|
||||
}
|
||||
else //writeStatistics("res: " + res.toString());
|
||||
//if (nextSetasList.size() == 0 && isUndefinedPairSetSet(result) && nextSet.size() > 1) {
|
||||
// return result;
|
||||
//}
|
||||
@@ -1559,9 +1513,6 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
//}
|
||||
//else result.stream().filter(y -> !isUndefinedPairSet(y));
|
||||
writeLog("res: " + res.toString());
|
||||
//writeStatistics(" End Number of Elements (" + rekTiefe + "): " + nextSetasList.size());
|
||||
noLoop++;
|
||||
//writeStatistics("Number of Loops: " + noLoop);
|
||||
}
|
||||
//2020-02-02: if (variance ==2) Hier Aufruf von filterOverriding einfuegen
|
||||
writeLog("Return computeCR: " + result.toString());
|
||||
@@ -2057,7 +2008,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
//System.out.println(pair);
|
||||
if (first) { //writeLog(pair.toString()+"\n");
|
||||
if (((PlaceholderType)(pair.getLhsType())).getName().equals("AR")) {
|
||||
//System.out.println("AR");
|
||||
System.out.println("AR");
|
||||
}
|
||||
Set<Set<UnifyPair>> x1 = unifyCase1(pair, fc);
|
||||
if (pairOp == PairOperator.SMALLERNEQDOT) {
|
||||
@@ -2625,18 +2576,4 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void writeStatistics(String str) {
|
||||
if (finalresult) {
|
||||
synchronized ( this ) {
|
||||
try {
|
||||
statistics.write("Thread No. " + thNo + ": " + str + "\n");
|
||||
statistics.flush();
|
||||
|
||||
}
|
||||
catch (IOException e) {
|
||||
System.err.println("kein StatisticsFile");
|
||||
}
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package de.dhbwstuttgart.util;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public class Pair<T, T1> {
|
||||
@@ -22,4 +23,17 @@ public class Pair<T, T1> {
|
||||
public String toString() {
|
||||
return "(" + key.toString() + "," + value.toString() + ")\n";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Pair<?, ?> pair = (Pair<?, ?>) o;
|
||||
return Objects.equals(key, pair.key) && Objects.equals(value, pair.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(key, value);
|
||||
}
|
||||
}
|
||||
|
105
src/test/java/GenericsParserTest.java
Normal file
105
src/test/java/GenericsParserTest.java
Normal file
@@ -0,0 +1,105 @@
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.GenericContext;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class GenericsParserTest {
|
||||
|
||||
@Test
|
||||
public void testMethodNoGenerics() {
|
||||
var signature = "()V";
|
||||
var generics = ASTFactory.createGenerics(signature);
|
||||
assertEquals(generics, new GenericDeclarationList(List.of(), new NullToken()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethodSimpleGenerics() {
|
||||
var signature = "<T:Ljava/lang/Object;>()V";
|
||||
var generics = ASTFactory.createGenerics(signature);
|
||||
assertEquals(generics, new GenericDeclarationList(
|
||||
List.of(new GenericTypeVar("T", List.of(ASTToTargetAST.OBJECT), new NullToken(), new NullToken())), new NullToken())
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethodExtends() {
|
||||
var signature = "<T:Ljava/lang/Class<TT;>;>()V";
|
||||
var generics = ASTFactory.createGenerics(signature);
|
||||
assertEquals(generics, new GenericDeclarationList(
|
||||
List.of(new GenericTypeVar("T", List.of(
|
||||
new RefType(new JavaClassName("java.lang.Class"), List.of(new GenericRefType("T", new NullToken())), new NullToken())),
|
||||
new NullToken(), new NullToken())), new NullToken()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethodVariance() {
|
||||
var signature = "<T:Ljava/lang/Class<+TT;>;>()V";
|
||||
var generics = ASTFactory.createGenerics(signature);
|
||||
|
||||
assertEquals(generics, new GenericDeclarationList(
|
||||
List.of(new GenericTypeVar("T", List.of(
|
||||
new RefType(new JavaClassName("java.lang.Class"), List.of(
|
||||
new ExtendsWildcardType(new GenericRefType("T", new NullToken()), new NullToken())
|
||||
), new NullToken())),
|
||||
new NullToken(), new NullToken())),
|
||||
new NullToken())
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethodTypeVars() {
|
||||
var signature = "<A:TB;B:LClassA;C:LClassB<TA;>;D:TB;>()V";
|
||||
var generics = ASTFactory.createGenerics(signature);
|
||||
assertEquals(generics, new GenericDeclarationList(
|
||||
List.of(
|
||||
new GenericTypeVar("A", List.of(new GenericRefType("B", new NullToken())), new NullToken(), new NullToken()),
|
||||
new GenericTypeVar("B", List.of(new RefType(new JavaClassName("ClassA"), new NullToken())), new NullToken(), new NullToken()),
|
||||
new GenericTypeVar("C", List.of(new RefType(new JavaClassName("ClassB"),
|
||||
List.of(new GenericRefType("A", new NullToken())),
|
||||
new NullToken())), new NullToken(), new NullToken()
|
||||
),
|
||||
new GenericTypeVar("D", List.of(new GenericRefType("B", new NullToken())), new NullToken(), new NullToken())
|
||||
),
|
||||
new NullToken()
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethodComplex() {
|
||||
var signature = "<T:LClassA<+TT;LClassB<+LClassA;-LClassC<LClassA;>;>;>;U:LClassC<LClassC;>;>()V";
|
||||
var generics = ASTFactory.createGenerics(signature);
|
||||
|
||||
assertEquals(generics, new GenericDeclarationList(
|
||||
List.of(new GenericTypeVar("T", List.of(
|
||||
new RefType(new JavaClassName("ClassA"), List.of(
|
||||
new ExtendsWildcardType(new GenericRefType("T", new NullToken()), new NullToken()),
|
||||
new RefType(new JavaClassName("ClassB"), List.of(
|
||||
new ExtendsWildcardType(new RefType(new JavaClassName("ClassA"), new NullToken()), new NullToken()),
|
||||
new SuperWildcardType(
|
||||
new RefType(new JavaClassName("ClassC"), List.of(
|
||||
new RefType(new JavaClassName("ClassA"), new NullToken())
|
||||
), new NullToken()), new NullToken())
|
||||
), new NullToken())
|
||||
), new NullToken())
|
||||
), new NullToken(), new NullToken()),
|
||||
new GenericTypeVar("U", List.of(
|
||||
new RefType(new JavaClassName("ClassC"), List.of(
|
||||
new RefType(new JavaClassName("ClassC"), new NullToken())
|
||||
), new NullToken())
|
||||
), new NullToken(), new NullToken())),
|
||||
new NullToken()
|
||||
));
|
||||
}
|
||||
}
|
@@ -281,7 +281,6 @@ public class TestComplete {
|
||||
|
||||
@Test
|
||||
public void scalarTest() throws Exception {
|
||||
|
||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Scalar.jav");
|
||||
var scalar = classFiles.get("Scalar");
|
||||
|
||||
@@ -576,6 +575,11 @@ public class TestComplete {
|
||||
assertEquals(fstArgm2, m2.getGenericReturnType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTXGenerics() throws Exception {
|
||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "TXGenerics.jav");
|
||||
var instance = classFiles.get("TXGenerics").getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typedIdTest() throws Exception {
|
||||
|
@@ -90,16 +90,15 @@ public class TestGenerics {
|
||||
|
||||
var generics = result.genericsResults.get(0);
|
||||
assertEquals(0, generics.get(result.clazz).size());
|
||||
assertEquals(2, generics.get(m).size());
|
||||
assertEquals(1, generics.get(m).size());
|
||||
assertEquals(2, generics.get(main).size());
|
||||
|
||||
var N = generics.getBounds(m.getParameterList().getParameterAt(0).getType(), result.clazz, m);
|
||||
var NChain = new BoundsList(new Bound(true, ASTToTargetAST.OBJECT));
|
||||
assertEquals(N, NChain);
|
||||
var N2 = generics.getBounds(m.getReturnType(), result.clazz, m);
|
||||
|
||||
var Q = generics.getBounds(m.getReturnType(), result.clazz, m);
|
||||
var QChain = new BoundsList(new Bound(true, TypePlaceholder.of("N")), new Bound(true, ASTToTargetAST.OBJECT));
|
||||
assertEquals(Q, QChain);
|
||||
var NChain = new BoundsList(new Bound(true, ASTToTargetAST.OBJECT));
|
||||
assertEquals(N, N2);
|
||||
assertEquals(N2, NChain);
|
||||
|
||||
var R = generics.getBounds(main.getParameterList().getParameterAt(0).getType(), result.clazz, main);
|
||||
assertEquals(R, NChain);
|
||||
@@ -304,17 +303,18 @@ public class TestGenerics {
|
||||
var main = result.findMethod("main");
|
||||
|
||||
var generics = result.genericsResults.get(0);
|
||||
var Q = generics.getBounds(id.getReturnType(), result.clazz, id);
|
||||
var N = generics.getBounds(id.getParameterList().getParameterAt(0).getType(), result.clazz, id);
|
||||
assertEquals(Q, new BoundsList(new Bound(true, ASTToTargetAST.OBJECT)));
|
||||
assertEquals(N, new BoundsList(new Bound(true, TypePlaceholder.of("Q")), new Bound(true, ASTToTargetAST.OBJECT)));
|
||||
var O = generics.getBounds(id.getReturnType(), result.clazz, id);
|
||||
var O2 = generics.getBounds(id.getParameterList().getParameterAt(0).getType(), result.clazz, id);
|
||||
assertEquals(O, O2);
|
||||
assertEquals(O2, new BoundsList(new Bound(true, ASTToTargetAST.OBJECT)));
|
||||
|
||||
var Q2 = generics.getBounds(main.getReturnType(), result.clazz, main);
|
||||
var R = generics.getBounds(main.getParameterList().getParameterAt(0).getType(), result.clazz, main);
|
||||
var S = generics.getBounds(main.getParameterList().getParameterAt(1).getType(), result.clazz, main);
|
||||
assertEquals(Q2, new BoundsList(new Bound(true, ASTToTargetAST.OBJECT)));
|
||||
assertEquals(R, new BoundsList(new Bound(true, TypePlaceholder.of("Q")), new Bound(true, ASTToTargetAST.OBJECT)));
|
||||
assertEquals(S, new BoundsList(new Bound(true, TypePlaceholder.of("Q")), new Bound(true, ASTToTargetAST.OBJECT)));
|
||||
// TODO Maybe test in other ways if the parameter generics equals the return generics
|
||||
var S = generics.getBounds(main.getReturnType(), result.clazz, main);
|
||||
var S2 = generics.getBounds(main.getParameterList().getParameterAt(0).getType(), result.clazz, main);
|
||||
var T = generics.getBounds(main.getParameterList().getParameterAt(1).getType(), result.clazz, main);
|
||||
assertEquals(S, S2);
|
||||
assertEquals(S2, new BoundsList(new Bound(true, ASTToTargetAST.OBJECT)));
|
||||
assertEquals(T, new BoundsList(new Bound(true, ASTToTargetAST.OBJECT)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
|
||||
|
||||
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
|
||||
|
||||
<appender name="CONSOLE" class="de.dhbwstuttgart.logger.ConsoleAppender">
|
||||
<param name="Target" value="System.out"/>
|
||||
|
||||
<layout class="de.dhbwstuttgart.logger.PatternLayout">
|
||||
<param name="ConversionPattern" value="%-15C{1} %-5p [%-9c] %m%n"/>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<logger name="trtest">
|
||||
<level value="DEBUG"/>
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
</logger>
|
||||
|
||||
<logger name="funcTest">
|
||||
<level value="DEBUG"/>
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
</logger>
|
||||
|
||||
</log4j:configuration>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user