forked from JavaTX/JavaCompilerCore
Merge branch 'targetBytecode' into bigRefactoring
This commit is contained in:
commit
4c685a9ed9
5
pom.xml
5
pom.xml
@ -17,10 +17,11 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
|||||||
<version>4.11</version>
|
<version>4.11</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.antlr/antlr4 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.antlr</groupId>
|
<groupId>org.antlr</groupId>
|
||||||
<artifactId>antlr4</artifactId>
|
<artifactId>antlr4</artifactId>
|
||||||
<version>4.8-1</version>
|
<version>4.11.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
@ -60,7 +61,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.antlr</groupId>
|
<groupId>org.antlr</groupId>
|
||||||
<artifactId>antlr4-maven-plugin</artifactId>
|
<artifactId>antlr4-maven-plugin</artifactId>
|
||||||
<version>4.8-1</version>
|
<version>4.11.1</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>antlr</id>
|
<id>antlr</id>
|
||||||
|
9
resources/AllgemeinTest/VectorNotObject.jav
Normal file
9
resources/AllgemeinTest/VectorNotObject.jav
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
class VectorNotObject {
|
||||||
|
|
||||||
|
vectorAddAll(v1, v2) {
|
||||||
|
v1.addAll(v2);
|
||||||
|
return v1;
|
||||||
|
}
|
||||||
|
}
|
16
resources/AllgemeinTest/WildcardCaptureConversionTest.jav
Normal file
16
resources/AllgemeinTest/WildcardCaptureConversionTest.jav
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import java.util.Vector;
|
||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.String;
|
||||||
|
|
||||||
|
class WildcardCaptureConversionTest {
|
||||||
|
|
||||||
|
m(x, y ,z) {
|
||||||
|
x = new Vector<Integer>();
|
||||||
|
y = new Vector<String>();
|
||||||
|
x.add(1);
|
||||||
|
y.add("2");
|
||||||
|
//Integer i = x.elementAt(0);
|
||||||
|
//String s = y.elementAt(0);
|
||||||
|
return z.vectorAddAll(x, y);
|
||||||
|
}
|
||||||
|
}
|
7
resources/bytecode/javFiles/Box.jav
Normal file
7
resources/bytecode/javFiles/Box.jav
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
class B { }
|
||||||
|
class Box_Main extends B {
|
||||||
|
m(b) {
|
||||||
|
b.m(new Box_Main());
|
||||||
|
b.m(new B());
|
||||||
|
}
|
||||||
|
}
|
3
resources/bytecode/javFiles/Box.java
Normal file
3
resources/bytecode/javFiles/Box.java
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
class Box<A> {
|
||||||
|
void m(A a) { }
|
||||||
|
}
|
@ -1,3 +1,6 @@
|
|||||||
|
import java.lang.String;
|
||||||
|
import java.lang.Integer;
|
||||||
|
|
||||||
class Generics2<B extends String>{
|
class Generics2<B extends String>{
|
||||||
<B extends Integer> B m1(B b){
|
<B extends Integer> B m1(B b){
|
||||||
return b;
|
return b;
|
||||||
|
7
resources/bytecode/javFiles/Generics3.jav
Normal file
7
resources/bytecode/javFiles/Generics3.jav
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import java.lang.String;
|
||||||
|
import java.lang.Integer;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
class Generics3<B extends String & List<Integer>> {
|
||||||
|
|
||||||
|
}
|
12
resources/bytecode/javFiles/Generics4.jav
Normal file
12
resources/bytecode/javFiles/Generics4.jav
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import java.lang.String;
|
||||||
|
import java.lang.Integer;
|
||||||
|
|
||||||
|
class Generics4<B extends String> {
|
||||||
|
<C extends Integer> C m1(C b){
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
m2(x) {
|
||||||
|
return m1(x);
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,10 @@ public class Inf {
|
|||||||
w=y;
|
w=y;
|
||||||
y=a;
|
y=a;
|
||||||
b=a;
|
b=a;
|
||||||
|
var c;
|
||||||
|
var d;
|
||||||
|
c = v;
|
||||||
|
d = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,21 +29,27 @@ TPH M m(TPH N x, TPH O y, TPH P a)({
|
|||||||
(w)::TPH S = (y)::TPH O;
|
(w)::TPH S = (y)::TPH O;
|
||||||
(y)::TPH O = (a)::TPH P;
|
(y)::TPH O = (a)::TPH P;
|
||||||
(b)::TPH T = (a)::TPH P;
|
(b)::TPH T = (a)::TPH P;
|
||||||
|
TPH U c;
|
||||||
|
TPH V d;
|
||||||
|
(c)::TPH U = (v)::TPH R;
|
||||||
|
(d)::TPH V = (v)::TPH R;
|
||||||
return;
|
return;
|
||||||
})::TPH U
|
})::TPH W
|
||||||
|
|
||||||
Inf()({
|
Inf()({
|
||||||
super(());
|
super(());
|
||||||
})::TPH X
|
})::TPH Z
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// c::U d::V
|
||||||
|
// \ /
|
||||||
// v::R w::S
|
// v::R w::S
|
||||||
// \ /
|
// \ /
|
||||||
// z::Q y::O b::T
|
// z::Q y::O b::T
|
||||||
// \ / \ /
|
// \ / \ /
|
||||||
// x::N a::P
|
// x::N a::P
|
||||||
|
|
||||||
RESULT Final: [[(TPH O < TPH S), (TPH P < TPH O), (TPH O < TPH R), (TPH P < TPH T), (TPH M = void), (TPH N < TPH O), (TPH N < TPH Q)]]
|
RESULT Final: [[(TPH N < TPH O), (TPH R < TPH V), (TPH N < TPH Q), (TPH P < TPH O), (TPH R < TPH U), (TPH M = void), (TPH O < TPH S), (TPH O < TPH R), (TPH P < TPH T)]]
|
||||||
Simplified constraints: [(TPH O < TPH S), (TPH P < TPH O), (TPH O < TPH R), (TPH P < TPH T), (TPH N < TPH O), (TPH N < TPH Q)]
|
Simplified constraints: [(TPH O < TPH S), (TPH P < TPH O), (TPH O < TPH R), (TPH P < TPH T), (TPH N < TPH O), (TPH N < TPH Q)]
|
||||||
m: [(TPH DDV = java.lang.Object), (TPH DDX = java.lang.Object), (TPH DDX < TPH DDV), (TPH N < TPH DDX), (TPH P < TPH DDX)]
|
m: [(TPH DDV = java.lang.Object), (TPH DDX = java.lang.Object), (TPH DDX < TPH DDV), (TPH N < TPH DDX), (TPH P < TPH DDX)]
|
||||||
Class Inf: []
|
Class Inf: []
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
public class SimpleCycle {
|
public class SimpleCycle {
|
||||||
|
|
||||||
m(a,b,d){
|
m(){
|
||||||
var g;
|
var g;
|
||||||
var h;
|
var h;
|
||||||
g = h;
|
g = h;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.lang.Integer;
|
import java.lang.Integer;
|
||||||
|
import java.lang.String;
|
||||||
|
|
||||||
public class VectorAdd {
|
public class VectorAdd {
|
||||||
vectorAdd(v1, v2) {
|
vectorAdd(v1, v2) {
|
||||||
@ -13,4 +13,14 @@ public class VectorAdd {
|
|||||||
}
|
}
|
||||||
return erg;
|
return erg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m(x, y, z) {
|
||||||
|
x = new Vector<Integer>();
|
||||||
|
y = new Vector<String>();
|
||||||
|
x.add(1);
|
||||||
|
y.add("2");
|
||||||
|
//Integer i = x.elementAt(0);
|
||||||
|
//String s = y.elementAt(0);
|
||||||
|
return z.addAll(x);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,29 @@
|
|||||||
public class TestTwoArgs {
|
public class TestTwoArgs //<T extends AS, AS extends Z, Z extends AN, AN extends AG, AG>
|
||||||
|
{
|
||||||
|
//AS
|
||||||
a;
|
a;
|
||||||
|
|
||||||
|
//AN -> AN
|
||||||
id(b) {
|
id(b) {
|
||||||
var c = b;
|
var c = b;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//T -> AS
|
||||||
setA(x) {
|
setA(x) {
|
||||||
a = x;
|
a = x;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//(AG,Z) -> AG
|
||||||
m(x,y) {
|
m(x,y) {
|
||||||
x = id(y);
|
x = id(y);
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//<AI extends AN, AH extends T> (AI, AH) -> AG
|
||||||
main(x,y) {
|
main(x,y) {
|
||||||
return m(id(x),setA(y));
|
return m(id(x),setA(y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
|
||||||
|
|
||||||
import org.objectweb.asm.Label;
|
|
||||||
import org.objectweb.asm.MethodVisitor;
|
|
||||||
import org.objectweb.asm.Opcodes;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
|
||||||
|
|
||||||
public abstract class AStatement implements IStatement {
|
|
||||||
protected Expression expr;
|
|
||||||
|
|
||||||
public AStatement(Expression expr) {
|
|
||||||
this.expr = expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isExprBinary() {
|
|
||||||
return (expr instanceof BinaryExpr);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void genBCForRelOp(MethodVisitor mv,Label branchLabel, Label endLabel, BytecodeGenMethod bytecodeGenMethod) {
|
|
||||||
mv.visitInsn(Opcodes.ICONST_1);
|
|
||||||
mv.visitJumpInsn(Opcodes.GOTO, endLabel);
|
|
||||||
mv.visitLabel(branchLabel);
|
|
||||||
mv.visitInsn(Opcodes.ICONST_0);
|
|
||||||
mv.visitLabel(endLabel);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
|
||||||
|
|
||||||
public class ArgumentExpr extends AStatement {
|
|
||||||
|
|
||||||
public ArgumentExpr(Expression expr) {
|
|
||||||
super(expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,258 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
|
||||||
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;
|
|
||||||
|
|
||||||
public class ArgumentVisitor implements StatementVisitor {
|
|
||||||
private List<Boolean> argListMethCall;
|
|
||||||
private BytecodeGenMethod bytecodeGenMethod;
|
|
||||||
|
|
||||||
public ArgumentVisitor(List<Boolean> argListMethCall, BytecodeGenMethod bytecodeGenMethod) {
|
|
||||||
this.argListMethCall = argListMethCall;
|
|
||||||
this.bytecodeGenMethod = bytecodeGenMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(ArgumentList argumentList) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(LambdaExpression lambdaExpression) {
|
|
||||||
lambdaExpression.accept(bytecodeGenMethod);
|
|
||||||
// Zieltype des Lambas ist Funktionale Interface
|
|
||||||
// kann nie primitiv sein => un-/boxing wird hier nicht gebraucht
|
|
||||||
argListMethCall.remove(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Assign assign) {
|
|
||||||
assign.accept(bytecodeGenMethod);
|
|
||||||
|
|
||||||
if(argListMethCall.get(0))
|
|
||||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(assign.getType()));
|
|
||||||
argListMethCall.remove(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(BinaryExpr binary) {
|
|
||||||
binary.accept(bytecodeGenMethod);
|
|
||||||
|
|
||||||
if(argListMethCall.get(0)) {
|
|
||||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(binary.getType()));
|
|
||||||
} else {
|
|
||||||
bytecodeGenMethod.doBoxing(bytecodeGenMethod.getResolver().getResolvedType(binary.getType()));
|
|
||||||
}
|
|
||||||
argListMethCall.remove(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Block block) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(CastExpr castExpr) {
|
|
||||||
castExpr.accept(bytecodeGenMethod);
|
|
||||||
|
|
||||||
if(argListMethCall.get(0))
|
|
||||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(castExpr.getType()));
|
|
||||||
argListMethCall.remove(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(EmptyStmt emptyStmt) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(FieldVar fieldVar) {
|
|
||||||
fieldVar.accept(bytecodeGenMethod);
|
|
||||||
|
|
||||||
if(argListMethCall.get(0))
|
|
||||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(fieldVar.getType()));
|
|
||||||
argListMethCall.remove(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(ForStmt forStmt) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(IfStmt ifStmt) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(InstanceOf instanceOf) {
|
|
||||||
instanceOf.accept(bytecodeGenMethod);
|
|
||||||
|
|
||||||
if(argListMethCall.get(0))
|
|
||||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(instanceOf.getType()));
|
|
||||||
argListMethCall.remove(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(LocalVar localVar) {
|
|
||||||
localVar.accept(bytecodeGenMethod);
|
|
||||||
if(!bytecodeGenMethod.isBinaryExp) {
|
|
||||||
if(argListMethCall.get(0))
|
|
||||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(localVar.getType()));
|
|
||||||
}
|
|
||||||
argListMethCall.remove(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(LocalVarDecl localVarDecl) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(MethodCall methodCall) {
|
|
||||||
methodCall.accept(bytecodeGenMethod);
|
|
||||||
|
|
||||||
if(argListMethCall.get(0))
|
|
||||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(methodCall.getType()));
|
|
||||||
argListMethCall.remove(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(NewClass methodCall) {
|
|
||||||
methodCall.accept(bytecodeGenMethod);
|
|
||||||
|
|
||||||
if(argListMethCall.get(0))
|
|
||||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(methodCall.getType()));
|
|
||||||
argListMethCall.remove(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(NewArray newArray) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Return aReturn) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(ReturnVoid aReturn) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(StaticClassName staticClassName) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Super aSuper) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(This aThis) {
|
|
||||||
aThis.accept(bytecodeGenMethod);
|
|
||||||
|
|
||||||
if(argListMethCall.get(0))
|
|
||||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(aThis.getType()));
|
|
||||||
argListMethCall.remove(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(WhileStmt whileStmt) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(DoStmt whileStmt) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(AssignToField assignLeftSide) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(AssignToLocal assignLeftSide) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(SuperCall superCall) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(ExpressionReceiver expressionReceiver) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(UnaryExpr unaryExpr) {
|
|
||||||
unaryExpr.accept(bytecodeGenMethod);
|
|
||||||
|
|
||||||
if(argListMethCall.get(0))
|
|
||||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(unaryExpr.getType()));
|
|
||||||
argListMethCall.remove(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Literal literal) {
|
|
||||||
literal.accept(bytecodeGenMethod);
|
|
||||||
|
|
||||||
if(argListMethCall.get(0))
|
|
||||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(literal.getType()));
|
|
||||||
argListMethCall.remove(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
|
||||||
|
|
||||||
public class AssignStmt extends AStatement {
|
|
||||||
|
|
||||||
public AssignStmt(Expression rightSide) {
|
|
||||||
super(rightSide);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,630 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
|
||||||
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.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.NormalConstructor;
|
|
||||||
import de.dhbwstuttgart.bytecode.utilities.NormalMethod;
|
|
||||||
import de.dhbwstuttgart.bytecode.utilities.Resolver;
|
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
|
||||||
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.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.ResultSet;
|
|
||||||
|
|
||||||
public class BytecodeGen implements ASTVisitor {
|
|
||||||
|
|
||||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
|
||||||
|
|
||||||
String type;
|
|
||||||
|
|
||||||
public static RefTypeOrTPHOrWildcardOrGeneric THISTYPE = null;
|
|
||||||
private JavaClassName className;
|
|
||||||
private String pkgName;
|
|
||||||
private boolean isInterface;
|
|
||||||
private Collection<ResultSet> listOfResultSets;
|
|
||||||
private ResultSet resultSet;
|
|
||||||
private SourceFile sf;
|
|
||||||
private File path;
|
|
||||||
|
|
||||||
private Optional<Constructor> fieldInitializations;
|
|
||||||
|
|
||||||
private int indexOfFirstParam = 0;
|
|
||||||
|
|
||||||
private String superClass;
|
|
||||||
|
|
||||||
private List<String> 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
|
|
||||||
HashMap<String, String> genericsAndBounds = new HashMap<>();
|
|
||||||
|
|
||||||
private int constructorPos = 0;
|
|
||||||
|
|
||||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes = new HashMap<>();
|
|
||||||
byte[] bytecode;
|
|
||||||
HashMap<JavaClassName, byte[]> classFiles;
|
|
||||||
|
|
||||||
private final ArrayList<String> methodNameAndParamsT = new ArrayList<>();
|
|
||||||
private final ArrayList<String> fieldNameAndParamsT = new ArrayList<>();
|
|
||||||
|
|
||||||
private final ArrayList<String> fieldNameSignature = new ArrayList<>();
|
|
||||||
|
|
||||||
private List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles;
|
|
||||||
private GenericsGeneratorResultForClass generatedGenerics;
|
|
||||||
|
|
||||||
private Resolver resolver;
|
|
||||||
private final ClassLoader classLoader;
|
|
||||||
|
|
||||||
public BytecodeGen(HashMap<JavaClassName, byte[]> classFiles, Collection<ResultSet> listOfResultSets, List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles, SourceFile sf,
|
|
||||||
File path, ClassLoader classLoader) {
|
|
||||||
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()) {
|
|
||||||
System.out.println("in Class: " + cl.getClassName().toString());
|
|
||||||
BytecodeGen classGen = new BytecodeGen(classFiles, listOfResultSets, simplifyResultsForAllSourceFiles, sf, path, classLoader);
|
|
||||||
cl.accept(classGen);
|
|
||||||
classGen.writeClass(cl.getClassName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
private void writeClass(JavaClassName name) {
|
|
||||||
bytecode = cw.toByteArray();
|
|
||||||
classFiles.put(name, bytecode);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashMap<JavaClassName, byte[]> getClassFiles() {
|
|
||||||
return classFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(ClassOrInterface classOrInterface) {
|
|
||||||
|
|
||||||
className = classOrInterface.getClassName();
|
|
||||||
|
|
||||||
cw.visitSource(className.getClassName() + ".jav", null);
|
|
||||||
|
|
||||||
isInterface = (classOrInterface.getModifiers() & 512) == 512;
|
|
||||||
|
|
||||||
int acc = isInterface ? classOrInterface.getModifiers() + Opcodes.ACC_ABSTRACT
|
|
||||||
: classOrInterface.getModifiers() + Opcodes.ACC_SUPER;
|
|
||||||
|
|
||||||
fieldInitializations = classOrInterface.getfieldInitializations();
|
|
||||||
|
|
||||||
// resultSet = listOfResultSets.get(0);
|
|
||||||
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) {
|
|
||||||
superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor());
|
|
||||||
resultSet = listOfResultSetsList.get(i);
|
|
||||||
resolver = new Resolver(resultSet);
|
|
||||||
// tphExtractor.setResultSet(resultSet);
|
|
||||||
|
|
||||||
|
|
||||||
// Nur einmal ausführen!!
|
|
||||||
if (!isVisited) {
|
|
||||||
|
|
||||||
String sig = null;
|
|
||||||
/*
|
|
||||||
* 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();
|
|
||||||
System.out.println("Signature: => " + sig);
|
|
||||||
}
|
|
||||||
|
|
||||||
cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString().replace(".", "/"), sig,
|
|
||||||
classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()), null);
|
|
||||||
|
|
||||||
isVisited = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Field f : classOrInterface.getFieldDecl()) {
|
|
||||||
f.accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Constructor c : classOrInterface.getConstructors()) {
|
|
||||||
c.accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Method m : classOrInterface.getMethods()) {
|
|
||||||
m.accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Constructor field) {
|
|
||||||
// stores generics and their bounds of method
|
|
||||||
HashMap<String, String> genericsAndBoundsMethod = new HashMap<>();
|
|
||||||
|
|
||||||
field.getParameterList().accept(this);
|
|
||||||
|
|
||||||
String id = MethodUtility.createID(resolver, field);
|
|
||||||
|
|
||||||
if (methodNameAndParamsT.contains(id)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
methodNameAndParamsT.add(id);
|
|
||||||
System.out.println("Constructor: " + field.name + " , paramsType: " + id);
|
|
||||||
|
|
||||||
String desc = null;
|
|
||||||
boolean hasGen = false;
|
|
||||||
|
|
||||||
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("<")) {
|
|
||||||
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 (field.getParameterList().iterator().hasNext())
|
|
||||||
System.out.println(field.getParameterList().iterator().next().getType().acceptTV(new TypeToDescriptor()));
|
|
||||||
|
|
||||||
NormalConstructor constructor = new NormalConstructor(field, genericsAndBounds, hasGen);
|
|
||||||
desc = constructor.accept(new DescriptorToString(resultSet));
|
|
||||||
System.out.println("Constructor: " + field.getName() + " Sig: " + sig + " Desc: " + desc);
|
|
||||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", desc, sig, null);
|
|
||||||
mv.visitCode();
|
|
||||||
|
|
||||||
Block block = fieldInitializations.get().block;
|
|
||||||
|
|
||||||
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)) {
|
|
||||||
mv.visitInsn(Opcodes.RETURN);
|
|
||||||
}
|
|
||||||
mv.visitMaxs(0, 0);
|
|
||||||
mv.visitEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
@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
|
|
||||||
// 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<>();
|
|
||||||
|
|
||||||
method.getParameterList().accept(this);
|
|
||||||
|
|
||||||
String methDesc = null;
|
|
||||||
|
|
||||||
// Method getModifiers() ?
|
|
||||||
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()) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 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(..)
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
|
|
||||||
mv.visitCode();
|
|
||||||
BytecodeGenMethod gen = new BytecodeGenMethod(className, superClass, resultSet, method, mv, paramsAndLocals, cw,
|
|
||||||
genericsAndBoundsMethod, genericsAndBounds, isInterface, classFiles, sf, path, classLoader);
|
|
||||||
|
|
||||||
mv.visitMaxs(0, 0);
|
|
||||||
mv.visitEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(ParameterList formalParameters) {
|
|
||||||
paramsAndLocals = new HashMap<>();
|
|
||||||
methodParamsAndTypes = new HashMap<>();
|
|
||||||
Iterator<FormalParameter> itr = formalParameters.iterator();
|
|
||||||
int i = 1;
|
|
||||||
while (itr.hasNext()) {
|
|
||||||
FormalParameter fp = itr.next();
|
|
||||||
paramsAndLocals.put(fp.getName(), i);
|
|
||||||
methodParamsAndTypes.put(fp.getName(), resultSet.resolveType(fp.getType()).resolvedType);
|
|
||||||
fp.accept(this);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(FormalParameter formalParameter) {
|
|
||||||
formalParameter.getType().accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(RefType refType) {
|
|
||||||
type = "L" + refType.toString() + ";";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(SuperWildcardType superWildcardType) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(TypePlaceholder typePlaceholder) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(ExtendsWildcardType extendsWildcardType) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(GenericRefType genericRefType) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// ??
|
|
||||||
@Override
|
|
||||||
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);
|
|
||||||
fv.visitEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Field field) {
|
|
||||||
System.out.println("In Field ---");
|
|
||||||
String des = "L";
|
|
||||||
if (resultSet.resolveType(field.getType()).resolvedType instanceof TypePlaceholder) {
|
|
||||||
des += Type.getInternalName(Object.class);
|
|
||||||
} else {
|
|
||||||
des += resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
|
||||||
}
|
|
||||||
des += ";";
|
|
||||||
System.out.println(des);
|
|
||||||
String sig = resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToSignature(generatedGenerics.getClassConstraints()));
|
|
||||||
System.out.println(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(LambdaExpression lambdaExpression) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Assign assign) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(BinaryExpr binary) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Block block) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(CastExpr castExpr) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(EmptyStmt emptyStmt) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(ForStmt forStmt) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(IfStmt ifStmt) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(InstanceOf instanceOf) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(LocalVar localVar) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(LocalVarDecl localVarDecl) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(MethodCall methodCall) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(NewClass methodCall) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(NewArray newArray) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Return aReturn) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(ReturnVoid aReturn) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(StaticClassName staticClassName) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Super aSuper) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(This aThis) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(WhileStmt whileStmt) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(DoStmt whileStmt) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// ???
|
|
||||||
@Override
|
|
||||||
public void visit(Literal literal) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(ArgumentList argumentList) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(GenericTypeVar genericTypeVar) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(GenericDeclarationList genericTypeVars) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(AssignToField assignLeftSide) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(AssignToLocal assignLeftSide) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(SuperCall superCall) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(ExpressionReceiver expressionReceiver) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(UnaryExpr unaryExpr) {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
|||||||
package de.dhbwstuttgart.target.bytecode;
|
package de.dhbwstuttgart.bytecode;
|
||||||
|
|
||||||
public class CodeGenException extends RuntimeException {
|
public class CodeGenException extends RuntimeException {
|
||||||
public CodeGenException(String cause) {
|
public CodeGenException(String cause) {
|
40
src/main/java/de/dhbwstuttgart/target/bytecode/Codegen.java → src/main/java/de/dhbwstuttgart/bytecode/Codegen.java
Executable file → Normal file
40
src/main/java/de/dhbwstuttgart/target/bytecode/Codegen.java → src/main/java/de/dhbwstuttgart/bytecode/Codegen.java
Executable file → Normal file
@ -1,6 +1,5 @@
|
|||||||
package de.dhbwstuttgart.target.bytecode;
|
package de.dhbwstuttgart.bytecode;
|
||||||
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Block;
|
|
||||||
import de.dhbwstuttgart.target.tree.*;
|
import de.dhbwstuttgart.target.tree.*;
|
||||||
import de.dhbwstuttgart.target.tree.expression.*;
|
import de.dhbwstuttgart.target.tree.expression.*;
|
||||||
import de.dhbwstuttgart.target.tree.type.*;
|
import de.dhbwstuttgart.target.tree.type.*;
|
||||||
@ -59,8 +58,10 @@ public class Codegen {
|
|||||||
Scope scope = new Scope(null);
|
Scope scope = new Scope(null);
|
||||||
int localCounter;
|
int localCounter;
|
||||||
MethodVisitor mv;
|
MethodVisitor mv;
|
||||||
|
TargetType returnType;
|
||||||
|
|
||||||
State(MethodVisitor mv, int localCounter) {
|
State(TargetType returnType, MethodVisitor mv, int localCounter) {
|
||||||
|
this.returnType = returnType;
|
||||||
this.mv = mv;
|
this.mv = mv;
|
||||||
this.localCounter = localCounter;
|
this.localCounter = localCounter;
|
||||||
}
|
}
|
||||||
@ -236,7 +237,7 @@ public class Codegen {
|
|||||||
mv.visitInsn(I2F);
|
mv.visitInsn(I2F);
|
||||||
else if (dest.equals(TargetType.Double))
|
else if (dest.equals(TargetType.Double))
|
||||||
mv.visitInsn(I2D);
|
mv.visitInsn(I2D);
|
||||||
} else {
|
} else if (!(dest instanceof TargetGenericType)) {
|
||||||
boxPrimitive(state, source);
|
boxPrimitive(state, source);
|
||||||
mv.visitTypeInsn(CHECKCAST, dest.getInternalName());
|
mv.visitTypeInsn(CHECKCAST, dest.getInternalName());
|
||||||
unboxPrimitive(state, dest);
|
unboxPrimitive(state, dest);
|
||||||
@ -751,7 +752,7 @@ public class Codegen {
|
|||||||
private void generate(State state, TargetExpression expr) {
|
private void generate(State state, TargetExpression expr) {
|
||||||
var mv = state.mv;
|
var mv = state.mv;
|
||||||
switch (expr) {
|
switch (expr) {
|
||||||
case TargetClassName className:
|
case TargetClassName ignored:
|
||||||
break; // NOP
|
break; // NOP
|
||||||
case TargetBlock block: {
|
case TargetBlock block: {
|
||||||
var localCounter = state.localCounter;
|
var localCounter = state.localCounter;
|
||||||
@ -810,6 +811,9 @@ public class Codegen {
|
|||||||
generate(state, varDecl.value());
|
generate(state, varDecl.value());
|
||||||
boxPrimitive(state, varDecl.varType());
|
boxPrimitive(state, varDecl.varType());
|
||||||
mv.visitVarInsn(ASTORE, local.index());
|
mv.visitVarInsn(ASTORE, local.index());
|
||||||
|
} else {
|
||||||
|
mv.visitInsn(ACONST_NULL);
|
||||||
|
mv.visitVarInsn(ASTORE, local.index());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -830,13 +834,15 @@ public class Codegen {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TargetFieldVar dot: {
|
case TargetFieldVar dot: {
|
||||||
|
var fieldType = dot.type();
|
||||||
generate(state, dot.left());
|
generate(state, dot.left());
|
||||||
generate(state, assign.right());
|
generate(state, assign.right());
|
||||||
boxPrimitive(state, assign.right().type());
|
convertTo(state, assign.right().type(), fieldType);
|
||||||
|
boxPrimitive(state, fieldType);
|
||||||
if (dot.isStatic())
|
if (dot.isStatic())
|
||||||
mv.visitInsn(DUP);
|
mv.visitInsn(DUP);
|
||||||
else mv.visitInsn(DUP_X1);
|
else mv.visitInsn(DUP_X1);
|
||||||
mv.visitFieldInsn(dot.isStatic() ? PUTSTATIC : PUTFIELD, dot.owner().getInternalName(), dot.right(), dot.type().toSignature());
|
mv.visitFieldInsn(dot.isStatic() ? PUTSTATIC : PUTFIELD, dot.owner().getInternalName(), dot.right(), fieldType.toSignature());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -867,6 +873,7 @@ public class Codegen {
|
|||||||
mv.visitLabel(start);
|
mv.visitLabel(start);
|
||||||
if (_for.termination() != null)
|
if (_for.termination() != null)
|
||||||
generate(state, _for.termination());
|
generate(state, _for.termination());
|
||||||
|
else mv.visitInsn(ICONST_1);
|
||||||
mv.visitJumpInsn(IFEQ, end);
|
mv.visitJumpInsn(IFEQ, end);
|
||||||
generate(state, _for.body());
|
generate(state, _for.body());
|
||||||
if (_for.increment() != null) {
|
if (_for.increment() != null) {
|
||||||
@ -907,9 +914,10 @@ public class Codegen {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TargetReturn ret: {
|
case TargetReturn ret: {
|
||||||
if (ret.expression() != null) {
|
if (ret.expression() != null && state.returnType != null) {
|
||||||
generate(state, ret.expression());
|
generate(state, ret.expression());
|
||||||
boxPrimitive(state, ret.expression().type());
|
convertTo(state, ret.expression().type(), state.returnType);
|
||||||
|
boxPrimitive(state, state.returnType);
|
||||||
mv.visitInsn(ARETURN);
|
mv.visitInsn(ARETURN);
|
||||||
} else mv.visitInsn(RETURN);
|
} else mv.visitInsn(RETURN);
|
||||||
break;
|
break;
|
||||||
@ -941,7 +949,7 @@ public class Codegen {
|
|||||||
mv.visitMethodInsn(call.isInterface() ? INVOKEINTERFACE : call.isStatic() ? INVOKESTATIC: call.name().equals("<init>") ? INVOKESPECIAL : INVOKEVIRTUAL,
|
mv.visitMethodInsn(call.isInterface() ? INVOKEINTERFACE : call.isStatic() ? INVOKESTATIC: call.name().equals("<init>") ? INVOKESPECIAL : INVOKEVIRTUAL,
|
||||||
call.owner().getInternalName(), call.name(), descriptor, call.isInterface());
|
call.owner().getInternalName(), call.name(), descriptor, call.isInterface());
|
||||||
|
|
||||||
if (call.returnType() != null && !(call.returnType() instanceof TargetPrimitiveType)) {
|
if (call.type() != null && call.returnType() != null && !(call.returnType() instanceof TargetPrimitiveType)) {
|
||||||
if (!call.returnType().equals(call.type()) && !(call.type() instanceof TargetGenericType))
|
if (!call.returnType().equals(call.type()) && !(call.type() instanceof TargetGenericType))
|
||||||
mv.visitTypeInsn(CHECKCAST, call.type().getInternalName());
|
mv.visitTypeInsn(CHECKCAST, call.type().getInternalName());
|
||||||
unboxPrimitive(state, call.type());
|
unboxPrimitive(state, call.type());
|
||||||
@ -967,13 +975,13 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateField(TargetField field) {
|
private void generateField(TargetField field) {
|
||||||
cw.visitField(field.access() | ACC_PUBLIC, field.name(), field.type().toSignature(), field.type().toGenericSignature(), null);
|
cw.visitField(field.access() | ACC_PUBLIC, field.name(), field.type().toSignature(), field.type().toDescriptor(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateConstructor(TargetConstructor constructor) {
|
private void generateConstructor(TargetConstructor constructor) {
|
||||||
MethodVisitor mv = cw.visitMethod(constructor.access() | ACC_PUBLIC, "<init>", constructor.getDescriptor(), constructor.getSignature(), null);
|
MethodVisitor mv = cw.visitMethod(constructor.access() | ACC_PUBLIC, "<init>", constructor.getDescriptor(), constructor.getSignature(), null);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
var state = new State(mv, 1);
|
var state = new State(null, mv, 1);
|
||||||
for (var param: constructor.parameters())
|
for (var param: constructor.parameters())
|
||||||
state.createVariable(param.name(), param.type());
|
state.createVariable(param.name(), param.type());
|
||||||
|
|
||||||
@ -997,7 +1005,7 @@ public class Codegen {
|
|||||||
// TODO The older codegen has set ACC_PUBLIC for all methods, good for testing but bad for everything else
|
// 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);
|
MethodVisitor mv = cw.visitMethod(method.access() | ACC_PUBLIC, method.name(), method.getDescriptor(), method.getSignature(), null);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
var state = new State(mv, method.isStatic() ? 0 : 1);
|
var state = new State(method.returnType(), mv, method.isStatic() ? 0 : 1);
|
||||||
for (var param: method.parameters())
|
for (var param: method.parameters())
|
||||||
state.createVariable(param.name(), param.type());
|
state.createVariable(param.name(), param.type());
|
||||||
generate(state, method.block());
|
generate(state, method.block());
|
||||||
@ -1010,16 +1018,16 @@ public class Codegen {
|
|||||||
private static String generateSignature(TargetClass clazz) {
|
private static String generateSignature(TargetClass clazz) {
|
||||||
String ret = "<";
|
String ret = "<";
|
||||||
for (var generic : clazz.generics()) {
|
for (var generic : clazz.generics()) {
|
||||||
ret += generic.name() + ":" + generic.bound().toGenericSignature();
|
ret += generic.name() + ":" + generic.bound().toDescriptor();
|
||||||
}
|
}
|
||||||
ret += ">";
|
ret += ">";
|
||||||
ret += clazz.superType().toGenericSignature();
|
ret += clazz.superType().toDescriptor();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] generate() {
|
public byte[] generate() {
|
||||||
cw.visit(V1_8, clazz.modifiers() | ACC_PUBLIC, clazz.qualifiedName(),
|
cw.visit(V1_8, clazz.modifiers() | ACC_PUBLIC | ACC_SUPER, clazz.qualifiedName(),
|
||||||
generateSignature(clazz), clazz.superType() != null ? clazz.superType().getInternalName(): "java/lang/Object",
|
generateSignature(clazz), clazz.superType() != null ? clazz.superType().getInternalName(): "java/lang/Object",
|
||||||
clazz.implementingInterfaces().stream().map(TargetType::toSignature).toArray(String[]::new)
|
clazz.implementingInterfaces().stream().map(TargetType::toSignature).toArray(String[]::new)
|
||||||
);
|
);
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
121
src/main/java/de/dhbwstuttgart/bytecode/FunNGenerator.java
Normal file
121
src/main/java/de/dhbwstuttgart/bytecode/FunNGenerator.java
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
package de.dhbwstuttgart.bytecode;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.target.tree.type.TargetGenericType;
|
||||||
|
import de.dhbwstuttgart.target.tree.type.TargetRefType;
|
||||||
|
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||||
|
import org.objectweb.asm.ClassWriter;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* //ToDo beschreiben
|
||||||
|
*
|
||||||
|
* @since Studienarbeit Type Erasure
|
||||||
|
* @author etiennezink
|
||||||
|
*/
|
||||||
|
public class FunNGenerator {
|
||||||
|
|
||||||
|
private static final String argumentGenericBase = "T";
|
||||||
|
private static final String returnGeneric = "R";
|
||||||
|
private static final String methodName = "apply";
|
||||||
|
private static final int bytecodeVersion = V1_8;
|
||||||
|
|
||||||
|
private static final String objectSuperType = Type.getInternalName(Object.class).replace('.','/');
|
||||||
|
private static final String objectSignature = applySignature(TargetType.Object);
|
||||||
|
|
||||||
|
private static String applyDescriptor(TargetType a) { return a.toDescriptor(); }
|
||||||
|
private static String applySignature(TargetType a) { return a.toSignature(); }
|
||||||
|
private static String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("L%s;", applySignature(a)); }
|
||||||
|
|
||||||
|
public static byte[] generateSuperBytecode(int numberArguments) {
|
||||||
|
StringBuilder superFunNClassSignature = new StringBuilder("<");
|
||||||
|
StringBuilder superFunNMethodSignature = new StringBuilder("(");
|
||||||
|
StringBuilder superFunNMethodDescriptor = new StringBuilder("(");
|
||||||
|
|
||||||
|
for (int currentParameter = 1; currentParameter <= numberArguments; currentParameter++){
|
||||||
|
superFunNClassSignature.append(String.format("%s%d:%s",argumentGenericBase, currentParameter, objectSignature));
|
||||||
|
superFunNMethodSignature.append(String.format("T%s;", applySignature(new TargetRefType(argumentGenericBase + currentParameter))));
|
||||||
|
superFunNMethodDescriptor.append(objectSignature);
|
||||||
|
}
|
||||||
|
superFunNClassSignature.append(String.format("%s:%s>%s", returnGeneric, objectSignature, objectSignature));
|
||||||
|
superFunNMethodSignature.append(String.format(")T%s;", applySignature(new TargetRefType(returnGeneric))));
|
||||||
|
superFunNMethodDescriptor.append(String.format(")%s", objectSignature));
|
||||||
|
|
||||||
|
ClassWriter classWriter = new ClassWriter(0);
|
||||||
|
MethodVisitor methodVisitor;
|
||||||
|
classWriter.visit(bytecodeVersion, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, getSuperClassName(numberArguments), superFunNClassSignature.toString(), objectSuperType, null);
|
||||||
|
methodVisitor = classWriter.visitMethod(ACC_PUBLIC | ACC_ABSTRACT, methodName, superFunNMethodDescriptor.toString(), superFunNMethodSignature.toString(), null);
|
||||||
|
methodVisitor.visitEnd();
|
||||||
|
classWriter.visitEnd();
|
||||||
|
return classWriter.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSuperClassName(int numberArguments) {
|
||||||
|
return String.format("Fun%d$$", numberArguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] generateSpecializedBytecode(List<TargetType> argumentTypes, TargetType returnType) {
|
||||||
|
List<TargetType> parameters = Stream
|
||||||
|
.concat(argumentTypes.stream(), Stream.of(returnType))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
StringBuilder funNClassSignature = new StringBuilder(objectSignature + applySignature(new TargetRefType(getSuperClassName(argumentTypes.size()), parameters)));
|
||||||
|
boolean containsGeneric = false;
|
||||||
|
|
||||||
|
String genericSignature = "<";
|
||||||
|
for (TargetType typeArgument : parameters) {
|
||||||
|
//ToDo Etienne: Refactor
|
||||||
|
if (typeArgument instanceof TargetGenericType generic){
|
||||||
|
//if(genericSignature.contains(generic.name())) continue;
|
||||||
|
genericSignature += String.format("%s:%s", generic.name(), applyDescriptor(generic));
|
||||||
|
containsGeneric = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
genericSignature += ">";
|
||||||
|
if (containsGeneric) funNClassSignature.insert(0, genericSignature);
|
||||||
|
System.out.println(funNClassSignature.toString());
|
||||||
|
|
||||||
|
ClassWriter classWriter = new ClassWriter(0);
|
||||||
|
classWriter.visit(bytecodeVersion, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, getSpecializedClassName(argumentTypes, returnType), funNClassSignature.toString(), objectSuperType, new String[]{getSuperClassName(argumentTypes.size())});
|
||||||
|
classWriter.visitEnd();
|
||||||
|
return classWriter.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSpecializedClassName(List<TargetType> argumentTypes, TargetType returnType) {
|
||||||
|
return String.format("Fun%d$$%s%s",
|
||||||
|
argumentTypes.size(),
|
||||||
|
argumentTypes
|
||||||
|
.stream()
|
||||||
|
.map(FunNGenerator::applyNameDescriptor)
|
||||||
|
.collect(Collectors.joining()),
|
||||||
|
applyNameDescriptor(returnType))
|
||||||
|
.replace('/', '$')
|
||||||
|
.replace(";", "$_$");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSpecializedDescriptor(List<TargetType> argumentTypes, TargetType returnType) {
|
||||||
|
return applyDescriptor(new TargetRefType(getSpecializedClassName(argumentTypes, returnType)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSpecializedSignature(List<TargetType> argumentTypes, TargetType returnType) {
|
||||||
|
return applySignature(new TargetRefType(getSpecializedClassName(argumentTypes, returnType)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<TargetType> getArguments(List<TargetType> list) {
|
||||||
|
return list
|
||||||
|
.stream()
|
||||||
|
.limit(Math.max(0, list.size() - 1))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TargetType getReturnType(List<TargetType> list) {
|
||||||
|
if(list.size() == 0)
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
return list.get(list.size() - 1);
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
|
||||||
|
|
||||||
import org.objectweb.asm.Label;
|
|
||||||
import org.objectweb.asm.MethodVisitor;
|
|
||||||
|
|
||||||
public interface IStatement {
|
|
||||||
public boolean isExprBinary();
|
|
||||||
public void genBCForRelOp(MethodVisitor mv, Label branchLabel, Label endLabel, BytecodeGenMethod bytecodeGenMethod);
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
|
||||||
|
|
||||||
import org.objectweb.asm.Label;
|
|
||||||
import org.objectweb.asm.MethodVisitor;
|
|
||||||
import org.objectweb.asm.Opcodes;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
|
||||||
|
|
||||||
public class IfStatement extends AStatement{
|
|
||||||
|
|
||||||
private Statement then_block;
|
|
||||||
private Statement else_block;
|
|
||||||
|
|
||||||
public IfStatement(Expression expr, Statement then_block, Statement else_block) {
|
|
||||||
super(expr);
|
|
||||||
this.then_block = then_block;
|
|
||||||
this.else_block = else_block;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void genBCForRelOp(MethodVisitor mv,Label branchLabel, Label endLabel, BytecodeGenMethod bytecodeGenMethod) {
|
|
||||||
bytecodeGenMethod.isBinary(false);
|
|
||||||
this.then_block.accept(bytecodeGenMethod);
|
|
||||||
|
|
||||||
mv.visitLabel(branchLabel);
|
|
||||||
this.else_block.accept(bytecodeGenMethod);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,24 @@
|
|||||||
|
package de.dhbwstuttgart.bytecode;
|
||||||
|
|
||||||
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
|
public class JavaTXSignatureAttribute extends Attribute {
|
||||||
|
final String signature;
|
||||||
|
|
||||||
|
protected JavaTXSignatureAttribute(String signature) {
|
||||||
|
super("JavaTXSignature");
|
||||||
|
this.signature = signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Attribute read(ClassReader classReader, int offset, int length, char[] charBuffer, int codeAttributeOffset, Label[] labels) {
|
||||||
|
return super.read(classReader, offset, length, charBuffer, codeAttributeOffset, labels);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ByteVector write(ClassWriter classWriter, byte[] code, int codeLength, int maxStack, int maxLocals) {
|
||||||
|
var data = new ByteVector();
|
||||||
|
data.putUTF8(this.signature);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
@ -1,26 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
|
||||||
|
|
||||||
import org.objectweb.asm.Label;
|
|
||||||
import org.objectweb.asm.MethodVisitor;
|
|
||||||
import org.objectweb.asm.Opcodes;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
|
||||||
|
|
||||||
public class LoopStmt extends AStatement {
|
|
||||||
|
|
||||||
private Statement loopBlock;
|
|
||||||
|
|
||||||
public LoopStmt(Expression expr, Statement loopBlock) {
|
|
||||||
super(expr);
|
|
||||||
this.loopBlock = loopBlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void genBCForRelOp(MethodVisitor mv,Label branchLabel, Label endLabel, BytecodeGenMethod bytecodeGenMethod) {
|
|
||||||
bytecodeGenMethod.isBinary(false);
|
|
||||||
this.loopBlock.accept(bytecodeGenMethod);
|
|
||||||
mv.visitJumpInsn(Opcodes.GOTO, endLabel);
|
|
||||||
mv.visitLabel(branchLabel);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
|
||||||
|
|
||||||
import org.objectweb.asm.MethodVisitor;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
|
||||||
|
|
||||||
public class ReturnStmt extends AStatement {
|
|
||||||
|
|
||||||
public ReturnStmt(Expression retexpr) {
|
|
||||||
super(retexpr);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,269 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
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 java.util.function.Function;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
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.constraints.Constraint;
|
|
||||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
|
||||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
|
||||||
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 {
|
|
||||||
// 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<>();
|
|
||||||
MethodAndTPH methodAndTph;
|
|
||||||
|
|
||||||
Boolean inMethod = false;
|
|
||||||
boolean inLocalOrParamOrReturn = false;
|
|
||||||
|
|
||||||
public final ArrayList<MethodAndTPH> ListOfMethodsAndTph = new ArrayList<>();
|
|
||||||
|
|
||||||
// Alle Constraints in einer Menge (Und- & Oder-Constraints)
|
|
||||||
public Set<Pair> oldConstraints = new HashSet<>();
|
|
||||||
|
|
||||||
final ArrayList<ResultPair<TypePlaceholder, TypePlaceholder>> allPairs = new ArrayList<>();
|
|
||||||
public final ArrayList<TPHConstraint> allCons = new ArrayList<>();
|
|
||||||
private ResultSet resultSet;
|
|
||||||
private Resolver resolver;
|
|
||||||
|
|
||||||
public TPHExtractor() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
TypePlaceholder resolvedTPH = (TypePlaceholder) resultSet.resolveType(tph).resolvedType;
|
|
||||||
String tphName = resolvedTPH.getName();
|
|
||||||
if (inMethod && !tphsClass.contains(tphName)) {
|
|
||||||
ArrayList<String> tphs = null;
|
|
||||||
if (!(tphs = methodAndTph.getTphs()).contains(tphName)) {
|
|
||||||
methodAndTph.addTph(tphName);
|
|
||||||
}
|
|
||||||
if (inLocalOrParamOrReturn) {
|
|
||||||
if (!(tphs = methodAndTph.getLocalTphs()).contains(tphName)) {
|
|
||||||
tphs.add(tphName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!tphsClass.contains(tphName)) {
|
|
||||||
tphsClass.add(tphName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!allTPHS.containsKey(tphName)) {
|
|
||||||
allTPHS.put(tphName, 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)
|
|
||||||
methodAndTph.getPairs().add(ag);
|
|
||||||
allPairs.add(ag);
|
|
||||||
TPHConstraint con = new ExtendsConstraint(ag.getLeft().getName(), ag.getRight().getName());
|
|
||||||
if(!containsConstraint(allCons,con))
|
|
||||||
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.addTph(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) {
|
|
||||||
GenericInsertPair p = pairs.get(i);
|
|
||||||
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);
|
|
||||||
Predicate<Pair> filterUndConstraints = cs -> ((cs.TA1 instanceof TypePlaceholder) && (cs.TA2 instanceof TypePlaceholder) &&
|
|
||||||
(resultSet.resolveType((TypePlaceholder)(cs.TA1)).resolvedType instanceof TypePlaceholder) &&
|
|
||||||
(resultSet.resolveType((TypePlaceholder)(cs.TA2)).resolvedType instanceof TypePlaceholder));
|
|
||||||
|
|
||||||
Function<ConstraintSet<Pair>, ConstraintSet<Pair>> filterConstrRemainingTVar =
|
|
||||||
csS -> {
|
|
||||||
ConstraintSet<Pair> ret = new ConstraintSet<>();
|
|
||||||
ret.addAllUndConstraint(
|
|
||||||
csS.getUndConstraints()
|
|
||||||
.stream().filter(filterUndConstraints)
|
|
||||||
.collect(Collectors.toCollection(Constraint<Pair>::new)));
|
|
||||||
|
|
||||||
csS.getOderConstraints()
|
|
||||||
.forEach(oConSSet -> { Set<Constraint<Pair>> setCons = new HashSet<>();
|
|
||||||
oConSSet.forEach(OConS -> { Constraint<Pair> newConsPair = new Constraint<Pair>();
|
|
||||||
newConsPair.isStatement = OConS.isStatement;
|
|
||||||
setCons.add(
|
|
||||||
OConS.stream()
|
|
||||||
.filter(filterUndConstraints)
|
|
||||||
.collect(Collectors.toCollection(() -> newConsPair)) );
|
|
||||||
} );
|
|
||||||
ret.addOderConstraint(setCons);} );
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
ConstraintSet<Pair> filteredConstraints = filterConstrRemainingTVar.apply(method.getConstraints());
|
|
||||||
methodAndTph = new MethodAndTPH(id, filteredConstraints);
|
|
||||||
oldConstraints.addAll(filteredConstraints.getAll());
|
|
||||||
|
|
||||||
inLocalOrParamOrReturn = true;
|
|
||||||
method.getReturnType().accept(this);
|
|
||||||
method.getParameterList().accept(this);
|
|
||||||
inLocalOrParamOrReturn = false;
|
|
||||||
|
|
||||||
if(method.block != null)
|
|
||||||
method.block.accept(this);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,260 +0,0 @@
|
|||||||
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.syntaxtree.FormalParameter;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
|
||||||
|
|
||||||
public class DescriptorToString implements DescriptorVisitor, CONSTANTS {
|
|
||||||
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)){
|
|
||||||
desc = desc + ")V";
|
|
||||||
}else {
|
|
||||||
desc = desc + ")" + "L"+resultSet.resolveType(returnType).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
|
||||||
}
|
|
||||||
return desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(NormalMethod method) {
|
|
||||||
|
|
||||||
String desc = "(";
|
|
||||||
Iterator<FormalParameter> itr = method.getParameterList().iterator();
|
|
||||||
while(itr.hasNext()) {
|
|
||||||
FormalParameter fp = itr.next();
|
|
||||||
// System.out.println(resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature()));
|
|
||||||
// System.out.println("Parmetrisierte typ ? "+ ((RefType) fp.getType()).getParaList().size());
|
|
||||||
if(method.hasGen()) {
|
|
||||||
String fpDesc = fp.getType().acceptTV(new TypeToDescriptor());
|
|
||||||
if(method.getGenericsAndBoundsMethod().containsKey(fpDesc)) {
|
|
||||||
String bound = getBound(fpDesc, method.getGenericsAndBoundsMethod());
|
|
||||||
desc += "L"+bound+ ";";
|
|
||||||
}else if(method.getGenericsAndBounds().containsKey(fpDesc)){
|
|
||||||
String bound = getBound(fpDesc, method.getGenericsAndBounds());
|
|
||||||
desc += "L"+bound+ ";";
|
|
||||||
}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 ")*/) {
|
|
||||||
// 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 {
|
|
||||||
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(resultSet.resolveType(method.getReturnType()).resolvedType.toString().equals(CONSTANTS.VOID)) {
|
|
||||||
desc += ")V";
|
|
||||||
}else {
|
|
||||||
if(method.hasGen()) {
|
|
||||||
String ret = method.getReturnType().acceptTV(new TypeToDescriptor());
|
|
||||||
if(method.getGenericsAndBoundsMethod().containsKey(ret)) {
|
|
||||||
desc += ")L"+method.getGenericsAndBoundsMethod().get(ret)+ ";";
|
|
||||||
}else if(method.getGenericsAndBounds().containsKey(ret)){
|
|
||||||
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 ")*/) {
|
|
||||||
// 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+ ";";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
desc += ")" + "L"+resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// desc = addReturnType(desc,method.getReturnType(), resultSet);
|
|
||||||
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 = "(";
|
|
||||||
Iterator<FormalParameter> itr = constructor.getParameterList().iterator();
|
|
||||||
while(itr.hasNext()) {
|
|
||||||
FormalParameter fp = itr.next();
|
|
||||||
if(constructor.hasGen()) {
|
|
||||||
// System.out.println("Cons has Gens");
|
|
||||||
String fpDesc = fp.getType().acceptTV(new TypeToDescriptor());
|
|
||||||
// System.out.println(fpDesc);
|
|
||||||
if(constructor.getGenericsAndBounds().containsKey(fpDesc)){
|
|
||||||
desc += "L"+constructor.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.subSequence(0, 4).equals(CONSTANTS.TPH)) {
|
|
||||||
// Bound ist immer Object
|
|
||||||
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
|
||||||
} else {
|
|
||||||
desc += "L"+resType+ ";";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
// System.out.println("Cons has NO Gens");
|
|
||||||
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
desc = desc + ")V";
|
|
||||||
return desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
//ToDo Etienne: ändern
|
|
||||||
@Override
|
|
||||||
public String visit(Lambda lambdaExpression) {
|
|
||||||
String desc = "(";
|
|
||||||
Iterator<FormalParameter> itr = lambdaExpression.getParams().iterator();
|
|
||||||
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)) {
|
|
||||||
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
|
||||||
}else {
|
|
||||||
desc = desc + "L"+ d + ";";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String retType = resultSet.resolveType(lambdaExpression.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
|
||||||
|
|
||||||
if(retType.contains(CONSTANTS.TPH)|| retType.contains(CONSTANTS.ANGLEBRACKET)){
|
|
||||||
desc += ")L"+Type.getInternalName(Object.class)+ ";";
|
|
||||||
}else {
|
|
||||||
desc = desc + ")"+"L"+retType+";";
|
|
||||||
}
|
|
||||||
return desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(SamMethod samMethod) {
|
|
||||||
String desc = "(";
|
|
||||||
Iterator<RefTypeOrTPHOrWildcardOrGeneric> itr = samMethod.getArgumentList().iterator();
|
|
||||||
while(itr.hasNext()) {
|
|
||||||
RefTypeOrTPHOrWildcardOrGeneric rt = itr.next();
|
|
||||||
String d = resultSet.resolveType(rt).resolvedType.acceptTV(new TypeToDescriptor());
|
|
||||||
|
|
||||||
if(d.contains(CONSTANTS.TPH) ||d.contains(CONSTANTS.ANGLEBRACKET)) {
|
|
||||||
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
|
||||||
}else {
|
|
||||||
desc += "L"+ d + ";";
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String retType = resultSet.resolveType(samMethod.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
|
||||||
|
|
||||||
if(retType.contains(CONSTANTS.TPH)|| retType.contains(CONSTANTS.ANGLEBRACKET)){
|
|
||||||
desc += ")L"+Type.getInternalName(Object.class)+ ";";
|
|
||||||
}else {
|
|
||||||
desc = desc + ")"+"L"+retType+";";
|
|
||||||
}
|
|
||||||
return desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(MethodFromMethodCall methodFromMethodCall) {
|
|
||||||
String desc = "(";
|
|
||||||
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("$$")) {
|
|
||||||
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
|
||||||
}else {
|
|
||||||
if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(d)) {
|
|
||||||
desc += "L"+methodFromMethodCall.getGenericsAndBoundsMethod().get(d)+ ";";
|
|
||||||
}else if(methodFromMethodCall.getGenericsAndBounds().containsKey(d)) {
|
|
||||||
desc += "L"+methodFromMethodCall.getGenericsAndBounds().get(d)+ ";";
|
|
||||||
}else {
|
|
||||||
desc += "L"+resultSet.resolveType(e.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
String retType = resultSet.resolveType(methodFromMethodCall.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
|
||||||
System.out.println("DescriptorToString retType = " + retType);
|
|
||||||
if(retType.equals(CONSTANTS.VOID)) {
|
|
||||||
desc += ")V";
|
|
||||||
}else if(retType.contains(CONSTANTS.TPH)|| retType.contains(CONSTANTS.ANGLEBRACKET) || methodFromMethodCall.getReceiverName().contains("$$")){
|
|
||||||
desc += ")L"+Type.getInternalName(Object.class)+ ";";
|
|
||||||
}else {
|
|
||||||
if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(retType)) {
|
|
||||||
desc += ")L"+methodFromMethodCall.getGenericsAndBoundsMethod().get(retType)+ ";";
|
|
||||||
}else if(methodFromMethodCall.getGenericsAndBounds().containsKey(retType)){
|
|
||||||
desc += ")L"+methodFromMethodCall.getGenericsAndBounds().get(retType)+ ";";
|
|
||||||
}else {
|
|
||||||
desc += ")" + "L"+retType+ ";";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// desc = addReturnType(desc, methodFromMethodCall.getReturnType(), resultSet);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode.descriptor;
|
|
||||||
|
|
||||||
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.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);
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode.descriptor;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.funN.FunNGenerator;
|
|
||||||
import de.dhbwstuttgart.bytecode.funN.FunNUtilities;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
|
||||||
|
|
||||||
public class TypeToDescriptor implements TypeVisitor<String>{
|
|
||||||
|
|
||||||
private final boolean specializedFunN;
|
|
||||||
|
|
||||||
public TypeToDescriptor(){ this(true); }
|
|
||||||
|
|
||||||
public TypeToDescriptor(boolean specializedFunN) { this.specializedFunN = specializedFunN; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(RefType refType) {
|
|
||||||
if (refType.getName().toString().matches("Fun\\d+\\$\\$") && specializedFunN) {
|
|
||||||
FunNUtilities funNUtilities = FunNGenerator.getInstance();
|
|
||||||
return funNUtilities.getSpecializedDescriptor(funNUtilities.getArguments(refType.getParaList()), funNUtilities.getReturnType(refType.getParaList()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return refType.getName().toString().replace(".", "/");
|
|
||||||
// String t = refType.getName().toString().replace(".", "/");
|
|
||||||
// return t.equals("Fun1")?(t+"$$"):t;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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());
|
|
||||||
//throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(TypePlaceholder typePlaceholder) {
|
|
||||||
return typePlaceholder.toString().replace(".", "/");
|
|
||||||
}
|
|
||||||
|
|
||||||
@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());
|
|
||||||
//throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(GenericRefType genericRefType) {
|
|
||||||
return genericRefType.getParsedName().replace(".", "/");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,149 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode.funN;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
|
||||||
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
|
|
||||||
import de.dhbwstuttgart.bytecode.utilities.CONSTANTS;
|
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
|
||||||
import org.objectweb.asm.ClassWriter;
|
|
||||||
import org.objectweb.asm.MethodVisitor;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import static org.objectweb.asm.Opcodes.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* //ToDo beschreiben
|
|
||||||
*
|
|
||||||
* @since Studienarbeit Type Erasure
|
|
||||||
* @author etiennezink
|
|
||||||
*/
|
|
||||||
public class FunNGenerator implements FunNUtilities{
|
|
||||||
|
|
||||||
private static FunNGenerator funNGenerator = new FunNGenerator();
|
|
||||||
|
|
||||||
public static FunNGenerator getInstance(){
|
|
||||||
return funNGenerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final String argumentGenericBase = "T";
|
|
||||||
private final String returnGeneric = "R";
|
|
||||||
private final String methodName = "apply";
|
|
||||||
private final int bytecodeVersion = V1_8;
|
|
||||||
|
|
||||||
private final String objectSuperType = Type.getInternalName(Object.class).replace('.','/');
|
|
||||||
private final RefType objectRefType = new RefType(new JavaClassName(objectSuperType), null);
|
|
||||||
private final String objectSignature = applySignature(objectRefType);
|
|
||||||
|
|
||||||
private String applyDescriptor(RefTypeOrTPHOrWildcardOrGeneric a) { return a.acceptTV(new TypeToDescriptor(true)); }
|
|
||||||
private String applySignature(RefTypeOrTPHOrWildcardOrGeneric a) { return a.acceptTV(new TypeToSignature(true)); }
|
|
||||||
private String applyNameDescriptor(RefTypeOrTPHOrWildcardOrGeneric a){ return a instanceof TypePlaceholder ? "LTPH;" : String.format("L%s;", applyDescriptor(a)); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] generateSuperBytecode(int numberArguments) {
|
|
||||||
StringBuilder superFunNClassSignature = new StringBuilder("<");
|
|
||||||
StringBuilder superFunNMethodSignature = new StringBuilder("(");
|
|
||||||
StringBuilder superFunNMethodDescriptor = new StringBuilder("(");
|
|
||||||
|
|
||||||
for (int currentParameter = 1; currentParameter <= numberArguments; currentParameter++){
|
|
||||||
superFunNClassSignature.append(String.format("%s%d:%s",argumentGenericBase, currentParameter, objectSignature));
|
|
||||||
superFunNMethodSignature.append(String.format("T%s;", applySignature( new GenericRefType(argumentGenericBase + currentParameter, null))));
|
|
||||||
superFunNMethodDescriptor.append(objectSignature);
|
|
||||||
}
|
|
||||||
superFunNClassSignature.append(String.format("%s:%s>%s", returnGeneric, objectSignature, objectSignature));
|
|
||||||
superFunNMethodSignature.append(String.format(")T%s;", applySignature(new GenericRefType(returnGeneric, null))));
|
|
||||||
superFunNMethodDescriptor.append(String.format(")%s", objectSignature));
|
|
||||||
|
|
||||||
ClassWriter classWriter = new ClassWriter(0);
|
|
||||||
MethodVisitor methodVisitor;
|
|
||||||
classWriter.visit(bytecodeVersion, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, getSuperClassName(numberArguments), superFunNClassSignature.toString(), objectSuperType, null);
|
|
||||||
methodVisitor = classWriter.visitMethod(ACC_PUBLIC | ACC_ABSTRACT, methodName, superFunNMethodDescriptor.toString(), superFunNMethodSignature.toString(), null);
|
|
||||||
methodVisitor.visitEnd();
|
|
||||||
classWriter.visitEnd();
|
|
||||||
return classWriter.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getSuperClassName(int numberArguments) {
|
|
||||||
return String.format("Fun%d$$", numberArguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] generateSpecializedBytecode(List<RefTypeOrTPHOrWildcardOrGeneric> argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType) {
|
|
||||||
List<RefTypeOrTPHOrWildcardOrGeneric> parameters = Stream
|
|
||||||
.concat(argumentTypes.stream(), Stream.of(returnType))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
RefType superFunN = new RefType(new JavaClassName(getSuperClassName(argumentTypes.size())), parameters , null);
|
|
||||||
StringBuilder funNClassSignature = new StringBuilder(objectSignature + (superFunN.acceptTV(new TypeToSignature(false))));
|
|
||||||
boolean containsGeneric = false;
|
|
||||||
|
|
||||||
String genericSignature = "<";
|
|
||||||
for (RefTypeOrTPHOrWildcardOrGeneric typeArgument : parameters) {
|
|
||||||
//ToDo Etienne: Refactor
|
|
||||||
if (typeArgument instanceof GenericRefType){
|
|
||||||
GenericRefType generic = (GenericRefType) typeArgument;
|
|
||||||
if(genericSignature.contains(generic.getParsedName())) continue;
|
|
||||||
genericSignature += String.format("%s:%s", generic.getParsedName(), applyDescriptor(generic));
|
|
||||||
containsGeneric = true;
|
|
||||||
} else if(typeArgument instanceof TypePlaceholder){
|
|
||||||
TypePlaceholder placeholder = (TypePlaceholder) typeArgument;
|
|
||||||
if(genericSignature.contains(applySignature(placeholder).substring(1))) continue;
|
|
||||||
genericSignature += String.format("%s:%s", applySignature(placeholder).substring(1), objectSignature);
|
|
||||||
containsGeneric = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
genericSignature += ">";
|
|
||||||
if (containsGeneric) funNClassSignature.insert(0, genericSignature);
|
|
||||||
|
|
||||||
ClassWriter classWriter = new ClassWriter(0);
|
|
||||||
classWriter.visit(bytecodeVersion, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, getSpecializedClassName(argumentTypes, returnType), funNClassSignature.toString(), objectSuperType, new String[]{getSuperClassName(argumentTypes.size())});
|
|
||||||
classWriter.visitEnd();
|
|
||||||
return classWriter.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getSpecializedClassName(List<RefTypeOrTPHOrWildcardOrGeneric> argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType) {
|
|
||||||
return String.format("Fun%d$$%s%s",
|
|
||||||
argumentTypes.size(),
|
|
||||||
argumentTypes
|
|
||||||
.stream()
|
|
||||||
.map(this::applyNameDescriptor)
|
|
||||||
.collect(Collectors.joining()),
|
|
||||||
applyNameDescriptor(returnType))
|
|
||||||
.replace('/', '$')
|
|
||||||
.replace(";", "$_$");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getSpecializedDescriptor(List<RefTypeOrTPHOrWildcardOrGeneric> argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType) {
|
|
||||||
return applyDescriptor(new RefType(new JavaClassName(getSpecializedClassName(argumentTypes, returnType)), null));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getSpecializedSignature(List<RefTypeOrTPHOrWildcardOrGeneric> argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType) {
|
|
||||||
return applySignature(new RefType(new JavaClassName(getSpecializedClassName(argumentTypes, returnType)), null));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<RefTypeOrTPHOrWildcardOrGeneric> getArguments(List<RefTypeOrTPHOrWildcardOrGeneric> list) {
|
|
||||||
return list
|
|
||||||
.stream()
|
|
||||||
.limit(Math.max(0, list.size() - 1))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RefTypeOrTPHOrWildcardOrGeneric getReturnType(List<RefTypeOrTPHOrWildcardOrGeneric> list) {
|
|
||||||
if(list.size() == 0)
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
return list.get(list.size() - 1);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode.funN;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.utilities.CONSTANTS;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface FunNUtilities {
|
|
||||||
|
|
||||||
byte[] generateSuperBytecode(int numberArguments);
|
|
||||||
String getSuperClassName(int numberArguments);
|
|
||||||
|
|
||||||
byte[] generateSpecializedBytecode(List<RefTypeOrTPHOrWildcardOrGeneric> argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType);
|
|
||||||
String getSpecializedClassName(List<RefTypeOrTPHOrWildcardOrGeneric> argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType);
|
|
||||||
String getSpecializedDescriptor(List<RefTypeOrTPHOrWildcardOrGeneric> argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType);
|
|
||||||
String getSpecializedSignature(List<RefTypeOrTPHOrWildcardOrGeneric> argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType);
|
|
||||||
|
|
||||||
List<RefTypeOrTPHOrWildcardOrGeneric> getArguments(List<RefTypeOrTPHOrWildcardOrGeneric> list);
|
|
||||||
RefTypeOrTPHOrWildcardOrGeneric getReturnType(List<RefTypeOrTPHOrWildcardOrGeneric> list);
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static boolean writeClassFile(String className, byte[] bytecode, File directory) {
|
|
||||||
try (FileOutputStream output = new FileOutputStream(new File(directory , className + CONSTANTS.EXTENSIONCLASS))){
|
|
||||||
output.write(bytecode);
|
|
||||||
output.flush();
|
|
||||||
return true;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -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,732 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
package de.dhbwstuttgart.bytecode.genericsGenerator;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.TPHExtractor;
|
|
||||||
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
|
||||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
|
||||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.*;
|
|
||||||
import de.dhbwstuttgart.bytecode.insertGenerics.ClassConstraint;
|
|
||||||
import de.dhbwstuttgart.bytecode.insertGenerics.FamilyOfGeneratedGenerics;
|
|
||||||
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;//Ergebnis des GGenerics
|
|
||||||
private ResultSet resultSet;
|
|
||||||
private final List<String> methodNameAndParamsT = new ArrayList<>();
|
|
||||||
private FamilyOfGeneratedGenerics fogg;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the family of Generated Generics
|
|
||||||
* insbesondere fuer Testzwecke
|
|
||||||
*/
|
|
||||||
public FamilyOfGeneratedGenerics getFogg() {
|
|
||||||
return fogg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (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;
|
|
||||||
GenericsGeneratorResultForClass ggResultAlternative = null;
|
|
||||||
|
|
||||||
for (int i = 0; i < listOfResultSetsList.size(); i++) {
|
|
||||||
resultSet = listOfResultSetsList.get(i);
|
|
||||||
tphExtractor.setResultSet(resultSet);
|
|
||||||
resolver = new Resolver(resultSet);
|
|
||||||
classOrInterface.accept(tphExtractor);
|
|
||||||
//PL 2020-10-16: Ab hier GGenerics implementieren durch Ali
|
|
||||||
//Rueckgabe an generatedGenericsForSF
|
|
||||||
fogg = new FamilyOfGeneratedGenerics(tphExtractor, resultSet);
|
|
||||||
|
|
||||||
System.out.println("fogg.allConstraints: "+ fogg.allConstraints);
|
|
||||||
System.out.println("fogg.posOfTPHs: "+ fogg.posOfTPHs);
|
|
||||||
System.out.println("fogg.classConstraints: "+ fogg.classConstraints);
|
|
||||||
System.out.println("fogg.methodConstraintsWithPosition: "+ fogg.methodConstraintsWithPosition);
|
|
||||||
System.out.println(fogg);
|
|
||||||
|
|
||||||
///*
|
|
||||||
//Fayez Ansatz Anfang
|
|
||||||
tphsClass = tphExtractor.tphsClass;
|
|
||||||
//PL 2020-01-15
|
|
||||||
//Es muss ggResult aus fogg gebildet werden
|
|
||||||
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) { //Hinzufuegen von Fayez ggResult
|
|
||||||
generatedGenericsForSF.addGenericGeneratorResultClass(ggResult);
|
|
||||||
}
|
|
||||||
// Fayez Ansatz Ende
|
|
||||||
//*/
|
|
||||||
|
|
||||||
//Ali Ansatz Anfang
|
|
||||||
List<GenericsGeneratorResult> listOfClassCons = new ArrayList<>();
|
|
||||||
for(TPHConstraint clCons: fogg.classConstraints) {
|
|
||||||
// ExtendsConstraint ec = new ExtendsConstraint(clCons.getLeft(), clCons.getRight());
|
|
||||||
GenericsGeneratorResult ggR = new GenericsGeneratorResult(clCons, new HashSet<>());
|
|
||||||
listOfClassCons.add(ggR);
|
|
||||||
}
|
|
||||||
|
|
||||||
GenericGeneratorResultsForAllMethods ggRfaM = null;
|
|
||||||
List<MethodAndConstraints> listOfMethAndCons = new ArrayList<>();
|
|
||||||
for(String methID: fogg.methodConstraintsWithPosition.keySet()) {
|
|
||||||
List<GenericsGeneratorResult> listOfGGR = new ArrayList<>();
|
|
||||||
for(TPHConstraint methCons: fogg.methodConstraintsWithPosition.get(methID)) {
|
|
||||||
// ExtendsConstraint ec = new ExtendsConstraint(methCons.getLeft(),methCons.getRight());
|
|
||||||
GenericsGeneratorResult ggR = new GenericsGeneratorResult(methCons, new HashSet<>());
|
|
||||||
listOfGGR.add(ggR);
|
|
||||||
}
|
|
||||||
MethodAndConstraints mac = new MethodAndConstraints(methID, listOfGGR);
|
|
||||||
listOfMethAndCons.add(mac);
|
|
||||||
}
|
|
||||||
ggRfaM = new GenericGeneratorResultsForAllMethods(listOfMethAndCons);
|
|
||||||
ggResultAlternative = new GenericsGeneratorResultForClass(className, listOfClassCons, ggRfaM);
|
|
||||||
|
|
||||||
if(ggResultAlternative != null) {//hinzufuegen von Alis ggResult
|
|
||||||
//generatedGenericsForSF.addGenericGeneratorResultClass(ggResultAlternative);
|
|
||||||
System.out.println(generatedGenericsForSF);
|
|
||||||
}
|
|
||||||
System.out.println(ggResultAlternative);
|
|
||||||
//Ali Ansatz Ende
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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,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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -24,7 +24,8 @@ public class MethodAndConstraints {
|
|||||||
* @return the methodID
|
* @return the methodID
|
||||||
*/
|
*/
|
||||||
public String getMethodID() {
|
public String getMethodID() {
|
||||||
return methodID;
|
// FIXME
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @return the constraints
|
* @return the constraints
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode.insertGenerics;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
|
||||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
|
||||||
|
|
||||||
public class ClassConstraint extends TPHConstraint {
|
|
||||||
//private TPHConstraint constraint;
|
|
||||||
|
|
||||||
public ClassConstraint(String left, String right, Relation rel) {
|
|
||||||
super(left, right, rel);
|
|
||||||
}
|
|
||||||
//besser?
|
|
||||||
/*public ClassConstraint(TPHConstraint constraint) {
|
|
||||||
this.constraint = constraint;
|
|
||||||
}*/
|
|
||||||
}
|
|
@ -1,880 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode.insertGenerics;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.TPHExtractor;
|
|
||||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
|
||||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
|
||||||
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
|
||||||
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
|
||||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultPair;
|
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
|
|
||||||
public class FamilyOfGeneratedGenerics {
|
|
||||||
public List<TPHConstraint> allConstraints = new ArrayList<>();
|
|
||||||
// HashMap speichert ob TPH in einer Methode oder in der Klasse ist; und wenn es in der Methode ist, in welcher Methode
|
|
||||||
public HashMap<String, List<PairTphMethod<PositionFinder.Position, String>>> posOfTPHs = new HashMap<>();
|
|
||||||
public List<ClassConstraint> classConstraints = new ArrayList<>();
|
|
||||||
private HashMap<String, MethodAndTPH> mapMethodsAndTph = new HashMap<>();
|
|
||||||
public List<MethodConstraint> methodConstraints = new ArrayList<>();
|
|
||||||
public HashMap<String, List<MethodConstraint>> methodConstraintsWithPosition = new HashMap<>();
|
|
||||||
public ResultSet resSet;
|
|
||||||
public Set<Pair> oldCons = new HashSet<>();
|
|
||||||
|
|
||||||
private static final String objectType = Type.getInternalName(Object.class);
|
|
||||||
|
|
||||||
public FamilyOfGeneratedGenerics(TPHExtractor tphExtractor, ResultSet resultSet) {
|
|
||||||
this.resSet = resultSet;
|
|
||||||
this.oldCons = tphExtractor.oldConstraints;
|
|
||||||
this.allConstraints = tphExtractor.allCons;
|
|
||||||
this.posOfTPHs = positionConverter(tphExtractor.allTPHS, tphExtractor.ListOfMethodsAndTph);
|
|
||||||
this.classConstraints = getClassConstraints(allConstraints,posOfTPHs);
|
|
||||||
tphExtractor.ListOfMethodsAndTph.forEach(matph -> this.mapMethodsAndTph.put(matph.getId(), matph));
|
|
||||||
this.methodConstraints = getMethodConstraints(allConstraints,classConstraints,posOfTPHs, tphExtractor.ListOfMethodsAndTph);
|
|
||||||
this.methodConstraintsWithPosition = getMethodConstraintsWithPositionNew(allConstraints,classConstraints,posOfTPHs, tphExtractor.ListOfMethodsAndTph, resSet, oldCons);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<ClassConstraint> getClassConstraints(List<TPHConstraint> cs, HashMap<String, List<PairTphMethod<PositionFinder.Position, String>>> posOfTphs) { //Inputparameter List<TPHConstraint> constraintsSet weg
|
|
||||||
List<ClassConstraint> cs_cl = new ArrayList<>();
|
|
||||||
List<ClassConstraint> classConstraints1 = typeOfANodeOfAField(cs, posOfTphs);
|
|
||||||
for (ClassConstraint cons: classConstraints1) {
|
|
||||||
if (!checkForDuplicates(cons, cs_cl)) {
|
|
||||||
cs_cl.add(cons);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if sth new is added to cs_cl, then do same step again
|
|
||||||
boolean addedToConstraintsListForCC2 = false;
|
|
||||||
do {
|
|
||||||
addedToConstraintsListForCC2 = false;
|
|
||||||
List<ClassConstraint> classConstraints2 = transitiveSubtypeForClassTypes(cs, cs_cl); // in Klammer classConstraints1 oder constraintsSet? beides eher
|
|
||||||
for (ClassConstraint cons: classConstraints2) {
|
|
||||||
if (!checkForDuplicates(cons, cs_cl)) {
|
|
||||||
cs_cl.add(cons);
|
|
||||||
addedToConstraintsListForCC2 = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (addedToConstraintsListForCC2);
|
|
||||||
|
|
||||||
List<ClassConstraint> classConstraints3 = hasNoSupertypeForClassTypes(cs_cl, posOfTphs);
|
|
||||||
for (ClassConstraint cons: classConstraints3) {
|
|
||||||
if (!checkForDuplicates(cons, cs_cl)) {
|
|
||||||
cs_cl.add(cons);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cs_cl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<MethodConstraint> getMethodConstraints(List<TPHConstraint> cs, List<ClassConstraint> cs_cl, HashMap<String, List<PairTphMethod<PositionFinder.Position, String>>> posOfTphs, List<MethodAndTPH> listOfMethodsAndTph) {
|
|
||||||
List<MethodConstraint> cs_m = new ArrayList<>();
|
|
||||||
List<MethodConstraint> methodConstraints1 = typeOfTheMethodInClSigma(cs, posOfTphs);
|
|
||||||
for (MethodConstraint cons: methodConstraints1) {
|
|
||||||
if (!checkForDuplicates(cons, cs_m)) {
|
|
||||||
cs_m.add(cons);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if sth new is added to cs_cl, then do same step again
|
|
||||||
boolean addedToConstraintsListForMC2 = false;
|
|
||||||
do {
|
|
||||||
addedToConstraintsListForMC2 = false;
|
|
||||||
List<MethodConstraint> methodConstraints2 = firstTransitiveSubtypeForMethodTypes(cs, cs_m);
|
|
||||||
for (MethodConstraint cons : methodConstraints2) {
|
|
||||||
if (!checkForDuplicates(cons, cs_m)) {
|
|
||||||
cs_m.add(cons);
|
|
||||||
addedToConstraintsListForMC2 = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (addedToConstraintsListForMC2);
|
|
||||||
|
|
||||||
// if sth new is added to cs_cl, then do same step again
|
|
||||||
boolean addedToConstraintsListForMC3 = false;
|
|
||||||
do {
|
|
||||||
addedToConstraintsListForMC3 = false;
|
|
||||||
List<MethodConstraint> methodConstraints3 = secondTransitiveSubtypeForMethodTypes(cs, cs_cl, cs_m);
|
|
||||||
for (MethodConstraint cons : methodConstraints3) {
|
|
||||||
if (!checkForDuplicates(cons, cs_m)) {
|
|
||||||
cs_m.add(cons);
|
|
||||||
addedToConstraintsListForMC3 = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (addedToConstraintsListForMC3);
|
|
||||||
List<MethodConstraint> methodConstraints4 = hasNoSupertypeForMethodTypes(cs, cs_m, posOfTphs, listOfMethodsAndTph);
|
|
||||||
for (MethodConstraint cons: methodConstraints4) {
|
|
||||||
if (!checkForDuplicates(cons, cs_m)) {
|
|
||||||
cs_m.add(cons);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List<MethodConstraint> methodConstraints5 = methodTypesWithoutClassTypes(cs_cl, cs_m);
|
|
||||||
cs_m = methodConstraints5;
|
|
||||||
return cs_m;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashMap<String, List<MethodConstraint>> getMethodConstraintsWithPosition(List<TPHConstraint> cs, List<ClassConstraint> cs_cl, HashMap<String, List<PairTphMethod<PositionFinder.Position, String>>> posOfTphs, List<MethodAndTPH> listOfMethodsAndTph, ResultSet resSet, Set<Pair> oldCons) {
|
|
||||||
HashMap<String, List<MethodConstraint>> tempMethodConstraintsWithPosition = new HashMap<>();
|
|
||||||
for(MethodAndTPH method: listOfMethodsAndTph){
|
|
||||||
List<String> methodsAddedToHashMap = new ArrayList<>();
|
|
||||||
String currentMethod = method.getId();
|
|
||||||
boolean containsCurrentMethod = false;
|
|
||||||
if(!containsCurrentMethod) {
|
|
||||||
methodsAddedToHashMap.add(currentMethod);
|
|
||||||
containsCurrentMethod = true;
|
|
||||||
List<MethodConstraint> listOfThisMethod = new ArrayList<>();
|
|
||||||
HashMap<String, List<PairTphMethod<PositionFinder.Position, String>>> posOfTPHsForThisMethod = new HashMap<>();
|
|
||||||
for(String s: posOfTphs.keySet()) {
|
|
||||||
for(PairTphMethod pair: posOfTphs.get(s)) {
|
|
||||||
if(pair.snd == currentMethod && pair.snd != null) {
|
|
||||||
posOfTPHsForThisMethod.put(s,posOfTphs.get(s));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
listOfThisMethod = getMethodConstraints(cs,cs_cl,posOfTPHsForThisMethod,listOfMethodsAndTph);
|
|
||||||
tempMethodConstraintsWithPosition.put(currentMethod, listOfThisMethod);
|
|
||||||
|
|
||||||
List<MethodConstraint> newMCList = firstLineMethodDefinition(cs, posOfTphs, method, resSet);
|
|
||||||
List<MethodConstraint> newMCList2 = secondLineMethodDefinition(cs, posOfTphs, method, resSet, oldCons);
|
|
||||||
System.out.println(newMCList);
|
|
||||||
System.out.println(newMCList2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(String curMeth: tempMethodConstraintsWithPosition.keySet()){
|
|
||||||
for(int i=0; i<tempMethodConstraintsWithPosition.get(curMeth).size(); i++) {
|
|
||||||
MethodConstraint currentMC = tempMethodConstraintsWithPosition.get(curMeth).get(i);
|
|
||||||
if(currentMC.getRight()!= objectType && !compareTphsOfConstraints(currentMC.getRight(), cs_cl) && !compareTphsOfConstraints(currentMC.getRight(), tempMethodConstraintsWithPosition.get(curMeth))) {
|
|
||||||
MethodConstraint mc = new MethodConstraint(currentMC.getRight(), objectType, Relation.EXTENDS);
|
|
||||||
tempMethodConstraintsWithPosition.get(curMeth).add(mc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tempMethodConstraintsWithPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hilfsmethode um TPHs in den Methoden zu finden, die <. Object sein müssen
|
|
||||||
private static boolean compareTphsOfConstraints(String tph, List list) {
|
|
||||||
List<TPHConstraint> tempList = new ArrayList<>(list);
|
|
||||||
for(TPHConstraint tphC: tempList) {
|
|
||||||
if(tph == tphC.getLeft()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Def. FGG: erste Zeile von cs_cl
|
|
||||||
* {T < .T' | T is a type variable in a type of a node of a field}
|
|
||||||
*/
|
|
||||||
public static List<ClassConstraint> typeOfANodeOfAField(List<TPHConstraint> allConstraints, HashMap<String, List<PairTphMethod<PositionFinder.Position, String>>> posOfTphs) {
|
|
||||||
//RuntimeException re = new RuntimeException("enthält EQUALS-Relation");
|
|
||||||
List<ClassConstraint> tempCC = new ArrayList<>();
|
|
||||||
for(TPHConstraint allCons: allConstraints){
|
|
||||||
if(posOfTphs.containsKey(allCons.getLeft()) && allCons.getRight()!=null && allCons.getRel()==Relation.EXTENDS) {
|
|
||||||
for(String tph: posOfTphs.keySet()) {
|
|
||||||
for(PairTphMethod pair: posOfTphs.get(tph)) {
|
|
||||||
if(tph == allCons.getLeft() && pair.fst == PositionFinder.Position.FIELD) {
|
|
||||||
ClassConstraint consToAdd = new ClassConstraint(tph, allCons.getRight(), allCons.getRel());
|
|
||||||
if (!checkForDuplicates(consToAdd, tempCC)) {
|
|
||||||
tempCC.add(consToAdd);
|
|
||||||
}
|
|
||||||
/*}else if(pair.fst == PositionFinder.Position.FIELD){
|
|
||||||
ClassConstraint consToAdd = new ClassConstraint(tph, objectType, Relation.EXTENDS);
|
|
||||||
if (!checkForDuplicates(consToAdd, tempCC)) {
|
|
||||||
tempCC.add(consToAdd);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*else if (allCons.getRel() != Relation.EXTENDS) {
|
|
||||||
throw re;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
return tempCC;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Def. FGG: zweite Zeile von cs_cl
|
|
||||||
* {T' <. T'' | \exists T: (T <. T') \in cs_cl, (T' <. T'') \in cs }
|
|
||||||
*/
|
|
||||||
public static List<ClassConstraint> transitiveSubtypeForClassTypes(List<TPHConstraint> allConstraints, List<ClassConstraint> cs_cl) {
|
|
||||||
List<ClassConstraint> tempCC = new ArrayList<>();
|
|
||||||
ClassConstraint consToAdd;
|
|
||||||
for(ClassConstraint cCons: cs_cl) {
|
|
||||||
if(cCons.getLeft() != null && cCons.getRel()==Relation.EXTENDS) {
|
|
||||||
for(TPHConstraint allCons: allConstraints) {
|
|
||||||
if(cCons.getRight() == allCons.getLeft() && allCons.getRight() != null && allCons.getRel()==Relation.EXTENDS){
|
|
||||||
consToAdd = new ClassConstraint(allCons.getLeft(), allCons.getRight(), allCons.getRel());
|
|
||||||
if (!checkForDuplicates(consToAdd, tempCC)) {
|
|
||||||
tempCC.add(consToAdd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tempCC;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Def. FGG: dritte Zeile von cs_cl
|
|
||||||
* {T <. Object | ((T is a type variable in a type of a node of a field
|
|
||||||
* or (\exists T~: (T~ <. T) \in cs_cl)) and (\existsnot T': T <. T') \in cs)}
|
|
||||||
*/
|
|
||||||
public static List<ClassConstraint> hasNoSupertypeForClassTypes(List<ClassConstraint> cs_cl, HashMap<String, List<PairTphMethod<PositionFinder.Position, String>>> posOfTphs) {
|
|
||||||
List<ClassConstraint> tempCC= new ArrayList<>();
|
|
||||||
List<TPHConstraint> clCons = new ArrayList<>(cs_cl);
|
|
||||||
for(String tph: posOfTphs.keySet()) {
|
|
||||||
for(PairTphMethod pair: posOfTphs.get(tph)) {
|
|
||||||
boolean tvInField = pair.fst == PositionFinder.Position.FIELD;
|
|
||||||
boolean hasSmallerTVInClCons = hasSmallerTVInClCons(tph, cs_cl);
|
|
||||||
if ((tvInField || hasSmallerTVInClCons) &&
|
|
||||||
!checkUpperBound(clCons, tph)) {
|
|
||||||
ClassConstraint consToAdd = new ClassConstraint(tph, objectType, Relation.EXTENDS);
|
|
||||||
if (!checkForDuplicates(consToAdd, tempCC)) {
|
|
||||||
tempCC.add(consToAdd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tempCC;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean hasSmallerTVInClCons(String tph, List<ClassConstraint> cs_cl) {
|
|
||||||
for(ClassConstraint cC: cs_cl) {
|
|
||||||
if(tph == cC.getRight() && cC.getRel() == Relation.EXTENDS) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Def. FGG: erste Zeile von cs_m
|
|
||||||
* {T < .T' | T is a type variable in a type of the method/constructor m in cl_\sigma, (T <. T') \in cs}
|
|
||||||
*/
|
|
||||||
public static List<MethodConstraint> typeOfTheMethodInClSigma(List<TPHConstraint> allConstraints, HashMap<String, List<PairTphMethod<PositionFinder.Position, String>>> posOfTphs) { // cl_\sigma??
|
|
||||||
//TODO:
|
|
||||||
List<MethodConstraint> tempMC= new ArrayList<>();
|
|
||||||
for(TPHConstraint allCons: allConstraints){
|
|
||||||
if(posOfTphs.containsKey(allCons.getLeft()) && allCons.getRight()!=null && allCons.getRel()==Relation.EXTENDS) {
|
|
||||||
for(String tph: posOfTphs.keySet()) {
|
|
||||||
for(PairTphMethod pair: posOfTphs.get(tph)) {
|
|
||||||
if(tph == allCons.getLeft() && (pair.fst == PositionFinder.Position.METHOD || pair.fst == PositionFinder.Position.CONSTRUCTOR)) {
|
|
||||||
MethodConstraint consToAdd = new MethodConstraint(allCons.getLeft(), allCons.getRight(), allCons.getRel());
|
|
||||||
if (!checkForDuplicates(consToAdd, tempMC)) {
|
|
||||||
tempMC.add(consToAdd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tempMC;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Def. FGG: zweite Zeile von cs_m
|
|
||||||
* {R' <. S | (R <. R'), (S <. S') \in cs_m and (R',S) is in the transitive closure of cs}
|
|
||||||
*/
|
|
||||||
public List<MethodConstraint> firstTransitiveSubtypeForMethodTypes(List<TPHConstraint> allConstraints, List<MethodConstraint> cs_m) { //transitive closure of cs
|
|
||||||
//TODO:
|
|
||||||
List<MethodConstraint> tempMC= new ArrayList<>();
|
|
||||||
List<TPHConstraint> tcOfCs = buildTransitiveClosure(allConstraints);
|
|
||||||
for(MethodConstraint mC1 : cs_m) { //(R <. R')
|
|
||||||
for(MethodConstraint mC2 : cs_m) { //(S <. S')
|
|
||||||
String lSide = mC1.getRight(); //R'
|
|
||||||
String rSide = mC2.getLeft(); //S
|
|
||||||
for(TPHConstraint tphC : tcOfCs) {
|
|
||||||
if(tphC.getLeft().equals(lSide)&&tphC.getRight().equals(rSide)) { //is it (R',S)
|
|
||||||
MethodConstraint consToAdd = new MethodConstraint(lSide, rSide, tphC.getRel()); //create (R'<.S)
|
|
||||||
if (!checkForDuplicates(consToAdd, tempMC)) {
|
|
||||||
tempMC.add(consToAdd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tempMC;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Def. FGG: dritte Zeile von cs_m
|
|
||||||
* {R' <. S | (R <. R') \in cs_m, (S <. S') \in cs_cl and (R',S) is in the transitive closure of cs}
|
|
||||||
*/
|
|
||||||
public List<MethodConstraint> secondTransitiveSubtypeForMethodTypes(List<TPHConstraint> allConstraints, List<ClassConstraint> cs_cl, List<MethodConstraint> cs_m) {
|
|
||||||
//TODO:
|
|
||||||
List<MethodConstraint> tempMC= new ArrayList<>();
|
|
||||||
List<TPHConstraint> tcOfCs = buildTransitiveClosure(allConstraints);
|
|
||||||
for(ClassConstraint cC : cs_cl) {
|
|
||||||
for(MethodConstraint mC : cs_m) {
|
|
||||||
String leftSide = mC.getRight();
|
|
||||||
String rightSide = cC.getLeft();
|
|
||||||
for(TPHConstraint tphC : tcOfCs) {
|
|
||||||
if(tphC.getLeft().equals(leftSide)&&tphC.getRight().equals(rightSide)) {
|
|
||||||
MethodConstraint consToAdd = new MethodConstraint(tphC.getLeft(), tphC.getRight(), tphC.getRel());
|
|
||||||
if (!checkForDuplicates(consToAdd, tempMC)) {
|
|
||||||
tempMC.add(consToAdd);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tempMC;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Def. FGG: vierte Zeile von cs_m
|
|
||||||
* {T <. Object | (T is a type variable in a type of a node of the method/constructor m in cl_\sigma),
|
|
||||||
* (\existsnot T': T <. T') \in cs)}
|
|
||||||
*/
|
|
||||||
public static List<MethodConstraint> hasNoSupertypeForMethodTypes(List<TPHConstraint> allConstraints, List<MethodConstraint> cs_m, HashMap<String, List<PairTphMethod<PositionFinder.Position, String>>> posOfTphs, List<MethodAndTPH> listOfMethodsAndTph) {
|
|
||||||
//TODO:
|
|
||||||
List<MethodConstraint> tempMC= new ArrayList<>();
|
|
||||||
for(String tph: posOfTphs.keySet()) {
|
|
||||||
for(PairTphMethod pair: posOfTphs.get(tph)) {
|
|
||||||
for(TPHConstraint allCons: allConstraints) {
|
|
||||||
if((pair.fst.equals(PositionFinder.Position.METHOD) || pair.fst.equals(PositionFinder.Position.CONSTRUCTOR)) && !checkUpperBound(allConstraints,tph)) {
|
|
||||||
MethodConstraint consToAdd = new MethodConstraint(tph, objectType, Relation.EXTENDS);
|
|
||||||
if (!checkForDuplicates(consToAdd, tempMC)) {
|
|
||||||
tempMC.add(consToAdd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List<TPHConstraint> tempMCObject1 = new ArrayList<>(cs_m);
|
|
||||||
String currentMethod = "";
|
|
||||||
for(MethodAndTPH mat: listOfMethodsAndTph) {
|
|
||||||
if(mat.getId().equals(pair.snd)) {
|
|
||||||
currentMethod = mat.getId();
|
|
||||||
}
|
|
||||||
for(TPHConstraint mc1: tempMCObject1) {
|
|
||||||
if(tph==mc1.getRight() && !checkUpperBound(tempMCObject1,tph)) {
|
|
||||||
MethodConstraint consToAdd = new MethodConstraint(tph, objectType, Relation.EXTENDS);
|
|
||||||
if (!checkForDuplicates(consToAdd, tempMC)) {
|
|
||||||
tempMC.add(consToAdd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tempMC;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* nimm die Menge cs_cl aus cs_m raus
|
|
||||||
*/
|
|
||||||
public List<MethodConstraint> methodTypesWithoutClassTypes(List<ClassConstraint> cs_cl, List<MethodConstraint> cs_m) {
|
|
||||||
// erstelle Kopie der Liste cs_cl
|
|
||||||
List<TPHConstraint> tempCC = new ArrayList<>();
|
|
||||||
for(ClassConstraint cc: cs_cl) {
|
|
||||||
TPHConstraint tphC = new TPHConstraint(cc.getLeft(), cc.getRight(), cc.getRel());
|
|
||||||
tempCC.add(tphC);
|
|
||||||
}
|
|
||||||
// Transitive Hülle von cs_cl
|
|
||||||
List<TPHConstraint> tcOfCsCl = buildTransitiveClosure(tempCC);
|
|
||||||
|
|
||||||
List<TPHConstraint> tempMC = new ArrayList<>();
|
|
||||||
for(MethodConstraint mc: cs_m) {
|
|
||||||
TPHConstraint tphC = new TPHConstraint(mc.getLeft(), mc.getRight(), mc.getRel());
|
|
||||||
tempMC.add(tphC);
|
|
||||||
}
|
|
||||||
List<TPHConstraint> tempMC2 = new ArrayList<>();
|
|
||||||
tempMC2.addAll(tempMC);
|
|
||||||
List<MethodConstraint> tempMCToReturn = new ArrayList<>();
|
|
||||||
|
|
||||||
for(TPHConstraint cc: tcOfCsCl) {
|
|
||||||
for(TPHConstraint mc: tempMC) {
|
|
||||||
if(cc.getLeft().equals(mc.getLeft()) && cc.getRight().equals(mc.getRight())) {
|
|
||||||
tempMC2.remove(mc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(TPHConstraint tphC: tempMC2) {
|
|
||||||
MethodConstraint mCons = new MethodConstraint(tphC.getLeft(), tphC.getRight(), tphC.getRel());
|
|
||||||
tempMCToReturn.add(mCons);
|
|
||||||
}
|
|
||||||
return tempMCToReturn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean checkForDuplicates(TPHConstraint constraint, List list) {
|
|
||||||
List<TPHConstraint> tempList = list;
|
|
||||||
boolean hasSame = false;
|
|
||||||
for (TPHConstraint tphC: tempList) {
|
|
||||||
hasSame = constraint.getLeft() == tphC.getLeft() &&
|
|
||||||
constraint.getRight() == tphC.getRight() &&
|
|
||||||
constraint.getRel() == tphC.getRel(); //constraint already in ArrayList if true
|
|
||||||
if (hasSame)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<TPHConstraint> buildTransitiveClosure(List list) {
|
|
||||||
List<TPHConstraint> iterList = new ArrayList<>(list);
|
|
||||||
List<TPHConstraint> runList = new ArrayList<>(list);
|
|
||||||
List<TPHConstraint> tcList = new ArrayList<>(list);
|
|
||||||
boolean addedConToList = false;
|
|
||||||
for (TPHConstraint cons: iterList) {
|
|
||||||
for (TPHConstraint cons2: runList) {
|
|
||||||
if(cons.getRight() == cons2.getLeft()) {
|
|
||||||
TPHConstraint consToAdd = new TPHConstraint(cons.getLeft(), cons2.getRight(), Relation.EXTENDS);
|
|
||||||
if (!checkForDuplicates(consToAdd,tcList)) {
|
|
||||||
tcList.add(consToAdd);
|
|
||||||
addedConToList = true;
|
|
||||||
if (addedConToList) {
|
|
||||||
return buildTransitiveClosure(tcList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tcList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean checkUpperBound(List<TPHConstraint> cs, String tph) {
|
|
||||||
for(int i=0; i<cs.size(); i++) {
|
|
||||||
if(cs.get(i).getLeft() == tph) {
|
|
||||||
//has upper bound
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static HashMap<String, List<PairTphMethod<PositionFinder.Position, String>>> positionConverter(HashMap<String, Boolean> allTphs, List<MethodAndTPH> listOfMethodsAndTphs) {
|
|
||||||
HashMap<String, List<PairTphMethod<PositionFinder.Position, String>>> convertedPositions = new HashMap<>();
|
|
||||||
for(String tph: allTphs.keySet()) {
|
|
||||||
List<PairTphMethod<PositionFinder.Position, String>> currMeth = new ArrayList<>();
|
|
||||||
if(allTphs.get(tph)) { //if true, then tph is a method-TPH
|
|
||||||
for(MethodAndTPH methTph: listOfMethodsAndTphs) {
|
|
||||||
if (methTph.getTphs().contains(tph)) {
|
|
||||||
currMeth.add(new PairTphMethod<>(PositionFinder.Position.METHOD, methTph.getId()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else { // else it is in the class-TPH
|
|
||||||
currMeth.add(new PairTphMethod<>(PositionFinder.Position.FIELD, null));
|
|
||||||
}
|
|
||||||
convertedPositions.put(tph, currMeth);
|
|
||||||
}
|
|
||||||
return convertedPositions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* public PositionFinder.Position positionConverter(TPHExtractor tphExtractor) {
|
|
||||||
if(tphExtractor.allTPHS.keySet())
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* GeneratedGenericsFinder genGenFinder;
|
|
||||||
ConstraintsSimplierResult simplifiedConstraints = null;
|
|
||||||
GenericsGeneratorResultForClass ggResult = null;
|
|
||||||
Method m;
|
|
||||||
|
|
||||||
public void addMethodConstraints(List<MethodConstraint> cs_m) {
|
|
||||||
genGenFinder.addMethodConstraints(simplifiedConstraints, ggResult, m);
|
|
||||||
cs_m.add();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static List<MethodConstraint> firstLineMethodDefinition(List<TPHConstraint> allConstraints, HashMap<String, List<PairTphMethod<PositionFinder.Position, String>>> posOfTphs, MethodAndTPH methodAndTPH, ResultSet resSet) {
|
|
||||||
List<MethodConstraint> tempMC= new ArrayList<>();
|
|
||||||
MethodAndTPH methAndTphs = methodAndTPH;
|
|
||||||
Set<Pair> undCons = methAndTphs.constraints.getUndConstraints();
|
|
||||||
List<Set<Constraint<Pair>>> orCons = methAndTphs.constraints.getOderConstraints();
|
|
||||||
Iterator<Pair> it = undCons.iterator();
|
|
||||||
while(it.hasNext()) {
|
|
||||||
Pair p = it.next();
|
|
||||||
String ta1 = ((TypePlaceholder) (resSet.resolveType(((TypePlaceholder) p.TA1)).resolvedType)).getName();
|
|
||||||
String ta2 = ((TypePlaceholder) (resSet.resolveType(((TypePlaceholder) p.TA2)).resolvedType)).getName();
|
|
||||||
Relation r = null;
|
|
||||||
if(p.GetOperator() == PairOperator.SMALLERDOT) {
|
|
||||||
r = Relation.EXTENDS;
|
|
||||||
} else if(p.GetOperator() == PairOperator.EQUALSDOT) {
|
|
||||||
r = Relation.EQUAL;
|
|
||||||
}
|
|
||||||
MethodConstraint mc = new MethodConstraint(ta1, ta2, r);
|
|
||||||
if(mc.getRel() == Relation.EXTENDS) {
|
|
||||||
if (!mc.getLeft().equals(mc.getRight())) { //eliminieren der Fälle wie AA<.AA
|
|
||||||
if(!checkForDuplicates(mc, tempMC)) {
|
|
||||||
tempMC.add(mc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tempMC;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<MethodConstraint> secondLineMethodDefinition(List<TPHConstraint> allConstraints, HashMap<String, List<PairTphMethod<PositionFinder.Position, String>>> posOfTphs, MethodAndTPH methodAndTPH, ResultSet resSet, Set<Pair> oldCons) {
|
|
||||||
List<MethodConstraint> tempMC = new ArrayList<>(); //für Ergebnisse basierend auf der neuen Datenstruktur (Ali)
|
|
||||||
Set<Pair> tempSet = new HashSet<>(); //für Ergebnisse des ersten Teils der Bedinung basierend auf der alten Datenstruktur
|
|
||||||
Set<Pair> tempSet2 = new HashSet<>(); //für Ergebnisse des zweiten Teils der Bedingung basierend auf der alten Datenstruktur
|
|
||||||
Set<Pair> tcOfoldConsSet = buildTransitiveClosureForCP(oldCons, resSet);
|
|
||||||
List<TPHConstraint> tcOfCs = buildTransitiveClosure(allConstraints);
|
|
||||||
MethodAndTPH methAndTphs = methodAndTPH;
|
|
||||||
Set<Pair> undCons = methAndTphs.constraints.getUndConstraints();
|
|
||||||
List<Set<Constraint<Pair>>> orCons = methAndTphs.constraints.getOderConstraints();
|
|
||||||
List<HashMap<Relation, List<TPHConstraint>>> orConsListConverted = new ArrayList<>();
|
|
||||||
//gehe die OrConstraints der aktuellen Methode durch und teile nach Operator auf (
|
|
||||||
for(int i=0; i<orCons.size(); i++) {
|
|
||||||
List<TPHConstraint> orConsWithEQUAL = new ArrayList();
|
|
||||||
List<TPHConstraint> orConsWithEXTENDS = new ArrayList();
|
|
||||||
HashMap<Relation, List<TPHConstraint>> orConsInternal = new HashMap<>();
|
|
||||||
for(Constraint con: orCons.get(i)) {
|
|
||||||
Iterator<Pair> it = con.iterator();
|
|
||||||
while(it.hasNext()) {
|
|
||||||
Pair p = it.next();
|
|
||||||
Relation r = null;
|
|
||||||
if(p.GetOperator() == PairOperator.SMALLERDOT) {
|
|
||||||
r = Relation.EXTENDS;
|
|
||||||
orConsWithEXTENDS.add(new TPHConstraint(((TypePlaceholder) p.TA1).getName(), ((TypePlaceholder) p.TA2).getName(), r));
|
|
||||||
/*MethodConstraint mc = new MethodConstraint(((TypePlaceholder) (resSet.resolveType(((TypePlaceholder) p.TA1)).resolvedType)).getName(), ((TypePlaceholder) (resSet.resolveType(((TypePlaceholder) p.TA2)).resolvedType)).getName(), r);
|
|
||||||
if(!checkForDuplicates(mc, tempMC)) {
|
|
||||||
tempMC.add(mc);
|
|
||||||
}*/
|
|
||||||
} else if(p.GetOperator() == PairOperator.EQUALSDOT) {
|
|
||||||
r = Relation.EQUAL;
|
|
||||||
orConsWithEQUAL.add(new TPHConstraint(((TypePlaceholder) p.TA1).getName(), ((TypePlaceholder) p.TA2).getName(), r));
|
|
||||||
/*MethodConstraint mc = new MethodConstraint(((TypePlaceholder) (resSet.resolveType(((TypePlaceholder) p.TA1)).resolvedType)).getName(), ((TypePlaceholder) (resSet.resolveType(((TypePlaceholder) p.TA2)).resolvedType)).getName(), r);
|
|
||||||
if(!checkForDuplicates(mc, tempMC)) {
|
|
||||||
tempMC.add(mc);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
orConsInternal.put(Relation.EXTENDS, orConsWithEXTENDS);
|
|
||||||
orConsInternal.put(Relation.EQUAL, orConsWithEQUAL);
|
|
||||||
orConsListConverted.add(orConsInternal);
|
|
||||||
}
|
|
||||||
|
|
||||||
// oldCons sind alle Und- und Oder-Constraints
|
|
||||||
// zunächst in meine Datenstruktur(Ali) konvertieren
|
|
||||||
List<Pair> oldConsList = new ArrayList<>(oldCons);
|
|
||||||
List<TPHConstraint> oldConsListConverted = new ArrayList<>();
|
|
||||||
for(Pair pair: oldConsList) {
|
|
||||||
Relation r = null;
|
|
||||||
if(pair.GetOperator() == PairOperator.SMALLERDOT) {
|
|
||||||
r = Relation.EXTENDS;
|
|
||||||
} else if(pair.GetOperator() == PairOperator.EQUALSDOT) {
|
|
||||||
r = Relation.EQUAL;
|
|
||||||
}
|
|
||||||
oldConsListConverted.add(new TPHConstraint(((TypePlaceholder) pair.TA1).getName(), ((TypePlaceholder) pair.TA2).getName(), r));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Berechnung des zweiten Teils der Bedingung der Regel
|
|
||||||
for(int i=0; i<orCons.size(); i++) {
|
|
||||||
Constraint<Pair> extendsSet = new Constraint<Pair>();
|
|
||||||
Constraint<Pair> equalSet = new Constraint<Pair>();
|
|
||||||
//für jede einzelne OrConstraint-Menge gehe durch
|
|
||||||
for (Constraint con : orCons.get(i)) {
|
|
||||||
Iterator<Pair> it = con.iterator();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
Pair p = it.next();
|
|
||||||
if (p.OperatorSmallerDot()) {
|
|
||||||
extendsSet.add(p);
|
|
||||||
} else if (p.OperatorEqual()) {
|
|
||||||
equalSet.add(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Iterator<Pair> itExtends2 = extendsSet.iterator();
|
|
||||||
while(itExtends2.hasNext()) {
|
|
||||||
Pair pairExtends2 = itExtends2.next();
|
|
||||||
Set<String> containedVars = new HashSet<>(methodAndTPH.getTphs());
|
|
||||||
String pairExtends2RHSName = ((TypePlaceholder)((resSet.resolveType((TypePlaceholder)pairExtends2.TA2)).resolvedType)).getName();
|
|
||||||
Iterator<Pair> itEqual2 = equalSet.iterator();
|
|
||||||
while (itEqual2.hasNext()) {
|
|
||||||
boolean transClo = false;
|
|
||||||
Pair pairEqual2 = itEqual2.next();
|
|
||||||
//TODO: Auf trans.FamilyOfGeneratedGenerics Huelle pruefen
|
|
||||||
Pair newPairOld = new Pair(pairExtends2.TA2, pairEqual2.TA1);
|
|
||||||
Pair newPair2 = new Pair(resSet.resolveType((TypePlaceholder) (pairExtends2.TA2)).resolvedType, resSet.resolveType((TypePlaceholder) (pairEqual2.TA1)).resolvedType, PairOperator.SMALLERDOT);
|
|
||||||
TPHConstraint newPairTPHConstraint = new TPHConstraint(newPair2);
|
|
||||||
if (tcOfCs.contains(newPairTPHConstraint)|| (newPairTPHConstraint.getLeft().equals(newPairTPHConstraint.getRight()))) {
|
|
||||||
transClo = true;
|
|
||||||
}
|
|
||||||
TypePlaceholder tphR = (TypePlaceholder) pairEqual2.TA2;
|
|
||||||
Iterator<Pair> itUndCons = undCons.iterator();
|
|
||||||
boolean rEqExRtilde = false;
|
|
||||||
while (itUndCons.hasNext()) {
|
|
||||||
Pair pairUndCons2 = itUndCons.next();
|
|
||||||
rEqExRtilde = rEqExRtilde || (tphR == pairUndCons2.TA1);
|
|
||||||
}
|
|
||||||
boolean isPairInTExTapostrophe = false;
|
|
||||||
for(Set<Constraint<Pair>> scp: orCons) {
|
|
||||||
Iterator<Constraint<Pair>> itSCP = scp.iterator();
|
|
||||||
while(itSCP.hasNext()) {
|
|
||||||
Constraint<Pair> cp = itSCP.next();
|
|
||||||
Iterator<Pair> itCP = cp.iterator();
|
|
||||||
while(itCP.hasNext()) {
|
|
||||||
Pair p = itCP.next();
|
|
||||||
if(p.OperatorSmallerDot()) {
|
|
||||||
isPairInTExTapostrophe = isPairInTExTapostrophe || tphR.equals(p.TA1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transClo && (rEqExRtilde || isPairInTExTapostrophe)) {
|
|
||||||
if (!newPair2.TA1.equals(newPair2.TA2)) { //eliminieren der Fälle wie AA<.AA
|
|
||||||
if (!checkForDuplicatesForSets(newPair2, tempSet2)) {
|
|
||||||
tempSet2.add(newPair2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!checkForDuplicatesForSets(pairExtends2, tempSet2)) {
|
|
||||||
tempSet2.add(pairExtends2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//containedVars.remove(((TypePlaceholder)newPair2.TA2).getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//String key = ((TypePlaceholder)((resSet.resolveType((TypePlaceholder)pairExtends2.TA2)).resolvedType)).getName();
|
|
||||||
//TODO: containedVars stimmt noch nicht. Ueberpruefen, ob ggf. mit den containedVars möglicherweise auch die anderen Faelle
|
|
||||||
// rEqExRtilde isPairInTExTapostrophe abgedeckt sind => ggf. integrieren
|
|
||||||
/*
|
|
||||||
posOfTphs.forEach((x,y) -> {
|
|
||||||
if (y.contains(new PairTphMethod<>(PositionFinder.Position.METHOD, methodAndTPH.getId()))) {
|
|
||||||
containedVars.add(x);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
//Referenzbeispiel Put.jav
|
|
||||||
if (containedVars.stream().filter(v -> tcOfCs.contains(new TPHConstraint(pairExtends2RHSName, v, Relation.EXTENDS)))
|
|
||||||
.count() > 0) {
|
|
||||||
System.out.println();
|
|
||||||
//tempSet2.add(pairExtends2);
|
|
||||||
}
|
|
||||||
if (posOfTphs.containsKey(pairExtends2RHSName)) {//Refrenzbeispiel TestVector.jav
|
|
||||||
if (posOfTphs.get(pairExtends2RHSName).contains(new PairTphMethod<>(PositionFinder.Position.METHOD, methodAndTPH.getId()))) {
|
|
||||||
tempSet2.add(pairExtends2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// aus der alten Datenstruktur in die neue Datenstruktur (von Ali) für ersten Teil
|
|
||||||
Iterator<Pair> itTemp = tempSet.iterator();
|
|
||||||
while(itTemp.hasNext()) {
|
|
||||||
Pair p = itTemp.next();
|
|
||||||
String ta1 = ((TypePlaceholder) (resSet.resolveType(((TypePlaceholder) p.TA1)).resolvedType)).getName();
|
|
||||||
String ta2 = ((TypePlaceholder) (resSet.resolveType(((TypePlaceholder) p.TA2)).resolvedType)).getName();
|
|
||||||
Relation r = null;
|
|
||||||
if(p.GetOperator() == PairOperator.SMALLERDOT) {
|
|
||||||
r = Relation.EXTENDS;
|
|
||||||
} else if(p.GetOperator() == PairOperator.EQUALSDOT) {
|
|
||||||
r = Relation.EQUAL;
|
|
||||||
}
|
|
||||||
MethodConstraint mc = new MethodConstraint(ta1, ta2, r);
|
|
||||||
if(mc.getRel() == Relation.EXTENDS) {
|
|
||||||
if(!checkForDuplicates(mc, tempMC)) {
|
|
||||||
tempMC.add(mc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// aus der alten Datenstruktur in die neue Datenstruktur (von Ali) für zweiten Teil
|
|
||||||
Iterator<Pair> itTemp2 = tempSet2.iterator();
|
|
||||||
while(itTemp2.hasNext()) {
|
|
||||||
Pair p = itTemp2.next();
|
|
||||||
String ta1 = ((TypePlaceholder) (resSet.resolveType(((TypePlaceholder) p.TA1)).resolvedType)).getName();
|
|
||||||
String ta2 = ((TypePlaceholder) (resSet.resolveType(((TypePlaceholder) p.TA2)).resolvedType)).getName();
|
|
||||||
Relation r = null;
|
|
||||||
if (p.GetOperator() == PairOperator.SMALLERDOT) {
|
|
||||||
r = Relation.EXTENDS;
|
|
||||||
} else if (p.GetOperator() == PairOperator.EQUALSDOT) {
|
|
||||||
r = Relation.EQUAL;
|
|
||||||
}
|
|
||||||
for(TPHConstraint tphCons: tcOfCs) {//TODO: hier werden Elemente der Trans. clo herausgenommen, aber die dazugehoerigen OrCons nicht.
|
|
||||||
if(ta1 == tphCons.getLeft() && ta2 == tphCons.getRight() && r==Relation.EXTENDS) {
|
|
||||||
MethodConstraint mc = new MethodConstraint(ta1, ta2, r);
|
|
||||||
if(!checkForDuplicates(mc, tempMC)) {
|
|
||||||
tempMC.add(mc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tempMC;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static Set<Pair> buildTransitiveClosureForCP(Set constraint, ResultSet resSet) {
|
|
||||||
Set<Pair> iterSet = new HashSet<>(constraint);
|
|
||||||
Set<Pair> runSet = new HashSet<>(constraint);
|
|
||||||
Set<Pair> tcSet = new HashSet<>(constraint);
|
|
||||||
boolean addedConToList = false;
|
|
||||||
// for (TPHConstraint cons: iterList) {
|
|
||||||
Iterator<Pair> itIterSet = iterSet.iterator();
|
|
||||||
while(itIterSet.hasNext()) {
|
|
||||||
Pair pairIterSet = itIterSet.next();
|
|
||||||
// for (TPHConstraint cons2: runList) {
|
|
||||||
Iterator<Pair> itRunSet = runSet.iterator();
|
|
||||||
while (itRunSet.hasNext()) {
|
|
||||||
Pair pairRunSet = itRunSet.next();
|
|
||||||
// if(cons.getRight() == cons2.getLeft()) {
|
|
||||||
if(pairIterSet.TA2 == pairRunSet.TA1 && pairIterSet.OperatorSmallerDot() && pairRunSet.OperatorSmallerDot()) {
|
|
||||||
// TPHConstraint consToAdd = new TPHConstraint(cons.getLeft(), cons2.getRight(), Relation.EXTENDS);
|
|
||||||
Pair p = new Pair(resSet.resolveType((TypePlaceholder)(pairIterSet.TA1)).resolvedType, resSet.resolveType((TypePlaceholder)(pairRunSet.TA2)).resolvedType, PairOperator.SMALLERDOT);
|
|
||||||
// if (!checkForDuplicates(consToAdd,tcList)) {
|
|
||||||
if(!checkForDuplicatesForSets(p, tcSet)) {
|
|
||||||
// tcList.add(consToAdd);
|
|
||||||
tcSet.add(p);
|
|
||||||
addedConToList = true;
|
|
||||||
if (addedConToList) {
|
|
||||||
return buildTransitiveClosureForCP(tcSet, resSet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.out.println("tcSet: " + tcSet);
|
|
||||||
return tcSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean checkForDuplicatesForSets(Pair pair, Set set) {
|
|
||||||
Set<Pair> tempSet = set;
|
|
||||||
boolean hasSame = false;
|
|
||||||
// for (TPHConstraint tphC: tempList) {
|
|
||||||
Iterator<Pair> it = tempSet.iterator();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
Pair p = it.next();
|
|
||||||
// hasSame = constraint.getLeft() == tphC.getLeft() &&
|
|
||||||
// constraint.getRight() == tphC.getRight() &&
|
|
||||||
// constraint.getRel() == tphC.getRel(); //constraint already in ArrayList if true
|
|
||||||
hasSame = pair.TA1 == p.TA1 &&
|
|
||||||
pair.TA2 == p.TA2 &&
|
|
||||||
pair.OperatorSmallerDot() && p.OperatorSmallerDot(); //constraint already in Set if true
|
|
||||||
if (hasSame)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<MethodConstraint> hasNoSupertypeForMethodTypesNew(HashMap<String, List<PairTphMethod<PositionFinder.Position, String>>> posOfTphs, MethodAndTPH methodAndTPH, List<MethodConstraint> cs_m) {
|
|
||||||
List<MethodConstraint> tempMC = new ArrayList<>();
|
|
||||||
List<TPHConstraint> methCons = new ArrayList<>(cs_m);
|
|
||||||
MethodAndTPH methAndTphs = methodAndTPH;
|
|
||||||
for(String tph: posOfTphs.keySet()) {
|
|
||||||
for(int i=0; i<posOfTphs.get(tph).size(); i++)
|
|
||||||
if(posOfTphs.get(tph).get(i).fst == PositionFinder.Position.METHOD && posOfTphs.get(tph).get(i).snd == methAndTphs.getId() && !checkUpperBound(methCons,tph)) {
|
|
||||||
MethodConstraint mc2 = new MethodConstraint(tph, objectType, Relation.EXTENDS);
|
|
||||||
if (!checkForDuplicates(mc2, tempMC)) {
|
|
||||||
tempMC.add(mc2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tempMC;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static List<MethodConstraint> methodTypesWithoutClassTypesNEW(List<String> tphsToCompute, List<MethodConstraint> cs_m) {
|
|
||||||
List<MethodConstraint> tempMC = new ArrayList<>(cs_m);
|
|
||||||
List<MethodConstraint> tempMC2 = new ArrayList<>(cs_m);
|
|
||||||
List<String> toRemove = new ArrayList<>();
|
|
||||||
for(String tph: tphsToCompute) {
|
|
||||||
for(TPHConstraint tphCons: tempMC) {
|
|
||||||
if(tphCons.getLeft() == tph) {
|
|
||||||
toRemove.add(tphCons.getRight());
|
|
||||||
tempMC2.remove(tphCons);
|
|
||||||
tempMC2 = methodTypesWithoutClassTypesNEW(toRemove,tempMC2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tempMC2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public HashMap<String, List<MethodConstraint>> getMethodConstraintsWithPositionNew(List<TPHConstraint> cs, List<ClassConstraint> cs_cl, HashMap<String, List<PairTphMethod<PositionFinder.Position, String>>> posOfTphs, List<MethodAndTPH> listOfMethodsAndTph, ResultSet resSet, Set<Pair> oldCons) {
|
|
||||||
HashMap<String, List<MethodConstraint>> tempMethodConstraintsWithPosition = new HashMap<>();
|
|
||||||
List<MethodConstraint> newMCList = new ArrayList<>();
|
|
||||||
List<MethodConstraint> newMCList2 = new ArrayList<>();
|
|
||||||
List<MethodConstraint> hasNoSupType = new ArrayList<>();
|
|
||||||
List<MethodConstraint> mcWithoutCc = new ArrayList<>();
|
|
||||||
|
|
||||||
List<String> methodsAddedToHashMap = new ArrayList<>();
|
|
||||||
for(MethodAndTPH method: listOfMethodsAndTph){
|
|
||||||
String currentMethod = method.getId();
|
|
||||||
boolean containsCurrentMethod = false;
|
|
||||||
if(!containsCurrentMethod) {
|
|
||||||
methodsAddedToHashMap.add(currentMethod);
|
|
||||||
containsCurrentMethod = true;
|
|
||||||
List<MethodConstraint> listToAdd = new ArrayList<>();
|
|
||||||
HashMap<String, List<PairTphMethod<PositionFinder.Position, String>>> posOfTPHsForThisMethod = new HashMap<>();
|
|
||||||
for(String s: posOfTphs.keySet()) {
|
|
||||||
for(PairTphMethod pair: posOfTphs.get(s)) {
|
|
||||||
if(pair.snd == currentMethod && pair.snd != null) {
|
|
||||||
posOfTPHsForThisMethod.put(s,posOfTphs.get(s));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newMCList = firstLineMethodDefinition(cs, posOfTphs, method, resSet);
|
|
||||||
for(int i=0; i<newMCList.size(); i++) {
|
|
||||||
listToAdd.add(newMCList.get(i));
|
|
||||||
}
|
|
||||||
newMCList2 = secondLineMethodDefinition(cs, posOfTphs, method, resSet, oldCons);
|
|
||||||
for(int i=0; i<newMCList2.size(); i++) {
|
|
||||||
listToAdd.add(newMCList2.get(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*if(!methodsAddedToHashMap.contains(currentMethod)) {
|
|
||||||
tempMethodConstraintsWithPosition.put(currentMethod, newMCList);
|
|
||||||
tempMethodConstraintsWithPosition.put(currentMethod, newMCList2);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
hasNoSupType = hasNoSupertypeForMethodTypesNew(posOfTphs,method,listToAdd);
|
|
||||||
for (MethodConstraint cons: hasNoSupType) {
|
|
||||||
if (!checkForDuplicates(cons, listToAdd)) {
|
|
||||||
listToAdd.add(cons);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mcWithoutCc = listToAdd;
|
|
||||||
List<String> tphs = new ArrayList<>();
|
|
||||||
for(String tph: posOfTphs.keySet()) {
|
|
||||||
for (PairTphMethod p : posOfTphs.get(tph)) {
|
|
||||||
if(p.fst == PositionFinder.Position.FIELD) {
|
|
||||||
tphs.add(tph);
|
|
||||||
mcWithoutCc = methodTypesWithoutClassTypesNEW(tphs, listToAdd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tempMethodConstraintsWithPosition.put(currentMethod, mcWithoutCc);
|
|
||||||
}
|
|
||||||
for(String curMeth: tempMethodConstraintsWithPosition.keySet()){
|
|
||||||
for(int i=0; i<tempMethodConstraintsWithPosition.get(curMeth).size(); i++) {
|
|
||||||
MethodConstraint currentMC = tempMethodConstraintsWithPosition.get(curMeth).get(i);
|
|
||||||
if(currentMC.getRight()!= objectType && !compareTphsOfConstraints(currentMC.getRight(), cs_cl) && !compareTphsOfConstraints(currentMC.getRight(), tempMethodConstraintsWithPosition.get(curMeth))) {
|
|
||||||
MethodConstraint mc = new MethodConstraint(currentMC.getRight(), objectType, Relation.EXTENDS);
|
|
||||||
tempMethodConstraintsWithPosition.get(curMeth).add(mc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tempMethodConstraintsWithPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
package de.dhbwstuttgart.bytecode.gGenericsAli;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* gets set of typed variable constraints with substitutions and the set of typed classes
|
|
||||||
* and returns the set of families of generated generics and the set of families of type variable mappings
|
|
||||||
*//*
|
|
||||||
|
|
||||||
public class GGenerics implements preGGenerics {
|
|
||||||
private TVarConstraints tVarCons;
|
|
||||||
private Substitutions subst;
|
|
||||||
private TClass typedClass;
|
|
||||||
|
|
||||||
|
|
||||||
public GGenerics(TVarConstraints tVarCons, Substitutions subst, TClass typedClass) throws IOException, ClassNotFoundException {
|
|
||||||
this.tVarCons = tVarCons;
|
|
||||||
this.subst = subst;
|
|
||||||
this.typedClass = typedClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<File> input = new ArrayList<>();
|
|
||||||
List<File> classpath = new ArrayList<>();
|
|
||||||
|
|
||||||
JavaTXCompiler compiler = new JavaTXCompiler(input, classpath);
|
|
||||||
compiler.typeInference();
|
|
||||||
|
|
||||||
public List<ResultSet> getResultOfTypeInference() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
@ -1,10 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode.insertGenerics;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
|
||||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
|
||||||
|
|
||||||
public class MethodConstraint extends TPHConstraint {
|
|
||||||
public MethodConstraint(String left, String right, Relation rel) {
|
|
||||||
super(left, right, rel);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode.insertGenerics;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/** A generic class for pairs.
|
|
||||||
*
|
|
||||||
* <p><b>This is NOT part of any supported API.
|
|
||||||
* If you write code that depends on this, you do so at your own risk.
|
|
||||||
* This code and its internal interfaces are subject to change or
|
|
||||||
* deletion without notice.</b>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
public class PairMethodAndConstraint<A, B> {
|
|
||||||
public final A fst;
|
|
||||||
public final B snd;
|
|
||||||
|
|
||||||
public PairMethodAndConstraint(A fst, B snd) {
|
|
||||||
this.fst = fst;
|
|
||||||
this.snd = snd;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return "PairTphMethod[" + fst + "," + snd + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object other) {
|
|
||||||
return
|
|
||||||
other instanceof PairMethodAndConstraint<?,?> &&
|
|
||||||
Objects.equals(fst, ((PairMethodAndConstraint<?,?>)other).fst) &&
|
|
||||||
Objects.equals(snd, ((PairMethodAndConstraint<?,?>)other).snd);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
if (fst == null) return (snd == null) ? 0 : snd.hashCode() + 1;
|
|
||||||
else if (snd == null) return fst.hashCode() + 2;
|
|
||||||
else return fst.hashCode() * 17 + snd.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <A,B> PairMethodAndConstraint<A,B> of(A a, B b) {
|
|
||||||
return new PairMethodAndConstraint<>(a,b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PairMethodAndConstraint add(A fst, B snd){
|
|
||||||
return new PairMethodAndConstraint<>(fst,snd);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode.insertGenerics;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/** A generic class for pairs.
|
|
||||||
*
|
|
||||||
* <p><b>This is NOT part of any supported API.
|
|
||||||
* If you write code that depends on this, you do so at your own risk.
|
|
||||||
* This code and its internal interfaces are subject to change or
|
|
||||||
* deletion without notice.</b>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
public class PairTphMethod<A, B> {
|
|
||||||
public final A fst;
|
|
||||||
public final B snd;
|
|
||||||
|
|
||||||
public PairTphMethod(A fst, B snd) {
|
|
||||||
this.fst = fst;
|
|
||||||
this.snd = snd;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return "PairTphMethod[" + fst + "," + snd + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object other) {
|
|
||||||
return
|
|
||||||
other instanceof PairTphMethod<?,?> &&
|
|
||||||
Objects.equals(fst, ((PairTphMethod<?,?>)other).fst) &&
|
|
||||||
Objects.equals(snd, ((PairTphMethod<?,?>)other).snd);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
if (fst == null) return (snd == null) ? 0 : snd.hashCode() + 1;
|
|
||||||
else if (snd == null) return fst.hashCode() + 2;
|
|
||||||
else return fst.hashCode() * 17 + snd.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <A,B> PairTphMethod<A,B> of(A a, B b) {
|
|
||||||
return new PairTphMethod<>(a,b);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,79 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode.insertGenerics;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.syntaxtree.*;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class PositionFinder{
|
|
||||||
static HashMap<String, PairTphMethod<Position, String>> posOfTphs = new HashMap<String, PairTphMethod<Position, String>>();
|
|
||||||
|
|
||||||
static PairTphMethod<Position, String> whichMethod; // gibt an, in welcher Methode sich TPH befindet (Position.METHOD, id_of_method)
|
|
||||||
|
|
||||||
public enum Position{
|
|
||||||
METHOD,
|
|
||||||
CONSTRUCTOR,
|
|
||||||
FIELD
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HashMap<String, PairTphMethod<Position, String>> getPositionOfTPH(SourceFile sf, Set<String> tphs) {
|
|
||||||
|
|
||||||
new Walker().visit(sf);
|
|
||||||
for (String tph: posOfTphs.keySet()) {
|
|
||||||
System.out.println(tph + " " + posOfTphs.get(tph));
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
public static void putPositionInMethod(String tph, String methodId) {
|
|
||||||
posOfTphs.put(tph, new PairTphMethod<>(Position.METHOD, methodId));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void putPositionInField(String tph) {
|
|
||||||
posOfTphs.put(tph, new PairTphMethod<>(Position.FIELD, null));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void putPositionInConstructor(String tph, String id) {
|
|
||||||
posOfTphs.put(tph, new PairTphMethod<>(Position.CONSTRUCTOR, id));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static class Walker extends AbstractASTWalker{
|
|
||||||
Boolean inMethod = false;
|
|
||||||
Boolean inConstructor = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(TypePlaceholder tph) {
|
|
||||||
if (inMethod) {
|
|
||||||
if (inConstructor) {
|
|
||||||
// System.out.println(tph);
|
|
||||||
// putPositionInConstructor(tph.getName(),);
|
|
||||||
}
|
|
||||||
// System.out.println(tph);
|
|
||||||
// putPositionInMethod(tph.getName(),);
|
|
||||||
} else {
|
|
||||||
putPositionInField(tph.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Field field) {
|
|
||||||
super.visit(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Method method) {
|
|
||||||
inMethod = true;
|
|
||||||
super.visit(method);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Constructor cons) {
|
|
||||||
inConstructor = true;
|
|
||||||
super.visit(cons);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode.insertGenerics;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
interface preGGenerics {
|
|
||||||
public List<ResultSet> getResultOfTypeInference();
|
|
||||||
}
|
|
@ -1,379 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode.signature;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.signature.SignatureVisitor;
|
|
||||||
import org.objectweb.asm.signature.SignatureWriter;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
|
||||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
|
||||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResult;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.Constructor;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
|
||||||
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.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 Constructor constructor;
|
|
||||||
private Method method;
|
|
||||||
private HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes;
|
|
||||||
private ResultSet resultSet;
|
|
||||||
private Map<TPHConstraint, Set<String>> methodConstraints;
|
|
||||||
private List<GenericsGeneratorResult> consClass;
|
|
||||||
private List<GenericsGeneratorResult> constraints;
|
|
||||||
|
|
||||||
// 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(HashMap<String, String> genericsAndBounds,
|
|
||||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes, ResultSet resultSet,
|
|
||||||
List<GenericsGeneratorResult> constraints) {
|
|
||||||
//this.constructor = constructor;
|
|
||||||
this.genericsAndBounds = genericsAndBounds;
|
|
||||||
this.methodParamsAndTypes = methodParamsAndTypes;
|
|
||||||
this.resultSet = resultSet;
|
|
||||||
this.constraints = constraints;
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
|
||||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes, ResultSet resultSet,
|
|
||||||
List<GenericsGeneratorResult> constraints,List<GenericsGeneratorResult> consClass) {
|
|
||||||
this.genericsAndBoundsMethod = genericsAndBoundsMethod;
|
|
||||||
this.genericsAndBounds = genericsAndBounds;
|
|
||||||
this.methodParamsAndTypes = methodParamsAndTypes;
|
|
||||||
this.resultSet = resultSet;
|
|
||||||
this.constraints = constraints;
|
|
||||||
this.consClass = consClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String createSignatureForConstructor(Constructor constructor) {
|
|
||||||
visitParams();
|
|
||||||
sw.visitReturnType().visitBaseType('V');
|
|
||||||
return sw.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String createSignatureForMethod(Method method) {
|
|
||||||
defineGenerics(method);
|
|
||||||
|
|
||||||
String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
|
|
||||||
|
|
||||||
visitParams();
|
|
||||||
visitReturnType(method, ret);
|
|
||||||
return sw.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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.visitEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void defineTypeVariablesForParametersOfFunN(int numberOfParams) {
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
private void doVisitParamsOrReturn(RefTypeOrTPHOrWildcardOrGeneric t, SignatureVisitor sv) {
|
|
||||||
String type = t.acceptTV(new TypeToString());
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case "RT":
|
|
||||||
String sig = t.acceptTV(new TypeToSignature(constraints));
|
|
||||||
sv.visitClassType(sig.substring(1, sig.length()));
|
|
||||||
break;
|
|
||||||
case "GRT":
|
|
||||||
GenericRefType g = (GenericRefType) t;
|
|
||||||
sv.visitTypeVariable(g.acceptTV(new TypeToSignature(constraints)));
|
|
||||||
break;
|
|
||||||
case "TPH":
|
|
||||||
RefTypeOrTPHOrWildcardOrGeneric r = resultSet.resolveType(t).resolvedType;
|
|
||||||
// der Fall wenn der Typ 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())
|
|
||||||
//
|
|
||||||
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));
|
|
||||||
} 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
} 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "SWC":
|
|
||||||
SuperWildcardType swc = (SuperWildcardType) t;
|
|
||||||
String sigInner = swc.getInnerType().acceptTV(new TypeToSignature(constraints));
|
|
||||||
int length = sigInner.length();
|
|
||||||
visitWildCard(sv, sigInner, length, swc.getInnerType(), SUPER_CHAR);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "EWC":
|
|
||||||
ExtendsWildcardType ewc = (ExtendsWildcardType) t;
|
|
||||||
String esigInner = ewc.getInnerType().acceptTV(new TypeToSignature(constraints));
|
|
||||||
int lengthEWCSig = esigInner.length();
|
|
||||||
visitWildCard(sv, esigInner, lengthEWCSig, ewc.getInnerType(), EXTENDS_CHAR);
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// if (!sv)
|
|
||||||
// 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
|
|
||||||
*/
|
|
||||||
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() {
|
|
||||||
Iterator<GenericTypeVar> itr = classOrInterface.getGenerics().iterator();
|
|
||||||
|
|
||||||
while (itr.hasNext()) {
|
|
||||||
GenericTypeVar g = itr.next();
|
|
||||||
visitTypeVarsAndTheirBounds(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);
|
|
||||||
|
|
||||||
String bound = c.getConstraint().getRight();
|
|
||||||
bound = checkBound(bound);
|
|
||||||
genericsAndBounds2.put(typeVariable, bound);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param bound
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private String checkBound(String bound) {
|
|
||||||
if (bound.equals(Type.getInternalName(Object.class))) {
|
|
||||||
visitClassBound(bound);
|
|
||||||
} else {
|
|
||||||
bound += SPECIAL_CHAR;
|
|
||||||
sw.visitClassBound().visitTypeVariable(bound);
|
|
||||||
}
|
|
||||||
return bound;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param bound
|
|
||||||
*/
|
|
||||||
private void visitClassBound(String bound) {
|
|
||||||
sw.visitClassBound().visitClassType(bound);
|
|
||||||
sw.visitClassBound().visitEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get bounds of type variable
|
|
||||||
*
|
|
||||||
* @param g type variable
|
|
||||||
* @param genAndBounds
|
|
||||||
*/
|
|
||||||
private void visitTypeVarsAndTheirBounds(GenericTypeVar g, HashMap<String, String> genAndBounds) {
|
|
||||||
sw.visitFormalTypeParameter(g.getName());
|
|
||||||
|
|
||||||
Iterator<? extends RefTypeOrTPHOrWildcardOrGeneric> bItr = g.getBounds().iterator();
|
|
||||||
while (bItr.hasNext()) {
|
|
||||||
RefTypeOrTPHOrWildcardOrGeneric b = bItr.next();
|
|
||||||
String boundDesc = b.acceptTV(new TypeToDescriptor());
|
|
||||||
// Ensure that <...> extends java.lang.Object OR ...
|
|
||||||
if (b instanceof GenericRefType) {
|
|
||||||
sw.visitClassBound().visitTypeVariable(boundDesc);
|
|
||||||
} else {
|
|
||||||
visitClassBound(boundDesc);
|
|
||||||
}
|
|
||||||
genAndBounds.put(g.getName(), boundDesc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
if(sw == null)
|
|
||||||
return super.toString();
|
|
||||||
return sw.toString();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,115 +0,0 @@
|
|||||||
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.funN.FunNGenerator;
|
|
||||||
import de.dhbwstuttgart.bytecode.funN.FunNUtilities;
|
|
||||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResult;
|
|
||||||
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.TypeVisitor;
|
|
||||||
|
|
||||||
public class TypeToSignature implements TypeVisitor<String> {
|
|
||||||
private List<GenericsGeneratorResult> constraints;
|
|
||||||
|
|
||||||
private final boolean specializedFunN;
|
|
||||||
|
|
||||||
public TypeToSignature() { this(new ArrayList<>(), true); }
|
|
||||||
|
|
||||||
public TypeToSignature(boolean specializedFunN) { this(new ArrayList<>(), specializedFunN); }
|
|
||||||
|
|
||||||
public TypeToSignature(List<GenericsGeneratorResult> constraints) {
|
|
||||||
this(constraints, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TypeToSignature(List<GenericsGeneratorResult> constraints, boolean specializedFunN){
|
|
||||||
this.constraints = constraints;
|
|
||||||
this.specializedFunN = specializedFunN;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(RefType refType) {
|
|
||||||
if(refType.getName().toString().equals("void"))
|
|
||||||
return "V";
|
|
||||||
if (refType.getName().toString().matches("Fun\\d+\\$\\$") && specializedFunN){
|
|
||||||
FunNUtilities funNUtilities = FunNGenerator.getInstance();
|
|
||||||
return funNUtilities.getSpecializedSignature(funNUtilities.getArguments(refType.getParaList()), funNUtilities.getReturnType(refType.getParaList()));
|
|
||||||
}
|
|
||||||
// return refType.toString().replace(".", "/");
|
|
||||||
String params = "";
|
|
||||||
if(refType.getParaList().size()>0){
|
|
||||||
params += "<";
|
|
||||||
Iterator<RefTypeOrTPHOrWildcardOrGeneric> it = refType.getParaList().iterator();
|
|
||||||
while(it.hasNext()){
|
|
||||||
RefTypeOrTPHOrWildcardOrGeneric param = it.next();
|
|
||||||
// if(param instanceof TypePlaceholder) {
|
|
||||||
// params += "T" + ((TypePlaceholder) param).getName() + "$";
|
|
||||||
// } else if(param instanceof ExtendsWildcardType) {
|
|
||||||
// params += "+" + ((ExtendsWildcardType) param).getInnerType().acceptTV(new TypeToSignature());
|
|
||||||
// } else if(param instanceof SuperWildcardType) {
|
|
||||||
// params += "-" + ((SuperWildcardType) param).getInnerType().acceptTV(new TypeToSignature());
|
|
||||||
// } else {
|
|
||||||
// params += "L"+param.toString().replace(".", "/");
|
|
||||||
// }
|
|
||||||
params += param.acceptTV(new TypeToSignature(constraints));
|
|
||||||
|
|
||||||
if(param instanceof TypePlaceholder)
|
|
||||||
params += ";";
|
|
||||||
}
|
|
||||||
params += ">";
|
|
||||||
}
|
|
||||||
// String t = refType.getName().toString().replace(".", "/");
|
|
||||||
// return t.equals("Fun1")?t+"$$"+params+";":t+params+";";
|
|
||||||
return "L"+refType.getName().toString().replace(".", "/") + params+";";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(SuperWildcardType superWildcardType) {
|
|
||||||
// throw new NotImplementedException();
|
|
||||||
String sig = "-" + superWildcardType.getInnerType().acceptTV(new TypeToSignature(constraints));
|
|
||||||
if(superWildcardType.getInnerType() instanceof TypePlaceholder)
|
|
||||||
sig += ";";
|
|
||||||
return sig;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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 + "$";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(ExtendsWildcardType extendsWildcardType) {
|
|
||||||
// throw new NotImplementedException();
|
|
||||||
String sig = "+" + extendsWildcardType.getInnerType().acceptTV(new TypeToSignature(constraints));
|
|
||||||
if(extendsWildcardType.getInnerType() instanceof TypePlaceholder)
|
|
||||||
sig += ";";
|
|
||||||
return sig;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(GenericRefType genericRefType) {
|
|
||||||
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,38 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode.signature;
|
|
||||||
|
|
||||||
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.SuperWildcardType;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypeVisitor;
|
|
||||||
|
|
||||||
public class TypeToString implements TypeVisitor<String>{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(RefType refType) {
|
|
||||||
return "RT";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(SuperWildcardType superWildcardType) {
|
|
||||||
return "SWC";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(TypePlaceholder typePlaceholder) {
|
|
||||||
return "TPH";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(ExtendsWildcardType extendsWildcardType) {
|
|
||||||
return "EWC";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(GenericRefType genericRefType) {
|
|
||||||
return "GRT";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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,243 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode.utilities;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.ParameterList;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Literal;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
|
||||||
|
|
||||||
public class KindOfLambda implements StatementVisitor{
|
|
||||||
private ParameterList params;
|
|
||||||
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 ArrayList<String> definedLocals = new ArrayList<>();
|
|
||||||
|
|
||||||
public KindOfLambda(LambdaExpression lambdaExpression) {
|
|
||||||
this.params = lambdaExpression.params;
|
|
||||||
lambdaExpression.methodBody.accept(this);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList<String> getUsedVars() {
|
|
||||||
return usedVars;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isInstanceCapturingLambda() {
|
|
||||||
return this.isInstanceCapturingLambda;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<RefTypeOrTPHOrWildcardOrGeneric> getArgumentList() {
|
|
||||||
return argumentList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isThisUsed() {
|
|
||||||
return thisUsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(ArgumentList argumentList) {
|
|
||||||
argumentList.getArguments().forEach(a->a.accept(this));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(LambdaExpression lambdaExpression) {
|
|
||||||
lambdaExpression.params.getFormalparalist().forEach(p->varsFromInnerLambdas.add(p.getName()));
|
|
||||||
lambdaExpression.methodBody.accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Assign assign) {
|
|
||||||
assign.rightSide.accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(BinaryExpr binary) {
|
|
||||||
binary.lexpr.accept(this);
|
|
||||||
binary.rexpr.accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Block block) {
|
|
||||||
for(Statement stmt : block.getStatements()) {
|
|
||||||
stmt.accept(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(CastExpr castExpr) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(EmptyStmt emptyStmt) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(FieldVar fieldVar) {
|
|
||||||
fieldVar.receiver.accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(ForStmt forStmt) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(IfStmt ifStmt) {
|
|
||||||
ifStmt.expr.accept(this);
|
|
||||||
ifStmt.then_block.accept(this);
|
|
||||||
ifStmt.else_block.accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(InstanceOf instanceOf) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@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) {
|
|
||||||
argumentList.add(localVar.getType());
|
|
||||||
if(thisUsed) {
|
|
||||||
usedVars.add(1, localVar.name);
|
|
||||||
} else {
|
|
||||||
usedVars.add(0, localVar.name);
|
|
||||||
}
|
|
||||||
if(!isInstanceCapturingLambda)
|
|
||||||
isInstanceCapturingLambda=true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean contain(ParameterList params2, String name) {
|
|
||||||
Iterator<FormalParameter> itr = params2.iterator();
|
|
||||||
while(itr.hasNext()) {
|
|
||||||
FormalParameter fp = itr.next();
|
|
||||||
if(fp.getName().equals(name))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(LocalVarDecl localVarDecl) {
|
|
||||||
definedLocals.add(localVarDecl.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(NewArray newArray) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(ExpressionReceiver receiver) {
|
|
||||||
receiver.expr.accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(UnaryExpr unaryExpr) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Return aReturn) {
|
|
||||||
aReturn.retexpr.accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(ReturnVoid aReturn) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(StaticClassName staticClassName) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Super aSuper) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(This aThis) {
|
|
||||||
if(!thisUsed) {
|
|
||||||
thisUsed = true;
|
|
||||||
this.argumentList.add(0,aThis.getType());
|
|
||||||
}
|
|
||||||
if(!isInstanceCapturingLambda) {
|
|
||||||
this.isInstanceCapturingLambda = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(WhileStmt whileStmt) {
|
|
||||||
whileStmt.expr.accept(this);
|
|
||||||
whileStmt.loopBlock.accept(this);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(DoStmt whileStmt) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Literal literal) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(AssignToField assignLeftSide) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(AssignToLocal assignLeftSide) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(SuperCall superCall) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode.utilities;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorVisitor;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.ParameterList;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
|
||||||
|
|
||||||
public class Lambda {
|
|
||||||
private LambdaExpression lambdaExpression;
|
|
||||||
|
|
||||||
public Lambda(LambdaExpression lambdaExpression) {
|
|
||||||
this.lambdaExpression = lambdaExpression;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ParameterList getParams() {
|
|
||||||
return lambdaExpression.params;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
|
|
||||||
return lambdaExpression.getReturnType();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String accept(DescriptorVisitor descVisitor) {
|
|
||||||
return descVisitor.visit(this);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
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.constraints.ConstraintSet;
|
|
||||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
|
||||||
import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
|
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultPair;
|
|
||||||
|
|
||||||
public class MethodAndTPH {
|
|
||||||
|
|
||||||
private String id;
|
|
||||||
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<>();
|
|
||||||
/*
|
|
||||||
* its Constraints
|
|
||||||
* eingefuegt PL 2021-02-15
|
|
||||||
*/
|
|
||||||
public final ConstraintSet constraints;
|
|
||||||
|
|
||||||
public MethodAndTPH(String name, ConstraintSet<Pair> constraints) {
|
|
||||||
this.id = name;
|
|
||||||
this.constraints = constraints;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addTph(String tph) {
|
|
||||||
tphs.add(tph);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList<String> getTphs() {
|
|
||||||
return tphs;
|
|
||||||
}
|
|
||||||
|
|
||||||
// public ArrayList<GenericInsertPair> getPairs(){
|
|
||||||
// return pairs;
|
|
||||||
// }
|
|
||||||
public ArrayList<ResultPair<TypePlaceholder, TypePlaceholder>> getPairs(){
|
|
||||||
return pairs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList<String> getLocalTphs() {
|
|
||||||
return localTphs;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode.utilities;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorVisitor;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
|
||||||
|
|
||||||
public class MethodFromMethodCall {
|
|
||||||
private ArgumentList argList;
|
|
||||||
private RefTypeOrTPHOrWildcardOrGeneric returnType;
|
|
||||||
private String receiverName;
|
|
||||||
private HashMap<String, String> genericsAndBoundsMethod;
|
|
||||||
private HashMap<String,String> genericsAndBounds;
|
|
||||||
|
|
||||||
public MethodFromMethodCall(ArgumentList argList,RefTypeOrTPHOrWildcardOrGeneric returnType,
|
|
||||||
String receiverName, HashMap<String, String> genericsAndBoundsMethod,
|
|
||||||
HashMap<String,String> genericsAndBounds) {
|
|
||||||
this.argList = argList;
|
|
||||||
this.returnType = returnType;
|
|
||||||
this.receiverName = receiverName;
|
|
||||||
this.genericsAndBoundsMethod = genericsAndBoundsMethod;
|
|
||||||
this.genericsAndBounds = genericsAndBounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public ArgumentList getArgList() {
|
|
||||||
return argList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
|
|
||||||
return returnType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getReceiverName() {
|
|
||||||
return receiverName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashMap<String, String> getGenericsAndBoundsMethod(){
|
|
||||||
return genericsAndBoundsMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashMap<String,String> getGenericsAndBounds(){
|
|
||||||
return genericsAndBounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String accept(DescriptorVisitor descVisitor) {
|
|
||||||
return descVisitor.visit(this);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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,40 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode.utilities;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorVisitor;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.Constructor;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.ParameterList;
|
|
||||||
|
|
||||||
public class NormalConstructor {
|
|
||||||
private Constructor constructor;
|
|
||||||
private HashMap<String, String> genericsAndBounds;
|
|
||||||
private boolean hasGenerics;
|
|
||||||
|
|
||||||
public NormalConstructor(Constructor constructor, boolean hasGenerics) {
|
|
||||||
this.constructor = constructor;
|
|
||||||
this.hasGenerics = hasGenerics;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NormalConstructor(Constructor constructor, HashMap<String, String> genericsAndBounds, boolean hasGenerics) {
|
|
||||||
this.constructor = constructor;
|
|
||||||
this.genericsAndBounds = genericsAndBounds;
|
|
||||||
this.hasGenerics = hasGenerics;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashMap<String, String> getGenericsAndBounds() {
|
|
||||||
return genericsAndBounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasGen() {
|
|
||||||
return hasGenerics;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ParameterList getParameterList() {
|
|
||||||
return constructor.getParameterList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String accept(DescriptorVisitor descVisitor) {
|
|
||||||
return descVisitor.visit(this);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,56 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode.utilities;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorVisitor;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.ParameterList;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
|
||||||
|
|
||||||
public class NormalMethod {
|
|
||||||
private Method method;
|
|
||||||
private HashMap<String, String> genericsAndBounds;
|
|
||||||
private HashMap<String, String> genericsAndBoundsMethod;
|
|
||||||
private boolean hasGenerics;
|
|
||||||
|
|
||||||
public NormalMethod(Method method, boolean hasGenerics) {
|
|
||||||
this.method = method;
|
|
||||||
this.hasGenerics = hasGenerics;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NormalMethod(Method method, HashMap<String, String> genericsAndBounds,
|
|
||||||
HashMap<String, String> genericsAndBoundsMethod,boolean hasGenerics) {
|
|
||||||
this.method = method;
|
|
||||||
this.genericsAndBounds = genericsAndBounds;
|
|
||||||
this.genericsAndBoundsMethod = genericsAndBoundsMethod;
|
|
||||||
this.hasGenerics = hasGenerics;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Method getMethod() {
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ParameterList getParameterList() {
|
|
||||||
return method.getParameterList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashMap<String, String> getGenericsAndBounds(){
|
|
||||||
return genericsAndBounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashMap<String, String> getGenericsAndBoundsMethod(){
|
|
||||||
return genericsAndBoundsMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
|
|
||||||
return method.getReturnType();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasGen() {
|
|
||||||
return this.hasGenerics;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String accept(DescriptorVisitor descVisitor) {
|
|
||||||
return descVisitor.visit(this);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +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());
|
|
||||||
}
|
|
||||||
|
|
||||||
//ToDo Etienne: Check ob benötigt
|
|
||||||
public RefTypeOrTPHOrWildcardOrGeneric resolve(RefTypeOrTPHOrWildcardOrGeneric type) {
|
|
||||||
return resultSet.resolveType(type).resolvedType;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode.utilities;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorVisitor;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
|
||||||
|
|
||||||
public class SamMethod {
|
|
||||||
private List<RefTypeOrTPHOrWildcardOrGeneric> argumentList;
|
|
||||||
private RefTypeOrTPHOrWildcardOrGeneric returnType;
|
|
||||||
|
|
||||||
public SamMethod(List<RefTypeOrTPHOrWildcardOrGeneric> argumentList, RefTypeOrTPHOrWildcardOrGeneric returnType) {
|
|
||||||
this.argumentList = argumentList;
|
|
||||||
this.returnType = returnType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<RefTypeOrTPHOrWildcardOrGeneric> getArgumentList() {
|
|
||||||
return argumentList;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
|
|
||||||
return returnType;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public String accept(DescriptorVisitor descVisitor) {
|
|
||||||
return descVisitor.visit(this);
|
|
||||||
}
|
|
||||||
}
|
|
@ -36,7 +36,7 @@ public class ConsoleInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
JavaTXCompiler compiler = new JavaTXCompiler(input, classpath);
|
JavaTXCompiler compiler = new JavaTXCompiler(input, classpath);
|
||||||
compiler.typeInference();
|
//compiler.typeInference();
|
||||||
compiler.generateBytecode(outputPath);
|
compiler.generateBytecode(outputPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,11 +2,8 @@
|
|||||||
package de.dhbwstuttgart.core;
|
package de.dhbwstuttgart.core;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import de.dhbwstuttgart.bytecode.BytecodeGen;
|
import de.dhbwstuttgart.bytecode.Codegen;
|
||||||
import de.dhbwstuttgart.bytecode.Exception.BytecodeGeneratorError;
|
|
||||||
import de.dhbwstuttgart.bytecode.genericsGenerator.GeneratedGenericsFinder;
|
|
||||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericGenratorResultForSourceFile;
|
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericGenratorResultForSourceFile;
|
||||||
import de.dhbwstuttgart.bytecode.insertGenerics.FamilyOfGeneratedGenerics;
|
|
||||||
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
||||||
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
||||||
import de.dhbwstuttgart.exceptions.DebugException;
|
import de.dhbwstuttgart.exceptions.DebugException;
|
||||||
@ -21,12 +18,10 @@ import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
|||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
import de.dhbwstuttgart.syntaxtree.ParameterList;
|
import de.dhbwstuttgart.syntaxtree.ParameterList;
|
||||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||||
import de.dhbwstuttgart.syntaxtree.TypeScope;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||||
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
|
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
|
||||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||||
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
|
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Block;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||||
@ -35,6 +30,8 @@ import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
|
|||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypeVisitor;
|
import de.dhbwstuttgart.syntaxtree.type.TypeVisitor;
|
||||||
import de.dhbwstuttgart.syntaxtree.visual.ASTTypePrinter;
|
import de.dhbwstuttgart.syntaxtree.visual.ASTTypePrinter;
|
||||||
|
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||||
|
import de.dhbwstuttgart.target.generate.GenericsResult;
|
||||||
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
||||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||||
@ -48,6 +45,7 @@ import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
|||||||
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
|
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
|
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
|
||||||
|
import de.dhbwstuttgart.util.BiRelation;
|
||||||
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
|
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
|
||||||
import de.dhbwstuttgart.typeinference.unify.UnifyResultListener;
|
import de.dhbwstuttgart.typeinference.unify.UnifyResultListener;
|
||||||
import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl;
|
import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl;
|
||||||
@ -59,16 +57,10 @@ import java.io.FileOutputStream;
|
|||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLClassLoader;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.antlr.v4.runtime.Token;
|
|
||||||
import org.apache.commons.io.output.NullOutputStream;
|
|
||||||
|
|
||||||
|
|
||||||
public class JavaTXCompiler {
|
public class JavaTXCompiler {
|
||||||
|
|
||||||
@ -78,12 +70,7 @@ public class JavaTXCompiler {
|
|||||||
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
||||||
Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+"src/test/java/logFiles" geschrieben werden soll?
|
Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+"src/test/java/logFiles" geschrieben werden soll?
|
||||||
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
||||||
private final ClassLoader classLoader;
|
private final DirectoryClassLoader classLoader;
|
||||||
|
|
||||||
//nur fuer Testzwecke of Generated Generics
|
|
||||||
//wieder loeschen PL 2021-03-22
|
|
||||||
public FamilyOfGeneratedGenerics fogg;
|
|
||||||
|
|
||||||
|
|
||||||
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
|
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
|
||||||
this(Arrays.asList(sourceFile), null);
|
this(Arrays.asList(sourceFile), null);
|
||||||
@ -141,7 +128,8 @@ public class JavaTXCompiler {
|
|||||||
allClasses.addAll(sf.getClasses());
|
allClasses.addAll(sf.getClasses());
|
||||||
}
|
}
|
||||||
allClasses.addAll(importedClasses);
|
allClasses.addAll(importedClasses);
|
||||||
return new TYPE(sourceFiles.values(), allClasses).getConstraints();
|
TYPE ty = new TYPE(sourceFiles.values(), allClasses);
|
||||||
|
return ty.getConstraints();
|
||||||
}
|
}
|
||||||
|
|
||||||
void addMethods(SourceFile sf, ClassOrInterface cl, List<ClassOrInterface> importedClasses, ClassOrInterface objectClass) {
|
void addMethods(SourceFile sf, ClassOrInterface cl, List<ClassOrInterface> importedClasses, ClassOrInterface objectClass) {
|
||||||
@ -739,6 +727,7 @@ public class JavaTXCompiler {
|
|||||||
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm,
|
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm,
|
||||||
usedTasks);
|
usedTasks);
|
||||||
System.out.println("RESULT Final: " + li.getResults());
|
System.out.println("RESULT Final: " + li.getResults());
|
||||||
|
System.out.println("Constraints for Generated Generics: " + " ???");
|
||||||
logFile.write("RES_FINAL: " + li.getResults().toString() + "\n");
|
logFile.write("RES_FINAL: " + li.getResults().toString() + "\n");
|
||||||
logFile.flush();
|
logFile.flush();
|
||||||
return li.getResults();
|
return li.getResults();
|
||||||
@ -767,6 +756,7 @@ public class JavaTXCompiler {
|
|||||||
return x; // wenn nichts veraendert wurde wird x zurueckgegeben
|
return x; // wenn nichts veraendert wurde wird x zurueckgegeben
|
||||||
}).collect(Collectors.toCollection(HashSet::new));
|
}).collect(Collectors.toCollection(HashSet::new));
|
||||||
System.out.println("RESULT Final: " + results);
|
System.out.println("RESULT Final: " + results);
|
||||||
|
System.out.println("Constraints for Generated Generics: " + " ???");
|
||||||
logFile.write("RES_FINAL: " + results.toString() + "\n");
|
logFile.write("RES_FINAL: " + results.toString() + "\n");
|
||||||
logFile.flush();
|
logFile.flush();
|
||||||
logFile.write("PLACEHOLDERS: " + PlaceholderType.EXISTING_PLACEHOLDERS);
|
logFile.write("PLACEHOLDERS: " + PlaceholderType.EXISTING_PLACEHOLDERS);
|
||||||
@ -844,54 +834,15 @@ public class JavaTXCompiler {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateBytecodForFile(File path, HashMap<JavaClassName, byte[]> classFiles, SourceFile sf,
|
|
||||||
List<ResultSet> typeinferenceResult) throws IOException {
|
|
||||||
try {
|
|
||||||
List<GenericGenratorResultForSourceFile> genericResults = getGeneratedGenericResultsForAllSourceFiles(typeinferenceResult);
|
|
||||||
BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult, genericResults, sf,path, classLoader);
|
|
||||||
bytecodeGen.visit(sf);
|
|
||||||
this.writeClassFile(bytecodeGen.getClassFiles(), path);
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public void generateBytecode() throws ClassNotFoundException, IOException {
|
||||||
public List<GenericGenratorResultForSourceFile> getGeneratedGenericResultsForAllSourceFiles()
|
|
||||||
throws ClassNotFoundException, IOException {
|
|
||||||
List<GenericGenratorResultForSourceFile> result = new ArrayList<>();
|
|
||||||
for (File f : sourceFiles.keySet()) {
|
|
||||||
SourceFile sf = sourceFiles.get(f);
|
|
||||||
List<ResultSet> typeinferenceResult = this.typeInference();
|
|
||||||
GeneratedGenericsFinder sResFinder = new GeneratedGenericsFinder(sf, typeinferenceResult);
|
|
||||||
GenericGenratorResultForSourceFile simplifyResOfSF = sResFinder.findGeneratedGenerics();
|
|
||||||
result.add(simplifyResOfSF);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GenericGenratorResultForSourceFile> getGeneratedGenericResultsForAllSourceFiles(
|
|
||||||
List<ResultSet> typeinferenceResult) throws ClassNotFoundException {
|
|
||||||
List<GenericGenratorResultForSourceFile> result = new ArrayList<>();
|
|
||||||
for (File f : sourceFiles.keySet()) {
|
|
||||||
SourceFile sf = sourceFiles.get(f);
|
|
||||||
GeneratedGenericsFinder sResFinder = new GeneratedGenericsFinder(sf, typeinferenceResult);
|
|
||||||
GenericGenratorResultForSourceFile simplifyResOfSF = sResFinder.findGeneratedGenerics();
|
|
||||||
this.fogg = sResFinder.getFogg();
|
|
||||||
result.add(simplifyResOfSF);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void generateBytecode() throws ClassNotFoundException, IOException, BytecodeGeneratorError {
|
|
||||||
generateBytecode((File) null);
|
generateBytecode((File) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param path - can be null, then class file output is in the same directory as the parsed source files
|
* @param path - can be null, then class file output is in the same directory as the parsed source files
|
||||||
*/
|
*/
|
||||||
public void generateBytecode(String path) throws ClassNotFoundException, IOException, BytecodeGeneratorError {
|
public void generateBytecode(String path) throws ClassNotFoundException, IOException {
|
||||||
if(path != null)
|
if(path != null)
|
||||||
generateBytecode(new File(path));
|
generateBytecode(new File(path));
|
||||||
else
|
else
|
||||||
@ -899,23 +850,26 @@ public class JavaTXCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param path - can be null, then class file output is in the same directory as the parsed source files
|
* @param path - output-Directory can be null, then class file output is in the same directory as the parsed source files
|
||||||
*/
|
*/
|
||||||
public void generateBytecode(File path) throws ClassNotFoundException, IOException, BytecodeGeneratorError {
|
public void generateBytecode(File path) throws ClassNotFoundException, IOException {
|
||||||
List<ResultSet> typeinferenceResult = this.typeInference();
|
List<ResultSet> typeinferenceResult = this.typeInference();
|
||||||
List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles = getGeneratedGenericResultsForAllSourceFiles(
|
generateBytecode(path, typeinferenceResult);
|
||||||
typeinferenceResult);
|
}
|
||||||
generateBytecode(path, typeinferenceResult, simplifyResultsForAllSourceFiles);
|
|
||||||
|
private Map<File, List<GenericsResult>> generatedGenerics = new HashMap<>();
|
||||||
|
|
||||||
|
// TODO This is a temporary solution, we should integrate with the old API for getting Generics
|
||||||
|
public Map<File, List<GenericsResult>> getGeneratedGenerics() {
|
||||||
|
return generatedGenerics;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param outputPath - can be null, then class file output is in the same directory as the parsed source files
|
* @param outputPath - can be null, then class file output is in the same directory as the parsed source files
|
||||||
* @param typeinferenceResult
|
* @param typeinferenceResult
|
||||||
* @param simplifyResultsForAllSourceFiles
|
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public void generateBytecode(File outputPath, List<ResultSet> typeinferenceResult,
|
public void generateBytecode(File outputPath, List<ResultSet> typeinferenceResult) throws IOException {
|
||||||
List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles) throws IOException {
|
|
||||||
for (File f : sourceFiles.keySet()) {
|
for (File f : sourceFiles.keySet()) {
|
||||||
HashMap<JavaClassName, byte[]> classFiles = new HashMap<>();
|
HashMap<JavaClassName, byte[]> classFiles = new HashMap<>();
|
||||||
SourceFile sf = sourceFiles.get(f);
|
SourceFile sf = sourceFiles.get(f);
|
||||||
@ -925,10 +879,19 @@ public class JavaTXCompiler {
|
|||||||
}else{
|
}else{
|
||||||
path = new File(outputPath ,sf.getPkgName().replace(".","/")); //add package path to root path
|
path = new File(outputPath ,sf.getPkgName().replace(".","/")); //add package path to root path
|
||||||
}
|
}
|
||||||
BytecodeGen bytecodeGen = new BytecodeGen(classFiles, typeinferenceResult, simplifyResultsForAllSourceFiles,
|
|
||||||
sf, path, classLoader);
|
var converter = new ASTToTargetAST(typeinferenceResult);
|
||||||
bytecodeGen.visit(sf);
|
var generatedClasses = new HashMap<JavaClassName, byte[]>();
|
||||||
writeClassFile(bytecodeGen.getClassFiles(), path);
|
for (var clazz : sf.getClasses()) {
|
||||||
|
var codegen = new Codegen(converter.convert(clazz));
|
||||||
|
var code = codegen.generate();
|
||||||
|
generatedClasses.put(clazz.getClassName(), code);
|
||||||
|
converter.auxiliaries.forEach((name, source) -> {
|
||||||
|
generatedClasses.put(new JavaClassName(name), source);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
generatedGenerics.put(f, converter.computedGenerics());
|
||||||
|
writeClassFile(generatedClasses, path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -948,6 +911,11 @@ public class JavaTXCompiler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<GenericGenratorResultForSourceFile> getGeneratedGenericResultsForAllSourceFiles(List<ResultSet> results) {
|
||||||
|
// FIXME
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/* PL 2020-03-17 mit TypeExchanger in FCGenerator.java zusammenfuehren */
|
/* PL 2020-03-17 mit TypeExchanger in FCGenerator.java zusammenfuehren */
|
||||||
/**
|
/**
|
||||||
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus.
|
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus.
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package de.dhbwstuttgart.environment;
|
||||||
|
|
||||||
|
public class ByteArrayClassLoader extends ClassLoader implements IByteArrayClassLoader {
|
||||||
|
@Override
|
||||||
|
public Class _defineClass(String name, byte[] code, int i, int length) throws ClassFormatError {
|
||||||
|
return defineClass(name, code, i, length);
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,16 @@
|
|||||||
package de.dhbwstuttgart.environment;
|
package de.dhbwstuttgart.environment;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class DirectoryClassLoader extends URLClassLoader {
|
public class DirectoryClassLoader extends URLClassLoader implements IByteArrayClassLoader {
|
||||||
public DirectoryClassLoader(File directory, java.lang.ClassLoader parent) {
|
public DirectoryClassLoader(File directory, java.lang.ClassLoader parent) {
|
||||||
super(generateURLArray(dirToURL(directory)), parent);
|
super(generateURLArray(dirToURL(directory)), parent);
|
||||||
}
|
}
|
||||||
@ -28,4 +31,9 @@ public class DirectoryClassLoader extends URLClassLoader {
|
|||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class _defineClass(String name, byte[] code, int i, int length) throws ClassFormatError {
|
||||||
|
return defineClass(name, code, i, length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package de.dhbwstuttgart.environment;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public interface IByteArrayClassLoader {
|
||||||
|
|
||||||
|
Class loadClass(String path) throws ClassNotFoundException;
|
||||||
|
|
||||||
|
default Class loadClass(byte[] code) {
|
||||||
|
return this._defineClass(null, code, 0, code.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
default Class loadClass(Path path) throws IOException {
|
||||||
|
var code = Files.readAllBytes(path);
|
||||||
|
return this._defineClass(null, code, 0, code.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
Class _defineClass(String name, byte[] code, int i, int length) throws ClassFormatError;
|
||||||
|
}
|
@ -210,12 +210,13 @@ public class StatementGenerator {
|
|||||||
}else throw new NotImplementedException();
|
}else throw new NotImplementedException();
|
||||||
|
|
||||||
ArgumentList argumentList = convert(methodInvocationContext.argumentList());
|
ArgumentList argumentList = convert(methodInvocationContext.argumentList());
|
||||||
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = argumentList.getArguments().stream()
|
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> signature = argumentList.getArguments().stream()
|
||||||
.map(x -> TypePlaceholder.fresh(methodInvocationContext.getStart()))
|
.map(x -> TypePlaceholder.fresh(methodInvocationContext.getStart()))
|
||||||
.collect(Collectors.toCollection(ArrayList::new));
|
.collect(Collectors.toCollection(ArrayList::new));
|
||||||
|
signature.add(TypePlaceholder.fresh(methodInvocationContext.getStart())); //ReturnType
|
||||||
MethodCall ret = new MethodCall(TypePlaceholder.fresh(methodInvocationContext.getStart()),
|
MethodCall ret = new MethodCall(TypePlaceholder.fresh(methodInvocationContext.getStart()),
|
||||||
getReceiver(receiver), name, argumentList, TypePlaceholder.fresh(methodInvocationContext.getStart()),
|
getReceiver(receiver), name, argumentList, TypePlaceholder.fresh(methodInvocationContext.getStart()),
|
||||||
argTypes, methodInvocationContext.getStart());
|
signature, methodInvocationContext.getStart());
|
||||||
ret.setStatement();
|
ret.setStatement();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -302,10 +303,11 @@ public class StatementGenerator {
|
|||||||
RefType newClass = (RefType) TypeGenerator.convertTypeName(identifier.getText(),genericArgs,identifier.getSymbol(),reg,generics);
|
RefType newClass = (RefType) TypeGenerator.convertTypeName(identifier.getText(),genericArgs,identifier.getSymbol(),reg,generics);
|
||||||
|
|
||||||
ArgumentList args = convert(newExpression.argumentList());
|
ArgumentList args = convert(newExpression.argumentList());
|
||||||
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = args.getArguments().stream()
|
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> signature = args.getArguments().stream()
|
||||||
.map(x -> TypePlaceholder.fresh(newExpression.getStart()))
|
.map(x -> TypePlaceholder.fresh(newExpression.getStart()))
|
||||||
.collect(Collectors.toCollection(ArrayList::new));
|
.collect(Collectors.toCollection(ArrayList::new));
|
||||||
Statement ret = new NewClass(newClass, args, null, argTypes, newExpression.getStart());
|
signature.add(TypePlaceholder.fresh(newExpression.getStart())); //ReturnType
|
||||||
|
Statement ret = new NewClass(newClass, args, null, signature, newExpression.getStart());
|
||||||
ret.setStatement();
|
ret.setStatement();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -803,11 +805,12 @@ public class StatementGenerator {
|
|||||||
}else {
|
}else {
|
||||||
Java8Parser.MethodInvocation_lf_primaryContext ctxt = e.methodInvocation_lf_primary();
|
Java8Parser.MethodInvocation_lf_primaryContext ctxt = e.methodInvocation_lf_primary();
|
||||||
String methodName = ctxt.Identifier().toString();
|
String methodName = ctxt.Identifier().toString();
|
||||||
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = ctxt.argumentList().expression().stream()
|
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> signature = ctxt.argumentList().expression().stream()
|
||||||
.map(x -> TypePlaceholder.fresh(e.getStart()))
|
.map(x -> TypePlaceholder.fresh(e.getStart()))
|
||||||
.collect(Collectors.toCollection(ArrayList::new));
|
.collect(Collectors.toCollection(ArrayList::new));
|
||||||
|
signature.add(TypePlaceholder.fresh(e.getStart())); //ReturnType
|
||||||
return new MethodCall(TypePlaceholder.fresh(e.getStart()), getReceiver(expr), methodName,
|
return new MethodCall(TypePlaceholder.fresh(e.getStart()), getReceiver(expr), methodName,
|
||||||
convert(ctxt.argumentList()), TypePlaceholder.fresh(e.getStart()), argTypes, e.getStart());
|
convert(ctxt.argumentList()), TypePlaceholder.fresh(e.getStart()), signature, e.getStart());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -861,10 +864,11 @@ public class StatementGenerator {
|
|||||||
RefType newClass = (RefType) TypeGenerator.convertTypeName(identifier.getText(),genericArgs,identifier.getSymbol(),reg,generics);
|
RefType newClass = (RefType) TypeGenerator.convertTypeName(identifier.getText(),genericArgs,identifier.getSymbol(),reg,generics);
|
||||||
|
|
||||||
ArgumentList args = convert(newExpression.argumentList());
|
ArgumentList args = convert(newExpression.argumentList());
|
||||||
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = args.getArguments().stream()
|
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> signature = args.getArguments().stream()
|
||||||
.map(x -> TypePlaceholder.fresh(newExpression.getStart()))
|
.map(x -> TypePlaceholder.fresh(newExpression.getStart()))
|
||||||
.collect(Collectors.toCollection(ArrayList::new));
|
.collect(Collectors.toCollection(ArrayList::new));
|
||||||
return new NewClass(newClass, args, null, argTypes, newExpression.getStart());
|
signature.add(TypePlaceholder.fresh(newExpression.getStart())); //ReturnType
|
||||||
|
return new NewClass(newClass, args, null, signature, newExpression.getStart());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Expression convert(Java8Parser.LiteralContext literal) {
|
private Expression convert(Java8Parser.LiteralContext literal) {
|
||||||
@ -922,12 +926,13 @@ public class StatementGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ArgumentList argumentList = convert(methodInvocationContext.argumentList());
|
ArgumentList argumentList = convert(methodInvocationContext.argumentList());
|
||||||
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = argumentList.getArguments().stream()
|
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> signature = argumentList.getArguments().stream()
|
||||||
.map(x -> TypePlaceholder.fresh(methodInvocationContext.getStart()))
|
.map(x -> TypePlaceholder.fresh(methodInvocationContext.getStart()))
|
||||||
.collect(Collectors.toCollection(ArrayList::new));
|
.collect(Collectors.toCollection(ArrayList::new));
|
||||||
|
signature.add(TypePlaceholder.fresh(methodInvocationContext.getStart())); //ReturnType
|
||||||
MethodCall ret = new MethodCall(TypePlaceholder.fresh(methodInvocationContext.getStart()),
|
MethodCall ret = new MethodCall(TypePlaceholder.fresh(methodInvocationContext.getStart()),
|
||||||
getReceiver(receiver), name, argumentList, TypePlaceholder.fresh(methodInvocationContext.getStart()),
|
getReceiver(receiver), name, argumentList, TypePlaceholder.fresh(methodInvocationContext.getStart()),
|
||||||
argTypes, methodInvocationContext.getStart());
|
signature, methodInvocationContext.getStart());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,12 +152,12 @@ public class UnifyTypeFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//NEVER USED
|
//NEVER USED
|
||||||
public static Constraint<UnifyPair> convert(Constraint<Pair> constraint){
|
//public static Constraint<UnifyPair> convert(Constraint<Pair> constraint){
|
||||||
Constraint<UnifyPair> unifyPairConstraint = constraint.stream()
|
// Constraint<UnifyPair> unifyPairConstraint = constraint.stream()
|
||||||
.map(UnifyTypeFactory::convert)
|
// .map(UnifyTypeFactory::convert)
|
||||||
.collect(Collectors.toCollection( () -> new Constraint<UnifyPair> (constraint.isInherited(), convert(constraint.getExtendConstraint()))));
|
// .collect(Collectors.toCollection( () -> new Constraint<UnifyPair> (constraint.isInherited(), convert(constraint.getExtendConstraint()))));
|
||||||
return unifyPairConstraint;
|
// return unifyPairConstraint;
|
||||||
}
|
//}
|
||||||
|
|
||||||
public static UnifyPair convert(Pair p) {
|
public static UnifyPair convert(Pair p) {
|
||||||
UnifyPair ret = null;
|
UnifyPair ret = null;
|
||||||
|
@ -25,16 +25,18 @@ public class MethodCall extends Statement
|
|||||||
public final ArgumentList arglist;
|
public final ArgumentList arglist;
|
||||||
|
|
||||||
public RefTypeOrTPHOrWildcardOrGeneric receiverType;
|
public RefTypeOrTPHOrWildcardOrGeneric receiverType;
|
||||||
public final ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes;
|
|
||||||
|
//sind Tphs, repraesentieren im Resultset die Signatur der aufgerufenen Methoden, letztes Element ist der Returntyp
|
||||||
|
public final ArrayList<RefTypeOrTPHOrWildcardOrGeneric> signature;
|
||||||
|
|
||||||
public MethodCall(RefTypeOrTPHOrWildcardOrGeneric retType, Receiver receiver, String methodName, ArgumentList argumentList,
|
public MethodCall(RefTypeOrTPHOrWildcardOrGeneric retType, Receiver receiver, String methodName, ArgumentList argumentList,
|
||||||
RefTypeOrTPHOrWildcardOrGeneric receiverType, ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes, Token offset){
|
RefTypeOrTPHOrWildcardOrGeneric receiverType, ArrayList<RefTypeOrTPHOrWildcardOrGeneric> signature, Token offset){
|
||||||
super(retType,offset);
|
super(retType,offset);
|
||||||
this.arglist = argumentList;
|
this.arglist = argumentList;
|
||||||
this.name = methodName;
|
this.name = methodName;
|
||||||
this.receiver = receiver;
|
this.receiver = receiver;
|
||||||
this.receiverType = receiverType;
|
this.receiverType = receiverType;
|
||||||
this.argTypes = argTypes;
|
this.signature = signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package de.dhbwstuttgart.syntaxtree.type;
|
package de.dhbwstuttgart.syntaxtree.type;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||||
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
|
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
|
||||||
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
||||||
@ -47,6 +48,10 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
|
|||||||
return new TypePlaceholder(NameGenerator.makeNewName(), position);
|
return new TypePlaceholder(NameGenerator.makeNewName(), position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static RefTypeOrTPHOrWildcardOrGeneric of(String name) {
|
||||||
|
return new TypePlaceholder(name, new NullToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Author: J�rg B�uerle<br/>
|
* Author: J�rg B�uerle<br/>
|
||||||
|
@ -271,6 +271,7 @@ public class OutputGenerator implements ASTVisitor{
|
|||||||
public void visit(MethodCall methodCall) {
|
public void visit(MethodCall methodCall) {
|
||||||
methodCall.receiver.accept(this);
|
methodCall.receiver.accept(this);
|
||||||
out.append("."+methodCall.name);
|
out.append("."+methodCall.name);
|
||||||
|
out.append(" Signature: "+methodCall.signature);
|
||||||
methodCall.getArgumentList().accept(this);
|
methodCall.getArgumentList().accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
package de.dhbwstuttgart.target;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
|
|
||||||
public class ByteArrayClassLoader extends ClassLoader {
|
|
||||||
public Class loadClass(byte[] code) {
|
|
||||||
return this.defineClass(null, code, 0, code.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Class loadClass(Path path) throws IOException {
|
|
||||||
var code = Files.readAllBytes(path);
|
|
||||||
return this.defineClass(null, code, 0, code.length);
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
10
src/main/java/de/dhbwstuttgart/target/generate/Bound.java
Normal file
10
src/main/java/de/dhbwstuttgart/target/generate/Bound.java
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package de.dhbwstuttgart.target.generate;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public record Bound(boolean isOnMethod, RefTypeOrTPHOrWildcardOrGeneric bound) {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package de.dhbwstuttgart.target.generate;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
|
|
||||||
|
import java.util.AbstractList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BoundsList extends AbstractList<Bound> {
|
||||||
|
private final List<Bound> bounds;
|
||||||
|
|
||||||
|
public BoundsList(List<Bound> bounds) {
|
||||||
|
this.bounds = bounds;
|
||||||
|
}
|
||||||
|
public BoundsList(Bound... bounds) {
|
||||||
|
this.bounds = List.of(bounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bound get(int index) {
|
||||||
|
return bounds.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return bounds.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
if (!(other instanceof BoundsList right)) return false;
|
||||||
|
if (size() != right.size()) return false;
|
||||||
|
for (var i = 0; i < size(); i++) {
|
||||||
|
var l = get(i);
|
||||||
|
var r = right.get(i);
|
||||||
|
if (l.isOnMethod() != r.isOnMethod()) return false;
|
||||||
|
if (i == size() - 1) {
|
||||||
|
if (!(l.bound() instanceof TypePlaceholder)) {
|
||||||
|
if (!(l.bound().equals(r.bound()))) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
package de.dhbwstuttgart.target.generate;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
|
import de.dhbwstuttgart.typeinference.result.ResultPair;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class GenericsResult {
|
||||||
|
final ASTToTargetAST.Sigma sigma;
|
||||||
|
|
||||||
|
GenericsResult(ASTToTargetAST.Sigma sigma) {
|
||||||
|
this.sigma = sigma;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<ResultPair<?, ?>> get(ClassOrInterface clazz) {
|
||||||
|
var generics = this.sigma.computedGenericsOfClasses.get(clazz);
|
||||||
|
if (generics == null) return Set.of();
|
||||||
|
return generics.txGenerics();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Compute generics if not present?
|
||||||
|
public Set<ResultPair<?, ?>> get(Method method) {
|
||||||
|
var generics = this.sigma.computedGenericsOfMethods.get(method);
|
||||||
|
if (generics == null) return Set.of();
|
||||||
|
return generics.txGenerics();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoundsList getBounds(RefTypeOrTPHOrWildcardOrGeneric type, ClassOrInterface clazz) {
|
||||||
|
return getBounds(type, clazz, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoundsList getBounds(RefTypeOrTPHOrWildcardOrGeneric type, ClassOrInterface clazz, Method method) {
|
||||||
|
type = resolve(type);
|
||||||
|
if (type instanceof TypePlaceholder) {
|
||||||
|
var methodGenerics = get(method);
|
||||||
|
var classGenerics = get(clazz);
|
||||||
|
List<Bound> result = new ArrayList<>();
|
||||||
|
|
||||||
|
Optional<Bound> bound = Optional.empty();
|
||||||
|
do {
|
||||||
|
bound = Optional.empty();
|
||||||
|
for (var pair : methodGenerics) {
|
||||||
|
if (pair.getLeft().equals(type)) {
|
||||||
|
type = resolve(pair.getRight());
|
||||||
|
bound = Optional.of(new Bound(true, type));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bound.isEmpty()) {
|
||||||
|
for (var pair : classGenerics) {
|
||||||
|
if (pair.getLeft().equals(type)) {
|
||||||
|
type = resolve(pair.getRight());
|
||||||
|
bound = Optional.of(new Bound(false, type));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bound.ifPresent(result::add);
|
||||||
|
} while (bound.isPresent());
|
||||||
|
return new BoundsList(result);
|
||||||
|
}
|
||||||
|
return new BoundsList(List.of());
|
||||||
|
}
|
||||||
|
|
||||||
|
public RefTypeOrTPHOrWildcardOrGeneric resolve(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||||
|
if (type instanceof TypePlaceholder tph)
|
||||||
|
return this.sigma.getType(tph);
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
@ -9,10 +9,7 @@ import de.dhbwstuttgart.syntaxtree.statement.*;
|
|||||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||||
import de.dhbwstuttgart.target.tree.MethodParameter;
|
import de.dhbwstuttgart.target.tree.MethodParameter;
|
||||||
import de.dhbwstuttgart.target.tree.expression.*;
|
import de.dhbwstuttgart.target.tree.expression.*;
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetFunNType;
|
import de.dhbwstuttgart.target.tree.type.*;
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetRefType;
|
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetSpecializedType;
|
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -79,7 +76,7 @@ public class StatementToTargetExpression implements StatementVisitor {
|
|||||||
});
|
});
|
||||||
|
|
||||||
result = new TargetLambdaExpression(
|
result = new TargetLambdaExpression(
|
||||||
new TargetFunNType(parameters.size(), parameters.stream().map(MethodParameter::type).toList()),
|
converter.convert(lambdaExpression.getType()),
|
||||||
captures, parameters, converter.convert(lambdaExpression.getReturnType()), converter.convert(lambdaExpression.methodBody)
|
captures, parameters, converter.convert(lambdaExpression.getReturnType()), converter.convert(lambdaExpression.methodBody)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -172,7 +169,7 @@ public class StatementToTargetExpression implements StatementVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static boolean convertsTo(TargetType from, TargetType to) {
|
static boolean convertsTo(TargetType from, TargetType to) {
|
||||||
if (to.equals(TargetType.Object)) return true; // TODO Consider type coercion and suptyping
|
if (to.equals(TargetType.Object)) return true; // TODO Consider type coercion and subtyping
|
||||||
return to.equals(from);
|
return to.equals(from);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,9 +210,10 @@ public class StatementToTargetExpression implements StatementVisitor {
|
|||||||
public void visit(MethodCall methodCall) {
|
public void visit(MethodCall methodCall) {
|
||||||
var receiverType = converter.convert(methodCall.receiver.getType());
|
var receiverType = converter.convert(methodCall.receiver.getType());
|
||||||
var isFunNType = receiverType instanceof TargetFunNType;
|
var isFunNType = receiverType instanceof TargetFunNType;
|
||||||
var returnType = isFunNType ? TargetType.Object : converter.convert(methodCall.getType());
|
var returnType = isFunNType ? TargetType.Object : converter.convert(methodCall.signature.get(methodCall.signature.size() - 1));
|
||||||
var receiverName = new JavaClassName(converter.convert(methodCall.receiver.getType()).name());
|
var receiverName = new JavaClassName(converter.convert(methodCall.receiver.getType()).name());
|
||||||
var argList = methodCall.arglist.getArguments().stream().map(expr -> converter.convert(expr.getType())).toList();
|
var argList = methodCall.signature.stream().map(converter::convert).toList();
|
||||||
|
argList = argList.subList(0, argList.size() - 1);
|
||||||
|
|
||||||
Method foundMethod = null;
|
Method foundMethod = null;
|
||||||
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver && expressionReceiver.expr instanceof This) {
|
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver && expressionReceiver.expr instanceof This) {
|
||||||
@ -306,9 +304,11 @@ public class StatementToTargetExpression implements StatementVisitor {
|
|||||||
public void visit(SuperCall superCall) {
|
public void visit(SuperCall superCall) {
|
||||||
var aSuper = converter.convert(converter.currentClass.getSuperClass());
|
var aSuper = converter.convert(converter.currentClass.getSuperClass());
|
||||||
var type = converter.convert(superCall.getType());
|
var type = converter.convert(superCall.getType());
|
||||||
|
var parameters = superCall.arglist.getArguments().stream().map(par -> converter.convert(par.getType())).toList();
|
||||||
|
|
||||||
result = new TargetMethodCall(
|
result = new TargetMethodCall(
|
||||||
type, type,
|
type, type,
|
||||||
superCall.argTypes == null ? List.of() : superCall.argTypes.stream().map(converter::convert).toList(),
|
parameters,
|
||||||
new TargetSuper(aSuper),
|
new TargetSuper(aSuper),
|
||||||
superCall.getArgumentList().getArguments().stream().map(converter::convert).toList(),
|
superCall.getArgumentList().getArguments().stream().map(converter::convert).toList(),
|
||||||
aSuper,
|
aSuper,
|
||||||
|
@ -22,15 +22,15 @@ public record TargetMethod(int access, String name, Set<TargetGeneric> generics,
|
|||||||
public static String getSignature(Set<TargetGeneric> generics, List<MethodParameter> parameters, TargetType returnType) {
|
public static String getSignature(Set<TargetGeneric> generics, List<MethodParameter> parameters, TargetType returnType) {
|
||||||
String ret = "<";
|
String ret = "<";
|
||||||
for (var generic : generics) {
|
for (var generic : generics) {
|
||||||
ret += generic.name() + ":" + generic.bound().toGenericSignature();
|
ret += generic.name() + ":" + generic.bound().toDescriptor();
|
||||||
}
|
}
|
||||||
ret += ">(";
|
ret += ">(";
|
||||||
for (var param : parameters) {
|
for (var param : parameters) {
|
||||||
ret += param.type().toGenericSignature();
|
ret += param.type().toDescriptor();
|
||||||
}
|
}
|
||||||
ret += ")";
|
ret += ")";
|
||||||
if (returnType == null) ret += "V";
|
if (returnType == null) ret += "V";
|
||||||
else ret += returnType.toGenericSignature();
|
else ret += returnType.toDescriptor();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@ public record TargetExtendsWildcard(TargetType innerType) implements TargetType
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toGenericSignature() {
|
public String toDescriptor() {
|
||||||
return innerType.toGenericSignature();
|
return "+" + innerType.toDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
package de.dhbwstuttgart.target.tree.type;
|
package de.dhbwstuttgart.target.tree.type;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public record TargetFunNType(int N, List<TargetType> params) implements TargetSpecializedType {
|
public record TargetFunNType(int N, List<TargetType> params) implements TargetSpecializedType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getInternalName() {
|
public String getInternalName() {
|
||||||
return "Fun" + N + "$$";
|
return FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -7,7 +7,7 @@ public record TargetGenericType(String name) implements TargetType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toGenericSignature() {
|
public String toDescriptor() {
|
||||||
return "T" + getInternalName() + ";";
|
return "T" + getInternalName() + ";";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ public record TargetPrimitiveType(String name) implements TargetType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toGenericSignature() {
|
public String toDescriptor() {
|
||||||
return toSignature();
|
return toSignature();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,12 +6,12 @@ public sealed interface TargetSpecializedType extends TargetType permits TargetF
|
|||||||
List<TargetType> params();
|
List<TargetType> params();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default String toGenericSignature() {
|
default String toDescriptor() {
|
||||||
String ret = "L" + getInternalName();
|
String ret = "L" + getInternalName();
|
||||||
if (params().size() > 0) {
|
if (params().size() > 0) {
|
||||||
ret += "<";
|
ret += "<";
|
||||||
for (var param : params()) {
|
for (var param : params()) {
|
||||||
ret += param.toGenericSignature();
|
ret += param.toDescriptor();
|
||||||
}
|
}
|
||||||
ret += ">";
|
ret += ">";
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,8 @@ public record TargetSuperWildcard(TargetType innerType) implements TargetType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toGenericSignature() {
|
public String toDescriptor() {
|
||||||
return innerType.toGenericSignature();
|
return "-" + innerType.toDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -53,7 +53,7 @@ public sealed interface TargetType
|
|||||||
}
|
}
|
||||||
|
|
||||||
String toSignature();
|
String toSignature();
|
||||||
String toGenericSignature();
|
String toDescriptor();
|
||||||
String getInternalName();
|
String getInternalName();
|
||||||
String name();
|
String name();
|
||||||
}
|
}
|
||||||
|
@ -6,15 +6,11 @@ import java.util.List;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericGenratorResultForSourceFile;
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericGenratorResultForSourceFile;
|
|
||||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResult;
|
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.syntaxtree.ClassOrInterface;
|
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||||
@ -48,6 +44,7 @@ public class TypeInsertFactory {
|
|||||||
|
|
||||||
private static List<ResultSet> newResults;
|
private static List<ResultSet> newResults;
|
||||||
|
|
||||||
|
|
||||||
public static Set<TypeInsert> createTypeInsertPoints(SourceFile forSourcefile, ResultSet withResults, List<ResultSet> newResults, List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles){
|
public static Set<TypeInsert> createTypeInsertPoints(SourceFile forSourcefile, ResultSet withResults, List<ResultSet> newResults, List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles){
|
||||||
TypeInsertFactory.newResults = newResults;
|
TypeInsertFactory.newResults = newResults;
|
||||||
return new TypeInsertPlacer().getTypeInserts(forSourcefile, withResults, simplifyResultsForAllSourceFiles);
|
return new TypeInsertPlacer().getTypeInserts(forSourcefile, withResults, simplifyResultsForAllSourceFiles);
|
||||||
@ -85,8 +82,6 @@ public class TypeInsertFactory {
|
|||||||
private static synchronized Set<TypeInsertPoint> createGenericInsert(List<GenericsGeneratorResult> methodConstraints, List<GenericsGeneratorResult> classConstraints,ClassOrInterface cl, Method m, ResultSet resultSet, Token mOffset){
|
private static synchronized Set<TypeInsertPoint> createGenericInsert(List<GenericsGeneratorResult> methodConstraints, List<GenericsGeneratorResult> classConstraints,ClassOrInterface cl, Method m, ResultSet resultSet, Token mOffset){
|
||||||
Set<TypeInsertPoint> result = createGenericClassInserts(classConstraints, cl);
|
Set<TypeInsertPoint> result = createGenericClassInserts(classConstraints, cl);
|
||||||
|
|
||||||
Resolver resolver = new Resolver(resultSet);
|
|
||||||
|
|
||||||
if (m != null) {
|
if (m != null) {
|
||||||
//List<GenericsGeneratorResult> methodConstraints = genericResult.getMethodConstraintsByID(MethodUtility.createID(resolver, m));
|
//List<GenericsGeneratorResult> methodConstraints = genericResult.getMethodConstraintsByID(MethodUtility.createID(resolver, m));
|
||||||
result.addAll(createMethodConstraints(methodConstraints, m.getOffset() != null ? m.getOffset() : mOffset));
|
result.addAll(createMethodConstraints(methodConstraints, m.getOffset() != null ? m.getOffset() : mOffset));
|
||||||
|
@ -3,8 +3,6 @@ package de.dhbwstuttgart.typedeployment;
|
|||||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericGenratorResultForSourceFile;
|
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericGenratorResultForSourceFile;
|
||||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResult;
|
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResult;
|
||||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResultForClass;
|
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResultForClass;
|
||||||
import de.dhbwstuttgart.bytecode.utilities.MethodUtility;
|
|
||||||
import de.dhbwstuttgart.bytecode.utilities.Resolver;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
@ -48,8 +46,6 @@ class TypeInsertPlacerClass extends AbstractASTWalker{
|
|||||||
public final Set<TypeInsert> inserts = new HashSet<>();
|
public final Set<TypeInsert> inserts = new HashSet<>();
|
||||||
private Method method;
|
private Method method;
|
||||||
|
|
||||||
private Resolver resolver;
|
|
||||||
|
|
||||||
List<GenericsGeneratorResult> constraints;
|
List<GenericsGeneratorResult> constraints;
|
||||||
List<GenericsGeneratorResult> classConstraints;
|
List<GenericsGeneratorResult> classConstraints;
|
||||||
|
|
||||||
@ -58,15 +54,13 @@ class TypeInsertPlacerClass extends AbstractASTWalker{
|
|||||||
this.method = null;
|
this.method = null;
|
||||||
this.results = withResults;
|
this.results = withResults;
|
||||||
this.generatedGenerics = generatedGenerics;
|
this.generatedGenerics = generatedGenerics;
|
||||||
resolver = new Resolver(withResults); //PL 2020-04-12 Ob das stimmt weiss ich nicht
|
|
||||||
forClass.accept(this);
|
forClass.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Method method) {
|
public void visit(Method method) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
String id = MethodUtility.createID(resolver, method);
|
//constraints = generatedGenerics.getMethodConstraintsByID(id);
|
||||||
constraints = generatedGenerics.getMethodConstraintsByID(id);
|
|
||||||
classConstraints = generatedGenerics.getClassConstraints();
|
classConstraints = generatedGenerics.getClassConstraints();
|
||||||
if(method.getReturnType() instanceof TypePlaceholder)
|
if(method.getReturnType() instanceof TypePlaceholder)
|
||||||
inserts.add(TypeInsertFactory.createInsertPoints(
|
inserts.add(TypeInsertFactory.createInsertPoints(
|
||||||
|
@ -39,6 +39,14 @@ public class MethodAssumption extends Assumption{
|
|||||||
return receiver;
|
return receiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
|
||||||
|
return retType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<? extends RefTypeOrTPHOrWildcardOrGeneric> getArgTypes(){
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
public RefTypeOrTPHOrWildcardOrGeneric getReturnType(GenericsResolver resolver) {
|
public RefTypeOrTPHOrWildcardOrGeneric getReturnType(GenericsResolver resolver) {
|
||||||
return resolver.resolve(retType);
|
return resolver.resolve(retType);
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,11 @@ public class Constraint<A> extends HashSet<A> {
|
|||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private Boolean isInherited = false;//wird nur für die Method-Constraints benoetigt
|
private Boolean isInherited = false;//wird nur für die Method-Constraints benoetigt
|
||||||
|
|
||||||
/* es darf kein Constraint für den Return-Type erstellt werden, sonst gibt
|
/*
|
||||||
* es Probleme beim Generated Generics
|
* wird verwendet um bei der Codegenerierung die richtige Methoden - Signatur
|
||||||
|
* auszuwaehlen
|
||||||
*/
|
*/
|
||||||
public boolean isStatement = false;
|
/*private*/ Set<A> methodSignatureConstraint = new HashSet<>();
|
||||||
|
|
||||||
private Constraint<A> extendConstraint = null;
|
private Constraint<A> extendConstraint = null;
|
||||||
|
|
||||||
@ -25,9 +26,10 @@ public class Constraint<A> extends HashSet<A> {
|
|||||||
this.isInherited = isInherited;
|
this.isInherited = isInherited;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Constraint(Boolean isInherited, Constraint<A> extendConstraint) {
|
public Constraint(Boolean isInherited, Constraint<A> extendConstraint, Set<A> methodSignatureConstraint) {
|
||||||
this.isInherited = isInherited;
|
this.isInherited = isInherited;
|
||||||
this.extendConstraint = extendConstraint;
|
this.extendConstraint = extendConstraint;
|
||||||
|
this.methodSignatureConstraint = methodSignatureConstraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIsInherited(Boolean isInherited) {
|
public void setIsInherited(Boolean isInherited) {
|
||||||
@ -46,8 +48,16 @@ public class Constraint<A> extends HashSet<A> {
|
|||||||
extendConstraint = c;
|
extendConstraint = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<A> getmethodSignatureConstraint() {
|
||||||
|
return methodSignatureConstraint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setmethodSignatureConstraint(Set<A> c) {
|
||||||
|
methodSignatureConstraint = c;
|
||||||
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString() + "\nisInherited = " + isInherited + "\nisStatement = " + isStatement
|
return super.toString() + "\nisInherited = " + isInherited
|
||||||
//" + extendsContraint: " + (extendConstraint != null ? extendConstraint.toStringBase() : "null" )
|
//" + extendsContraint: " + (extendConstraint != null ? extendConstraint.toStringBase() : "null" )
|
||||||
+ "\n" ;
|
+ "\n" ;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,8 @@ public class ConstraintSet<A> {
|
|||||||
.map(o)
|
.map(o)
|
||||||
.collect(Collectors.toCollection((as.getExtendConstraint() != null)
|
.collect(Collectors.toCollection((as.getExtendConstraint() != null)
|
||||||
? () -> new Constraint<B> (as.isInherited(),
|
? () -> new Constraint<B> (as.isInherited(),
|
||||||
as.getExtendConstraint().stream().map(o).collect(Collectors.toCollection(Constraint::new)))
|
as.getExtendConstraint().stream().map(o).collect(Collectors.toCollection(Constraint::new)),
|
||||||
|
as.getmethodSignatureConstraint().stream().map(o).collect(Collectors.toCollection(HashSet::new)))
|
||||||
: () -> new Constraint<B> (as.isInherited())
|
: () -> new Constraint<B> (as.isInherited())
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ public class Pair implements Serializable
|
|||||||
public final RefTypeOrTPHOrWildcardOrGeneric TA2;
|
public final RefTypeOrTPHOrWildcardOrGeneric TA2;
|
||||||
|
|
||||||
private PairOperator eOperator = PairOperator.SMALLER;
|
private PairOperator eOperator = PairOperator.SMALLER;
|
||||||
|
private Boolean noUnification = false;
|
||||||
|
|
||||||
|
|
||||||
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2 )
|
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2 )
|
||||||
@ -32,6 +33,15 @@ public class Pair implements Serializable
|
|||||||
this.eOperator = eOp;
|
this.eOperator = eOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp, Boolean noUnification)
|
||||||
|
{
|
||||||
|
// Konstruktor
|
||||||
|
this(TA1,TA2);
|
||||||
|
this.eOperator = eOp;
|
||||||
|
this.noUnification = noUnification;
|
||||||
|
}
|
||||||
|
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
// otth: Gibt ein Paar als String aus --> zum Debuggen und Vergleichen
|
// otth: Gibt ein Paar als String aus --> zum Debuggen und Vergleichen
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user