forked from JavaTX/JavaCompilerCore
Compare commits
82 Commits
unif23NoOp
...
inferWildc
Author | SHA1 | Date | |
---|---|---|---|
|
26ae463e96 | ||
|
2e1e69df9a | ||
|
0e8012c132 | ||
|
68394565b5 | ||
|
c3b17a8f2f | ||
|
423cf8b9d2 | ||
|
87fb9e5a33 | ||
|
df6debec4f | ||
|
59177e09ad | ||
|
a9281a0db2 | ||
|
fe36b34a80 | ||
|
d3a18887c3 | ||
|
14821575bd | ||
|
c1519783ba | ||
|
53bbf3c511 | ||
|
41492e53ca | ||
|
74b9b024ee | ||
|
97483714e7 | ||
|
a7b9c2a4ee | ||
|
fd7628cb40 | ||
|
76a291ab41 | ||
|
c5c8ffeed1 | ||
|
ba9335e2f6 | ||
|
c098a0a1b0 | ||
|
cfce2f55ac | ||
|
4009a28333 | ||
|
f3dc0cbeb7 | ||
|
cd2f030ac6 | ||
|
f548548788 | ||
|
5cf41101bf | ||
|
e139f8c867 | ||
|
5a151a965c | ||
|
e5f03369cc | ||
|
f698c967c0 | ||
|
1509e21214 | ||
|
50c05064c7 | ||
|
6458a06293 | ||
|
a984e455e4 | ||
|
19c9f648a8 | ||
|
077bd62b92 | ||
|
de62df00e0 | ||
|
78e3b76dc3 | ||
|
c627f9de60 | ||
|
ff92807b83 | ||
|
1043b3f55f | ||
|
88440b873a | ||
|
4ca0e1e5f6 | ||
|
cb28405fe1 | ||
|
c7f91724a6 | ||
|
11b63e0a5d | ||
|
5f7829191c | ||
|
044d9a1860 | ||
|
6fcbca1187 | ||
|
572f41ffd4 | ||
|
e0f7f95bed | ||
|
78c365a7be | ||
|
bea072689b | ||
|
81697eee64 | ||
|
c474abd2bd | ||
|
6dd02a654b | ||
|
e5d5376ce9 | ||
|
0cdeee9e0d | ||
|
98b3ad1517 | ||
|
b59aabeea5 | ||
|
26953665c9 | ||
|
465f82e967 | ||
|
ce8b19acae | ||
|
7dfe546999 | ||
|
c96c56e882 | ||
|
3e57a64f9c | ||
|
e8539a84fd | ||
|
0551d25fbf | ||
|
cbe2d7b0f5 | ||
|
59b45b5f87 | ||
|
ad7e7ec42b | ||
|
9d2c85d686 | ||
|
63b4dbcc10 | ||
|
ca816fba85 | ||
|
54a2dbfedc | ||
|
07c1eeeb36 | ||
|
69a557f1f2 | ||
|
88175f8b48 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -29,3 +29,4 @@ logFiles/**
|
|||||||
|
|
||||||
src/main/java/de/dhbwstuttgart/parser/antlr/
|
src/main/java/de/dhbwstuttgart/parser/antlr/
|
||||||
src/main/java/de/dhbwstuttgart/sat/asp/parser/antlr/
|
src/main/java/de/dhbwstuttgart/sat/asp/parser/antlr/
|
||||||
|
/pull.sh
|
||||||
|
3
Makefile
3
Makefile
@@ -1,3 +0,0 @@
|
|||||||
NoOptParallel:
|
|
||||||
mvn -DskipTests package
|
|
||||||
cp target/JavaTXcompiler-0.1-jar-with-dependencies.jar target/JavaTXcompiler-0.1-jar-with-dependencies_NoOptParallel.jar
|
|
@@ -1,6 +1,5 @@
|
|||||||
Stand: 24.5.21
|
Stand: 24.5.21
|
||||||
bigRefactoring: Master-Brach
|
bigRefactoring: Master-Brach
|
||||||
targetBytecode: Neuer Codegenerator mit generated generics Daniel
|
|
||||||
bigRefactoringUnifyComment: Dokumentation Unify, Martin
|
bigRefactoringUnifyComment: Dokumentation Unify, Martin
|
||||||
bytecodeGenericsSecond: Generated Generics, Ali, Martin
|
bytecodeGenericsSecond: Generated Generics, Ali, Martin
|
||||||
inferWildcards, Wildcards, Till
|
inferWildcards, Wildcards, Till
|
||||||
|
Binary file not shown.
60
pom.xml
60
pom.xml
@@ -17,11 +17,10 @@ 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.11.1</version>
|
<version>4.8-1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
@@ -44,44 +43,60 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
|||||||
<artifactId>asm</artifactId>
|
<artifactId>asm</artifactId>
|
||||||
<version>7.0</version>
|
<version>7.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- <dependency> <groupId>org.ow2.asm</groupId> <artifactId>asm-all</artifactId>
|
||||||
|
<version>[4.0.0,)</version> </dependency> -->
|
||||||
|
<!-- <dependency> <groupId>org.bitbucket.mstrobel</groupId> <artifactId>procyon-reflection</artifactId>
|
||||||
|
<version>[0.5.32,)</version> </dependency> -->
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
<directory>target</directory>
|
||||||
|
<outputDirectory>target/classes</outputDirectory>
|
||||||
|
<finalName>${project.artifactId}-${project.version}</finalName>
|
||||||
|
<testOutputDirectory>target/test-classes</testOutputDirectory>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>3.8.0</version>
|
<version>3.0.0-M3</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<compilerArgs>--enable-preview</compilerArgs>
|
<skipTests>true</skipTests>
|
||||||
<source>19</source>
|
|
||||||
<target>19</target>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<!-- plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<configuration>
|
||||||
|
<verbose>true</verbose>
|
||||||
|
<fork>true</fork>
|
||||||
|
<executable>/home/michael/programs/jdk/jdk8u232-b09/bin/javac</executable>
|
||||||
|
<compilerVersion>1.8</compilerVersion>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin -->
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.antlr</groupId>
|
<groupId>org.antlr</groupId>
|
||||||
<artifactId>antlr4-maven-plugin</artifactId>
|
<artifactId>antlr4-maven-plugin</artifactId>
|
||||||
<version>4.11.1</version>
|
<version>4.8-1</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>antlr</id>
|
<id>antlr</id>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>antlr4</goal>
|
<goal>antlr4</goal>
|
||||||
</goals>
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<sourceDirectory>src/main/antlr4/java8</sourceDirectory>
|
||||||
|
<outputDirectory>${project.basedir}/src/main/java/de/dhbwstuttgart/parser/antlr</outputDirectory>
|
||||||
|
<arguments>
|
||||||
|
<argument>-package</argument>
|
||||||
|
<argument>de.dhbwstuttgart.parser.antlr</argument>
|
||||||
|
</arguments>
|
||||||
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifest>
|
|
||||||
<mainClass>de.dhbwstuttgart.core.ConsoleInterface</mainClass>
|
|
||||||
</manifest>
|
|
||||||
</archive>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
<executions>
|
<executions>
|
||||||
@@ -112,8 +127,11 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
|||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>19</maven.compiler.source>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<maven.compiler.target>19</maven.compiler.target>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
<tycho.version>0.23.0</tycho.version>
|
||||||
<mainClass>de.dhbwstuttgart.core.ConsoleInterface</mainClass>
|
<mainClass>de.dhbwstuttgart.core.ConsoleInterface</mainClass>
|
||||||
</properties>
|
</properties>
|
||||||
<distributionManagement>
|
<distributionManagement>
|
||||||
|
@@ -1,10 +0,0 @@
|
|||||||
class Assign {
|
|
||||||
|
|
||||||
assign(x, y) {
|
|
||||||
x = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
assign2(x, y) {
|
|
||||||
assign(x,y);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,13 +0,0 @@
|
|||||||
class Box<A>{
|
|
||||||
void m(A a){}
|
|
||||||
}
|
|
||||||
|
|
||||||
class B { }
|
|
||||||
|
|
||||||
class Box_Main extends B {
|
|
||||||
|
|
||||||
m(b) {
|
|
||||||
b.m(new Box_Main());
|
|
||||||
b.m(new B());
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,13 +0,0 @@
|
|||||||
class Box<A>{
|
|
||||||
A f;
|
|
||||||
}
|
|
||||||
|
|
||||||
class B { }
|
|
||||||
|
|
||||||
class Box_Main extends B {//Fehler Bugzilla Bug 230
|
|
||||||
|
|
||||||
m(b) {
|
|
||||||
b.f = new Box_Main();
|
|
||||||
b.f = new B();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,18 +0,0 @@
|
|||||||
import java.lang.Object;
|
|
||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
class CaptureConversion {
|
|
||||||
|
|
||||||
<X> void assign(Vector<X> v1, Vector<X> v2) {
|
|
||||||
v1 = v2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
Vector<?> v1;
|
|
||||||
v1 = new Vector<Object>();
|
|
||||||
Vector<? extends Object> v2;
|
|
||||||
v2 = new Vector<Object>();
|
|
||||||
v1 = v2;
|
|
||||||
assign(v1, v2);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,7 +0,0 @@
|
|||||||
import java.util.List;
|
|
||||||
class M {
|
|
||||||
void m(p, p2){
|
|
||||||
|
|
||||||
new addList().addLists(p, p2);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,36 +0,0 @@
|
|||||||
import java.util.Vector;
|
|
||||||
import java.lang.Boolean;
|
|
||||||
import java.lang.Object;
|
|
||||||
|
|
||||||
class Pair<U, T> {
|
|
||||||
U a;
|
|
||||||
T b;
|
|
||||||
|
|
||||||
make(x) {
|
|
||||||
var ret = new Pair<>();
|
|
||||||
ret.a = x.elementAt(0);
|
|
||||||
ret.b = x.elementAt(1);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
eq(a, b) {
|
|
||||||
b = a;
|
|
||||||
return a == b;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
compare( p) {
|
|
||||||
return eq(p.a, p.b);
|
|
||||||
//return p.a == p.b;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
void m(Pair<?, ?> p, Vector<?> b)
|
|
||||||
{
|
|
||||||
//this.compare(p); //1, type incorrect
|
|
||||||
this.compare(this.make(b)); //2, OK
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
@@ -1,19 +0,0 @@
|
|||||||
import java.util.Vector;
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
class Put {
|
|
||||||
|
|
||||||
putElement(ele, v) {
|
|
||||||
v.addElement(ele);
|
|
||||||
}
|
|
||||||
|
|
||||||
putElement(ele, s) {
|
|
||||||
s.push(ele);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
main(ele, x) {
|
|
||||||
putElement(ele, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
class Test {
|
|
||||||
a;
|
|
||||||
Test b;
|
|
||||||
}
|
|
@@ -1,12 +0,0 @@
|
|||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
class TestSubTypless {
|
|
||||||
m(a){
|
|
||||||
var l = new ArrayList<>();
|
|
||||||
l.add(a);
|
|
||||||
return m2(l).get(0);
|
|
||||||
}
|
|
||||||
m2(a){
|
|
||||||
return m(a);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,3 +0,0 @@
|
|||||||
class Twice {
|
|
||||||
twice = f -> x -> f.apply(f.apply(x));
|
|
||||||
}
|
|
@@ -1,12 +0,0 @@
|
|||||||
import java.util.Vector;
|
|
||||||
import java.lang.Boolean;
|
|
||||||
|
|
||||||
class UseWildcardPair{
|
|
||||||
|
|
||||||
void m(Pair<?, ?> p, Vector<?> b)
|
|
||||||
{
|
|
||||||
p.compare(p); //1, type incorrect
|
|
||||||
p.compare(p.make(b)); //2, OK
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
class Var {
|
|
||||||
|
|
||||||
var(x) { var y; }
|
|
||||||
|
|
||||||
}
|
|
@@ -1,15 +0,0 @@
|
|||||||
import java.util.Vector;
|
|
||||||
import java.lang.Integer;
|
|
||||||
|
|
||||||
|
|
||||||
public class VectorConstAdd {
|
|
||||||
vectorAdd(v1) {
|
|
||||||
var i = 0;
|
|
||||||
var erg = new Vector<>();
|
|
||||||
while (i < v1.size()) {
|
|
||||||
erg.addElement(v1.elementAt(i) + 1);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return erg;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,9 +0,0 @@
|
|||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
class VectorNotObject {
|
|
||||||
|
|
||||||
vectorAddAll(v1, v2) {
|
|
||||||
v1.addAll(v2);
|
|
||||||
return v1;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,16 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,8 +0,0 @@
|
|||||||
class Wildcard_Andi {
|
|
||||||
|
|
||||||
Test<? extends A> ex = new Test<>();
|
|
||||||
|
|
||||||
Test<? super A> sup = new Test<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@@ -1,8 +0,0 @@
|
|||||||
import java.util.List;
|
|
||||||
|
|
||||||
class addList {
|
|
||||||
addLists(a, b){
|
|
||||||
a.add(b.get(0));
|
|
||||||
b.add(a.get(0));
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,22 +0,0 @@
|
|||||||
import java.util.List;
|
|
||||||
import java.lang.Integer;
|
|
||||||
import java.lang.Object;
|
|
||||||
import java.lang.Boolean;
|
|
||||||
|
|
||||||
class wildcardPair {
|
|
||||||
|
|
||||||
make(l) {
|
|
||||||
var p = new Pair(l.get(0), l.get(1));
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
//<X>Boolean compare(Pair<X, X> x) { return true; }
|
|
||||||
void m(l) {
|
|
||||||
Object o = l.get(0);
|
|
||||||
|
|
||||||
//Pair<? extends Object, ? extends Object> p;
|
|
||||||
//List<?> b;
|
|
||||||
//this.compare(p); //1, type incorrect
|
|
||||||
make(l);
|
|
||||||
//this.compare(this.make(b)); //2, OK
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,7 +0,0 @@
|
|||||||
class B { }
|
|
||||||
class Box_Main extends B {
|
|
||||||
m(b) {
|
|
||||||
b.m(new Box_Main());
|
|
||||||
b.m(new B());
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,3 +0,0 @@
|
|||||||
class Box<A> {
|
|
||||||
void m(A a) { }
|
|
||||||
}
|
|
@@ -1,6 +0,0 @@
|
|||||||
class Cycle {
|
|
||||||
m(x, y) {
|
|
||||||
y = x;
|
|
||||||
x = y;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,7 +0,0 @@
|
|||||||
import java.lang.String;
|
|
||||||
import java.lang.Integer;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
class Generics3<B extends String & List<Integer>> {
|
|
||||||
|
|
||||||
}
|
|
@@ -1,12 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,65 +0,0 @@
|
|||||||
public class Inf {
|
|
||||||
m(x,y,a){
|
|
||||||
var z;
|
|
||||||
var v;
|
|
||||||
var w;
|
|
||||||
var b;
|
|
||||||
y=x;
|
|
||||||
z=x;
|
|
||||||
v=y;
|
|
||||||
w=y;
|
|
||||||
y=a;
|
|
||||||
b=a;
|
|
||||||
var c;
|
|
||||||
var d;
|
|
||||||
c = v;
|
|
||||||
d = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
TPH M m(TPH N x, TPH O y, TPH P a)({
|
|
||||||
TPH Q z;
|
|
||||||
TPH R v;
|
|
||||||
TPH S w;
|
|
||||||
TPH T b;
|
|
||||||
(y)::TPH O = (x)::TPH N;
|
|
||||||
(z)::TPH Q = (x)::TPH N;
|
|
||||||
(v)::TPH R = (y)::TPH O;
|
|
||||||
(w)::TPH S = (y)::TPH O;
|
|
||||||
(y)::TPH O = (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;
|
|
||||||
})::TPH W
|
|
||||||
|
|
||||||
Inf()({
|
|
||||||
super(());
|
|
||||||
})::TPH Z
|
|
||||||
|
|
||||||
}
|
|
||||||
// c::U d::V
|
|
||||||
// \ /
|
|
||||||
// v::R w::S
|
|
||||||
// \ /
|
|
||||||
// z::Q y::O b::T
|
|
||||||
// \ / \ /
|
|
||||||
// x::N a::P
|
|
||||||
|
|
||||||
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)]
|
|
||||||
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: []
|
|
||||||
Inf: []
|
|
||||||
|
|
||||||
Unify nach Oder-Constraints-Anpassung:
|
|
||||||
UND:[(void =. M, , -1 WC: false, IT: false), (N <. O, 1 WC: false, IT: false, 1 WC: false, IT: false), (P <. O, 1 WC: false, IT: false, 1 WC: false, IT: false), (N <. Q, 1 WC: false, IT: false, 0 WC: true, IT: false), (O <. S, 1 WC: false, IT: false, 0 WC: true, IT: false), (O <. R, 1 WC: false, IT: false, 0 WC: true, IT: false), (P <. T, 1 WC: false, IT: false, 0 WC: true, IT: false)]
|
|
||||||
isInherited = false
|
|
||||||
isStatement = false
|
|
||||||
|
|
||||||
ODER:
|
|
||||||
*/
|
|
||||||
|
|
@@ -1,6 +0,0 @@
|
|||||||
class Infimum {
|
|
||||||
m(x, y, z) {
|
|
||||||
y = x;
|
|
||||||
z = x;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,13 +0,0 @@
|
|||||||
import java.lang.String;
|
|
||||||
import java.lang.Integer;
|
|
||||||
import java.lang.Double;
|
|
||||||
import java.util.Vector;
|
|
||||||
import java.lang.Boolean;
|
|
||||||
|
|
||||||
public class OLFun2 {
|
|
||||||
|
|
||||||
x;
|
|
||||||
m(f){
|
|
||||||
x = f.apply(x + x);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,32 +0,0 @@
|
|||||||
import java.util.Vector;
|
|
||||||
import java.lang.Boolean;
|
|
||||||
import java.lang.Object;
|
|
||||||
|
|
||||||
class Pair<U, T> {
|
|
||||||
U a;
|
|
||||||
T b;
|
|
||||||
|
|
||||||
make(x) {
|
|
||||||
var ret = new Pair<>();
|
|
||||||
ret.a = x.elementAt(0);
|
|
||||||
ret.b = x.elementAt(1);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
eq(a, b) {
|
|
||||||
b = a;
|
|
||||||
return a == b;
|
|
||||||
}
|
|
||||||
|
|
||||||
compare( p) {
|
|
||||||
return eq(p.a, p.b);
|
|
||||||
//return p.a == p.b;
|
|
||||||
}
|
|
||||||
|
|
||||||
void m(Pair<?, ?> p, List<? extends Eq> b)
|
|
||||||
{
|
|
||||||
//this.compare(p); //1, type incorrect
|
|
||||||
this.compare(this.make(b)); //2, OK
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
@@ -1,17 +0,0 @@
|
|||||||
//import java.util.Vector;
|
|
||||||
import java.lang.Integer;
|
|
||||||
import java.lang.Float;
|
|
||||||
//import java.lang.Byte;
|
|
||||||
//import java.lang.Boolean;
|
|
||||||
|
|
||||||
public class Scalar extends Vector<Integer> {
|
|
||||||
|
|
||||||
mul(v) {
|
|
||||||
var ret = 0;
|
|
||||||
var i = 0;
|
|
||||||
while(i < size()) {
|
|
||||||
ret = ret + this.elementAt(i) * v.elementAt(i);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,11 +0,0 @@
|
|||||||
public class Tph7 {
|
|
||||||
|
|
||||||
m(a,b){
|
|
||||||
var c = m2(b);
|
|
||||||
return m2(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
m2(b){
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,26 +0,0 @@
|
|||||||
import java.util.Vector;
|
|
||||||
import java.lang.Integer;
|
|
||||||
import java.lang.String;
|
|
||||||
|
|
||||||
public class VectorAdd {
|
|
||||||
vectorAdd(v1, v2) {
|
|
||||||
var i = 0;
|
|
||||||
v1 = new Vector<Integer>();
|
|
||||||
var erg = new Vector<>();
|
|
||||||
while (i < v1.size()) {
|
|
||||||
erg.addElement(v1.elementAt(i) + v2.elementAt(i));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
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,9 +0,0 @@
|
|||||||
class TestAssign {
|
|
||||||
assign(x, y) {
|
|
||||||
x = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
assign2(x, y) {
|
|
||||||
assign(x, y);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,13 +0,0 @@
|
|||||||
class Box<A> {
|
|
||||||
A f;
|
|
||||||
}
|
|
||||||
class B {
|
|
||||||
}
|
|
||||||
|
|
||||||
class Box_Main extends B {
|
|
||||||
|
|
||||||
m(b) {
|
|
||||||
b.f = new Box_Main();
|
|
||||||
b.f = new B();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
class C<A>{
|
|
||||||
A f;
|
|
||||||
m(b, c){
|
|
||||||
c.f = b;
|
|
||||||
c.m(b, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
class C<X>{
|
|
||||||
X f;
|
|
||||||
m(b, c, d){
|
|
||||||
this.f = b;
|
|
||||||
this.f = c.f;
|
|
||||||
c.m2(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
m2(a){
|
|
||||||
a.f = this.f;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,14 +0,0 @@
|
|||||||
import de.test.Pair;
|
|
||||||
|
|
||||||
class Pairs {
|
|
||||||
setfst(fst) {
|
|
||||||
return new Pair<>(snd, fst);
|
|
||||||
}
|
|
||||||
|
|
||||||
swap () {
|
|
||||||
return new Pair<> (snd, fst); }
|
|
||||||
|
|
||||||
polyrec(p) {
|
|
||||||
return polyrec (p.swap());
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,12 +0,0 @@
|
|||||||
package de.test;
|
|
||||||
|
|
||||||
class Pair {
|
|
||||||
fst;
|
|
||||||
snd;
|
|
||||||
|
|
||||||
Pair(fst, snd) {
|
|
||||||
this.fst = fst;
|
|
||||||
this.snd = snd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
207
src/main/antlr4/java8/Java8.tokens
Normal file
207
src/main/antlr4/java8/Java8.tokens
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
T__0=1
|
||||||
|
ABSTRACT=2
|
||||||
|
ASSERT=3
|
||||||
|
BOOLEAN=4
|
||||||
|
BREAK=5
|
||||||
|
BYTE=6
|
||||||
|
CASE=7
|
||||||
|
CATCH=8
|
||||||
|
CHAR=9
|
||||||
|
CLASS=10
|
||||||
|
CONST=11
|
||||||
|
CONTINUE=12
|
||||||
|
DEFAULT=13
|
||||||
|
DO=14
|
||||||
|
DOUBLE=15
|
||||||
|
ELSE=16
|
||||||
|
ENUM=17
|
||||||
|
EXTENDS=18
|
||||||
|
FINAL=19
|
||||||
|
FINALLY=20
|
||||||
|
FLOAT=21
|
||||||
|
FOR=22
|
||||||
|
IF=23
|
||||||
|
GOTO=24
|
||||||
|
IMPLEMENTS=25
|
||||||
|
IMPORT=26
|
||||||
|
INSTANCEOF=27
|
||||||
|
INT=28
|
||||||
|
INTERFACE=29
|
||||||
|
LONG=30
|
||||||
|
NATIVE=31
|
||||||
|
NEW=32
|
||||||
|
PACKAGE=33
|
||||||
|
PRIVATE=34
|
||||||
|
PROTECTED=35
|
||||||
|
PUBLIC=36
|
||||||
|
RETURN=37
|
||||||
|
SHORT=38
|
||||||
|
STATIC=39
|
||||||
|
STRICTFP=40
|
||||||
|
SUPER=41
|
||||||
|
SWITCH=42
|
||||||
|
SYNCHRONIZED=43
|
||||||
|
THIS=44
|
||||||
|
THROW=45
|
||||||
|
THROWS=46
|
||||||
|
TRANSIENT=47
|
||||||
|
TRY=48
|
||||||
|
VOID=49
|
||||||
|
VOLATILE=50
|
||||||
|
WHILE=51
|
||||||
|
IntegerLiteral=52
|
||||||
|
FloatingPointLiteral=53
|
||||||
|
BooleanLiteral=54
|
||||||
|
CharacterLiteral=55
|
||||||
|
StringLiteral=56
|
||||||
|
NullLiteral=57
|
||||||
|
LPAREN=58
|
||||||
|
RPAREN=59
|
||||||
|
LBRACE=60
|
||||||
|
RBRACE=61
|
||||||
|
LBRACK=62
|
||||||
|
RBRACK=63
|
||||||
|
SEMI=64
|
||||||
|
COMMA=65
|
||||||
|
DOT=66
|
||||||
|
ASSIGN=67
|
||||||
|
GT=68
|
||||||
|
LT=69
|
||||||
|
BANG=70
|
||||||
|
TILDE=71
|
||||||
|
QUESTION=72
|
||||||
|
COLON=73
|
||||||
|
EQUAL=74
|
||||||
|
LE=75
|
||||||
|
GE=76
|
||||||
|
NOTEQUAL=77
|
||||||
|
AND=78
|
||||||
|
OR=79
|
||||||
|
INC=80
|
||||||
|
DEC=81
|
||||||
|
ADD=82
|
||||||
|
SUB=83
|
||||||
|
MUL=84
|
||||||
|
DIV=85
|
||||||
|
BITAND=86
|
||||||
|
BITOR=87
|
||||||
|
CARET=88
|
||||||
|
MOD=89
|
||||||
|
ARROW=90
|
||||||
|
COLONCOLON=91
|
||||||
|
ADD_ASSIGN=92
|
||||||
|
SUB_ASSIGN=93
|
||||||
|
MUL_ASSIGN=94
|
||||||
|
DIV_ASSIGN=95
|
||||||
|
AND_ASSIGN=96
|
||||||
|
OR_ASSIGN=97
|
||||||
|
XOR_ASSIGN=98
|
||||||
|
MOD_ASSIGN=99
|
||||||
|
LSHIFT_ASSIGN=100
|
||||||
|
RSHIFT_ASSIGN=101
|
||||||
|
URSHIFT_ASSIGN=102
|
||||||
|
Identifier=103
|
||||||
|
AT=104
|
||||||
|
ELLIPSIS=105
|
||||||
|
WS=106
|
||||||
|
COMMENT=107
|
||||||
|
LINE_COMMENT=108
|
||||||
|
'var'=1
|
||||||
|
'abstract'=2
|
||||||
|
'assert'=3
|
||||||
|
'boolean'=4
|
||||||
|
'break'=5
|
||||||
|
'byte'=6
|
||||||
|
'case'=7
|
||||||
|
'catch'=8
|
||||||
|
'char'=9
|
||||||
|
'class'=10
|
||||||
|
'const'=11
|
||||||
|
'continue'=12
|
||||||
|
'default'=13
|
||||||
|
'do'=14
|
||||||
|
'double'=15
|
||||||
|
'else'=16
|
||||||
|
'enum'=17
|
||||||
|
'extends'=18
|
||||||
|
'final'=19
|
||||||
|
'finally'=20
|
||||||
|
'float'=21
|
||||||
|
'for'=22
|
||||||
|
'if'=23
|
||||||
|
'goto'=24
|
||||||
|
'implements'=25
|
||||||
|
'import'=26
|
||||||
|
'instanceof'=27
|
||||||
|
'int'=28
|
||||||
|
'interface'=29
|
||||||
|
'long'=30
|
||||||
|
'native'=31
|
||||||
|
'new'=32
|
||||||
|
'package'=33
|
||||||
|
'private'=34
|
||||||
|
'protected'=35
|
||||||
|
'public'=36
|
||||||
|
'return'=37
|
||||||
|
'short'=38
|
||||||
|
'static'=39
|
||||||
|
'strictfp'=40
|
||||||
|
'super'=41
|
||||||
|
'switch'=42
|
||||||
|
'synchronized'=43
|
||||||
|
'this'=44
|
||||||
|
'throw'=45
|
||||||
|
'throws'=46
|
||||||
|
'transient'=47
|
||||||
|
'try'=48
|
||||||
|
'void'=49
|
||||||
|
'volatile'=50
|
||||||
|
'while'=51
|
||||||
|
'null'=57
|
||||||
|
'('=58
|
||||||
|
')'=59
|
||||||
|
'{'=60
|
||||||
|
'}'=61
|
||||||
|
'['=62
|
||||||
|
']'=63
|
||||||
|
';'=64
|
||||||
|
','=65
|
||||||
|
'.'=66
|
||||||
|
'='=67
|
||||||
|
'>'=68
|
||||||
|
'<'=69
|
||||||
|
'!'=70
|
||||||
|
'~'=71
|
||||||
|
'?'=72
|
||||||
|
':'=73
|
||||||
|
'=='=74
|
||||||
|
'<='=75
|
||||||
|
'>='=76
|
||||||
|
'!='=77
|
||||||
|
'&&'=78
|
||||||
|
'||'=79
|
||||||
|
'++'=80
|
||||||
|
'--'=81
|
||||||
|
'+'=82
|
||||||
|
'-'=83
|
||||||
|
'*'=84
|
||||||
|
'/'=85
|
||||||
|
'&'=86
|
||||||
|
'|'=87
|
||||||
|
'^'=88
|
||||||
|
'%'=89
|
||||||
|
'->'=90
|
||||||
|
'::'=91
|
||||||
|
'+='=92
|
||||||
|
'-='=93
|
||||||
|
'*='=94
|
||||||
|
'/='=95
|
||||||
|
'&='=96
|
||||||
|
'|='=97
|
||||||
|
'^='=98
|
||||||
|
'%='=99
|
||||||
|
'<<='=100
|
||||||
|
'>>='=101
|
||||||
|
'>>>='=102
|
||||||
|
'@'=104
|
||||||
|
'...'=105
|
207
src/main/antlr4/java8/Java8Lexer.tokens
Normal file
207
src/main/antlr4/java8/Java8Lexer.tokens
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
T__0=1
|
||||||
|
ABSTRACT=2
|
||||||
|
ASSERT=3
|
||||||
|
BOOLEAN=4
|
||||||
|
BREAK=5
|
||||||
|
BYTE=6
|
||||||
|
CASE=7
|
||||||
|
CATCH=8
|
||||||
|
CHAR=9
|
||||||
|
CLASS=10
|
||||||
|
CONST=11
|
||||||
|
CONTINUE=12
|
||||||
|
DEFAULT=13
|
||||||
|
DO=14
|
||||||
|
DOUBLE=15
|
||||||
|
ELSE=16
|
||||||
|
ENUM=17
|
||||||
|
EXTENDS=18
|
||||||
|
FINAL=19
|
||||||
|
FINALLY=20
|
||||||
|
FLOAT=21
|
||||||
|
FOR=22
|
||||||
|
IF=23
|
||||||
|
GOTO=24
|
||||||
|
IMPLEMENTS=25
|
||||||
|
IMPORT=26
|
||||||
|
INSTANCEOF=27
|
||||||
|
INT=28
|
||||||
|
INTERFACE=29
|
||||||
|
LONG=30
|
||||||
|
NATIVE=31
|
||||||
|
NEW=32
|
||||||
|
PACKAGE=33
|
||||||
|
PRIVATE=34
|
||||||
|
PROTECTED=35
|
||||||
|
PUBLIC=36
|
||||||
|
RETURN=37
|
||||||
|
SHORT=38
|
||||||
|
STATIC=39
|
||||||
|
STRICTFP=40
|
||||||
|
SUPER=41
|
||||||
|
SWITCH=42
|
||||||
|
SYNCHRONIZED=43
|
||||||
|
THIS=44
|
||||||
|
THROW=45
|
||||||
|
THROWS=46
|
||||||
|
TRANSIENT=47
|
||||||
|
TRY=48
|
||||||
|
VOID=49
|
||||||
|
VOLATILE=50
|
||||||
|
WHILE=51
|
||||||
|
IntegerLiteral=52
|
||||||
|
FloatingPointLiteral=53
|
||||||
|
BooleanLiteral=54
|
||||||
|
CharacterLiteral=55
|
||||||
|
StringLiteral=56
|
||||||
|
NullLiteral=57
|
||||||
|
LPAREN=58
|
||||||
|
RPAREN=59
|
||||||
|
LBRACE=60
|
||||||
|
RBRACE=61
|
||||||
|
LBRACK=62
|
||||||
|
RBRACK=63
|
||||||
|
SEMI=64
|
||||||
|
COMMA=65
|
||||||
|
DOT=66
|
||||||
|
ASSIGN=67
|
||||||
|
GT=68
|
||||||
|
LT=69
|
||||||
|
BANG=70
|
||||||
|
TILDE=71
|
||||||
|
QUESTION=72
|
||||||
|
COLON=73
|
||||||
|
EQUAL=74
|
||||||
|
LE=75
|
||||||
|
GE=76
|
||||||
|
NOTEQUAL=77
|
||||||
|
AND=78
|
||||||
|
OR=79
|
||||||
|
INC=80
|
||||||
|
DEC=81
|
||||||
|
ADD=82
|
||||||
|
SUB=83
|
||||||
|
MUL=84
|
||||||
|
DIV=85
|
||||||
|
BITAND=86
|
||||||
|
BITOR=87
|
||||||
|
CARET=88
|
||||||
|
MOD=89
|
||||||
|
ARROW=90
|
||||||
|
COLONCOLON=91
|
||||||
|
ADD_ASSIGN=92
|
||||||
|
SUB_ASSIGN=93
|
||||||
|
MUL_ASSIGN=94
|
||||||
|
DIV_ASSIGN=95
|
||||||
|
AND_ASSIGN=96
|
||||||
|
OR_ASSIGN=97
|
||||||
|
XOR_ASSIGN=98
|
||||||
|
MOD_ASSIGN=99
|
||||||
|
LSHIFT_ASSIGN=100
|
||||||
|
RSHIFT_ASSIGN=101
|
||||||
|
URSHIFT_ASSIGN=102
|
||||||
|
Identifier=103
|
||||||
|
AT=104
|
||||||
|
ELLIPSIS=105
|
||||||
|
WS=106
|
||||||
|
COMMENT=107
|
||||||
|
LINE_COMMENT=108
|
||||||
|
'var'=1
|
||||||
|
'abstract'=2
|
||||||
|
'assert'=3
|
||||||
|
'boolean'=4
|
||||||
|
'break'=5
|
||||||
|
'byte'=6
|
||||||
|
'case'=7
|
||||||
|
'catch'=8
|
||||||
|
'char'=9
|
||||||
|
'class'=10
|
||||||
|
'const'=11
|
||||||
|
'continue'=12
|
||||||
|
'default'=13
|
||||||
|
'do'=14
|
||||||
|
'double'=15
|
||||||
|
'else'=16
|
||||||
|
'enum'=17
|
||||||
|
'extends'=18
|
||||||
|
'final'=19
|
||||||
|
'finally'=20
|
||||||
|
'float'=21
|
||||||
|
'for'=22
|
||||||
|
'if'=23
|
||||||
|
'goto'=24
|
||||||
|
'implements'=25
|
||||||
|
'import'=26
|
||||||
|
'instanceof'=27
|
||||||
|
'int'=28
|
||||||
|
'interface'=29
|
||||||
|
'long'=30
|
||||||
|
'native'=31
|
||||||
|
'new'=32
|
||||||
|
'package'=33
|
||||||
|
'private'=34
|
||||||
|
'protected'=35
|
||||||
|
'public'=36
|
||||||
|
'return'=37
|
||||||
|
'short'=38
|
||||||
|
'static'=39
|
||||||
|
'strictfp'=40
|
||||||
|
'super'=41
|
||||||
|
'switch'=42
|
||||||
|
'synchronized'=43
|
||||||
|
'this'=44
|
||||||
|
'throw'=45
|
||||||
|
'throws'=46
|
||||||
|
'transient'=47
|
||||||
|
'try'=48
|
||||||
|
'void'=49
|
||||||
|
'volatile'=50
|
||||||
|
'while'=51
|
||||||
|
'null'=57
|
||||||
|
'('=58
|
||||||
|
')'=59
|
||||||
|
'{'=60
|
||||||
|
'}'=61
|
||||||
|
'['=62
|
||||||
|
']'=63
|
||||||
|
';'=64
|
||||||
|
','=65
|
||||||
|
'.'=66
|
||||||
|
'='=67
|
||||||
|
'>'=68
|
||||||
|
'<'=69
|
||||||
|
'!'=70
|
||||||
|
'~'=71
|
||||||
|
'?'=72
|
||||||
|
':'=73
|
||||||
|
'=='=74
|
||||||
|
'<='=75
|
||||||
|
'>='=76
|
||||||
|
'!='=77
|
||||||
|
'&&'=78
|
||||||
|
'||'=79
|
||||||
|
'++'=80
|
||||||
|
'--'=81
|
||||||
|
'+'=82
|
||||||
|
'-'=83
|
||||||
|
'*'=84
|
||||||
|
'/'=85
|
||||||
|
'&'=86
|
||||||
|
'|'=87
|
||||||
|
'^'=88
|
||||||
|
'%'=89
|
||||||
|
'->'=90
|
||||||
|
'::'=91
|
||||||
|
'+='=92
|
||||||
|
'-='=93
|
||||||
|
'*='=94
|
||||||
|
'/='=95
|
||||||
|
'&='=96
|
||||||
|
'|='=97
|
||||||
|
'^='=98
|
||||||
|
'%='=99
|
||||||
|
'<<='=100
|
||||||
|
'>>='=101
|
||||||
|
'>>>='=102
|
||||||
|
'@'=104
|
||||||
|
'...'=105
|
37
src/main/antlr4/sat/UnifyResult.g4
Normal file
37
src/main/antlr4/sat/UnifyResult.g4
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
grammar UnifyResult;
|
||||||
|
|
||||||
|
answer : 'ANSWER' (resultSetRule '.')*;
|
||||||
|
|
||||||
|
resultSetRule :
|
||||||
|
parameter
|
||||||
|
| equals
|
||||||
|
| smaller
|
||||||
|
| typeVar
|
||||||
|
| type
|
||||||
|
| otherRule
|
||||||
|
;
|
||||||
|
|
||||||
|
parameterList : '(' value (',' value)* ')';
|
||||||
|
value : NAME
|
||||||
|
| resultSetRule ;
|
||||||
|
|
||||||
|
parameter : PARAMLIST_NAME parameterList;
|
||||||
|
equals : EQUALS_NAME parameterList;
|
||||||
|
smaller : SMALLER_NAME parameterList;
|
||||||
|
typeVar : TYPEVAR_NAME parameterList;
|
||||||
|
type : TYPE_NAME parameterList;
|
||||||
|
otherRule : NAME parameterList;
|
||||||
|
|
||||||
|
//TODO: Es sollte Regeln für das Result set geben, welche sich nicht mit den anderen überdecken, dann auch nur diese im Result ausgeben
|
||||||
|
PARAMLIST_NAME : 'param';
|
||||||
|
EQUALS_NAME : 'equals';
|
||||||
|
SMALLER_NAME : 'smaller';
|
||||||
|
TYPEVAR_NAME : 'typeVar';
|
||||||
|
TYPE_NAME : 'type';
|
||||||
|
NAME : [a-zA-Z0-9_]+;
|
||||||
|
|
||||||
|
WS : [ \t\r\n\u000C]+ -> skip
|
||||||
|
;
|
||||||
|
LINE_COMMENT
|
||||||
|
: '%' ~[\r\n]* -> skip
|
||||||
|
;
|
23
src/main/antlr4/sat/UnifyResult.tokens
Normal file
23
src/main/antlr4/sat/UnifyResult.tokens
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
T__0=1
|
||||||
|
T__1=2
|
||||||
|
T__2=3
|
||||||
|
T__3=4
|
||||||
|
T__4=5
|
||||||
|
PARAMLIST_NAME=6
|
||||||
|
EQUALS_NAME=7
|
||||||
|
SMALLER_NAME=8
|
||||||
|
TYPEVAR_NAME=9
|
||||||
|
TYPE_NAME=10
|
||||||
|
NAME=11
|
||||||
|
WS=12
|
||||||
|
LINE_COMMENT=13
|
||||||
|
'ANSWER'=1
|
||||||
|
'.'=2
|
||||||
|
'('=3
|
||||||
|
','=4
|
||||||
|
')'=5
|
||||||
|
'param'=6
|
||||||
|
'equals'=7
|
||||||
|
'smaller'=8
|
||||||
|
'typeVar'=9
|
||||||
|
'type'=10
|
23
src/main/antlr4/sat/UnifyResultLexer.tokens
Normal file
23
src/main/antlr4/sat/UnifyResultLexer.tokens
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
T__0=1
|
||||||
|
T__1=2
|
||||||
|
T__2=3
|
||||||
|
T__3=4
|
||||||
|
T__4=5
|
||||||
|
PARAMLIST_NAME=6
|
||||||
|
EQUALS_NAME=7
|
||||||
|
SMALLER_NAME=8
|
||||||
|
TYPEVAR_NAME=9
|
||||||
|
TYPE_NAME=10
|
||||||
|
NAME=11
|
||||||
|
WS=12
|
||||||
|
LINE_COMMENT=13
|
||||||
|
'ANSWER'=1
|
||||||
|
'.'=2
|
||||||
|
'('=3
|
||||||
|
','=4
|
||||||
|
')'=5
|
||||||
|
'param'=6
|
||||||
|
'equals'=7
|
||||||
|
'smaller'=8
|
||||||
|
'typeVar'=9
|
||||||
|
'type'=10
|
@@ -1,10 +0,0 @@
|
|||||||
import de.dhbwstuttgart.core.ConsoleInterface;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class Main {
|
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException, ClassNotFoundException {
|
|
||||||
ConsoleInterface.main(args);
|
|
||||||
}
|
|
||||||
}
|
|
30
src/main/java/de/dhbwstuttgart/bytecode/AStatement.java
Normal file
30
src/main/java/de/dhbwstuttgart/bytecode/AStatement.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
11
src/main/java/de/dhbwstuttgart/bytecode/ArgumentExpr.java
Normal file
11
src/main/java/de/dhbwstuttgart/bytecode/ArgumentExpr.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package de.dhbwstuttgart.bytecode;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||||
|
|
||||||
|
public class ArgumentExpr extends AStatement {
|
||||||
|
|
||||||
|
public ArgumentExpr(Expression expr) {
|
||||||
|
super(expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
258
src/main/java/de/dhbwstuttgart/bytecode/ArgumentVisitor.java
Normal file
258
src/main/java/de/dhbwstuttgart/bytecode/ArgumentVisitor.java
Normal file
@@ -0,0 +1,258 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
src/main/java/de/dhbwstuttgart/bytecode/AssignStmt.java
Normal file
11
src/main/java/de/dhbwstuttgart/bytecode/AssignStmt.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package de.dhbwstuttgart.bytecode;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||||
|
|
||||||
|
public class AssignStmt extends AStatement {
|
||||||
|
|
||||||
|
public AssignStmt(Expression rightSide) {
|
||||||
|
super(rightSide);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
630
src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java
Normal file
630
src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java
Normal file
@@ -0,0 +1,630 @@
|
|||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
1501
src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java
Normal file
1501
src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
|
||||||
|
|
||||||
public class CodeGenException extends RuntimeException {
|
|
||||||
public CodeGenException(String cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package de.dhbwstuttgart.bytecode.Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author fayez
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class BytecodeGeneratorError extends RuntimeException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
public BytecodeGeneratorError(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -1,123 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.target.tree.TargetGeneric;
|
|
||||||
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("%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;", argumentGenericBase + currentParameter));
|
|
||||||
superFunNMethodDescriptor.append(objectSignature);
|
|
||||||
}
|
|
||||||
superFunNClassSignature.append(String.format("%s:%s>%s", returnGeneric, objectSignature, objectSignature));
|
|
||||||
superFunNMethodSignature.append(String.format(")T%s;", returnGeneric));
|
|
||||||
superFunNMethodDescriptor.append(String.format(")%s", objectSignature));
|
|
||||||
|
|
||||||
System.out.println(superFunNMethodSignature);
|
|
||||||
|
|
||||||
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 + applyDescriptor(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(), 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
9
src/main/java/de/dhbwstuttgart/bytecode/IStatement.java
Normal file
9
src/main/java/de/dhbwstuttgart/bytecode/IStatement.java
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
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);
|
||||||
|
}
|
29
src/main/java/de/dhbwstuttgart/bytecode/IfStatement.java
Normal file
29
src/main/java/de/dhbwstuttgart/bytecode/IfStatement.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
@@ -1,26 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
|
||||||
|
|
||||||
import org.objectweb.asm.*;
|
|
||||||
|
|
||||||
public class JavaTXSignatureAttribute extends Attribute {
|
|
||||||
final int signature;
|
|
||||||
|
|
||||||
protected JavaTXSignatureAttribute(int signature) {
|
|
||||||
super("JavaTXSignature");
|
|
||||||
this.signature = signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Attribute read(ClassReader classReader, int offset, int length, char[] charBuffer, int codeAttributeOffset, Label[] labels) {
|
|
||||||
var data = new byte[length];
|
|
||||||
System.arraycopy(classReader.b, offset, data, 0, length);
|
|
||||||
return new JavaTXSignatureAttribute(data[0] << 8 | data[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ByteVector write(ClassWriter classWriter, byte[] code, int codeLength, int maxStack, int maxLocals) {
|
|
||||||
var data = new ByteVector();
|
|
||||||
data.putShort(this.signature);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
26
src/main/java/de/dhbwstuttgart/bytecode/LoopStmt.java
Normal file
26
src/main/java/de/dhbwstuttgart/bytecode/LoopStmt.java
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
14
src/main/java/de/dhbwstuttgart/bytecode/ReturnStmt.java
Normal file
14
src/main/java/de/dhbwstuttgart/bytecode/ReturnStmt.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
269
src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java
Normal file
269
src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java
Normal file
@@ -0,0 +1,269 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,259 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,17 @@
|
|||||||
|
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);
|
||||||
|
}
|
@@ -0,0 +1,45 @@
|
|||||||
|
package de.dhbwstuttgart.bytecode.descriptor;
|
||||||
|
|
||||||
|
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 TypeToDescriptor implements TypeVisitor<String>{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String visit(RefType refType) {
|
||||||
|
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(".", "/");
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,137 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,106 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,732 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,256 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,571 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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,8 +24,7 @@ public class MethodAndConstraints {
|
|||||||
* @return the methodID
|
* @return the methodID
|
||||||
*/
|
*/
|
||||||
public String getMethodID() {
|
public String getMethodID() {
|
||||||
// FIXME
|
return methodID;
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @return the constraints
|
* @return the constraints
|
||||||
|
@@ -0,0 +1,16 @@
|
|||||||
|
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;
|
||||||
|
}*/
|
||||||
|
}
|
@@ -0,0 +1,880 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
@@ -0,0 +1,10 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,47 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,43 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,79 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
package de.dhbwstuttgart.bytecode.insertGenerics;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
interface preGGenerics {
|
||||||
|
public List<ResultSet> getResultOfTypeInference();
|
||||||
|
}
|
379
src/main/java/de/dhbwstuttgart/bytecode/signature/Signature.java
Normal file
379
src/main/java/de/dhbwstuttgart/bytecode/signature/Signature.java
Normal file
@@ -0,0 +1,379 @@
|
|||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,102 @@
|
|||||||
|
package de.dhbwstuttgart.bytecode.signature;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResult;
|
||||||
|
import de.dhbwstuttgart.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;
|
||||||
|
|
||||||
|
public TypeToSignature() {
|
||||||
|
this.constraints = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeToSignature(List<GenericsGeneratorResult> constraints) {
|
||||||
|
this.constraints = constraints;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String visit(RefType refType) {
|
||||||
|
if(refType.getName().toString().equals("void"))
|
||||||
|
return "V";
|
||||||
|
// 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();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,38 @@
|
|||||||
|
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";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,75 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,94 @@
|
|||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,22 @@
|
|||||||
|
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";
|
||||||
|
}
|
@@ -0,0 +1,53 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,243 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,26 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,59 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,244 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,50 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,145 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,40 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user