forked from JavaTX/JavaCompilerCore
Tphs einer Methode, die groesser als Tphs der Felder, werden als Class-Generics definiert
This commit is contained in:
parent
e380c77ce6
commit
b71efd65a0
@ -6,6 +6,7 @@ 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.exceptions.NotImplementedException;
|
||||
@ -62,6 +63,8 @@ public class BytecodeGen implements ASTVisitor {
|
||||
|
||||
private String superClass;
|
||||
|
||||
private ArrayList<TypePlaceholder> tphsClass;
|
||||
|
||||
// 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
|
||||
@ -138,12 +141,28 @@ public class BytecodeGen implements ASTVisitor {
|
||||
|
||||
getCommonTPHS(tphExtractor);
|
||||
|
||||
ArrayList<TypePlaceholder> tphsClass = new ArrayList<>();
|
||||
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:
|
||||
@ -152,7 +171,7 @@ public class BytecodeGen implements ASTVisitor {
|
||||
if(classOrInterface.getGenerics().iterator().hasNext() || !commonPairs.isEmpty() ||
|
||||
classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<")
|
||||
|| !tphsClass.isEmpty()) {
|
||||
Signature signature = new Signature(classOrInterface, genericsAndBounds,commonPairs,tphsClass);
|
||||
Signature signature = new Signature(classOrInterface, genericsAndBounds,commonPairs,tphsClass, consClass);
|
||||
sig = signature.toString();
|
||||
System.out.println("Signature: => " + sig);
|
||||
}
|
||||
@ -184,6 +203,31 @@ 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<>();
|
||||
@ -236,7 +280,7 @@ public class BytecodeGen implements ASTVisitor {
|
||||
}
|
||||
String sig = null;
|
||||
if(hasGen) {
|
||||
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(field.name, tphExtractor);
|
||||
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(field.name, tphExtractor,tphsClass);
|
||||
Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes,resultSet,constraints);
|
||||
sig = signature.toString();
|
||||
}
|
||||
@ -315,7 +359,7 @@ public class BytecodeGen implements ASTVisitor {
|
||||
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);
|
||||
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();
|
||||
|
@ -708,7 +708,13 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
@Override
|
||||
public void visit(FieldVar fieldVar) {
|
||||
fieldName = fieldVar.fieldVarName;
|
||||
fieldDesc = "L" + getResolvedType(fieldVar.getType()) + ";";
|
||||
fieldDesc = "L";
|
||||
if(resultSet.resolveType(fieldVar.getType()).resolvedType instanceof TypePlaceholder) {
|
||||
fieldDesc += Type.getInternalName(Object.class);
|
||||
} else {
|
||||
fieldDesc += resultSet.resolveType(fieldVar.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
}
|
||||
fieldDesc +=";";
|
||||
|
||||
fieldVar.receiver.accept(this);
|
||||
// test (if)
|
||||
@ -1405,9 +1411,18 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
// array slot onto the top of the operand stack.
|
||||
assignLeftSide.field.receiver.accept(this);
|
||||
this.rightSideTemp.accept(this);
|
||||
String fDesc = "L";
|
||||
if(resultSet.resolveType(assignLeftSide.field.getType()).resolvedType instanceof TypePlaceholder) {
|
||||
fDesc += Type.getInternalName(Object.class);
|
||||
} else {
|
||||
fDesc += resultSet.resolveType(assignLeftSide.field.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
}
|
||||
fDesc +=";";
|
||||
|
||||
|
||||
System.out.println("Receiver = " + getResolvedType(assignLeftSide.field.receiver.getType()));
|
||||
mv.visitFieldInsn(Opcodes.PUTFIELD, getResolvedType(assignLeftSide.field.receiver.getType()),
|
||||
assignLeftSide.field.fieldVarName, "L"+getResolvedType(assignLeftSide.field.getType())+";");
|
||||
assignLeftSide.field.fieldVarName, fDesc);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -42,13 +42,15 @@ public class Signature {
|
||||
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,
|
||||
ArrayList<GenericInsertPair> commonPairs, ArrayList<TypePlaceholder> tphsClass) {
|
||||
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();
|
||||
}
|
||||
@ -370,7 +372,37 @@ public class Signature {
|
||||
GenericTypeVar g = itr.next();
|
||||
getBoundsOfTypeVar(g,genericsAndBounds);
|
||||
}
|
||||
if(!commonPairs.isEmpty()) {
|
||||
|
||||
if(!consClass.isEmpty()) {
|
||||
ArrayList<String> types = new ArrayList<>();
|
||||
ArrayList<String> superTypes = new ArrayList<>();
|
||||
|
||||
for(TPHConstraint cons : consClass) {
|
||||
types.add(cons.getLeft());
|
||||
superTypes.add(cons.getRight());
|
||||
}
|
||||
|
||||
for(TPHConstraint cons : consClass) {
|
||||
String t = cons.getLeft()+"$";
|
||||
String bound = cons.getRight()+"$";
|
||||
sw.visitFormalTypeParameter(t);
|
||||
sw.visitClassBound().visitTypeVariable(bound);
|
||||
genericsAndBounds.put(t, 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<>();
|
||||
|
||||
@ -405,7 +437,7 @@ public class Signature {
|
||||
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();
|
||||
|
@ -15,8 +15,8 @@ import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
|
||||
public class Simplify {
|
||||
private static int a = 6;
|
||||
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraints(String name, TPHExtractor tphExtractor) {
|
||||
|
||||
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
|
||||
|
52
test/bytecode/FieldTph2Test.java
Normal file
52
test/bytecode/FieldTph2Test.java
Normal file
@ -0,0 +1,52 @@
|
||||
package bytecode;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
|
||||
public class FieldTph2Test {
|
||||
|
||||
private static String path;
|
||||
private static File fileToTest;
|
||||
private static JavaTXCompiler compiler;
|
||||
private static ClassLoader loader;
|
||||
private static Class<?> classToTest;
|
||||
private static String pathToClassFile;
|
||||
private static Object instanceOfClass;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/FieldTph2.jav";
|
||||
fileToTest = new File(path);
|
||||
compiler = new JavaTXCompiler(fileToTest);
|
||||
compiler.generateBytecode(System.getProperty("user.dir")+"/testBytecode/generatedBC/");
|
||||
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||
classToTest = loader.loadClass("FieldTph2");
|
||||
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
Field a = classToTest.getDeclaredField("a");
|
||||
a.setAccessible(true);
|
||||
|
||||
Method m2 = classToTest.getDeclaredMethod("m2", Object.class);
|
||||
m2.invoke(instanceOfClass, 1);
|
||||
|
||||
Method m = classToTest.getDeclaredMethod("m", Object.class);
|
||||
Object result = m.invoke(instanceOfClass, 1);
|
||||
|
||||
assertEquals(1,result);
|
||||
}
|
||||
|
||||
}
|
12
test/bytecode/javFiles/FieldTph2.jav
Normal file
12
test/bytecode/javFiles/FieldTph2.jav
Normal file
@ -0,0 +1,12 @@
|
||||
public class FieldTph2 {
|
||||
a;
|
||||
|
||||
m(b){
|
||||
b = a;
|
||||
return b;
|
||||
}
|
||||
|
||||
m2(c){
|
||||
a = c;
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ package bytecode.simplifyalgo;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
@ -68,7 +69,7 @@ public class CycleTest {
|
||||
TPHConstraint k = new ExtendsConstraint("A", Type.getInternalName(Object.class), Relation.EXTENDS);
|
||||
result.put(k, equals);
|
||||
|
||||
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor);
|
||||
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor,new ArrayList<>());
|
||||
boolean areEquals = SimpleCycle.areMapsEqual(result, sim);
|
||||
assertTrue(areEquals);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package bytecode.simplifyalgo;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
@ -76,7 +77,7 @@ public class SameLeftSide {
|
||||
|
||||
result.put(b, hs);
|
||||
|
||||
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor);
|
||||
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor,new ArrayList<>());
|
||||
boolean areEquals = SimpleCycle.areMapsEqual(result, sim);
|
||||
assertTrue(areEquals);
|
||||
}
|
||||
@ -93,7 +94,7 @@ public class SameLeftSide {
|
||||
hs.add("B");
|
||||
result.put(c, hs);
|
||||
|
||||
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName2, tphExtractor);
|
||||
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName2, tphExtractor,new ArrayList<>());
|
||||
boolean areEquals = SimpleCycle.areMapsEqual(result, sim);
|
||||
assertTrue(areEquals);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package bytecode.simplifyalgo;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
@ -45,7 +46,7 @@ public class SimpleCycle {
|
||||
TPHConstraint k = new ExtendsConstraint("B", Type.getInternalName(Object.class), Relation.EXTENDS);
|
||||
result.put(k, equals);
|
||||
|
||||
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor);
|
||||
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor,new ArrayList<>());
|
||||
boolean areEquals = areMapsEqual(result, sim);
|
||||
assertTrue(areEquals);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user