Compare commits
92 Commits
bigRefacto
...
fba7f0ee81
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fba7f0ee81 | ||
|
|
e0da2a4c46 | ||
| f588ece7c3 | |||
| 9ad5b76542 | |||
| 3d2c699964 | |||
| f95c3c5fcf | |||
| 4654ecacaf | |||
| 1be27746e3 | |||
|
|
c51190feef | ||
|
|
c4ce97f20c | ||
| 837317c84c | |||
|
|
df852ef36e | ||
|
|
c00722823a | ||
| e31f1c59e1 | |||
| 5d0d7a6d94 | |||
| b372c6ac1c | |||
| 124dea2e58 | |||
| eaef00ff54 | |||
| 892ba5fff0 | |||
| 628f1631e8 | |||
| 0b815950e1 | |||
| f10e7e6d72 | |||
| 700ecf3e5d | |||
|
|
f7c53fc6c3 | ||
|
|
9764ec6db1 | ||
|
|
b21faa30fc | ||
|
|
87f8b8799e | ||
|
|
769f1bb677 | ||
|
|
5623fdc020 | ||
|
|
dfd91b5f8b | ||
|
|
3c43978c55 | ||
|
|
fb7b51a971 | ||
| 56c360104b | |||
| e414da3369 | |||
| 5f1f698530 | |||
| 729e88bc6d | |||
| bffc7f9f1c | |||
| 011b272af6 | |||
| ee359da751 | |||
| 6025e17186 | |||
| 93d7aca9e6 | |||
| 677c784b6d | |||
| e69a367c33 | |||
| 14d0475d59 | |||
| 762d344e42 | |||
| be5591f7dc | |||
| 7193f5a646 | |||
| f46c2ad0f7 | |||
| b0f7a264c2 | |||
| 4f3164a48a | |||
| be55d661cb | |||
| 3de9fde672 | |||
| a0582e918b | |||
|
|
18429d9cf9 | ||
|
|
b65df7c390 | ||
|
|
22d1be5ea4 | ||
|
|
18fc82f036 | ||
|
|
f5b843ec11 | ||
|
|
bad5d26969 | ||
|
|
951d741d90 | ||
|
|
fe6c9858a2 | ||
|
|
1df354d5f1 | ||
|
|
6119bc92ed | ||
|
|
e8140b3160 | ||
|
|
75789e574e | ||
|
|
c0c46e197f | ||
|
|
a0e6df7cfd | ||
|
|
1643412f1b | ||
|
|
3ed6edc323 | ||
|
|
fa7a331a66 | ||
|
|
939d402b1e | ||
|
|
492cbe48e9 | ||
| a17e1f473a | |||
|
|
359f3e68ab | ||
| 5c62191f3b | |||
| b04201de42 | |||
|
|
a15cbcba7b | ||
|
|
9019d90b1e | ||
| d07b2bdf0a | |||
| d05054755c | |||
|
|
1a89920430 | ||
|
|
54a836b734 | ||
|
|
8b3b07e32c | ||
| d55b402269 | |||
|
|
24900b8fcc | ||
|
|
2368a087c0 | ||
|
|
994a1571b7 | ||
|
|
aed1d3848b | ||
|
|
93cf39cfe9 | ||
| bdaf578f86 | |||
| 6079e96efa | |||
|
|
41d8e223ce |
14165
doc/Studienarbeiten_Bachelorarbeiten/S2023_Luca_Trumpfheller.pdf
Normal file
14165
doc/Studienarbeiten_Bachelorarbeiten/S2023_Luca_Trumpfheller.pdf
Normal file
File diff suppressed because it is too large
Load Diff
14
pom.xml
14
pom.xml
@@ -54,12 +54,8 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<version>3.11.0</version>
|
||||
<configuration>
|
||||
<compilerArgs>--enable-preview</compilerArgs>
|
||||
<<<<<<< HEAD
|
||||
<source>20</source>
|
||||
<target>20</target>
|
||||
=======
|
||||
<release>20</release>
|
||||
>>>>>>> patternMatching
|
||||
<source>21</source>
|
||||
<target>21</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
@@ -89,6 +85,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
@@ -127,11 +124,6 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
</repository>
|
||||
</repositories>
|
||||
<properties>
|
||||
<<<<<<< HEAD
|
||||
<maven.compiler.source>20</maven.compiler.source>
|
||||
<maven.compiler.target>20</maven.compiler.target>
|
||||
=======
|
||||
>>>>>>> patternMatching
|
||||
<mainClass>de.dhbwstuttgart.core.ConsoleInterface</mainClass>
|
||||
</properties>
|
||||
<distributionManagement>
|
||||
|
||||
22
resources/AllgemeinTest/Complex.jav
Normal file
22
resources/AllgemeinTest/Complex.jav
Normal file
@@ -0,0 +1,22 @@
|
||||
class Pair<U, T> {
|
||||
U a;
|
||||
T b;
|
||||
Pair(U x, T y) {
|
||||
a = x; b = y;
|
||||
}
|
||||
}
|
||||
|
||||
class Complex {
|
||||
m(b) {
|
||||
var c = b;
|
||||
var d = c;
|
||||
var e;
|
||||
d = e;
|
||||
var r1 = e;
|
||||
var f = e;
|
||||
var g;
|
||||
f = g;
|
||||
var r2 = g;
|
||||
return new Pair<>(r1, r2);
|
||||
}
|
||||
}
|
||||
7
resources/AllgemeinTest/InfReturn.jav
Normal file
7
resources/AllgemeinTest/InfReturn.jav
Normal file
@@ -0,0 +1,7 @@
|
||||
public class InfReturn {
|
||||
m(a) {
|
||||
var ret;
|
||||
a = ret;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
8
resources/AllgemeinTest/InfReturnII.jav
Normal file
8
resources/AllgemeinTest/InfReturnII.jav
Normal file
@@ -0,0 +1,8 @@
|
||||
public class InfReturnII {
|
||||
m(a, b) {
|
||||
var ret;
|
||||
a = ret;
|
||||
b = ret;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
7
resources/AllgemeinTest/InnerInf.jav
Normal file
7
resources/AllgemeinTest/InnerInf.jav
Normal file
@@ -0,0 +1,7 @@
|
||||
class InnerInf {
|
||||
m(a, b) {
|
||||
var i;
|
||||
a = i;
|
||||
b = i;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
/*
|
||||
class Pair<T, U> {
|
||||
T x;
|
||||
U y;
|
||||
@@ -17,7 +17,7 @@ class Pair<T, U> {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
public class Iteration {
|
||||
id(x) {
|
||||
|
||||
7
resources/AllgemeinTest/Overloading.jav
Normal file
7
resources/AllgemeinTest/Overloading.jav
Normal file
@@ -0,0 +1,7 @@
|
||||
import java.lang.Integer;
|
||||
import java.lang.Double;
|
||||
|
||||
class Overloading {
|
||||
m(x) { return x + x; }
|
||||
m(x) { return x || x; }
|
||||
}
|
||||
8
resources/AllgemeinTest/RecursionCond.jav
Normal file
8
resources/AllgemeinTest/RecursionCond.jav
Normal file
@@ -0,0 +1,8 @@
|
||||
class RecursionCond {
|
||||
m(a, b, c) {
|
||||
if (1 == 2) {
|
||||
b = m(a, b);
|
||||
c = m(a, b);
|
||||
} else return a;
|
||||
}
|
||||
}
|
||||
9
resources/AllgemeinTest/Test.jav
Normal file
9
resources/AllgemeinTest/Test.jav
Normal file
@@ -0,0 +1,9 @@
|
||||
import java.lang.Boolean;
|
||||
import java.lang.Integer;
|
||||
|
||||
public class Test {
|
||||
fac = (x) -> {
|
||||
if (x == 1) { return 1; }
|
||||
return x * fac.apply(x - 1);
|
||||
};
|
||||
}
|
||||
19
resources/AllgemeinTest/TripleTest.jav
Normal file
19
resources/AllgemeinTest/TripleTest.jav
Normal file
@@ -0,0 +1,19 @@
|
||||
class Triple<U, T, S> {
|
||||
U a;
|
||||
T b;
|
||||
S c;
|
||||
|
||||
Triple(U x, T y, S z) {
|
||||
a = x; b = y; c = z;
|
||||
}
|
||||
|
||||
U fst() { return a; }
|
||||
T snd() { return b; }
|
||||
S thrd() { return c; }
|
||||
}
|
||||
|
||||
public class TripleTest {
|
||||
m() {
|
||||
return new Triple<>(m().thrd(), m().thrd(), m().thrd());
|
||||
}
|
||||
}
|
||||
12
resources/AllgemeinTest/Twice2.jav
Normal file
12
resources/AllgemeinTest/Twice2.jav
Normal file
@@ -0,0 +1,12 @@
|
||||
class Twice2 {
|
||||
id1inst = new Id<>();
|
||||
id1 = id1inst.id;
|
||||
id2inst = new Id<>();
|
||||
id2 = id2inst.id;
|
||||
twice = id1.apply(id2);
|
||||
|
||||
}
|
||||
|
||||
class Id<T> {
|
||||
id = (T x) -> x;
|
||||
}
|
||||
13
resources/bytecode/javFiles/Chain.jav
Normal file
13
resources/bytecode/javFiles/Chain.jav
Normal file
@@ -0,0 +1,13 @@
|
||||
import java.lang.Integer;
|
||||
|
||||
public class Chain {
|
||||
x = 5;
|
||||
|
||||
chain() {
|
||||
return this;
|
||||
}
|
||||
|
||||
m() {
|
||||
return this.chain().chain().chain().x;
|
||||
}
|
||||
}
|
||||
0
resources/bytecode/javFiles/Cycle.class
Normal file → Executable file
0
resources/bytecode/javFiles/Cycle.class
Normal file → Executable file
@@ -1,12 +1,12 @@
|
||||
import java.lang.Integer;
|
||||
import java.lang.Double;
|
||||
import java.lang.String;
|
||||
|
||||
public class Fac {
|
||||
|
||||
getFac(n){
|
||||
public class Fac {
|
||||
getFac(n) {
|
||||
var res = 1;
|
||||
var i = 1;
|
||||
while(i<=n) {
|
||||
while (i <= n) {
|
||||
res = res * i;
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import java.lang.String;
|
||||
|
||||
public class FieldTph2 {
|
||||
a;
|
||||
|
||||
|
||||
@@ -4,20 +4,20 @@ import java.lang.Boolean;
|
||||
class For{
|
||||
Integer m(Integer x){
|
||||
var c = x + 2;
|
||||
// Boolean b = true;
|
||||
// c = 5;
|
||||
// c++;
|
||||
// ++c;
|
||||
// c--;
|
||||
// --c;
|
||||
// while(x<2){
|
||||
// x = x +1;
|
||||
// b = false;
|
||||
// }
|
||||
return c;
|
||||
// for(int i = 0;i<10;i++) {
|
||||
// x = x + 5;
|
||||
// }
|
||||
Boolean b = true;
|
||||
c = 5;
|
||||
c++;
|
||||
++c;
|
||||
c--;
|
||||
--c;
|
||||
while(x<2){
|
||||
x = x +1;
|
||||
b = false;
|
||||
}
|
||||
for(int i = 0; i<10; i++) {
|
||||
x = x + 5;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
// m2(Integer x){
|
||||
|
||||
15
resources/bytecode/javFiles/FunctionalInterface.jav
Normal file
15
resources/bytecode/javFiles/FunctionalInterface.jav
Normal file
@@ -0,0 +1,15 @@
|
||||
import java.lang.Integer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class FunctionalInterface {
|
||||
Integer accept(Function<Integer, Integer> f) {
|
||||
return f.apply(20);
|
||||
}
|
||||
|
||||
Integer m() {
|
||||
var v = accept(i -> {
|
||||
return i * 10;
|
||||
});
|
||||
return v;
|
||||
}
|
||||
}
|
||||
9
resources/bytecode/javFiles/HelloWorld.jav
Normal file
9
resources/bytecode/javFiles/HelloWorld.jav
Normal file
@@ -0,0 +1,9 @@
|
||||
import java.lang.System;
|
||||
import java.lang.String;
|
||||
import java.io.PrintStream;
|
||||
|
||||
public class HelloWorld {
|
||||
static hello() {
|
||||
System.out.println("Hello World!");
|
||||
}
|
||||
}
|
||||
18
resources/bytecode/javFiles/InstanceOf.jav
Normal file
18
resources/bytecode/javFiles/InstanceOf.jav
Normal file
@@ -0,0 +1,18 @@
|
||||
import java.lang.Number;
|
||||
import java.lang.Integer;
|
||||
import java.lang.Double;
|
||||
import java.lang.String;
|
||||
|
||||
public class InstanceOf {
|
||||
main(n) {
|
||||
if (n instanceof Integer i) {
|
||||
takes(i);
|
||||
return "Integer";
|
||||
} else if (n instanceof Double d) {
|
||||
takes(d);
|
||||
return "Double";
|
||||
}
|
||||
}
|
||||
|
||||
takes(i) {} // Should be overloaded
|
||||
}
|
||||
33
resources/bytecode/javFiles/Interfaces.jav
Normal file
33
resources/bytecode/javFiles/Interfaces.jav
Normal file
@@ -0,0 +1,33 @@
|
||||
import java.lang.Integer;
|
||||
|
||||
interface A {
|
||||
void method1();
|
||||
default method2() {
|
||||
}
|
||||
}
|
||||
|
||||
interface B {
|
||||
void method3();
|
||||
}
|
||||
|
||||
interface C {
|
||||
Integer myInt();
|
||||
}
|
||||
|
||||
class ClassX implements A {
|
||||
}
|
||||
|
||||
record ClassY(Integer myInt) implements C {}
|
||||
|
||||
public class Interfaces implements A, B {
|
||||
public void method1() {
|
||||
}
|
||||
public void method3() {
|
||||
var intf = new Interfaces();
|
||||
intf = new ClassX();
|
||||
intf.method1();
|
||||
|
||||
C c = new ClassY(10);
|
||||
c.myInt();
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,16 @@
|
||||
import java.lang.Runnable;
|
||||
import java.lang.String;
|
||||
import java.lang.System;
|
||||
import java.io.PrintStream;
|
||||
|
||||
public class LamRunnable{
|
||||
public class LambdaRunnable {
|
||||
|
||||
public LamRunnable(){
|
||||
public LambdaRunnable(){
|
||||
|
||||
|
||||
Runnable lam = () -> {System.out.println("lambda");};
|
||||
|
||||
Runnable lam = () -> {
|
||||
System.out.println("Runnable is running");
|
||||
};
|
||||
lam.run();
|
||||
}
|
||||
}
|
||||
|
||||
50
resources/bytecode/javFiles/OverloadPattern.jav
Normal file
50
resources/bytecode/javFiles/OverloadPattern.jav
Normal file
@@ -0,0 +1,50 @@
|
||||
import java.lang.Integer;
|
||||
import java.lang.Number;
|
||||
import java.lang.Float;
|
||||
|
||||
record Point(Number x, Number y) {}
|
||||
|
||||
public class OverloadPattern {
|
||||
m(Point(Integer x, Integer y)) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
m(Point(Float x, Float y)) {
|
||||
return x * y;
|
||||
}
|
||||
|
||||
m(Integer x) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public class OverloadPattern {
|
||||
Integer m$Point$_$java$lang$Integer$_$java$lang$Integer$_$(Point point) {
|
||||
var x = point.x();
|
||||
var y = point.y();
|
||||
return x + y;
|
||||
}
|
||||
|
||||
Float m$Point$_$java$lang$Float$_$java$lang$Float$_$(Point point) {
|
||||
var x = point.x();
|
||||
var y = point.y();
|
||||
return x * y;
|
||||
}
|
||||
|
||||
Number m(Point point) {
|
||||
return switch(point) {
|
||||
case Point(Integer x, Integer y) ->
|
||||
m$Point$_$java$lang$Integer$_$java$lang$Integer$_$(point);
|
||||
case Point(Float x, Float y) ->
|
||||
m$Point$_$java$lang$Float$_$java$lang$Float$_$(point);
|
||||
default -> throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
Integer m(Integer x) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
22
resources/bytecode/javFiles/RecordTest.jav
Normal file
22
resources/bytecode/javFiles/RecordTest.jav
Normal file
@@ -0,0 +1,22 @@
|
||||
import java.lang.Integer;
|
||||
|
||||
record Rec(Integer a, Integer b) {}
|
||||
|
||||
/*public class Rec {
|
||||
x; y;
|
||||
Rec(Integer a, Integer b) {
|
||||
x = a;
|
||||
y = b;
|
||||
}
|
||||
}*/
|
||||
|
||||
public class RecordTest {
|
||||
a = new Rec(10, 20);
|
||||
b = new Rec(10, 20);
|
||||
c = new Rec(20, 40);
|
||||
|
||||
doesEqual() { return a.equals(b); }
|
||||
doesNotEqual() { return b.equals(c); }
|
||||
hashCode() { return a.hashCode(); }
|
||||
toString() { return a.toString(); }
|
||||
}
|
||||
18
resources/bytecode/javFiles/Static.jav
Normal file
18
resources/bytecode/javFiles/Static.jav
Normal file
@@ -0,0 +1,18 @@
|
||||
import java.lang.Integer;
|
||||
|
||||
class Other {
|
||||
static field = 20;
|
||||
}
|
||||
|
||||
public class Static {
|
||||
static i = 20;
|
||||
|
||||
static {
|
||||
var x = 30;
|
||||
i = x;
|
||||
}
|
||||
|
||||
static m() {
|
||||
return i + Other.field;
|
||||
}
|
||||
}
|
||||
17
resources/bytecode/javFiles/Switch.jav
Normal file
17
resources/bytecode/javFiles/Switch.jav
Normal file
@@ -0,0 +1,17 @@
|
||||
import java.lang.Integer;
|
||||
import java.lang.Object;
|
||||
import java.lang.Float;
|
||||
|
||||
record Rec(Integer a, Object b) {}
|
||||
|
||||
public class Switch {
|
||||
main(o) {
|
||||
return switch (o) {
|
||||
case Rec(Integer a, Integer b) -> a + b;
|
||||
case Rec(Integer a, Float b) -> a + 10;
|
||||
case Rec(Integer a, Rec(Integer b, Integer c)) -> a + b + c;
|
||||
case Integer i -> i;
|
||||
default -> 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
13
resources/bytecode/javFiles/Switch2.jav
Normal file
13
resources/bytecode/javFiles/Switch2.jav
Normal file
@@ -0,0 +1,13 @@
|
||||
import java.lang.Integer;
|
||||
|
||||
record Point(x, y) {}
|
||||
|
||||
class Switch2 {
|
||||
m() {
|
||||
var pt = new Point(10, 20);
|
||||
return switch (pt) {
|
||||
case Point(x, y) -> 10;
|
||||
default -> 20;
|
||||
};
|
||||
}
|
||||
}
|
||||
14
resources/bytecode/javFiles/SwitchString.jav
Normal file
14
resources/bytecode/javFiles/SwitchString.jav
Normal file
@@ -0,0 +1,14 @@
|
||||
import java.lang.Integer;
|
||||
import java.lang.String;
|
||||
import java.lang.Object;
|
||||
|
||||
public class SwitchString {
|
||||
main(o) {
|
||||
return switch (o) {
|
||||
case "AaAaAa" -> 1; // These two have the same hash code!
|
||||
case "AaAaBB" -> 2;
|
||||
case "test", "TEST" -> 3;
|
||||
default -> 4;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,6 @@
|
||||
public class Tph2 {
|
||||
id = x->x;
|
||||
id = x->x;
|
||||
id3 (x) {
|
||||
return id.apply(x);
|
||||
}
|
||||
|
||||
/*
|
||||
m(a,b){
|
||||
var c = m2(a,b);
|
||||
//m2(a,b);
|
||||
return a;
|
||||
}
|
||||
|
||||
m2(a,b){
|
||||
return b;
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -9,4 +9,4 @@ public class TestVector {
|
||||
id(x) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
11
resources/packageTest/pkg/sub/Cycle1.jav
Normal file
11
resources/packageTest/pkg/sub/Cycle1.jav
Normal file
@@ -0,0 +1,11 @@
|
||||
package pkg.sub;
|
||||
|
||||
import java.lang.Integer;
|
||||
import pkg.sub2.Cycle2;
|
||||
|
||||
public class Cycle1 {
|
||||
test() {
|
||||
var cycle2 = new Cycle2();
|
||||
cycle2.test();
|
||||
}
|
||||
}
|
||||
11
resources/packageTest/pkg/sub/Test1.jav
Normal file
11
resources/packageTest/pkg/sub/Test1.jav
Normal file
@@ -0,0 +1,11 @@
|
||||
package pkg.sub;
|
||||
|
||||
import pkg.sub2.Test2;
|
||||
|
||||
public class Test1 {
|
||||
|
||||
main() {
|
||||
var t2 = new Test2();
|
||||
t2.test();
|
||||
}
|
||||
}
|
||||
11
resources/packageTest/pkg/sub2/Cycle2.jav
Normal file
11
resources/packageTest/pkg/sub2/Cycle2.jav
Normal file
@@ -0,0 +1,11 @@
|
||||
package pkg.sub2;
|
||||
|
||||
import java.lang.Integer;
|
||||
import pkg.sub.Cycle1;
|
||||
|
||||
public class Cycle2 {
|
||||
test() {
|
||||
var cycle1 = new Cycle1();
|
||||
cycle1.test();
|
||||
}
|
||||
}
|
||||
6
resources/packageTest/pkg/sub2/Test2.jav
Normal file
6
resources/packageTest/pkg/sub2/Test2.jav
Normal file
@@ -0,0 +1,6 @@
|
||||
package pkg.sub2;
|
||||
|
||||
public class Test2 {
|
||||
|
||||
test() {}
|
||||
}
|
||||
44
resources/syntaxtreegenerator/Instanceof.ast
Normal file
44
resources/syntaxtreegenerator/Instanceof.ast
Normal file
@@ -0,0 +1,44 @@
|
||||
class Instanceof {
|
||||
|
||||
Instanceof(){
|
||||
super(());
|
||||
}
|
||||
void checkInstanceof(){
|
||||
TPH a;
|
||||
a = 4;
|
||||
return a instanceof java.lang.Integer;
|
||||
}
|
||||
|
||||
void checkInstanceOfWithPattern(){
|
||||
TPH b;
|
||||
b = 4.0;
|
||||
if(b instanceof d)
|
||||
{
|
||||
return d;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Kein Double;
|
||||
};
|
||||
}
|
||||
|
||||
void checkInstanceOfWithGuardedPattern(){
|
||||
TPH obj;
|
||||
obj = test;
|
||||
TPH flag;
|
||||
if(obj instanceof s op s.length Signature: [TPH]() op 5)
|
||||
{
|
||||
flag = s.contains Signature: [TPH, TPH](jdk);
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
java.lang.Boolean equals(java.lang.Object o){
|
||||
return o instanceof other op x op other.x op y op other.y;
|
||||
}
|
||||
|
||||
Instanceof(){
|
||||
super(());
|
||||
}
|
||||
|
||||
}
|
||||
120
resources/syntaxtreegenerator/PatternMatching.ast
Normal file
120
resources/syntaxtreegenerator/PatternMatching.ast
Normal file
@@ -0,0 +1,120 @@
|
||||
class Point {
|
||||
|
||||
java.lang.Integer x;
|
||||
java.lang.Integer y;
|
||||
Point(java.lang.Integer x, java.lang.Integer y){
|
||||
super(());
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
java.lang.Integer x(){
|
||||
return this.x;
|
||||
}
|
||||
|
||||
java.lang.Integer y(){
|
||||
return this.y;
|
||||
}
|
||||
|
||||
Point(java.lang.Integer x, java.lang.Integer y){
|
||||
super(());
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
}class Shape {
|
||||
|
||||
}class ColoredPoint {
|
||||
|
||||
Point pt;
|
||||
java.lang.String color;
|
||||
ColoredPoint(Point pt, java.lang.String color){
|
||||
super(());
|
||||
this.pt = pt;
|
||||
this.color = color;
|
||||
}
|
||||
Point pt(){
|
||||
return this.pt;
|
||||
}
|
||||
|
||||
java.lang.String color(){
|
||||
return this.color;
|
||||
}
|
||||
|
||||
ColoredPoint(Point pt, java.lang.String color){
|
||||
super(());
|
||||
this.pt = pt;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
}class Rectangle {
|
||||
|
||||
ColoredPoint upperLeft;
|
||||
ColoredPoint lowerRight;
|
||||
Rectangle(ColoredPoint upperLeft, ColoredPoint lowerRight){
|
||||
super(());
|
||||
this.upperLeft = upperLeft;
|
||||
this.lowerRight = lowerRight;
|
||||
}
|
||||
ColoredPoint upperLeft(){
|
||||
return this.upperLeft;
|
||||
}
|
||||
|
||||
ColoredPoint lowerRight(){
|
||||
return this.lowerRight;
|
||||
}
|
||||
|
||||
Rectangle(ColoredPoint upperLeft, ColoredPoint lowerRight){
|
||||
super(());
|
||||
this.upperLeft = upperLeft;
|
||||
this.lowerRight = lowerRight;
|
||||
}
|
||||
|
||||
}class Color {
|
||||
|
||||
Color(){
|
||||
super(());
|
||||
}
|
||||
Color(){
|
||||
super(());
|
||||
}
|
||||
|
||||
}class Blue {
|
||||
|
||||
Blue(){
|
||||
super(());
|
||||
}
|
||||
Blue(){
|
||||
super(());
|
||||
}
|
||||
|
||||
}class Red {
|
||||
|
||||
Red(){
|
||||
super(());
|
||||
}
|
||||
Red(){
|
||||
super(());
|
||||
}
|
||||
|
||||
}class PatternMatching {
|
||||
|
||||
PatternMatching(){
|
||||
super(());
|
||||
}
|
||||
void printColorOfUpperLeftPoint(Shape shape){
|
||||
switch(shape){
|
||||
case Rectangle(ColoredPoint(Point pt, java.lang.String color), ColoredPoint lowerRight):
|
||||
System.out.println Signature: [TPH, TPH](x: op pt.x Signature: [TPH]() op / color: op color op / lowerRight: op lowerRight);
|
||||
|
||||
default:
|
||||
System.out.println Signature: [TPH, TPH](not a rectangle);
|
||||
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
PatternMatching(){
|
||||
super(());
|
||||
}
|
||||
|
||||
}
|
||||
47
resources/syntaxtreegenerator/Record.ast
Normal file
47
resources/syntaxtreegenerator/Record.ast
Normal file
@@ -0,0 +1,47 @@
|
||||
class Point {
|
||||
|
||||
TPH x;
|
||||
TPH y;
|
||||
Point(TPH x, TPH y){
|
||||
super(());
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
TPH x(){
|
||||
return this.x;
|
||||
}
|
||||
|
||||
TPH y(){
|
||||
return this.y;
|
||||
}
|
||||
|
||||
Point(TPH x, TPH y){
|
||||
super(());
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
}class Line {
|
||||
|
||||
TPH pt1;
|
||||
TPH pt2;
|
||||
Line(TPH pt1, TPH pt2){
|
||||
super(());
|
||||
this.pt1 = pt1;
|
||||
this.pt2 = pt2;
|
||||
}
|
||||
TPH pt1(){
|
||||
return this.pt1;
|
||||
}
|
||||
|
||||
TPH pt2(){
|
||||
return this.pt2;
|
||||
}
|
||||
|
||||
Line(TPH pt1, TPH pt2){
|
||||
super(());
|
||||
this.pt1 = pt1;
|
||||
this.pt2 = pt2;
|
||||
}
|
||||
|
||||
}
|
||||
144
resources/syntaxtreegenerator/Sealed.ast
Normal file
144
resources/syntaxtreegenerator/Sealed.ast
Normal file
@@ -0,0 +1,144 @@
|
||||
class Shape {
|
||||
|
||||
Shape(){
|
||||
super(());
|
||||
}
|
||||
Shape(){
|
||||
super(());
|
||||
}
|
||||
|
||||
}class Circle {
|
||||
|
||||
Circle(){
|
||||
super(());
|
||||
}
|
||||
Circle(){
|
||||
super(());
|
||||
}
|
||||
|
||||
}class Rectangle {
|
||||
|
||||
Rectangle(){
|
||||
super(());
|
||||
}
|
||||
Rectangle(){
|
||||
super(());
|
||||
}
|
||||
|
||||
}class TransparentRectangle {
|
||||
|
||||
TransparentRectangle(){
|
||||
super(());
|
||||
}
|
||||
TransparentRectangle(){
|
||||
super(());
|
||||
}
|
||||
|
||||
}class FilledRectangle {
|
||||
|
||||
FilledRectangle(){
|
||||
super(());
|
||||
}
|
||||
FilledRectangle(){
|
||||
super(());
|
||||
}
|
||||
|
||||
}class Square {
|
||||
|
||||
Square(){
|
||||
super(());
|
||||
}
|
||||
Square(){
|
||||
super(());
|
||||
}
|
||||
|
||||
}class WeirdShape {
|
||||
|
||||
WeirdShape(){
|
||||
super(());
|
||||
}
|
||||
WeirdShape(){
|
||||
super(());
|
||||
}
|
||||
|
||||
}class Expr {
|
||||
|
||||
}class ConstantExpr {
|
||||
|
||||
java.lang.Integer i;
|
||||
ConstantExpr(java.lang.Integer i){
|
||||
super(());
|
||||
this.i = i;
|
||||
}
|
||||
java.lang.Integer i(){
|
||||
return this.i;
|
||||
}
|
||||
|
||||
ConstantExpr(java.lang.Integer i){
|
||||
super(());
|
||||
this.i = i;
|
||||
}
|
||||
|
||||
}class PlusExpr {
|
||||
|
||||
Expr a;
|
||||
Expr b;
|
||||
PlusExpr(Expr a, Expr b){
|
||||
super(());
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
Expr a(){
|
||||
return this.a;
|
||||
}
|
||||
|
||||
Expr b(){
|
||||
return this.b;
|
||||
}
|
||||
|
||||
PlusExpr(Expr a, Expr b){
|
||||
super(());
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
}class TimesExpr {
|
||||
|
||||
Expr a;
|
||||
Expr b;
|
||||
TimesExpr(Expr a, Expr b){
|
||||
super(());
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
Expr a(){
|
||||
return this.a;
|
||||
}
|
||||
|
||||
Expr b(){
|
||||
return this.b;
|
||||
}
|
||||
|
||||
TimesExpr(Expr a, Expr b){
|
||||
super(());
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
}class NegExpr {
|
||||
|
||||
Expr e;
|
||||
NegExpr(Expr e){
|
||||
super(());
|
||||
this.e = e;
|
||||
}
|
||||
Expr e(){
|
||||
return this.e;
|
||||
}
|
||||
|
||||
NegExpr(Expr e){
|
||||
super(());
|
||||
this.e = e;
|
||||
}
|
||||
|
||||
}
|
||||
96
resources/syntaxtreegenerator/Switch.ast
Normal file
96
resources/syntaxtreegenerator/Switch.ast
Normal file
@@ -0,0 +1,96 @@
|
||||
class SwitchStatement {
|
||||
|
||||
SwitchStatement(){
|
||||
super(());
|
||||
}
|
||||
TPH switchStandard(){
|
||||
str = SwitchMe;
|
||||
switch(str){
|
||||
case java.lang.String s:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
TPH switchInteger(){
|
||||
i = 5;
|
||||
switch(i){
|
||||
case java.lang.Integer j:
|
||||
case java.lang.String s:
|
||||
i = 6;
|
||||
break;
|
||||
|
||||
default:
|
||||
i = 0;
|
||||
break;
|
||||
|
||||
};
|
||||
return i op 0;
|
||||
}
|
||||
|
||||
TPH guardedPattern(){
|
||||
TPH i;
|
||||
i = 1;
|
||||
switch(i){
|
||||
case java.lang.Integer j:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
TPH recordPattern(java.lang.Object obj){
|
||||
switch(obj){
|
||||
case Coordinates(java.lang.Double lat, java.lang.Double lon):
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
SwitchStatement(){
|
||||
super(());
|
||||
}
|
||||
|
||||
}class SwitchExpression {
|
||||
|
||||
java.lang.Integer x;
|
||||
java.lang.Integer y;
|
||||
SwitchExpression(java.lang.Integer x, java.lang.Integer y){
|
||||
super(());
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
java.lang.Integer x(){
|
||||
return this.x;
|
||||
}
|
||||
|
||||
java.lang.Integer y(){
|
||||
return this.y;
|
||||
}
|
||||
|
||||
java.lang.Boolean switchStandard(TPH str){
|
||||
return switch(str){
|
||||
case java.lang.String s:
|
||||
yield true;
|
||||
|
||||
default:
|
||||
yield false;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
SwitchExpression(java.lang.Integer x, java.lang.Integer y){
|
||||
super(());
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
}
|
||||
36
resources/syntaxtreegenerator/javFiles/Instanceof.jav
Normal file
36
resources/syntaxtreegenerator/javFiles/Instanceof.jav
Normal file
@@ -0,0 +1,36 @@
|
||||
import java.lang.Integer;
|
||||
import java.lang.Double;
|
||||
import java.lang.String;
|
||||
import java.lang.Object;
|
||||
|
||||
public class Instanceof{
|
||||
void checkInstanceof() {
|
||||
var a = 4;
|
||||
return (a instanceof java.lang.Integer);
|
||||
}
|
||||
|
||||
void checkInstanceOfWithPattern(){
|
||||
var b = 4.0;
|
||||
if(b instanceof java.lang.Double d){
|
||||
return d;
|
||||
}else{
|
||||
return "Kein Double";
|
||||
}
|
||||
}
|
||||
|
||||
void checkInstanceOfWithGuardedPattern(){
|
||||
var obj = "test";
|
||||
var flag;
|
||||
if (obj instanceof String s && s.length() > 5) {
|
||||
flag = s.contains("jdk");
|
||||
}
|
||||
}
|
||||
|
||||
record Point(int x, int y){ }
|
||||
|
||||
boolean equals(Object o) {
|
||||
return (o instanceof Point other)
|
||||
&& x == other.x
|
||||
&& y == other.y;
|
||||
}
|
||||
}
|
||||
19
resources/syntaxtreegenerator/javFiles/PatternMatching.jav
Normal file
19
resources/syntaxtreegenerator/javFiles/PatternMatching.jav
Normal file
@@ -0,0 +1,19 @@
|
||||
import java.lang.String;
|
||||
|
||||
record Point(int x, int y) {}
|
||||
interface Shape {}
|
||||
record ColoredPoint(Point pt, String color) {}
|
||||
record Rectangle(ColoredPoint upperLeft, ColoredPoint lowerRight) implements Shape {}
|
||||
sealed class Color permits Blue, Red {}
|
||||
class Blue extends Color {}
|
||||
class Red extends Color {}
|
||||
|
||||
class PatternMatching {
|
||||
void printColorOfUpperLeftPoint(Shape shape)
|
||||
{
|
||||
switch (shape) {
|
||||
case Rectangle(ColoredPoint(Point pt, String color), ColoredPoint lowerRight) -> System.out.println("x: " + pt.x() + " / color: " + color + " / lowerRight: " + lowerRight);
|
||||
default -> System.out.println("not a rectangle");
|
||||
};
|
||||
}
|
||||
}
|
||||
5
resources/syntaxtreegenerator/javFiles/Record.jav
Normal file
5
resources/syntaxtreegenerator/javFiles/Record.jav
Normal file
@@ -0,0 +1,5 @@
|
||||
// Simple records
|
||||
record Point(x, y){ }
|
||||
|
||||
//Combination of records
|
||||
record Line(pt1, pt2){}
|
||||
21
resources/syntaxtreegenerator/javFiles/Sealed.jav
Normal file
21
resources/syntaxtreegenerator/javFiles/Sealed.jav
Normal file
@@ -0,0 +1,21 @@
|
||||
public abstract sealed class Shape
|
||||
permits Circle, Rectangle, Square, WeirdShape { }
|
||||
|
||||
public final class Circle extends Shape { }
|
||||
|
||||
public sealed class Rectangle extends Shape
|
||||
permits TransparentRectangle, FilledRectangle { }
|
||||
public final class TransparentRectangle extends Rectangle { }
|
||||
public final class FilledRectangle extends Rectangle { }
|
||||
|
||||
public final class Square extends Shape { }
|
||||
|
||||
public non-sealed class WeirdShape extends Shape { }
|
||||
|
||||
public sealed interface Expr
|
||||
permits ConstantExpr, PlusExpr, TimesExpr, NegExpr { }
|
||||
|
||||
public record ConstantExpr(int i) implements Expr { }
|
||||
public record PlusExpr(Expr a, Expr b) implements Expr { }
|
||||
public record TimesExpr(Expr a, Expr b) implements Expr { }
|
||||
public record NegExpr(Expr e) implements Expr { }
|
||||
52
resources/syntaxtreegenerator/javFiles/Switch.jav
Normal file
52
resources/syntaxtreegenerator/javFiles/Switch.jav
Normal file
@@ -0,0 +1,52 @@
|
||||
import java.lang.Integer;
|
||||
import java.lang.Boolean;
|
||||
import java.lang.String;
|
||||
import java.lang.Object;
|
||||
|
||||
class SwitchStatement {
|
||||
|
||||
switchStandard(){
|
||||
str = "SwitchMe";
|
||||
switch(str){
|
||||
case String s: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
switchInteger(){
|
||||
i = 5;
|
||||
switch(i){
|
||||
case Integer j:
|
||||
case String s: i = 6; break;
|
||||
default: i = 0; break;
|
||||
}
|
||||
return (i==0);
|
||||
}
|
||||
|
||||
guardedPattern(){
|
||||
var i = 1;
|
||||
switch(i){
|
||||
case Integer j && j == 1: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
record Coordinates(double x, double y) {}
|
||||
|
||||
recordPattern(Object obj){
|
||||
switch(obj){
|
||||
case Coordinates(double lat, double lon): return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
record SwitchExpression(int x, int y){
|
||||
|
||||
boolean switchStandard(str){
|
||||
return switch(str){
|
||||
case String s -> yield true;
|
||||
default -> yield false;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -165,7 +165,7 @@ methodBody
|
||||
;
|
||||
|
||||
refType
|
||||
: typeType # reftype
|
||||
: typeType # refType2
|
||||
| VOID # refvoid
|
||||
;
|
||||
|
||||
@@ -199,11 +199,7 @@ interfaceMemberDeclaration
|
||||
: constDeclaration # interfaceconst
|
||||
| interfaceMethodDeclaration # interfacemethod
|
||||
| genericInterfaceMethodDeclaration # genericinterfacemethod
|
||||
| interfaceDeclaration # subinterface
|
||||
| annotationTypeDeclaration # interfaceannotationtype
|
||||
| classDeclaration # interfaceclass
|
||||
| enumDeclaration # interfaceenum
|
||||
| recordDeclaration # interfacerecord // Java17
|
||||
| classOrInterface # subclassorinterface
|
||||
;
|
||||
|
||||
constDeclaration
|
||||
@@ -308,6 +304,7 @@ formalParameterList
|
||||
|
||||
formalParameter
|
||||
: variableModifier* typeType? variableDeclaratorId
|
||||
| pattern // Pattern matching for Methods
|
||||
;
|
||||
|
||||
lastFormalParameter
|
||||
@@ -391,11 +388,7 @@ annotationTypeElementDeclaration
|
||||
|
||||
annotationTypeElementRest
|
||||
: typeType annotationMethodOrConstantRest ';'
|
||||
| classDeclaration ';'?
|
||||
| interfaceDeclaration ';'?
|
||||
| enumDeclaration ';'?
|
||||
| annotationTypeDeclaration ';'?
|
||||
| recordDeclaration ';'? // Java17
|
||||
| classOrInterface ';'?
|
||||
;
|
||||
|
||||
annotationMethodOrConstantRest
|
||||
@@ -538,7 +531,6 @@ statement
|
||||
| YIELD expression ';' #yieldstmt // Java17
|
||||
| SEMI #semistmt
|
||||
| statementExpression=expression ';' #stmtexpression
|
||||
| switchExpression ';'? #switchexpressionstmt // Java17
|
||||
| identifierLabel=identifier ':' statement #labeledstmt
|
||||
;
|
||||
|
||||
@@ -575,8 +567,10 @@ switchBlockStatementGroup
|
||||
;
|
||||
|
||||
switchLabel
|
||||
: CASE (constantExpression=expression | enumConstantName=IDENTIFIER | pattern) ':'
|
||||
| DEFAULT ':'
|
||||
: CASE constantExpression=expression ':' #switchLabelConst
|
||||
| CASE enumConstantName=IDENTIFIER ':' #switchLabelEnum
|
||||
| CASE pattern ':' #switchLabelPattern
|
||||
| DEFAULT ':' #switchLabelDefault
|
||||
;
|
||||
|
||||
forControl
|
||||
@@ -610,7 +604,7 @@ methodCall
|
||||
;
|
||||
|
||||
expression
|
||||
: primary #primaryexpression
|
||||
: primary #primaryExpression2
|
||||
| expression bop='.'
|
||||
(
|
||||
identifier
|
||||
@@ -641,8 +635,8 @@ expression
|
||||
| <assoc=right> expression
|
||||
bop=('=' | '+=' | '-=' | '*=' | '/=' | '&=' | '|=' | '^=' | '>>=' | '>>>=' | '<<=' | '%=')
|
||||
expression #assignexpression
|
||||
| lambdaExpression #lambdaexpression // Java8
|
||||
| switchExpression #switchexpression // Java17
|
||||
| lambdaExpression #lambdaExpression2 // Java8
|
||||
| switchExpression #switchExpression2 // Java17
|
||||
|
||||
// Java 8 methodReference
|
||||
| expression '::' typeArguments? identifier #methodreferenceexpression
|
||||
@@ -652,14 +646,14 @@ expression
|
||||
|
||||
// Java17
|
||||
pattern
|
||||
: primaryPattern
|
||||
| guardedPattern
|
||||
: primaryPattern #pPattern
|
||||
| guardedPattern #gPattern
|
||||
;
|
||||
|
||||
primaryPattern
|
||||
: typePattern
|
||||
| recordPattern
|
||||
| '(' pattern ')'
|
||||
: typePattern #tPattern
|
||||
| recordPattern #rPattern
|
||||
| '(' pattern ')' #enclosedPattern
|
||||
;
|
||||
|
||||
recordPattern
|
||||
@@ -667,13 +661,18 @@ recordPattern
|
||||
;
|
||||
|
||||
typePattern
|
||||
: variableModifier* typeType? identifier
|
||||
: variableModifier* typeType identifier
|
||||
;
|
||||
|
||||
recordStructurePattern
|
||||
: '(' recordComponentPatternList? ')'
|
||||
;
|
||||
|
||||
recordComponentPatternElement
|
||||
: pattern
|
||||
| identifier
|
||||
;
|
||||
|
||||
recordComponentPatternList
|
||||
: pattern (',' pattern)*
|
||||
;
|
||||
@@ -714,20 +713,25 @@ switchExpression
|
||||
|
||||
// Java17
|
||||
switchLabeledRule
|
||||
: CASE (expressionList | NULL_LITERAL | pattern) (ARROW | COLON) switchRuleOutcome
|
||||
| DEFAULT (ARROW | COLON) switchRuleOutcome
|
||||
: switchLabelCase switchRuleOutcome
|
||||
;
|
||||
|
||||
// Java17
|
||||
switchLabelCase
|
||||
: CASE expressionList (ARROW | COLON) #labeledRuleExprList
|
||||
| CASE NULL_LITERAL (ARROW | COLON) #labeledRuleNull
|
||||
| CASE pattern (ARROW | COLON) #labeledRulePattern
|
||||
| DEFAULT (ARROW | COLON) #labeledRuleDefault
|
||||
;
|
||||
|
||||
// Java20
|
||||
guardedPattern
|
||||
: variableModifier* typeType? annotation* identifier ('&&' expression)*
|
||||
| guardedPattern '&&' expression
|
||||
: primaryPattern WITH expression
|
||||
;
|
||||
|
||||
// Java17
|
||||
switchRuleOutcome
|
||||
: block
|
||||
| blockStatement*
|
||||
| expression ';'
|
||||
;
|
||||
|
||||
classType
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -28,12 +28,15 @@ public class FunNGenerator {
|
||||
private static final String objectSuperType = Type.getInternalName(Object.class).replace('.','/');
|
||||
private static final String objectSignature = applySignature(TargetType.Object);
|
||||
|
||||
private static final String VOID = "Ljava/lang/Void;";
|
||||
|
||||
public static class GenericParameters {
|
||||
int start;
|
||||
public List<TargetType> parameters = new ArrayList<>();
|
||||
}
|
||||
|
||||
private static String applyDescriptor(TargetType type, GenericParameters gep) {
|
||||
if (type == null) return VOID;
|
||||
var res = "L" + type.getInternalName();
|
||||
if (type instanceof TargetSpecializedType a) {
|
||||
if (a.params().size() > 0) {
|
||||
@@ -59,7 +62,12 @@ public class FunNGenerator {
|
||||
}
|
||||
|
||||
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)); }
|
||||
private static String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("%s", applySignature(a)); }
|
||||
|
||||
public static String encodeType(TargetType type) {
|
||||
if (type == null) return VOID;
|
||||
return applyNameDescriptor(type).replace("/", "$").replace(";", "$_$");
|
||||
}
|
||||
|
||||
public static byte[] generateSuperBytecode(int numberArguments) {
|
||||
StringBuilder superFunNClassSignature = new StringBuilder("<");
|
||||
@@ -127,14 +135,12 @@ public class FunNGenerator {
|
||||
|
||||
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(";", "$_$");
|
||||
argumentTypes.size(),
|
||||
argumentTypes
|
||||
.stream()
|
||||
.map(FunNGenerator::encodeType)
|
||||
.collect(Collectors.joining()),
|
||||
encodeType(returnType));
|
||||
}
|
||||
|
||||
public static List<TargetType> getArguments(List<TargetType> list) {
|
||||
|
||||
@@ -12,12 +12,12 @@ import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SourceFileContext;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.ParameterList;
|
||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
|
||||
@@ -31,6 +31,7 @@ import de.dhbwstuttgart.syntaxtree.type.TypeVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.visual.ASTTypePrinter;
|
||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||
import de.dhbwstuttgart.target.generate.GenericsResult;
|
||||
import de.dhbwstuttgart.target.tree.expression.TargetBinaryOp;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
@@ -44,7 +45,6 @@ import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
|
||||
import de.dhbwstuttgart.util.BiRelation;
|
||||
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyResultListener;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl;
|
||||
@@ -62,7 +62,6 @@ import java.util.Map.Entry;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.apache.commons.io.output.NullOutputStream;
|
||||
|
||||
public class JavaTXCompiler {
|
||||
@@ -70,11 +69,18 @@ public class JavaTXCompiler {
|
||||
// public static JavaTXCompiler INSTANCE;
|
||||
final CompilationEnvironment environment;
|
||||
Boolean resultmodel = false;
|
||||
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
||||
Boolean log = false; // gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll?
|
||||
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
||||
private final DirectoryClassLoader classLoader;
|
||||
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
||||
|
||||
Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll?
|
||||
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
||||
private final DirectoryClassLoader classLoader;
|
||||
|
||||
private final List<File> classPath;
|
||||
|
||||
public DirectoryClassLoader getClassLoader() {
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
|
||||
this(Arrays.asList(sourceFile), null);
|
||||
}
|
||||
@@ -95,12 +101,32 @@ public class JavaTXCompiler {
|
||||
}
|
||||
classLoader = new DirectoryClassLoader(contextPath, ClassLoader.getSystemClassLoader());
|
||||
environment = new CompilationEnvironment(sources);
|
||||
classPath = contextPath;
|
||||
|
||||
for (File s : sources) {
|
||||
sourceFiles.put(s, parse(s));
|
||||
parse(s);
|
||||
}
|
||||
// INSTANCE = this;
|
||||
}
|
||||
|
||||
private void addSourceFile(File file, SourceFile sf) {
|
||||
sourceFiles.put(file, sf);
|
||||
}
|
||||
|
||||
public ClassOrInterface getClass(JavaClassName name) {
|
||||
for (var sf : sourceFiles.values()) {
|
||||
for (var clazz : sf.KlassenVektor) {
|
||||
if (clazz.getClassName().equals(name)) return clazz;
|
||||
}
|
||||
}
|
||||
try {
|
||||
var clazz = classLoader.loadClass(name.toString());
|
||||
if (clazz != null)
|
||||
return ASTFactory.createClass(clazz);
|
||||
} catch (ClassNotFoundException ignored) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException, IOException {
|
||||
List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses();
|
||||
List<ClassOrInterface> importedClasses = new ArrayList<>();
|
||||
@@ -108,11 +134,9 @@ public class JavaTXCompiler {
|
||||
// Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
|
||||
for (Entry<File, SourceFile> source : sourceFiles.entrySet()) {
|
||||
for (JavaClassName name : source.getValue().getImports()) {
|
||||
// TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet
|
||||
ClassOrInterface importedClass = ASTFactory.createClass(classLoader.loadClass(name.toString()));
|
||||
importedClasses.add(importedClass);
|
||||
importedClasses.addAll(getAvailableClasses(name));
|
||||
}
|
||||
for (Class c : CompilationEnvironment.loadDefaultPackageClasses(source.getValue().getPkgName(), source.getKey(), classLoader)) {
|
||||
for (Class c : CompilationEnvironment.loadDefaultPackageClasses(source.getValue().getPkgName(), source.getKey(), this)) {
|
||||
ClassOrInterface importedClass = ASTFactory.createClass(c);
|
||||
importedClasses.add(importedClass);
|
||||
}
|
||||
@@ -135,22 +159,23 @@ public class JavaTXCompiler {
|
||||
void addMethods(SourceFile sf, ClassOrInterface cl, List<ClassOrInterface> importedClasses, ClassOrInterface objectClass) {
|
||||
if (!cl.areMethodsAdded()) {
|
||||
ClassOrInterface superclass = null;
|
||||
if (cl.getSuperClass().getName().equals(new JavaClassName("java.lang.Object"))) {
|
||||
superclass = objectClass;
|
||||
Optional<ClassOrInterface> optSuperclass = importedClasses.stream().filter(x -> x.getClassName().equals(cl.getSuperClass().getName())).findFirst();
|
||||
if (optSuperclass.isPresent()) {
|
||||
superclass = optSuperclass.get();
|
||||
} else {
|
||||
Optional<ClassOrInterface> optSuperclass = importedClasses.stream().filter(x -> x.getClassName().equals(cl.getSuperClass().getName())).findFirst();
|
||||
optSuperclass = sf.KlassenVektor.stream().filter(x -> x.getClassName().equals(cl.getSuperClass().getName())).findFirst();
|
||||
if (optSuperclass.isPresent()) {
|
||||
superclass = optSuperclass.get();
|
||||
addMethods(sf, superclass, importedClasses, objectClass);
|
||||
} else {
|
||||
optSuperclass = sf.KlassenVektor.stream().filter(x -> x.getClassName().equals(cl.getSuperClass().getName())).findFirst();
|
||||
if (optSuperclass.isPresent()) {
|
||||
superclass = optSuperclass.get();
|
||||
addMethods(sf, superclass, importedClasses, objectClass);
|
||||
} else {
|
||||
// throw new ClassNotFoundException("");
|
||||
}
|
||||
try {
|
||||
var className = cl.getSuperClass().getName().toString();
|
||||
superclass = ASTFactory.createClass(classLoader.loadClass(className));
|
||||
} catch (ClassNotFoundException ignored) {}
|
||||
// throw new ClassNotFoundException("");
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<RefTypeOrTPHOrWildcardOrGeneric> paraIt = cl.getSuperClass().getParaList().iterator();
|
||||
Iterator<GenericTypeVar> tvarVarIt = superclass.getGenerics().iterator();
|
||||
|
||||
@@ -163,7 +188,7 @@ public class JavaTXCompiler {
|
||||
// werden
|
||||
while (methodIt.hasNext()) {
|
||||
Method m = methodIt.next();
|
||||
ParameterList newParaList = new ParameterList(m.getParameterList().getFormalparalist().stream().map(fp -> new FormalParameter(fp.getName(), fp.getType().acceptTV(new TypeExchanger(gtvs)), fp.getOffset())).collect(Collectors.toCollection(ArrayList::new)), m.getParameterList().getOffset());
|
||||
ParameterList newParaList = new ParameterList(m.getParameterList().getFormalparalist().stream().map(fp -> fp.withType(fp.getType().acceptTV(new TypeExchanger(gtvs)))).collect(Collectors.toCollection(ArrayList::new)), m.getParameterList().getOffset());
|
||||
cl.getMethods().add(new Method(m.modifier, m.name, m.getReturnType().acceptTV(new TypeExchanger(gtvs)), newParaList, m.block,
|
||||
// new GenericDeclarationList(newGenericsList,
|
||||
// ((GenericDeclarationList)m.getGenerics()).getOffset()),
|
||||
@@ -174,6 +199,19 @@ public class JavaTXCompiler {
|
||||
cl.setMethodsAdded();
|
||||
}
|
||||
|
||||
private List<ClassOrInterface> getAvailableClasses(JavaClassName name) throws ClassNotFoundException {
|
||||
Set<ClassOrInterface> allClasses = new HashSet<>();
|
||||
if (loadJavaTXClass(name)) {
|
||||
var file = findFileForClass(name);
|
||||
var sf = sourceFiles.get(file);
|
||||
if (sf != null) allClasses.addAll(sf.KlassenVektor);
|
||||
} else {
|
||||
ClassOrInterface importedClass = ASTFactory.createClass(classLoader.loadClass(name.toString()));
|
||||
allClasses.add(importedClass);
|
||||
}
|
||||
return new ArrayList<>(allClasses);
|
||||
}
|
||||
|
||||
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
|
||||
// PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal
|
||||
// hinzugefuegt werden
|
||||
@@ -181,22 +219,8 @@ public class JavaTXCompiler {
|
||||
// ArrayList<>();//environment.getAllAvailableClasses();
|
||||
Set<ClassOrInterface> allClasses = new HashSet<>();
|
||||
|
||||
/*
|
||||
* PL 2018-09-19 geloescht werden bereits in typeInference hinzugefuegt } allClasses.addAll(importedClasses);
|
||||
*
|
||||
* return new TYPE(sourceFiles.values(), allClasses).getConstraints(); }
|
||||
*
|
||||
* public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException { // PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal // hinzugefuegt werden // List<ClassOrInterface> allClasses = new // ArrayList<>();//environment.getAllAvailableClasses(); Set<ClassOrInterface> allClasses = new HashSet<>();
|
||||
*
|
||||
* /* PL 2018-09-19 geloescht werden bereits in typeInference hinzugefuegt for (SourceFile sf : sourceFiles.values()) { allClasses.addAll(sf.getClasses()); }
|
||||
*/
|
||||
|
||||
List<ClassOrInterface> importedClasses = new ArrayList<>();
|
||||
for (JavaClassName name : forSourceFile.getImports()) {
|
||||
// TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet
|
||||
ClassOrInterface importedClass = ASTFactory.createClass(classLoader.loadClass(name.toString()));
|
||||
importedClasses.add(importedClass);
|
||||
allClasses.addAll(importedClasses);
|
||||
allClasses.addAll(getAvailableClasses(name));
|
||||
}
|
||||
return new ArrayList<>(allClasses);
|
||||
}
|
||||
@@ -251,7 +275,7 @@ public class JavaTXCompiler {
|
||||
SourceFile sf = source.getValue();
|
||||
allClasses.addAll(getAvailableClasses(sf));
|
||||
allClasses.addAll(sf.getClasses());
|
||||
allClasses.addAll(CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), source.getKey(), classLoader).stream().map(ASTFactory::createClass).collect(Collectors.toList()));
|
||||
allClasses.addAll(CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), source.getKey(), this).stream().map(ASTFactory::createClass).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
final ConstraintSet<Pair> cons = getConstraints();
|
||||
@@ -260,7 +284,7 @@ public class JavaTXCompiler {
|
||||
// urm.addUnifyResultListener(resultListener);
|
||||
try {
|
||||
logFile = logFile == null ? new FileWriter(new File("log_" + sourceFiles.keySet().iterator().next().getName())) : logFile;
|
||||
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, classLoader);
|
||||
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, getClassLoader());
|
||||
System.out.println(finiteClosure);
|
||||
urm = new UnifyResultModel(cons, finiteClosure);
|
||||
urm.addUnifyResultListener(resultListener);
|
||||
@@ -382,16 +406,12 @@ public class JavaTXCompiler {
|
||||
SourceFile sf = source.getValue();
|
||||
allClasses.addAll(getAvailableClasses(sf));
|
||||
allClasses.addAll(sf.getClasses());
|
||||
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), source.getKey(), classLoader).stream().map(ASTFactory::createClass).collect(Collectors.toList());
|
||||
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), source.getKey(), this).stream().map(ASTFactory::createClass).collect(Collectors.toList());
|
||||
for (var clazz : newClasses) {
|
||||
var found = false;
|
||||
for (var old : allClasses) {
|
||||
if (clazz.getClassName().equals(old.getClassName())) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
// Don't load classes that get recompiled
|
||||
if (sf.getClasses().stream().anyMatch(nf -> nf.getClassName().equals(clazz.getClassName())))
|
||||
continue;
|
||||
if (allClasses.stream().noneMatch(old -> old.getClassName().equals(clazz.getClassName())))
|
||||
allClasses.add(clazz);
|
||||
}
|
||||
}
|
||||
@@ -399,7 +419,9 @@ public class JavaTXCompiler {
|
||||
final ConstraintSet<Pair> cons = getConstraints();
|
||||
Set<Set<UnifyPair>> results = new HashSet<>();
|
||||
try {
|
||||
Writer logFile = log ? new FileWriter(new File(System.getProperty("user.dir") + "/logFiles/" + "log_" + sourceFiles.keySet().iterator().next().getName())) : new OutputStreamWriter(new NullOutputStream());
|
||||
var logFolder = new File(System.getProperty("user.dir") + "/logFiles/");
|
||||
if (log) logFolder.mkdirs();
|
||||
Writer logFile = log ? new FileWriter(new File(logFolder, "log_" + sourceFiles.keySet().iterator().next().getName())) : new OutputStreamWriter(new NullOutputStream());
|
||||
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, classLoader);
|
||||
System.out.println(finiteClosure);
|
||||
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons);
|
||||
@@ -624,11 +646,53 @@ public class JavaTXCompiler {
|
||||
return usedTPH;
|
||||
}
|
||||
|
||||
public final JavaClassRegistry classRegistry = new JavaClassRegistry();
|
||||
|
||||
private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException {
|
||||
SourceFileContext tree = JavaTXParser.parse(sourceFile);
|
||||
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(tree, sourceFile, classLoader), new GenericsRegistry(null));
|
||||
SourceFile ret = generator.convert(tree, environment.packageCrawler, classLoader);
|
||||
return ret;
|
||||
environment.addClassesToRegistry(classRegistry, tree, sourceFile, this);
|
||||
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null));
|
||||
var classes = new ArrayList<ClassOrInterface>();
|
||||
var sf = new SourceFile(generator.pkgName, classes, generator.imports);
|
||||
addSourceFile(sourceFile, sf);
|
||||
generator.convert(classes, tree, environment.packageCrawler);
|
||||
sf.imports.addAll(generator.imports);
|
||||
return sf;
|
||||
}
|
||||
|
||||
/**
|
||||
* When an import tries to import a JavaTX class it first looks it up in the cache and
|
||||
* if it doesn't exist it's going to compile it and add it to the source files list
|
||||
* @param name
|
||||
*/
|
||||
public boolean loadJavaTXClass(JavaClassName name) {
|
||||
var file = findFileForClass(name);
|
||||
if (file != null) {
|
||||
try {
|
||||
var tree = JavaTXParser.parse(file);
|
||||
classRegistry.addName(name.toString(), 0); // TODO This gets overwritten later, is it bad if we don't know this right away?
|
||||
environment.addClassesToRegistry(classRegistry, tree, file, this);
|
||||
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null));
|
||||
var classes = new ArrayList<ClassOrInterface>();
|
||||
var sf = new SourceFile(generator.pkgName, classes, generator.imports);
|
||||
addSourceFile(file, sf);
|
||||
generator.convert(classes, tree, environment.packageCrawler);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public File findFileForClass(JavaClassName name) {
|
||||
var packageName = name.getPackageName();
|
||||
var className = name.getClassName().split("\\.")[0];
|
||||
for (var cp : classPath) {
|
||||
var file = new File(cp, packageName.replaceAll("\\.", "/") + "/" + className + ".jav");
|
||||
if (file.exists()) return file;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void generateBytecode() throws ClassNotFoundException, IOException {
|
||||
@@ -681,10 +745,10 @@ public class JavaTXCompiler {
|
||||
}
|
||||
|
||||
public synchronized Map<JavaClassName, byte[]> generateBytecode(SourceFile sf, List<ResultSet> typeInferenceResult) {
|
||||
var converter = new ASTToTargetAST(typeInferenceResult, sf, classLoader);
|
||||
var converter = new ASTToTargetAST(this, typeInferenceResult, sf, classLoader);
|
||||
var generatedClasses = new HashMap<JavaClassName, byte[]>();
|
||||
for (var clazz : sf.getClasses()) {
|
||||
var codegen = new Codegen(converter.convert(clazz));
|
||||
var codegen = new Codegen(converter.convert(clazz), this);
|
||||
var code = codegen.generate();
|
||||
generatedClasses.put(clazz.getClassName(), code);
|
||||
converter.auxiliaries.forEach((name, source) -> {
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.net.URL;
|
||||
import java.util.*;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
|
||||
@@ -56,21 +57,22 @@ public class CompilationEnvironment {
|
||||
this.packageCrawler = new PackageCrawler(librarys);
|
||||
}
|
||||
|
||||
public JavaClassRegistry getRegistry(SourceFileContext tree, File sourceFile, ClassLoader classLoader) throws ClassNotFoundException, IOException {
|
||||
public void addClassesToRegistry(JavaClassRegistry registry, SourceFileContext tree, File sourceFile, JavaTXCompiler compiler) throws ClassNotFoundException, IOException {
|
||||
Map<String, Integer> allNames;
|
||||
if (tree instanceof SrcfileContext srcfile) {
|
||||
allNames = GatherNames.getNames((SrcfileContext) tree, packageCrawler, classLoader);
|
||||
for (Class c : loadDefaultPackageClasses(getPackageName(srcfile), sourceFile, classLoader)) {
|
||||
allNames = GatherNames.getNames((SrcfileContext) tree, packageCrawler, compiler);
|
||||
for (Class c : loadDefaultPackageClasses(getPackageName(srcfile), sourceFile, compiler)) {
|
||||
allNames.put(c.getName(), c.getTypeParameters().length);
|
||||
}
|
||||
return new JavaClassRegistry(allNames);
|
||||
registry.addNames(allNames);
|
||||
} else {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static List<Class> loadDefaultPackageClasses(String packageName, File sourceFile, ClassLoader classLoader) throws IOException, ClassNotFoundException {
|
||||
public static List<Class> loadDefaultPackageClasses(String packageName, File sourceFile, JavaTXCompiler compiler) throws IOException, ClassNotFoundException {
|
||||
ClassLoader classLoader = compiler.getClassLoader();
|
||||
List<Class> ret = new ArrayList<>();
|
||||
// Set classLoader to include default package for this specific source file
|
||||
File dir = sourceFile.getParentFile();
|
||||
|
||||
@@ -2,8 +2,11 @@ package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.Pattern;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
@@ -31,13 +34,36 @@ public class FCGenerator {
|
||||
//PL 2018-09-18: gtvs vor die for-Schleife gezogen, damit immer die gleichen Typeplaceholder eingesetzt werden.
|
||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>();
|
||||
for(ClassOrInterface cly : availableClasses){
|
||||
pairs.addAll(getSuperTypes(cly, availableClasses, gtvs, classLoader));
|
||||
List<Pair> newPairs = getSuperTypes(cly, availableClasses, gtvs, classLoader);
|
||||
pairs.addAll(newPairs);
|
||||
|
||||
//For all Functional Interfaces FI: FunN$$<... args auf dem Functional Interface ...> <. FI is added to FC
|
||||
if (isFunctionalInterface(cly)) {
|
||||
pairs.add(genImplFunType(cly, newPairs.get(0).TA1, gtvs));
|
||||
}
|
||||
}
|
||||
return pairs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static Boolean isFunctionalInterface(ClassOrInterface cly) {
|
||||
return (cly.isInterface() && (cly.isFunctionalInterface() || cly.getMethods().size() == 1));
|
||||
}
|
||||
|
||||
private static Pair genImplFunType(ClassOrInterface cly, RefTypeOrTPHOrWildcardOrGeneric fIType, HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs) {
|
||||
for(Method m : cly.getMethods()) {
|
||||
if (!java.lang.reflect.Modifier.isAbstract(m.modifier))
|
||||
continue;
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> tl =
|
||||
(m.getParameterList().getFormalparalist()
|
||||
.stream().map(p -> p.getType().acceptTV(new TypeExchanger(gtvs)))
|
||||
.collect(Collectors.toList()));
|
||||
tl.add(m.getReturnType().acceptTV(new TypeExchanger(gtvs)));
|
||||
return new Pair(new RefType(new JavaClassName("Fun" + (tl.size()-1) + "$$"), tl, new NullToken()),
|
||||
fIType);
|
||||
}
|
||||
return null; //kann nicht passieren, da die Methode nur aufgerufen wird wenn cl Functional Interface ist
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
|
||||
public record FieldEntry(String name, RefTypeOrTPHOrWildcardOrGeneric type, int modifiers) {
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@@ -8,6 +9,10 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
@@ -34,11 +39,17 @@ import de.dhbwstuttgart.parser.antlr.Java17Parser.EqualityexpressionContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.ExpressionContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.FltLiteralContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.ForloopContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.GPatternContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.GuardedPatternContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.IdentifierContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.InstanceofexpressionContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.IntLiteralContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.LabeledRuleDefaultContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.LabeledRuleExprListContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.LabeledRulePatternContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.LabeledstmtContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.LambdaLVTIParameterContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.LambdaexpressionContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.LambdaExpression2Context;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.MathaddsubexpressionContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.MathmuldivmodexpressionContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.MethodCallContext;
|
||||
@@ -46,81 +57,74 @@ import de.dhbwstuttgart.parser.antlr.Java17Parser.MethodcallexpressionContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.NewinstanceexpressionContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.NullLiteralContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.OrexpressionContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.PPatternContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.PatternContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.PostfixexpressionContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrefixexpressionContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrimaryClassrefContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrimaryExpressionContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrimaryIdentifierContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrimaryLiteralContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrimaryPatternContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrimarySuperContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrimaryThisContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrimaryexpressionContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrimaryExpression2Context;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.RPatternContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.RecordPatternContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.RelationalexpressionContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.ReturnstmtContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SemistmtContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.ShiftexpressionContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.StmtexpressionContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.StringLiteralContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchexpressionstmtContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchBlockStatementGroupContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchLabelConstContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchLabelContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchLabelDefaultContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchLabelPatternContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchLabeledRuleContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchRuleOutcomeContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchExpression2Context;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchstmtContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SynchronizedstmtContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.TPatternContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.ThrowstmtContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.TrycatchblockContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.TrycatchresourceContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.TypePatternContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.WhileloopContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.YieldstmtContext;
|
||||
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||
import de.dhbwstuttgart.syntaxtree.ParameterList;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Assign;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.AssignLeftSide;
|
||||
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.Expression;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.ExpressionReceiver;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.FieldVar;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.IfStmt;
|
||||
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.NewClass;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Receiver;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Return;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.ReturnVoid;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.StaticClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Super;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.This;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.WhileStmt;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
|
||||
public class StatementGenerator {
|
||||
|
||||
private JavaClassRegistry reg;
|
||||
private Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields; // PL 2018-11-01 fields eingefuegt, damit die fields
|
||||
// immer die gleiche TPH bekommen
|
||||
private Map<String, RefTypeOrTPHOrWildcardOrGeneric> localVars;
|
||||
private GenericsRegistry generics;
|
||||
private final JavaClassRegistry reg;
|
||||
|
||||
public StatementGenerator(JavaClassRegistry reg, GenericsRegistry generics, Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields, Map<String, RefTypeOrTPHOrWildcardOrGeneric> localVars) {
|
||||
private final Map<String, FieldEntry> fields; // PL 2018-11-01 fields eingefuegt, damit die fields
|
||||
// immer die gleiche TPH bekommen
|
||||
private final Map<String, RefTypeOrTPHOrWildcardOrGeneric> localVars;
|
||||
private final GenericsRegistry generics;
|
||||
private final JavaTXCompiler compiler;
|
||||
|
||||
private final RefType superClass;
|
||||
|
||||
// TODO How about instead of passing all of these types we just pass an instance of the SyntaxTreeGenerator?
|
||||
public StatementGenerator(RefType superType, JavaTXCompiler compiler, JavaClassRegistry reg, GenericsRegistry generics, Map<String, FieldEntry> fields, Map<String, RefTypeOrTPHOrWildcardOrGeneric> localVars) {
|
||||
this.reg = reg;
|
||||
this.generics = generics;
|
||||
this.fields = fields;
|
||||
this.localVars = localVars;
|
||||
this.compiler = compiler;
|
||||
this.superClass = superType;
|
||||
}
|
||||
|
||||
public ParameterList convert(Java17Parser.FormalParameterListContext formalParameterListContext) {
|
||||
List<FormalParameter> ret = new ArrayList<>();
|
||||
List<Pattern> ret = new ArrayList<>();
|
||||
List<Java17Parser.FormalParameterContext> fps = new ArrayList<>();
|
||||
if (Objects.isNull(formalParameterListContext))
|
||||
return new ParameterList(ret, new NullToken()); // Dann ist die Parameterliste leer
|
||||
@@ -133,15 +137,19 @@ public class StatementGenerator {
|
||||
|
||||
fps = formalParameterListContext.formalParameter();
|
||||
for (Java17Parser.FormalParameterContext fp : fps) {
|
||||
String paramName = SyntaxTreeGenerator.convert(fp.variableDeclaratorId());
|
||||
RefTypeOrTPHOrWildcardOrGeneric type;
|
||||
if (fp.typeType() != null) {
|
||||
type = TypeGenerator.convert(fp.typeType(), reg, generics);
|
||||
if (fp.pattern() != null) {
|
||||
ret.add(convert(fp.pattern()));
|
||||
} else {
|
||||
type = TypePlaceholder.fresh(fp.getStart());
|
||||
String paramName = SyntaxTreeGenerator.convert(fp.variableDeclaratorId());
|
||||
RefTypeOrTPHOrWildcardOrGeneric type;
|
||||
if (fp.typeType() != null) {
|
||||
type = TypeGenerator.convert(fp.typeType(), reg, generics);
|
||||
} else {
|
||||
type = TypePlaceholder.fresh(fp.getStart());
|
||||
}
|
||||
ret.add(new FormalParameter(paramName, type, fp.getStart()));
|
||||
localVars.put(paramName, type);
|
||||
}
|
||||
ret.add(new FormalParameter(paramName, type, fp.getStart()));
|
||||
localVars.put(paramName, type);
|
||||
}
|
||||
return new ParameterList(ret, ret.get(0).getOffset());
|
||||
}
|
||||
@@ -162,8 +170,6 @@ public class StatementGenerator {
|
||||
return convert(dowhileloop);
|
||||
case SwitchstmtContext switchstmt:
|
||||
return convert(switchstmt);
|
||||
case SwitchexpressionstmtContext switchexpression:
|
||||
return convert(switchexpression);
|
||||
case ReturnstmtContext returnstmt:
|
||||
return convert(returnstmt);
|
||||
case YieldstmtContext yieldstmt:
|
||||
@@ -243,7 +249,12 @@ public class StatementGenerator {
|
||||
ret = convert(prefix);
|
||||
ret.setStatement();
|
||||
return ret;
|
||||
case SwitchExpression2Context switchexpr:
|
||||
ret = convert(switchexpr);
|
||||
ret.setStatement();
|
||||
return ret;
|
||||
default:
|
||||
System.out.println(stmt.getClass());
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -317,23 +328,152 @@ public class StatementGenerator {
|
||||
}
|
||||
|
||||
private Statement convert(Java17Parser.SwitchstmtContext stmt) {
|
||||
// TODO
|
||||
throw new NotImplementedException();
|
||||
Expression switched = convert(stmt.parExpression().expression());
|
||||
List<SwitchBlock> switchBlocks = new ArrayList<>();
|
||||
for (SwitchBlockStatementGroupContext blockstmt : stmt.switchBlockStatementGroup()) {
|
||||
switchBlocks.add(convert(blockstmt));
|
||||
}
|
||||
return new Switch(switched, switchBlocks, TypePlaceholder.fresh(switched.getOffset()), true, stmt.getStart());
|
||||
}
|
||||
|
||||
private Statement convert(Java17Parser.SwitchexpressionstmtContext switchexpression) {
|
||||
// TODO
|
||||
throw new NotImplementedException();
|
||||
// Um switchExpressions als Statement zu behandeln
|
||||
private Statement convert(Java17Parser.SwitchExpression2Context switchexpression) {
|
||||
Expression switchExpr = convert(switchexpression.switchExpression());
|
||||
if (switchExpr instanceof Switch s) {
|
||||
s.setStatement();
|
||||
return s;
|
||||
} else {
|
||||
// sollte nie vorkommen, da convert(Java17Parser.SwitchExpressionContext switchExpression) eine Instanz von Switch zurückgibt
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
private Expression convert(Java17Parser.SwitchExpressionContext switchExpression) {
|
||||
Expression switched = convert(switchExpression.parExpression().expression());
|
||||
List<SwitchBlock> switchBlocks = new ArrayList<>();
|
||||
Token offset = switchExpression.getStart();
|
||||
for (SwitchLabeledRuleContext labeledRule : switchExpression.switchLabeledRule()) {
|
||||
switchBlocks.add(convert(labeledRule));
|
||||
}
|
||||
return new Switch(switched, switchBlocks, TypePlaceholder.fresh(offset), false, offset);
|
||||
}
|
||||
|
||||
private SwitchBlock convert(SwitchLabeledRuleContext labeledRule) {
|
||||
Boolean isDefault = false;
|
||||
List<SwitchLabel> labels = switch (labeledRule.switchLabelCase()) {
|
||||
case LabeledRuleExprListContext exprList -> {
|
||||
List<SwitchLabel> labelList = exprList.expressionList().expression().stream().map((exprctx) -> {
|
||||
Pattern expr = new ExpressionPattern(convert(exprctx), exprList.getStart());
|
||||
return new SwitchLabel(expr, expr.getType(), exprList.getStart());
|
||||
}).toList();
|
||||
yield labelList;
|
||||
}
|
||||
case LabeledRulePatternContext pattern -> {
|
||||
Pattern p = convert(pattern.pattern());
|
||||
yield Arrays.asList(new SwitchLabel(p, p.getType(), pattern.getStart()));
|
||||
}
|
||||
case LabeledRuleDefaultContext def -> {
|
||||
isDefault = true;
|
||||
yield Arrays.asList(new SwitchLabel(new Void(def.getStart()), def.getStart()));
|
||||
}
|
||||
default -> throw new NotImplementedException();
|
||||
};
|
||||
|
||||
var isSingleExpression = false;
|
||||
Token offset = labeledRule.getStart();
|
||||
SwitchRuleOutcomeContext outcome = labeledRule.switchRuleOutcome();
|
||||
Block block;
|
||||
if (Objects.isNull(outcome.block())) {
|
||||
List<Statement> stmts = new ArrayList<>();
|
||||
stmts.add(new Yield(convert(outcome.expression()), outcome.expression().start));
|
||||
isSingleExpression = true;
|
||||
block = new Block(stmts, outcome.expression().getStart());
|
||||
} else {
|
||||
block = convert(outcome.block(), false);
|
||||
}
|
||||
return new SwitchBlock(labels, block, isDefault, isSingleExpression, offset);
|
||||
}
|
||||
|
||||
private Statement convert(Java17Parser.YieldstmtContext yieldstmt) {
|
||||
// TODO
|
||||
throw new NotImplementedException();
|
||||
return new Yield(convert(yieldstmt.expression()), yieldstmt.getStart());
|
||||
}
|
||||
|
||||
private Statement convert(Java17Parser.SwitchBlockStatementGroupContext stmt) {
|
||||
// TODO
|
||||
throw new NotImplementedException();
|
||||
private SwitchBlock convert(Java17Parser.SwitchBlockStatementGroupContext stmt) {
|
||||
List<SwitchLabel> labels = new ArrayList<>();
|
||||
stmt.switchLabel().forEach((label) -> {
|
||||
labels.add(convert(label));
|
||||
});
|
||||
List<Statement> block = new ArrayList<>();
|
||||
stmt.blockStatement().stream().forEach((blockStmt) -> {
|
||||
block.addAll(convert(blockStmt));
|
||||
});
|
||||
return new SwitchBlock(labels, new Block(block, stmt.blockStatement(0).getStart()), false, stmt.getStart());
|
||||
}
|
||||
|
||||
private SwitchLabel convert(SwitchLabelContext switchLabel) {
|
||||
RefTypeOrTPHOrWildcardOrGeneric type = null;
|
||||
Pattern caseExpression = switch (switchLabel) {
|
||||
case SwitchLabelConstContext cons -> {
|
||||
yield new ExpressionPattern(convert(cons.constantExpression), cons.getStart());
|
||||
}
|
||||
case SwitchLabelPatternContext pattern -> {
|
||||
yield convert(pattern.pattern());
|
||||
}
|
||||
case SwitchLabelDefaultContext def -> {
|
||||
type = new Void(switchLabel.getStart());
|
||||
yield null;
|
||||
}
|
||||
default -> throw new NotImplementedException();
|
||||
};
|
||||
Token offset = switchLabel.getStart();
|
||||
if (Objects.isNull(caseExpression)) {
|
||||
if (type == null)
|
||||
type = TypePlaceholder.fresh(offset);
|
||||
return new SwitchLabel(type, offset);
|
||||
} else {
|
||||
return new SwitchLabel(caseExpression, caseExpression.getType(), offset);
|
||||
}
|
||||
}
|
||||
|
||||
private Pattern convert(PatternContext pattern) {
|
||||
return switch (pattern) {
|
||||
case PPatternContext pPattern -> {
|
||||
yield convert(pPattern.primaryPattern());
|
||||
}
|
||||
case GPatternContext gPattern -> {
|
||||
GuardedPatternContext guarded = gPattern.guardedPattern();
|
||||
Expression condition = convert(guarded.expression());
|
||||
yield new GuardedPattern(condition, convert(guarded.primaryPattern()), guarded.getStart());
|
||||
}
|
||||
default -> throw new NotImplementedException();
|
||||
};
|
||||
}
|
||||
|
||||
private FormalParameter convert(PrimaryPatternContext pPattern) {
|
||||
switch (pPattern) {
|
||||
case TPatternContext tPattern:
|
||||
TypePatternContext typePattern = tPattern.typePattern();
|
||||
var text = typePattern.identifier().getText();
|
||||
var type = TypeGenerator.convert(typePattern.typeType(), reg, generics);
|
||||
localVars.put(text, type);
|
||||
return new FormalParameter(text, type, typePattern.getStart());
|
||||
case RPatternContext rPattern:
|
||||
RecordPatternContext recordPattern = rPattern.recordPattern();
|
||||
return convert(recordPattern);
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private RecordPattern convert(RecordPatternContext recordPatternCtx) {
|
||||
List<PatternContext> subPatternCtx = recordPatternCtx.recordStructurePattern().recordComponentPatternList().pattern();
|
||||
List<Pattern> subPattern = subPatternCtx.stream().map(this::convert).collect(Collectors.toList());
|
||||
IdentifierContext identifierCtx = recordPatternCtx.identifier();
|
||||
var text = (identifierCtx != null) ? identifierCtx.getText() : null;
|
||||
var type = TypeGenerator.convert(recordPatternCtx.typeType(), reg, generics);
|
||||
if (text != null) localVars.put(text, type);
|
||||
return new RecordPattern(subPattern, text, type, recordPatternCtx.getStart());
|
||||
}
|
||||
|
||||
private Statement convert(Java17Parser.WhileloopContext stmt) {
|
||||
@@ -349,7 +489,18 @@ public class StatementGenerator {
|
||||
}
|
||||
|
||||
private Statement convert(Java17Parser.ForloopContext stmt) {
|
||||
throw new NotImplementedException();
|
||||
var control = stmt.forControl();
|
||||
var block = convert(stmt.statement());
|
||||
if (control.enhancedForControl() != null)
|
||||
throw new NotImplementedException();
|
||||
else {
|
||||
return new ForStmt(
|
||||
stmt.getStart(),
|
||||
convert(control.forInit().localVariableDeclaration()),
|
||||
convert(control.expression()), control.forUpdate.expression().stream().map(this::convert).toList(),
|
||||
block
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private ArgumentList convertArguments(Java17Parser.ExpressionListContext arglist) {
|
||||
@@ -410,12 +561,18 @@ public class StatementGenerator {
|
||||
} else {
|
||||
initValue = convert(varDecl.variableInitializer().expression());
|
||||
}
|
||||
return (new Assign(new AssignToField(new FieldVar(new This(varDecl.getStart()), name.getText(), type, varDecl.getStart())), initValue, name.getStart()));
|
||||
var fieldEntry = fields.get(name.getText());
|
||||
return (new Assign(new AssignToField(new FieldVar(new This(varDecl.getStart()), (fieldEntry.modifiers() & Modifier.STATIC) != 0, name.getText(), type, varDecl.getStart())), initValue, name.getStart()));
|
||||
}
|
||||
|
||||
private Statement convert(Java17Parser.BreakstmtContext stmt) {
|
||||
// TODO
|
||||
throw new NotImplementedException();
|
||||
Token offset = stmt.getStart();
|
||||
if (!Objects.isNull(stmt.identifier())) {
|
||||
return new Break(localVars.get(stmt.identifier().getText()), offset);
|
||||
} else {
|
||||
return new Break(TypePlaceholder.fresh(offset), offset);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Statement convert(Java17Parser.ContinuestmtContext stmt) {
|
||||
@@ -462,7 +619,7 @@ public class StatementGenerator {
|
||||
|
||||
private Expression convert(Java17Parser.ExpressionContext expression) {
|
||||
switch (expression) {
|
||||
case PrimaryexpressionContext primary:
|
||||
case PrimaryExpression2Context primary:
|
||||
return convert(primary.primary());
|
||||
case DottedexpressionContext dotted:
|
||||
return convert(dotted, expression.getStart());
|
||||
@@ -482,14 +639,15 @@ public class StatementGenerator {
|
||||
return convert(mathexpr);
|
||||
case RelationalexpressionContext comparison:
|
||||
return convert(comparison);
|
||||
/*
|
||||
* TODO: syntaxtree for instanceof vorbereiten case InstanceofexpressionContext instanceof: case SwitchexpressionContext switchexpression:
|
||||
*/
|
||||
case InstanceofexpressionContext instanceOf:
|
||||
return convert(instanceOf);
|
||||
case SwitchExpression2Context switchexpression:
|
||||
return convert(switchexpression.switchExpression());
|
||||
case EqualityexpressionContext equal:
|
||||
return convert(equal);
|
||||
case AssignexpressionContext assignment:
|
||||
return convert(assignment);
|
||||
case LambdaexpressionContext lambdaexpr:
|
||||
case LambdaExpression2Context lambdaexpr:
|
||||
return convert(lambdaexpr.lambdaExpression());
|
||||
case ArrayaccessexpressionContext arrayaccess:
|
||||
return convert(arrayaccess);
|
||||
@@ -562,7 +720,7 @@ public class StatementGenerator {
|
||||
public Receiver getReceiver(ExpressionContext expr) {
|
||||
Expression expression = convert(expr);
|
||||
/*
|
||||
* if (expr instanceof PrimaryexpressionContext pc) { expression = convert(pc.primary()); } else { expression = generateLocalOrFieldVarOrClassName(expr.getText(), expr.getStart()); }
|
||||
* if (expr instanceof PrimaryExpression2Context pc) { expression = convert(pc.primary()); } else { expression = generateLocalOrFieldVarOrClassName(expr.getText(), expr.getStart()); }
|
||||
*/
|
||||
return getReceiver(expression);
|
||||
}
|
||||
@@ -588,16 +746,15 @@ public class StatementGenerator {
|
||||
// Check for localVar:
|
||||
if (localVars.get(expression) != null) {
|
||||
return new LocalVar(expression, localVars.get(expression), offset);
|
||||
} else {
|
||||
if (fields.get(expression) != null) {// PL 2018-11-01 fields eingefuegt, damit die fields immer die
|
||||
// gleiche TPH bekommen
|
||||
return new FieldVar(new This(offset), expression, fields.get(expression), offset);
|
||||
} else if (fields.get(expression) != null) {// PL 2018-11-01 fields eingefuegt, damit die fields immer die
|
||||
// gleiche TPH bekommen
|
||||
var field = fields.get(expression);
|
||||
return new FieldVar(new This(offset), Modifier.isStatic(field.modifiers()), expression, fields.get(expression).type(), offset);
|
||||
|
||||
} else {
|
||||
// kann eigentlich nicht vorkommen
|
||||
// Dann Muss es ein Feld sein!
|
||||
return new FieldVar(new This(offset), expression, TypePlaceholder.fresh(offset), offset);
|
||||
}
|
||||
} else {
|
||||
// lokale Variable wurde ohne "var"-Keyword deklariert und direkt mit Wert versehen
|
||||
localVars.put(expression, TypePlaceholder.fresh(offset));
|
||||
return new LocalVar(expression, localVars.get(expression), offset);
|
||||
}
|
||||
}
|
||||
return generateFieldVarOrClassname(expression, offset);
|
||||
@@ -615,16 +772,24 @@ public class StatementGenerator {
|
||||
}
|
||||
whole += ".";
|
||||
}
|
||||
var fieldName = parts[parts.length - 1];
|
||||
|
||||
var isStatic = false;
|
||||
if (parts.length < 2 || parts[0].contentEquals("this")) {
|
||||
receiver = new This(offset);
|
||||
isStatic = Modifier.isStatic(fields.get(fieldName).modifiers());
|
||||
} else if (parts[0].contentEquals("super")) {
|
||||
receiver = new Super(offset);
|
||||
isStatic = Modifier.isStatic(compiler.getClass(new JavaClassName(superClass.getName().toString())).getField(fieldName).orElseThrow().modifier);
|
||||
} else if (receiver == null) { // Handelt es sich um keinen Statischen Klassennamen:
|
||||
String part = expression.substring(0, expression.length() - (1 + parts[parts.length - 1].length()));
|
||||
receiver = generateLocalOrFieldVarOrClassName(part, offset);
|
||||
} else {
|
||||
StaticClassName cname = (StaticClassName) receiver;
|
||||
var javaClassName = reg.getName(cname.getType().toString());
|
||||
isStatic = Modifier.isStatic(compiler.getClass(javaClassName).getField(fieldName).orElseThrow().modifier);
|
||||
}
|
||||
return new FieldVar(receiver, parts[parts.length - 1], TypePlaceholder.fresh(offset), offset);
|
||||
return new FieldVar(receiver, isStatic, fieldName, TypePlaceholder.fresh(offset), offset);
|
||||
}
|
||||
|
||||
private Expression convert(Java17Parser.ArrayaccessexpressionContext arrayaccess) {
|
||||
@@ -636,11 +801,19 @@ public class StatementGenerator {
|
||||
}
|
||||
|
||||
private Expression convert(Java17Parser.OrexpressionContext expression) {
|
||||
throw new NotImplementedException();
|
||||
if (expression.expression().size() != 2) {
|
||||
throw new NotImplementedException();
|
||||
} else {
|
||||
return new BoolExpression(BoolExpression.Operator.OR, new RefType(new JavaClassName("java.lang.Boolean"), expression.getStart()), convert(expression.expression(0)), convert(expression.expression(1)), expression.getStart());
|
||||
}
|
||||
}
|
||||
|
||||
private Expression convert(Java17Parser.AndexpressionContext expression) {
|
||||
throw new NotImplementedException();
|
||||
if (expression.expression().size() != 2) {
|
||||
throw new NotImplementedException();
|
||||
} else {
|
||||
return new BoolExpression(BoolExpression.Operator.AND, new RefType(new JavaClassName("java.lang.Boolean"), expression.getStart()), convert(expression.expression(0)), convert(expression.expression(1)), expression.getStart());
|
||||
}
|
||||
}
|
||||
|
||||
private Statement convert(AssignexpressionContext expr) {
|
||||
@@ -700,6 +873,30 @@ public class StatementGenerator {
|
||||
return new BinaryExpr(convertBinaryOperator(operator), TypePlaceholder.fresh(expression.getStart()), convert(expression.expression(0)), convert(expression.expression(1)), expression.getStart());
|
||||
}
|
||||
|
||||
private Expression convert(Java17Parser.InstanceofexpressionContext expression) {
|
||||
Expression left = convert(expression.expression());
|
||||
Token offset = expression.getStart();
|
||||
if (Objects.isNull(expression.pattern())) {;
|
||||
return new InstanceOf(left, new RefType(reg.getName("java.lang.Boolean"), expression.getStart()), TypeGenerator.convert(expression.typeType(), reg, generics), offset);
|
||||
} else {
|
||||
switch (expression.pattern()) {
|
||||
case PPatternContext primaryPattern:
|
||||
switch (primaryPattern.primaryPattern()) {
|
||||
case TPatternContext typePattern:
|
||||
TypePatternContext typePatternCtx = typePattern.typePattern();
|
||||
String localVarName = typePatternCtx.identifier().getText();
|
||||
RefTypeOrTPHOrWildcardOrGeneric localVarType = TypeGenerator.convert(typePatternCtx.typeType(), reg, generics);
|
||||
localVars.put(localVarName, localVarType);
|
||||
return new InstanceOf(left, new RefType(reg.getName("java.lang.Boolean"), expression.getStart()), new FormalParameter(localVarName, localVarType, typePatternCtx.getStart()), offset);
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BinaryExpr.Operator convertBinaryOperator(String operator) {
|
||||
// return BinaryExpr.Operator.ADD;
|
||||
if (operator.equals("+")) {
|
||||
@@ -837,7 +1034,7 @@ public class StatementGenerator {
|
||||
Java17Parser.LambdaParametersContext lambdaParams = expression.lambdaParameters();
|
||||
ParameterList params;
|
||||
if (lambdaParams.identifier().size() > 0) {
|
||||
List<FormalParameter> parameterList = new ArrayList<>();
|
||||
List<Pattern> parameterList = new ArrayList<>();
|
||||
for (IdentifierContext identifier : lambdaParams.identifier()) {
|
||||
Token offset = identifier.getStart();
|
||||
parameterList.add(new FormalParameter(identifier.getText(), TypePlaceholder.fresh(offset), offset));
|
||||
@@ -847,7 +1044,7 @@ public class StatementGenerator {
|
||||
params = convert(lambdaParams.formalParameterList());
|
||||
// }else if( lambdaParams.inferredFormalParameterList != null){
|
||||
} else if (!Objects.isNull(lambdaParams.lambdaLVTIList())) {
|
||||
List<FormalParameter> parameterList = new ArrayList<>();
|
||||
List<Pattern> parameterList = new ArrayList<>();
|
||||
for (LambdaLVTIParameterContext param : lambdaParams.lambdaLVTIList().lambdaLVTIParameter()) {
|
||||
Token offset = param.getStart();
|
||||
parameterList.add(new FormalParameter(param.identifier().getText(), TypePlaceholder.fresh(offset), offset));
|
||||
@@ -859,10 +1056,11 @@ public class StatementGenerator {
|
||||
|
||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> lambdaLocals = new HashMap<>();
|
||||
lambdaLocals.putAll(localVars);
|
||||
for (FormalParameter param : params.getFormalparalist()) {
|
||||
lambdaLocals.put(param.getName(), param.getType());
|
||||
for (Pattern param : params.getFormalparalist()) {
|
||||
if (!(param instanceof FormalParameter fp)) throw new IllegalArgumentException();
|
||||
lambdaLocals.put(fp.getName(), fp.getType());
|
||||
}
|
||||
StatementGenerator lambdaGenerator = new StatementGenerator(reg, generics, fields, lambdaLocals);
|
||||
StatementGenerator lambdaGenerator = new StatementGenerator(superClass, compiler, reg, generics, fields, lambdaLocals);
|
||||
|
||||
Block block;
|
||||
if (expression.lambdaBody().expression() != null) {
|
||||
|
||||
@@ -12,6 +12,10 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.Record;
|
||||
import org.antlr.v4.runtime.CommonToken;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
@@ -54,22 +58,13 @@ import de.dhbwstuttgart.parser.antlr.Java17Parser.ModifierContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.NoclassorinterfaceContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.RecordComponentContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.RecordDeclarationContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.ReftypeContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.RefType2Context;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SrcfileContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.TypeArgumentsContext;
|
||||
import de.dhbwstuttgart.parser.scope.GatherNames;
|
||||
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
||||
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.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.ParameterList;
|
||||
import de.dhbwstuttgart.syntaxtree.Record;
|
||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Assign;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.AssignLeftSide;
|
||||
@@ -85,20 +80,27 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||
import de.dhbwstuttgart.typeinference.constraints.GenericsResolver;
|
||||
import javassist.compiler.SyntaxError;
|
||||
|
||||
import javax.swing.text.html.Option;
|
||||
|
||||
public class SyntaxTreeGenerator {
|
||||
private JavaClassRegistry reg;
|
||||
private final GenericsRegistry globalGenerics;
|
||||
private String pkgName = "";
|
||||
Set<JavaClassName> imports = new HashSet<>();
|
||||
public String pkgName = "";
|
||||
public Set<JavaClassName> imports = new HashSet<>();
|
||||
HashMap<String, Integer> allmodifiers = new HashMap<>();
|
||||
// PL 2018-11-01 fields eingefuegt, damit die fields immer die gleiche TPH
|
||||
// bekommen
|
||||
private Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields = new HashMap<>();
|
||||
private final Map<String, FieldEntry> fields = new HashMap<>();
|
||||
// PL 2019-10-23: Muss für jede Klasse neu initilisiert werden
|
||||
List<Statement> fieldInitializations = new ArrayList<>();
|
||||
List<Statement> staticFieldInitializations = new ArrayList<>();
|
||||
|
||||
public SyntaxTreeGenerator(JavaClassRegistry reg, GenericsRegistry globalGenerics) {
|
||||
private final JavaTXCompiler compiler;
|
||||
private RefType superClass;
|
||||
|
||||
public SyntaxTreeGenerator(JavaTXCompiler compiler, JavaClassRegistry reg, GenericsRegistry globalGenerics) {
|
||||
// Die Generics müssen während des Bauens des AST erstellt werden,
|
||||
// da diese mit der Methode oder Klasse, in welcher sie deklariert werden
|
||||
// verknüpft sein müssen. Dennoch werden die Namen aller Generics in einer
|
||||
@@ -121,6 +123,8 @@ public class SyntaxTreeGenerator {
|
||||
this.allmodifiers.put("non-sealed", 8192);
|
||||
this.allmodifiers.put("default", 16384);
|
||||
this.allmodifiers.put("strictfp", 32768);
|
||||
|
||||
this.compiler = compiler;
|
||||
}
|
||||
|
||||
public JavaClassRegistry getReg() {
|
||||
@@ -134,17 +138,16 @@ public class SyntaxTreeGenerator {
|
||||
return ctx.getText();
|
||||
}
|
||||
|
||||
public SourceFile convert(Java17Parser.SourceFileContext ctx, PackageCrawler packageCrawler, ClassLoader classLoader) throws ClassNotFoundException, NotImplementedException {
|
||||
public void convert(List<ClassOrInterface> classes, Java17Parser.SourceFileContext ctx, PackageCrawler packageCrawler) throws ClassNotFoundException, NotImplementedException {
|
||||
SrcfileContext srcfile;
|
||||
List<ClassOrInterface> classes = new ArrayList<>();
|
||||
if (ctx instanceof Java17Parser.SrcfileContext) {
|
||||
srcfile = (SrcfileContext) ctx;
|
||||
} else {
|
||||
return new SourceFile(this.pkgName, classes, this.imports);
|
||||
return;
|
||||
}
|
||||
if (srcfile.packageDeclaration() != null)
|
||||
this.pkgName = convert(srcfile.packageDeclaration());
|
||||
Map<String, Integer> imports = GatherNames.getImports(srcfile, packageCrawler, classLoader);
|
||||
Map<String, Integer> imports = GatherNames.getImports(srcfile, packageCrawler, compiler);
|
||||
this.imports = imports.keySet().stream().map(name -> reg.getName(name)).collect(Collectors.toSet());
|
||||
for (Java17Parser.ClassOrInterfaceContext type : srcfile.classOrInterface()) {
|
||||
ClassorinterfacedeclContext clsoif;
|
||||
@@ -161,6 +164,7 @@ public class SyntaxTreeGenerator {
|
||||
}
|
||||
}
|
||||
fieldInitializations = new ArrayList<>(); // PL 2019-10-22: muss für jede Klasse neu initilisiert werden
|
||||
staticFieldInitializations = new ArrayList<>();
|
||||
if (!Objects.isNull(clsoif.classDeclaration())) {
|
||||
newClass = convertClass(clsoif.classDeclaration(), modifiers);
|
||||
} else if (!Objects.isNull(clsoif.interfaceDeclaration())) {
|
||||
@@ -172,9 +176,7 @@ public class SyntaxTreeGenerator {
|
||||
}
|
||||
classes.add(newClass);
|
||||
}
|
||||
if (classes.size() > 0) {
|
||||
return new SourceFile(this.pkgName, classes, this.imports);
|
||||
} else {
|
||||
if (classes.isEmpty()) {
|
||||
throw new NotImplementedException("SourceFile enthält keine Klassen");
|
||||
}
|
||||
}
|
||||
@@ -193,7 +195,7 @@ public class SyntaxTreeGenerator {
|
||||
Token offset = ctx.getStart();
|
||||
GenericDeclarationList genericClassParameters;
|
||||
if (ctx.genericDeclarationList() == null) {
|
||||
genericClassParameters = new GenericDeclarationList(new ArrayList<>(), ctx.identifier().getStop());
|
||||
genericClassParameters = new GenericDeclarationList(new ArrayList<>(), ctx.classBody().getStart());
|
||||
} else {
|
||||
genericClassParameters = TypeGenerator.convert(ctx.genericDeclarationList(), name, "", reg, generics);
|
||||
}
|
||||
@@ -203,10 +205,12 @@ public class SyntaxTreeGenerator {
|
||||
} else {
|
||||
superClass = new RefType(ASTFactory.createObjectClass().getClassName(), ctx.getStart());
|
||||
}
|
||||
this.superClass = superClass;
|
||||
List<Field> fielddecl = new ArrayList<>();
|
||||
List<Method> methods = new ArrayList<>();
|
||||
List<Constructor> constructors = new ArrayList<>();
|
||||
Boolean isInterface = false;
|
||||
Boolean isFunctionalInterface = false;
|
||||
List<RefType> implementedInterfaces = new ArrayList<>();
|
||||
List<RefType> permittedSubtypes = new ArrayList<>();
|
||||
for (ClassBodyDeclarationContext clsbodydecl : ctx.classBody().classBodyDeclaration()) {
|
||||
@@ -220,24 +224,22 @@ public class SyntaxTreeGenerator {
|
||||
}
|
||||
// Ist Bit für 'sealed'-Modifier gesetzt
|
||||
if ((modifiers & 4096) != 0) {
|
||||
switch (ctx.typeList().size()) {
|
||||
case 1: {
|
||||
permittedSubtypes.addAll(convert(ctx.typeList(0), generics));
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
permittedSubtypes.addAll(convert(ctx.typeList(1), generics));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
if (!Objects.isNull(ctx.PERMITS())) {
|
||||
// permitted subtypes sind letzte typeList (siehe Grammatikregel 'classDeclaration')
|
||||
permittedSubtypes.addAll(convert(ctx.typeList(ctx.typeList().size() - 1), generics));
|
||||
} else {
|
||||
// falls sealed modifier ohne 'permits'-List oder umgekehrt
|
||||
throw new NotImplementedException("Invalid sealed class declaration");
|
||||
}
|
||||
}
|
||||
return new ClassOrInterface(modifiers, name, fielddecl, Optional.of(this.generatePseudoConstructor(ctx.identifier().getText(), name, superClass, genericClassParameters, offset)), methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset);
|
||||
var ctor = Optional.of(this.generatePseudoConstructor(ctx.identifier().getText(), fieldInitializations, genericClassParameters, offset));
|
||||
var staticCtor = Optional.of(this.generateStaticConstructor(ctx.identifier().getText(), staticFieldInitializations, genericClassParameters, offset));
|
||||
return new ClassOrInterface(modifiers, name, fielddecl, ctor, staticCtor, methods, constructors, genericClassParameters, superClass, isInterface, isFunctionalInterface, implementedInterfaces, permittedSubtypes, offset);
|
||||
|
||||
}
|
||||
|
||||
private de.dhbwstuttgart.syntaxtree.Record convertRecord(RecordDeclarationContext recordDeclaration, int modifiers) {
|
||||
this.superClass = new RefType(new JavaClassName("java.lang.Record"), new NullToken());
|
||||
String identifier = recordDeclaration.identifier().getText();
|
||||
String className = this.pkgName + (this.pkgName.length() > 0 ? "." : "") + identifier;
|
||||
JavaClassName name = reg.getName(className); // Holt den Package Namen mit dazu
|
||||
@@ -248,17 +250,17 @@ public class SyntaxTreeGenerator {
|
||||
}
|
||||
GenericDeclarationList genericClassParameters;
|
||||
if (recordDeclaration.genericDeclarationList() == null) {
|
||||
genericClassParameters = new GenericDeclarationList(new ArrayList<>(), recordDeclaration.identifier().getStop());
|
||||
genericClassParameters = new GenericDeclarationList(new ArrayList<>(), recordDeclaration.recordBody().getStart());
|
||||
} else {
|
||||
genericClassParameters = TypeGenerator.convert(recordDeclaration.genericDeclarationList(), name, "", reg, generics);
|
||||
}
|
||||
RefType superClass = new RefType(ASTFactory.createObjectClass().getClassName(), offset);
|
||||
RefType superClass = new RefType(ASTFactory.createClass(java.lang.Record.class).getClassName(), offset);
|
||||
List<Field> fielddecl = new ArrayList<>();
|
||||
List<Method> methods = new ArrayList<>();
|
||||
List<Constructor> constructors = new ArrayList<>();
|
||||
Boolean isInterface = false;
|
||||
List<RefType> implementedInterfaces = new ArrayList<>();
|
||||
List<FormalParameter> constructorParameters = new ArrayList<>();
|
||||
List<Pattern> constructorParameters = new ArrayList<>();
|
||||
List<Statement> constructorStatements = new ArrayList<>();
|
||||
for (RecordComponentContext component : recordDeclaration.recordHeader().recordComponentList().recordComponent()) {
|
||||
int fieldmodifiers = allmodifiers.get("private") + allmodifiers.get("final");
|
||||
@@ -272,7 +274,7 @@ public class SyntaxTreeGenerator {
|
||||
}
|
||||
fielddecl.add(new Field(fieldname, fieldtype, fieldmodifiers, fieldoffset));
|
||||
constructorParameters.add(new FormalParameter(fieldname, fieldtype, fieldoffset));
|
||||
FieldVar fieldvar = new FieldVar(new This(offset), fieldname, fieldtype, fieldoffset);
|
||||
FieldVar fieldvar = new FieldVar(new This(offset), false, fieldname, fieldtype, fieldoffset);
|
||||
constructorStatements.add(new Assign(new AssignToField(fieldvar), new LocalVar(fieldname, fieldtype, fieldoffset), offset));
|
||||
Statement returnStatement = new Return(fieldvar, offset);
|
||||
methods.add(new Method(allmodifiers.get("public"), fieldname, fieldtype, new ParameterList(new ArrayList<>(), offset), new Block(Arrays.asList(returnStatement), offset), new GenericDeclarationList(new ArrayList<>(), offset), offset));
|
||||
@@ -287,12 +289,12 @@ public class SyntaxTreeGenerator {
|
||||
if (!Objects.isNull(recordDeclaration.IMPLEMENTS())) {
|
||||
implementedInterfaces.addAll(convert(recordDeclaration.typeList(), generics));
|
||||
}
|
||||
return new Record(modifiers, name, fielddecl, initializations, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset);
|
||||
var staticCtor = Optional.of(this.generateStaticConstructor(recordDeclaration.identifier().getText(), staticFieldInitializations, genericClassParameters, offset));
|
||||
return new Record(modifiers, name, fielddecl, initializations, staticCtor, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset);
|
||||
}
|
||||
|
||||
private void convert(ClassBodyDeclarationContext classBody, List<Field> fields, List<Constructor> constructors, List<Method> methods, JavaClassName name, RefType superClass, GenericsRegistry generics) {
|
||||
MemberdeclContext member;
|
||||
// Statement-Blöcke und "leere Zeilen" (;) werden noch nicht berücksichtigt
|
||||
if (classBody instanceof MemberdeclContext) {
|
||||
member = (MemberdeclContext) classBody;
|
||||
Integer membermodifiers = 0;
|
||||
@@ -323,10 +325,16 @@ public class SyntaxTreeGenerator {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (classBody instanceof Java17Parser.ClassblockContext ctx && ctx.STATIC() != null) {
|
||||
// Static blocks
|
||||
var stmtgen = new StatementGenerator(superClass, compiler, reg, generics, this.fields, new HashMap<>());
|
||||
var block = stmtgen.convert(((Java17Parser.ClassblockContext) classBody).block(), false);
|
||||
staticFieldInitializations.addAll(block.statements);
|
||||
}
|
||||
}
|
||||
|
||||
private ClassOrInterface convertInterface(Java17Parser.InterfaceDeclarationContext ctx, int modifiers) {
|
||||
this.superClass = new RefType(new JavaClassName("java.lang.Object"), new NullToken());
|
||||
String className = this.pkgName.length() > 0 ? this.pkgName + "." : "" + ctx.identifier().getText();
|
||||
JavaClassName name = reg.getName(className); // Holt den Package Namen mit dazu
|
||||
if (!name.toString().equals(className)) { // Kommt die Klasse schon in einem anderen Package vor?
|
||||
@@ -388,7 +396,20 @@ public class SyntaxTreeGenerator {
|
||||
if (!Objects.isNull(ctx.EXTENDS())) {
|
||||
extendedInterfaces.addAll(convert(ctx.typeList(0), generics));
|
||||
}
|
||||
return new ClassOrInterface(modifiers, name, fields, Optional.empty(), methods, new ArrayList<>(), genericParams, superClass, true, extendedInterfaces, ctx.getStart());
|
||||
List<RefType> permittedSubtypes = new ArrayList<>();
|
||||
// Ist Bit für 'sealed'-Modifier gesetzt
|
||||
if ((modifiers & 4096) != 0) {
|
||||
if (!Objects.isNull(ctx.PERMITS())) {
|
||||
// permitted subtypes sind letzte typeList (siehe Grammatikregel 'classDeclaration')
|
||||
permittedSubtypes.addAll(convert(ctx.typeList(ctx.typeList().size() - 1), generics));
|
||||
} else {
|
||||
// falls sealed modifier ohne 'permits'-List oder umgekehrt
|
||||
throw new NotImplementedException("Invalid sealed class declaration");
|
||||
}
|
||||
}
|
||||
|
||||
var staticCtor = Optional.of(this.generateStaticConstructor(ctx.identifier().getText(), staticFieldInitializations, genericParams, ctx.getStart()));
|
||||
return new ClassOrInterface(modifiers, name, fields, Optional.empty(), staticCtor, methods, new ArrayList<>(), genericParams, superClass, true, methods.size() == 1 ? true : false, extendedInterfaces, permittedSubtypes, ctx.getStart());
|
||||
}
|
||||
|
||||
private GenericDeclarationList createEmptyGenericDeclarationList(Token classNameIdentifier) {
|
||||
@@ -410,13 +431,13 @@ public class SyntaxTreeGenerator {
|
||||
if (Objects.isNull(bodydeclaration.refType())) {
|
||||
retType = TypePlaceholder.fresh(bodydeclaration.getStart());
|
||||
} else {
|
||||
if (bodydeclaration.refType() instanceof ReftypeContext reftype) {
|
||||
if (bodydeclaration.refType() instanceof RefType2Context reftype) {
|
||||
retType = TypeGenerator.convert(reftype.typeType(), reg, generics);
|
||||
} else {
|
||||
retType = new Void(bodydeclaration.refType().getStart());
|
||||
}
|
||||
}
|
||||
StatementGenerator stmtgen = new StatementGenerator(reg, generics, fields, new HashMap<>());
|
||||
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, generics, fields, new HashMap<>());
|
||||
ParameterList paramlist = stmtgen.convert(bodydeclaration.formalParameters().formalParameterList());
|
||||
MethodBodyContext body = bodydeclaration.methodBody();
|
||||
Block block = null;
|
||||
@@ -444,15 +465,22 @@ public class SyntaxTreeGenerator {
|
||||
/*
|
||||
* fieldInitializations werden in einem Psedokonstruktor in der abstrakten Syntax gespeichert
|
||||
*/
|
||||
private Constructor generatePseudoConstructor(String className, JavaClassName parentClass, RefType superClass, GenericDeclarationList classGenerics, Token offset) {
|
||||
private Constructor generatePseudoConstructor(String className, List<Statement> initializations, GenericDeclarationList classGenerics, Token offset) {
|
||||
RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset);
|
||||
ParameterList params = new ParameterList(new ArrayList<>(), offset);
|
||||
Block block = new Block(new ArrayList<>(fieldInitializations), offset);
|
||||
Block block = new Block(new ArrayList<>(initializations), offset);
|
||||
return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset /*
|
||||
* fieldInitializations geloescht PL 2018-11-24
|
||||
*/);
|
||||
}
|
||||
|
||||
private Method generateStaticConstructor(String className, List<Statement> initializations, GenericDeclarationList classGenerics, Token offset) {
|
||||
RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset);
|
||||
ParameterList params = new ParameterList(new ArrayList<>(), offset);
|
||||
Block block = new Block(new ArrayList<>(initializations), offset);
|
||||
return new Method(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset);
|
||||
}
|
||||
|
||||
private RefType convertSuperType(Java17Parser.TypeTypeContext typeType) {
|
||||
ClassOrInterfaceTypeContext supertypecontext = typeType.classOrInterfaceType();
|
||||
if (supertypecontext != null && supertypecontext.DOT().size() > 0) {
|
||||
@@ -503,13 +531,13 @@ public class SyntaxTreeGenerator {
|
||||
if (Objects.isNull(header.refType())) {
|
||||
retType = TypePlaceholder.fresh(header.getStart());
|
||||
} else {
|
||||
if (header.refType() instanceof ReftypeContext reftype) {
|
||||
if (header.refType() instanceof RefType2Context reftype) {
|
||||
retType = TypeGenerator.convert(reftype.typeType(), reg, generics);
|
||||
} else {
|
||||
retType = new Void(header.refType().getStart());
|
||||
}
|
||||
}
|
||||
StatementGenerator stmtgen = new StatementGenerator(reg, localgenerics, fields, new HashMap<>());
|
||||
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>());
|
||||
ParameterList paramlist = stmtgen.convert(header.formalParameters().formalParameterList());
|
||||
MethodBodyContext body = methoddeclaration.methodBody();
|
||||
Block block = null;
|
||||
@@ -549,13 +577,13 @@ public class SyntaxTreeGenerator {
|
||||
gtvDeclarations = new GenericDeclarationList(new ArrayList<>(), constructordeclaration.getStart());
|
||||
}
|
||||
RefTypeOrTPHOrWildcardOrGeneric retType = TypeGenerator.convertTypeName(name, constructordeclaration.getStart(), reg, localgenerics);
|
||||
StatementGenerator stmtgen = new StatementGenerator(reg, localgenerics, fields, new HashMap<>());
|
||||
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>());
|
||||
ParameterList paramlist = stmtgen.convert(constructordeclaration.formalParameters().formalParameterList());
|
||||
Block block = stmtgen.convert(constructordeclaration.constructorBody, true);
|
||||
return new Constructor(modifiers, name, retType, paramlist, block, gtvDeclarations, constructordeclaration.getStart());
|
||||
}
|
||||
|
||||
private List<? extends Field> convert(Java17Parser.FieldDeclarationContext fieldDeclContext, int modifiers, GenericsRegistry generics) {
|
||||
List<? extends Field> convert(Java17Parser.FieldDeclarationContext fieldDeclContext, int modifiers, GenericsRegistry generics) {
|
||||
List<Field> ret = new ArrayList<>();
|
||||
RefTypeOrTPHOrWildcardOrGeneric fieldType;
|
||||
if (fieldDeclContext.typeType() != null) {
|
||||
@@ -567,9 +595,9 @@ public class SyntaxTreeGenerator {
|
||||
}
|
||||
for (Java17Parser.VariableDeclaratorContext varDecl : fieldDeclContext.variableDeclarators().variableDeclarator()) {
|
||||
String fieldName = varDecl.variableDeclaratorId().getText();
|
||||
this.fields.put(fieldName, fieldType);
|
||||
this.fields.put(fieldName, new FieldEntry(fieldName, fieldType, modifiers));
|
||||
if (varDecl.variableInitializer() != null) {
|
||||
initializeField(varDecl, fieldType, generics);
|
||||
initializeField(varDecl, Modifier.isStatic(modifiers), fieldType, generics);
|
||||
}
|
||||
ret.add(new Field(fieldName, fieldType, modifiers, varDecl.getStart()));
|
||||
}
|
||||
@@ -581,9 +609,13 @@ public class SyntaxTreeGenerator {
|
||||
}
|
||||
|
||||
// Initialize a field by creating implicit constructor.
|
||||
private void initializeField(Java17Parser.VariableDeclaratorContext ctx, RefTypeOrTPHOrWildcardOrGeneric typeOfField, GenericsRegistry generics) {
|
||||
StatementGenerator statementGenerator = new StatementGenerator(reg, generics, fields, new HashMap<>());
|
||||
fieldInitializations.add(statementGenerator.generateFieldAssignment(ctx, typeOfField));
|
||||
private void initializeField(Java17Parser.VariableDeclaratorContext ctx, boolean isStatic, RefTypeOrTPHOrWildcardOrGeneric typeOfField, GenericsRegistry generics) {
|
||||
StatementGenerator statementGenerator = new StatementGenerator(superClass, compiler, reg, generics, fields, new HashMap<>());
|
||||
var assignment = statementGenerator.generateFieldAssignment(ctx, typeOfField);
|
||||
if (isStatic) {
|
||||
staticFieldInitializations.add(assignment);
|
||||
}
|
||||
else fieldInitializations.add(assignment);
|
||||
}
|
||||
|
||||
public int convertModifier(String modifier) {
|
||||
|
||||
@@ -65,6 +65,8 @@ public class TypeGenerator {
|
||||
return new RefType(ASTFactory.createClass(Boolean.class).getClassName(), typeContext.getStart());
|
||||
case "int":
|
||||
return new RefType(ASTFactory.createClass(Integer.class).getClassName(), typeContext.getStart());
|
||||
case "double":
|
||||
return new RefType(ASTFactory.createClass(Double.class).getClassName(), typeContext.getStart());
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@@ -1,96 +1,153 @@
|
||||
package de.dhbwstuttgart.parser.scope;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassDeclarationContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassorinterfacedeclContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.NoclassorinterfaceContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SrcfileContext;
|
||||
import com.google.common.collect.Iterables;
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.environment.PackageCrawler;
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.AnnotationTypeElementDeclarationContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassBodyContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassBodyDeclarationContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassOrInterfaceContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassorinterfacedeclContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.EnumConstantContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.EnumConstantsContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfaceBodyDeclarationContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfacememberContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberclassorinterfaceContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberdeclContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.NoclassorinterfaceContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SrcfileContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SubclassorinterfaceContext;
|
||||
|
||||
public class GatherNames {
|
||||
|
||||
public static Map<String, Integer> getNames(SrcfileContext ctx, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException {
|
||||
public static Map<String, Integer> getNames(SrcfileContext ctx, PackageCrawler packages, JavaTXCompiler compiler) throws ClassNotFoundException {
|
||||
Map<String, Integer> ret = new HashMap<>();
|
||||
String pkgName = getPackageName(ctx);
|
||||
String nameString = "";
|
||||
for (Java17Parser.ClassOrInterfaceContext member : ctx.classOrInterface()) {
|
||||
if (member instanceof NoclassorinterfaceContext) {
|
||||
for (Java17Parser.ClassOrInterfaceContext clsoifctx : ctx.classOrInterface()) {
|
||||
if (clsoifctx instanceof NoclassorinterfaceContext) {
|
||||
continue;
|
||||
}
|
||||
ClassorinterfacedeclContext clsoif = (ClassorinterfacedeclContext) member;
|
||||
String fullname = clsoif.getChild(clsoif.getChildCount() - 1).getClass().getName();
|
||||
String classname = fullname.substring(fullname.indexOf("$") + 1);
|
||||
int numGenerics = 0;
|
||||
/*
|
||||
* Es werden alle Namen gesammelt, die syntaktisch von Java-TX (sprich der Grammatik) erkannt werden. Auch wenn z.B. Annotationen oder Enumerationen noch nicht im Compiler implementiert sind. Die "NotImplementedException" wird dann im "SyntaxTreeGenerator" geworfen. Das Statement soll als Vorbereitung dienen, für den Fall, dass weitere Sprachkonstrukte in den Compiler aufgenommen werden.
|
||||
*/
|
||||
switch (classname) {
|
||||
case "ClassDeclarationContext":
|
||||
if (!pkgName.isEmpty()) {
|
||||
nameString = pkgName + "." + clsoif.classDeclaration().identifier().getText();
|
||||
} else {
|
||||
nameString = clsoif.classDeclaration().identifier().getText();
|
||||
}
|
||||
numGenerics = clsoif.classDeclaration().genericDeclarationList() != null ? clsoif.classDeclaration().genericDeclarationList().genericTypeVar().size() : 0;
|
||||
ret.put(nameString, numGenerics);
|
||||
break;
|
||||
case "EnumDeclarationContext":
|
||||
if (!pkgName.isEmpty()) {
|
||||
nameString = pkgName + "." + clsoif.enumDeclaration().identifier().getText();
|
||||
} else {
|
||||
nameString = clsoif.enumDeclaration().identifier().getText();
|
||||
}
|
||||
numGenerics = 0;
|
||||
ret.put(nameString, numGenerics);
|
||||
break;
|
||||
case "InterfaceDeclarationContext":
|
||||
if (pkgName != "") {
|
||||
nameString = pkgName + "." + clsoif.interfaceDeclaration().identifier().getText();
|
||||
} else {
|
||||
nameString = clsoif.interfaceDeclaration().identifier().getText();
|
||||
}
|
||||
numGenerics = clsoif.interfaceDeclaration().genericDeclarationList() != null ? clsoif.interfaceDeclaration().genericDeclarationList().genericTypeVar().size() : 0;
|
||||
ret.put(nameString, numGenerics);
|
||||
break;
|
||||
case "AnnotationTypeDeclarationContext":
|
||||
if (pkgName != "") {
|
||||
nameString = pkgName + "." + clsoif.annotationTypeDeclaration().identifier().getText();
|
||||
} else {
|
||||
nameString = clsoif.annotationTypeDeclaration().identifier().getText();
|
||||
}
|
||||
numGenerics = 0;
|
||||
ret.put(nameString, numGenerics);
|
||||
break;
|
||||
case "RecordDeclarationContext":
|
||||
if (pkgName != "") {
|
||||
nameString = pkgName + "." + clsoif.recordDeclaration().identifier().getText();
|
||||
} else {
|
||||
nameString = clsoif.recordDeclaration().identifier().getText();
|
||||
}
|
||||
numGenerics = clsoif.recordDeclaration().genericDeclarationList() != null ? clsoif.recordDeclaration().genericDeclarationList().genericTypeVar().size() : 0;
|
||||
ret.put(nameString, numGenerics);
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
ret.putAll(getNames(clsoifctx, getPackageName(ctx), packages, compiler));
|
||||
}
|
||||
ret.putAll(getImports(ctx, packages, classLoader));
|
||||
ret.putAll(getImports(ctx, packages, compiler));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static Map<String, Integer> getImports(Java17Parser.SrcfileContext ctx, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException {
|
||||
public static Map<String, Integer> getNames(ClassOrInterfaceContext clsoifctx, String pkgName, PackageCrawler packages, JavaTXCompiler compiler) throws ClassNotFoundException {
|
||||
Map<String, Integer> ret = new HashMap<>();
|
||||
ClassorinterfacedeclContext clsoif = (ClassorinterfacedeclContext) clsoifctx;
|
||||
String nameString = "";
|
||||
String fullname = clsoif.getChild(clsoif.getChildCount() - 1).getClass().getName();
|
||||
String classname = fullname.substring(fullname.indexOf("$") + 1);
|
||||
int numGenerics = 0;
|
||||
/*
|
||||
* Es werden alle Namen gesammelt, die syntaktisch von Java-TX (sprich der Grammatik) erkannt werden. Auch wenn z.B. Annotationen oder Enumerationen noch nicht im Compiler implementiert sind. Die "NotImplementedException" wird dann im "SyntaxTreeGenerator" geworfen. Das Statement soll als Vorbereitung dienen, für den Fall, dass weitere Sprachkonstrukte in den Compiler aufgenommen werden.
|
||||
*/
|
||||
switch (classname) {
|
||||
case "ClassDeclarationContext":
|
||||
if (!pkgName.isEmpty()) {
|
||||
nameString = pkgName + "." + clsoif.classDeclaration().identifier().getText();
|
||||
} else {
|
||||
nameString = clsoif.classDeclaration().identifier().getText();
|
||||
}
|
||||
numGenerics = clsoif.classDeclaration().genericDeclarationList() != null ? clsoif.classDeclaration().genericDeclarationList().genericTypeVar().size() : 0;
|
||||
ret.put(nameString, numGenerics);
|
||||
ret.putAll(getNames(clsoif.classDeclaration().classBody().classBodyDeclaration(), pkgName, packages, compiler));
|
||||
break;
|
||||
case "EnumDeclarationContext":
|
||||
if (!pkgName.isEmpty()) {
|
||||
nameString = pkgName + "." + clsoif.enumDeclaration().identifier().getText();
|
||||
} else {
|
||||
nameString = clsoif.enumDeclaration().identifier().getText();
|
||||
}
|
||||
numGenerics = 0;
|
||||
ret.put(nameString, numGenerics);
|
||||
EnumConstantsContext enumConstants = clsoif.enumDeclaration().enumConstants();
|
||||
if (!Objects.isNull(enumConstants)) {
|
||||
for (EnumConstantContext enumConstant : enumConstants.enumConstant()) {
|
||||
ClassBodyContext enumConstClassBody = enumConstant.classBody();
|
||||
if (!Objects.isNull(enumConstClassBody)) {
|
||||
ret.putAll(getNames(enumConstClassBody.classBodyDeclaration(), pkgName, packages, compiler));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "InterfaceDeclarationContext":
|
||||
if (pkgName != "") {
|
||||
nameString = pkgName + "." + clsoif.interfaceDeclaration().identifier().getText();
|
||||
} else {
|
||||
nameString = clsoif.interfaceDeclaration().identifier().getText();
|
||||
}
|
||||
numGenerics = clsoif.interfaceDeclaration().genericDeclarationList() != null ? clsoif.interfaceDeclaration().genericDeclarationList().genericTypeVar().size() : 0;
|
||||
ret.put(nameString, numGenerics);
|
||||
for (InterfaceBodyDeclarationContext ifbody : clsoif.interfaceDeclaration().interfaceBody().interfaceBodyDeclaration()) {
|
||||
if (ifbody instanceof InterfacememberContext member && member.interfaceMemberDeclaration() instanceof SubclassorinterfaceContext sub) {
|
||||
ret.putAll(getNames(sub.classOrInterface(), pkgName, packages, compiler));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "AnnotationTypeDeclarationContext":
|
||||
if (pkgName != "") {
|
||||
nameString = pkgName + "." + clsoif.annotationTypeDeclaration().identifier().getText();
|
||||
} else {
|
||||
nameString = clsoif.annotationTypeDeclaration().identifier().getText();
|
||||
}
|
||||
numGenerics = 0;
|
||||
ret.put(nameString, numGenerics);
|
||||
for (AnnotationTypeElementDeclarationContext anTypeElem : clsoif.annotationTypeDeclaration().annotationTypeBody().annotationTypeElementDeclaration()) {
|
||||
ClassOrInterfaceContext anClsoifctx = anTypeElem.annotationTypeElementRest().classOrInterface();
|
||||
if (!Objects.isNull(anClsoifctx)) {
|
||||
ret.putAll(getNames(anClsoifctx, pkgName, packages, compiler));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "RecordDeclarationContext":
|
||||
if (pkgName != "") {
|
||||
nameString = pkgName + "." + clsoif.recordDeclaration().identifier().getText();
|
||||
} else {
|
||||
nameString = clsoif.recordDeclaration().identifier().getText();
|
||||
}
|
||||
numGenerics = clsoif.recordDeclaration().genericDeclarationList() != null ? clsoif.recordDeclaration().genericDeclarationList().genericTypeVar().size() : 0;
|
||||
ret.put(nameString, numGenerics);
|
||||
ret.putAll(getNames(clsoif.recordDeclaration().recordBody().classBodyDeclaration(), pkgName, packages, compiler));
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static Map<String, Integer> getNames(List<ClassBodyDeclarationContext> clsBodyDecl, String pkgName, PackageCrawler packages, JavaTXCompiler compiler) throws ClassNotFoundException {
|
||||
Map<String, Integer> ret = new HashMap<>();
|
||||
for (ClassBodyDeclarationContext clsbody : clsBodyDecl) {
|
||||
if (clsbody instanceof MemberdeclContext member && member.memberDeclaration() instanceof MemberclassorinterfaceContext memberclsoifctx) {
|
||||
ret.putAll(getNames(memberclsoifctx.classOrInterface(), pkgName, packages, compiler));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static Map<String, Integer> getImports(Java17Parser.SrcfileContext ctx, PackageCrawler packages, JavaTXCompiler compiler) throws ClassNotFoundException {
|
||||
Map<String, Integer> ret = new HashMap<>();
|
||||
// ret.putAll(packages.getClassNames("java.lang"));
|
||||
for (Java17Parser.ImportDeclarationContext importDeclCtx : ctx.importDeclaration()) {
|
||||
if (importDeclCtx.MUL() == null) {
|
||||
Class<?> cl = classLoader.loadClass(importDeclCtx.qualifiedName().getText());
|
||||
ret.put(cl.getName(), cl.getTypeParameters().length);
|
||||
var name = importDeclCtx.qualifiedName().getText();
|
||||
var className = new JavaClassName(name);
|
||||
if (compiler.loadJavaTXClass(className)) {
|
||||
ret.put(name, compiler.classRegistry.getNumberOfGenerics(name));
|
||||
} else {
|
||||
Class<?> cl = compiler.getClassLoader().loadClass(name);
|
||||
ret.put(cl.getName(), cl.getTypeParameters().length);
|
||||
}
|
||||
} else if (importDeclCtx.MUL() != null) {
|
||||
// TODO Find stuff in user defined packages
|
||||
ret.putAll(packages.getClassNames(importDeclCtx.qualifiedName().getText()));
|
||||
}
|
||||
// Die Unterscheidungen für 'static imports' wurden herausgenommen, da sie den
|
||||
|
||||
@@ -12,6 +12,10 @@ import java.util.List;
|
||||
*/
|
||||
public class JavaClassName {
|
||||
|
||||
// FIXME It's very much possible to have imports to inner classes
|
||||
// In that case a.package.Foo.Bar, a.package is the Package and Foo.Bar the class name
|
||||
// Its impossible to decide what's the package based solely on the name of the class
|
||||
|
||||
public static final JavaClassName Void = new JavaClassName("void");
|
||||
private String name;
|
||||
private PackageName packageName;
|
||||
|
||||
@@ -11,11 +11,21 @@ public class JavaClassRegistry {
|
||||
final Map<JavaClassName, Integer> existingClasses = new HashMap<>();
|
||||
|
||||
public JavaClassRegistry(Map<String, Integer> initialNames) {
|
||||
for (String name : initialNames.keySet()) {
|
||||
existingClasses.put(new JavaClassName(name), initialNames.get(name));
|
||||
addNames(initialNames);
|
||||
}
|
||||
|
||||
public JavaClassRegistry() {}
|
||||
|
||||
public void addNames(Map<String, Integer> names) {
|
||||
for (String name : names.keySet()) {
|
||||
existingClasses.put(new JavaClassName(name), names.get(name));
|
||||
}
|
||||
}
|
||||
|
||||
public void addName(String className, int numberOfGenerics) {
|
||||
existingClasses.put(new JavaClassName(className), numberOfGenerics);
|
||||
}
|
||||
|
||||
public JavaClassName getName(String className) {
|
||||
for (JavaClassName name : existingClasses.keySet()) {
|
||||
if (name.equals(new JavaClassName(className)))
|
||||
|
||||
@@ -31,4 +31,11 @@ public interface ASTVisitor extends StatementVisitor{
|
||||
void visit(ExtendsWildcardType extendsWildcardType);
|
||||
|
||||
void visit(GenericRefType genericRefType);
|
||||
|
||||
void visit(ExpressionPattern aPattern);
|
||||
|
||||
void visit(RecordPattern aRecordPattern);
|
||||
|
||||
void visit(GuardedPattern aGuardedPattern);
|
||||
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@ package de.dhbwstuttgart.syntaxtree;
|
||||
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Literal;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class AbstractASTWalker implements ASTVisitor {
|
||||
@Override
|
||||
@@ -66,7 +66,7 @@ public abstract class AbstractASTWalker implements ASTVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(ParameterList formalParameters) {
|
||||
Iterator<FormalParameter> it = formalParameters.getFormalparalist().iterator();
|
||||
Iterator<Pattern> it = formalParameters.getFormalparalist().iterator();
|
||||
if (it.hasNext()) {
|
||||
while (it.hasNext()) {
|
||||
it.next().accept(this);
|
||||
@@ -134,6 +134,11 @@ public abstract class AbstractASTWalker implements ASTVisitor {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(BoolExpression logical) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Block block) {
|
||||
for (Statement stmt : block.getStatements()) {
|
||||
@@ -158,13 +163,14 @@ public abstract class AbstractASTWalker implements ASTVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(ForStmt forStmt) {
|
||||
forStmt.body_Loop_block.accept(this);
|
||||
forStmt.block.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(IfStmt ifStmt) {
|
||||
ifStmt.then_block.accept(this);
|
||||
ifStmt.else_block.accept(this);
|
||||
if (!Objects.isNull(ifStmt.else_block))
|
||||
ifStmt.else_block.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -269,4 +275,46 @@ public abstract class AbstractASTWalker implements ASTVisitor {
|
||||
public void visit(SuperCall superCall) {
|
||||
this.visit((MethodCall) superCall);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Switch switchStmt) {
|
||||
switchStmt.getSwitch().accept(this);
|
||||
switchStmt.getBlocks().stream().forEach((switchBlock) -> {
|
||||
switchBlock.accept(this);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(SwitchBlock switchBlock) {
|
||||
switchBlock.getLabels().stream().forEach((label) -> {
|
||||
label.accept(this);
|
||||
});
|
||||
switchBlock.getStatements().stream().forEach((stmt) -> {
|
||||
stmt.accept(this);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(SwitchLabel switchLabel) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Yield aYield) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ExpressionPattern aPattern) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RecordPattern aRecordPattern) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(GuardedPattern aGuardedPattern) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
package de.dhbwstuttgart.syntaxtree;
|
||||
|
||||
import de.dhbwstuttgart.core.IItemWithOffset;
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
@@ -24,96 +17,119 @@ import java.util.Optional;
|
||||
/**
|
||||
* Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces
|
||||
*/
|
||||
public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
|
||||
private Boolean methodAdded = false; //wird benoetigt bei in JavaTXCompiler.getConstraints()
|
||||
public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
||||
private Boolean methodAdded = false; // wird benoetigt bei in JavaTXCompiler.getConstraints()
|
||||
protected int modifiers;
|
||||
protected JavaClassName name;
|
||||
private List<Field> fields = new ArrayList<>();
|
||||
private Optional<Constructor> fieldInitializations; //PL 2018-11-24: Noetig, um Bytecode fuer initializators nur einmal zu erzeugen
|
||||
private Optional<Constructor> fieldInitializations; // PL 2018-11-24: Noetig, um Bytecode fuer initializators nur einmal zu erzeugen
|
||||
private Optional<Method> staticInitializer;
|
||||
private List<Method> methods = new ArrayList<>();
|
||||
private GenericDeclarationList genericClassParameters;
|
||||
private RefType superClass;
|
||||
protected boolean isInterface;
|
||||
protected boolean isFunctionalInterface;
|
||||
private List<RefType> implementedInterfaces;
|
||||
private List<RefType> permittedSubtypes;
|
||||
private List<Constructor> constructors;
|
||||
|
||||
|
||||
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters,
|
||||
RefType superClass, Boolean isInterface, List<RefType> implementedInterfaces, Token offset){
|
||||
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, Optional<Method> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, Boolean isFunctionalInterface, List<RefType> implementedInterfaces, List<RefType> permittedSubtypes, Token offset) {
|
||||
super(offset);
|
||||
if(isInterface && !Modifier.isInterface(modifiers))modifiers += Modifier.INTERFACE;
|
||||
this.modifiers = modifiers;
|
||||
this.name = name;
|
||||
this.fields = fielddecl;
|
||||
this.fieldInitializations= fieldInitializations;
|
||||
if (isInterface) {
|
||||
modifiers |= Modifier.INTERFACE | Modifier.ABSTRACT;
|
||||
}
|
||||
this.modifiers = modifiers;
|
||||
this.name = name;
|
||||
this.fields = fielddecl;
|
||||
this.fieldInitializations = fieldInitializations;
|
||||
this.staticInitializer = staticInitializer;
|
||||
this.genericClassParameters = genericClassParameters;
|
||||
this.superClass = superClass;
|
||||
this.superClass = superClass;
|
||||
this.isInterface = isInterface;
|
||||
this.implementedInterfaces = implementedInterfaces;
|
||||
this.isFunctionalInterface= isFunctionalInterface;
|
||||
this.implementedInterfaces = implementedInterfaces;
|
||||
this.permittedSubtypes = permittedSubtypes;
|
||||
this.methods = methods;
|
||||
this.constructors = constructors;
|
||||
}
|
||||
|
||||
/* erzeugt fuer Fields, Konstruktoren und Methoden neue ArrayList-Objekte
|
||||
* alle anderen Datenobjekte werden nur kopiert.
|
||||
|
||||
/*
|
||||
* erzeugt fuer Fields, Konstruktoren und Methoden neue ArrayList-Objekte alle anderen Datenobjekte werden nur kopiert.
|
||||
*/
|
||||
public ClassOrInterface(ClassOrInterface cl){
|
||||
super(cl.getOffset());
|
||||
this.modifiers = cl.modifiers;
|
||||
this.name = cl.name;
|
||||
this.fields = new ArrayList<>(cl.fields);
|
||||
this.fieldInitializations= cl.fieldInitializations;
|
||||
this.genericClassParameters = cl.genericClassParameters;
|
||||
this.superClass = cl.superClass;
|
||||
this.isInterface = cl.isInterface;
|
||||
this.implementedInterfaces = cl.implementedInterfaces;
|
||||
this.methods = new ArrayList<>(cl.methods);
|
||||
this.constructors = new ArrayList<>(cl.constructors);
|
||||
public ClassOrInterface(ClassOrInterface cl) {
|
||||
super(cl.getOffset());
|
||||
this.modifiers = cl.modifiers;
|
||||
this.name = cl.name;
|
||||
this.fields = new ArrayList<>(cl.fields);
|
||||
this.fieldInitializations = cl.fieldInitializations;
|
||||
this.staticInitializer = cl.staticInitializer;
|
||||
this.genericClassParameters = cl.genericClassParameters;
|
||||
this.superClass = cl.superClass;
|
||||
this.isInterface = cl.isInterface;
|
||||
this.isFunctionalInterface= cl.isFunctionalInterface;
|
||||
this.implementedInterfaces = cl.implementedInterfaces;
|
||||
this.methods = new ArrayList<>(cl.methods);
|
||||
this.constructors = new ArrayList<>(cl.constructors);
|
||||
}
|
||||
|
||||
public Optional<Field> getField(String name) {
|
||||
// TODO This should be a map
|
||||
return fields.stream().filter(field -> field.getName().equals(name)).findFirst();
|
||||
}
|
||||
|
||||
public Optional<Method> getStaticInitializer() {
|
||||
return staticInitializer;
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return (Modifier.INTERFACE & this.getModifiers()) != 0;
|
||||
}
|
||||
|
||||
public boolean isFunctionalInterface() {
|
||||
return this.isFunctionalInterface;
|
||||
}
|
||||
|
||||
//Gets if it is added
|
||||
// Gets if it is added
|
||||
public Boolean areMethodsAdded() {
|
||||
return methodAdded;
|
||||
return methodAdded;
|
||||
}
|
||||
|
||||
//Sets that it is added
|
||||
|
||||
// Sets that it is added
|
||||
public void setMethodsAdded() {
|
||||
methodAdded = true;
|
||||
methodAdded = true;
|
||||
}
|
||||
|
||||
|
||||
// Gets class name
|
||||
public JavaClassName getClassName(){
|
||||
public JavaClassName getClassName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
|
||||
// Get modifiers
|
||||
public int getModifiers(){
|
||||
public int getModifiers() {
|
||||
return this.modifiers;
|
||||
}
|
||||
|
||||
public List<Field> getFieldDecl(){
|
||||
public List<Field> getFieldDecl() {
|
||||
return this.fields;
|
||||
}
|
||||
|
||||
public Optional<Constructor> getfieldInitializations(){
|
||||
return this.fieldInitializations;
|
||||
}
|
||||
|
||||
public List<Method> getMethods(){
|
||||
|
||||
public Optional<Constructor> getfieldInitializations() {
|
||||
return this.fieldInitializations;
|
||||
}
|
||||
|
||||
public List<Method> getMethods() {
|
||||
return this.methods;
|
||||
}
|
||||
|
||||
/*
|
||||
public RefType getType() {
|
||||
return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset());
|
||||
}
|
||||
*/
|
||||
//TODO: Das hier ist ein Problem. Je nach Kontext wird hier ein anderer Typ benötigt
|
||||
public static RefType generateTypeOfClass(JavaClassName name, GenericDeclarationList genericsOfClass ,Token offset){
|
||||
//Hier wird immer ein generischer Typ generiert, also mit Type placeholdern
|
||||
* public RefType getType() { return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset()); }
|
||||
*/
|
||||
// TODO: Das hier ist ein Problem. Je nach Kontext wird hier ein anderer Typ benötigt
|
||||
public static RefType generateTypeOfClass(JavaClassName name, GenericDeclarationList genericsOfClass, Token offset) {
|
||||
// Hier wird immer ein generischer Typ generiert, also mit Type placeholdern
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
for(GenericTypeVar genericTypeVar : genericsOfClass){
|
||||
//params.add(genericTypeVar.getTypePlaceholder());
|
||||
for (GenericTypeVar genericTypeVar : genericsOfClass) {
|
||||
// params.add(genericTypeVar.getTypePlaceholder());
|
||||
params.add(TypePlaceholder.fresh(offset));
|
||||
}
|
||||
return new RefType(name, params, offset);
|
||||
@@ -123,18 +139,18 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
|
||||
*
|
||||
* @return die aktuelle Klasse als RefType
|
||||
*/
|
||||
public RefType generateTypeOfThisClass(){
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
for(GenericTypeVar genericTypeVar : this.getGenerics()){
|
||||
//params.add(genericTypeVar.getTypePlaceholder());
|
||||
params.add(new GenericRefType(genericTypeVar.getName(), new NullToken()));
|
||||
}
|
||||
return new RefType(name, params, new NullToken());
|
||||
}
|
||||
public RefType generateTypeOfThisClass() {
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
for (GenericTypeVar genericTypeVar : this.getGenerics()) {
|
||||
// params.add(genericTypeVar.getTypePlaceholder());
|
||||
params.add(new GenericRefType(genericTypeVar.getName(), new NullToken()));
|
||||
}
|
||||
return new RefType(name, params, new NullToken());
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Superklasse im Kontext dieser ClassOrInterface
|
||||
* Das bedeutet, dass generische Variablen als GenericRefTypes dargestellt sind
|
||||
*/
|
||||
* Die Superklasse im Kontext dieser ClassOrInterface Das bedeutet, dass generische Variablen als GenericRefTypes dargestellt sind
|
||||
*/
|
||||
public RefType getSuperClass() {
|
||||
return superClass;
|
||||
}
|
||||
@@ -160,8 +176,9 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
|
||||
public Collection<RefType> getSuperInterfaces() {
|
||||
return implementedInterfaces;
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
return this.name.toString() + this.genericClassParameters.toString();
|
||||
return this.name.toString() + this.genericClassParameters.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package de.dhbwstuttgart.syntaxtree;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
public class ExpressionPattern extends Pattern {
|
||||
private final Expression expression;
|
||||
|
||||
public ExpressionPattern(Expression expression, Token offset) {
|
||||
super(expression.getType(), offset);
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public Expression getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ASTVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressionPattern withType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||
return new ExpressionPattern(expression, getOffset());
|
||||
}
|
||||
}
|
||||
@@ -3,18 +3,12 @@ package de.dhbwstuttgart.syntaxtree;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
public class FormalParameter extends SyntaxTreeNode {
|
||||
private RefTypeOrTPHOrWildcardOrGeneric type;
|
||||
public class FormalParameter extends Pattern {
|
||||
private String name;
|
||||
|
||||
public FormalParameter(String name, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
|
||||
super(offset);
|
||||
super(type, offset);
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public RefTypeOrTPHOrWildcardOrGeneric getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@@ -25,4 +19,9 @@ public class FormalParameter extends SyntaxTreeNode {
|
||||
public void accept(ASTVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FormalParameter withType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||
return new FormalParameter(name, type, getOffset());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package de.dhbwstuttgart.syntaxtree;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
public class GuardedPattern extends Pattern {
|
||||
|
||||
private final Expression condition;
|
||||
private final Pattern nested;
|
||||
|
||||
public GuardedPattern(Expression condition, Pattern nested, Token offset) {
|
||||
super(nested.getType(), offset);
|
||||
this.condition = condition;
|
||||
this.nested = nested;
|
||||
}
|
||||
|
||||
public Expression getCondition() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
public Pattern getNestedPattern() {
|
||||
return nested;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ASTVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuardedPattern withType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||
return new GuardedPattern(condition, nested, getOffset());
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,7 @@ public class Method extends SyntaxTreeNode implements IItemWithOffset, TypeScope
|
||||
return parameterlist;
|
||||
}
|
||||
|
||||
public Iterable<? extends GenericTypeVar> getGenerics() {
|
||||
public GenericDeclarationList getGenerics() {
|
||||
return generics;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,27 +5,27 @@ import org.antlr.v4.runtime.Token;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class ParameterList extends SyntaxTreeNode implements Iterable<FormalParameter> {
|
||||
private List<FormalParameter> formalparameter;
|
||||
public class ParameterList extends SyntaxTreeNode implements Iterable<Pattern> {
|
||||
private List<Pattern> formalparameter;
|
||||
|
||||
public ParameterList(List<FormalParameter> params, Token offset) {
|
||||
public ParameterList(List<Pattern> params, Token offset) {
|
||||
super(offset);
|
||||
this.formalparameter = params;
|
||||
}
|
||||
|
||||
public FormalParameter getParameterAt(int i) {
|
||||
public Pattern getParameterAt(int i) {
|
||||
if (i >= formalparameter.size())
|
||||
return null;
|
||||
|
||||
return formalparameter.get(i);
|
||||
}
|
||||
|
||||
public List<FormalParameter> getFormalparalist() {
|
||||
public List<Pattern> getFormalparalist() {
|
||||
return formalparameter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<FormalParameter> iterator() {
|
||||
public Iterator<Pattern> iterator() {
|
||||
return formalparameter.iterator();
|
||||
}
|
||||
|
||||
|
||||
19
src/main/java/de/dhbwstuttgart/syntaxtree/Pattern.java
Normal file
19
src/main/java/de/dhbwstuttgart/syntaxtree/Pattern.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package de.dhbwstuttgart.syntaxtree;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
public abstract class Pattern extends SyntaxTreeNode {
|
||||
private final RefTypeOrTPHOrWildcardOrGeneric type;
|
||||
|
||||
public Pattern(RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
|
||||
super(offset);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public RefTypeOrTPHOrWildcardOrGeneric getType(){
|
||||
return type;
|
||||
}
|
||||
|
||||
public abstract Pattern withType(RefTypeOrTPHOrWildcardOrGeneric type);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package de.dhbwstuttgart.syntaxtree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -8,9 +9,11 @@ import org.antlr.v4.runtime.Token;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
|
||||
import javax.swing.text.html.Option;
|
||||
|
||||
public class Record extends ClassOrInterface {
|
||||
|
||||
public Record(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List<RefType> implementedInterfaces, Token offset) {
|
||||
super(modifiers, name, fielddecl, fieldInitializations, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset);
|
||||
public Record(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, Optional<Method> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List<RefType> implementedInterfaces, Token offset) {
|
||||
super(modifiers, name, fielddecl, fieldInitializations, staticInitializer, methods, constructors, genericClassParameters, superClass, isInterface, methods.size() == 1 ? true : false, implementedInterfaces, new ArrayList<>(), offset);
|
||||
}
|
||||
}
|
||||
|
||||
33
src/main/java/de/dhbwstuttgart/syntaxtree/RecordPattern.java
Normal file
33
src/main/java/de/dhbwstuttgart/syntaxtree/RecordPattern.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package de.dhbwstuttgart.syntaxtree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
|
||||
public class RecordPattern extends FormalParameter {
|
||||
|
||||
private final List<Pattern> subPattern;
|
||||
|
||||
public RecordPattern(String name, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
|
||||
super(name, type, offset);
|
||||
subPattern = new ArrayList<>();
|
||||
}
|
||||
|
||||
public RecordPattern(List<Pattern> subPattern, String name, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
|
||||
super(name, type, offset);
|
||||
this.subPattern = subPattern;
|
||||
}
|
||||
|
||||
public List<Pattern> getSubPattern() {
|
||||
return this.subPattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ASTVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,11 +21,11 @@ public class SourceFile extends SyntaxTreeNode {
|
||||
*/
|
||||
public SourceFile(String pkgName, List<ClassOrInterface> classDefinitions, Set<JavaClassName> imports) {
|
||||
super(new NullToken());
|
||||
if (classDefinitions.size() > 0) { // Enthält die Liste Klassen?
|
||||
//if (classDefinitions.size() > 0) { // Enthält die Liste Klassen?
|
||||
this.KlassenVektor = classDefinitions; // Klassen werden übernommen
|
||||
} else {
|
||||
this.KlassenVektor = null; // es handelt sich um ein "Java Module"
|
||||
}
|
||||
//} else {
|
||||
// this.KlassenVektor = null; // es handelt sich um ein "Java Module"
|
||||
//}
|
||||
this.pkgName = pkgName;
|
||||
this.imports = imports;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ public interface StatementVisitor {
|
||||
|
||||
void visit(BinaryExpr binary);
|
||||
|
||||
void visit(BoolExpression logical);
|
||||
|
||||
void visit(Block block);
|
||||
|
||||
void visit(CastExpr castExpr);
|
||||
@@ -41,8 +43,16 @@ public interface StatementVisitor {
|
||||
|
||||
void visit(ReturnVoid aReturn);
|
||||
|
||||
void visit(Switch switchStmt);
|
||||
|
||||
void visit(SwitchBlock switchBlock);
|
||||
|
||||
void visit(SwitchLabel switchLabel);
|
||||
|
||||
void visit(Break aBreak);
|
||||
|
||||
void visit(Yield aYield);
|
||||
|
||||
void visit(StaticClassName staticClassName);
|
||||
|
||||
void visit(Super aSuper);
|
||||
|
||||
@@ -1,27 +1,25 @@
|
||||
package de.dhbwstuttgart.syntaxtree.factory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.*;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.JavaTXSignatureAttribute;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.Field;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Block;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
||||
import de.dhbwstuttgart.syntaxtree.type.WildcardType;
|
||||
import de.dhbwstuttgart.target.tree.type.TargetRefType;
|
||||
import de.dhbwstuttgart.util.Pair;
|
||||
import javassist.bytecode.SignatureAttribute;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.objectweb.asm.*;
|
||||
@@ -29,13 +27,15 @@ import org.objectweb.asm.signature.SignatureReader;
|
||||
import org.objectweb.asm.signature.SignatureVisitor;
|
||||
|
||||
/**
|
||||
* Anmerkung:
|
||||
* Die ASTFactory Methoden, welche ASTBäume aus java.lang.Class Objekten generieren, können davon ausgehen,
|
||||
* dass alle Imports und Typnamen korrekt sind und müssen diese nicht überprüfen.
|
||||
* Anmerkung: Die ASTFactory Methoden, welche ASTBäume aus java.lang.Class Objekten generieren, können davon ausgehen, dass alle Imports und Typnamen korrekt sind und müssen diese nicht überprüfen.
|
||||
*/
|
||||
public class ASTFactory {
|
||||
|
||||
public static ClassOrInterface createClass(java.lang.Class jreClass){
|
||||
private static final HashMap<java.lang.Class, ClassOrInterface> cache = new HashMap<>();
|
||||
|
||||
public static ClassOrInterface createClass(java.lang.Class jreClass) {
|
||||
if (cache.containsKey(jreClass))
|
||||
return cache.get(jreClass);
|
||||
|
||||
// TODO Inner classes
|
||||
|
||||
@@ -46,7 +46,7 @@ public class ASTFactory {
|
||||
try {
|
||||
var path = jreClass.getName().replace('.', '/') + ".class";
|
||||
var classLoader = jreClass.getClassLoader();
|
||||
if (classLoader != null) {
|
||||
if (classLoader != null && new File(path).exists()) {
|
||||
var bytes = IOUtils.toByteArray(Objects.requireNonNull(classLoader.getResourceAsStream(path)));
|
||||
var classReader = new ClassReader(bytes);
|
||||
var classVisitor = new ClassVisitor(Opcodes.ASM7) {
|
||||
@@ -82,17 +82,16 @@ public class ASTFactory {
|
||||
}
|
||||
};
|
||||
|
||||
classReader.accept(classVisitor, new Attribute[]{new JavaTXSignatureAttribute()}, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
|
||||
classReader.accept(classVisitor, new Attribute[] { new JavaTXSignatureAttribute() }, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
|
||||
classSignature = classVisitor.classSignature;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Skip
|
||||
}
|
||||
|
||||
JavaClassName name = new JavaClassName(jreClass.getName());
|
||||
List<Method> methoden = new ArrayList<>();
|
||||
List<de.dhbwstuttgart.syntaxtree.Constructor> konstruktoren = new ArrayList<>();
|
||||
for(java.lang.reflect.Constructor constructor : jreClass.getConstructors()){
|
||||
for (java.lang.reflect.Constructor constructor : jreClass.getConstructors()) {
|
||||
var signature = methodSignatures.get(new Pair<>(constructor.getName(), org.objectweb.asm.Type.getConstructorDescriptor(constructor)));
|
||||
createConstructor(constructor, signature, jreClass).map(c -> konstruktoren.add(c));
|
||||
}
|
||||
@@ -100,65 +99,80 @@ public class ASTFactory {
|
||||
Set<java.lang.reflect.Method> allDeclaredMethods = new HashSet<>(Arrays.asList(jreClass.getDeclaredMethods()));
|
||||
Set<java.lang.reflect.Method> allInheritedMethods = new HashSet<>(allMethods);
|
||||
allInheritedMethods.removeAll(allDeclaredMethods);
|
||||
for(java.lang.reflect.Method method : allDeclaredMethods){
|
||||
for (java.lang.reflect.Method method : allDeclaredMethods) {
|
||||
var signature = methodSignatures.get(new Pair<>(method.getName(), org.objectweb.asm.Type.getMethodDescriptor(method)));
|
||||
methoden.add(createMethod(method, signature, jreClass, false));
|
||||
}
|
||||
for(java.lang.reflect.Method method : allInheritedMethods){
|
||||
for (java.lang.reflect.Method method : allInheritedMethods) {
|
||||
var signature = methodSignatures.get(new Pair<>(method.getName(), org.objectweb.asm.Type.getMethodDescriptor(method)));
|
||||
methoden.add(createMethod(method, signature, jreClass, true));
|
||||
}
|
||||
List<Field> felder = new ArrayList<>();
|
||||
for(java.lang.reflect.Field field : jreClass.getDeclaredFields()){
|
||||
for (java.lang.reflect.Field field : jreClass.getDeclaredFields()) {
|
||||
felder.add(createField(field, name));
|
||||
}
|
||||
int modifier = jreClass.getModifiers();
|
||||
boolean isInterface = jreClass.isInterface();
|
||||
//see: https://stackoverflow.com/questions/9934774/getting-generic-parameter-from-supertype-class
|
||||
List<Annotation> aLA;
|
||||
boolean isFunctionalInterface =
|
||||
(aLA = Arrays.asList(jreClass.getAnnotations())).size() > 0 &&
|
||||
aLA.get(0) instanceof FunctionalInterface ?
|
||||
true :
|
||||
false;
|
||||
// see: https://stackoverflow.com/questions/9934774/getting-generic-parameter-from-supertype-class
|
||||
ParameterizedType parameterSuperClass = null;
|
||||
Type tempSuperClass = jreClass.getGenericSuperclass();
|
||||
if(tempSuperClass != null && tempSuperClass instanceof ParameterizedType)
|
||||
if (tempSuperClass != null && tempSuperClass instanceof ParameterizedType)
|
||||
parameterSuperClass = (ParameterizedType) tempSuperClass;
|
||||
java.lang.Class superjreClass = jreClass.getSuperclass();
|
||||
RefType superClass;
|
||||
if(parameterSuperClass != null){
|
||||
if (parameterSuperClass != null) {
|
||||
superClass = (RefType) createType(parameterSuperClass);
|
||||
}else if(superjreClass != null){
|
||||
} else if (superjreClass != null) {
|
||||
superClass = (RefType) createType(superjreClass);
|
||||
}else{//Jede Klasse und jedes Interface erbt von Object: (auch Object selbst!)
|
||||
} else {// Jede Klasse und jedes Interface erbt von Object: (auch Object selbst!)
|
||||
superClass = (RefType) createType(java.lang.Object.class);
|
||||
}
|
||||
List<RefType> implementedInterfaces = new ArrayList<>();
|
||||
for(Type jreInterface : jreClass.getGenericInterfaces()){
|
||||
for (Type jreInterface : jreClass.getGenericInterfaces()) {
|
||||
implementedInterfaces.add((RefType) createType(jreInterface));
|
||||
}
|
||||
List<RefType> permittedSubtypes = new ArrayList<>();
|
||||
if (jreClass.isSealed()) {
|
||||
for (Class subclass : jreClass.getPermittedSubclasses()) {
|
||||
permittedSubtypes.add((RefType) createType(subclass));
|
||||
}
|
||||
}
|
||||
|
||||
GenericDeclarationList genericDeclarationList = createGenerics(jreClass.getTypeParameters(), jreClass, null, classSignature);
|
||||
GenericDeclarationList genericDeclarationList = createGenerics(jreClass.getTypeParameters(), jreClass, null, classSignature);
|
||||
|
||||
Token offset = new NullToken(); //Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde
|
||||
Token offset = new NullToken(); // Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde
|
||||
|
||||
return new ClassOrInterface(modifier, name, felder, Optional.empty() /* eingefuegt PL 2018-11-24 */,methoden, konstruktoren, genericDeclarationList, superClass,isInterface, implementedInterfaces, offset);
|
||||
var cinf = new ClassOrInterface(modifier, name, felder, Optional.empty() /* eingefuegt PL 2018-11-24 */, Optional.empty(), methoden, konstruktoren, genericDeclarationList, superClass, isInterface, isFunctionalInterface, implementedInterfaces, permittedSubtypes, offset);
|
||||
cache.put(jreClass, cinf);
|
||||
return cinf;
|
||||
}
|
||||
|
||||
private static Field createField(java.lang.reflect.Field field, JavaClassName jreClass) {
|
||||
return new Field(field.getName(), createType(field.getGenericType()), field.getModifiers(), new NullToken());
|
||||
}
|
||||
|
||||
//private static RefType createType(Class classType) {
|
||||
// return createClass(classType).getType();
|
||||
//}
|
||||
// private static RefType createType(Class classType) {
|
||||
// return createClass(classType).getType();
|
||||
// }
|
||||
|
||||
private static Optional<de.dhbwstuttgart.syntaxtree.Constructor> createConstructor(Constructor constructor, String signature, Class inClass) {
|
||||
private static Optional<de.dhbwstuttgart.syntaxtree.Constructor> createConstructor(Constructor constructor, String signature, Class inClass) {
|
||||
String name = constructor.getName();
|
||||
RefTypeOrTPHOrWildcardOrGeneric returnType = createType(inClass);
|
||||
Parameter[] jreParams = constructor.getParameters();
|
||||
Type[] jreGenericParams = constructor.getGenericParameterTypes();
|
||||
List<FormalParameter> params = new ArrayList<>();
|
||||
List<Pattern> params = new ArrayList<>();
|
||||
int i = 0;
|
||||
for(Type jreParam : jreGenericParams){
|
||||
if (jreParam == null) continue;
|
||||
for (Type jreParam : jreGenericParams) {
|
||||
if (jreParam == null)
|
||||
continue;
|
||||
RefTypeOrTPHOrWildcardOrGeneric paramType = createType(jreParam);
|
||||
params.add(new FormalParameter(jreParams[i].getName(),paramType, new NullToken()));
|
||||
params.add(new FormalParameter(jreParams[i].getName(), paramType, new NullToken()));
|
||||
i++;
|
||||
}
|
||||
ParameterList parameterList = new ParameterList(params, new NullToken());
|
||||
@@ -167,45 +181,46 @@ public class ASTFactory {
|
||||
Token offset = new NullToken();
|
||||
int modifier = constructor.getModifiers();
|
||||
|
||||
if(inClass.equals(java.lang.Object.class)){
|
||||
if (inClass.equals(java.lang.Object.class)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(new de.dhbwstuttgart.syntaxtree.Constructor(modifier, name,returnType, parameterList, block, gtvDeclarations, offset /*, new ArrayList<>() geloescht PL 2018-11-24 */));
|
||||
return Optional.of(new de.dhbwstuttgart.syntaxtree.Constructor(modifier, name, returnType, parameterList, block, gtvDeclarations, offset /* , new ArrayList<>() geloescht PL 2018-11-24 */));
|
||||
}
|
||||
|
||||
public static Method createMethod(java.lang.reflect.Method jreMethod, String signature, java.lang.Class inClass, Boolean isInherited){
|
||||
public static Method createMethod(java.lang.reflect.Method jreMethod, String signature, java.lang.Class inClass, Boolean isInherited) {
|
||||
String name = jreMethod.getName();
|
||||
RefTypeOrTPHOrWildcardOrGeneric returnType;
|
||||
Type jreRetType;
|
||||
if(jreMethod.getGenericReturnType()!=null){
|
||||
if (jreMethod.getGenericReturnType() != null) {
|
||||
jreRetType = jreMethod.getGenericReturnType();
|
||||
}else{
|
||||
} else {
|
||||
jreRetType = jreMethod.getReturnType();
|
||||
}
|
||||
returnType = createType(jreRetType);
|
||||
Parameter[] jreParams = jreMethod.getParameters();
|
||||
Type[] jreGenericParams = jreMethod.getGenericParameterTypes();
|
||||
List<FormalParameter> params = new ArrayList<>();
|
||||
List<Pattern> params = new ArrayList<>();
|
||||
int i = 0;
|
||||
for(Type jreParam : jreGenericParams){
|
||||
if (jreParam == null) continue;
|
||||
for (Type jreParam : jreGenericParams) {
|
||||
if (jreParam == null)
|
||||
continue;
|
||||
RefTypeOrTPHOrWildcardOrGeneric paramType = createType(jreParam);
|
||||
params.add(new FormalParameter(jreParams[i].getName(),paramType, new NullToken()));
|
||||
params.add(new FormalParameter(jreParams[i].getName(), paramType, new NullToken()));
|
||||
i++;
|
||||
}
|
||||
ParameterList parameterList = new ParameterList(params, new NullToken());
|
||||
Block block = new Block(new ArrayList<Statement>(), new NullToken());
|
||||
GenericDeclarationList gtvDeclarations = createGenerics(jreMethod.getTypeParameters(), inClass, jreMethod.getName(), signature);
|
||||
GenericDeclarationList gtvDeclarations = createGenerics(jreMethod.getTypeParameters(), inClass, jreMethod.getName(), signature);
|
||||
Token offset = new NullToken();
|
||||
|
||||
return new Method(jreMethod.getModifiers(), name,returnType, parameterList, block, gtvDeclarations, offset, isInherited);
|
||||
return new Method(jreMethod.getModifiers(), name, returnType, parameterList, block, gtvDeclarations, offset, isInherited);
|
||||
}
|
||||
|
||||
public static GenericDeclarationList createGenerics(TypeVariable[] typeParameters, Class context, String methodName, String signature) {
|
||||
if (signature == null) {
|
||||
List<de.dhbwstuttgart.syntaxtree.GenericTypeVar> gtvs = new ArrayList<>();
|
||||
for(TypeVariable jreTV : typeParameters){
|
||||
for (TypeVariable jreTV : typeParameters) {
|
||||
de.dhbwstuttgart.syntaxtree.GenericTypeVar gtv = createGeneric(jreTV, jreTV.getName(), context, methodName);
|
||||
gtvs.add(gtv);
|
||||
}
|
||||
@@ -217,7 +232,8 @@ public class ASTFactory {
|
||||
}
|
||||
|
||||
public static GenericDeclarationList createGenerics(String signature) {
|
||||
if (signature == null) return new GenericDeclarationList(new ArrayList<>(), new NullToken());
|
||||
if (signature == null)
|
||||
return new GenericDeclarationList(new ArrayList<>(), new NullToken());
|
||||
|
||||
var gtvs = new ArrayList<GenericTypeVar>();
|
||||
var signatureVisitor = new SignatureVisitor(Opcodes.ASM7) {
|
||||
@@ -226,7 +242,8 @@ public class ASTFactory {
|
||||
final Stack<RefType> classTypes = new Stack<>();
|
||||
|
||||
// All hail the mighty visitor pattern
|
||||
final SignatureVisitor doNothing = new SignatureVisitor(Opcodes.ASM7) {};
|
||||
final SignatureVisitor doNothing = new SignatureVisitor(Opcodes.ASM7) {
|
||||
};
|
||||
|
||||
char wildcard = '=';
|
||||
|
||||
@@ -334,61 +351,61 @@ public class ASTFactory {
|
||||
return new GenericDeclarationList(gtvs, new NullToken());
|
||||
}
|
||||
|
||||
private static RefTypeOrTPHOrWildcardOrGeneric createType(java.lang.reflect.Type type){
|
||||
if(type == null || type.getTypeName().equals("void")){
|
||||
private static RefTypeOrTPHOrWildcardOrGeneric createType(java.lang.reflect.Type type) {
|
||||
if (type == null || type.getTypeName().equals("void")) {
|
||||
return new Void(new NullToken());
|
||||
}else if(type.getTypeName().equals("int")){
|
||||
return new RefType(new JavaClassName("java.lang.Integer"), new ArrayList<>(), new NullToken());
|
||||
}else if(type.getTypeName().equals("byte")){
|
||||
return new RefType(new JavaClassName("java.lang.Byte"), new ArrayList<>(), new NullToken());
|
||||
}else if(type.getTypeName().equals("boolean")){
|
||||
return new RefType(new JavaClassName("java.lang.Boolean"), new ArrayList<>(), new NullToken());
|
||||
}else if(type.getTypeName().equals("char")){
|
||||
return new RefType(new JavaClassName("java.lang.Char"), new ArrayList<>(), new NullToken());
|
||||
}else if(type.getTypeName().equals("short")){
|
||||
return new RefType(new JavaClassName("java.lang.Short"), new ArrayList<>(), new NullToken());
|
||||
}else if(type.getTypeName().equals("double")){
|
||||
return new RefType(new JavaClassName("java.lang.Double"), new ArrayList<>(), new NullToken());
|
||||
}else if(type.getTypeName().equals("long")){
|
||||
return new RefType(new JavaClassName("java.lang.Long"), new ArrayList<>(), new NullToken());
|
||||
}else{
|
||||
if(type instanceof TypeVariable){
|
||||
//GTVDeclarationContext via "(TypeVariable) type).getGenericDeclaration()"
|
||||
} else if (type.getTypeName().equals("int")) {
|
||||
return new RefType(new JavaClassName("java.lang.Integer"), new ArrayList<>(), new NullToken(), true);
|
||||
} else if (type.getTypeName().equals("byte")) {
|
||||
return new RefType(new JavaClassName("java.lang.Byte"), new ArrayList<>(), new NullToken(), true);
|
||||
} else if (type.getTypeName().equals("boolean")) {
|
||||
return new RefType(new JavaClassName("java.lang.Boolean"), new ArrayList<>(), new NullToken(), true);
|
||||
} else if (type.getTypeName().equals("char")) {
|
||||
return new RefType(new JavaClassName("java.lang.Char"), new ArrayList<>(), new NullToken(), true);
|
||||
} else if (type.getTypeName().equals("short")) {
|
||||
return new RefType(new JavaClassName("java.lang.Short"), new ArrayList<>(), new NullToken(), true);
|
||||
} else if (type.getTypeName().equals("double")) {
|
||||
return new RefType(new JavaClassName("java.lang.Double"), new ArrayList<>(), new NullToken(), true);
|
||||
} else if (type.getTypeName().equals("long")) {
|
||||
return new RefType(new JavaClassName("java.lang.Long"), new ArrayList<>(), new NullToken(), true);
|
||||
} else {
|
||||
if (type instanceof TypeVariable) {
|
||||
// GTVDeclarationContext via "(TypeVariable) type).getGenericDeclaration()"
|
||||
return new GenericRefType(type.getTypeName(), new NullToken());
|
||||
}
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
if(type instanceof ParameterizedType){
|
||||
for(Type t : ((ParameterizedType)type).getActualTypeArguments()){
|
||||
if (type instanceof ParameterizedType) {
|
||||
for (Type t : ((ParameterizedType) type).getActualTypeArguments()) {
|
||||
params.add(createType(t));
|
||||
}
|
||||
}
|
||||
String name = type.getTypeName();
|
||||
if(name.contains("<")){ //Komischer fix. Type von Generischen Typen kann die Generics im Namen enthalten Type<A>
|
||||
//Diese entfernen:
|
||||
if (name.contains("<")) { // Komischer fix. Type von Generischen Typen kann die Generics im Namen enthalten Type<A>
|
||||
// Diese entfernen:
|
||||
name = name.split("<")[0];
|
||||
}
|
||||
if(type instanceof java.lang.reflect.WildcardType){
|
||||
if (type instanceof java.lang.reflect.WildcardType) {
|
||||
java.lang.reflect.WildcardType wildcardType = (java.lang.reflect.WildcardType) type;
|
||||
if(wildcardType.getLowerBounds().length > 0){
|
||||
if (wildcardType.getLowerBounds().length > 0) {
|
||||
return new SuperWildcardType(createType(wildcardType.getLowerBounds()[0]), new NullToken());
|
||||
}else if(wildcardType.getUpperBounds().length > 0){
|
||||
} else if (wildcardType.getUpperBounds().length > 0) {
|
||||
return new ExtendsWildcardType(createType(wildcardType.getUpperBounds()[0]), new NullToken());
|
||||
}else{//Es handelt sich um den '?'-Typ:
|
||||
} else {// Es handelt sich um den '?'-Typ:
|
||||
return new ExtendsWildcardType(createObjectType(), new NullToken());
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
RefType ret = new RefType(new JavaClassName(name), params, new NullToken());
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static de.dhbwstuttgart.syntaxtree.GenericTypeVar createGeneric(TypeVariable jreTypeVar, String jreTVName, Class context, String parentMethod){
|
||||
public static de.dhbwstuttgart.syntaxtree.GenericTypeVar createGeneric(TypeVariable jreTypeVar, String jreTVName, Class context, String parentMethod) {
|
||||
JavaClassName parentClass = new JavaClassName(context.getName());
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> genericBounds = new ArrayList<>();
|
||||
java.lang.reflect.Type[] bounds = jreTypeVar.getBounds();
|
||||
if(bounds.length > 0){
|
||||
for(java.lang.reflect.Type bound : bounds){
|
||||
if (bounds.length > 0) {
|
||||
for (java.lang.reflect.Type bound : bounds) {
|
||||
genericBounds.add(createType(bound));
|
||||
}
|
||||
}
|
||||
@@ -403,49 +420,27 @@ public class ASTFactory {
|
||||
return new RefType(createClass(Object.class).getClassName(), new NullToken());
|
||||
}
|
||||
|
||||
/*
|
||||
public Constructor createEmptyConstructor(Class parent){
|
||||
Block block = new Block();
|
||||
block.setType(new de.dhbwstuttgart.syntaxtree.type.Void(block, 0));
|
||||
block.statements.add(new SuperCall(block));
|
||||
|
||||
return ASTFactory.createConstructor(parent, new ParameterList(), block);
|
||||
}
|
||||
|
||||
public static Constructor createConstructor(Class superClass, ParameterList paralist, Block block){
|
||||
block.parserPostProcessing(superClass);
|
||||
|
||||
Method method = ASTFactory.createMethod("<init>", paralist, block, superClass);
|
||||
method.setType(new de.dhbwstuttgart.syntaxtree.type.Void(block, 0));
|
||||
|
||||
return new Constructor(method, superClass);
|
||||
}
|
||||
|
||||
public static Class createClass(String className, RefType type, Modifiers modifiers, Menge supertypeGenPara, SourceFile parent) {
|
||||
// TODO bytecode createClass
|
||||
//String name, RefType superClass, Modifiers modifiers, Menge<String> supertypeGenPara
|
||||
Class generatedClass = new Class(className, type, modifiers, supertypeGenPara);
|
||||
generatedClass.addField(ASTFactory.createEmptyConstructor(generatedClass));
|
||||
|
||||
generatedClass.parserPostProcessing(parent);
|
||||
|
||||
return generatedClass;
|
||||
}
|
||||
|
||||
public static Class createObject(){
|
||||
return createClass(java.lang.Object.class);
|
||||
}
|
||||
|
||||
public static Class createInterface(String className, RefType superClass, Modifiers modifiers,
|
||||
Menge supertypeGenPara, SourceFile parent){
|
||||
Class generatedClass = new Class(new JavaClassName(className), new ArrayList<Method>(), new ArrayList<Field>(), modifiers,
|
||||
true, superClass, new ArrayList<RefType>(), new GenericDeclarationList(), -1);
|
||||
generatedClass.parserPostProcessing(parent);
|
||||
return generatedClass;
|
||||
}
|
||||
|
||||
public static RefType createObjectType(){
|
||||
return createObjectClass().getType();
|
||||
}
|
||||
*/
|
||||
/*
|
||||
* public Constructor createEmptyConstructor(Class parent){ Block block = new Block(); block.setType(new de.dhbwstuttgart.syntaxtree.type.Void(block, 0)); block.statements.add(new SuperCall(block));
|
||||
*
|
||||
* return ASTFactory.createConstructor(parent, new ParameterList(), block); }
|
||||
*
|
||||
* public static Constructor createConstructor(Class superClass, ParameterList paralist, Block block){ block.parserPostProcessing(superClass);
|
||||
*
|
||||
* Method method = ASTFactory.createMethod("<init>", paralist, block, superClass); method.setType(new de.dhbwstuttgart.syntaxtree.type.Void(block, 0));
|
||||
*
|
||||
* return new Constructor(method, superClass); }
|
||||
*
|
||||
* public static Class createClass(String className, RefType type, Modifiers modifiers, Menge supertypeGenPara, SourceFile parent) { // TODO bytecode createClass //String name, RefType superClass, Modifiers modifiers, Menge<String> supertypeGenPara Class generatedClass = new Class(className, type, modifiers, supertypeGenPara); generatedClass.addField(ASTFactory.createEmptyConstructor(generatedClass));
|
||||
*
|
||||
* generatedClass.parserPostProcessing(parent);
|
||||
*
|
||||
* return generatedClass; }
|
||||
*
|
||||
* public static Class createObject(){ return createClass(java.lang.Object.class); }
|
||||
*
|
||||
* public static Class createInterface(String className, RefType superClass, Modifiers modifiers, Menge supertypeGenPara, SourceFile parent){ Class generatedClass = new Class(new JavaClassName(className), new ArrayList<Method>(), new ArrayList<Field>(), modifiers, true, superClass, new ArrayList<RefType>(), new GenericDeclarationList(), -1); generatedClass.parserPostProcessing(parent); return generatedClass; }
|
||||
*
|
||||
* public static RefType createObjectType(){ return createObjectClass().getType(); }
|
||||
*/
|
||||
}
|
||||
@@ -15,8 +15,8 @@ public class BinaryExpr extends Expression {
|
||||
SUB, // -
|
||||
MUL, // *
|
||||
MOD, // Modulo Operator %
|
||||
AND, // &&
|
||||
OR, // ||
|
||||
AND, // &
|
||||
OR, // |
|
||||
DIV, // /
|
||||
LESSTHAN, // <
|
||||
BIGGERTHAN, // >
|
||||
|
||||
@@ -1,26 +1,22 @@
|
||||
package de.dhbwstuttgart.syntaxtree.statement;
|
||||
import java.util.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
|
||||
public class Block extends Statement
|
||||
{
|
||||
public class Block extends Statement {
|
||||
public Block(List<Statement> statements, Token offset) {
|
||||
super(TypePlaceholder.fresh(offset), offset);
|
||||
this.statements = statements;
|
||||
}
|
||||
super(TypePlaceholder.fresh(offset), offset);
|
||||
this.statements = statements;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public List<Statement> statements = new ArrayList<>();
|
||||
|
||||
public List<Statement> getStatements()
|
||||
{
|
||||
public List<Statement> getStatements() {
|
||||
return statements;
|
||||
}
|
||||
|
||||
@@ -29,5 +25,3 @@ public class Block extends Statement
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package de.dhbwstuttgart.syntaxtree.statement;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
|
||||
public class BoolExpression extends Expression {
|
||||
|
||||
public enum Operator {
|
||||
AND, // &&
|
||||
OR, // ||
|
||||
}
|
||||
|
||||
public final Operator operation;
|
||||
public final Expression lexpr;
|
||||
public final Expression rexpr;
|
||||
|
||||
public BoolExpression(Operator operation, RefTypeOrTPHOrWildcardOrGeneric type, Expression lexpr, Expression rexpr, Token offset) {
|
||||
super(type, offset);
|
||||
this.operation = operation;
|
||||
this.lexpr = lexpr;
|
||||
this.rexpr = rexpr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(StatementVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,7 +13,7 @@ public class Break extends Statement {
|
||||
|
||||
@Override
|
||||
public void accept(StatementVisitor visitor) {
|
||||
this.accept((StatementVisitor) visitor);
|
||||
visitor.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