Compare commits

..

5 Commits

Author SHA1 Message Date
pl@gohorb.ba-horb.de
9c519d0746 new file: resources/AllgemeinTest/Uncurrier.jav
All checks were successful
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 2m28s
new file:   resources/AllgemeinTest/UncurrierMain.jav
	modified:   resources/KPSPresentation/Faculty.jav
	modified:   resources/KPSPresentation/Main.jav
	new file:   resources/KPSPresentation/MainFaculty.jav
	new file:   resources/KPSPresentation/MainOL.jav
	modified:   resources/KPSPresentation/MatrixOP.jav
	modified:   resources/KPSPresentation/OL.jav
	modified:   src/test/java/KPSPresentation.java
2025-10-10 10:38:05 +02:00
pl@gohorb.ba-horb.de
db040d590e modified: Main.jav
All checks were successful
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 1m37s
modified:   Matrix.jav
	modified:   ../../src/test/java/KPSPresentation.java
2025-09-24 18:35:19 +02:00
pl@gohorb.ba-horb.de
f496ff13b8 new file: ../applyLambda.jav
All checks were successful
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 1m35s
2025-09-24 15:57:47 +02:00
pl@gohorb.ba-horb.de
642ecc9a50 modified: ../Id.jav
modified:   ../Main.jav
	modified:   ../OL.jav
	modified:   ../../../src/test/java/KPSPresentation.java
2025-09-24 15:57:22 +02:00
pl@gohorb.ba-horb.de
a0e59eebe8 new file: AddEle.jav
All checks were successful
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 1m35s
new file:   Fac.jav
	new file:   Faculty.jav
2025-09-24 13:53:55 +02:00
163 changed files with 5162 additions and 8713 deletions

View File

@@ -18,7 +18,7 @@ jobs:
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '25'
java-version: '24'
cache: 'maven'
- name: Compile project
run: |

View File

@@ -24,7 +24,7 @@ jobs:
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '25'
java-version: '24'
cache: 'maven'
- name: Compile project
run: |

View File

@@ -1,40 +0,0 @@
#!/usr/bin/env bash
REPO="https://gitea.hb.dhbw-stuttgart.de/f.holzwarth/JavaCompilerCore.git"
TDIR="./testBuild"
rm -rf "$TDIR" 2>/dev/null
mkdir $TDIR
cd $TDIR
git clone $REPO .
git checkout feat/unify-server
# git checkout 93e1a8787cd94c73f4538f6a348f58613893a584
# git checkout dad468368b86bdd5a3d3b2754b17617cee0a9107 # 1:55
# git checkout a0c11b60e8c9d7addcbe0d3a09c9ce2924e9d5c0 # 2:25
# git checkout 4cddf73e6d6c9116d3e1705c4b27a8e7f18d80c3 # 2:27
# git checkout 6c2d97b7703d954e4a42eef3ec374bcf313af75c # 2:13
# git checkout f722a00fbb6e69423d48a890e4a6283471763e64 # 1:35
# git checkout f0a4a51ce65639ce9a9470ff0fdb538fdf9c02cc # 2:19
# git checkout 1391206dfe59263cdb22f93371cfd1dd5465d97f # 1:29
date "+%Y.%m.%d %H:%M:%S"
# sed -i -e 's/source>21/source>23/g' pom.xml
# sed -i -e 's/target>21/target>23/g' pom.xml
mvn clean compile -DskipTests package
time java -jar target/JavaTXcompiler-0.1-jar-with-dependencies.jar resources/bytecode/javFiles/Matrix.jav;
# mvn clean compile test
echo -e "\nCleanup... "
cd -
rm -rf "$TDIR" 2>/dev/null
echo -e "\nFinished "
date "+%Y.%m.%d %H:%M:%S"
echo -e "\n "

32
pom.xml
View File

@@ -44,31 +44,6 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<artifactId>asm</artifactId>
<version>9.8</version>
</dependency>
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.5.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.2</version>
</dependency>
<dependency>
<groupId>com.diogonunes</groupId>
<artifactId>JColor</artifactId>
<version>5.5.1</version>
</dependency>
<dependency>
<groupId>org.jcommander</groupId>
<artifactId>jcommander</artifactId>
<version>3.0</version>
</dependency>
</dependencies>
<build>
@@ -97,8 +72,9 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.0</version>
<configuration>
<source>25</source>
<target>25</target>
<compilerArgs>--enable-preview</compilerArgs>
<source>24</source>
<target>24</target>
</configuration>
</plugin>
<plugin>
@@ -181,4 +157,4 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<url>file:///${project.basedir}/maven-repository/</url>
</repository>
</distributionManagement>
</project>
</project>

View File

@@ -0,0 +1,7 @@
public class Uncurrier{
uncurry (f){
return x -> f.apply(x);}
uncurry (f){
return (x, y) -> f.apply(x).apply(y);
}
}

View File

@@ -0,0 +1,9 @@
import Uncurrier;
import java.lang.Integer;
class UncurrierMain {
meth(y) {
var uc = new Uncurrier() ;
uc.uncurry(x -> x+1);
}
}

View File

@@ -0,0 +1,9 @@
import java.util.Vector;
import java.util.Collection;
class AddEle {
addEle(x, y) {
x.add(y);
return x;
}
}

View File

@@ -0,0 +1,15 @@
import java.lang.Double;
import java.lang.Integer;
public class Fac {
getFac(n){
var res = 1;
var i = 1;
while(i<=n) {
res = res * i;
i++;
}
return res;
}
}

View File

@@ -0,0 +1,25 @@
import java.lang.Integer;
import java.lang.Double;
import java.lang.System;
import java.io.PrintStream;
public class Faculty {
public Fun1$$<Double, Double> fact = (x) -> {
if (x == 1) {
return 1;
}
else {
return x * (fact.apply(x-1.0));
}
};
public getFact(x) {
return fact.apply(x);
}
public static void main(x) {
var f = new Faculty();
var intRes = f.getFact(3.0);
System.out.println(intRes);
}
}

View File

@@ -0,0 +1,18 @@
import java.lang.Integer;
import java.lang.Float;
public class FacultyBug {
public Fun1$$<Float, Float> fact = (x) -> {
if (x == 1) {
return 1;
}
else {
return x * (fact.apply(x-1));
}
};
public getFact(x) {
return fact.apply(x);
}
}

View File

@@ -0,0 +1,11 @@
class Id {
id2 = x -> x;
id(x) {
return x;
}
id3(x) {
return id(x);
}
}

View File

@@ -0,0 +1,11 @@
import java.lang.Integer;
public class Lambda {
m () {
var lam1 = (x) -> {
return x * x;
};
return lam1;
}
}

View File

@@ -0,0 +1,106 @@
import java.lang.String ;
import java.lang.System;
import java.io.PrintStream;
import java.lang.Character;
import java.lang.Object;
import java.lang.Integer;
import fst;
import Id;
import OLMain;
import Fac;
import Faculty;
import applyLambda;
import java.util.Vector;
import Matrix;
import MatrixOP;
public class Main {
public static main(x) {
/*
new fst().main(5);
System.out.println(new fst().main(5));
//Id.jav: the identity-function
//applied to an integer
System.out.println(new Id().id(1));
//applied to a string
System.out.println(new Id().id("hallo"));
//lamda-Expr
//System.out.println(new Id().id2.apply(1));
//Bug: https://gitea.hb.dhbw-stuttgart.de/JavaTX/JavaCompilerCore/issues/378
//OL.jav: Overloading
OLMain ol = new OLMain();
//the function main is applied to an integer
System.out.println(ol.main(2));
//the main is applied to a double
System.out.println(ol.main(2.0));
System.out.println(ol.main("Hallo"));
//Fac.jav
System.out.println(new Fac().getFac(6));
//Faculty.jav
//System.out.println(new Faculty().fact.apply(6));
//Bug: https://gitea.hb.dhbw-stuttgart.de/JavaTX/JavaCompilerCore/issues/378
System.out.println(new Faculty().getFact(3));
//Lambda.jav: An lambda expression applied by the method apply
//System.out.println(new Lambda().m().apply(77));
//Bug: https://gitea.hb.dhbw-stuttgart.de/JavaTX/JavaCompilerCore/issues/378
//applyLambda.jav: A defined lambda expression is applied
System.out.println(new applyLambda().m());
*/
Vector<Vector<Integer>> vv = new Vector<Vector<Integer>>();
Vector<Integer> v1 = new Vector<Integer> ();
v1.addElement(2);
v1.addElement(2);
Vector<Integer> v2 = new Vector<Integer> ();
v2.addElement(3);
v2.addElement(3);
Matrix m1 = new Matrix();
m1.addElement(v1);
m1.addElement(v2);
//vv.addElement(v1);
//vv.addElement(v2);
//Matrix m1 = new Matrix(vv);
Vector<Vector<Integer>> vv1 = new Vector<Vector<Integer>>();
Vector<Integer> v3 = new Vector<Integer> ();
v3.addElement(2);
v3.addElement(2);
Vector<Integer> v4 = new Vector<Integer> ();
v4.addElement(3);
v4.addElement(3);
Matrix m2 = new Matrix();
m2.addElement(v3);
m2.addElement(v4);
//vv1.addElement(v3);
//vv1.addElement(v4);
//Matrix m2 = new Matrix(vv1);
//Matrix m3 = m1.mul(vv1);
Matrix m3 = m1.mul(m2);
System.out.println(m1.toString() + " * " + m2.toString() + " = " + m3.toString());
//MatrixOP
MatrixOP mOp1 = new MatrixOP();
mOp1.addElement(v1);
mOp1.addElement(v2);
MatrixOP mOp2 = mOp1.mul.apply(mOp1, mOp1);
System.out.println(m1.toString() + " * " + m2.toString() + " = " + mOp2.toString());
}
}
/*
public class MainBug {
public static main(x) {
System.out.println(new fst().main(5));
//System.out.println(new FacultyBug().getFact(3));
}
}
*/

View File

@@ -0,0 +1,11 @@
import java.lang.System;
import java.io.PrintStream;
import Faculty;
public class MainFaculty {
public static void main(x) {
//var f = new Faculty();
//var intRes = f.getFact(3);
//System.out.println(intRes);
}
}

View File

@@ -0,0 +1,20 @@
import java.lang.String ;
import java.lang.System;
import java.io.PrintStream;
import java.lang.Float;
import OL2;
class MainOL {
public static main(x) {
var ol = new OL2();
//the function main is applied to an integer
//var res1 = ol.m2(2);
//the main is applied to a double
//System.out.println(ol.m2(2.0));
//System.out.println(ol.m2("Hallo").toString());
var res2 = ol.m2("Hallo").toString();
System.out.println(res2);
}
}

View File

@@ -0,0 +1,41 @@
import java.util.Vector;
import java.lang.Integer;
import java.lang.Boolean;
public class Matrix extends Vector<Vector<Integer>> {
public Matrix () {
}
public Matrix(vv) {
var i = 0;
while(i < vv.size()) {
this.add(vv.elementAt(i));
i=i+1;
}
}
mul(m) {
var ret = new Matrix();
var i = 0;
while(i < size()) {
var v1 = this.elementAt(i);
var v2 = new Vector<Integer>();
var j = 0;
while(j < v1.size()) {
var erg = 0;
var k = 0;
while(k < v1.size()) {
erg = erg + v1.elementAt(k)
* m.elementAt(k).elementAt(j);
k++; }
v2.addElement(erg);
j++; }
ret.addElement(v2);
i++;
}
return ret;
}
}

View File

@@ -0,0 +1,64 @@
import java.util.Vector;
import java.lang.Integer;
//import java.lang.Byte;
import java.lang.Boolean;
import java.lang.String;
import java.lang.System;
import java.io.PrintStream;
public class MatrixOP extends Vector<Vector<Integer>> {
public MatrixOP () {
}
public MatrixOP(vv) {
Integer i;
i = 0;
while(i < vv.size()) {
this.add(vv.elementAt(i));
i=i+1;
}
}
mul = (m1, m2) -> {
var ret = new MatrixOP();
var i = 0;
while(i < m1.size()) {
var v1 = m1.elementAt(i);
var v2 = new Vector<Integer>();
var j = 0;
while(j < v1.size()) {
var erg = 0;
var k = 0;
while(k < v1.size()) {
erg = erg + v1.elementAt(k)
* m2.elementAt(k).elementAt(j);
k++; }
// v2.addElement(new Integer(erg));
v2.addElement(erg);
j++; }
ret.addElement(v2);
i++;
}
return ret;
};
public static main(x) {
var vv = new Vector<Vector<Integer>>();
var v1 = new Vector<Integer> ();
v1.addElement(2);
v1.addElement(2);
var v2 = new Vector<Integer> ();
v2.addElement(3);
v2.addElement(3);
//MatrixOP
MatrixOP mOp1 = new MatrixOP();
mOp1.addElement(v1);
mOp1.addElement(v2);
MatrixOP mOp2 = mOp1.mul.apply(mOp1, mOp1);
System.out.print(mOp1); System.out.print(" * "); System.out.print(mOp1); System.out.print(" = "); System.out.println(mOp2);
//System.out.print(mOp1 + " * " + mOp1 + " = " + mOp2);
}
}
}

View File

@@ -0,0 +1,33 @@
import java.lang.String;
import java.lang.Integer;
import java.lang.Double;
import java.lang.Boolean;
import java.lang.Object;
import java.lang.System;
import java.io.PrintStream;
public class OL1 {
m1( x) { return x + x; }
m1(x) { return x || x; }
}
public class OL2 {
m2(x) {
var ol;
ol = new OL1();
return ol.m1(x);
}
}

View File

@@ -0,0 +1,20 @@
import java.lang.String;
import java.lang.Integer;
import java.lang.Double;
import java.util.Vector;
import java.lang.Boolean;
public class OLFun {
x;
m(f, y) {
y = f.apply(x+x);
return x;
}
}

View File

@@ -0,0 +1,12 @@
class Pair {
fst;
snd;
Pair(fst, snd) { this.fst=fst; this.snd=snd; }
getfst() { return this.fst; }
swap() {
return new Pair<>(this.snd, this.fst);
}
}

View File

@@ -0,0 +1,9 @@
import java.lang.Integer;
import java.lang.String;
public class Plus {
m(a, b) {
return a+b;
}
}

View File

@@ -0,0 +1,25 @@
import java.util.List;
import java.util.ArrayList;
import java.lang.String;
public class Sorting{
merge(a, b){
a.addAll(b);
return a;
}
sort(in){
var firstHalf = in;
var secondHalf = in;
return merge(sort(firstHalf), sort(secondHalf));
}
/*
void sort(a){
a = merge(a,a);
}
*/
}

View File

@@ -0,0 +1,20 @@
import java.lang.String;
import java.lang.Object;
import java.lang.System;
import java.io.PrintStream;
import java.lang.Character;
public class Swap{
<ZDP, ZEA, ZDO, YZP, ZCY, ZDZ> Fun1$$<ZCY, Fun1$$<ZDZ, ZEA>> swap(f){
return x->y->f.apply(y).apply(x);
}
Fun1$$<String, Fun1$$<String, Fun1$$<String, String>>> swap(f){
return x -> y -> z -> f.apply(z).apply(x).apply(y);
}
public static main (y) {
var func = x -> y -> z -> x + y + z;
var res = new Swap().swap(func).apply("A").apply("B").apply("C");
System.out.println(res);}
}

View File

@@ -0,0 +1,6 @@
class TPHMethod {
void m(a, b) {
a = b;
b=a;
}
}

View File

@@ -0,0 +1,16 @@
class Test{
void m( op, a, b ){
op.myapply(a, b);
}
}
class Atype{}
class Btype{}
class Operator1{
void myapply(Atype p1, Atype p2){...}
}
class Operator2{
void myapply(Btype p1, Btype p2){...}
}

View File

@@ -0,0 +1,7 @@
public class Uncurrier{
uncurry (f){
return x -> f.apply(x);}
uncurry (f){
return (x, y) -> f.apply(x).apply(y);
}
}

View File

@@ -0,0 +1,7 @@
import Uncurrier;
class UncurrierMain {
public static main(x) {
var uc = new Uncurrier() ;
}
}

View File

@@ -0,0 +1,16 @@
import java.lang.Integer;
import java.lang.String;
import java.util.Vector;
class VectorAdd {
vectorAdd(v1, v2) {
var i = 0;
var erg = new Vector<>();
while (i < v1.size()) {
erg.addElement(v1.elementAt(i) + v2.elementAt(i));
i++;
}
return erg;
}
}

View File

@@ -0,0 +1,16 @@
import java.util.Vector;
class Apply { }
public class applyLambda {
public m () {
var lam1 = (x) -> {
return x;
};
return lam1.apply(new Apply());
//return lam1;
//return new Vector();
}
}

View File

@@ -0,0 +1,7 @@
//import java.lang.Integer;
class fst {
main(x) {
return x;
}
}

View File

@@ -0,0 +1,8 @@
import java.util.Vector;
class genVector {
m(v) {
return v.elementAt(0);
}
}

View File

@@ -0,0 +1,8 @@
import java.lang.Integer;
import Id;
class Test {
m() {
Integer o1 = new Id<Integer,Integer>().id2.apply(1);
}
}

View File

@@ -0,0 +1,9 @@
public class lambdaId {
lambdaId = x -> x;
/*
id3 (x) {
return lambdaId.apply(x);
}
*/
}

View File

@@ -0,0 +1,9 @@
class mathStruc {
model;
innerOp = (o) -> (ms) -> new mathStruc<>(o.apply(model,ms.model));
mathStruc(m) {
model =m;
}
}

View File

@@ -0,0 +1,18 @@
import java.lang.Integer;
class mathStruc {
model;
innerOp = (o) -> (ms) -> new mathStruc<>(o.apply(model,ms.model));
mathStruc(m) {
model =m;
}
}
class mathStrucIntegerUse {
main() {
var ms = new mathStruc<>(2);
return ms.innerOp.apply((x,y) -> x+y).apply(ms);
}
}

View File

@@ -0,0 +1,90 @@
import java.util.Vector;
import java.lang.Integer;
import java.lang.Boolean;
public class mathStrucMatrixOP {
model;
innerOp = (o) -> (ms) -> new mathStrucMatrixOP<>(o.apply(model,ms.model));
public mathStrucMatrixOP(m) {
model =m;
}
}
public class MatrixOP extends Vector<Vector<Integer>> {
MatrixOP () {
}
MatrixOP(vv) {
Integer i;
i = 0;
while(i < vv.size()) {
// Boolean a = this.add(vv.elementAt(i));
this.add(vv.elementAt(i));
i=i+1;
}
}
public mul = (m1, m2) -> {
var ret = new MatrixOP();
var i = 0;
while(i < m1.size()) {
var v1 = m1.elementAt(i);
var v2 = new Vector<Integer>();
var j = 0;
while(j < v1.size()) {
var erg = 0;
var k = 0;
while(k < v1.size()) {
erg = erg + v1.elementAt(k)
* m2.elementAt(k).elementAt(j);
k++; }
// v2.addElement(new Integer(erg));
v2.addElement(erg);
j++; }
ret.addElement(v2);
i++;
}
return ret;
};
}
class mathStrucUseMatrixOP {
main() {
Vector<Vector<Integer>> vv = new Vector<Vector<Integer>>();
Vector<Integer> v1 = new Vector<Integer>();
v1.addElement(2);
v1.addElement(2);
Vector<Integer> v2 = new Vector<Integer>();
v2.addElement(3);
v2.addElement(3);
vv.addElement(v1);
vv.addElement(v2);
MatrixOP m1 = new MatrixOP(vv);
Vector<Vector<Integer>> vv1 = new Vector<Vector<Integer>>();
Vector<Integer> v3 = new Vector<Integer>();
v3.addElement(2);
v3.addElement(2);
Vector<Integer> v4 = new Vector<Integer>();
v4.addElement(3);
v4.addElement(3);
vv1.addElement(v3);
vv1.addElement(v4);
MatrixOP m2 = new MatrixOP(vv1);
var mms;
mms = new mathStrucMatrixOP<>(m1);
var mms2;
mms2 = new mathStrucMatrixOP<>(m2);
var mms3;
mms3 = mms.innerOp.apply(m1.mul).apply(mms2);
return mms3;
}
}

View File

@@ -0,0 +1,14 @@
import java.lang.String;
import java.lang.Boolean;
import java.lang.Integer;
import java.io.Serializable;
public class testclass{
public testMethod(ele){
if(ele){
return 1;
}
return "";
}
}

View File

@@ -1,3 +0,0 @@
class Bug378Id {
id2 = x -> x;
}

View File

@@ -1,8 +0,0 @@
import Bug378Id;
import java.lang.Integer;
public class Bug378Main {
public static main(args) {
var hallo = (new Bug378Id<Integer>().id2).apply(1);
}
}

View File

@@ -1,24 +0,0 @@
import java.lang.Integer;
import java.lang.Double;
import java.lang.System;
import java.io.PrintStream;
public class Bug379 {
public Fun1$$<Double, Double> fact = (x) -> {
if (x == 1) {
return 1;
} else {
return x * (fact.apply(x-1));
}
};
public getFact(x) {
return fact.apply(x);
}
public static void main(x) {
var f = new Bug379();
var intRes = f.getFact(3);
System.out.println(intRes);
}
}

View File

@@ -1,12 +0,0 @@
sealed interface List<T> permits Cons, Empty {}
record Cons<T>(T a , List<T> l ) implements List <T> {}
record Empty<T>() implements List <T> {}
public class Bug380 {
public <T> List<T> append(l1, List<T> l2) {
return switch ( l1 ) {
case Cons(e, rest) -> new Cons<>(e, append(rest, l2)); //::Typ TPH A
case Empty() -> l2;//::TPH B
};
}
}

View File

@@ -1,13 +0,0 @@
import java.lang.Runnable;
import java.lang.String;
import java.lang.System;
import java.io.PrintStream;
import java.lang.Thread;
public class Bug382 {
public static main(a) {
var f = () -> System.out.println("Hallo Welt!");
new Thread(f).run();
}
}

View File

@@ -1,10 +0,0 @@
import java.lang.String;
import java.lang.System;
import java.io.PrintStream;
public class Bug383 {
public static main(a) {
var f = () -> System.out.println("Hello from Thread!");
f.apply();
}
}

View File

@@ -2,6 +2,7 @@ import java.util.Vector;
import java.lang.Integer;
//import java.lang.Byte;
import java.lang.Boolean;
import java.util.function.BiFunction;
public class MatrixOP extends Vector<Vector<Integer>> {

View File

@@ -1,18 +1,17 @@
import java.lang.Integer;
import java.lang.Double;
import java.lang.Number;
import java.lang.String;
public record R(String n) {}
public record R(Number n) {}
public class SwitchOverload {
f() { return 10; }
g() { return 20; }
public f(){}
public m(r) {
return switch(r) {
case R("test") -> f();
case R("foo") -> g();
case R r -> 0;
};
}
}

View File

@@ -8,7 +8,6 @@ import de.dhbwstuttgart.target.generate.ASTToTargetAST;
import de.dhbwstuttgart.target.tree.*;
import de.dhbwstuttgart.target.tree.expression.*;
import de.dhbwstuttgart.target.tree.type.*;
import de.dhbwstuttgart.util.Logger;
import org.objectweb.asm.*;
import java.lang.invoke.*;
@@ -21,8 +20,6 @@ import static de.dhbwstuttgart.target.tree.expression.TargetBinaryOp.*;
import static de.dhbwstuttgart.target.tree.expression.TargetLiteral.*;
public class Codegen {
public static Logger logger = new Logger("codegen");
private final TargetStructure clazz;
private final ClassWriter cw;
public final String className;
@@ -128,7 +125,7 @@ public class Codegen {
}
private void popValue(State state, TargetType type) {
if (type.equals(TargetType.double_) || type.equals(TargetType.long_))
if (type.equals(TargetType.Double) || type.equals(TargetType.Long))
state.mv.visitInsn(POP2);
else
state.mv.visitInsn(POP);
@@ -137,21 +134,21 @@ public class Codegen {
private void boxPrimitive(State state, TargetType type) {
if (type instanceof TargetExtendsWildcard ew) type = ew.innerType();
var mv = state.mv;
if (type.equals(TargetType.boolean_)) {
if (type.equals(TargetType.Boolean) || type.equals(TargetType.boolean_)) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
} else if (type.equals(TargetType.byte_)) {
} else if (type.equals(TargetType.Byte) || type.equals(TargetType.byte_)) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
} else if (type.equals(TargetType.double_)) {
} else if (type.equals(TargetType.Double) || type.equals(TargetType.double_)) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
} else if (type.equals(TargetType.long_)) {
} else if (type.equals(TargetType.Long) || type.equals(TargetType.long_)) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
} else if (type.equals(TargetType.int_)) {
} else if (type.equals(TargetType.Integer) || type.equals(TargetType.int_)) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
} else if (type.equals(TargetType.float_)) {
} else if (type.equals(TargetType.Float) || type.equals(TargetType.float_)) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
} else if (type.equals(TargetType.short_)) {
} else if (type.equals(TargetType.Short) || type.equals(TargetType.short_)) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
} else if (type.equals(TargetType.char_)) {
} else if (type.equals(TargetType.Char) || type.equals(TargetType.char_)) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false);
}
}
@@ -188,11 +185,9 @@ public class Codegen {
convertTo(state, op.right().type(), type);
mv.visitJumpInsn(code, if_true);
mv.visitInsn(ICONST_0);
boxPrimitive(state, TargetType.toPrimitive(op.type()));
mv.visitJumpInsn(GOTO, end);
mv.visitLabel(if_true);
mv.visitInsn(ICONST_1);
boxPrimitive(state, TargetType.toPrimitive(op.type()));
mv.visitLabel(end);
}
@@ -207,11 +202,9 @@ public class Codegen {
mv.visitInsn(cmp);
mv.visitJumpInsn(code, if_true);
mv.visitInsn(ICONST_0);
boxPrimitive(state, TargetType.toPrimitive(op.type()));
mv.visitJumpInsn(GOTO, end);
mv.visitLabel(if_true);
mv.visitInsn(ICONST_1);
boxPrimitive(state, TargetType.toPrimitive(op.type()));
mv.visitLabel(end);
}
@@ -240,85 +233,65 @@ public class Codegen {
if (source instanceof TargetExtendsWildcard ew) source = ew.innerType();
if (dest instanceof TargetExtendsWildcard ew) dest = ew.innerType();
var mv = state.mv;
if (source.equals(dest))
return;
if (isFunctionalInterface(source) && isFunctionalInterface(dest) &&
if (source.equals(TargetType.Long)) {
if (dest.equals(TargetType.Integer))
mv.visitInsn(L2I);
else if (dest.equals(TargetType.Float))
mv.visitInsn(L2F);
else if (dest.equals(TargetType.Double))
mv.visitInsn(L2D);
else if (dest.equals(TargetType.Byte) || dest.equals(TargetType.Char) || dest.equals(TargetType.Short)) {
mv.visitInsn(L2I);
convertTo(state, TargetType.Integer, dest);
}
} else if (source.equals(TargetType.Float)) {
if (dest.equals(TargetType.Integer))
mv.visitInsn(F2I);
else if (dest.equals(TargetType.Double))
mv.visitInsn(F2D);
else if (dest.equals(TargetType.Long))
mv.visitInsn(F2L);
else if (dest.equals(TargetType.Byte) || dest.equals(TargetType.Char) || dest.equals(TargetType.Short)) {
mv.visitInsn(F2I);
convertTo(state, TargetType.Integer, dest);
}
} else if (source.equals(TargetType.Double)) {
if (dest.equals(TargetType.Integer))
mv.visitInsn(D2I);
else if (dest.equals(TargetType.Float))
mv.visitInsn(D2F);
else if (dest.equals(TargetType.Long))
mv.visitInsn(D2L);
else if (dest.equals(TargetType.Byte) || dest.equals(TargetType.Char) || dest.equals(TargetType.Short)) {
mv.visitInsn(D2I);
convertTo(state, TargetType.Integer, dest);
}
} else if (source.equals(TargetType.Byte) || source.equals(TargetType.Char) || source.equals(TargetType.Short) || source.equals(TargetType.Integer)) {
if (dest.equals(TargetType.Byte))
mv.visitInsn(I2B);
else if (dest.equals(TargetType.Char))
mv.visitInsn(I2C);
else if (dest.equals(TargetType.Short))
mv.visitInsn(I2S);
else if (dest.equals(TargetType.Long))
mv.visitInsn(I2L);
else if (dest.equals(TargetType.Float))
mv.visitInsn(I2F);
else if (dest.equals(TargetType.Double))
mv.visitInsn(I2D);
} else if (source.equals(TargetType.Boolean)) {
unboxPrimitive(state, dest);
} else if (isFunctionalInterface(source) && isFunctionalInterface(dest) &&
!(source instanceof TargetFunNType && dest instanceof TargetFunNType)) {
boxFunctionalInterface(state, source, dest);
return;
}
var mv = state.mv;
if ((source instanceof TargetRefType || source instanceof TargetGenericType) &&
(dest instanceof TargetRefType || dest instanceof TargetGenericType)) {
if (dest instanceof TargetGenericType) return;
} else if (!(dest instanceof TargetGenericType)) {
//boxPrimitive(state, source);
mv.visitTypeInsn(CHECKCAST, dest.getInternalName());
return;
}
if (!(source instanceof TargetPrimitiveType)) {
unboxPrimitive(state, source);
source = TargetType.toPrimitive(source);
}
var origDest = dest;
dest = TargetType.toPrimitive(dest);
if (source.equals(TargetType.long_)) {
if (dest.equals(TargetType.int_))
mv.visitInsn(L2I);
else if (dest.equals(TargetType.float_))
mv.visitInsn(L2F);
else if (dest.equals(TargetType.double_))
mv.visitInsn(L2D);
else if (dest.equals(TargetType.byte_) || dest.equals(TargetType.char_) || dest.equals(TargetType.short_)) {
mv.visitInsn(L2I);
convertTo(state, TargetType.int_, dest);
}
} else if (source.equals(TargetType.float_)) {
if (dest.equals(TargetType.int_))
mv.visitInsn(F2I);
else if (dest.equals(TargetType.double_))
mv.visitInsn(F2D);
else if (dest.equals(TargetType.long_))
mv.visitInsn(F2L);
else if (dest.equals(TargetType.byte_) || dest.equals(TargetType.char_) || dest.equals(TargetType.short_)) {
mv.visitInsn(F2I);
convertTo(state, TargetType.int_, dest);
}
} else if (source.equals(TargetType.double_)) {
if (dest.equals(TargetType.int_))
mv.visitInsn(D2I);
else if (dest.equals(TargetType.float_))
mv.visitInsn(D2F);
else if (dest.equals(TargetType.long_))
mv.visitInsn(D2L);
else if (dest.equals(TargetType.byte_) || dest.equals(TargetType.char_) || dest.equals(TargetType.short_)) {
mv.visitInsn(D2I);
convertTo(state, TargetType.int_, dest);
}
} else if (source.equals(TargetType.byte_) || source.equals(TargetType.char_) || source.equals(TargetType.short_) || source.equals(TargetType.int_)) {
if (dest.equals(TargetType.byte_))
mv.visitInsn(I2B);
else if (dest.equals(TargetType.char_))
mv.visitInsn(I2C);
else if (dest.equals(TargetType.short_))
mv.visitInsn(I2S);
else if (dest.equals(TargetType.long_))
mv.visitInsn(I2L);
else if (dest.equals(TargetType.float_))
mv.visitInsn(I2F);
else if (dest.equals(TargetType.double_))
mv.visitInsn(I2D);
} else if (source.equals(TargetType.boolean_)) {
unboxPrimitive(state, dest);
}
if (!(origDest instanceof TargetPrimitiveType)) {
if (dest instanceof TargetPrimitiveType)
boxPrimitive(state, dest);
else boxPrimitive(state, source);
}
}
record TypePair(TargetType from, TargetType to) {}
@@ -377,9 +350,9 @@ public class Codegen {
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false);
} else {
generate(state, add.left());
convertTo(state, add.left().type(), TargetType.toPrimitive(add.type()));
convertTo(state, add.left().type(), add.type());
generate(state, add.right());
convertTo(state, add.right().type(), TargetType.toPrimitive(add.type()));
convertTo(state, add.right().type(), add.type());
var type = add.type();
if (type.equals(TargetType.Byte) || type.equals(TargetType.Char) || type.equals(TargetType.Integer) || type.equals(TargetType.Short)) {
mv.visitInsn(IADD);
@@ -392,7 +365,6 @@ public class Codegen {
} else {
throw new CodeGenException("Invalid argument to Add expression, type: " + add.type());
}
boxPrimitive(state, TargetType.toPrimitive(op.type()));
}
if (add.type().equals(TargetType.String)) {
generate(state, add.right());
@@ -404,9 +376,9 @@ public class Codegen {
}
case Sub sub: {
generate(state, sub.left());
convertTo(state, sub.left().type(), TargetType.toPrimitive(op.type()));
convertTo(state, sub.left().type(), op.type());
generate(state, sub.right());
convertTo(state, sub.right().type(), TargetType.toPrimitive(op.type()));
convertTo(state, sub.right().type(), op.type());
var type = sub.type();
if (type.equals(TargetType.Byte) || type.equals(TargetType.Char) || type.equals(TargetType.Integer) || type.equals(TargetType.Short)) {
mv.visitInsn(ISUB);
@@ -419,14 +391,13 @@ public class Codegen {
} else {
throw new CodeGenException("Invalid argument to Sub expression");
}
boxPrimitive(state, TargetType.toPrimitive(op.type()));
break;
}
case Div div: {
generate(state, div.left());
convertTo(state, div.left().type(), TargetType.toPrimitive(op.type()));
convertTo(state, div.left().type(), op.type());
generate(state, div.right());
convertTo(state, div.right().type(), TargetType.toPrimitive(op.type()));
convertTo(state, div.right().type(), op.type());
var type = div.type();
if (type.equals(TargetType.Byte) || type.equals(TargetType.Char) || type.equals(TargetType.Integer) || type.equals(TargetType.Short)) {
mv.visitInsn(IDIV);
@@ -439,14 +410,13 @@ public class Codegen {
} else {
throw new CodeGenException("Invalid argument to Div expression");
}
boxPrimitive(state, TargetType.toPrimitive(op.type()));
break;
}
case Mul mul: {
generate(state, mul.left());
convertTo(state, mul.left().type(), TargetType.toPrimitive(op.type()));
convertTo(state, mul.left().type(), op.type());
generate(state, mul.right());
convertTo(state, mul.right().type(), TargetType.toPrimitive(op.type()));
convertTo(state, mul.right().type(), op.type());
var type = mul.type();
if (type.equals(TargetType.Byte) || type.equals(TargetType.Char) || type.equals(TargetType.Integer) || type.equals(TargetType.Short)) {
mv.visitInsn(IMUL);
@@ -459,14 +429,13 @@ public class Codegen {
} else {
throw new CodeGenException("Invalid argument to Mul expression");
}
boxPrimitive(state, TargetType.toPrimitive(op.type()));
break;
}
case Rem rem: {
generate(state, rem.left());
convertTo(state, rem.left().type(), TargetType.toPrimitive(op.type()));
convertTo(state, rem.left().type(), op.type());
generate(state, rem.right());
convertTo(state, rem.right().type(), TargetType.toPrimitive(op.type()));
convertTo(state, rem.right().type(), op.type());
var type = rem.type();
if (type.equals(TargetType.Byte) || type.equals(TargetType.Char) || type.equals(TargetType.Integer) || type.equals(TargetType.Short)) {
mv.visitInsn(IREM);
@@ -479,7 +448,6 @@ public class Codegen {
} else {
throw new CodeGenException("Invalid argument to Rem expression");
}
boxPrimitive(state, TargetType.toPrimitive(op.type()));
break;
}
case Or or: {
@@ -487,18 +455,14 @@ public class Codegen {
Label or_true = new Label();
Label end = new Label();
generate(state, or.left());
convertTo(state, or.left().type(), TargetType.toPrimitive(op.type()));
mv.visitJumpInsn(IFNE, or_true);
generate(state, or.right());
convertTo(state, or.right().type(), TargetType.toPrimitive(op.type()));
mv.visitJumpInsn(IFEQ, or_false);
mv.visitLabel(or_true);
mv.visitInsn(ICONST_1);
boxPrimitive(state, TargetType.toPrimitive(op.type()));
mv.visitJumpInsn(GOTO, end);
mv.visitLabel(or_false);
mv.visitInsn(ICONST_0);
boxPrimitive(state, TargetType.toPrimitive(op.type()));
mv.visitLabel(end);
break;
}
@@ -506,54 +470,47 @@ public class Codegen {
Label and_false = new Label();
Label end = new Label();
generate(state, and.left());
convertTo(state, and.left().type(), TargetType.toPrimitive(op.type()));
mv.visitJumpInsn(IFEQ, and_false);
generate(state, and.right());
convertTo(state, and.right().type(), TargetType.toPrimitive(op.type()));
mv.visitJumpInsn(IFEQ, and_false);
mv.visitInsn(ICONST_1);
boxPrimitive(state, TargetType.toPrimitive(op.type()));
mv.visitJumpInsn(GOTO, end);
mv.visitLabel(and_false);
mv.visitInsn(ICONST_0);
boxPrimitive(state, TargetType.toPrimitive(op.type()));
mv.visitLabel(end);
break;
}
case BAnd band: {
generate(state, band.left());
convertTo(state, band.left().type(), TargetType.toPrimitive(op.type()));
convertTo(state, band.left().type(), op.type());
generate(state, band.right());
convertTo(state, band.right().type(), TargetType.toPrimitive(op.type()));
convertTo(state, band.right().type(), op.type());
if (band.type().equals(TargetType.Long))
mv.visitInsn(LAND);
else
mv.visitInsn(IAND);
boxPrimitive(state, TargetType.toPrimitive(op.type()));
break;
}
case BOr bor: {
generate(state, bor.left());
convertTo(state, bor.left().type(), TargetType.toPrimitive(op.type()));
convertTo(state, bor.left().type(), op.type());
generate(state, bor.right());
convertTo(state, bor.right().type(), TargetType.toPrimitive(op.type()));
convertTo(state, bor.right().type(), op.type());
if (bor.type().equals(TargetType.Long))
mv.visitInsn(LOR);
else
mv.visitInsn(IOR);
boxPrimitive(state, TargetType.toPrimitive(op.type()));
break;
}
case XOr xor: {
generate(state, xor.left());
convertTo(state, xor.left().type(), TargetType.toPrimitive(op.type()));
convertTo(state, xor.left().type(), op.type());
generate(state, xor.right());
convertTo(state, xor.right().type(), TargetType.toPrimitive(op.type()));
convertTo(state, xor.right().type(), op.type());
if (xor.type().equals(TargetType.Long))
mv.visitInsn(LXOR);
else
mv.visitInsn(IXOR);
boxPrimitive(state, TargetType.toPrimitive(op.type()));
break;
}
case Instof instof: {
@@ -562,47 +519,44 @@ public class Codegen {
}
case Shl shl: {
generate(state, shl.left());
convertTo(state, shl.left().type(), TargetType.toPrimitive(op.type()));
convertTo(state, shl.left().type(), op.type());
generate(state, shl.right());
convertTo(state, shl.right().type(), TargetType.toPrimitive(op.type()));
convertTo(state, shl.right().type(), op.type());
if (shl.type().equals(TargetType.Long))
mv.visitInsn(LSHL);
else
mv.visitInsn(ISHL);
boxPrimitive(state, TargetType.toPrimitive(op.type()));
break;
}
case Shr shr: {
generate(state, shr.left());
convertTo(state, shr.left().type(), TargetType.toPrimitive(op.type()));
convertTo(state, shr.left().type(), op.type());
generate(state, shr.right());
convertTo(state, shr.right().type(), TargetType.toPrimitive(op.type()));
convertTo(state, shr.right().type(), op.type());
if (shr.type().equals(TargetType.Long))
mv.visitInsn(LSHR);
else
mv.visitInsn(ISHR);
boxPrimitive(state, TargetType.toPrimitive(op.type()));
break;
}
case UShr ushr: {
generate(state, ushr.left());
convertTo(state, ushr.left().type(), TargetType.toPrimitive(op.type()));
convertTo(state, ushr.left().type(), op.type());
generate(state, ushr.right());
convertTo(state, ushr.right().type(), TargetType.toPrimitive(op.type()));
convertTo(state, ushr.right().type(), op.type());
if (ushr.type().equals(TargetType.Long))
mv.visitInsn(LUSHR);
else
mv.visitInsn(IUSHR);
boxPrimitive(state, TargetType.toPrimitive(op.type()));
break;
}
case Greater greater: {
var type = TargetType.toPrimitive(largerType(greater.left().type(), greater.right().type()));
if (type.equals(TargetType.long_)) {
var type = largerType(greater.left().type(), greater.right().type());
if (type.equals(TargetType.Long)) {
generateRelationalOperator(state, greater, type, LCMP, IFGT);
} else if (type.equals(TargetType.float_)) {
} else if (type.equals(TargetType.Float)) {
generateRelationalOperator(state, greater, type, FCMPL, IFGT);
} else if (type.equals(TargetType.double_)) {
} else if (type.equals(TargetType.Double)) {
generateRelationalOperator(state, greater, type, DCMPL, IFGT);
} else {
generateRelationalOperator(state, greater, type, IF_ICMPGT);
@@ -610,12 +564,12 @@ public class Codegen {
break;
}
case Less less: {
var type = TargetType.toPrimitive(largerType(less.left().type(), less.right().type()));
if (type.equals(TargetType.long_)) {
var type = largerType(less.left().type(), less.right().type());
if (type.equals(TargetType.Long)) {
generateRelationalOperator(state, less, type, LCMP, IFLT);
} else if (type.equals(TargetType.float_)) {
} else if (type.equals(TargetType.Float)) {
generateRelationalOperator(state, less, type, FCMPL, IFLT);
} else if (type.equals(TargetType.double_)) {
} else if (type.equals(TargetType.Double)) {
generateRelationalOperator(state, less, type, DCMPL, IFLT);
} else {
generateRelationalOperator(state, less, type, IF_ICMPLT);
@@ -623,12 +577,12 @@ public class Codegen {
break;
}
case GreaterOrEqual greaterOrEqual: {
var type = TargetType.toPrimitive(largerType(greaterOrEqual.left().type(), greaterOrEqual.right().type()));
if (type.equals(TargetType.long_)) {
var type = largerType(greaterOrEqual.left().type(), greaterOrEqual.right().type());
if (type.equals(TargetType.Long)) {
generateRelationalOperator(state, greaterOrEqual, type, LCMP, IFGE);
} else if (type.equals(TargetType.float_)) {
} else if (type.equals(TargetType.Float)) {
generateRelationalOperator(state, greaterOrEqual, type, FCMPL, IFGE);
} else if (type.equals(TargetType.double_)) {
} else if (type.equals(TargetType.Double)) {
generateRelationalOperator(state, greaterOrEqual, type, DCMPL, IFGE);
} else {
generateRelationalOperator(state, greaterOrEqual, type, IF_ICMPGE);
@@ -636,12 +590,12 @@ public class Codegen {
break;
}
case LessOrEqual lessOrEqual: {
var type = TargetType.toPrimitive(largerType(lessOrEqual.left().type(), lessOrEqual.right().type()));
if (type.equals(TargetType.long_)) {
var type = largerType(lessOrEqual.left().type(), lessOrEqual.right().type());
if (type.equals(TargetType.Long)) {
generateRelationalOperator(state, lessOrEqual, type, LCMP, IFLE);
} else if (type.equals(TargetType.float_)) {
} else if (type.equals(TargetType.Float)) {
generateRelationalOperator(state, lessOrEqual, type, FCMPL, IFLE);
} else if (type.equals(TargetType.double_)) {
} else if (type.equals(TargetType.Double)) {
generateRelationalOperator(state, lessOrEqual, type, DCMPL, IFLE);
} else {
generateRelationalOperator(state, lessOrEqual, type, IF_ICMPLE);
@@ -649,30 +603,30 @@ public class Codegen {
break;
}
case Equal equal: {
var type = TargetType.toPrimitive(largerType(equal.left().type(), equal.right().type()));
if (type.equals(TargetType.long_)) {
generateRelationalOperator(state, equal, TargetType.long_, LCMP, IFEQ);
} else if (type.equals(TargetType.float_)) {
generateRelationalOperator(state, equal, TargetType.float_, FCMPL, IFEQ);
} else if (type.equals(TargetType.double_)) {
generateRelationalOperator(state, equal, TargetType.double_, DCMPL, IFEQ);
} else if (type.equals(TargetType.char_) || type.equals(TargetType.short_) || type.equals(TargetType.byte_) || type.equals(TargetType.int_) || type.equals(TargetType.boolean_)) {
generateRelationalOperator(state, equal, TargetType.int_, IF_ICMPEQ);
var type = largerType(equal.left().type(), equal.right().type());
if (type.equals(TargetType.Long)) {
generateRelationalOperator(state, equal, type, LCMP, IFEQ);
} else if (type.equals(TargetType.Float)) {
generateRelationalOperator(state, equal, type, FCMPL, IFEQ);
} else if (type.equals(TargetType.Double)) {
generateRelationalOperator(state, equal, type, DCMPL, IFEQ);
} else if (type.equals(TargetType.Char) || type.equals(TargetType.Short) || type.equals(TargetType.Byte) || type.equals(TargetType.Integer) || type.equals(TargetType.Boolean)) {
generateRelationalOperator(state, equal, type, IF_ICMPEQ);
} else {
generateRelationalOperator(state, equal, type, IF_ACMPEQ);
}
break;
}
case NotEqual notEqual: {
var type = TargetType.toPrimitive(largerType(notEqual.left().type(), notEqual.right().type()));
if (type.equals(TargetType.long_)) {
generateRelationalOperator(state, notEqual, TargetType.long_, LCMP, IFNE);
} else if (type.equals(TargetType.float_)) {
generateRelationalOperator(state, notEqual, TargetType.float_, FCMPL, IFNE);
} else if (type.equals(TargetType.double_)) {
generateRelationalOperator(state, notEqual, TargetType.double_, DCMPL, IFNE);
} else if (type.equals(TargetType.char_) || type.equals(TargetType.short_) || type.equals(TargetType.byte_) || type.equals(TargetType.int_) || type.equals(TargetType.boolean_)) {
generateRelationalOperator(state, notEqual, TargetType.int_, IF_ICMPNE);
var type = largerType(notEqual.left().type(), notEqual.right().type());
if (type.equals(TargetType.Long)) {
generateRelationalOperator(state, notEqual, type, LCMP, IFNE);
} else if (type.equals(TargetType.Float)) {
generateRelationalOperator(state, notEqual, type, FCMPL, IFNE);
} else if (type.equals(TargetType.Double)) {
generateRelationalOperator(state, notEqual, type, DCMPL, IFNE);
} else if (type.equals(TargetType.Char) || type.equals(TargetType.Short) || type.equals(TargetType.Byte) || type.equals(TargetType.Integer)) {
generateRelationalOperator(state, notEqual, type, IF_ICMPNE);
} else {
generateRelationalOperator(state, notEqual, type, IF_ACMPNE);
}
@@ -703,7 +657,6 @@ public class Codegen {
generate(state, add.expr());
case TargetUnaryOp.Negate negate -> {
generate(state, negate.expr());
convertTo(state, negate.expr().type(), TargetType.boolean_);
if (negate.type().equals(TargetType.Double))
mv.visitInsn(DNEG);
else if (negate.type().equals(TargetType.Float))
@@ -712,11 +665,9 @@ public class Codegen {
mv.visitInsn(LNEG);
else
mv.visitInsn(INEG);
boxPrimitive(state, TargetType.toPrimitive(negate.expr().type()));
}
case TargetUnaryOp.Not not -> {
generate(state, not.expr());
convertTo(state, not.expr().type(), TargetType.boolean_);
if (not.type().equals(TargetType.Long)) {
mv.visitLdcInsn(-1L);
mv.visitInsn(LXOR);
@@ -724,86 +675,93 @@ public class Codegen {
mv.visitInsn(ICONST_M1);
mv.visitInsn(IXOR);
}
boxPrimitive(state, TargetType.toPrimitive(not.expr().type()));
}
case TargetUnaryOp.PreIncrement preIncrement -> {
generate(state, preIncrement.expr());
convertTo(state, preIncrement.expr().type(), TargetType.toPrimitive(op.type()));
if (preIncrement.type().equals(TargetType.Float)) {
mv.visitLdcInsn(1F);
mv.visitInsn(FADD);
mv.visitInsn(DUP);
} else if (preIncrement.type().equals(TargetType.Double)) {
mv.visitLdcInsn(1D);
mv.visitInsn(DADD);
mv.visitInsn(DUP2);
} else if (preIncrement.type().equals(TargetType.Long)) {
mv.visitLdcInsn(1L);
mv.visitInsn(LADD);
mv.visitInsn(DUP2);
} else {
mv.visitLdcInsn(1);
mv.visitInsn(IADD);
mv.visitInsn(DUP);
}
boxPrimitive(state, TargetType.toPrimitive(op.type()));
mv.visitInsn(DUP);
boxPrimitive(state, preIncrement.type());
afterIncDec(state, preIncrement);
}
case TargetUnaryOp.PreDecrement preDecrement -> {
generate(state, preDecrement.expr());
convertTo(state, preDecrement.expr().type(), TargetType.toPrimitive(op.type()));
if (preDecrement.type().equals(TargetType.Float)) {
mv.visitLdcInsn(1F);
mv.visitInsn(FSUB);
mv.visitInsn(DUP);
} else if (preDecrement.type().equals(TargetType.Double)) {
mv.visitLdcInsn(1D);
mv.visitInsn(DSUB);
mv.visitInsn(DUP2);
} else if (preDecrement.type().equals(TargetType.Long)) {
mv.visitLdcInsn(1L);
mv.visitInsn(LSUB);
mv.visitInsn(DUP2);
} else {
mv.visitLdcInsn(1);
mv.visitInsn(ISUB);
mv.visitInsn(DUP);
}
boxPrimitive(state, TargetType.toPrimitive(op.type()));
mv.visitInsn(DUP);
boxPrimitive(state, preDecrement.type());
afterIncDec(state, preDecrement);
}
case TargetUnaryOp.PostIncrement postIncrement -> {
generate(state, postIncrement.expr());
mv.visitInsn(DUP);
convertTo(state, postIncrement.expr().type(), TargetType.toPrimitive(op.type()));
if (postIncrement.type().equals(TargetType.Float)) {
mv.visitInsn(DUP);
mv.visitLdcInsn(1F);
mv.visitInsn(FADD);
} else if (postIncrement.type().equals(TargetType.Double)) {
mv.visitInsn(DUP2);
mv.visitLdcInsn(1D);
mv.visitInsn(DADD);
} else if (postIncrement.type().equals(TargetType.Long)) {
mv.visitInsn(DUP2);
mv.visitLdcInsn(1L);
mv.visitInsn(LADD);
} else {
mv.visitInsn(DUP);
mv.visitLdcInsn(1);
mv.visitInsn(IADD);
}
boxPrimitive(state, TargetType.toPrimitive(op.type()));
boxPrimitive(state, postIncrement.type());
afterIncDec(state, postIncrement);
}
case TargetUnaryOp.PostDecrement postDecrement -> {
generate(state, postDecrement.expr());
mv.visitInsn(DUP);
convertTo(state, postDecrement.expr().type(), TargetType.toPrimitive(op.type()));
if (postDecrement.type().equals(TargetType.Float)) {
mv.visitInsn(DUP);
mv.visitLdcInsn(1F);
mv.visitInsn(FSUB);
} else if (postDecrement.type().equals(TargetType.Double)) {
mv.visitInsn(DUP2);
mv.visitLdcInsn(1D);
mv.visitInsn(DSUB);
} else if (postDecrement.type().equals(TargetType.Long)) {
mv.visitInsn(DUP2);
mv.visitLdcInsn(1L);
mv.visitInsn(LSUB);
} else {
mv.visitInsn(DUP);
mv.visitLdcInsn(1);
mv.visitInsn(ISUB);
}
boxPrimitive(state, TargetType.toPrimitive(op.type()));
boxPrimitive(state, postDecrement.type());
afterIncDec(state, postDecrement);
}
}
@@ -951,7 +909,7 @@ public class Codegen {
var local = state.createVariable(varDecl.name(), varDecl.varType());
if (varDecl.value() != null) {
generate(state, varDecl.value());
boxPrimitive(state, varDecl.value().type());
boxPrimitive(state, varDecl.varType());
mv.visitVarInsn(ASTORE, local.index());
} else {
mv.visitInsn(ACONST_NULL);
@@ -1000,14 +958,14 @@ public class Codegen {
mv.visitVarInsn(ALOAD, local.index());
// This is a bit weird but sometimes the types don't match (see lambda expressions)
convertTo(state, local.type(), localVar.type());
//unboxPrimitive(state, local.type());
unboxPrimitive(state, local.type());
break;
}
case TargetFieldVar dot: {
if (!dot.isStatic())
generate(state, dot.left());
mv.visitFieldInsn(dot.isStatic() ? GETSTATIC : GETFIELD, dot.left().type().getInternalName(), dot.right(), dot.type().toDescriptor());
//unboxPrimitive(state, dot.type());
unboxPrimitive(state, dot.type());
break;
}
case TargetFor _for: {
@@ -1023,14 +981,11 @@ public class Codegen {
Label start = new Label();
Label end = new Label();
mv.visitLabel(start);
if (_for.termination() != null) {
if (_for.termination() != null)
generate(state, _for.termination());
convertTo(state, _for.termination().type(), TargetType.boolean_);
mv.visitJumpInsn(IFEQ, end);
} else {
else
mv.visitInsn(ICONST_1);
mv.visitJumpInsn(IFEQ, end);
}
mv.visitJumpInsn(IFEQ, end);
var env = new BreakEnv();
env.startLabel = start;
@@ -1062,7 +1017,6 @@ public class Codegen {
Label end = new Label();
mv.visitLabel(start);
generate(state, _while.cond());
convertTo(state, _while.cond().type(), TargetType.boolean_);
mv.visitJumpInsn(IFEQ, end);
var env = new BreakEnv();
@@ -1093,7 +1047,6 @@ public class Codegen {
mv.visitLabel(check);
generate(state, _do.cond());
convertTo(state, _do.cond().type(), TargetType.boolean_);
mv.visitJumpInsn(IFEQ, end);
mv.visitJumpInsn(GOTO, start);
mv.visitLabel(end);
@@ -1101,7 +1054,6 @@ public class Codegen {
}
case TargetIf _if: {
generate(state, _if.cond());
convertTo(state, _if.cond().type(), TargetType.boolean_);
Label _else = new Label();
Label end = new Label();
mv.visitJumpInsn(IFEQ, _else);
@@ -1115,23 +1067,20 @@ public class Codegen {
break;
}
case TargetReturn ret: {
if (ret.expression() != null) {
if (ret.expression() != null && state.returnType != null) {
if (state.returnType instanceof TargetPrimitiveType) {
generate(state, ret.expression());
// Lambdas wrap the expression in a return if they are a single expression
// It means we have to execute the code anyway but not return anything
if (state.returnType != null) {
convertTo(state, ret.expression().type(), state.returnType);
mv.visitInsn(findReturnCode(state.returnType));
}
unboxPrimitive(state, state.returnType);
mv.visitInsn(findReturnCode(state.returnType));
} else {
generate(state, ret.expression());
if (state.returnType != null) {
convertTo(state, ret.expression().type(), state.returnType);
mv.visitInsn(ARETURN);
}
boxPrimitive(state, ret.expression().type());
convertTo(state, ret.expression().type(), state.returnType);
mv.visitInsn(ARETURN);
}
} else mv.visitInsn(RETURN);
} else
mv.visitInsn(RETURN);
break;
}
case TargetYield yield: {
@@ -1178,14 +1127,12 @@ public class Codegen {
var arg = call.parameterTypes().get(i);
generate(state, e);
convertTo(state, e.type(), arg);
if (!(arg instanceof TargetPrimitiveType))
boxPrimitive(state, e.type());
}
var descriptor = call.getDescriptor();
if (call.owner() instanceof TargetFunNType owner) {
// Decay FunN
descriptor = TargetMethod.getDescriptor(
(owner.returnArguments() == 0 ? null : TargetType.Object),
call.parameterTypes().stream().map(x -> TargetType.Object).toArray(TargetType[]::new));
}
if (call.owner() instanceof TargetFunNType) // Decay FunN
descriptor = TargetMethod.getDescriptor(call.returnType() == null ? null : TargetType.Object, call.parameterTypes().stream().map(x -> TargetType.Object).toArray(TargetType[]::new));
int insn = INVOKEVIRTUAL;
if (call.isStatic()) insn = INVOKESTATIC;
@@ -1194,13 +1141,11 @@ public class Codegen {
mv.visitMethodInsn(insn, call.owner().getInternalName(), call.name(), descriptor, call.isInterface());
/*if (call.type() != null && call.returnType() != null && !(call.returnType() instanceof TargetPrimitiveType)) {
if (call.type() != null && call.returnType() != null && !(call.returnType() instanceof TargetPrimitiveType)) {
if (!call.returnType().equals(call.type()) && !(call.type() instanceof TargetGenericType))
mv.visitTypeInsn(CHECKCAST, call.type().getInternalName());
unboxPrimitive(state, call.type());
}*/
if (call.type() != null)
convertTo(state, call.returnType(), call.type());
}
break;
}
case TargetLambdaExpression lambda:
@@ -1209,10 +1154,9 @@ public class Codegen {
case TargetNew _new: {
mv.visitTypeInsn(NEW, _new.type().getInternalName());
mv.visitInsn(DUP);
for (var i = 0; i < _new.params().size(); i++) {
var e = _new.params().get(i);
for (TargetExpression e : _new.params()) {
generate(state, e);
convertTo(state, e.type(), _new.signature().get(i));
boxPrimitive(state, e.type());
}
mv.visitMethodInsn(INVOKESPECIAL, _new.type().getInternalName(), "<init>", _new.getDescriptor(), false);
break;
@@ -1224,7 +1168,6 @@ public class Codegen {
}
case TargetTernary ternary: {
generate(state, ternary.cond());
convertTo(state, ternary.cond().type(), TargetType.boolean_);
var iffalse = new Label();
var end = new Label();
mv.visitJumpInsn(IFEQ, iffalse);
@@ -1278,7 +1221,6 @@ public class Codegen {
if (instanceOf.right() instanceof TargetTypePattern right && right.name() == null) {
generate(state, instanceOf.left());
mv.visitTypeInsn(INSTANCEOF, right.type().getInternalName());
boxPrimitive(state, TargetType.boolean_);
return;
}
@@ -1286,7 +1228,6 @@ public class Codegen {
}
private void yieldValue(State state, TargetType type) {
if (type == null) return;
boxPrimitive(state, type);
state.mv.visitVarInsn(ASTORE, state.switchResultValue.peek());
}
@@ -1302,7 +1243,6 @@ public class Codegen {
state.pushSwitch();
generate(state, aSwitch.expr());
unboxPrimitive(state, aSwitch.expr().type());
state.enterScope();
@@ -1399,7 +1339,7 @@ public class Codegen {
types.add(Type.getObjectType(guard.inner().type().getInternalName()));
// TODO Same here we need to evaluate constant;
} else {
logger.info(label);
System.out.println(label);
throw new NotImplementedException();
}
}
@@ -1438,7 +1378,6 @@ public class Codegen {
if (label instanceof TargetGuard gd) {
generate(state, gd.expression());
unboxPrimitive(state, TargetType.Boolean);
var next = new Label();
mv.visitJumpInsn(IFNE, next);
mv.visitVarInsn(ALOAD, tmp);
@@ -1476,7 +1415,7 @@ public class Codegen {
if (aSwitch.isExpression()) {
if (aSwitch.type() != null) {
mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
//unboxPrimitive(state, aSwitch.type());
unboxPrimitive(state, aSwitch.type());
}
state.popSwitch();
}
@@ -1493,8 +1432,8 @@ public class Codegen {
}
private void bindPattern(State state, TargetType type, TargetPattern pat, Label start, int index, int depth) {
//if (pat.type() instanceof TargetPrimitiveType)
// boxPrimitive(state, pat.type());
if (pat.type() instanceof TargetPrimitiveType)
boxPrimitive(state, pat.type());
if (pat.type() instanceof TargetRefType) {
state.mv.visitInsn(DUP);
@@ -1515,14 +1454,11 @@ public class Codegen {
}
if (pat instanceof TargetExpressionPattern ep) {
var cur = state.createVariable(TargetType.toWrapper(pat.type()));
var cur = state.createVariable(pat.type());
state.mv.visitVarInsn(ASTORE, cur.index);
// For Strings we must use equals, and why not make it work for all types?
generate(state, new TargetLocalVar(cur.type, cur.name));
generate(state, ep.expression());
boxPrimitive(state, ep.expression().type());
state.mv.visitMethodInsn(INVOKESTATIC, "java/util/Objects", "equals", "(Ljava/lang/Object;Ljava/lang/Object;)Z", false);
var expr = new Equal(pat.type(), new TargetLocalVar(cur.type, cur.name), ep.expression());
generate(state, expr);
var cont = new Label();
state.mv.visitJumpInsn(IFNE, cont);
@@ -1720,7 +1656,7 @@ public class Codegen {
generate(state, method.block());
if (method.signature().returnType() == null)
mv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
mv.visitMaxs(0, 0);
}
mv.visitEnd();
}
@@ -1736,8 +1672,6 @@ public class Codegen {
}
if (clazz.superType() != null)
ret += clazz.superType().toSignature();
else ret += "Ljava/lang/Object;";
for (var intf : clazz.implementingInterfaces()) {
ret += intf.toSignature();
}
@@ -1840,12 +1774,8 @@ public class Codegen {
} else convertTo(state, fromReturn, toReturn);
}
if (toReturn != null) {
if ((fromReturn instanceof TargetRefType || fromReturn instanceof TargetGenericType)
&& (toReturn instanceof TargetPrimitiveType))
unboxPrimitive(state, TargetType.toWrapper(toReturn));
if (toReturn != null)
mv.visitInsn(findReturnCode(toReturn));
}
else mv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
@@ -1854,13 +1784,19 @@ public class Codegen {
cw2.visitEnd();
var bytes = cw2.toByteArray();
compiler.auxiliaries.put(className, bytes);
// TODO These class loading shenanigans happen in a few places, the tests load the classes individually.
// Instead we should just look at the folder.
try {
converter.classLoader.findClass(className);
} catch (ClassNotFoundException e) {
try {
converter.classLoader.loadClass(className, bytes);
} catch (LinkageError ignored) {}
}
}
cw.visitEnd();
//ClassReader cr = new ClassReader(cw.toByteArray());
//System.out.println("Checking class " + className);
// TODO This fails for multi class projects because it tries to load the other classes
//CheckClassAdapter.verify(cr, false, new PrintWriter(System.err));
return cw.toByteArray();
}

View File

@@ -75,7 +75,7 @@ public class FunNGenerator {
if (type == null) return VOID;
var res = "L" + type.getInternalName();
if (type instanceof TargetSpecializedType a) {
if (!a.params().isEmpty() && !(a.params().size() == 1 && a.params().getFirst() == null)) {
if (a.params().size() > 0) {
res += "<";
for (var param : a.params()) {
if (param instanceof TargetGenericType gp) {
@@ -115,17 +115,16 @@ public class FunNGenerator {
superFunNMethodSignature.append(String.format("T%s;", argumentGenericBase + currentParameter));
superFunNMethodDescriptor.append(objectSignature);
}
superFunNClassSignature.append(String.format("%s:%s>%s", returnGeneric, objectSignature, objectSignature));
if (numReturnTypes > 0) {
superFunNClassSignature.append(String.format("%s:%s>%s", returnGeneric, objectSignature, objectSignature));
superFunNMethodSignature.append(String.format(")T%s;", returnGeneric));
superFunNMethodDescriptor.append(String.format(")%s", objectSignature));
} else {
superFunNClassSignature = new StringBuilder(objectSignature);
superFunNMethodSignature.append(")V");
superFunNMethodDescriptor.append(")V");
}
Codegen.logger.info(superFunNMethodSignature);
System.out.println(superFunNMethodSignature);
ClassWriter classWriter = new ClassWriter(0);
MethodVisitor methodVisitor;

View File

@@ -1,83 +1,46 @@
package de.dhbwstuttgart.core;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterException;
import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.util.Logger;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.*;
class Args {
@Parameter(description = "Set destination directory", names = "-d")
File outputPath;
@Parameter(description = "Set class path", names = {"-cp", "-classpath"})
String classpath;
@Parameter(description = "[FILE]...")
List<File> input;
@Parameter(description = "Server mode", names = "--server-port")
Integer serverPort;
@Parameter(description = "Unify server url", names = "--unify-server")
String serverUrl;
@Parameter(description = "Write logs", names = "--write-logs")
boolean writeLogs = false;
@Parameter(names = "-v", description = "Verbosity level")
int verbosity = 0;
@Parameter(names = "--infer-together", description = "Runs the type inference on all input files together instead of sequentially")
boolean inferTogether = false;
@Parameter(names = "--help", help = true)
boolean help;
}
public class ConsoleInterface {
public static Logger.LogLevel logLevel = Logger.LogLevel.ERROR;
public static boolean writeLogFiles = false;
public static boolean inferTogether = false;
public static Optional<String> unifyServerUrl = Optional.empty();
private static final String directory = System.getProperty("user.dir");
public static void main(String[] argv) throws IOException, ClassNotFoundException {
var args = new Args();
var builder = JCommander.newBuilder().addObject(args).build();
builder.setProgramName("javatx");
try {
builder.parse(argv);
if (args.help) {
builder.usage();
return;
}
} catch (ParameterException e) {
System.err.println(e.getMessage());
System.err.println();
builder.usage();
public static void main(String[] args) throws IOException, ClassNotFoundException {
List<File> input = new ArrayList<>();
List<File> classpath = new ArrayList<>();
String outputPath = null;
Iterator<String> it = Arrays.asList(args).iterator();
if(args.length == 0){
System.out.println("No input files given. Get help with --help");
System.exit(1);
}else if(args.length == 1 && args[0].equals("--help")){
System.out.println("Usage: javatx [OPTION]... [FILE]...\n" +
"\t-cp\tSet Classpath\n" +
"\t-d\tSet destination directory");
System.exit(1);
}
inferTogether = args.inferTogether;
unifyServerUrl = Optional.ofNullable(args.serverUrl);
writeLogFiles = args.writeLogs;
switch (args.verbosity) {
case 1 -> logLevel = Logger.LogLevel.WARNING;
case 2 -> logLevel = Logger.LogLevel.INFO;
case 3 -> logLevel = Logger.LogLevel.DEBUG;
default -> logLevel = Logger.LogLevel.ERROR;
}
if (args.serverPort != null) {
if (unifyServerUrl.isPresent()) throw new RuntimeException("Cannot use unifyServer when in server mode!");
JavaTXServer server = new JavaTXServer(args.serverPort);
server.listen();
} else {
if (args.input == null) {
System.err.println("No input files given. Get help with --help");
System.exit(1);
while(it.hasNext()){
String arg = it.next();
if(arg.equals("-d")){
outputPath = it.next();
}else if(arg.startsWith("-d")) {
outputPath = arg.substring(2);
}else if(arg.equals("-cp") || arg.equals("-classpath")){
String[] cps = it.next().split(":");
for(String cp : cps){
classpath.add(new File(cp));
}
}else{
input.add(new File(arg));
}
List<File> classpath = args.classpath == null ? List.of() : Arrays.stream(args.classpath.split(File.pathSeparator)).map(File::new).toList();
JavaTXCompiler compiler = new JavaTXCompiler(args.input, classpath, args.outputPath);
compiler.generateBytecode();
SocketClient.closeIfOpen();
}
JavaTXCompiler compiler = new JavaTXCompiler(input, classpath, outputPath != null ? new File(outputPath) : null);
//compiler.typeInference();
compiler.generateBytecode();
}
}

View File

@@ -6,7 +6,6 @@ import de.dhbwstuttgart.bytecode.FunNGenerator;
import de.dhbwstuttgart.environment.CompilationEnvironment;
import de.dhbwstuttgart.environment.DirectoryClassLoader;
import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.languageServerInterface.model.LanguageServerTransferObject;
import de.dhbwstuttgart.parser.JavaTXParser;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
@@ -14,11 +13,6 @@ 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.server.SocketClient;
import de.dhbwstuttgart.server.SocketFuture;
import de.dhbwstuttgart.server.packet.SetAutoclosePacket;
import de.dhbwstuttgart.server.packet.UnifyRequestPacket;
import de.dhbwstuttgart.server.packet.UnifyResultPacket;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method;
@@ -42,13 +36,10 @@ import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.typeAlgo.TYPE;
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
import de.dhbwstuttgart.typeinference.unify.RuleSet;
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import de.dhbwstuttgart.typeinference.unify.distributeVariance;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
@@ -59,11 +50,9 @@ import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl;
import de.dhbwstuttgart.typeinference.unify.UnifyResultModel;
import de.dhbwstuttgart.typeinference.unify.UnifyTaskModel;
import de.dhbwstuttgart.util.Logger;
import java.io.*;
import java.lang.reflect.Modifier;
import java.nio.file.Path;
import java.sql.Array;
import java.util.*;
import java.util.Map.Entry;
import java.util.function.Function;
@@ -73,18 +62,14 @@ import org.apache.commons.io.output.NullOutputStream;
public class JavaTXCompiler {
// do not use this in any code, that can be executed serverside!
public static PlaceholderRegistry defaultClientPlaceholderRegistry = new PlaceholderRegistry();
public static Logger defaultLogger = new Logger();
// public static JavaTXCompiler INSTANCE;
final CompilationEnvironment environment;
Boolean resultmodel = true;
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
public final List<File> input;
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
public final DirectoryClassLoader classLoader;
Boolean log = false; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll?
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
public final DirectoryClassLoader classLoader;
public final List<File> classPath;
private final File outputPath;
@@ -97,9 +82,14 @@ public class JavaTXCompiler {
public DirectoryClassLoader getClassLoader() {
return classLoader;
}
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
this(Collections.singletonList(sourceFile), List.of(), new File("."));
this(Arrays.asList(sourceFile), List.of(), new File("."));
}
public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
this(sourceFile);
this.log = log;
}
public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException {
@@ -107,9 +97,6 @@ public class JavaTXCompiler {
}
public JavaTXCompiler(List<File> sources, List<File> contextPath, File outputPath) throws IOException, ClassNotFoundException {
// ensure new default placeholder registry for tests
defaultClientPlaceholderRegistry = new PlaceholderRegistry();
var path = new ArrayList<>(contextPath);
if (contextPath.isEmpty()) {
// When no contextPaths are given, the working directory is the sources root
@@ -120,7 +107,6 @@ public class JavaTXCompiler {
environment = new CompilationEnvironment(sources, classLoader);
classPath = path;
this.outputPath = outputPath;
this.input = sources.stream().map(File::getAbsoluteFile).toList();
for (File s : sources) {
parse(s);
@@ -147,7 +133,7 @@ public class JavaTXCompiler {
return null;
}
public Set<ClassOrInterface> getAvailableClasses(File sourceFile) throws ClassNotFoundException, IOException {
public ConstraintSet<Pair> getConstraints(File sourceFile) throws ClassNotFoundException, IOException {
Set<ClassOrInterface> allClasses = new HashSet<>();// environment.getAllAvailableClasses();
ClassOrInterface objectClass = ASTFactory.createClass(Object.class);
var recordClass = ASTFactory.createClass(Record.class);
@@ -186,13 +172,7 @@ public class JavaTXCompiler {
allClasses.addAll(sf.KlassenVektor);
return allClasses;
}
public ConstraintSet<Pair> getConstraints(File sourceFile) throws ClassNotFoundException, IOException {
var sf = sourceFiles.get(sourceFile);
var allClasses = getAvailableClasses(sourceFile);
TYPE ty = new TYPE(new HashSet<>(sf.availableClasses), allClasses);
TYPE ty = new TYPE(sf, allClasses);
var constraints = ty.getConstraints();
return constraints;
}
@@ -242,12 +222,12 @@ public class JavaTXCompiler {
private Set<ClassOrInterface> getAvailableClasses(JavaClassName name) throws ClassNotFoundException {
Set<ClassOrInterface> allClasses = new HashSet<>();
var cle = loadJavaTXClass(name);
if (cle == null) {
var clazz = loadJavaTXClass(name);
if (clazz == null) {
ClassOrInterface importedClass = ASTFactory.createClass(classLoader.loadClass(name.toString()));
allClasses.add(importedClass);
} else if (cle.cif != null) {
allClasses.add(cle.cif);
} else {
allClasses.add(clazz);
}
return allClasses;
}
@@ -326,193 +306,58 @@ public class JavaTXCompiler {
Set<Set<UnifyPair>> results = new HashSet<>();
UnifyResultModel urm = null;
// urm.addUnifyResultListener(resultListener);
logFile = logFile == null ? new FileWriter("log_" + sourceFiles.keySet().iterator().next().getName()) : logFile;
Logger logger = new Logger(logFile, "TypeInferenceAsync");
UnifyContext context = new UnifyContext(logger, true, urm, usedTasks, defaultClientPlaceholderRegistry);
try {
logFile = logFile == null ? new FileWriter(new File("log_" + sourceFiles.keySet().iterator().next().getName())) : logFile;
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, getClassLoader(), this);
System.out.println(finiteClosure);
urm = new UnifyResultModel(cons, finiteClosure);
urm.addUnifyResultListener(resultListener);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons);
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logger, getClassLoader(), this, context.placeholderRegistry());
logger.info(finiteClosure.toString());
urm = new UnifyResultModel(cons, finiteClosure);
urm.addUnifyResultListener(resultListener);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons, context.placeholderRegistry());
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
UnifyType lhs, rhs;
if (((lhs = x.getLhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType) && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
((PlaceholderType) lhs).setInnerType(true);
((PlaceholderType) rhs).setInnerType(true);
}
return x;
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
UnifyType lhs, rhs;
if (((lhs = x.getLhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType) && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
((PlaceholderType) lhs).setInnerType(true);
((PlaceholderType) rhs).setInnerType(true);
};
logFile.write(unifyCons.toString());
unifyCons = unifyCons.map(distributeInnerVars);
logFile.write(unifyCons.toString());
TypeUnify unify = new TypeUnify();
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
logFile.write("FC:\\" + finiteClosure.toString() + "\n");
for (SourceFile f : this.sourceFiles.values()) {
logFile.write(ASTTypePrinter.print(f));
}
return x;
logFile.flush();
Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = new HashSet<>();
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
};
logger.debug(unifyCons.toString());
unifyCons = unifyCons.map(distributeInnerVars);
logger.debug(unifyCons.toString());
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
logger.debug("FC:\\" + finiteClosure.toString() + "\n");
for (SourceFile f : this.sourceFiles.values()) {
logger.debug(ASTTypePrinter.print(f));
/*
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH); varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { if (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) { ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType( )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType( )).getVariance()); } } return y; } ); } while (!varianceTPHold.equals(varianceTPH));
*/
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
// logFile, log);
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()/*
* .stream().map(x -> { Set<Set<UnifyPair>> ret = new HashSet<>(); for (Constraint<UnifyPair> y : x) { ret.add(new HashSet<>(y)); } return ret; }).collect(Collectors. toCollection(ArrayList::new))
*/;
unify.unifyAsync(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm, usedTasks);
} catch (IOException e) {
System.err.println("kein LogFile");
}
// logFile.flush();
Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = new HashSet<>();
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
/*
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH); varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { if (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) { ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType( )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType( )).getVariance()); } } return y; } ); } while (!varianceTPHold.equals(varianceTPH));
*/
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
// logFile, log);
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()/*
* .stream().map(x -> { Set<Set<UnifyPair>> ret = new HashSet<>(); for (Constraint<UnifyPair> y : x) { ret.add(new HashSet<>(y)); } return ret; }).collect(Collectors. toCollection(ArrayList::new))
*/;
TypeUnify.unifyAsync(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
return urm;
}
public List<ResultSet> typeInference(File file) throws ClassNotFoundException, IOException {
return typeInference(List.of(file));
}
public List<ResultSet> typeInference(List<File> files) throws ClassNotFoundException, IOException {
Set<ClassOrInterface> allClasses = new HashSet<>();
var ressf = new ArrayList<SourceFile>();
var definedClasses = new HashSet<ClassOrInterface>();
for (var file : files) {
var sf = sourceFiles.get(file);
definedClasses.addAll(sf.KlassenVektor);
ressf.add(sf);
allClasses.addAll(getAvailableClasses(file));
allClasses.addAll(sf.availableClasses);
}
TYPE ty = new TYPE(definedClasses, allClasses);
var cons = ty.getConstraints();
Set<Set<UnifyPair>> results = new HashSet<>();
PlaceholderRegistry placeholderRegistry = new PlaceholderRegistry();
var logFolder = new File(System.getProperty("user.dir") + "/logFiles/");
if (ConsoleInterface.writeLogFiles && !logFolder.mkdirs()) throw new RuntimeException("Could not create directory for log files: " + logFolder);
Writer logFile = ConsoleInterface.writeLogFiles ? new FileWriter(new File(logFolder, "log_" + sourceFiles.keySet().iterator().next().getName())) : new OutputStreamWriter(new NullOutputStream());
Logger logger = new Logger(logFile, "TypeInference");
FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses.stream().toList(), logger, classLoader, this, placeholderRegistry);
logger.info(finiteClosure.toString());
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons, placeholderRegistry);
logger.info("xxx1");
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
UnifyType lhs, rhs;
if (((lhs = x.getLhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType) && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
((PlaceholderType) lhs).setInnerType(true);
((PlaceholderType) rhs).setInnerType(true);
}
return x;
};
logger.debug("Unify:" + unifyCons.toString());
logger.info("Unify:" + unifyCons.toString());
unifyCons = unifyCons.map(distributeInnerVars);
logger.debug("\nUnify_distributeInnerVars: " + unifyCons.toString());
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
logger.debug("FC:\\" + finiteClosure.toString() + "\n");
for (var sf : ressf) logger.info(ASTTypePrinter.print(sf));
// logFile.flush();
List<UnifyPair> andConstraintsSorted = unifyCons.getUndConstraints().stream()
.sorted(Comparator.comparing(UnifyPair::getPairOp).thenComparing(UnifyPair::getLhsType, Comparator.comparing(UnifyType::getName)))
.collect(Collectors.toList());
logger.info(andConstraintsSorted);
Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = new HashSet<>();
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
/*
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH); varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { if (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) { ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType( )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType( )).getVariance()); } } return y; } ); } while (!varianceTPHold.equals(varianceTPH));
*/
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
// logFile, log);
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()// .stream().map(x -> {
/*
* Set<Set<UnifyPair>> ret = new HashSet<>(); for (Constraint<UnifyPair> y : x) { ret.add(new HashSet<>(y)); } return ret; }).collect(Collectors.toCollection(ArrayList::new))
*/;
if (ConsoleInterface.unifyServerUrl.isPresent()) {
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
UnifyContext context = new UnifyContext(logger, true, urm, usedTasks, placeholderRegistry);
SocketFuture<UnifyResultPacket> future = SocketClient.execute(
UnifyRequestPacket.create(finiteClosure, cons, unifyCons, context.placeholderRegistry())
);
SocketClient.execute(SetAutoclosePacket.create());
return future.get().getResultSet(context);
}
else if (resultmodel) {
/* UnifyResultModel Anfang */
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
urm.addUnifyResultListener(li);
UnifyContext context = new UnifyContext(logger, true, urm, usedTasks, placeholderRegistry);
TypeUnify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
var finalResults = li.getResults().stream().sorted().toList();
int i = 0;
logger.info("RESULT Final: ");
for (var result : finalResults){
logger.info("Result: " + i++);
logger.info(result.getSortedResults());
}
logger.info("RES_FINAL: " + li.getResults().toString() + "\n");
return li.getResults();
}
/* UnifyResultModel End */
else {
// Set<Set<UnifyPair>> result = unify.unify(unifyCons.getUndConstraints(),
// oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons,
// finiteClosure));
UnifyContext context = new UnifyContext(logger, false, new UnifyResultModel(cons, finiteClosure), usedTasks, placeholderRegistry);
Set<Set<UnifyPair>> result = TypeUnify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
logger.info("RESULT: " + result);
results.addAll(result);
results = results.stream().map(x -> {
Optional<Set<UnifyPair>> res = new RuleSet(placeholderRegistry).subst(x.stream().map(y -> {
if (y.getPairOp() == PairOperator.SMALLERDOTWC)
y.setPairOp(PairOperator.EQUALSDOT);
return y; // alle Paare a <.? b erden durch a =. b ersetzt
}).collect(Collectors.toCollection(HashSet::new)));
if (res.isPresent()) {// wenn subst ein Erg liefert wurde was veraendert
return new TypeUnifyTask(context).applyTypeUnificationRules(res.get(), finiteClosure);
} else
return x; // wenn nichts veraendert wurde wird x zurueckgegeben
}).collect(Collectors.toCollection(HashSet::new));
logger.info("RESULT Final: " + results);
logger.info("Constraints for Generated Generics: " + " ???");
logger.debug("RES_FINAL: " + results.toString() + "\n");
// logFile.flush();
logger.debug("PLACEHOLDERS: " + placeholderRegistry);
// logFile.flush();
}
return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons), placeholderRegistry)))).collect(Collectors.toList());
}
/**
* TEMPORARY - Only for Language Server Usage
*/
public LanguageServerTransferObject getResultSetAndAbstractSyntax(File file) throws IOException, ClassNotFoundException {
var sf = sourceFiles.get(file);
if(sf == null){
sf = sourceFiles.values().stream().findFirst().get();
}
Set<ClassOrInterface> allClasses = new HashSet<>();
Set<ClassOrInterface> allClasses = new HashSet<>();// environment.getAllAvailableClasses();
allClasses.addAll(getAvailableClasses(sf));
allClasses.addAll(sf.getClasses());
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), file, this).stream().map(ASTFactory::createClass).collect(Collectors.toSet());
@@ -526,13 +371,14 @@ public class JavaTXCompiler {
final ConstraintSet<Pair> cons = getConstraints(file);
Set<Set<UnifyPair>> results = new HashSet<>();
Writer logFile = new OutputStreamWriter(new NullOutputStream());
Logger logger = new Logger(logFile, "TypeInferenceAsync");
UnifyContext context = new UnifyContext(logger, false, null, usedTasks, defaultClientPlaceholderRegistry);
try {
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses.stream().toList(), logger, classLoader, this, context.placeholderRegistry());
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons, context.placeholderRegistry());
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.stream().toList(), logFile, classLoader, this);
System.out.println(finiteClosure);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons);
System.out.println("xxx1");
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
UnifyType lhs, rhs;
if (((lhs = x.getLhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType) && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
@@ -543,48 +389,92 @@ public class JavaTXCompiler {
};
logFile.write("Unify:" + unifyCons.toString());
System.out.println("Unify:" + unifyCons.toString());
unifyCons = unifyCons.map(distributeInnerVars);
logFile.write("\nUnify_distributeInnerVars: " + unifyCons.toString());
TypeUnify unify = new TypeUnify();
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
logFile.write("FC:\\" + finiteClosure.toString() + "\n");
logFile.write(ASTTypePrinter.print(sf));
System.out.println(ASTTypePrinter.print(sf));
logFile.flush();
List<UnifyPair> andConstraintsSorted = unifyCons.getUndConstraints().stream()
.sorted(Comparator.comparing(UnifyPair::getPairOp).thenComparing(UnifyPair::getLhsType, Comparator.comparing(UnifyType::getName)))
.collect(Collectors.toList());
System.out.println(andConstraintsSorted);
Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = new HashSet<>();
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints();
/*
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH); varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { if (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) { ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType( )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType( )).getVariance()); } } return y; } ); } while (!varianceTPHold.equals(varianceTPH));
*/
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
// logFile, log);
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()// .stream().map(x -> {
/*
* Set<Set<UnifyPair>> ret = new HashSet<>(); for (Constraint<UnifyPair> y : x) { ret.add(new HashSet<>(y)); } return ret; }).collect(Collectors.toCollection(ArrayList::new))
*/;
if (resultmodel) {
/* UnifyResultModel Anfang */
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
urm.addUnifyResultListener(li);
TypeUnify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
generateBytecode(sf, li.getResults());
return new LanguageServerTransferObject(li.getResults(), sf, ASTTypePrinter.print(sf), generatedGenerics);
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm, usedTasks);
//System.out.println("RESULT Final: " + li.getResults());
var finalResults = li.getResults().stream().sorted().toList();
int i = 0;
System.out.println("RESULT Final: ");
for (var result : finalResults){
System.out.println("Result: " + i++);
System.out.println(result.getSortedResults());
}
System.out.println("Constraints for Generated Generics: " + " ???");
logFile.write("RES_FINAL: " + li.getResults().toString() + "\n");
logFile.flush();
return li.getResults();
}
/* UnifyResultModel End */
else {
Set<Set<UnifyPair>> result = TypeUnify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
// Set<Set<UnifyPair>> result = unify.unify(unifyCons.getUndConstraints(),
// oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons,
// finiteClosure));
Set<Set<UnifyPair>> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons, finiteClosure), usedTasks);
System.out.println("RESULT: " + result);
logFile.write("RES: " + result.toString() + "\n");
logFile.flush();
results.addAll(result);
results = results.stream().map(x -> {
Optional<Set<UnifyPair>> res = new RuleSet(context.placeholderRegistry()).subst(x.stream().map(y -> {
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> {
if (y.getPairOp() == PairOperator.SMALLERDOTWC)
y.setPairOp(PairOperator.EQUALSDOT);
return y; // alle Paare a <.? b erden durch a =. b ersetzt
}).collect(Collectors.toCollection(HashSet::new)));
if (res.isPresent()) {// wenn subst ein Erg liefert wurde was veraendert
return new TypeUnifyTask(context).applyTypeUnificationRules(res.get(), finiteClosure);
return new TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure);
} else
return x; // wenn nichts veraendert wurde wird x zurueckgegeben
}).collect(Collectors.toCollection(HashSet::new));
System.out.println("RESULT Final: " + results);
System.out.println("Constraints for Generated Generics: " + " ???");
logFile.write("RES_FINAL: " + results.toString() + "\n");
logFile.flush();
logFile.write("PLACEHOLDERS: " + PlaceholderType.EXISTING_PLACEHOLDERS);
logFile.flush();
}
} catch (ClassNotFoundException e) {
} catch (IOException e) {
System.err.println("kein LogFile");
}
generateBytecode(sf, results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons), context.placeholderRegistry())))).collect(Collectors.toList()));
return new LanguageServerTransferObject(results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons), context.placeholderRegistry())))).collect(Collectors.toList()), sf, ASTTypePrinter.print(sf), generatedGenerics);
return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList());
}
/**
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine Variance !=0 hat auf alle Typvariablen in Theta.
*
@@ -665,12 +555,10 @@ public class JavaTXCompiler {
* if it doesn't exist it's going to compile it and add it to the source files list
* @param name
*/
public ClassEntry loadJavaTXClass(JavaClassName name) {
public ClassOrInterface loadJavaTXClass(JavaClassName name) {
var file = findFileForClass(name);
var classEntry = new ClassEntry(new File(outputPath, name.getClassName() + ".class"), null);
if (input.contains(file)) return classEntry;
if (file != null) {
if (loadedClasses.containsKey(name)) return loadedClasses.get(name);
if (loadedClasses.containsKey(name)) return loadedClasses.get(name).cif();
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?
@@ -687,9 +575,8 @@ public class JavaTXCompiler {
writeClassFile(classFiles, outputPath != null ? outputPath : new File("."), false);
var clazz = classLoader.loadClass(name.toString());
var classOrInterface = ASTFactory.createClass(clazz);
classEntry = new ClassEntry(new File(outputPath, clazz.getName() + ".class"), classOrInterface);
loadedClasses.put(name, classEntry);
return classEntry;
loadedClasses.put(name, new ClassEntry(new File(outputPath, clazz.getName() + ".class"), classOrInterface));
return classOrInterface;
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -708,27 +595,19 @@ public class JavaTXCompiler {
}
public void generateBytecode() throws ClassNotFoundException, IOException {
if (ConsoleInterface.inferTogether) {
var files = sourceFiles.keySet().stream().toList();
var typeinferenceResult = this.typeInference(files);
for (var file : files) {
var sf = sourceFiles.get(file);
if (sf.isGenerated()) continue;
var classes = generateBytecode(sf, typeinferenceResult);
sf.setGenerated();
writeClassFile(classes, outputPath == null ? file.getParentFile() : outputPath, outputPath == null);
}
} else {
for (var file : sourceFiles.keySet()) {
var sf = sourceFiles.get(file);
if (sf.isGenerated()) continue;
var classes = generateBytecode(file);
sf.setGenerated();
writeClassFile(classes, outputPath == null ? file.getParentFile() : outputPath, outputPath == null);
}
for (var file : sourceFiles.keySet()) {
var sf = sourceFiles.get(file);
if (sf.isGenerated()) continue;
var classes = generateBytecode(file);
sf.setGenerated();
writeClassFile(classes, outputPath == null ? file.getParentFile() : outputPath, outputPath == null);
}
}
/**
* @param path - output-Directory can be null, then class file output is in the same directory as the parsed source files
* @return
*/
public Map<JavaClassName, byte[]> generateBytecode(File sourceFile) throws ClassNotFoundException, IOException {
var sf = sourceFiles.get(sourceFile);
if (sf.isGenerated()) return null;
@@ -783,15 +662,15 @@ public class JavaTXCompiler {
FileOutputStream output;
for (JavaClassName name : classFiles.keySet()) {
byte[] bytecode = classFiles.get(name);
defaultLogger.info("generating " + name + ".class file ...");
System.out.println("generating " + name + ".class file ...");
var subPath = preserveHierarchy ? path : Path.of(path.toString(), name.getPackageName().split("\\.")).toFile();
File outputFile = new File(subPath, name.getClassName() + ".class");
outputFile.getAbsoluteFile().getParentFile().mkdirs();
defaultLogger.info(outputFile.toString());
System.out.println(outputFile);
output = new FileOutputStream(outputFile);
output.write(bytecode);
output.close();
defaultLogger.success(name + ".class file generated");
System.out.println(name + ".class file generated");
}
}

View File

@@ -1,31 +0,0 @@
package de.dhbwstuttgart.core;
import de.dhbwstuttgart.server.SocketServer;
public class JavaTXServer {
public static boolean isRunning = false;
final SocketServer socketServer;
public JavaTXServer(int port) {
this.socketServer = new SocketServer(port);
}
public void listen() {
isRunning = true;
socketServer.start();
}
public void forceStop() {
try {
socketServer.stop();
}
catch (InterruptedException exception) {
System.err.println("Interrupted socketServer: " + exception);
}
isRunning = false;
}
}

View File

@@ -86,10 +86,6 @@ public class CompilationEnvironment {
File[] files = dir.listFiles((dir1, name) -> name.endsWith(".class"));
if (files != null)
for (File classFile : files) {
var javFile = new File(classFile.getParentFile(), classFile.getName().substring(0, classFile.getName().lastIndexOf('.')) + ".jav").getAbsoluteFile();
// Ignore class file if the corresponding jav file already exists in the input
// FIXME this can't work because we don't know the corresponding file that created a class
if (compiler.input.contains(javFile)) continue;
String className = classFile.getName().substring(0, classFile.getName().length() - 6);
if (className.matches("Fun\\d+\\$\\$.*"))
continue;

View File

@@ -1,11 +0,0 @@
package de.dhbwstuttgart.exceptions;
/**
* Eine Runtime Exception, die für den Fall genutzt wird, dass eine Unifikation abgebrochen wird.
* Durch das Werfen einer Exception können Abbrüche auch aus Methodenaufrufen heraus
* geprüft werden, da zuvor nur ein return X; stattfinden würde.
*/
public class UnifyCancelException extends RuntimeException {
}

View File

@@ -1,120 +0,0 @@
package de.dhbwstuttgart.languageServerInterface;
import de.dhbwstuttgart.bytecode.Codegen;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
import de.dhbwstuttgart.languageServerInterface.model.LanguageServerTransferObject;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
import de.dhbwstuttgart.target.generate.GenericsResult;
import de.dhbwstuttgart.target.tree.TargetStructure;
import org.apache.commons.io.FileUtils;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Implementation of an Interface for the Language-Server to get the Resultset and abstract Syntax.
*/
public class LanguageServerInterface {
public LanguageServerTransferObject getResultSetAndAbastractSyntax(String path, String resetNamesTo) throws IOException, URISyntaxException, ClassNotFoundException {
NameGenerator.resetTo(resetNamesTo);
return getResultSetAndAbstractSyntax(path);
}
public SourceFile getAst(String path, String resetNamesTo) throws IOException, URISyntaxException, ClassNotFoundException {
NameGenerator.resetTo(resetNamesTo);
return getAST(path);
}
/**
* returns the ResultSets, GenericResultSet and the AST
* You have to give the input as well as the path because of potential locks when the File is currently opened in an IDE.
* Example: file:///c:/test/main.jav -> file:///c:/test/out/main.class
*
* @param pathAsString the URI of the File. See Example.
*/
public LanguageServerTransferObject getResultSetAndAbstractSyntax(String pathAsString){
System.setOut(new PrintStream(OutputStream.nullOutputStream()));
try {
var uri = new URI(pathAsString);
var path = Path.of(uri);
var file = path.toFile();
Files.createDirectories(path.getParent().resolve("out"));
var compiler = new JavaTXCompiler(List.of(file), List.of(path.getParent().toFile()), path.getParent().resolve("out").toFile());
var parsedSource = compiler.sourceFiles.get(file);
var tiResults = compiler.typeInference(file);
Map<JavaClassName, byte[]> bytecode = compiler.generateBytecode(parsedSource, tiResults);
Files.createDirectories(path.getParent().resolve("out"));
compiler.writeClassFile(bytecode, path.getParent().resolve("out").toFile(), false);
return new LanguageServerTransferObject(tiResults, parsedSource, "", compiler.getGeneratedGenerics());
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
/**
* returns the AST without calculating the result
* You have to give the input as well as the path because of potential locks when the File is currently opened in an IDE.
* Example: file:///c:/test/main.jav -> file:///c:/test/out/main.class
*
* @param path the URI of the File. See Example.
* @throws IOException
* @throws ClassNotFoundException
* @throws URISyntaxException
*/
public SourceFile getAST(String path) throws IOException, ClassNotFoundException, URISyntaxException {
System.setOut(new PrintStream(OutputStream.nullOutputStream()));
URI uri = new URI(path);
ArrayList<String> pathWithoutName = new ArrayList<>(List.of(uri.getPath().split("/")));
pathWithoutName.remove(List.of(uri.getPath().split("/")).size() - 1);
String stringPathWithoutName = "";
for (String i : pathWithoutName) {
stringPathWithoutName += "/" + i;
}
try {
FileUtils.cleanDirectory(new File(stringPathWithoutName + "/out"));
} catch (Exception e) {
}
try {
(new File(stringPathWithoutName + "/out")).mkdirs();
} catch (Exception e) {
}
var test = getAST(uri.getPath().split("/")[uri.getPath().split("/").length - 1], new File(stringPathWithoutName).getPath());
System.setOut(System.out);
return test;
}
public static SourceFile getAST(String filename, String filePath) throws IOException, ClassNotFoundException {
var file = Path.of(filePath, filename).toFile();
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()), Path.of(filePath + "/out").toFile());
return compiler.sourceFiles.get(file);
}
}

View File

@@ -1,40 +0,0 @@
package de.dhbwstuttgart.languageServerInterface;
import de.dhbwstuttgart.languageServerInterface.model.CustomParserErrorHandler;
import de.dhbwstuttgart.languageServerInterface.model.ParserError;
import de.dhbwstuttgart.parser.antlr.Java17Lexer;
import de.dhbwstuttgart.parser.antlr.Java17Parser;
import de.dhbwstuttgart.parser.antlr.Java17ParserBaseListener;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import java.util.List;
public class ParserInterface {
public List<ParserError> getParseErrors(String input){
CustomParserErrorHandler errorListener = new CustomParserErrorHandler();
CharStream charStream = CharStreams.fromString(input);
Java17Lexer lexer = new Java17Lexer(charStream);
CommonTokenStream tokens = new CommonTokenStream(lexer);
Java17Parser parser = new Java17Parser(tokens);
parser.removeErrorListeners();
parser.addErrorListener(errorListener);
ParseTree tree = parser.sourceFile();
ParseTreeWalker walker = new ParseTreeWalker();
Java17ParserBaseListener listener = new Java17ParserBaseListener();
walker.walk(listener, tree);
return errorListener.getErrorMessages();
}
}

View File

@@ -1,47 +0,0 @@
package de.dhbwstuttgart.languageServerInterface.model;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.ATNConfigSet;
import org.antlr.v4.runtime.dfa.DFA;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
public class CustomParserErrorHandler implements ANTLRErrorListener {
private final List<ParserError> errorMessages = new ArrayList<>();
@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
int endCharPosition = charPositionInLine;
if (offendingSymbol instanceof Token) {
Token offendingToken = (Token) offendingSymbol;
endCharPosition = charPositionInLine + offendingToken.getText().length();
}
ParserError parserError = new ParserError(line, charPositionInLine, endCharPosition, msg);
errorMessages.add(parserError);
}
@Override
public void reportAmbiguity(Parser parser, DFA dfa, int i, int i1, boolean b, BitSet bitSet, ATNConfigSet atnConfigSet) {
}
@Override
public void reportAttemptingFullContext(Parser parser, DFA dfa, int i, int i1, BitSet bitSet, ATNConfigSet atnConfigSet) {
}
@Override
public void reportContextSensitivity(Parser parser, DFA dfa, int i, int i1, int i2, ATNConfigSet atnConfigSet) {
}
public List<ParserError> getErrorMessages() {
return errorMessages;
}
}

View File

@@ -1,31 +0,0 @@
package de.dhbwstuttgart.languageServerInterface.model;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.target.generate.GenericsResult;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LanguageServerTransferObject {
List<ResultSet> resultSets;
SourceFile Ast;
String printedAst;
Map<SourceFile, List<GenericsResult>> generatedGenerics = new HashMap<>();
public LanguageServerTransferObject(List<ResultSet> resultSets, SourceFile Ast, String printedAst, Map<SourceFile, List<GenericsResult>> generatedGenerics) {
this.resultSets = resultSets;
this.Ast = Ast;
this.printedAst = printedAst;
this.generatedGenerics = generatedGenerics;
}
public List<ResultSet> getResultSets() {return resultSets;}
public SourceFile getAst() {return Ast;}
public String getPrintedAst() {return printedAst;}
public Map<SourceFile, List<GenericsResult>> getGeneratedGenerics() {return generatedGenerics;}
}

View File

@@ -1,48 +0,0 @@
package de.dhbwstuttgart.languageServerInterface.model;
public class ParserError {
private int line;
private int charPositionInLine;
private int endCharPosition;
String msg;
public ParserError(int line, int charPositionInLine, int endCharPosition, String msg) {
this.line = line;
this.charPositionInLine = charPositionInLine;
this. endCharPosition = endCharPosition;
this.msg = msg;
}
public int getEndCharPosition() {
return endCharPosition;
}
public void setEndCharPosition(int endCharPosition) {
this.endCharPosition = endCharPosition;
}
public void setCharPositionInLine(int charPositionInLine) {
this.charPositionInLine = charPositionInLine;
}
public void setLine(int line) {
this.line = line;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getCharPositionInLine() {
return charPositionInLine;
}
public int getLine() {
return line;
}
public String getMsg() {
return msg;
}
}

View File

@@ -1,20 +0,0 @@
package de.dhbwstuttgart.languageServerInterface.model;
import com.google.common.reflect.TypeResolver;
import de.dhbwstuttgart.typeinference.unify.UnifyResultEvent;
import de.dhbwstuttgart.typeinference.unify.UnifyResultListener;
public class ResultSetListener implements UnifyResultListener {
TypeResolver typeResolver;
public ResultSetListener(TypeResolver typeResolver){
this.typeResolver = typeResolver;
}
@Override
public void onNewTypeResultFound(UnifyResultEvent evt) {
}
}

View File

@@ -7,7 +7,6 @@ import de.dhbwstuttgart.parser.antlr.Java17Parser;
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.util.Logger;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
@@ -18,9 +17,6 @@ import java.util.ArrayList;
import java.util.List;
public class JavaTXParser {
public static Logger logger = new Logger("Parser");
public static Java17Parser.SourceFileContext parse(File source) throws IOException, java.lang.ClassNotFoundException {
InputStream stream = new FileInputStream(source);
// DEPRECATED: ANTLRInputStream input = new ANTLRInputStream(stream);

View File

@@ -1,25 +1,4 @@
package de.dhbwstuttgart.parser;
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
public record SourceLoc(String file, int line) implements ISerializableData {
@Override
public SerialMap toSerial(KeyStorage keyStorage) {
var serialized = new SerialMap();
serialized.put("file", file);
serialized.put("line", line);
return serialized;
}
public static SourceLoc fromSerial(SerialMap data) {
return new SourceLoc(
data.getValue("file").getOf(String.class),
data.getValue("line").getOf(Integer.class)
);
}
public record SourceLoc(String file, int line) {
}

View File

@@ -12,7 +12,6 @@ import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
import de.dhbwstuttgart.typeinference.unify.model.*;
import java.util.*;
@@ -27,21 +26,16 @@ public class FCGenerator {
*
* @param availableClasses - Alle geparsten Klassen
*/
public static Set<UnifyPair> toUnifyFC(JavaTXCompiler compiler, Collection<ClassOrInterface> availableClasses, ClassLoader classLoader, PlaceholderRegistry placeholderRegistry) throws ClassNotFoundException {
return toFC(
availableClasses,
classLoader,
placeholderRegistry
).stream().map(t -> UnifyTypeFactory.convert(compiler, t, placeholderRegistry))
.collect(Collectors.toSet());
public static Set<UnifyPair> toUnifyFC(JavaTXCompiler compiler, Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException {
return toFC(availableClasses, classLoader).stream().map(t -> UnifyTypeFactory.convert(compiler, t)).collect(Collectors.toSet());
}
public static Set<Pair> toFC(Collection<ClassOrInterface> availableClasses, ClassLoader classLoader, PlaceholderRegistry placeholderRegistry) throws ClassNotFoundException {
public static Set<Pair> toFC(Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException {
HashSet<Pair> pairs = new HashSet<>();
//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){
List<Pair> newPairs = getSuperTypes(cly, availableClasses, gtvs, classLoader, placeholderRegistry);
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
@@ -81,13 +75,8 @@ public class FCGenerator {
* @param forType
* @return
*/
private static List<Pair> getSuperTypes(
ClassOrInterface forType,
Collection<ClassOrInterface> availableClasses,
ClassLoader classLoader,
PlaceholderRegistry placeholderRegistry
) throws ClassNotFoundException {
return getSuperTypes(forType, availableClasses, new HashMap<>(), classLoader, placeholderRegistry);
private static List<Pair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException {
return getSuperTypes(forType, availableClasses, new HashMap<>(), classLoader);
}
/**
@@ -98,13 +87,8 @@ public class FCGenerator {
* @return
* @throws ClassNotFoundException
*/
private static List<Pair> getSuperTypes(
ClassOrInterface forType,
Collection<ClassOrInterface> availableClasses,
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs,
ClassLoader classLoader,
PlaceholderRegistry placeholderRegistry
) throws ClassNotFoundException {
private static List<Pair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses,
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs, ClassLoader classLoader) throws ClassNotFoundException {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
//Die GTVs, die in forType hinzukommen:
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> newGTVs = new HashMap<>();
@@ -163,7 +147,7 @@ public class FCGenerator {
if(superClass.getClassName().equals(ASTFactory.createObjectClass().getClassName())){
superTypes = Arrays.asList(new Pair(ASTFactory.createObjectType(), ASTFactory.createObjectType(), PairOperator.SMALLER));
}else{
superTypes = getSuperTypes(superClass, availableClasses, newGTVs, classLoader, placeholderRegistry);
superTypes = getSuperTypes(superClass, availableClasses, newGTVs, classLoader);
}
retList.add(ret);

View File

@@ -1,6 +1,5 @@
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import de.dhbwstuttgart.parser.JavaTXParser;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
@@ -260,7 +259,7 @@ public class StatementGenerator {
ret.setStatement();
return ret;
default:
JavaTXParser.logger.info(stmt.getClass());
System.out.println(stmt.getClass());
throw new NotImplementedException();
}
}

View File

@@ -111,7 +111,7 @@ public class SyntaxTreeGenerator {
this.allmodifiers.put(Modifier.toString(Modifier.INTERFACE), Modifier.INTERFACE);
this.allmodifiers.put("sealed", 4096);
this.allmodifiers.put("non-sealed", 8192);
this.allmodifiers.put("default", 0); // Doesn't exist
this.allmodifiers.put("default", 16384);
this.allmodifiers.put("strictfp", 32768);
this.compiler = compiler;

View File

@@ -74,7 +74,7 @@ public class TypeGenerator {
throw new NotImplementedException();
}
} else if (!typeContext.LBRACK().isEmpty()) { // ArrayType über eckige Klammer prüfen
// JavaTXParser.logger.info(unannTypeContext.getText());
// System.out.println(unannTypeContext.getText());
throw new NotImplementedException();
}
/*
@@ -168,7 +168,7 @@ public class TypeGenerator {
if (generics.contains(name)) {
return new GenericRefType(name, offset);
} else {
Pattern p = Pattern.compile("Fun(Void|VoidImpl|Wrapper)?(\\d+)[$][$]"); // TODO Regex shenanigans
Pattern p = Pattern.compile("Fun(\\d+)[$][$]");
Matcher m = p.matcher(name);
if (m.matches()) {// es ist FunN$$-Type
return new RefType(new JavaClassName(name), convert(typeArguments, reg, generics), offset);

View File

@@ -64,6 +64,6 @@ public class JavaClassRegistry{
}
public int getNumberOfGenerics(String name) {
return existingClasses.getOrDefault(new JavaClassName(name), 0);
return existingClasses.get(new JavaClassName(name));
}
}

View File

@@ -1,41 +0,0 @@
package de.dhbwstuttgart.server;
import de.dhbwstuttgart.util.Logger;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import org.java_websocket.WebSocket;
public class ServerTaskLogger extends Logger {
private final WebSocket webSocket;
private final SocketServer socketServer;
private final LogLevel customLogLevel;
public ServerTaskLogger(WebSocket webSocket, SocketServer socketServer, LogLevel customLogLevel) {
this.webSocket = webSocket;
this.socketServer = socketServer;
this.customLogLevel = customLogLevel;
}
@Override
public boolean isLogLevelActive(LogLevel logLevel) {
return logLevel.isHigherOrEqualTo(customLogLevel);
}
@Override
protected void print(String s, LogLevel logLevel) {
String coloredPrefix = this.getPrefix(logLevel);
if (logLevel.isHigherOrEqualTo(LogLevel.ERROR)) {
socketServer.sendError(webSocket, coloredPrefix + s, false);
}
else {
socketServer.sendMessage(webSocket, coloredPrefix + s);
}
}
@Override
protected void write(String s) {
// under no circumstances write anything to a file
}
}

View File

@@ -1,202 +0,0 @@
package de.dhbwstuttgart.server;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.dhbwstuttgart.core.ConsoleInterface;
import de.dhbwstuttgart.server.packet.IClientToServerPacket;
import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.server.packet.IServerToClientPacket;
import de.dhbwstuttgart.server.packet.PacketContainer;
import de.dhbwstuttgart.server.packet.UnifyRequestPacket;
import de.dhbwstuttgart.server.packet.UnifyResultPacket;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.util.Logger;
import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.enums.ReadyState;
import org.java_websocket.handshake.ServerHandshake;
/**
* The Client-side of the websocket
*/
public class SocketClient extends WebSocketClient {
public static Logger logger = new Logger("SocketClient");
/**
* The singleton object
*/
private static SocketClient socketClient = null;
/**
* List of futures that are still waiting to be fulfilled
*/
private final Map<String, SocketFuture<?>> responseFutures = new HashMap<>();
private SocketClient(String url) {
super(
URI.create(url), // target url
//SocketServer.perMessageDeflateDraft, // enable compression
Map.of( // headers
"packetProtocolVersion", SocketServer.packetProtocolVersion
)
);
// make sure the url is in a valid format
final String regex = "^wss?://(\\w+(\\.\\w+)?)*:(\\d+)$";
final Matcher matcher = Pattern.compile(regex).matcher(url);
if (!matcher.find()) {
throw new RuntimeException("Provided string \"" + url + "\" is not a valid server URL! Use pattern ws(s?)://<host.name>:<port>");
}
try {
// wait for the connection to be set up
this.connectBlocking();
// make sure the connection has been established successfully
if (this.getReadyState() != ReadyState.OPEN) {
throw new RuntimeException("WebSocket Client could not connect to remote host at " + this.uri);
}
} catch (InterruptedException exception) {
throw new RuntimeException(exception);
}
// add a shutdown hook to close the connection when the process ends or is stopped by a SIGINT signal
Runtime.getRuntime().addShutdownHook(new Thread(this::close));
}
private SocketClient(String host, int port, boolean secure) throws InterruptedException {
this(String.format("%s://%s:%d/", secure ? "wss" : "ws", host, port));
}
/**
* Singleton access method, creates one if none is available
*
* @return The one and only socketClient
*/
private static SocketClient initializeClient() {
if (socketClient == null) {
socketClient = new SocketClient(ConsoleInterface.unifyServerUrl.get());
}
return socketClient;
}
/**
* Send a packet to the server (connection will be created, if none is found) and return a future
* for the response packet
*/
synchronized public static <T extends IServerToClientPacket> SocketFuture<T> execute(IClientToServerPacket<T> packet) {
SocketClient client = initializeClient();
/*
* Create a future that will be associated with the packet and eventually completed
*/
SocketFuture<T> future = packet.getFuture();
if (!future.isDone()) {
client.responseFutures.put(future.futureId, future);
}
/*
* Establish connection, if not already done.
* Serialize the packet and send it to the server.
* Return the future to be handled by the caller.
*/
try {
String json = PacketContainer.serialize(packet);
client.send(json);
} catch (Exception exception) {
logger.exception(exception);
throw new RuntimeException("Exception occurred in server connection: ", exception);
}
return future;
}
/**
* Shortcut for waiting and retrieving the response immediately
*
* @param packet The packet to send
* @param <T> The type of response packet to await
* @return The response packet, once it is received
*/
public static <T extends IServerToClientPacket> T executeAndGet(IClientToServerPacket<T> packet) {
return SocketClient.execute(packet).get();
}
/**
* Specific client-side implementations to handle incoming packets
*/
protected void handleReceivedPacket(IPacket packet) {
if (!(packet instanceof IServerToClientPacket serverToClientPacket)) {
System.err.println("Received package of invalid type + " + packet.getClass().getName());
this.close();
return;
}
serverToClientPacket.onHandle(this.getConnection(), this);
}
/**
* Complete a registered future, so it can be handled by whoever executed the creator task
*
* @param id The associated id for this future
* @param trigger The object triggering the completion
*/
public void completeResponseFuture(String id, IServerToClientPacket trigger) {
SocketFuture<?> future = this.responseFutures.remove(id);
if (future == null) return;
if (!future.accept(trigger)) {
throw new RuntimeException("Packet " + trigger.getClass().getName() + " tried to complete future, but was not allowed to");
}
}
public static void closeIfOpen() {
if (socketClient != null && socketClient.isOpen()) {
socketClient.close();
}
}
@Override
public void onOpen(ServerHandshake handshakedata) {
logger.success("Connected to server with status " + handshakedata.getHttpStatus());
}
@Override
public void onMessage(String message) {
// logger.info("received: " + message);
IPacket packet = PacketContainer.deserialize(message);
this.handleReceivedPacket(packet);
}
@Override
public void onClose(int code, String reason, boolean remote) {
logger.info(
"Disconnected from server " +
"with code " + code + " " +
(reason.isEmpty() ? "" : "and reason " + reason + " ") +
"(closed by remote: " + remote + ")"
);
if (!this.responseFutures.isEmpty()) {
throw new RuntimeException("Server closed before all required tasks were answered");
}
}
@Override
public void onError(Exception e) {
logger.exception(e);
throw new RuntimeException(e);
}
}

View File

@@ -1,48 +0,0 @@
package de.dhbwstuttgart.server;
import de.dhbwstuttgart.server.packet.IServerToClientPacket;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class SocketFuture<T extends IServerToClientPacket> extends CompletableFuture<T> {
public final String futureId = UUID.randomUUID().toString();
public final List<Class<T>> allowedTriggers;
public SocketFuture(List<Class<T>> allowedTriggers) {
this.allowedTriggers = allowedTriggers;
}
public boolean accept(IServerToClientPacket trigger) {
if (this.allowedTriggers.contains(trigger.getClass())) {
this.complete((T)trigger);
return true;
}
return false;
}
@Override
public T get() {
try {
return super.get();
}
catch (InterruptedException | ExecutionException exception) {
throw new RuntimeException(exception);
}
}
/**
* Special case where the future is immediately fulfilled without a response package similar to
* <code>CompletableFuture.completedFuture()</code> but without a value
*/
public static <R extends IServerToClientPacket> SocketFuture<R> completedFuture() {
SocketFuture<R> dummyFuture = new SocketFuture<>(new ArrayList<>(0));
dummyFuture.complete(null);
return dummyFuture;
}
}

View File

@@ -1,235 +0,0 @@
package de.dhbwstuttgart.server;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.dhbwstuttgart.server.packet.ErrorPacket;
import de.dhbwstuttgart.server.packet.IClientToServerPacket;
import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.server.packet.MessagePacket;
import de.dhbwstuttgart.server.packet.PacketContainer;
import de.dhbwstuttgart.util.Logger;
import java.net.InetSocketAddress;
import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.java_websocket.WebSocket;
import org.java_websocket.drafts.Draft;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.extensions.permessage_deflate.PerMessageDeflateExtension;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
public class SocketServer extends WebSocketServer {
public static Logger logger = new Logger("SocketServer");
public static final int maxTasksPerSession = 100;
private static boolean serverRunning = false;
/**
* Increase this every time a breaking change to the server communication is done.
* This will prevent errors when the server version and client version do not match.
*/
public static final String packetProtocolVersion = "1";
// create an executor for tasks that will always keep at least one task around
private final ThreadPoolExecutor taskExecutor = new ThreadPoolExecutor(1, Integer.MAX_VALUE,60L, TimeUnit.SECONDS, new SynchronousQueue<>());
// create an executor for scheduling timeouts
private final ScheduledExecutorService timeoutExecutor = Executors.newSingleThreadScheduledExecutor();
public SocketServer(int port) {
super(new InetSocketAddress(port));
this.setConnectionLostTimeout(30);
serverRunning = true;
// add a shutdown hook to close all connections when the process ends or is stopped by a SIGINT signal
Runtime.getRuntime().addShutdownHook(new Thread(this::onShutdown));
}
public static boolean isServerRunning() {
return serverRunning;
}
private void onShutdown() {
serverRunning = false;
try {
for (var webSocket : this.getConnections()) {
this.sendError(webSocket, "Sorry, i am shutting down. You are now on your own, good Luck!", true);
webSocket.close();
}
this.stop();
taskExecutor.shutdown();
timeoutExecutor.shutdown();
} catch (InterruptedException exception) {
// we are shutting down anyway
}
}
@Override
public void onOpen(WebSocket webSocket, ClientHandshake clientHandshake) {
String ppv = clientHandshake.getFieldValue("packetProtocolVersion");
if (!ppv.equals(packetProtocolVersion)) {
this.sendError(webSocket,
"Mismatch in packet protocol version! Client (you): \"" + ppv + "\" and Server (me): \"" + packetProtocolVersion + "\"",
true
);
webSocket.close(1);
return;
}
SocketData socketData = new SocketData(webSocket);
logger.info("New connection: " + socketData.id + " (with ppv " + ppv + ")");
try {
sendMessage(webSocket, "Welcome to the server!");
// wait 10 seconds for the client to send a task and close the connection if nothing has been received until then
final int secondsUntilTimeout = 10;
timeoutExecutor.schedule(() -> {
if (webSocket.<SocketData>getAttachment().totalTasks.get() > 0 || !webSocket.isOpen()) {
return;
}
sendMessage(webSocket, "No task received after " + secondsUntilTimeout + " seconds. Closing connection...");
webSocket.close();
},
secondsUntilTimeout,
TimeUnit.SECONDS
);
// and finally, when your program wants to exit
} catch (Exception e) {
logger.exception(e);
webSocket.close(1, e.getMessage());
}
}
@Override
public void onClose(WebSocket webSocket, int code, String reason, boolean remote) {
SocketData socketData = webSocket.getAttachment();
logger.info("Connection closed: " + socketData.id);
logger.info(
"Disconnected client " + socketData.id + " " +
"with code " + code + " " +
(reason.isEmpty() ? "" : "and reason " + reason + " ") +
"(closed by client: " + remote + ")"
);
}
@Override
public void onMessage(WebSocket webSocket, String s) {
// logger.info("Received: " + s.substring(0, 50));
IPacket reconstructedPacket = PacketContainer.deserialize(s);
try {
this.onPacketReceived(webSocket, reconstructedPacket);
} catch (JsonProcessingException e) {
logger.exception(e);
this.log(webSocket, "Error on processing incoming package: " + e.getMessage());
}
}
@Override
public void onError(WebSocket webSocket, Exception e) {
if (webSocket != null) {
log(webSocket, e.getMessage());
webSocket.close();
}
logger.exception(e);
}
@Override
public void onStart() {
logger.success("Websocket server started on port " + this.getPort());
}
/**
* A shorthand method for sending informational messages to the client
*/
public void sendMessage(WebSocket webSocket, String text) {
try {
MessagePacket message = MessagePacket.create(text);
webSocket.send(PacketContainer.serialize(message));
} catch (Exception e) {
System.err.println("Failed to send message: " + text);
logger.exception(e);
}
}
/**
* A shorthand method for sending error messages to the client
*/
public void sendError(WebSocket webSocket, String text, boolean isFatal) {
try {
ErrorPacket error = ErrorPacket.create(text, isFatal);
webSocket.send(PacketContainer.serialize(error));
} catch (Exception e) {
logger.exception(e);
log(webSocket, "Failed to send error: " + text);
}
}
/**
* The server-side implementation on how to handle certain packets when received
*/
private void onPacketReceived(WebSocket webSocket, IPacket packet) throws JsonProcessingException {
SocketData socketData = webSocket.getAttachment();
// limit the number of tasks per connection
if (socketData.totalTasks.get() >= maxTasksPerSession) {
sendError(webSocket, "Exceeded the maximum amount of " + maxTasksPerSession + " tasks per session", true);
webSocket.close();
return;
}
// only allow packets that are meant to be handled by the server
if (!(packet instanceof IClientToServerPacket<?> clientToServerPacket)) {
sendMessage(webSocket, "The package of type " + packet.getClass().getName() + " is not handled by the server!");
return;
}
// update the socket data
socketData.unhandledTasks.incrementAndGet();
socketData.totalTasks.incrementAndGet();
// add the packet to the queue so it can be started by the worker
CompletableFuture.runAsync(() -> {
clientToServerPacket.onHandle(webSocket, this);
int remainingUnhandledTasks = socketData.unhandledTasks.decrementAndGet();
if (socketData.closeIfNoTasksLeft) {
// if the websocket has 0 unhandled Tasks, close the connection
if (remainingUnhandledTasks <= 0) {
sendMessage(webSocket, "All requested tasks finished! Closing connection...");
webSocket.close();
}
}
}, taskExecutor);
}
public void log(WebSocket webSocket, String msg) {
String socketId = (webSocket == null) ? "???" : webSocket.<SocketData>getAttachment().id;
logger.info("[" + socketId + "] " + msg);
}
/**
* The data that is associated server-side with any connected client.
* This makes it possible to store information that can be mapped to any existing connection.
*/
public static class SocketData {
public final String id;
public final AtomicInteger unhandledTasks = new AtomicInteger(0);
public final AtomicInteger totalTasks = new AtomicInteger(0);
public boolean closeIfNoTasksLeft = false;
public SocketData(WebSocket webSocket) {
this.id = UUID.randomUUID().toString();
webSocket.setAttachment(this);
}
}
}

View File

@@ -1,35 +0,0 @@
package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.server.SocketFuture;
import de.dhbwstuttgart.server.SocketServer;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialUUID;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialValue;
import org.java_websocket.WebSocket;
public class DebugPacket implements IClientToServerPacket.Void, IServerToClientPacket {
public SerialUUID a1;
public SerialUUID a2;
public SerialMap b1;
public SerialMap b2;
public SerialList<? extends ISerialNode> c1;
public SerialList<? extends ISerialNode> c2;
public SerialValue<?> d1;
public SerialValue<?> d2;
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketClient socketClient) {}
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketServer socketServer) {}
@JsonIgnore
public SocketFuture<IServerToClientPacket> getFuture() {
return SocketFuture.completedFuture();
}
}

View File

@@ -1,36 +0,0 @@
package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.server.SocketFuture;
import de.dhbwstuttgart.server.SocketServer;
import org.java_websocket.WebSocket;
/**
* A packet to send simple error messages between the client and the server
*/
public class ErrorPacket implements IServerToClientPacket {
/**
* The error endpoint for messages from the server that should be logged out as errors and possibly abort the process
*/
public String error;
public boolean isFatal;
@JsonIgnore
public static ErrorPacket create(String error, boolean isFatal) {
ErrorPacket packet = new ErrorPacket();
packet.error = error;
packet.isFatal = isFatal;
return packet;
}
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketClient socketClient) {
SocketClient.logger.exception(new RuntimeException(this.error));
if (this.isFatal) {
socketClient.close(1, "Received fatal error from server");
}
}
}

View File

@@ -1,26 +0,0 @@
package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.server.SocketFuture;
import de.dhbwstuttgart.server.SocketServer;
import org.java_websocket.WebSocket;
/**
* A packet that will be sent to the server. Use <code>Void</code> Sub-Interface for packets without response
*
* @param <T> The response packet that will fulfill the future.
*/
public interface IClientToServerPacket<T extends IServerToClientPacket> extends IPacket {
@JsonIgnore
void onHandle(WebSocket webSocket, SocketServer socketServer);
@JsonIgnore
SocketFuture<T> getFuture();
/**
* Special case, where the packet will remain unanswered by the server
*/
interface Void extends IClientToServerPacket<IServerToClientPacket> {}
}

View File

@@ -1,12 +0,0 @@
package de.dhbwstuttgart.server.packet;
/**
* The shared interface for all packet of the client-server connection.
* A packet must always:
* - Have a default / no-parameter constructor
* - Have only serializable public properties (or disable them via jackson annotations)
*
*/
public interface IPacket {
}

View File

@@ -1,12 +0,0 @@
package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.server.SocketClient;
import org.java_websocket.WebSocket;
public interface IServerToClientPacket extends IPacket {
@JsonIgnore
void onHandle(WebSocket webSocket, SocketClient socketClient);
}

View File

@@ -1,35 +0,0 @@
package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.server.SocketFuture;
import de.dhbwstuttgart.server.SocketServer;
import org.java_websocket.WebSocket;
/**
* A fallback packet that is generated if the received JSON could not be mapped to an existing package
*/
public class InvalidPacket implements IClientToServerPacket.Void, IServerToClientPacket {
/**
* If available, the error that caused this package to appear
*/
public String error = "<unknown error>";
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketClient socketClient) {
SocketClient.logger.error("InvalidPacket: " + this.error);
}
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
socketServer.log(webSocket, "InvalidPacket: " + this.error);
}
@JsonIgnore
public SocketFuture<IServerToClientPacket> getFuture() {
return SocketFuture.completedFuture();
}
}

View File

@@ -1,40 +0,0 @@
package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.server.SocketFuture;
import de.dhbwstuttgart.server.SocketServer;
import org.java_websocket.WebSocket;
/**
* A packet to send simple informational messages between the client and the server
*/
public class MessagePacket implements IClientToServerPacket.Void, IServerToClientPacket {
/**
* The informational message from the server that should be logged out outputted
*/
public String message;
@JsonIgnore
public static MessagePacket create(String message) {
MessagePacket packet = new MessagePacket();
packet.message = message;
return packet;
}
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketClient socketClient) {
SocketClient.logger.info("SocketMessage: " + this.message);
}
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
socketServer.log(webSocket, this.message);
}
@JsonIgnore
public SocketFuture<IServerToClientPacket> getFuture() {
return SocketFuture.completedFuture();
}
}

View File

@@ -1,98 +0,0 @@
package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.dhbwstuttgart.util.Logger;
/**
* A wrapper for the packet to ensure correct serialization/deserialization and make it possible to detect the matching
* packet type for deserialization.
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public class PacketContainer {
// The jackson serializer / deserializer tool
private static final ObjectMapper objectMapper = new ObjectMapper();
/*
* The available packet types. The one type that is represented in the JSON should always be the ONLY non-null value.
* They have to be public (for the moment) to let jackson fill them in while deserializing
*/
public ErrorPacket errorPacket = null;
public MessagePacket messagePacket = null;
public InvalidPacket invalidPacket = null;
public UnifyRequestPacket unifyRequestPacket = null;
public UnifyResultPacket unifyResultPacket = null;
public DebugPacket debugPacket = null;
public SetAutoclosePacket setAutoclosePacket = null;
/**
* Generate the JSON string for the given packet
*
* @param packet The packet to serialize
* @return The JSON representation of the packet
*/
public static String serialize(IPacket packet) throws JsonProcessingException {
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
PacketContainer container = new PacketContainer();
if (packet instanceof ErrorPacket)
container.errorPacket = (ErrorPacket) packet;
else if (packet instanceof MessagePacket)
container.messagePacket = (MessagePacket) packet;
else if (packet instanceof UnifyRequestPacket)
container.unifyRequestPacket = (UnifyRequestPacket) packet;
else if (packet instanceof UnifyResultPacket)
container.unifyResultPacket = (UnifyResultPacket) packet;
else if (packet instanceof DebugPacket)
container.debugPacket = (DebugPacket) packet;
else if (packet instanceof SetAutoclosePacket)
container.setAutoclosePacket = (SetAutoclosePacket) packet;
// Add new packets here and in the deserialize method
else
throw new RuntimeException("Cannot map packet to any known packet class");
return objectMapper.writeValueAsString(container);
}
/**
* Use the JSON string to generate the matching packet object
*
* @param json The serialized representation of a packet container
* @return The deserialized Packet object
*/
public static IPacket deserialize(String json) {
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
try {
PacketContainer container = objectMapper.readValue(json, PacketContainer.class);
if (container.errorPacket != null)
return container.errorPacket;
if (container.messagePacket != null)
return container.messagePacket;
if (container.invalidPacket != null)
return container.invalidPacket;
if (container.unifyRequestPacket != null)
return container.unifyRequestPacket;
if (container.unifyResultPacket != null)
return container.unifyResultPacket;
if (container.debugPacket != null)
return container.debugPacket;
if (container.setAutoclosePacket != null)
return container.setAutoclosePacket;
// Add new packets here and in the serialize method
throw new RuntimeException("Cannot map received json to any known packet class");
} catch (Exception e) {
(new Logger()).exception(e);
InvalidPacket packet = new InvalidPacket();
packet.error = e.getMessage();
return packet;
}
}
}

View File

@@ -1,32 +0,0 @@
package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.server.SocketFuture;
import de.dhbwstuttgart.server.SocketServer;
import org.java_websocket.WebSocket;
/**
* Normally, a connection stays open until either the client or the server process ends.
* Send this packet to inform the server that the connection can be closed once all tasks are done
*/
public class SetAutoclosePacket implements IClientToServerPacket.Void {
public int dummyProperty = 1;
@JsonIgnore
public static SetAutoclosePacket create() {
return new SetAutoclosePacket();
}
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
webSocket.<SocketServer.SocketData>getAttachment().closeIfNoTasksLeft = true;
socketServer.log(webSocket, "Marked connection as autoclose");
}
@JsonIgnore
public SocketFuture<IServerToClientPacket> getFuture() {
return SocketFuture.completedFuture();
}
}

View File

@@ -1,164 +0,0 @@
package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.core.ConsoleInterface;
import de.dhbwstuttgart.server.ServerTaskLogger;
import de.dhbwstuttgart.server.SocketFuture;
import de.dhbwstuttgart.server.SocketServer;
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialValue;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl;
import de.dhbwstuttgart.typeinference.unify.UnifyResultModel;
import de.dhbwstuttgart.typeinference.unify.UnifyTaskModel;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
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.Logger;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import org.java_websocket.WebSocket;
/**
* A packet to send all required data for the unification algorithm to the server and request the unification
*/
public class UnifyRequestPacket implements IClientToServerPacket<UnifyResultPacket> {
public SerialMap finiteClosure;
public SerialMap constraintSet;
public SerialMap unifyConstraintSet;
public SerialMap serialKeyStorage;
public SerialValue<?> placeholders;
public SerialList<SerialMap> factoryplaceholders;
public String futureId;
public int logLevel;
@JsonIgnore
private KeyStorage keyStorage = new KeyStorage();
@JsonIgnore
private boolean keyStorageLoaded = false;
public static UnifyRequestPacket create(
FiniteClosure finiteClosure,
ConstraintSet<Pair> constraintSet,
ConstraintSet<UnifyPair> unifyConstraintSet,
PlaceholderRegistry placeholderRegistry
) {
UnifyRequestPacket packet = new UnifyRequestPacket();
// store constraint and finite closure
packet.finiteClosure = finiteClosure.toSerial(packet.keyStorage);
packet.constraintSet = constraintSet.toSerial(packet.keyStorage);
packet.unifyConstraintSet = unifyConstraintSet.toSerial(packet.keyStorage);
// store placeholder registry
var serialRegistry = placeholderRegistry.toSerial(packet.keyStorage);
packet.placeholders = serialRegistry.getValue("ph");
packet.factoryplaceholders = serialRegistry.getList("factoryPh").assertListOfMaps();
// store referenced objects separately
packet.serialKeyStorage = packet.keyStorage.toSerial(packet.keyStorage);
packet.logLevel = ConsoleInterface.logLevel.getValue();
return packet;
}
@JsonIgnore
public void loadKeyStorage(UnifyContext context) {
if (!keyStorageLoaded) {
keyStorageLoaded = true;
keyStorage = KeyStorage.fromSerial(this.serialKeyStorage, context);
}
}
@JsonIgnore
private FiniteClosure retrieveFiniteClosure(UnifyContext context) {
this.loadKeyStorage(context);
return FiniteClosure.fromSerial(this.finiteClosure, context, keyStorage);
}
@JsonIgnore
private ConstraintSet<Pair> retrieveConstraintSet(UnifyContext context) {
this.loadKeyStorage(context);
return ConstraintSet.fromSerial(this.constraintSet, context, Pair.class, keyStorage);
}
@JsonIgnore
private ConstraintSet<UnifyPair> retrieveUnifyConstraintSet(UnifyContext context) {
this.loadKeyStorage(context);
return ConstraintSet.fromSerial(this.unifyConstraintSet, context, UnifyPair.class, keyStorage);
}
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
socketServer.sendMessage(webSocket, "You requested a unify! Please wait until I calculated everything...");
socketServer.log(webSocket, "Client requested a unification. Starting now...");
try {
var placeholderRegistry = new PlaceholderRegistry();
ArrayList<String> existingPlaceholders = (ArrayList) this.placeholders.getOf(ArrayList.class);
existingPlaceholders.forEach(placeholderRegistry::addPlaceholder);
Logger logger = new ServerTaskLogger(
webSocket,
socketServer,
Logger.LogLevel.fromValue(
Math.max(this.logLevel, Logger.LogLevel.INFO.getValue())
)
);
var unifyContext = new UnifyContext(logger, true,
new UnifyResultModel(new ConstraintSet<>(), new FiniteClosure(new HashSet<>(), logger, placeholderRegistry)),
new UnifyTaskModel(), ForkJoinPool.commonPool(), placeholderRegistry
);
this.factoryplaceholders.stream()
.map(p -> (PlaceholderType)UnifyType.fromSerial(p, unifyContext))
.forEach(placeholderRegistry.UnifyTypeFactory_PLACEHOLDERS::add);
// start the unification algorithm from the received data
IFiniteClosure finiteClosure = this.retrieveFiniteClosure(unifyContext);
ConstraintSet<Pair> constraintSet = this.retrieveConstraintSet(unifyContext);
ConstraintSet<UnifyPair> unifyConstraintSet = this.retrieveUnifyConstraintSet(unifyContext);
var resultModel = new UnifyResultModel(constraintSet, finiteClosure);
UnifyResultListenerImpl resultListener = new UnifyResultListenerImpl();
resultModel.addUnifyResultListener(resultListener);
TypeUnify.unifyParallel(
unifyConstraintSet.getUndConstraints(),
unifyConstraintSet.getOderConstraints(),
finiteClosure,
unifyContext.newWithResultModel(resultModel)
);
var resultSets = resultListener.getResults();
socketServer.log(webSocket, "Finished unification");
socketServer.sendMessage(webSocket, "Unification finished. Found " + resultSets.size() + " result sets");
if (webSocket.isOpen()) {
UnifyResultPacket resultPacket = UnifyResultPacket.create(resultSets, futureId);
webSocket.send(PacketContainer.serialize(resultPacket));
}
} catch (Exception e) {
SocketServer.logger.exception(e);
socketServer.log(webSocket, e.getMessage());
}
}
@JsonIgnore
public SocketFuture<UnifyResultPacket> getFuture() {
var future = new SocketFuture<>(List.of(UnifyResultPacket.class));
futureId = future.futureId;
return future;
}
}

View File

@@ -1,45 +0,0 @@
package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import java.util.List;
import org.java_websocket.WebSocket;
/**
* A packet to send all calculated data from the unification algorithm back to the client
*/
public class UnifyResultPacket implements IServerToClientPacket {
public SerialList<ISerialNode> results;
public SerialMap keyStorage;
public String futureId;
public static UnifyResultPacket create(List<ResultSet> resultSets, String futureId) {
UnifyResultPacket serialized = new UnifyResultPacket();
KeyStorage keyStorage = new KeyStorage();
serialized.results = SerialList.fromMapped(resultSets, resultSet -> resultSet.toSerial(keyStorage));
serialized.keyStorage = keyStorage.toSerial(keyStorage);
serialized.futureId = futureId;
return serialized;
}
@JsonIgnore
public List<ResultSet> getResultSet(UnifyContext context) {
return this.results.assertListOfMaps().stream()
.map(resultData -> ResultSet.fromSerial(resultData, context)).toList();
}
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketClient socketClient) {
SocketClient.logger.info("Received unify result");
socketClient.completeResponseFuture(futureId, this);
}
}

View File

@@ -1,16 +0,0 @@
package de.dhbwstuttgart.server.packet.dataContainers;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
public interface ISerializableData {
public abstract ISerialNode toSerial(KeyStorage keyStorage);
public static Object fromSerial(SerialMap data, UnifyContext context) {
throw new NotImplementedException("Missing implementation of \"fromSerial\" for a serializable element");
}
}

View File

@@ -1,103 +0,0 @@
package de.dhbwstuttgart.server.packet.dataContainers;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
public class KeyStorage implements ISerializableData {
/**
* Store a unique identifier for every element, so it can be referenced in the json
*/
protected AtomicInteger identifierCount = new AtomicInteger();
/**
* Store the serialized element per identifier when serializing
*/
protected SerialMap serializedElements = new SerialMap();
/**
* Store the unserialized element per identifier when unserializing
*/
protected Map<String, ISerializableData> unserializedElements = new HashMap<>();
/**
* Retrieve or generate a new identifier for a constraint
*/
public String getIdentifier() {
return this.identifierCount.incrementAndGet() + "_";
}
/**
* Checks if the given element identifier belongs to an element that was already serialized
*/
public boolean isAlreadySerialized(String identifier) {
return this.serializedElements.containsKey(identifier);
}
/**
* Checks if the given element identifier belongs to a element that was already unserialized
*/
public boolean isAlreadyUnserialized(String identifier) {
return this.unserializedElements.containsKey(identifier);
}
/**
* Register a serialized element to prevent it from being serialized again
*/
public void putSerialized(String identifier, SerialMap serializedElement) {
this.serializedElements.put(identifier, serializedElement);
}
/**
* Retrieve a serialized element
*/
public SerialMap getSerialized(String identifier) {
if (!this.serializedElements.containsKey(identifier)) {
throw new RuntimeException("No serialized element of identifier " + identifier + " available to get");
}
return this.serializedElements.getMap(identifier);
}
/**
* Register an unserialized element to prevent it from being unserialized again
*/
public void putUnserialized(String identifier, ISerializableData element) {
this.unserializedElements.put(identifier, element);
}
/**
* Retrieve an unserialized element
*/
public <T extends ISerializableData> T getUnserialized(String identifier, Class<T> target) {
if (!this.unserializedElements.containsKey(identifier)) {
throw new RuntimeException("No unserialized element of identifier " + identifier + " available to get");
}
var element = this.unserializedElements.get(identifier);
if (target.isInstance(element)) {
return (T) element;
}
throw new RuntimeException("Failed to get unserialized element from KeyStorage. Expected instance of " +
target.getName() + " but found " + element.getClass().getName());
}
@Override
public SerialMap toSerial(KeyStorage keyStorage) {
SerialMap serialized = new SerialMap();
serialized.put("serializedElements", this.serializedElements);
return serialized;
}
public static KeyStorage fromSerial(SerialMap data, UnifyContext context) {
var serializedConstraintsData = data.getMap("serializedElements");
var constraintContext = new KeyStorage();
for (var entry : serializedConstraintsData.entrySet()) {
if (entry.getValue() instanceof SerialMap valueMap) {
constraintContext.putSerialized(entry.getKey(), valueMap);
}
}
return constraintContext;
}
}

View File

@@ -1,31 +0,0 @@
package de.dhbwstuttgart.server.packet.dataContainers.serialized;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
/**
* Use the following classes for an intermediate serialized tree structure
*/
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "_t"
)
@JsonSubTypes({
@JsonSubTypes.Type(value = SerialMap.class, name = "m"),
@JsonSubTypes.Type(value = SerialList.class, name = "l"),
@JsonSubTypes.Type(value = SerialValue.class, name = "v"),
@JsonSubTypes.Type(value = SerialUUID.class, name = "u")
})
public interface ISerialNode {
default <T extends ISerialNode> T assertType(Class<T> type) {
if (type.isInstance(this)) {
return (T) this;
}
throw new RuntimeException("Expected ISerialNode to be of type " + type.getName()
+ " but found " + this.getClass().getName() + " instead");
}
}

View File

@@ -1,74 +0,0 @@
package de.dhbwstuttgart.server.packet.dataContainers.serialized;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.function.Function;
import java.util.stream.Stream;
public class SerialList<I extends ISerialNode> extends ArrayList<I> implements ISerialNode {
public SerialList() {}
public SerialList(Collection<I> data) {
this.addAll(data);
}
public SerialList(Stream<I> data) {
this(data.toList());
}
public SerialList(I[] data) {
this(Arrays.stream(data).toList());
}
@SafeVarargs
@JsonIgnore
public static <A extends ISerialNode> ArrayList<A> from(A ...values) {
ArrayList<A> list = new SerialList<>();
Collections.addAll(list, values);
return list;
}
@JsonIgnore
public static <A,B extends ISerialNode> SerialList<B> fromMapped(Stream<A> data, Function<A,B> mapper) {
return new SerialList<>(data.map(mapper).toList());
}
@JsonIgnore
public static <A,B extends ISerialNode> SerialList<B> fromMapped(Collection<A> data, Function<A,B> mapper) {
return SerialList.fromMapped(data.stream(), mapper);
}
@JsonIgnore
public static <A,B extends ISerialNode> SerialList<B> fromMapped(A[] data, Function<A,B> mapper) {
return SerialList.fromMapped(Arrays.stream(data), mapper);
}
@JsonIgnore
public SerialList<SerialMap> assertListOfMaps() {
if (this.isEmpty() || this.get(0) instanceof SerialMap) {
return (SerialList<SerialMap>) this;
}
throw new RuntimeException("Required List to contain SerialMap elements but condition failed");
}
@JsonIgnore
public SerialList<SerialList<?>> assertListOfLists() {
if (this.isEmpty() || this.get(0) instanceof SerialList) {
return (SerialList<SerialList<?>>) this;
}
throw new RuntimeException("Required List to contain SerialList elements but condition failed");
}
@JsonIgnore
public SerialList<SerialValue<?>> assertListOfValues() {
if (this.isEmpty() || this.get(0) instanceof SerialValue) {
return (SerialList<SerialValue<?>>) this;
}
throw new RuntimeException("Required List to contain SerialValue elements but condition failed");
}
@JsonIgnore
public SerialList<SerialUUID> assertListOfUUIDs() {
if (this.isEmpty() || this.get(0) instanceof SerialUUID) {
return (SerialList<SerialUUID>) this;
}
throw new RuntimeException("Required List to contain SerialUUID elements but condition failed");
}
}

View File

@@ -1,84 +0,0 @@
package de.dhbwstuttgart.server.packet.dataContainers.serialized;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.util.HashMap;
import java.util.Map;
import org.jspecify.annotations.Nullable;
public class SerialMap extends HashMap<String, ISerialNode> implements ISerialNode {
public SerialMap() {
super();
}
public SerialMap(Map<String, ISerialNode> data) {
super(data);
}
@JsonIgnore
public void put(String key, Boolean value) {
this.put(key, new SerialValue<>(value));
}
@JsonIgnore
public void put(String key, String value) {
this.put(key, new SerialValue<>(value));
}
@JsonIgnore
public void put(String key, Number value) {
this.put(key, new SerialValue<>(value));
}
@JsonIgnore
private <T> T get(String key, Class<T> expectedType) {
if (!this.containsKey(key)) {
throw new RuntimeException("Missing required value " + key + " in ObjectMap");
}
var element = this.get(key);
if (element != null && element.getClass() != expectedType) {
throw new RuntimeException(
"Required value " + key + " to be of type " + expectedType.getName() + " but found " + element.getClass().getName()
);
}
return (T)element;
}
@JsonIgnore
public SerialList<?> getList(String key) {
return this.get(key, SerialList.class);
}
@Nullable
@JsonIgnore
public SerialList<?> getListOrNull(String key) {
return this.containsKey(key) ? this.getList(key) : null;
}
@JsonIgnore
public SerialMap getMap(String key) {
return this.get(key, SerialMap.class);
}
@Nullable
@JsonIgnore
public SerialMap getMapOrNull(String key) {
return this.containsKey(key) ? this.getMap(key) : null;
}
@JsonIgnore
public SerialValue<?> getValue(String key) {
return this.get(key, SerialValue.class);
}
@JsonIgnore
public SerialUUID getUUID(String key) {
return this.get(key, SerialUUID.class);
}
@Nullable
@JsonIgnore
public SerialUUID getUUIDOrNull(String key) {
return this.containsKey(key) ? this.getUUID(key) : null;
}
}

View File

@@ -1,13 +0,0 @@
package de.dhbwstuttgart.server.packet.dataContainers.serialized;
public class SerialUUID implements ISerialNode {
public String uuid;
public SerialUUID() {}
public SerialUUID(String uuid) {
this.uuid = uuid;
}
}

View File

@@ -1,28 +0,0 @@
package de.dhbwstuttgart.server.packet.dataContainers.serialized;
import com.fasterxml.jackson.annotation.JsonIgnore;
public class SerialValue<T> implements ISerialNode {
public T value;
public static final SerialValue<Object> NULL = new SerialValue<>(null);
public SerialValue() {}
public SerialValue(T value) {
this.value = value;
}
@JsonIgnore
public <A> SerialValue<A> assertValueOf(Class<A> targetClass) {
if (this.value == null || targetClass.isInstance(this.value)) {
return (SerialValue<A>) this;
}
throw new RuntimeException("Required Value to contain " + targetClass.getName() + " value but condition failed on" +
" type " + this.value.getClass().getName());
}
@JsonIgnore
public <A> A getOf(Class<A> targetClass) {
return this.assertValueOf(targetClass).value;
}
}

View File

@@ -1,8 +0,0 @@
package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.util.Logger;
public class SyntaxTree {
public static Logger logger = new Logger("SyntaxTree");
}

View File

@@ -1,8 +1,5 @@
package de.dhbwstuttgart.syntaxtree.factory;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.core.JavaTXServer;
public class NameGenerator {
private static String strNextName = "A";
@@ -16,10 +13,6 @@ public class NameGenerator {
public static void reset() {
strNextName = "A";
}
public static void resetTo(String name) {
strNextName = name;
}
/**
* Berechnet einen neuen, eindeutigen Namen f�r eine neue
@@ -33,11 +26,7 @@ public class NameGenerator {
// n�chster Name berechnen und in strNextName speichern
inc( strNextName.length() - 1 );
if (JavaTXServer.isRunning) {
throw new RuntimeException("Using the NameGenerator on a server is not allowed");
}
JavaTXCompiler.defaultClientPlaceholderRegistry.addPlaceholder(strReturn);
return strReturn;
}

View File

@@ -1,8 +1,5 @@
package de.dhbwstuttgart.syntaxtree.factory;
import de.dhbwstuttgart.syntaxtree.SyntaxTree;
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
import de.dhbwstuttgart.util.Logger;
import java.io.Writer;
import java.lang.reflect.Modifier;
import java.util.*;
@@ -34,13 +31,9 @@ import org.antlr.v4.runtime.Token;
public class UnifyTypeFactory {
public static FiniteClosure generateFC(
List<ClassOrInterface> fromClasses,
Logger logger,
ClassLoader classLoader,
JavaTXCompiler compiler,
PlaceholderRegistry placeholderRegistry
) throws ClassNotFoundException {
private static ArrayList<PlaceholderType> PLACEHOLDERS = new ArrayList<>();
public static FiniteClosure generateFC(List<ClassOrInterface> fromClasses, Writer logFile, ClassLoader classLoader, JavaTXCompiler compiler) throws ClassNotFoundException {
/*
Die transitive Hülle muss funktionieren.
Man darf schreiben List<A> extends AL<A>
@@ -51,7 +44,7 @@ public class UnifyTypeFactory {
Generell dürfen sie immer die gleichen Namen haben.
TODO: die transitive Hülle bilden
*/
return new FiniteClosure(FCGenerator.toUnifyFC(compiler, fromClasses, classLoader, placeholderRegistry), logger, compiler, placeholderRegistry);
return new FiniteClosure(FCGenerator.toUnifyFC(compiler, fromClasses, classLoader), logFile, compiler);
}
public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr, SourceLoc location){
@@ -74,23 +67,23 @@ public class UnifyTypeFactory {
* Convert from
* ASTType -> UnifyType
*/
public static UnifyType convert(JavaTXCompiler compiler, RefTypeOrTPHOrWildcardOrGeneric t, Boolean innerType, PlaceholderRegistry placeholderRegistry){
public static UnifyType convert(JavaTXCompiler compiler, RefTypeOrTPHOrWildcardOrGeneric t, Boolean innerType){
if (t instanceof GenericRefType){
return UnifyTypeFactory.convert(compiler, (GenericRefType)t, innerType, placeholderRegistry);
return UnifyTypeFactory.convert(compiler, (GenericRefType)t, innerType);
} else if (t instanceof TypePlaceholder){
return UnifyTypeFactory.convert(compiler, (TypePlaceholder)t, innerType, placeholderRegistry);
return UnifyTypeFactory.convert(compiler, (TypePlaceholder)t, innerType);
} else if (t instanceof ExtendsWildcardType){
return UnifyTypeFactory.convert(compiler, (ExtendsWildcardType)t, innerType, placeholderRegistry);
return UnifyTypeFactory.convert(compiler, (ExtendsWildcardType)t, innerType);
} else if (t instanceof SuperWildcardType) {
return UnifyTypeFactory.convert(compiler, (SuperWildcardType) t, innerType, placeholderRegistry);
return UnifyTypeFactory.convert(compiler, (SuperWildcardType) t, innerType);
} else if (t instanceof RefType){
return UnifyTypeFactory.convert(compiler, (RefType)t, innerType, placeholderRegistry);
return UnifyTypeFactory.convert(compiler, (RefType)t, innerType);
}
//Es wurde versucht ein Typ umzuwandeln, welcher noch nicht von der Factory abgedeckt ist
throw new NotImplementedException("Der Typ "+t+" kann nicht umgewandelt werden");
}
public static UnifyType convert(JavaTXCompiler compiler, RefType t, Boolean innerType, PlaceholderRegistry placeholderRegistry){
public static UnifyType convert(JavaTXCompiler compiler, RefType t, Boolean innerType){
//Check if it is a FunN Type:
Pattern p = Pattern.compile("Fun(\\d+)[$][$]");
Matcher m = p.matcher(t.getName().toString());
@@ -98,76 +91,76 @@ public class UnifyTypeFactory {
if(b){
Integer N = Integer.valueOf(m.group(1));
if((N + 1) == t.getParaList().size()){
return convertFunN(compiler, t.getParaList(), false, placeholderRegistry);
return convertFunN(compiler, t.getParaList(), false);
}
}
UnifyType ret;
List<UnifyType> params = new ArrayList<>();
if (t.getParaList() != null) {
for (RefTypeOrTPHOrWildcardOrGeneric pT : t.getParaList()) {
params.add(UnifyTypeFactory.convert(compiler, pT, true, placeholderRegistry));
params.add(UnifyTypeFactory.convert(compiler, pT, true));
}
}
var clazz = compiler.getClass(t.getName());
if (clazz != null && clazz.isInterface() && clazz.isFunctionalInterface()) {
var method = clazz.getMethods().stream().filter(x -> Modifier.isAbstract(x.modifier)).findFirst().orElseThrow();
var methodParams = method.getParameterList().getFormalparalist().stream().map(x -> convert(compiler, x.getType(), true, placeholderRegistry)).toList();
var methodParams = method.getParameterList().getFormalparalist().stream().map(x -> convert(compiler, x.getType(), true)).toList();
var generics = StreamSupport.stream(clazz.getGenerics().spliterator(), false).map(GenericTypeVar::getName).toList();
return new FunInterfaceType(t.getName().toString(), new TypeParams(params), methodParams, convert(compiler, method.getReturnType(), true, placeholderRegistry), generics);
return new FunInterfaceType(t.getName().toString(), new TypeParams(params), methodParams, convert(compiler, method.getReturnType(), true), generics);
}
return new ReferenceType(t.getName().toString(),new TypeParams(params));
}
public static UnifyType convertFunN(JavaTXCompiler compiler, List<RefTypeOrTPHOrWildcardOrGeneric> paraList, Boolean innerType, PlaceholderRegistry placeholderRegistry){
public static UnifyType convertFunN(JavaTXCompiler compiler, List<RefTypeOrTPHOrWildcardOrGeneric> paraList, Boolean innerType){
UnifyType ret;
List<UnifyType> params = new ArrayList<>();
if(paraList != null && paraList.size() > 0){
for(RefTypeOrTPHOrWildcardOrGeneric pT : paraList){
params.add(UnifyTypeFactory.convert(compiler, pT, false, placeholderRegistry));
params.add(UnifyTypeFactory.convert(compiler, pT, false));
}
}
ret = FunNType.getFunNType(new TypeParams(params));
return ret;
}
public static UnifyType convert(JavaTXCompiler compiler, TypePlaceholder tph, Boolean innerType, PlaceholderRegistry placeholderRegistry) {
public static UnifyType convert(JavaTXCompiler compiler, TypePlaceholder tph, Boolean innerType){
if (tph.getName().equals("AFR")) {
SyntaxTree.logger.info("XXX"+innerType);
System.out.println("XXX"+innerType);
}
PlaceholderType ntph = new PlaceholderType(tph.getName(), tph.getVariance(), placeholderRegistry);
PlaceholderType ntph = new PlaceholderType(tph.getName(), tph.getVariance());
ntph.setVariance(tph.getVariance());
ntph.setOrCons(tph.getOrCons());
ntph.setWildcardtable(tph.getWildcardtable());
int in = placeholderRegistry.UnifyTypeFactory_PLACEHOLDERS.indexOf(ntph);
int in = PLACEHOLDERS.indexOf(ntph);
if (in == -1) {
placeholderRegistry.UnifyTypeFactory_PLACEHOLDERS.add(ntph);
PLACEHOLDERS.add(ntph);
ntph.setInnerType(innerType);
return ntph;
}
else {
PlaceholderType oldpht = placeholderRegistry.UnifyTypeFactory_PLACEHOLDERS.get(in);
PlaceholderType oldpht = PLACEHOLDERS.get(in);
oldpht.setInnerType(oldpht.isInnerType() || innerType);
return oldpht;
}
}
public static UnifyType convert(JavaTXCompiler compiler, GenericRefType t, Boolean innerType, PlaceholderRegistry placeholderRegistry){
public static UnifyType convert(JavaTXCompiler compiler, GenericRefType t, Boolean innerType){
return new ReferenceType(t.getParsedName(), true);
}
public static UnifyType convert(JavaTXCompiler compiler, WildcardType t, Boolean innerType, PlaceholderRegistry placeholderRegistry){
public static UnifyType convert(JavaTXCompiler compiler, WildcardType t, Boolean innerType){
if(t.isExtends())
return new ExtendsType(UnifyTypeFactory.convert(compiler, t.getInnerType(), false, placeholderRegistry));
return new ExtendsType(UnifyTypeFactory.convert(compiler, t.getInnerType(), false));
else if(t.isSuper())
return new SuperType(UnifyTypeFactory.convert(compiler, t.getInnerType(), false, placeholderRegistry));
return new SuperType(UnifyTypeFactory.convert(compiler, t.getInnerType(), false));
else throw new NotImplementedException();
}
public static ConstraintSet<UnifyPair> convert(JavaTXCompiler compiler, ConstraintSet<Pair> constraints, PlaceholderRegistry placeholderRegistry) {
return constraints.map(c -> UnifyTypeFactory.convert(compiler, c, placeholderRegistry));
public static ConstraintSet<UnifyPair> convert(JavaTXCompiler compiler, ConstraintSet<Pair> constraints) {
return constraints.map(c -> UnifyTypeFactory.convert(compiler, c));
}
//NEVER USED
@@ -178,30 +171,30 @@ public class UnifyTypeFactory {
// return unifyPairConstraint;
//}
public static UnifyPair convert(JavaTXCompiler compiler, Pair p, PlaceholderRegistry placeholderRegistry) {
public static UnifyPair convert(JavaTXCompiler compiler, Pair p) {
UnifyPair ret = null;
if(p.GetOperator().equals(PairOperator.SMALLERDOT)) {
ret = generateSmallerDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false, placeholderRegistry)
, UnifyTypeFactory.convert(compiler, p.TA2, false, placeholderRegistry), p.getLocation());
ret = generateSmallerDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false)
, UnifyTypeFactory.convert(compiler, p.TA2, false), p.getLocation());
//return ret;
}else if(p.GetOperator().equals(PairOperator.SMALLERNEQDOT)) {
ret = generateSmallNotEqualDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false, placeholderRegistry)
, UnifyTypeFactory.convert(compiler, p.TA2, false, placeholderRegistry), p.getLocation());
ret = generateSmallNotEqualDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false)
, UnifyTypeFactory.convert(compiler, p.TA2, false), p.getLocation());
//return ret;
}else if(p.GetOperator().equals(PairOperator.EQUALSDOT)) {
ret = generateEqualDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false, placeholderRegistry)
, UnifyTypeFactory.convert(compiler, p.TA2, false, placeholderRegistry), p.getLocation());
ret = generateEqualDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false)
, UnifyTypeFactory.convert(compiler, p.TA2, false), p.getLocation());
//return ret;
}else if(p.GetOperator().equals(PairOperator.SMALLER)){
ret = generateSmallerPair(UnifyTypeFactory.convert(compiler, p.TA1, false, placeholderRegistry),
UnifyTypeFactory.convert(compiler, p.TA2, false, placeholderRegistry), p.getLocation());
ret = generateSmallerPair(UnifyTypeFactory.convert(compiler, p.TA1, false),
UnifyTypeFactory.convert(compiler, p.TA2, false), p.getLocation());
}else throw new NotImplementedException();
UnifyType lhs, rhs;
if (((lhs = ret.getLhsType()) instanceof PlaceholderType)
&& ((PlaceholderType)lhs).isWildcardable()
&& (rhs = ret.getLhsType()) instanceof PlaceholderType) {
if (lhs.getName().equals("AQ")) {
// SyntaxTree.logger.info("");
System.out.println("");
}
((PlaceholderType)rhs).enableWildcardtable();
}
@@ -210,7 +203,7 @@ public class UnifyTypeFactory {
&& ((PlaceholderType)rhs).isWildcardable()
&& (lhs = ret.getLhsType()) instanceof PlaceholderType) {
if (rhs.getName().equals("AQ")) {
// SyntaxTree.logger.info("");
System.out.println("");
}
((PlaceholderType)lhs).enableWildcardtable();
}
@@ -221,16 +214,16 @@ public class UnifyTypeFactory {
* Convert from
* UnifyType -> ASTType
*/
public static Set<ResultPair> convert(Set<UnifyPair> unifyPairSet, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
public static Set<ResultPair> convert(Set<UnifyPair> unifyPairSet, Map<String,TypePlaceholder> tphs) {
return unifyPairSet.stream().map(
unifyPair -> convert(unifyPair, tphs, placeholderRegistry))
unifyPair -> convert(unifyPair, tphs))
.collect(Collectors.toSet());
}
public static ResultPair convert(UnifyPair mp, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
public static ResultPair convert(UnifyPair mp, Map<String,TypePlaceholder> tphs) {
if (mp == null) { return null;} //kann bei basePairs passieren
RefTypeOrTPHOrWildcardOrGeneric tl = UnifyTypeFactory.convert(mp.getLhsType(), tphs, placeholderRegistry);
RefTypeOrTPHOrWildcardOrGeneric tr = UnifyTypeFactory.convert(mp.getRhsType(), tphs, placeholderRegistry);
RefTypeOrTPHOrWildcardOrGeneric tl = UnifyTypeFactory.convert(mp.getLhsType(), tphs);
RefTypeOrTPHOrWildcardOrGeneric tr = UnifyTypeFactory.convert(mp.getRhsType(), tphs);
if(tl instanceof TypePlaceholder){
if(tr instanceof TypePlaceholder) {
@@ -239,7 +232,7 @@ public class UnifyTypeFactory {
//Einfach ignorieren TODO: Das hier muss ausgebessert werden:
//return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, ASTFactory.createObjectType());
}else{
return new PairTPHsmallerTPH((TypePlaceholder)tl, (TypePlaceholder)tr, convert(mp.getBasePair(), tphs, placeholderRegistry));
return new PairTPHsmallerTPH((TypePlaceholder)tl, (TypePlaceholder)tr, convert(mp.getBasePair(), tphs));
}
}else if(tr instanceof RefType){
return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, (RefType) tr);
@@ -251,51 +244,51 @@ public class UnifyTypeFactory {
}else return new PairNoResult(tl, tr);//throw new NotImplementedException();
}
public static RefTypeOrTPHOrWildcardOrGeneric convert(ReferenceType t, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
public static RefTypeOrTPHOrWildcardOrGeneric convert(ReferenceType t, Map<String,TypePlaceholder> tphs) {
if(JavaClassName.Void.equals(t.getName()))return new Void(new NullToken());
if (t.isGenTypeVar()) return new GenericRefType(t.getName(),new NullToken());
RefType ret = new RefType(new JavaClassName(t.getName()),convert(t.getTypeParams(), tphs, placeholderRegistry),new NullToken());
RefType ret = new RefType(new JavaClassName(t.getName()),convert(t.getTypeParams(), tphs),new NullToken());
return ret;
}
public static RefTypeOrTPHOrWildcardOrGeneric convert(FunNType t, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
RefType ret = new RefType(new JavaClassName(t.getName()), convert(t.getTypeParams(), tphs, placeholderRegistry), new NullToken());
public static RefTypeOrTPHOrWildcardOrGeneric convert(FunNType t, Map<String,TypePlaceholder> tphs) {
RefType ret = new RefType(new JavaClassName(t.getName()), convert(t.getTypeParams(), tphs), new NullToken());
return ret;
}
public static RefTypeOrTPHOrWildcardOrGeneric convert(SuperType t, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
RefTypeOrTPHOrWildcardOrGeneric innerType = convert(t.getSuperedType(), tphs, placeholderRegistry);
public static RefTypeOrTPHOrWildcardOrGeneric convert(SuperType t, Map<String,TypePlaceholder> tphs) {
RefTypeOrTPHOrWildcardOrGeneric innerType = convert(t.getSuperedType(), tphs);
return new SuperWildcardType(innerType, new NullToken());
}
public static RefTypeOrTPHOrWildcardOrGeneric convert(ExtendsType t, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
RefTypeOrTPHOrWildcardOrGeneric innerType = convert(t.getExtendedType(), tphs, placeholderRegistry);
public static RefTypeOrTPHOrWildcardOrGeneric convert(ExtendsType t, Map<String,TypePlaceholder> tphs) {
RefTypeOrTPHOrWildcardOrGeneric innerType = convert(t.getExtendedType(), tphs);
return new ExtendsWildcardType(innerType, new NullToken());
}
public static RefTypeOrTPHOrWildcardOrGeneric convert(PlaceholderType t, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
public static RefTypeOrTPHOrWildcardOrGeneric convert(PlaceholderType t, Map<String,TypePlaceholder> tphs) {
TypePlaceholder ret = tphs.get(t.getName());
if(ret == null){ //Dieser TPH wurde vom Unifikationsalgorithmus erstellt
ret = TypePlaceholder.fresh(new NullToken(), placeholderRegistry);
ret = TypePlaceholder.fresh(new NullToken());
tphs.put(t.getName(), ret);
}
ret.setVariance(t.getVariance());
return ret;
}
public static RefTypeOrTPHOrWildcardOrGeneric convert(UnifyType t, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
if(t instanceof FunNType)return convert((FunNType) t, tphs, placeholderRegistry);
if(t instanceof ReferenceType)return convert((ReferenceType) t, tphs, placeholderRegistry);
if(t instanceof SuperType)return convert((SuperType) t, tphs, placeholderRegistry);
if(t instanceof ExtendsType)return convert((ExtendsType) t, tphs, placeholderRegistry);
if(t instanceof PlaceholderType)return convert((PlaceholderType) t, tphs, placeholderRegistry);
public static RefTypeOrTPHOrWildcardOrGeneric convert(UnifyType t, Map<String,TypePlaceholder> tphs) {
if(t instanceof FunNType)return convert((FunNType) t, tphs);
if(t instanceof ReferenceType)return convert((ReferenceType) t, tphs);
if(t instanceof SuperType)return convert((SuperType) t, tphs);
if(t instanceof ExtendsType)return convert((ExtendsType) t, tphs);
if(t instanceof PlaceholderType)return convert((PlaceholderType) t, tphs);
throw new NotImplementedException("Der Typ "+t+" kann nicht umgewandelt werden");
}
private static List<RefTypeOrTPHOrWildcardOrGeneric> convert(TypeParams typeParams, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
private static List<RefTypeOrTPHOrWildcardOrGeneric> convert(TypeParams typeParams, Map<String,TypePlaceholder> tphs) {
List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
for(UnifyType uT : typeParams){
RefTypeOrTPHOrWildcardOrGeneric toAdd = convert(uT, tphs, placeholderRegistry);
RefTypeOrTPHOrWildcardOrGeneric toAdd = convert(uT, tphs);
ret.add(toAdd);
}
return ret;

View File

@@ -1,13 +1,8 @@
package de.dhbwstuttgart.syntaxtree.type;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import org.antlr.v4.runtime.Token;
import java.util.Objects;
@@ -20,7 +15,7 @@ import java.util.Objects;
*
*/
public class ExtendsWildcardType extends WildcardType implements ISerializableData {
public class ExtendsWildcardType extends WildcardType{
/**
* Author: Arne Lüdtke<br/>
@@ -73,22 +68,4 @@ public class ExtendsWildcardType extends WildcardType implements ISerializableDa
ExtendsWildcardType that = (ExtendsWildcardType) o;
return that.innerType.equals(this.innerType);
}
@Override
public SerialMap toSerial(KeyStorage keyStorage) {
SerialMap serialized = new SerialMap();
serialized.put("innerType", this.innerType.toSerial(keyStorage));
// create the wrapper and put this as the object
var serializedWrapper = super.toSerial(keyStorage).assertType(SerialMap.class);
serializedWrapper.put("object", serialized);
return serializedWrapper;
}
public static ExtendsWildcardType fromSerial(SerialMap data, UnifyContext context) {
return new ExtendsWildcardType(
RefTypeOrTPHOrWildcardOrGeneric.fromSerial(data.getMap("innerType"), context),
new NullToken()
);
}
}

View File

@@ -1,77 +1,57 @@
package de.dhbwstuttgart.syntaxtree.type;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import org.antlr.v4.runtime.Token;
import java.util.Objects;
public class GenericRefType extends RefTypeOrTPHOrWildcardOrGeneric implements ISerializableData {
private String name;
public class GenericRefType extends RefTypeOrTPHOrWildcardOrGeneric
{
private String name;
public GenericRefType(String name, Token offset) {
super(offset);
this.name = name;
}
public GenericRefType(String name, Token offset)
{
super(offset);
this.name = name;
}
public String getParsedName() {
return name.toString();
}
public String getParsedName(){
return name.toString();
}
@Override
public void accept(ASTVisitor visitor) {
visitor.visit(this);
}
@Override
public void accept(ASTVisitor visitor) {
visitor.visit(this);
}
@Override
public <A> A acceptTV(TypeVisitor<A> visitor) {
return visitor.visit(this);
}
@Override
public <A> A acceptTV(TypeVisitor<A> visitor) {
return visitor.visit(this);
}
@Override
public void accept(ResultSetVisitor visitor) {
visitor.visit(this);
}
@Override
public void accept(ResultSetVisitor visitor) {
visitor.visit(this);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GenericRefType that = (GenericRefType) o;
return name.equals(that.name);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GenericRefType that = (GenericRefType) o;
return name.equals(that.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
@Override
public String toString() {
return "GTV " + this.name;
}
@Override
public SerialMap toSerial(KeyStorage keyStorage) {
SerialMap serialized = new SerialMap();
serialized.put("name", this.name);
// create the wrapper and put this as the object
var serializedWrapper = super.toSerial(keyStorage).assertType(SerialMap.class);
serializedWrapper.put("object", serialized);
return serializedWrapper;
}
public static GenericRefType fromSerial(SerialMap data, UnifyContext context) {
return new GenericRefType(
data.getValue("name").getOf(String.class),
new NullToken()
);
}
@Override
public String toString()
{
return "GTV " + this.name;
}
}

View File

@@ -1,15 +1,8 @@
package de.dhbwstuttgart.syntaxtree.type;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import org.antlr.v4.runtime.Token;
import java.util.ArrayList;
@@ -18,137 +11,122 @@ import java.util.List;
import java.util.Objects;
public class RefType extends RefTypeOrTPHOrWildcardOrGeneric implements ISerializableData {
protected final JavaClassName name;
protected final List<RefTypeOrTPHOrWildcardOrGeneric> parameter;
/**
* Ist primitiveFlag auf true, muss beim Codegen dieser Reftype durch
* den primitiven Datentyp ersetzt werden
* <p>
* Bsp: java.lang.Integer mit Flag wird dann zu [int]
*/
boolean primitiveFlag = false; // TODO Should be final
public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
{
protected final JavaClassName name;
protected final List<RefTypeOrTPHOrWildcardOrGeneric> parameter;
/**
* Ist primitiveFlag auf true, muss beim Codegen dieser Reftype durch
* den primitiven Datentyp ersetzt werden
*
* Bsp: java.lang.Integer mit Flag wird dann zu [int]
*/
boolean primitiveFlag = false; // TODO Should be final
public RefType(JavaClassName fullyQualifiedName, Token offset) {
this(fullyQualifiedName, new ArrayList<>(), offset);
}
public boolean isPrimitive() {
return primitiveFlag;
}
@Override
public String toString() {
String params = "";
if (parameter.size() > 0) {
params += "<";
Iterator<RefTypeOrTPHOrWildcardOrGeneric> it = parameter.iterator();
while (it.hasNext()) {
RefTypeOrTPHOrWildcardOrGeneric param = it.next();
params += param.toString();
if (it.hasNext()) params += ", ";
}
params += ">";
}
return this.name.toString() + params;
}
@Override
public int hashCode() {
return this.name.hashCode();//Nur den Name hashen. Sorgt für langsame, aber funktionierende HashMaps
}
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset) {
this(fullyQualifiedName, parameter, offset, false);
}
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset, boolean primitiveFlag) {
super(offset);
this.name = (fullyQualifiedName);
this.parameter = parameter;
this.primitiveFlag = primitiveFlag;
}
public JavaClassName getName() {
return name;
}
public List<RefTypeOrTPHOrWildcardOrGeneric> getParaList() {
if (this.parameter == null) return new ArrayList<>();
return this.parameter;
}
/**
* Author: Jrg Buerle<br/>
*
* @return
*/
public boolean equals(Object obj) {
if (!(obj instanceof RefType refObj)) {
return false;
public RefType(JavaClassName fullyQualifiedName, Token offset)
{
this(fullyQualifiedName, new ArrayList<>(), offset);
}
if (!Objects.equals(this.name, refObj.name)) return false;
boolean ret = true;
public boolean isPrimitive() {
return primitiveFlag;
}
//if(!(super.equals(obj))) PL 2020-03-12 muss vll. einkommentiert werden
// return false;
if (parameter == null || parameter.size() == 0) {
ret &= (refObj.getParaList() == null || refObj.getParaList().isEmpty());
} else {
if (refObj.getParaList() == null) {
ret = false;
} else if (parameter.size() != refObj.getParaList().size()) {
ret = false;
} else {
for (int i = 0; i < parameter.size(); i++) {
ret &= parameter.get(i).equals(refObj.getParaList().get(i));
@Override
public String toString(){
String params = "";
if(parameter.size()>0){
params += "<";
Iterator<RefTypeOrTPHOrWildcardOrGeneric> it = parameter.iterator();
while(it.hasNext()){
RefTypeOrTPHOrWildcardOrGeneric param = it.next();
params += param.toString();
if(it.hasNext())params += ", ";
}
params += ">";
}
}
return this.name.toString() + params;
}
return ret;
}
@Override
public int hashCode() {
return this.name.hashCode();//Nur den Name hashen. Sorgt für langsame, aber funktionierende HashMaps
}
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset) {
this(fullyQualifiedName, parameter, offset, false);
}
@Override
public void accept(ASTVisitor visitor) {
visitor.visit(this);
}
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset, boolean primitiveFlag) {
super(offset);
this.name = (fullyQualifiedName);
this.parameter = parameter;
this.primitiveFlag = primitiveFlag;
}
@Override
public <A> A acceptTV(TypeVisitor<A> visitor) {
return visitor.visit(this);
}
public JavaClassName getName()
{
return name;
}
@Override
public void accept(ResultSetVisitor visitor) {
visitor.visit(this);
}
public List<RefTypeOrTPHOrWildcardOrGeneric> getParaList(){
if(this.parameter==null)return new ArrayList<>();
return this.parameter;
}
@Override
public ISerialNode toSerial(KeyStorage keyStorage) {
SerialMap serialized = new SerialMap();
serialized.put("isPrimitive", this.primitiveFlag);
serialized.put("name", this.name.toString());
serialized.put("parameters", SerialList.fromMapped(this.parameter, param -> param.toSerial(keyStorage)));
/**
* Author: Jrg Buerle<br/>
* @return
*/
public boolean equals(Object obj)
{
if(obj instanceof RefType){
if (!Objects.equals(this.name, ((RefType) obj).name)) return false;
boolean ret = true;
//if(!(super.equals(obj))) PL 2020-03-12 muss vll. einkommentiert werden
// return false;
if(parameter==null || parameter.size()==0){
ret &= (((RefType)obj).getParaList()==null || ((RefType)obj).getParaList().size()==0);
}
else{
if(((RefType)obj).getParaList()==null){
ret = false;
}
else if(parameter.size() != ((RefType)obj).getParaList().size())
{
ret = false;
}
else
{
for(int i = 0; i<parameter.size(); i++)
{
ret &= parameter.get(i).equals(((RefType)obj).getParaList().get(i));
}
}
}
return ret;
}
else{
return false;
}
}
// create the wrapper and put this as the object
var serializedWrapper = super.toSerial(keyStorage).assertType(SerialMap.class);
serializedWrapper.put("object", serialized);
return serializedWrapper;
}
@Override
public void accept(ASTVisitor visitor) {
visitor.visit(this);
}
public static RefType fromSerial(SerialMap data, UnifyContext context) {
return new RefType(
new JavaClassName(data.getValue("name").getOf(String.class)),
data.getList("parameters").assertListOfMaps().stream()
.map(param -> RefTypeOrTPHOrWildcardOrGeneric.fromSerial(param, context))
.toList(),
new NullToken(),
data.getValue("isPrimitive").getOf(Boolean.class)
);
}
@Override
public <A> A acceptTV(TypeVisitor<A> visitor) {
return visitor.visit(this);
}
@Override
public void accept(ResultSetVisitor visitor) {
visitor.visit(this);
}
}

View File

@@ -1,17 +1,11 @@
package de.dhbwstuttgart.syntaxtree.type;
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialValue;
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import org.antlr.v4.runtime.Token;
public abstract class RefTypeOrTPHOrWildcardOrGeneric extends SyntaxTreeNode implements ISerializableData {
public abstract class RefTypeOrTPHOrWildcardOrGeneric extends SyntaxTreeNode{
public RefTypeOrTPHOrWildcardOrGeneric(Token offset) {
super(offset);
}
@@ -24,26 +18,5 @@ public abstract class RefTypeOrTPHOrWildcardOrGeneric extends SyntaxTreeNode imp
@Override
public abstract boolean equals(Object o);
@Override
public ISerialNode toSerial(KeyStorage keyStorage) {
SerialMap serialized = new SerialMap();
serialized.put("type", this.getClass().getSimpleName());
// we only insert null for the object and expect the child classes to call this and override the value with themselves
serialized.put("object", SerialValue.NULL);
return serialized;
}
public static RefTypeOrTPHOrWildcardOrGeneric fromSerial(SerialMap data, UnifyContext context) {
String type = data.getValue("type").getOf(String.class);
SerialMap object = data.getMap("object");
if (type.equals(ExtendsWildcardType.class.getSimpleName())) return ExtendsWildcardType.fromSerial(object, context);
else if (type.equals(GenericRefType.class.getSimpleName())) return GenericRefType.fromSerial(object, context);
else if (type.equals(SuperWildcardType.class.getSimpleName())) return SuperWildcardType.fromSerial(object, context);
else if (type.equals(RefType.class.getSimpleName())) return RefType.fromSerial(object, context);
else if (type.equals(Void.class.getSimpleName())) return Void.fromSerial(object, context);
else if (type.equals(TypePlaceholder.class.getSimpleName())) return TypePlaceholder.fromSerial(object, context);
else throw new RuntimeException("Could not unserialize class of unhandled type " + type);
}
}

View File

@@ -1,13 +1,9 @@
package de.dhbwstuttgart.syntaxtree.type;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import org.antlr.v4.runtime.Token;
import java.util.Objects;
@@ -20,7 +16,7 @@ import java.util.Objects;
*
*/
public class SuperWildcardType extends WildcardType implements ISerializableData {
public class SuperWildcardType extends WildcardType{
/**
* Author: Arne Lüdtke<br/>
@@ -84,22 +80,4 @@ public class SuperWildcardType extends WildcardType implements ISerializableData
SuperWildcardType that = (SuperWildcardType) o;
return that.innerType.equals(this.innerType);
}
@Override
public SerialMap toSerial(KeyStorage keyStorage) {
SerialMap serialized = new SerialMap();
serialized.put("innerType", this.innerType.toSerial(keyStorage));
// create the wrapper and put this as the object
var serializedWrapper = super.toSerial(keyStorage).assertType(SerialMap.class);
serializedWrapper.put("object", serialized);
return serializedWrapper;
}
public static SuperWildcardType fromSerial(SerialMap data, UnifyContext context) {
return new SuperWildcardType(
RefTypeOrTPHOrWildcardOrGeneric.fromSerial(data.getMap("innerType"), context),
new NullToken()
);
}
}

View File

@@ -1,12 +1,9 @@
package de.dhbwstuttgart.syntaxtree.type;
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import java.util.Hashtable;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
import org.antlr.v4.runtime.Token;
@@ -19,7 +16,7 @@ import org.antlr.v4.runtime.Token;
* @author J�rg B�uerle
* @version $Date: 2013/06/19 12:45:37 $
*/
public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric implements ISerializableData
public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
{
private final String name;
@@ -68,12 +65,7 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric implements
public static TypePlaceholder fresh(Token position){
return new TypePlaceholder(NameGenerator.makeNewName(), position, 0, true);
}
public static TypePlaceholder fresh(Token position, PlaceholderRegistry placeholderRegistry){
String newName = placeholderRegistry.generateFreshPlaceholderName();
return new TypePlaceholder(newName, position, 0, true);
}
public static TypePlaceholder fresh(Token position, int variance, boolean wildcardable){
return new TypePlaceholder(NameGenerator.makeNewName(), position, variance, wildcardable);
}
@@ -147,26 +139,4 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric implements
public Boolean getWildcardtable() {
return wildcardable;
}
@Override
public SerialMap toSerial(KeyStorage keyStorage) {
SerialMap serialized = new SerialMap();
serialized.put("name", this.name);
serialized.put("variance", this.variance);
serialized.put("wildcardable", this.wildcardable);
// create the wrapper and put this as the object
var serializedWrapper = super.toSerial(keyStorage).assertType(SerialMap.class);
serializedWrapper.put("object", serialized);
return serializedWrapper;
}
public static TypePlaceholder fromSerial(SerialMap data, UnifyContext context) {
return new TypePlaceholder(
data.getValue("name").getOf(String.class),
new NullToken(),
data.getValue("variance").getOf(Integer.class),
data.getValue("wildcardable").getOf(Boolean.class)
);
}
}

View File

@@ -1,32 +1,14 @@
package de.dhbwstuttgart.syntaxtree.type;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.parser.scope.JavaClassName;
public class Void extends RefType implements ISerializableData
public class Void extends RefType
{
public Void(Token offset) {
super(JavaClassName.Void, offset);
}
@Override
public ISerialNode toSerial(KeyStorage keyStorage) {
// create the wrapper and put this as the object
var serializedWrapper = super.toSerial(keyStorage).assertType(SerialMap.class);
serializedWrapper.put("object", new SerialMap());
return serializedWrapper;
}
public static Void fromSerial(SerialMap data, UnifyContext context) {
return new Void(new NullToken());
}
}

View File

@@ -1,8 +0,0 @@
package de.dhbwstuttgart.target;
import de.dhbwstuttgart.util.Logger;
public class Target {
public static Logger logger = new Logger("Target");
}

View File

@@ -1,4 +1,3 @@
package de.dhbwstuttgart.target.generate;
import de.dhbwstuttgart.bytecode.FunNGenerator;
@@ -14,7 +13,6 @@ import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
import de.dhbwstuttgart.syntaxtree.visual.OutputGenerator;
import de.dhbwstuttgart.target.Target;
import de.dhbwstuttgart.target.tree.*;
import de.dhbwstuttgart.target.tree.expression.*;
import de.dhbwstuttgart.target.tree.type.*;
@@ -345,10 +343,10 @@ public class ASTToTargetAST {
var result = r0.stream().map(l -> l.stream().toList()).toList();
Target.logger.info("============== OUTPUT ==============");
System.out.println("============== OUTPUT ==============");
for (var l : result) {
for (var m : l) Target.logger.info(m.name() + " " + m.getSignature());
Target.logger.info("");
for (var m : l) System.out.println(m.name() + " " + m.getSignature());
System.out.println();
}
return result;
}
@@ -847,6 +845,13 @@ public class ASTToTargetAST {
compiler.usedFunNSuperTypes.add(params.size());
var code = FunNGenerator.generateSuperBytecode(params.size() - 1, returnType != null ? 1 : 0);
var superClassName = FunNGenerator.getSuperClassName(params.size() - 1, returnType != null ? 1 : 0);
try {
compiler.classLoader.findClass(superClassName);
} catch (ClassNotFoundException e) {
try {
compiler.classLoader.loadClass(superClassName, code);
} catch (LinkageError ignored) {}
}
compiler.auxiliaries.put(superClassName, code);
}
FunNGenerator.GenericParameters gep = null;

View File

@@ -7,7 +7,6 @@ import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.target.Target;
import de.dhbwstuttgart.target.tree.type.TargetGenericType;
import de.dhbwstuttgart.target.tree.type.TargetType;
import de.dhbwstuttgart.typeinference.result.PairTPHEqualTPH;
@@ -141,17 +140,17 @@ public abstract class GenerateGenerics {
this.compiler = compiler;
for (var constraint : constraints.results) {
if (constraint instanceof PairTPHsmallerTPH p) {
Target.logger.info(p.left + " " + p.left.getVariance());
System.out.println(p.left + " " + p.left.getVariance());
simplifiedConstraints.add(new PairLT(new TPH(p.left), new TPH(p.right)));
} else if (constraint instanceof PairTPHEqualTPH p) {
equality.put(p.getLeft(), p.getRight());
} else if (constraint instanceof PairTPHequalRefTypeOrWildcardType p) {
Target.logger.info(p.left + " = " + p.right);
System.out.println(p.left + " = " + p.right);
concreteTypes.put(new TPH(p.left), p.right);
}
}
Target.logger.info("Simplified constraints: " + simplifiedConstraints);
System.out.println("Simplified constraints: " + simplifiedConstraints);
}
/*public record GenericsState(Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes, Map<TypePlaceholder, TypePlaceholder> equality) {}
@@ -251,7 +250,7 @@ public abstract class GenerateGenerics {
equality.put(entry.getKey(), to);
}
}
Target.logger.info(from + " -> " + to + " " + from.getVariance());
System.out.println(from + " -> " + to + " " + from.getVariance());
//from.setVariance(to.getVariance());
equality.put(from, to);
referenced.remove(new TPH(from));
@@ -320,7 +319,7 @@ public abstract class GenerateGenerics {
Set<TPH> T2s = new HashSet<>();
findTphs(superType, T2s);
Target.logger.info("T1s: " + T1s + " T2s: " + T2s);
System.out.println("T1s: " + T1s + " T2s: " + T2s);
//Ende
superType = methodCall.receiverType;
@@ -335,7 +334,7 @@ public abstract class GenerateGenerics {
var optMethod = ASTToTargetAST.findMethod(owner, methodCall.name, methodCall.signatureArguments().stream().map(x -> getTargetType(x)).toList(), GenerateGenerics.this, compiler);
if (optMethod.isEmpty()) return;
var method2 = optMethod.get();
Target.logger.info("In: " + method.getName() + " Method: " + method2.getName());
System.out.println("In: " + method.getName() + " Method: " + method2.getName());
var generics = family(owner, method2);
// transitive and
@@ -368,7 +367,7 @@ public abstract class GenerateGenerics {
if (!T1s.contains(R1) || !T2s.contains(R2)) continue;
var newPair = new PairLT(R1, R2);
Target.logger.info("New pair: " + newPair);
System.out.println("New pair: " + newPair);
newPairs.add(newPair);
if (!containsRelation(result, newPair))
@@ -570,7 +569,7 @@ public abstract class GenerateGenerics {
Set<Pair> generics(ClassOrInterface owner, Method method) {
if (computedGenericsOfMethods.containsKey(method)) {
var cached = computedGenericsOfMethods.get(method);
Target.logger.info("Cached " + method.getName() + ": " + cached);
System.out.println("Cached " + method.getName() + ": " + cached);
return cached;
}
@@ -599,7 +598,7 @@ public abstract class GenerateGenerics {
normalize(result, classGenerics, usedTphs);
Target.logger.info(this.getClass().getSimpleName() + " " + method.name + ": " + result);
System.out.println(this.getClass().getSimpleName() + " " + method.name + ": " + result);
return result;
}
@@ -678,7 +677,7 @@ public abstract class GenerateGenerics {
normalize(javaResult, null, referencedByClass);
Target.logger.info(this.getClass().getSimpleName() + " Class " + classOrInterface.getClassName().getClassName() + ": " + javaResult);
System.out.println(this.getClass().getSimpleName() + " Class " + classOrInterface.getClassName().getClassName() + ": " + javaResult);
return javaResult;
}
@@ -729,7 +728,7 @@ public abstract class GenerateGenerics {
if (!added) break;
}
Target.logger.info(chain + " " + chain.stream().map(e -> e.resolve().getVariance()).toList());
System.out.println(chain + " " + chain.stream().map(e -> e.resolve().getVariance()).toList());
var variance = chain.get(0).resolve().getVariance();
if (variance != 1) continue;
var index = 0;
@@ -924,7 +923,7 @@ public abstract class GenerateGenerics {
for (var pair : infima) {
var returnTypes = findTypeVariables(method.getReturnType());
var chain = findConnectionToReturnType(returnTypes, input, new HashSet<>(), pair.left);
Target.logger.info("Find: " + pair.left + " " + chain);
System.out.println("Find: " + pair.left + " " + chain);
chain.remove(pair.left);
if (chain.size() > 0) {
for (var tph : chain)
@@ -962,8 +961,8 @@ public abstract class GenerateGenerics {
}
}
newTph.setVariance(variance);
Target.logger.info(infima + " " + infima.stream().map(i -> i.right.resolve().getVariance()).toList());
Target.logger.info("Infima new TPH " + newTph + " variance " + variance);
System.out.println(infima + " " + infima.stream().map(i -> i.right.resolve().getVariance()).toList());
System.out.println("Infima new TPH " + newTph + " variance " + variance);
//referenced.add(newTph);
addToPairs(input, new PairLT(left, new TPH(newTph)));

Some files were not shown because too many files have changed in this diff Show More