Compare commits

..

4 Commits

Author SHA1 Message Date
Fabian Holzwarth
1af31e4513 feat: update parallelization for 0variance 2025-08-04 13:41:17 +02:00
Fabian Holzwarth
5b06f0a249 Merge branch 'feat/unify-server' into feat/unify-server-0variance 2025-07-21 16:27:55 +02:00
Fabian Holzwarth
512b10542e feat: adjusted parallelization 2025-07-21 15:41:04 +02:00
Fabian Holzwarth
3b1185d9d0 feat: paralellize 0-variance cases 2025-07-20 15:06:50 +02:00
118 changed files with 2589 additions and 3520 deletions

View File

@@ -1,8 +1,5 @@
name: Build and Test with Maven name: Build and Test with Maven
on: on: [push]
push:
branches-ignore:
- master
jobs: jobs:
Build-and-test-with-Maven: Build-and-test-with-Maven:
@@ -18,11 +15,11 @@ jobs:
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: '25' java-version: '23'
cache: 'maven' cache: 'maven'
- name: Compile project - name: Compile project
run: | run: |
mvn compile mvn compile
- name: Run tests - name: Run tests
run: | run: |
mvn test mvn test

View File

@@ -1,45 +0,0 @@
on:
push:
branches:
- master
pull_request:
types: [opened, synchronize, reopened]
name: SonarQube Scan
jobs:
sonarqube:
name: SonarQube Trigger
runs-on: ubuntu-latest
steps:
- name: Checking out
uses: actions/checkout@v4
with:
# Disabling shallow clone is recommended for improving relevancy of reporting
fetch-depth: 0
- name: Install maven
run: |
apt update
apt install -y maven
- name: Install java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '25'
cache: 'maven'
- name: Compile project
run: |
mvn clean dependency:copy-dependencies verify
- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@v5.3.0
env:
SONAR_HOST_URL: ${{ secrets.SONARQUBE_HOST }}
SONAR_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
with:
args: >
-Dsonar.projectKey=Java-TX
-Dsonar.sources=src/main/java
-Dsonar.tests=src/test/java
-Dsonar.junit.reportPaths=target/test-reports
-Dsonar.java.binaries=target/classes
-Dsonar.java.libraries=target/dependency/*.jar
-Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml

View File

@@ -1,7 +0,0 @@
## Java-TX Compiler
[![Lines of Code](https://gitea.hb.dhbw-stuttgart.de/sonarqube/api/project_badges/measure?project=Java-TX&metric=ncloc&token=sqb_d4a372fca7a6b86441243728a6ea5f88183db5eb)](https://gitea.hb.dhbw-stuttgart.de/sonarqube/dashboard?id=Java-TX)
[![Coverage](https://gitea.hb.dhbw-stuttgart.de/sonarqube/api/project_badges/measure?project=Java-TX&metric=coverage&token=sqb_d4a372fca7a6b86441243728a6ea5f88183db5eb)](https://gitea.hb.dhbw-stuttgart.de/sonarqube/dashboard?id=Java-TX)
[![Quality Gate Status](https://gitea.hb.dhbw-stuttgart.de/sonarqube/api/project_badges/measure?project=Java-TX&metric=alert_status&token=sqb_d4a372fca7a6b86441243728a6ea5f88183db5eb)](https://gitea.hb.dhbw-stuttgart.de/sonarqube/dashboard?id=Java-TX)
Work in Progress Java-TX Compiler repository!

55
pom.xml
View File

@@ -12,37 +12,37 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<url>http://maven.apache.org</url> <url>http://maven.apache.org</url>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>junit</groupId>
<artifactId>junit-jupiter-api</artifactId> <artifactId>junit</artifactId>
<version>5.13.2</version> <version>4.13.2</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.antlr/antlr4 --> <!-- https://mvnrepository.com/artifact/org.antlr/antlr4 -->
<dependency> <dependency>
<groupId>org.antlr</groupId> <groupId>org.antlr</groupId>
<artifactId>antlr4</artifactId> <artifactId>antlr4</artifactId>
<version>4.13.2</version> <version>4.11.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>commons-io</groupId> <groupId>commons-io</groupId>
<artifactId>commons-io</artifactId> <artifactId>commons-io</artifactId>
<version>2.19.0</version> <version>2.16.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.github.classgraph</groupId> <groupId>io.github.classgraph</groupId>
<artifactId>classgraph</artifactId> <artifactId>classgraph</artifactId>
<version>4.8.180</version> <version>4.8.172</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
<version>33.4.8-jre</version> <version>33.2.0-jre</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.ow2.asm/asm --> <!-- https://mvnrepository.com/artifact/org.ow2.asm/asm -->
<dependency> <dependency>
<groupId>org.ow2.asm</groupId> <groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId> <artifactId>asm</artifactId>
<version>9.8</version> <version>9.5</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.java-websocket</groupId> <groupId>org.java-websocket</groupId>
@@ -64,51 +64,28 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<artifactId>JColor</artifactId> <artifactId>JColor</artifactId>
<version>5.5.1</version> <version>5.5.1</version>
</dependency> </dependency>
<dependency>
<groupId>org.jcommander</groupId>
<artifactId>jcommander</artifactId>
<version>3.0</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.13</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.14.0</version> <version>3.11.0</version>
<configuration> <configuration>
<source>25</source> <compilerArgs>--enable-preview</compilerArgs>
<target>25</target> <source>23</source>
<target>23</target>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>3.5.3</version> <version>3.1.0</version>
<configuration> <configuration>
<redirectTestOutputToFile>true</redirectTestOutputToFile> <redirectTestOutputToFile>true</redirectTestOutputToFile>
<reportsDirectory>${project.build.directory}/test-reports</reportsDirectory> <reportsDirectory>${project.build.directory}/test-reports</reportsDirectory>
<argLine>${argLine} --enable-preview</argLine> <argLine>--enable-preview</argLine>
<trimStackTrace>false</trimStackTrace> <trimStackTrace>false</trimStackTrace>
<excludes> <excludes>
<exclude>**/JavaTXCompilerTest.java</exclude> <exclude>**/JavaTXCompilerTest.java</exclude>
@@ -120,7 +97,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<plugin> <plugin>
<groupId>org.antlr</groupId> <groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId> <artifactId>antlr4-maven-plugin</artifactId>
<version>4.13.2</version> <version>4.11.1</version>
<executions> <executions>
<execution> <execution>
<id>antlr</id> <id>antlr</id>
@@ -133,7 +110,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId> <artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version> <version>3.3.0</version>
<configuration> <configuration>
<archive> <archive>
<manifest> <manifest>

View File

@@ -0,0 +1,51 @@
class C1 {
C1 self() {
return this;
}
}
class C2 {
C2 self() {
return this;
}
}
class Example {
untypedMethod(var) {
return var.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self();
}
}

View File

@@ -0,0 +1,43 @@
import java.lang.Integer;
import java.lang.Boolean;
import java.util.Queue;
import java.util.Vector;
import java.util.List;
import java.util.ArrayDeque;
class Pos {
public Integer x;
public Integer y;
public Pos(Integer x, Integer y) {
this.x = x;
this.y = y;
}
}
class GridSearch {
Pos search(Vector<Vector<Boolean>> grid) {
var w = grid.size();
var h = grid.getFirst().size();
// keep a queue on which cells to check
var cellQueue = new ArrayDeque<Pos>();
cellQueue.add(new Pos(0,0));
while (!cellQueue.isEmpty()) {
var pos = cellQueue.poll();
// if the target was found: return the position
var value = grid.get(pos.x).get(pos.y);
if (value) {
return pos;
}
// keep searching on neighboring tiles
if (pos.x < w-1) cellQueue.add(new Pos(pos.x + 1, pos.y));
if (pos.y < h-1) cellQueue.add(new Pos(pos.x, pos.y + 1));
}
return (Pos)null;
}
}

View File

@@ -0,0 +1,42 @@
import java.util.List;
import java.util.AbstractList;
import java.util.Vector;
import java.lang.Integer;
class Pixel {
public color;
}
class Mask {
mask;
Mask(mask) {
this.mask = mask;
}
apply(pixels) {
var w = mask.size();
var h = mask.get(0).size();
var imgW = pixels.size();
var imgH = pixels.get(0).size();
for (var x = 0; x < imgW - w; x++) {
for (var y = 0; y < imgH - h; y++) {
var total = 0;
for (var xd = 0; xd < w; xd++) {
for (var yd = 0; yd < h; yd++) {
var p = pixels.get(x + xd).get(y + yd);
var m = mask.get(xd).get(yd);
total = total + (p.color * m);
}
}
pixels.get(x).get(y).color = total;
}
}
return pixels;
}
}

View File

@@ -0,0 +1,39 @@
import java.lang.Integer;
import java.lang.Boolean;
import java.util.ArrayList;
import java.util.HashMap;
public class PascalsTriangle {
create(n) {
var rows = new ArrayList<ArrayList<Integer>>();
var evens = new ArrayList<ArrayList<Boolean>>();
if (n <= 0) return rows;
// first row
rows.add(new ArrayList<Integer>(1));
evens.add(new ArrayList<Boolean>(false));
for (int y = 1; y < n; y++) {
var row = new ArrayList<Integer>();
var evensRow = new ArrayList<Boolean>();
row.add(1);
evensRow.add(false);
for (int x = 1; x < y-1; x++) {
int tl = rows.getLast().get(x-1);
int tr = rows.getLast().get(x);
row.add(tl + tr);
evensRow.add(((tl + tr) % 2) == 1);
}
row.add(1);
rows.add(row);
evensRow.add(false);
evens.add(evensRow);
}
return rows;
}
}

View File

@@ -6,7 +6,7 @@ import java.util.stream.Stream;
public class Bug325 { public class Bug325 {
public main() { public main() {
var list = new ArrayList<>(List.of(1,2,3,4,5)); List<Integer> list = new ArrayList<>(List.of(1,2,3,4,5));
var func = x -> x*2; var func = x -> x*2;
return list.stream().map(func).toList(); return list.stream().map(func).toList();
} }

View File

@@ -1,22 +0,0 @@
import java.lang.String;
public class Bug363 {
uncurry (f){
return x -> f.apply(x);
}
uncurry (f){
return (x, y) -> f.apply(x).apply(y);
}
uncurry (f){
return (x, y, z) -> f.apply(x).apply(y).apply(z);
}
public test(){
var f = x -> y -> z -> x + y + z;
var g = uncurry(f);
return g.apply("A", "B", "C"); // Outputs: 6
}
}

View File

@@ -1,8 +0,0 @@
import java.lang.String;
public class Bug364{
public main(){
var f = x -> y -> z -> x + y + z;
return f.apply("A").apply("B").apply("C");
}
}

View File

@@ -1,21 +0,0 @@
import java.lang.String;
import java.lang.Object;
public class Bug365{
swap(f){
return x -> y -> f.apply(y).apply(x);
}
swap(Fun1$$<String, Fun1$$<String, Fun1$$<String, Object>>> f){
return x -> y -> z -> f.apply(z).apply(y).apply(x);
}
public ex1() {
var func = x -> y -> z -> x + y + z;
return func.apply("A").apply("B").apply("C");
}
public ex2() {
var func = x -> y -> z -> x + y + z;
return swap(func).apply("A").apply("B").apply("C");
}
}

View File

@@ -1,12 +0,0 @@
import java.lang.Integer;
public class Bug366 {
public static lambda() {
return (a, b) -> a + b;
}
public static test() {
var l = lambda();
return l.apply(10, 20);
}
}

View File

@@ -1,10 +0,0 @@
import java.lang.Boolean;
public class Bug371 {
static m1(x, y) { return x || y; }
static m2(x, y) { return x && y; }
public static test() {
return m2(m1(true, false), true);
}
}

View File

@@ -1,17 +0,0 @@
import java.lang.Boolean;
import java.lang.Integer;
import java.lang.System;
import java.io.PrintStream;
import java.lang.Character;
public class Bug373 {
public static main() {
System.out.println(true);
System.out.println(false);
System.out.println(1);
System.out.println(1l);
System.out.println(1.0);
System.out.println(1.0f);
System.out.println('a');
}
}

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

@@ -1,8 +0,0 @@
import java.lang.Math;
import java.lang.Double;
public class Bug390 {
public static main(args) {
var pi = Math.PI;
}
}

View File

@@ -0,0 +1,16 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.lang.String;
import java.util.stream.Stream;
import java.util.function.Function;
import java.util.function.Predicate;
import java.lang.Integer;
class BugXXX {
public main() {
List<Integer> i = new ArrayList<>(List.of(1,2,3,4,5,6,7,8,9,10));
Optional<Integer> tmp = i.stream().filter(x -> x == 5).map(x -> x*2).findFirst();
return tmp;
}
}

View File

@@ -1,14 +0,0 @@
import java.lang.Object;
import java.lang.System;
import java.lang.Iterable;
import java.io.PrintStream;
import java.util.List;
import java.lang.String;
class Main {
static main(args) {
for (var arg : args) {
System.out.println(arg);
}
}
}

View File

@@ -4,7 +4,7 @@ import java.lang.Integer;
import java.lang.Boolean; import java.lang.Boolean;
public class MatrixOP extends Vector<Vector<Integer>> { public class MatrixOP extends Vector<Vector<Integer>> {
MatrixOP () { MatrixOP () {
} }
@@ -36,8 +36,8 @@ public class MatrixOP extends Vector<Vector<Integer>> {
v2.addElement(erg); v2.addElement(erg);
j++; } j++; }
ret.addElement(v2); ret.addElement(v2);
i++; i++;
} }
return ret; return ret;
}; };
} }

View File

@@ -0,0 +1,17 @@
import java.util.List;
import java.lang.Integer;
//import java.util.Collection;
public class Merge2 {
public merge(a, b) {
a.addAll(b);
return a;
}
public sort(in){
var firstHalf = in.subList(1,2);
return merge(sort(firstHalf), sort(in));
}
}

View File

@@ -4,10 +4,16 @@ import java.lang.Double;
import java.util.Vector; import java.util.Vector;
import java.lang.Boolean; import java.lang.Boolean;
public class OLFun { public class OLFun {
m(f) {
var x; //f = x -> {return x + x;};
x = f.apply(x + x); m(f, x) {
return x; x = f.apply(x+x);
} return x;
}
m2(y) {
m(x -> x * 2, y);
return;
}
} }

View File

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

View File

@@ -1,25 +0,0 @@
sealed interface List<T> permits Cons, Empty {}
public record Cons<T>(T a, List<T> l) implements List<T> {}
public record Empty<T>() implements List<T> {}
public record Tuple<T1, T2>(T1 a, T2 b) {}
public class PatternMatching {
public zip(Cons(x, xs), Cons(y, ys)) {
return new Cons(new Tuple(x, y), zip(xs, ys));
}
public zip(Empty x, Empty y) { return new Empty(); }
/*public zip(Empty x, Cons y) { return new Empty(); }
public zip(Cons x, Empty y) { return new Empty(); }
public zip(Empty x, Empty y) { return new Empty(); }
*/
/*
Generiert:
Cons zip<T>(Cons(T x, Cons xs), Cons(T y, Cons ys))
Cons zip<T>(Cons(T x, Cons xs), Cons(T y, Empty ys))
Cons zip<T>(Cons(T x, Empty xs), Cons(T y, Cons ys))
Cons zip<T>(Cons(T x, Empty xs), Cons(T y, Empty ys))
*/
}

View File

@@ -1,19 +0,0 @@
import java.lang.Object;
import List;
import Cons;
import Empty;
import Tuple;
public class PatternMatchingJava {
public zip(a, b) {
switch (a) {
case Cons(x, Cons xs) -> {
switch (b) {
case Cons(y, Cons ys) -> { return new Cons<>(new Tuple<>(x, y), zip(xs, ys)); }
case Cons(y, Empty()) -> { return new Empty<>(); }
};
}
case Cons(x, Empty()) -> { return new Empty<>(); }
};
}
}

View File

@@ -1,5 +0,0 @@
sealed interface List<T> permits Cons, Empty {}
public record Cons<T>(T a, List<T> l) implements List<T> {}
public record Empty<T>() implements List<T> {}
public record Tuple<T1, T2>(T1 a, T2 b) {}

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -39,10 +39,6 @@ public class FunNGenerator {
public final List<TargetType> inParams; public final List<TargetType> inParams;
public final List<TargetType> realParams; public final List<TargetType> realParams;
public GenericParameters(TargetFunNType funNType) {
this(funNType.funNParams(), funNType.returnArguments());
}
public GenericParameters(List<TargetType> params, int numReturns) { public GenericParameters(List<TargetType> params, int numReturns) {
this.realParams = params; this.realParams = params;
this.inParams = flattenTypeParams(params); this.inParams = flattenTypeParams(params);
@@ -75,7 +71,7 @@ public class FunNGenerator {
if (type == null) return VOID; if (type == null) return VOID;
var res = "L" + type.getInternalName(); var res = "L" + type.getInternalName();
if (type instanceof TargetSpecializedType a) { if (type instanceof TargetSpecializedType a) {
if (!a.params().isEmpty() && !(a.params().size() == 1 && a.params().getFirst() == null)) { if (a.params().size() > 0) {
res += "<"; res += "<";
for (var param : a.params()) { for (var param : a.params()) {
if (param instanceof TargetGenericType gp) { if (param instanceof TargetGenericType gp) {
@@ -98,7 +94,7 @@ public class FunNGenerator {
} }
private static String applySignature(TargetType a) { return a.toSignature(); } private static String applySignature(TargetType a) { return a.toSignature(); }
private static String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("%s", a.toDescriptor()); } private static String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("%s", applySignature(a)); }
public static String encodeType(TargetType type) { public static String encodeType(TargetType type) {
if (type == null) return VOID; if (type == null) return VOID;
@@ -115,12 +111,11 @@ public class FunNGenerator {
superFunNMethodSignature.append(String.format("T%s;", argumentGenericBase + currentParameter)); superFunNMethodSignature.append(String.format("T%s;", argumentGenericBase + currentParameter));
superFunNMethodDescriptor.append(objectSignature); superFunNMethodDescriptor.append(objectSignature);
} }
superFunNClassSignature.append(String.format("%s:%s>%s", returnGeneric, objectSignature, objectSignature));
if (numReturnTypes > 0) { if (numReturnTypes > 0) {
superFunNClassSignature.append(String.format("%s:%s>%s", returnGeneric, objectSignature, objectSignature));
superFunNMethodSignature.append(String.format(")T%s;", returnGeneric)); superFunNMethodSignature.append(String.format(")T%s;", returnGeneric));
superFunNMethodDescriptor.append(String.format(")%s", objectSignature)); superFunNMethodDescriptor.append(String.format(")%s", objectSignature));
} else { } else {
superFunNClassSignature = new StringBuilder(objectSignature);
superFunNMethodSignature.append(")V"); superFunNMethodSignature.append(")V");
superFunNMethodDescriptor.append(")V"); superFunNMethodDescriptor.append(")V");
} }

View File

@@ -1,83 +1,81 @@
package de.dhbwstuttgart.core; 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.server.SocketClient;
import de.dhbwstuttgart.util.Logger; import de.dhbwstuttgart.util.Logger;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.*; 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 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();
public static void main(String[] argv) throws IOException, ClassNotFoundException { /**
var args = new Args(); * Leave the argument configurations here for the rest of the code to read
var builder = JCommander.newBuilder().addObject(args).build(); */
builder.setProgramName("javatx"); public static Logger.LogLevel logLevel = Logger.LogLevel.ERROR;
try { public static boolean writeLogFiles = false;
builder.parse(argv); public static Optional<String> unifyServerUrl = Optional.empty();
if (args.help) {
builder.usage(); public static void main(String[] args) throws IOException, ClassNotFoundException {
return; List<File> input = new ArrayList<>();
} List<File> classpath = new ArrayList<>();
} catch (ParameterException e) { String outputPath = null;
System.err.println(e.getMessage()); Iterator<String> it = Arrays.asList(args).iterator();
System.err.println(); Optional<Integer> serverPort = Optional.empty();
builder.usage();
System.exit(1); 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\n" +
"\t[--server-mode <port>]\n" +
"\t[--unify-server <url>]\n" +
"\t[--write-logs]\n" +
"\t[-v|-vv-|-vvv]");
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 if (arg.equals("--server-mode")) {
serverPort = Optional.of(Integer.parseInt(it.next()));
} else if (arg.equals("--unify-server")) {
unifyServerUrl = Optional.of(it.next());
} else if (arg.equals("--write-logs")) {
ConsoleInterface.writeLogFiles = true;
} else if (arg.startsWith("-v")) {
logLevel = switch (arg) {
case "-v" -> Logger.LogLevel.WARNING;
case "-vv" -> Logger.LogLevel.INFO;
case "-vvv" -> Logger.LogLevel.DEBUG;
default -> throw new IllegalArgumentException("Argument " + arg + " is not a valid verbosity level");
};
} else {
input.add(new File(arg));
}
}
inferTogether = args.inferTogether; if (serverPort.isPresent()) {
unifyServerUrl = Optional.ofNullable(args.serverUrl); if (unifyServerUrl.isPresent()) throw new RuntimeException("Cannot use unifyServer when in server mode!");
writeLogFiles = args.writeLogs; JavaTXServer server = new JavaTXServer(serverPort.get());
switch (args.verbosity) { server.listen();
case 1 -> logLevel = Logger.LogLevel.WARNING; }
case 2 -> logLevel = Logger.LogLevel.INFO; else {
case 3 -> logLevel = Logger.LogLevel.DEBUG; JavaTXCompiler compiler = new JavaTXCompiler(input, classpath, outputPath != null ? new File(outputPath) : null);
default -> logLevel = Logger.LogLevel.ERROR; //compiler.typeInference();
} compiler.generateBytecode();
SocketClient.closeIfOpen();
}
}
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);
}
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, inferTogether);
compiler.generateBytecode();
SocketClient.closeIfOpen();
}
}
} }

View File

@@ -2,14 +2,11 @@
package de.dhbwstuttgart.core; package de.dhbwstuttgart.core;
import de.dhbwstuttgart.bytecode.Codegen; import de.dhbwstuttgart.bytecode.Codegen;
import de.dhbwstuttgart.bytecode.FunNGenerator;
import de.dhbwstuttgart.environment.CompilationEnvironment; import de.dhbwstuttgart.environment.CompilationEnvironment;
import de.dhbwstuttgart.environment.DirectoryClassLoader; import de.dhbwstuttgart.environment.DirectoryClassLoader;
import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.languageServerInterface.model.LanguageServerTransferObject;
import de.dhbwstuttgart.parser.JavaTXParser; import de.dhbwstuttgart.parser.JavaTXParser;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.antlr.Java17Parser;
import de.dhbwstuttgart.parser.scope.GenericsRegistry; import de.dhbwstuttgart.parser.scope.GenericsRegistry;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SourceFileContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.SourceFileContext;
@@ -27,6 +24,7 @@ import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.SourceFile; import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList; import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory; import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
@@ -64,7 +62,6 @@ import de.dhbwstuttgart.util.Logger;
import java.io.*; import java.io.*;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.nio.file.Path; import java.nio.file.Path;
import java.sql.Array;
import java.util.*; import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.function.Function; import java.util.function.Function;
@@ -77,13 +74,11 @@ public class JavaTXCompiler {
// do not use this in any code, that can be executed serverside! // do not use this in any code, that can be executed serverside!
public static PlaceholderRegistry defaultClientPlaceholderRegistry = new PlaceholderRegistry(); public static PlaceholderRegistry defaultClientPlaceholderRegistry = new PlaceholderRegistry();
public static Logger defaultLogger = new Logger(); public static Logger defaultLogger = new Logger();
private final boolean inferTogether;
// public static JavaTXCompiler INSTANCE; // public static JavaTXCompiler INSTANCE;
final CompilationEnvironment environment; final CompilationEnvironment environment;
Boolean resultmodel = true; Boolean resultmodel = true;
public final Map<File, SourceFile> sourceFiles = new HashMap<>(); public final Map<File, SourceFile> sourceFiles = new HashMap<>();
public final Set<JavaClassName> input = new HashSet<>();
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel(); public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
public final DirectoryClassLoader classLoader; public final DirectoryClassLoader classLoader;
@@ -91,28 +86,23 @@ public class JavaTXCompiler {
public final List<File> classPath; public final List<File> classPath;
private final File outputPath; private final File outputPath;
public final Map<String, FunNGenerator.GenericParameters> usedFunN = new HashMap<>();
public final Set<Integer> usedFunNSuperTypes = new HashSet<>();
private final Map<JavaClassName, ClassOrInterface> loadedClasses = new HashMap<>();
public Map<String, byte[]> auxiliaries = new HashMap<>();
public DirectoryClassLoader getClassLoader() { public DirectoryClassLoader getClassLoader() {
return classLoader; return classLoader;
} }
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException { public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
this(Collections.singletonList(sourceFile), List.of(), new File("."), ConsoleInterface.inferTogether); this(Collections.singletonList(sourceFile), List.of(), new File("."));
} }
public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException { public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException {
this(sourceFiles, List.of(), new File("."), ConsoleInterface.inferTogether); this(sourceFiles, List.of(), new File("."));
} }
public JavaTXCompiler(List<File> sources, List<File> contextPath, File outputPath, boolean inferTogether) throws IOException, ClassNotFoundException { public JavaTXCompiler(List<File> sources, List<File> contextPath, File outputPath) throws IOException, ClassNotFoundException {
// ensure new default placeholder registry for tests // ensure new default placeholder registry for tests
defaultClientPlaceholderRegistry = new PlaceholderRegistry(); defaultClientPlaceholderRegistry = new PlaceholderRegistry();
this.inferTogether = inferTogether; NameGenerator.reset();
ASTToTargetAST.OBJECT = ASTFactory.createObjectType();
var path = new ArrayList<>(contextPath); var path = new ArrayList<>(contextPath);
if (contextPath.isEmpty()) { if (contextPath.isEmpty()) {
@@ -120,43 +110,13 @@ public class JavaTXCompiler {
path.add(new File(System.getProperty("user.dir"))); path.add(new File(System.getProperty("user.dir")));
} }
if (outputPath != null) path.add(outputPath); if (outputPath != null) path.add(outputPath);
classLoader = new DirectoryClassLoader(path, ClassLoader.getSystemClassLoader().getParent()); classLoader = new DirectoryClassLoader(path, ClassLoader.getSystemClassLoader());
environment = new CompilationEnvironment(sources, classLoader); environment = new CompilationEnvironment(sources, classLoader);
classPath = path; classPath = path;
this.outputPath = outputPath; this.outputPath = outputPath;
// TODO This should maybe be moved elsewhere for (File s : sources) {
var treeList = new ArrayList<SourceFileContext>(sources.size()); parse(s);
for (var s : sources) {
var tree = (Java17Parser.SrcfileContext) JavaTXParser.parse(s);
treeList.add(tree);
// Find defined classes
var pkgName = tree.packageDeclaration() != null ? tree.packageDeclaration().qualifiedName().getText(): "";
for (var ctx : tree.classOrInterface()) {
if (ctx instanceof Java17Parser.NoclassorinterfaceContext) continue;
var classContext = (Java17Parser.ClassorinterfacedeclContext) ctx;
String name = null;
Java17Parser.GenericDeclarationListContext decl = null;
if (classContext.classDeclaration() != null) {
name = classContext.classDeclaration().identifier().getText();
decl = classContext.classDeclaration().genericDeclarationList();
} else if (classContext.recordDeclaration() != null) {
name = classContext.recordDeclaration().identifier().getText();
decl = classContext.recordDeclaration().genericDeclarationList();
} else if (classContext.interfaceDeclaration() != null) {
name = classContext.interfaceDeclaration().identifier().getText();
decl = classContext.interfaceDeclaration().genericDeclarationList();
}
var numberOfGenerics = decl == null ? 0 : decl.genericTypeVar().size();
var className = pkgName + (!pkgName.isEmpty() ? "." : "") + name;
classRegistry.addName(className, numberOfGenerics);
input.add(classRegistry.getName(className));
}
}
for (var i = 0; i < sources.size(); i++) {
parse(treeList.get(i), sources.get(i));
} }
// INSTANCE = this; // INSTANCE = this;
} }
@@ -166,26 +126,21 @@ public class JavaTXCompiler {
} }
public ClassOrInterface getClass(JavaClassName name) { public ClassOrInterface getClass(JavaClassName name) {
if (loadedClasses.containsKey(name)) return loadedClasses.get(name); if (loadedClasses.containsKey(name)) return loadedClasses.get(name).cif();
for (var sf : sourceFiles.values()) { for (var sf : sourceFiles.values()) {
for (var clazz : sf.KlassenVektor) { for (var clazz : sf.KlassenVektor) {
if (clazz.getClassName().equals(name)) return clazz; if (clazz.getClassName().equals(name)) return clazz;
} }
} }
if (input.contains(name)) return null;
try { try {
var clazz = classLoader.loadClass(name.toString()); var clazz = classLoader.loadClass(name.toString());
ClassOrInterface cif = null; if (clazz != null)
if (clazz != null) { return ASTFactory.createClass(clazz);
cif = ASTFactory.createClass(clazz);
loadedClasses.put(name, cif);
}
return cif;
} catch (ClassNotFoundException ignored) {} } catch (ClassNotFoundException ignored) {}
return null; 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(); Set<ClassOrInterface> allClasses = new HashSet<>();// environment.getAllAvailableClasses();
ClassOrInterface objectClass = ASTFactory.createClass(Object.class); ClassOrInterface objectClass = ASTFactory.createClass(Object.class);
var recordClass = ASTFactory.createClass(Record.class); var recordClass = ASTFactory.createClass(Record.class);
@@ -211,7 +166,7 @@ public class JavaTXCompiler {
for (var clazz : sf.availableClasses) { for (var clazz : sf.availableClasses) {
if (loadedClasses.containsKey(clazz.getClassName())) { if (loadedClasses.containsKey(clazz.getClassName())) {
allClasses.removeIf(cl -> cl.getClassName().equals(clazz.getClassName())); allClasses.removeIf(cl -> cl.getClassName().equals(clazz.getClassName()));
var cif = loadedClasses.get(clazz.getClassName()); var cif = loadedClasses.get(clazz.getClassName()).cif();
allClasses.add(cif); allClasses.add(cif);
isCached = true; isCached = true;
} }
@@ -224,13 +179,7 @@ public class JavaTXCompiler {
allClasses.addAll(sf.KlassenVektor); allClasses.addAll(sf.KlassenVektor);
return allClasses; TYPE ty = new TYPE(sf, 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);
var constraints = ty.getConstraints(); var constraints = ty.getConstraints();
return constraints; return constraints;
} }
@@ -250,9 +199,8 @@ public class JavaTXCompiler {
try { try {
var className = cl.getSuperClass().getName().toString(); var className = cl.getSuperClass().getName().toString();
superclass = ASTFactory.createClass(classLoader.loadClass(className)); superclass = ASTFactory.createClass(classLoader.loadClass(className));
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException ignored) {}
throw new RuntimeException(e); // throw new ClassNotFoundException("");
}
} }
} }
@@ -281,18 +229,13 @@ public class JavaTXCompiler {
private Set<ClassOrInterface> getAvailableClasses(JavaClassName name) throws ClassNotFoundException { private Set<ClassOrInterface> getAvailableClasses(JavaClassName name) throws ClassNotFoundException {
Set<ClassOrInterface> allClasses = new HashSet<>(); Set<ClassOrInterface> allClasses = new HashSet<>();
if (input.contains(name)) { var clazz = loadJavaTXClass(name);
for (var sf : sourceFiles.values()) { if (clazz == null) {
for (var cif : sf.KlassenVektor) { ClassOrInterface importedClass = ASTFactory.createClass(classLoader.loadClass(name.toString()));
if (cif.getClassName().equals(name)) { allClasses.add(importedClass);
allClasses.add(cif); } else {
return allClasses; allClasses.add(clazz);
}
}
}
} }
ClassOrInterface importedClass = ASTFactory.createClass(classLoader.loadClass(name.toString()));
allClasses.add(importedClass);
return allClasses; return allClasses;
} }
@@ -419,97 +362,25 @@ public class JavaTXCompiler {
} }
public List<ResultSet> typeInference(File file) throws ClassNotFoundException, IOException { public List<ResultSet> typeInference(File file) throws ClassNotFoundException, IOException {
return typeInference(List.of(file)); var sf = sourceFiles.get(file);
} Set<ClassOrInterface> allClasses = new HashSet<>();// environment.getAllAvailableClasses();
allClasses.addAll(getAvailableClasses(sf));
public static String constraintSetToDot(ConstraintSet<Pair> c){ allClasses.addAll(sf.getClasses());
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), file, this).stream().map(ASTFactory::createClass).collect(Collectors.toSet());
Iterator<String> colors = List.of( for (var clazz : newClasses) {
"#FF0000", "#FF7F00", "#FFFF00", "#7FFF00", "#00FF00", "#00FF7F", "#00FFFF", "#007FFF", // Don't load classes that get recompiled
"#0000FF", "#7F00FF", "#FF00FF", "#FF007F", "#BF0000", "#BF5F00", "#BFBF00", "#5FBF00", if (sf.getClasses().stream().anyMatch(nf -> nf.getClassName().equals(clazz.getClassName())))
"#00BF00", "#00BF5F", "#00BFBF", "#005FBF", "#0000BF", "#5F00BF", "#BF00BF", "#BF005F", continue;
"#800000", "#804000", "#808000", "#408000", "#008000", "#008040", "#008080", "#004080", if (allClasses.stream().noneMatch(old -> old.getClassName().equals(clazz.getClassName())))
"#000080", "#400080", "#800080", "#800040", "#FF4040", "#FF8040", "#FFFF40", "#80FF40", allClasses.add(clazz);
"#40FF40", "#40FF80", "#40FFFF", "#4080FF", "#4040FF", "#8040FF", "#FF40FF", "#FF4080",
"#BF4040", "#BF8040", "#BFBF40", "#80BF40", "#40BF40", "#40BF80", "#40BFBF", "#4080BF",
"#4040BF", "#8040BF", "#BF40BF", "#BF4080", "#FF8080", "#FFBF80", "#FFFF80", "#BFFF80",
"#80FF80", "#80FFBF", "#80FFFF", "#80BFFF", "#8080FF", "#BF80FF", "#FF80FF", "#FF80BF").iterator();
StringBuilder sb = new StringBuilder();
sb.append("diagraph G{");
//and constraints to dot
sb.append(c.getUndConstraints().stream().map(Pair::toDot).collect(Collectors.joining("\n")));
//or constraints to dot
for (var orConstSet : c.getOderConstraints()){
for(var cons : orConstSet){
String color = colors.next();
sb.append(cons.stream().map(x -> x.toDot(color)).collect(Collectors.joining("\n")));
}
} }
sb.append("}"); final ConstraintSet<Pair> cons = getConstraints(file);
return sb.toString();
}
public static String q(String s) {
return "\"" + s.replace("\"", "\\\"") + "\"";
}
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();
var ANDconstraints = cons.getUndConstraints();
var ORConstraints = cons.getOderConstraints();
var orIterator = ORConstraints.iterator();
while(orIterator.hasNext()){
Set<Constraint<Pair>> y = orIterator.next();
if (y.isEmpty()) orIterator.remove();
else if (y.size() == 1){
ANDconstraints.addAll(y.iterator().next()); // add the OR constraint to the AND constraint since we only have one option
orIterator.remove();
}
}
String dot = constraintSetToDot(cons);
ANDconstraints.forEach(System.out::println);
for (var orc : ORConstraints){
System.out.println();
System.out.println("------");
System.out.println();
for(var hashs : orc){
System.out.print(hashs);
System.out.print("\n | \n");
}
}
Set<Set<UnifyPair>> results = new HashSet<>(); Set<Set<UnifyPair>> results = new HashSet<>();
PlaceholderRegistry placeholderRegistry = new PlaceholderRegistry(); PlaceholderRegistry placeholderRegistry = new PlaceholderRegistry();
var logFolder = new File(System.getProperty("user.dir") + "/logFiles/"); 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); if (ConsoleInterface.writeLogFiles && !logFolder.mkdirs()) throw new RuntimeException("Could not creat directoy for log files: " + logFolder);
Writer logFile = ConsoleInterface.writeLogFiles ? new FileWriter(new File(logFolder, "log_" + sourceFiles.keySet().iterator().next().getName())) : new OutputStreamWriter(new NullOutputStream()); 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"); Logger logger = new Logger(logFile, "TypeInference");
@@ -527,175 +398,89 @@ public class JavaTXCompiler {
}; };
logger.debug("Unify:" + unifyCons.toString()); logger.debug("Unify:" + unifyCons.toString());
logger.info("Unify:" + unifyCons.toString()); logger.info("Unify:" + unifyCons.toString());
unifyCons = unifyCons.map(distributeInnerVars); unifyCons = unifyCons.map(distributeInnerVars);
logger.debug("\nUnify_distributeInnerVars: " + unifyCons.toString()); logger.debug("\nUnify_distributeInnerVars: " + unifyCons.toString());
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen // Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
logger.debug("FC:\\" + finiteClosure.toString() + "\n"); logger.debug("FC:\\" + finiteClosure.toString() + "\n");
for (var sf : ressf) logger.info(ASTTypePrinter.print(sf)); logger.debug(ASTTypePrinter.print(sf));
// logFile.flush(); logger.info(ASTTypePrinter.print(sf));
List<UnifyPair> andConstraintsSorted = unifyCons.getUndConstraints().stream() // logFile.flush();
.sorted(Comparator.comparing(UnifyPair::getPairOp).thenComparing(UnifyPair::getLhsType, Comparator.comparing(UnifyType::getName))) logger.info("Unify nach Oder-Constraints-Anpassung:" + unifyCons.toString());
.collect(Collectors.toList()); Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = new HashSet<>();
logger.info(andConstraintsSorted); varianceTPH = varianceInheritanceConstraintSet(unifyCons);
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 && * 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)); * ((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, // Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
// logFile, log); // logFile, log);
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure); // Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()// .stream().map(x -> { 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)) * 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 -> { if (ConsoleInterface.unifyServerUrl.isPresent()) {
Optional<Set<UnifyPair>> res = new RuleSet(placeholderRegistry).subst(x.stream().map(y -> { UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
if (y.getPairOp() == PairOperator.SMALLERDOTWC) UnifyContext context = new UnifyContext(logger, true, urm, usedTasks, placeholderRegistry);
y.setPairOp(PairOperator.EQUALSDOT); SocketFuture<UnifyResultPacket> future = SocketClient.execute(
return y; // alle Paare a <.? b erden durch a =. b ersetzt UnifyRequestPacket.create(finiteClosure, cons, unifyCons, context.placeholderRegistry())
}).collect(Collectors.toCollection(HashSet::new))); );
if (res.isPresent()) {// wenn subst ein Erg liefert wurde was veraendert SocketClient.execute(SetAutoclosePacket.create());
return new TypeUnifyTask(context).applyTypeUnificationRules(res.get(), finiteClosure); return future.get().getResultSet(context);
} else }
return x; // wenn nichts veraendert wurde wird x zurueckgegeben else if (resultmodel) {
}).collect(Collectors.toCollection(HashSet::new)); /* UnifyResultModel Anfang */
logger.info("RESULT Final: " + results); UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
logger.info("Constraints for Generated Generics: " + " ???"); UnifyResultListenerImpl li = new UnifyResultListenerImpl();
logger.debug("RES_FINAL: " + results.toString() + "\n"); urm.addUnifyResultListener(li);
// logFile.flush(); UnifyContext context = new UnifyContext(logger, true, urm, usedTasks, placeholderRegistry);
logger.debug("PLACEHOLDERS: " + placeholderRegistry); TypeUnify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
// logFile.flush(); logger.info("RESULT Final: " + li.getResults());
logger.info("Constraints for Generated Generics: " + " ???");
logFile.write("RES_FINAL: " + li.getResults().toString() + "\n");
// logFile.flush();
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);
logFile.write("RES: " + result.toString() + "\n");
// logFile.flush();
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()); 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<>();
allClasses.addAll(getAvailableClasses(sf));
allClasses.addAll(sf.getClasses());
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), file, this).stream().map(ASTFactory::createClass).collect(Collectors.toSet());
for (var clazz : newClasses) {
// Don't load classes that get recompiled
if (sf.getClasses().stream().anyMatch(nf -> nf.getClassName().equals(clazz.getClassName())))
continue;
if (allClasses.stream().noneMatch(old -> old.getClassName().equals(clazz.getClassName())))
allClasses.add(clazz);
}
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());
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;
};
unifyCons = unifyCons.map(distributeInnerVars);
Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = new HashSet<>();
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints();
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);
}
/* UnifyResultModel End */
else {
Set<Set<UnifyPair>> result = TypeUnify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
results.addAll(result);
results = results.stream().map(x -> {
Optional<Set<UnifyPair>> res = new RuleSet(context.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));
}
} catch (ClassNotFoundException e) {
}
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);
}
/** /**
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine Variance !=0 hat auf alle Typvariablen in Theta. * Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine Variance !=0 hat auf alle Typvariablen in Theta.
* *
@@ -753,36 +538,75 @@ public class JavaTXCompiler {
public final JavaClassRegistry classRegistry = new JavaClassRegistry(); public final JavaClassRegistry classRegistry = new JavaClassRegistry();
private void parse(SourceFileContext tree, File sourceFile) throws IOException, java.lang.ClassNotFoundException { public record ClassEntry(File classFile, ClassOrInterface cif) {}
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null), sourceFile.getName());
public final Map<JavaClassName, ClassEntry> loadedClasses = new HashMap<>();
private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException {
if (sourceFiles.containsKey(sourceFile)) return sourceFiles.get(sourceFile);
SourceFileContext tree = JavaTXParser.parse(sourceFile);
environment.addClassesToRegistry(classRegistry, tree, sourceFile, this); environment.addClassesToRegistry(classRegistry, tree, sourceFile, this);
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null), sourceFile.getName());
var classes = new ArrayList<ClassOrInterface>(); var classes = new ArrayList<ClassOrInterface>();
var sf = new SourceFile("", classes, generator.imports); var sf = new SourceFile("", classes, generator.imports);
addSourceFile(sourceFile, sf); addSourceFile(sourceFile, sf);
generator.convert(classes, tree, environment.packageCrawler); generator.convert(classes, tree, environment.packageCrawler);
sf.setPackageName(generator.pkgName); sf.setPackageName(generator.pkgName);
sf.imports.addAll(generator.imports); sf.imports.addAll(generator.imports);
return sf;
}
/**
* When an import tries to import a JavaTX class it first looks it up in the cache and
* if it doesn't exist it's going to compile it and add it to the source files list
* @param name
*/
public ClassOrInterface loadJavaTXClass(JavaClassName name) {
var file = findFileForClass(name);
if (file != null) {
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?
environment.addClassesToRegistry(classRegistry, tree, file, this);
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null), file.getName());
var classes = new ArrayList<ClassOrInterface>();
var sf = new SourceFile("", classes, generator.imports);
addSourceFile(file, sf);
generator.convert(classes, tree, environment.packageCrawler);
sf.setPackageName(generator.pkgName);
var classFiles = generateBytecode(file);
sf.setGenerated();
writeClassFile(classFiles, outputPath != null ? outputPath : new File("."), false);
var clazz = classLoader.loadClass(name.toString());
var classOrInterface = ASTFactory.createClass(clazz);
loadedClasses.put(name, new ClassEntry(new File(outputPath, clazz.getName() + ".class"), classOrInterface));
return classOrInterface;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return null;
}
public File findFileForClass(JavaClassName name) {
var packageName = name.getPackageName();
var className = name.getClassName().split("\\.")[0];
for (var cp : classPath) {
var file = new File(cp, packageName.replaceAll("\\.", "/") + "/" + className + ".jav");
if (file.exists()) return file;
}
return null;
} }
public void generateBytecode() throws ClassNotFoundException, IOException { public void generateBytecode() throws ClassNotFoundException, IOException {
if (inferTogether) { for (var file : sourceFiles.keySet()) {
var files = sourceFiles.keySet().stream().toList(); var sf = sourceFiles.get(file);
var typeinferenceResult = this.typeInference(files); if (sf.isGenerated()) continue;
for (var file : files) { var classes = generateBytecode(file);
var sf = sourceFiles.get(file); sf.setGenerated();
if (sf.isGenerated()) continue; writeClassFile(classes, outputPath == null ? file.getParentFile() : outputPath, outputPath == null);
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);
}
} }
} }
@@ -827,12 +651,12 @@ public class JavaTXCompiler {
var codegen = new Codegen(converter.convert(clazz), this, converter); var codegen = new Codegen(converter.convert(clazz), this, converter);
var code = codegen.generate(); var code = codegen.generate();
generatedClasses.put(clazz.getClassName(), code); generatedClasses.put(clazz.getClassName(), code);
converter.auxiliaries.forEach((name, source) -> {
generatedClasses.put(new JavaClassName(name), source);
});
} }
generatedGenerics.put(sf, converter.javaGenerics()); generatedGenerics.put(sf, converter.javaGenerics());
converter.generateFunNTypes(); converter.generateFunNTypes();
auxiliaries.forEach((name, source) -> {
generatedClasses.put(new JavaClassName(name), source);
});
return generatedClasses; return generatedClasses;
} }

View File

@@ -0,0 +1,13 @@
package de.dhbwstuttgart.environment;
public class ByteArrayClassLoader extends ClassLoader implements IByteArrayClassLoader {
@Override
public Class _defineClass(String name, byte[] code, int i, int length) throws ClassFormatError {
return defineClass(name, code, i, length);
}
@Override
public Class<?> findClass(String name) throws ClassNotFoundException {
return super.findClass(name);
}
}

View File

@@ -8,7 +8,6 @@ import java.util.*;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
@@ -31,7 +30,7 @@ public class CompilationEnvironment {
public final PackageCrawler packageCrawler; public final PackageCrawler packageCrawler;
/** /**
* Imitiert die Environment beim Aufruf des JavaCompilers auf einer Menge von java-Dateien Die Environment enthält automatisch die Java Standard Library * Imitiert die Environment beim Aufruf des JavaCompilers auf einer Menge von java-Dateien Die Environment enth<EFBFBD>lt automatisch die Java Standard Library
* *
* @param sourceFiles die zu kompilierenden Dateien * @param sourceFiles die zu kompilierenden Dateien
*/ */
@@ -88,8 +87,6 @@ public class CompilationEnvironment {
if (files != null) if (files != null)
for (File classFile : files) { for (File classFile : files) {
String className = classFile.getName().substring(0, classFile.getName().length() - 6); String className = classFile.getName().substring(0, classFile.getName().length() - 6);
// Don't load class if its defined in the input
if (compiler.input.contains(new JavaClassName(className))) continue;
if (className.matches("Fun\\d+\\$\\$.*")) if (className.matches("Fun\\d+\\$\\$.*"))
continue; continue;
var name = packageName; var name = packageName;

View File

@@ -16,7 +16,7 @@ public class DirectoryClassLoader extends URLClassLoader implements IByteArrayCl
// } // }
public DirectoryClassLoader(List<File> directory, java.lang.ClassLoader parent) { public DirectoryClassLoader(List<File> directory, java.lang.ClassLoader parent) {
super(directory.stream().map(DirectoryClassLoader::dirToURL).flatMap(List::stream).collect(Collectors.toList()).toArray(new URL[0]), parent); super(directory.stream().map(DirectoryClassLoader::dirToURL).flatMap(List::stream).collect(Collectors.toList()).toArray(new URL[0]), parent.getParent());
} }
private static URL[] generateURLArray(URL url) { private static URL[] generateURLArray(URL url) {

View File

@@ -6,22 +6,18 @@ import java.nio.file.Path;
public interface IByteArrayClassLoader { public interface IByteArrayClassLoader {
Class<?> loadClass(String path) throws ClassNotFoundException; Class loadClass(String path) throws ClassNotFoundException;
default Class<?> loadClass(byte[] code) { default Class loadClass(byte[] code) {
return this.loadClass(null, code); return this._defineClass(null, code, 0, code.length);
} }
default Class<?> loadClass(String name, byte[] code) { default Class loadClass(Path path) throws IOException {
return this._defineClass(name, code, 0, code.length);
}
default Class<?> loadClass(Path path) throws IOException {
var code = Files.readAllBytes(path); var code = Files.readAllBytes(path);
return this._defineClass(null, code, 0, code.length); return this._defineClass(null, code, 0, code.length);
} }
public Class<?> findClass(String name) throws ClassNotFoundException; public Class<?> findClass(String name) throws ClassNotFoundException;
Class<?> _defineClass(String name, byte[] code, int i, int length) throws ClassFormatError; Class _defineClass(String name, byte[] code, int i, int length) throws ClassFormatError;
} }

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(), false);
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(), false);
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

@@ -151,7 +151,7 @@ public class StatementGenerator {
} else { } else {
type = methodparameters? type = methodparameters?
TypePlaceholder.fresh(fp.getStart(), 1, false) TypePlaceholder.fresh(fp.getStart(), 1, false)
: TypePlaceholder.fresh(fp.getStart(), 1, false); : TypePlaceholder.fresh(fp.getStart());
} }
ret.add(new FormalParameter(paramName, type, fp.getStart())); ret.add(new FormalParameter(paramName, type, fp.getStart()));
localVars.put(paramName, type); localVars.put(paramName, type);
@@ -1066,7 +1066,7 @@ public class StatementGenerator {
List<Pattern> parameterList = new ArrayList<>(); List<Pattern> parameterList = new ArrayList<>();
for (IdentifierContext identifier : lambdaParams.identifier()) { for (IdentifierContext identifier : lambdaParams.identifier()) {
Token offset = identifier.getStart(); Token offset = identifier.getStart();
parameterList.add(new FormalParameter(identifier.getText(), TypePlaceholder.fresh(offset, 1, false), offset)); parameterList.add(new FormalParameter(identifier.getText(), TypePlaceholder.fresh(offset), offset));
} }
params = new ParameterList(parameterList, lambdaParams.getStart()); params = new ParameterList(parameterList, lambdaParams.getStart());
} else if (lambdaParams.formalParameterList() != null) { } else if (lambdaParams.formalParameterList() != null) {
@@ -1076,7 +1076,7 @@ public class StatementGenerator {
List<Pattern> parameterList = new ArrayList<>(); List<Pattern> parameterList = new ArrayList<>();
for (LambdaLVTIParameterContext param : lambdaParams.lambdaLVTIList().lambdaLVTIParameter()) { for (LambdaLVTIParameterContext param : lambdaParams.lambdaLVTIList().lambdaLVTIParameter()) {
Token offset = param.getStart(); Token offset = param.getStart();
parameterList.add(new FormalParameter(param.identifier().getText(), TypePlaceholder.fresh(offset, 1, false), offset)); parameterList.add(new FormalParameter(param.identifier().getText(), TypePlaceholder.fresh(offset), offset));
} }
params = new ParameterList(parameterList, lambdaParams.getStart()); params = new ParameterList(parameterList, lambdaParams.getStart());
} else { } else {
@@ -1100,9 +1100,9 @@ public class StatementGenerator {
block = lambdaGenerator.convert(expression.lambdaBody().block(), true); block = lambdaGenerator.convert(expression.lambdaBody().block(), true);
} }
List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>();
funNParams.add(TypePlaceholder.fresh(expression.getStart(), -1, false));// ret-Type funNParams.add(TypePlaceholder.fresh(expression.getStart()));// ret-Type
params.getFormalparalist().forEach(formalParameter -> // Für jeden Parameter einen TPH anfügen: params.getFormalparalist().forEach(formalParameter -> // Für jeden Parameter einen TPH anfügen:
funNParams.add(TypePlaceholder.fresh(expression.getStart(), 1, false))); funNParams.add(TypePlaceholder.fresh(expression.getStart())));
RefTypeOrTPHOrWildcardOrGeneric lambdaType = TypePlaceholder.fresh(expression.getStart()); RefTypeOrTPHOrWildcardOrGeneric lambdaType = TypePlaceholder.fresh(expression.getStart());
// RefType lambdaType = new // RefType lambdaType = new
// RefType(reg.getName("Fun"+params.getFormalparalist().size()), // RefType(reg.getName("Fun"+params.getFormalparalist().size()),

View File

@@ -111,7 +111,7 @@ public class SyntaxTreeGenerator {
this.allmodifiers.put(Modifier.toString(Modifier.INTERFACE), Modifier.INTERFACE); this.allmodifiers.put(Modifier.toString(Modifier.INTERFACE), Modifier.INTERFACE);
this.allmodifiers.put("sealed", 4096); this.allmodifiers.put("sealed", 4096);
this.allmodifiers.put("non-sealed", 8192); 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.allmodifiers.put("strictfp", 32768);
this.compiler = compiler; this.compiler = compiler;

View File

@@ -168,7 +168,7 @@ public class TypeGenerator {
if (generics.contains(name)) { if (generics.contains(name)) {
return new GenericRefType(name, offset); return new GenericRefType(name, offset);
} else { } else {
Pattern p = Pattern.compile("Fun(Void|VoidImpl|Wrapper)?(\\d+)[$][$]"); // TODO Regex shenanigans Pattern p = Pattern.compile("Fun(\\d+)[$][$]");
Matcher m = p.matcher(name); Matcher m = p.matcher(name);
if (m.matches()) {// es ist FunN$$-Type if (m.matches()) {// es ist FunN$$-Type
return new RefType(new JavaClassName(name), convert(typeArguments, reg, generics), offset); return new RefType(new JavaClassName(name), convert(typeArguments, reg, generics), offset);

View File

@@ -140,7 +140,8 @@ public class GatherNames {
if (importDeclCtx.MUL() == null) { if (importDeclCtx.MUL() == null) {
var name = importDeclCtx.qualifiedName().getText(); var name = importDeclCtx.qualifiedName().getText();
var className = new JavaClassName(name); var className = new JavaClassName(name);
if (compiler.input.contains(className)) { var clazz = compiler.loadJavaTXClass(className);
if (clazz != null) {
ret.put(name, compiler.classRegistry.getNumberOfGenerics(name)); ret.put(name, compiler.classRegistry.getNumberOfGenerics(name));
} else { } else {
Class<?> cl = compiler.getClassLoader().loadClass(name); Class<?> cl = compiler.getClassLoader().loadClass(name);

View File

@@ -41,7 +41,7 @@ public class JavaClassName {
} }
/** /**
* Gibt von einem Klassennamen nur den Namen der Klasse zurück * Gibt von einem Klassennamen nur den Namen der Klasse zur<EFBFBD>ck
* Beispiel: * Beispiel:
* java.lang.Object wird zu: Object * java.lang.Object wird zu: Object
*/ */

View File

@@ -5,9 +5,9 @@ import de.dhbwstuttgart.exceptions.NotImplementedException;
import java.util.*; import java.util.*;
/** /**
* Speichert die Klassen für einen bestimmten Projektscope * Speichert die Klassen f<EFBFBD>r einen bestimmten Projektscope
*/ */
public class JavaClassRegistry{ public class JavaClassRegistry {
final Map<JavaClassName, Integer> existingClasses = new HashMap<>(); final Map<JavaClassName, Integer> existingClasses = new HashMap<>();
public JavaClassRegistry(Map<String, Integer> initialNames) { public JavaClassRegistry(Map<String, Integer> initialNames) {
@@ -22,10 +22,6 @@ public class JavaClassRegistry{
} }
} }
public Set<JavaClassName> getAllClassNames(){
return existingClasses.keySet();
}
public void addName(String className, int numberOfGenerics) { public void addName(String className, int numberOfGenerics) {
existingClasses.put(new JavaClassName(className), numberOfGenerics); existingClasses.put(new JavaClassName(className), numberOfGenerics);
} }
@@ -64,6 +60,6 @@ public class JavaClassRegistry{
} }
public int getNumberOfGenerics(String name) { public int getNumberOfGenerics(String name) {
return existingClasses.getOrDefault(new JavaClassName(name), 0); return existingClasses.get(new JavaClassName(name));
} }
} }

View File

@@ -3,7 +3,7 @@ package de.dhbwstuttgart.server.packet.dataContainers.serialized;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.jspecify.annotations.Nullable; import javax.annotation.Nullable;
public class SerialMap extends HashMap<String, ISerialNode> implements ISerialNode { public class SerialMap extends HashMap<String, ISerialNode> implements ISerialNode {

View File

@@ -6,12 +6,10 @@ import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.target.tree.TargetGeneric;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
/** /**
* Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces * Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces
@@ -33,7 +31,6 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
private List<RefType> implementedInterfaces; private List<RefType> implementedInterfaces;
private List<RefType> permittedSubtypes; private List<RefType> permittedSubtypes;
private List<Constructor> constructors; private List<Constructor> constructors;
private Set<GenericTypeVar> userDefinedGenerics;
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, Optional<Method> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, Boolean isFunctionalInterface, List<RefType> implementedInterfaces, List<RefType> permittedSubtypes, Token offset, String fileName) { public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, Optional<Method> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, Boolean isFunctionalInterface, List<RefType> implementedInterfaces, List<RefType> permittedSubtypes, Token offset, String fileName) {
super(offset); super(offset);
@@ -202,22 +199,4 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
public int hashCode() { public int hashCode() {
return Objects.hash(name); return Objects.hash(name);
} }
public Set<GenericTypeVar> getUserDefinedGenerics() {
if (this.userDefinedGenerics != null) return this.userDefinedGenerics;
var genericsIter = getGenerics().iterator();
if (genericsIter.hasNext()) {
// Add empty set of generics to cache so that it doesn't try to calculate it later
this.userDefinedGenerics = new HashSet<>();
while (genericsIter.hasNext()) {
var next = genericsIter.next();
userDefinedGenerics.add(next);
}
} else {
this.userDefinedGenerics = new HashSet<>();
}
return this.userDefinedGenerics;
}
} }

View File

@@ -5,10 +5,8 @@ import java.util.*;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
import de.dhbwstuttgart.typeinference.result.ResultSet;
//import sun.security.x509.X509CertInfo; //import sun.security.x509.X509CertInfo;
public class SourceFile extends SyntaxTreeNode { public class SourceFile extends SyntaxTreeNode {
@@ -20,7 +18,6 @@ public class SourceFile extends SyntaxTreeNode {
private boolean isGenerated; private boolean isGenerated;
public List<ClassOrInterface> availableClasses = new ArrayList<>(); public List<ClassOrInterface> availableClasses = new ArrayList<>();
public List<ASTToTargetAST.Generics> generics = new ArrayList<>();
/** /**
* Die SourceFile repräsntiert eine zu einem Syntaxbaum eingelesene Java-Datei. * Die SourceFile repräsntiert eine zu einem Syntaxbaum eingelesene Java-Datei.
@@ -43,10 +40,6 @@ public class SourceFile extends SyntaxTreeNode {
this.imports = new HashSet<>(sf.imports); this.imports = new HashSet<>(sf.imports);
} }
public void addResultSet(ResultSet rs) {
}
public void setPackageName(String packageName) { public void setPackageName(String packageName) {
this.pkgName = packageName; this.pkgName = packageName;
} }

View File

@@ -8,7 +8,6 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.*; import java.util.*;
import com.google.common.collect.Lists;
import de.dhbwstuttgart.bytecode.JavaTXSignatureAttribute; import de.dhbwstuttgart.bytecode.JavaTXSignatureAttribute;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
@@ -154,13 +153,15 @@ public class ASTFactory {
int modifier = jreClass.getModifiers(); int modifier = jreClass.getModifiers();
boolean isInterface = jreClass.isInterface(); boolean isInterface = jreClass.isInterface();
List<Annotation> aLA; List<Annotation> aLA;
boolean isFunctionalInterface = boolean isFunctionalInterface =
!(aLA = Arrays.asList(jreClass.getAnnotations())).isEmpty() && (aLA = Arrays.asList(jreClass.getAnnotations())).size() > 0 &&
aLA.get(0) instanceof FunctionalInterface; aLA.get(0) instanceof FunctionalInterface ?
true :
false;
// see: https://stackoverflow.com/questions/9934774/getting-generic-parameter-from-supertype-class // see: https://stackoverflow.com/questions/9934774/getting-generic-parameter-from-supertype-class
ParameterizedType parameterSuperClass = null; ParameterizedType parameterSuperClass = null;
Type tempSuperClass = jreClass.getGenericSuperclass(); Type tempSuperClass = jreClass.getGenericSuperclass();
if (tempSuperClass instanceof ParameterizedType) if (tempSuperClass != null && tempSuperClass instanceof ParameterizedType)
parameterSuperClass = (ParameterizedType) tempSuperClass; parameterSuperClass = (ParameterizedType) tempSuperClass;
java.lang.Class superjreClass = jreClass.getSuperclass(); java.lang.Class superjreClass = jreClass.getSuperclass();
RefType superClass; RefType superClass;
@@ -183,7 +184,8 @@ public class ASTFactory {
} }
} }
GenericDeclarationList genericDeclarationList = createGenerics(jreClass.getTypeParameters(), jreClass, null, null); GenericDeclarationList genericDeclarationList = createGenerics(jreClass.getTypeParameters(), jreClass, null, classSignature);
Token offset = new NullToken(); // Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde Token offset = new NullToken(); // Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde
var cinf = new ClassOrInterface(modifier, name, felder, Optional.empty() /* eingefuegt PL 2018-11-24 */, Optional.empty(), methoden, konstruktoren, genericDeclarationList, superClass, isInterface, isFunctionalInterface, implementedInterfaces, permittedSubtypes, offset, null); var cinf = new ClassOrInterface(modifier, name, felder, Optional.empty() /* eingefuegt PL 2018-11-24 */, Optional.empty(), methoden, konstruktoren, genericDeclarationList, superClass, isInterface, isFunctionalInterface, implementedInterfaces, permittedSubtypes, offset, null);
@@ -229,9 +231,6 @@ public class ASTFactory {
public static Method createMethod(java.lang.reflect.Method jreMethod, String signature, java.lang.Class inClass, Boolean isInherited, Boolean isImplemented) { public static Method createMethod(java.lang.reflect.Method jreMethod, String signature, java.lang.Class inClass, Boolean isInherited, Boolean isImplemented) {
String name = jreMethod.getName(); String name = jreMethod.getName();
RefTypeOrTPHOrWildcardOrGeneric returnType; RefTypeOrTPHOrWildcardOrGeneric returnType;
if (inClass.getName().equals("Swap")){
System.out.println();
}
Type jreRetType; Type jreRetType;
if (jreMethod.getGenericReturnType() != null) { if (jreMethod.getGenericReturnType() != null) {
jreRetType = jreMethod.getGenericReturnType(); jreRetType = jreMethod.getGenericReturnType();

View File

@@ -16,10 +16,6 @@ public class NameGenerator {
public static void reset() { public static void reset() {
strNextName = "A"; strNextName = "A";
} }
public static void resetTo(String name) {
strNextName = name;
}
/** /**
* Berechnet einen neuen, eindeutigen Namen f�r eine neue * Berechnet einen neuen, eindeutigen Namen f�r eine neue

View File

@@ -2,6 +2,7 @@ package de.dhbwstuttgart.target.generate;
import de.dhbwstuttgart.bytecode.FunNGenerator; import de.dhbwstuttgart.bytecode.FunNGenerator;
import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
import de.dhbwstuttgart.environment.IByteArrayClassLoader; import de.dhbwstuttgart.environment.IByteArrayClassLoader;
import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
@@ -11,14 +12,12 @@ import de.dhbwstuttgart.syntaxtree.Record;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter; import de.dhbwstuttgart.target.Target;
import de.dhbwstuttgart.syntaxtree.visual.OutputGenerator;
import de.dhbwstuttgart.target.tree.*; import de.dhbwstuttgart.target.tree.*;
import de.dhbwstuttgart.target.tree.expression.*; import de.dhbwstuttgart.target.tree.expression.*;
import de.dhbwstuttgart.target.tree.type.*; import de.dhbwstuttgart.target.tree.type.*;
import de.dhbwstuttgart.typeinference.result.*; import de.dhbwstuttgart.typeinference.result.*;
import java.lang.annotation.Target;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -33,9 +32,9 @@ public class ASTToTargetAST {
public static RefType OBJECT = ASTFactory.createObjectType(); // TODO It would be better if I could call this directly but the hashcode seems to change public static RefType OBJECT = ASTFactory.createObjectType(); // TODO It would be better if I could call this directly but the hashcode seems to change
public List<Generics> all; protected List<Generics> all;
//public Generics generics; public Generics generics;
//public List<Generics> currentMethodOverloads; public List<Generics> currentMethodOverloads;
final Map<ClassOrInterface, Set<GenericTypeVar>> userDefinedGenerics = new HashMap<>(); final Map<ClassOrInterface, Set<GenericTypeVar>> userDefinedGenerics = new HashMap<>();
final Map<Method, Set<SignaturePair>> tphsInMethods = new HashMap<>(); final Map<Method, Set<SignaturePair>> tphsInMethods = new HashMap<>();
@@ -55,26 +54,24 @@ public class ASTToTargetAST {
return all.stream().map(generics -> new GenericsResult(generics.javaGenerics)).toList(); return all.stream().map(generics -> new GenericsResult(generics.javaGenerics)).toList();
} }
public TargetExpression convert(Pattern pattern, IGenerics generics) { public TargetExpression convert(Pattern pattern) {
var converter = new StatementToTargetExpression(this, generics); var converter = new StatementToTargetExpression(this);
pattern.accept(converter); pattern.accept(converter);
return converter.result; return converter.result;
} }
public record Generics(JavaGenerics javaGenerics, TxGenerics txGenerics) { public record Generics(JavaGenerics javaGenerics, TxGenerics txGenerics) {
public Generics(JavaTXCompiler compiler, ResultSet set) {
this(new JavaGenerics(compiler, set), new TxGenerics(compiler, set));
}
} }
public IByteArrayClassLoader classLoader; public IByteArrayClassLoader classLoader;
protected SourceFile sourceFile; protected SourceFile sourceFile;
public ASTToTargetAST(List<ResultSet> resultSets, IByteArrayClassLoader classLoader) { public ASTToTargetAST(List<ResultSet> resultSets) {
this(null, resultSets, classLoader); this(null, resultSets);
} }
public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets, IByteArrayClassLoader classLoader) { public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets) {
this(compiler, resultSets, null, classLoader); this(compiler, resultSets, null, new ByteArrayClassLoader());
} }
public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets, SourceFile sourceFile, IByteArrayClassLoader classLoader) { public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets, SourceFile sourceFile, IByteArrayClassLoader classLoader) {
@@ -84,8 +81,9 @@ public class ASTToTargetAST {
all = new ArrayList<>(); all = new ArrayList<>();
for (var set : resultSets) { for (var set : resultSets) {
all.add(new Generics(compiler, set)); all.add(new Generics(new JavaGenerics(this, set), new TxGenerics(this, set)));
} }
this.generics = all.get(0);
} }
public void addSignaturePair(TypePlaceholder signature, RefTypeOrTPHOrWildcardOrGeneric parameter) { public void addSignaturePair(TypePlaceholder signature, RefTypeOrTPHOrWildcardOrGeneric parameter) {
@@ -94,27 +92,27 @@ public class ASTToTargetAST {
tphsInMethods.put(currentMethod, set); tphsInMethods.put(currentMethod, set);
} }
public static Optional<Method> findMethod(ClassOrInterface owner, String name, List<TargetType> argumentList, IGenerics generics, JavaTXCompiler compiler) { Optional<Method> findMethod(ClassOrInterface owner, String name, List<TargetType> argumentList) {
Optional<Method> method = Optional.empty(); Optional<Method> method = Optional.empty();
while (method.isEmpty()) { while (method.isEmpty()) {
method = owner.getMethods().stream().filter(m -> m.name.equals(name) && parameterEquals(m.getParameterList(), argumentList, generics)).findFirst(); method = owner.getMethods().stream().filter(m -> m.name.equals(name) && parameterEquals(m.getParameterList(), argumentList)).findFirst();
if (owner.getClassName().toString().equals("java.lang.Object")) break; if (owner.getClassName().toString().equals("java.lang.Object")) break;
owner = compiler.getClass(owner.getSuperClass().getName()); owner = compiler.getClass(owner.getSuperClass().getName());
} }
return method; return method;
} }
Optional<Constructor> findConstructor(ClassOrInterface owner, List<TargetType> argumentList, IGenerics generics) { Optional<Constructor> findConstructor(ClassOrInterface owner, List<TargetType> argumentList) {
return owner.getConstructors().stream().filter(c -> parameterEquals(c.getParameterList(), argumentList, generics)).findFirst(); return owner.getConstructors().stream().filter(c -> parameterEquals(c.getParameterList(), argumentList)).findFirst();
} }
static boolean parameterEquals(ParameterList parameterList, List<TargetType> arguments, IGenerics generics) { boolean parameterEquals(ParameterList parameterList, List<TargetType> arguments) {
var pars = parameterList.getFormalparalist(); var pars = parameterList.getFormalparalist();
if (pars.size() != arguments.size()) if (pars.size() != arguments.size())
return false; return false;
for (var i = 0; i < pars.size(); i++) { for (var i = 0; i < pars.size(); i++) {
var type1 = generics.getTargetType(pars.get(i).getType()); var type1 = convert(pars.get(i).getType(), generics.javaGenerics);
var type2 = arguments.get(i); var type2 = arguments.get(i);
if (type1 instanceof TargetGenericType) if (type1 instanceof TargetGenericType)
return true; return true;
@@ -127,19 +125,19 @@ public class ASTToTargetAST {
return true; return true;
} }
Set<TargetGeneric> convert(Set<GenerateGenerics.Pair> result, IGenerics generics) { Set<TargetGeneric> convert(Set<GenerateGenerics.Pair> result, GenerateGenerics generics) {
return result.stream().map(p -> { return result.stream().map(p -> {
if (p instanceof GenerateGenerics.PairLT pair) { if (p instanceof GenerateGenerics.PairLT pair) {
return new TargetGeneric(pair.left.resolve().getName(), convert(pair.right.resolve(), generics, compiler)); return new TargetGeneric(pair.left.resolve().getName(), convert(pair.right.resolve(), generics));
} else if (p instanceof GenerateGenerics.PairEQ pair) { } else if (p instanceof GenerateGenerics.PairEQ pair) {
return new TargetGeneric(pair.left.resolve().getName(), convert(pair.right, generics, compiler)); return new TargetGeneric(pair.left.resolve().getName(), convert(pair.right, generics));
} else { } else {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
}).collect(Collectors.toSet()); }).collect(Collectors.toSet());
} }
public List<TargetGeneric> convert(GenericTypeVar typeVar, IGenerics generics) { public List<TargetGeneric> convert(GenericTypeVar typeVar, GenerateGenerics generics) {
var ret = new ArrayList<TargetGeneric>(); var ret = new ArrayList<TargetGeneric>();
for (var bound : typeVar.getBounds()) { for (var bound : typeVar.getBounds()) {
ret.add(new TargetGeneric(typeVar.getName(), generics.getTargetType(bound))); ret.add(new TargetGeneric(typeVar.getName(), generics.getTargetType(bound)));
@@ -148,7 +146,6 @@ public class ASTToTargetAST {
} }
// This finds a common sealed interface type to group together methods that use different records // This finds a common sealed interface type to group together methods that use different records
// This function should do matching or unification
private List<ClassOrInterface> commonSuperInterfaceTypes(TargetType a, TargetType b) { private List<ClassOrInterface> commonSuperInterfaceTypes(TargetType a, TargetType b) {
if (a instanceof TargetGenericType && b instanceof TargetGenericType) return List.of(ASTFactory.createObjectClass()); if (a instanceof TargetGenericType && b instanceof TargetGenericType) return List.of(ASTFactory.createObjectClass());
if (a instanceof TargetRefType ta && b instanceof TargetGenericType) if (a instanceof TargetRefType ta && b instanceof TargetGenericType)
@@ -186,28 +183,44 @@ public class ASTToTargetAST {
return List.of(); return List.of();
} }
private boolean canCombine(Signature m1, Signature m2) { // TODO This is ugly and probably doesn't work right
var pl1 = m1.java.parameters(); private boolean patternStrictlyEquals(TargetComplexPattern a, TargetComplexPattern b) {
var pl2 = m2.java.parameters(); if (!a.name().equals(b.name())) return false;
if (pl1.size() != pl2.size()) return false; if (a.subPatterns().size() != b.subPatterns().size()) return false;
if (pl1.isEmpty()) return false; for (var i = 0; i < a.subPatterns().size(); i++) {
for (var i = 0; i < pl1.size(); i++) { var p1 = a.subPatterns().get(i);
var p1 = pl1.get(i).pattern(); var p2 = b.subPatterns().get(i);
var p2 = pl2.get(i).pattern();
// TPH <> RefType sind nicht unterscheidbar
if (p1.type() instanceof TargetGenericType || p2.type() instanceof TargetGenericType) continue;
// Pattern(X) <> Pattern(Y) ist nicht unterscheidbar
if (p1 instanceof TargetComplexPattern pc1 && p2 instanceof TargetComplexPattern pc2 && if (p1 instanceof TargetComplexPattern pc1 && p2 instanceof TargetComplexPattern pc2 &&
pc1.type().equals(pc2.type())) continue; patternStrictlyEquals(pc1, pc2)) return false;
if (!p1.equals(p2)) return false; if (p1 instanceof TargetTypePattern pt1 && p2 instanceof TargetTypePattern pt2) {
if (pt1.type() instanceof TargetGenericType && pt2.type() instanceof TargetGenericType) continue;
}
if (!p1.type().equals(p2.type()) && commonSuperInterfaceTypes(p1.type(), p2.type()).isEmpty()) return false;
} }
return true; return true;
} }
private record Combination(MethodWithTphs a, MethodWithTphs b) { private boolean canCombine(TargetMethod m1, TargetMethod m2) {
if (!m1.name().equals(m2.name())) return false;
var s1 = m1.signature();
var s2 = m2.signature();
if (s1.parameters().size() != s2.parameters().size()) return false;
if (s1.parameters().isEmpty()) return false;
for (var i = 0; i < s1.parameters().size(); i++) {
var p1 = s1.parameters().get(i).pattern();
var p2 = s2.parameters().get(i).pattern();
if (p1.type() instanceof TargetGenericType || p2.type() instanceof TargetGenericType) continue;
if (p1 instanceof TargetComplexPattern pc1 && p2 instanceof TargetComplexPattern pc2 &&
patternStrictlyEquals(pc1, pc2)) return false;
if (!p1.equals(p2) && commonSuperInterfaceTypes(p1.type(), p2.type()).isEmpty()) return false;
}
return true;
}
private record Combination(TargetMethod a, TargetMethod b) {
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (!(o instanceof Combination(MethodWithTphs a1, MethodWithTphs b1))) return false; if (!(o instanceof Combination(TargetMethod a1, TargetMethod b1))) return false;
return this.a.equals(a1) && this.b.equals(b1) || return this.a.equals(a1) && this.b.equals(b1) ||
this.a.equals(b1) && this.b.equals(a1); this.a.equals(b1) && this.b.equals(a1);
} }
@@ -218,10 +231,10 @@ public class ASTToTargetAST {
} }
} }
private List<List<MethodWithTphs>> groupOverloads(ClassOrInterface input, List<Method> methods) { public List<List<TargetMethod>> groupOverloads(ClassOrInterface input, List<Method> methods) {
var mapOfTargetMethods = new HashMap<Generics, MethodWithTphs[]>(); var mapOfTargetMethods = new HashMap<Generics, TargetMethod[]>();
for (var gen : all) { for (var generics : all) {
mapOfTargetMethods.put(gen, new MethodWithTphs[methods.size()]); mapOfTargetMethods.put(generics, new TargetMethod[methods.size()]);
} }
for (var i = 0; i < methods.size(); i++) { for (var i = 0; i < methods.size(); i++) {
@@ -230,14 +243,14 @@ public class ASTToTargetAST {
var methodsWithTphs = convert(input, method); var methodsWithTphs = convert(input, method);
for (var m : methodsWithTphs) { for (var m : methodsWithTphs) {
var resultMethods = mapOfTargetMethods.get(m.generics); var resultMethods = mapOfTargetMethods.get(m.generics);
resultMethods[i] = new MethodWithTphs(m.method, m.generics, m.signature); resultMethods[i] = m.method;
} }
} }
System.out.println("============== INPUT =============="); /*System.out.println("============== INPUT ==============");
for (var m : mapOfTargetMethods.values()) { for (var m : mapOfTargetMethods.values()) {
for (var v : m) if (v != null) System.out.println(v.signature.java.returnType() + " " + v.method.name + " " + v.signature.java().parameters()); for (var v : m) System.out.println(v.name() + " " + v.getSignature());
System.out.println(); System.out.println();
} }*/
var allCombinations = new HashSet<Set<Combination>>(); var allCombinations = new HashSet<Set<Combination>>();
// Combine methods based on their signature and position in the result set // Combine methods based on their signature and position in the result set
@@ -255,8 +268,8 @@ public class ASTToTargetAST {
var combinations = new HashSet<Combination>(); var combinations = new HashSet<Combination>();
if (canCombine(m1.signature, m2.signature)) { if (canCombine(m1, m2)) {
//System.out.println(" Combining " + m1.signature.java.getSignature() + " and " + m2.signature.java.getSignature()); //System.out.println(" Combining " + m1.getSignature() + " and " + m2.getSignature());
combinations.add(new Combination(m1, m2)); combinations.add(new Combination(m1, m2));
for (var j = 0; j < methods.size(); j++) { for (var j = 0; j < methods.size(); j++) {
if (j == i) continue; if (j == i) continue;
@@ -265,10 +278,10 @@ public class ASTToTargetAST {
var m4 = resMeth1[j]; var m4 = resMeth1[j];
if (m4 == null) continue; if (m4 == null) continue;
combinations.add(new Combination(m4, m3)); combinations.add(new Combination(m4, m3));
//System.out.println("Also Combining " + m4.signature.java.getSignature() + " and " + m3.signature.java.getSignature()); //System.out.println("Also Combining " + m4.getSignature() + " and " + m3.getSignature());
} }
} else { } else {
//System.out.println(" Not Combining " + m1.signature.java.getSignature() + " and " + m2.signature.java.getSignature()); //System.out.println(" Not Combining " + m1.getSignature() + " and " + m2.getSignature());
} }
if (!combinations.isEmpty()) allCombinations.add(combinations); if (!combinations.isEmpty()) allCombinations.add(combinations);
} }
@@ -278,14 +291,14 @@ public class ASTToTargetAST {
if (allCombinations.isEmpty()) allCombinations.add(new HashSet<>()); if (allCombinations.isEmpty()) allCombinations.add(new HashSet<>());
// Combine back into output format // Combine back into output format
var r0 = new HashSet<Set<MethodWithTphs>>(); var r0 = new HashSet<Set<TargetMethod>>();
for (var combinations : allCombinations) { for (var combinations : allCombinations) {
var r1 = new HashSet<Set<MethodWithTphs>>(); var r1 = new HashSet<Set<TargetMethod>>();
// This is used to weed out duplicates // This is used to weed out duplicates
var uniqued = new HashSet<MethodWithTphs>(); var uniqued = new HashSet<TargetMethod>();
// We go over all methods in the result // We go over all methods in the result
for (var g : all) for (var i = 0; i < methods.size(); i++) { for (var g : all) for (var i = 0; i < methods.size(); i++) {
var r2 = new HashSet<MethodWithTphs>(); var r2 = new HashSet<TargetMethod>();
var m = mapOfTargetMethods.get(g)[i]; var m = mapOfTargetMethods.get(g)[i];
if (m == null) continue; if (m == null) continue;
if (!uniqued.contains(m)) { if (!uniqued.contains(m)) {
@@ -325,16 +338,15 @@ public class ASTToTargetAST {
var result = r0.stream().map(l -> l.stream().toList()).toList(); var result = r0.stream().map(l -> l.stream().toList()).toList();
//System.out.println("============== OUTPUT =============="); Target.logger.info("============== OUTPUT ==============");
//for (var l : result) { for (var l : result) {
// for (var m : l) System.out.println(m.method.name + " " + m.signature.java.getSignature()); for (var m : l) Target.logger.info(m.name() + " " + m.getSignature());
// System.out.println(); Target.logger.info("");
//} }
return result; return result;
} }
public TargetStructure convert(ClassOrInterface input) { public TargetStructure convert(ClassOrInterface input) {
var generics = all.getFirst();
Set<TargetGeneric> javaGenerics = new HashSet<>(); Set<TargetGeneric> javaGenerics = new HashSet<>();
Set<TargetGeneric> txGenerics = new HashSet<>(); Set<TargetGeneric> txGenerics = new HashSet<>();
@@ -347,7 +359,7 @@ public class ASTToTargetAST {
var next = genericsIter.next(); var next = genericsIter.next();
userDefinedGenerics.add(next); userDefinedGenerics.add(next);
// TODO Support multiple bounds // TODO Support multiple bounds
javaGenerics.add(new TargetGeneric(next.getName(), convert(next.getBounds().getFirst(), generics.javaGenerics, compiler))); javaGenerics.add(new TargetGeneric(next.getName(), convert(next.getBounds().get(0))));
} }
} else { } else {
this.userDefinedGenerics.put(input, new HashSet<>()); this.userDefinedGenerics.put(input, new HashSet<>());
@@ -358,38 +370,31 @@ public class ASTToTargetAST {
TargetBlock fieldInitializer = null; TargetBlock fieldInitializer = null;
if (input.getfieldInitializations().isPresent()) if (input.getfieldInitializations().isPresent())
fieldInitializer = convert(input.getfieldInitializations().get().block, generics.javaGenerics); fieldInitializer = convert(input.getfieldInitializations().get().block);
TargetBlock finalFieldInitializer = fieldInitializer; TargetBlock finalFieldInitializer = fieldInitializer;
var superInterfaces = input.getSuperInterfaces().stream().map(clazz -> convert(clazz, generics.javaGenerics, compiler)).toList(); var superInterfaces = input.getSuperInterfaces().stream().map(clazz -> convert(clazz, generics.javaGenerics)).toList();
var constructors = input.getConstructors().stream().map(constructor -> this.convert(input, constructor, finalFieldInitializer, generics)).flatMap(List::stream).toList(); var constructors = input.getConstructors().stream().map(constructor -> this.convert(input, constructor, finalFieldInitializer)).flatMap(List::stream).toList();
var fields = input.getFieldDecl().stream().map(f -> convert(f, generics.javaGenerics)).toList(); var fields = input.getFieldDecl().stream().map(this::convert).toList();
var methods = groupOverloads(input, input.getMethods()).stream().map(m -> generatePatternOverloads(input, m)).flatMap(List::stream) var methods = groupOverloads(input, input.getMethods()).stream().map(m -> generatePatternOverloads(input, m)).flatMap(List::stream)
.collect(Collectors.toSet()).stream().toList(); // Unique generated methods .collect(Collectors.toSet()).stream().toList(); // Unique generated methods
TargetMethod staticConstructor = null; TargetMethod staticConstructor = null;
if (input.getStaticInitializer().isPresent()) { if (input.getStaticInitializer().isPresent())
var init = this.convert(input, input.getStaticInitializer().get()).stream().findFirst().orElseThrow(); staticConstructor = this.convert(input, input.getStaticInitializer().get()).stream().findFirst().orElseThrow().method;
staticConstructor = this.convert(init, init.generics.javaGenerics);
}
if (input instanceof Record) if (input instanceof Record)
return new TargetRecord(input.getModifiers(), input.getClassName(), javaGenerics, txGenerics, superInterfaces, constructors, staticConstructor, fields, methods); return new TargetRecord(input.getModifiers(), input.getClassName(), javaGenerics, txGenerics, superInterfaces, constructors, staticConstructor, fields, methods);
else if (input.isInterface()) else if (input.isInterface())
return new TargetInterface(input.getModifiers(), input.getClassName(), javaGenerics, txGenerics, methods, superInterfaces, staticConstructor); return new TargetInterface(input.getModifiers(), input.getClassName(), javaGenerics, txGenerics, methods, superInterfaces, staticConstructor);
else return new TargetClass(input.getModifiers(), input.getClassName(), convert(input.getSuperClass(), generics.javaGenerics, compiler), javaGenerics, txGenerics, superInterfaces, constructors, staticConstructor, fields, methods); else return new TargetClass(input.getModifiers(), input.getClassName(), convert(input.getSuperClass(), generics.javaGenerics), javaGenerics, txGenerics, superInterfaces, constructors, staticConstructor, fields, methods);
} }
@Deprecated public List<MethodParameter> convert(ParameterList input, GenerateGenerics generics) {
public List<MethodParameter> convert(ParameterList input) {
return convert(input, all.getFirst().javaGenerics);
}
public List<MethodParameter> convert(ParameterList input, IGenerics generics) {
var res = new ArrayList<MethodParameter>(); var res = new ArrayList<MethodParameter>();
for (var i = 0; i < input.getFormalparalist().size(); i++) { for (var i = 0; i < input.getFormalparalist().size(); i++) {
var param = input.getFormalparalist().get(i); var param = input.getFormalparalist().get(i);
var pattern = (TargetPattern) convert(param, generics); var pattern = (TargetPattern) convert(param);
if (pattern instanceof TargetComplexPattern) pattern = pattern.withName("__var" + i); if (pattern instanceof TargetComplexPattern) pattern = pattern.withName("__var" + i);
res.add(new MethodParameter(pattern)); res.add(new MethodParameter(pattern));
} }
@@ -400,7 +405,7 @@ public class ASTToTargetAST {
return generics.stream().anyMatch(g -> g.name().equals(type.getParsedName())); return generics.stream().anyMatch(g -> g.name().equals(type.getParsedName()));
} }
private Set<TargetGeneric> collectMethodGenerics(ClassOrInterface clazz, IGenerics generateGenerics, Set<GenerateGenerics.Pair> generics, Method input) { private Set<TargetGeneric> collectMethodGenerics(ClassOrInterface clazz, GenerateGenerics generateGenerics, Set<GenerateGenerics.Pair> generics, Method input) {
var convertedGenerics = new HashSet<>(convert(generics, generateGenerics)); var convertedGenerics = new HashSet<>(convert(generics, generateGenerics));
outer: for (GenericTypeVar typeVar : input.getGenerics()) { outer: for (GenericTypeVar typeVar : input.getGenerics()) {
for (var classGeneric : clazz.getGenerics()) { for (var classGeneric : clazz.getGenerics()) {
@@ -418,7 +423,7 @@ public class ASTToTargetAST {
return convertedGenerics; return convertedGenerics;
} }
private List<TargetConstructor> convert(ClassOrInterface currentClass, Constructor input, TargetBlock fieldInitializer, Generics generics) { private List<TargetConstructor> convert(ClassOrInterface currentClass, Constructor input, TargetBlock fieldInitializer) {
generics = all.get(0); generics = all.get(0);
List<TargetConstructor> result = new ArrayList<>(); List<TargetConstructor> result = new ArrayList<>();
Set<List<MethodParameter>> parameterSet = new HashSet<>(); Set<List<MethodParameter>> parameterSet = new HashSet<>();
@@ -426,15 +431,15 @@ public class ASTToTargetAST {
for (var s : all) { for (var s : all) {
generics = s; generics = s;
var javaGenerics = generics.javaGenerics.generics(currentClass, input); var javaGenerics = this.generics.javaGenerics.generics(currentClass, input);
var txGenerics = generics.txGenerics.generics(currentClass, input); var txGenerics = this.generics.txGenerics.generics(currentClass, input);
List<MethodParameter> params = convert(input.getParameterList(), generics.javaGenerics); List<MethodParameter> params = convert(input.getParameterList(), this.generics.javaGenerics);
if (parameterSet.stream().noneMatch(p -> p.equals(params))) { if (parameterSet.stream().noneMatch(p -> p.equals(params))) {
List<MethodParameter> txParams = convert(input.getParameterList(), generics.txGenerics); List<MethodParameter> txParams = convert(input.getParameterList(), this.generics.txGenerics);
var javaMethodGenerics = collectMethodGenerics(currentClass, generics.javaGenerics(), javaGenerics, input); var javaMethodGenerics = collectMethodGenerics(currentClass, generics.javaGenerics(), javaGenerics, input);
var txMethodGenerics = collectMethodGenerics(currentClass, generics.txGenerics(), txGenerics, input); var txMethodGenerics = collectMethodGenerics(currentClass, generics.txGenerics(), txGenerics, input);
result.add(new TargetConstructor(input.modifier, javaMethodGenerics, txMethodGenerics, params, txParams, convert(input.block, generics.javaGenerics), fieldInitializer)); result.add(new TargetConstructor(input.modifier, javaMethodGenerics, txMethodGenerics, params, txParams, convert(input.block), fieldInitializer));
parameterSet.add(params); parameterSet.add(params);
} }
} }
@@ -442,13 +447,10 @@ public class ASTToTargetAST {
return result; return result;
} }
private static int counter = 0;
private String encodeName(String name, TargetMethod.Signature params) { private String encodeName(String name, TargetMethod.Signature params) {
var res = new StringBuilder(); var res = new StringBuilder();
res.append(name); res.append(name);
res.append('$'); res.append('$');
res.append(counter++);
res.append('$');
for (var param : params.parameters()) { for (var param : params.parameters()) {
encodeName(param.pattern(), res); encodeName(param.pattern(), res);
} }
@@ -524,14 +526,12 @@ public class ASTToTargetAST {
var j = 0; var j = 0;
for (var param : m.signature().parameters()) { for (var param : m.signature().parameters()) {
if (j >= patternsRec.size()) return true; if (j >= patternsRec.size()) return true;
if (!patternsRec.get(j).equals(param.pattern())) return false; if (!patternsRec.get(j).type().equals(param.pattern().type())) return false;
j++; j++;
} }
return true; return true;
}).toList(); }).toList();
//System.out.println(offset + " -> " + lastPattern);
//candidates.forEach(m -> System.out.println(m.getSignature()));
var caseBody = generatePatternOverloadsRec(offset + 1, expr, params, patternsRec, candidates, classType); var caseBody = generatePatternOverloadsRec(offset + 1, expr, params, patternsRec, candidates, classType);
var body = new TargetBlock(List.of(caseBody)); var body = new TargetBlock(List.of(caseBody));
var case_ = new TargetSwitch.Case(List.of(lastPattern), body); var case_ = new TargetSwitch.Case(List.of(lastPattern), body);
@@ -542,14 +542,19 @@ public class ASTToTargetAST {
return new TargetSwitch(switchExpr, cases, null, true); return new TargetSwitch(switchExpr, cases, null, true);
} }
private List<TargetMethod> generatePatternOverloads(ClassOrInterface clazz, List<MethodWithTphs> overloadedMethods) { private List<TargetMethod> generatePatternOverloads(ClassOrInterface clazz, List<TargetMethod> overloadedMethods) {
if (overloadedMethods.isEmpty()) return List.of(); if (overloadedMethods.size() <= 1) return overloadedMethods;
// Check if we have a pattern as a parameter // Check if we have a pattern as a parameter
var firstMethod = convert(overloadedMethods.getFirst(), overloadedMethods.getFirst().generics.javaGenerics); var firstMethod = overloadedMethods.getFirst();
if (overloadedMethods.size() == 1) return List.of(firstMethod); var secondMethod = overloadedMethods.get(1);
var secondMethod = convert(overloadedMethods.get(1), overloadedMethods.get(1).generics.javaGenerics); if (firstMethod.signature().parameters().stream().noneMatch(mp -> mp.pattern() instanceof TargetComplexPattern)) return overloadedMethods;
if (firstMethod.signature().parameters().stream().noneMatch(mp -> mp.pattern() instanceof TargetComplexPattern)) // Rename existing methods
return overloadedMethods.stream().map(m -> convert(m, m.generics.javaGenerics)).toList();
var res = new ArrayList<TargetMethod>();
for (var method : overloadedMethods) {
var name = encodeName(method.name(), method.signature());
res.add(new TargetMethod(method.access(), name, method.block(), method.signature(), method.txSignature()));
}
var signatureParams = new ArrayList<MethodParameter>(); var signatureParams = new ArrayList<MethodParameter>();
for (var i = 0; i < firstMethod.signature().parameters().size(); i++) { for (var i = 0; i < firstMethod.signature().parameters().size(); i++) {
@@ -558,7 +563,7 @@ public class ASTToTargetAST {
var t2 = secondMethod.signature().parameters().get(i).pattern().type(); var t2 = secondMethod.signature().parameters().get(i).pattern().type();
var commonSubTypes = new HashSet<>(commonSuperInterfaceTypes(t1, t2)); var commonSubTypes = new HashSet<>(commonSuperInterfaceTypes(t1, t2));
for (var m : overloadedMethods.subList(2, overloadedMethods.size())) { for (var m : overloadedMethods.subList(2, overloadedMethods.size())) {
var t3 = m.signature().java.parameters().get(i).pattern().type(); var t3 = m.signature().parameters().get(i).pattern().type();
commonSubTypes.retainAll(commonSuperInterfaceTypes(t1, t3)); commonSubTypes.retainAll(commonSuperInterfaceTypes(t1, t3));
} }
if (commonSubTypes.size() > 1) throw new DebugException("Invalid overload"); if (commonSubTypes.size() > 1) throw new DebugException("Invalid overload");
@@ -573,28 +578,9 @@ public class ASTToTargetAST {
signatureParams.add(new MethodParameter(new TargetRefType(superType.getClassName().toString()), name)); signatureParams.add(new MethodParameter(new TargetRefType(superType.getClassName().toString()), name));
} }
// Rename existing methods
var res = new ArrayList<TargetMethod>();
for (var method : overloadedMethods) {
var name = encodeName(method.method.name, method.signature.java);
var generics = new OverlayGenerics(method.generics.javaGenerics, this);
var m = overloadedMethods.getFirst();
var params = m.method.getParameterList().getFormalparalist();
for (var i = 0; i < params.size(); i++) {
var param = params.get(i);
if (param.getType() instanceof TypePlaceholder tph) {
generics.addOverlay(tph, signatureParams.get(i).pattern().type());
}
}
var tMethod = convert(method, generics);
res.add(new TargetMethod(tMethod.access(), name, tMethod.block(), tMethod.signature(), tMethod.txSignature()));
}
var commonSubTypes = new HashSet<>(commonSuperInterfaceTypes(firstMethod.signature().returnType(), secondMethod.signature().returnType())); var commonSubTypes = new HashSet<>(commonSuperInterfaceTypes(firstMethod.signature().returnType(), secondMethod.signature().returnType()));
for (var m : overloadedMethods.subList(2, overloadedMethods.size())) { for (var m : overloadedMethods.subList(2, overloadedMethods.size())) {
commonSubTypes.retainAll(commonSuperInterfaceTypes(firstMethod.signature().returnType(), m.signature().java.returnType())); commonSubTypes.retainAll(commonSuperInterfaceTypes(firstMethod.signature().returnType(), m.signature().returnType()));
} }
var returnType = commonSubTypes.isEmpty() ? TargetType.Object : new TargetRefType(commonSubTypes.iterator().next().getClassName().toString()); var returnType = commonSubTypes.isEmpty() ? TargetType.Object : new TargetRefType(commonSubTypes.iterator().next().getClassName().toString());
@@ -615,7 +601,7 @@ public class ASTToTargetAST {
} }
private Expression makeRecordSwitch(RefTypeOrTPHOrWildcardOrGeneric returnType, ParameterList params, List<Method> overloadedMethods) { private Expression makeRecordSwitch(RefTypeOrTPHOrWildcardOrGeneric returnType, ParameterList params, List<Method> overloadedMethods) {
var param = params.getFormalparalist().getFirst(); var param = params.getFormalparalist().get(0);
assert param instanceof RecordPattern; // TODO assert param instanceof RecordPattern; // TODO
var cases = new ArrayList<SwitchBlock>(); var cases = new ArrayList<SwitchBlock>();
@@ -635,7 +621,7 @@ public class ASTToTargetAST {
return swtch; return swtch;
} }
private Optional<Method> findSuperMethodToOverride(ClassOrInterface currentClass, String name, List<MethodParameter> params, IGenerics generics) { private Optional<Method> findSuperMethodToOverride(ClassOrInterface currentClass, String name, List<MethodParameter> params) {
var superClass = compiler.getClass(currentClass.getSuperClass().getName()); var superClass = compiler.getClass(currentClass.getSuperClass().getName());
var methodStream = superClass.getMethods().stream(); var methodStream = superClass.getMethods().stream();
for (var superInterface : currentClass.getSuperInterfaces()) { for (var superInterface : currentClass.getSuperInterfaces()) {
@@ -648,106 +634,124 @@ public class ASTToTargetAST {
if (sParams.getFormalparalist().size() != params.size()) return false; if (sParams.getFormalparalist().size() != params.size()) return false;
for (var i = 0; i < params.size(); i++) { for (var i = 0; i < params.size(); i++) {
var a = TargetType.toPrimitive(params.get(i).pattern().type()); var a = TargetType.toPrimitive(params.get(i).pattern().type());
var b = convert(sParams.getFormalparalist().get(i).getType(), generics, compiler); var b = convert(sParams.getFormalparalist().get(i).getType());
if (!Objects.equals(a, b)) return false; if (!Objects.equals(a, b)) return false;
} }
return true; return true;
}).findFirst(); }).findFirst();
} }
record MethodWithTphs(Method method, Generics generics, Signature signature) { record MethodWithTphs(TargetMethod method, Generics generics, List<SignaturePairTarget> args) {
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;
if (!(o instanceof MethodWithTphs that)) return false; if (!(o instanceof MethodWithTphs that)) return false;
return Objects.equals(method, that.method) && Objects.equals(signature, that.signature); return Objects.equals(method, that.method) && Objects.equals(args, that.args);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(method, signature); return Objects.hash(method, args);
} }
} }
private TargetMethod convert(MethodWithTphs mtph, IGenerics generics) {
return new TargetMethod(mtph.method.modifier, mtph.method.name, convert(mtph.method.block, generics), mtph.signature.java(), mtph.signature.tx());
}
record Signature(TargetMethod.Signature java, TargetMethod.Signature tx, Generics generics) {} record Signature(TargetMethod.Signature java, TargetMethod.Signature tx, Generics generics) {}
private List<MethodWithTphs> convert(ClassOrInterface currentClass, Method method) { private List<MethodWithTphs> convert(ClassOrInterface currentClass, Method method) {
generics = all.getFirst();
List<MethodWithTphs> result = new ArrayList<>(); List<MethodWithTphs> result = new ArrayList<>();
this.currentMethod = method; this.currentMethod = method;
List<Signature> signatures = new ArrayList<>(); List<Signature> signatures = new ArrayList<>();
for (var generics : all) { HashMap<TargetMethod.Signature, List<Generics>> collectedGenerics = new HashMap<>();
var javaGenerics = generics.javaGenerics.generics(currentClass, method);
var txGenerics = generics.txGenerics.generics(currentClass, method); for (var s : all) {
List<MethodParameter> params = convert(method.getParameterList(), generics.javaGenerics); generics = s;
var returnType = convert(method.getReturnType(), generics.javaGenerics, compiler); var javaGenerics = this.generics.javaGenerics.generics(currentClass, method);
var superMethod = findSuperMethodToOverride(currentClass, method.getName(), params, generics.javaGenerics); var txGenerics = this.generics.txGenerics.generics(currentClass, method);
List<MethodParameter> params = convert(method.getParameterList(), this.generics.javaGenerics);
var returnType = convert(method.getReturnType(), this.generics.javaGenerics);
var superMethod = findSuperMethodToOverride(currentClass, method.getName(), params);
if (superMethod.isPresent()) { if (superMethod.isPresent()) {
// If we find a super method to override, use its parameters and return types // If we find a super method to override, use its parameters and return types
var newReturnType = convert(superMethod.get().getReturnType(), generics.javaGenerics, compiler); var newReturnType = convert(superMethod.get().getReturnType(), this.generics.javaGenerics);
if (newReturnType instanceof TargetPrimitiveType && TargetType.toPrimitive(returnType).equals(newReturnType)) { if (newReturnType instanceof TargetPrimitiveType && TargetType.toPrimitive(returnType).equals(newReturnType)) {
returnType = newReturnType; returnType = newReturnType;
params = convert(superMethod.get().getParameterList(), method.getParameterList(), generics.javaGenerics); params = convert(superMethod.get().getParameterList(), method.getParameterList(), this.generics.javaGenerics);
} }
} }
List<MethodParameter> txParams = convert(method.getParameterList(), generics.txGenerics); List<MethodParameter> txParams = convert(method.getParameterList(), this.generics.txGenerics);
var javaMethodGenerics = collectMethodGenerics(currentClass, generics.javaGenerics(), javaGenerics, method); var javaMethodGenerics = collectMethodGenerics(currentClass, generics.javaGenerics(), javaGenerics, method);
var txMethodGenerics = collectMethodGenerics(currentClass, generics.txGenerics(), txGenerics, method); var txMethodGenerics = collectMethodGenerics(currentClass, generics.txGenerics(), txGenerics, method);
var javaSignature = new TargetMethod.Signature(javaMethodGenerics, params, returnType); var javaSignature = new TargetMethod.Signature(javaMethodGenerics, params, returnType);
var txSignature = new TargetMethod.Signature(txMethodGenerics, txParams, convert(method.getReturnType(), generics.txGenerics, compiler)); var txSignature = new TargetMethod.Signature(txMethodGenerics, txParams, convert(method.getReturnType(), this.generics.txGenerics));
signatures.add(new Signature(javaSignature, txSignature, generics)); signatures.add(new Signature(javaSignature, txSignature, generics));
var listOfGenerics = collectedGenerics.getOrDefault(javaSignature, new ArrayList<>());
listOfGenerics.add(generics);
collectedGenerics.put(javaSignature, listOfGenerics);
} }
for (var signature : signatures) { for (var signature : signatures) {
result.add(new MethodWithTphs(method, signature.generics, signature)); generics = signature.generics;
currentMethodOverloads = collectedGenerics.get(signature.java);
var newMethod = new TargetMethod(method.modifier, method.name, convert(method.block), signature.java, signature.tx);
var concreteParams = tphsInMethods.getOrDefault(method, new HashSet<>()).stream().map(sig -> new SignaturePairTarget(convert(sig.signature), convert(sig.parameter))).toList();
result.add(new MethodWithTphs(newMethod, generics, concreteParams));
} }
return result; return result;
} }
private List<MethodParameter> convert(ParameterList superList, ParameterList paraList, IGenerics generics) { private List<MethodParameter> convert(ParameterList superList, ParameterList paraList, JavaGenerics generics) {
var list = new ArrayList<MethodParameter>(); var list = new ArrayList<MethodParameter>();
for (var i = 0; i < paraList.getFormalparalist().size(); i++) { for (var i = 0; i < paraList.getFormalparalist().size(); i++) {
var param = paraList.getParameterAt(i); var param = paraList.getParameterAt(i);
var pattern = (TargetPattern) convert(param, generics); var pattern = (TargetPattern) convert(param);
if (pattern instanceof TargetComplexPattern) pattern = pattern.withName("__var" + i); if (pattern instanceof TargetComplexPattern) pattern = pattern.withName("__var" + i);
list.add(new MethodParameter(pattern).withType(convert(superList.getParameterAt(i).getType(), generics, compiler))); list.add(new MethodParameter(pattern).withType(convert(superList.getParameterAt(i).getType(), generics)));
} }
return list; return list;
} }
protected TargetSwitch.Case convert(SwitchBlock block, IGenerics generics) { protected TargetSwitch.Case convert(SwitchBlock block) {
return new TargetSwitch.Case(block.getLabels().stream().map(s -> convert(s, generics)).toList(), convert((Block) block, generics), block.isExpression); return new TargetSwitch.Case(block.getLabels().stream().map(this::convert).toList(), convert((Block) block), block.isExpression);
} }
protected TargetBlock convert(Block block, IGenerics generics) { protected TargetBlock convert(Block block) {
if (block == null) return null; if (block == null) return null;
return new TargetBlock(block.statements.stream().map(s -> convert(s, generics)).toList()); return new TargetBlock(block.statements.stream().map(this::convert).toList());
} }
protected TargetBlock convertWrapInBlock(Expression expression, IGenerics generics) { protected TargetBlock convertWrapInBlock(Expression expression) {
var res = convert(expression, generics); var res = convert(expression);
if (!(res instanceof TargetBlock)) if (!(res instanceof TargetBlock))
return new TargetBlock(List.of(res)); return new TargetBlock(List.of(res));
return (TargetBlock) res; return (TargetBlock) res;
} }
protected TargetExpression convert(Expression expr, IGenerics generics) { protected TargetExpression convert(Expression expr) {
var converter = new StatementToTargetExpression(this, generics); var converter = new StatementToTargetExpression(this);
expr.accept(converter); expr.accept(converter);
return converter.result; return converter.result;
} }
private TargetField convert(Field input, IGenerics generics) { private TargetField convert(Field input) {
return new TargetField(input.modifier, convert(input.getType(), generics, compiler), input.getName()); return new TargetField(input.modifier, convert(input.getType(), generics.javaGenerics), input.getName());
}
private final Map<String, FunNGenerator.GenericParameters> usedFunN = new HashMap<>();
private final Set<Integer> usedFunNSuperTypes = new HashSet<>();
public Map<String, byte[]> auxiliaries = new HashMap<>();
public TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input) {
return convert(input, generics.javaGenerics);
} }
private static void collectArguments(TargetSpecializedType tspec, List<TargetType> newParams) { private static void collectArguments(TargetSpecializedType tspec, List<TargetType> newParams) {
@@ -778,15 +782,7 @@ public class ASTToTargetAST {
return TargetFunNType.fromParams(params, filteredParams, gep.getReturnType() != null ? 1 : 0); return TargetFunNType.fromParams(params, filteredParams, gep.getReturnType() != null ? 1 : 0);
} }
private FunNGenerator.GenericParameters convertToParameters(TargetFunNType input) {
return null;
}
private boolean isSubtype(TargetType test, TargetType other) { private boolean isSubtype(TargetType test, TargetType other) {
if (other.equals(TargetType.Object)) return true;
if (test instanceof TargetFunNType tfun && other instanceof TargetFunNType ofun)
return isSubtype(new FunNGenerator.GenericParameters(tfun), new FunNGenerator.GenericParameters(ofun));
var testClass = compiler.getClass(new JavaClassName(test.name())); var testClass = compiler.getClass(new JavaClassName(test.name()));
var otherClass = compiler.getClass(new JavaClassName(other.name())); var otherClass = compiler.getClass(new JavaClassName(other.name()));
if (testClass == null) return false; if (testClass == null) return false;
@@ -814,30 +810,28 @@ public class ASTToTargetAST {
} }
public void generateFunNTypes() { public void generateFunNTypes() {
for (var entry : compiler.usedFunN.entrySet()) { for (var entry : usedFunN.entrySet()) {
var gep = entry.getValue(); var gep = entry.getValue();
var superInterfaces = compiler.usedFunN.values().stream() var superInterfaces = usedFunN.values().stream()
.filter(g -> !g.equals(gep)) .filter(g -> !g.equals(gep))
.filter(genericParameters -> isSubtype(gep, genericParameters)) .filter(genericParameters -> isSubtype(gep, genericParameters))
.map(FunNGenerator::getSpecializedClassName) .map(FunNGenerator::getSpecializedClassName)
.toList(); .toList();
var code = FunNGenerator.generateSpecializedBytecode(gep, superInterfaces); var code = FunNGenerator.generateSpecializedBytecode(gep, superInterfaces);
compiler.auxiliaries.put(entry.getKey(), code);
try {
classLoader.findClass(entry.getKey());
} catch (ClassNotFoundException e) {
try {
classLoader.loadClass(code);
} catch (LinkageError ignored) {}
}
auxiliaries.put(entry.getKey(), code);
} }
} }
// FIXME This method shouldn't be used protected TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, GenerateGenerics generics) {
@Deprecated
public TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input) {
return convert(input, all.getFirst().javaGenerics, compiler);
}
public TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, IGenerics generics) {
return convert(input, generics, compiler);
}
static public TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, IGenerics generics, JavaTXCompiler compiler) {
return input.acceptTV(new TypeVisitor<>() { return input.acceptTV(new TypeVisitor<>() {
@Override @Override
public TargetType visit(RefType refType) { public TargetType visit(RefType refType) {
@@ -849,31 +843,31 @@ public class ASTToTargetAST {
} }
var params = refType.getParaList().stream().map(type -> { var params = refType.getParaList().stream().map(type -> {
return convert(type, generics, compiler); return convert(type, generics);
}).toList(); }).toList();
if (name.matches("Fun\\d+\\$\\$")) { // TODO This seems like a bad idea if (name.matches("Fun\\d+\\$\\$")) { // TODO This seems like a bad idea
var returnType = FunNGenerator.getReturnType(params); var returnType = FunNGenerator.getReturnType(params);
var className = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), returnType); var className = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), returnType);
if (!compiler.usedFunNSuperTypes.contains(params.size())) { if (!usedFunNSuperTypes.contains(params.size())) {
compiler.usedFunNSuperTypes.add(params.size()); usedFunNSuperTypes.add(params.size());
var code = FunNGenerator.generateSuperBytecode(params.size() - 1, returnType != null ? 1 : 0); var code = FunNGenerator.generateSuperBytecode(params.size() - 1, returnType != null ? 1 : 0);
var superClassName = FunNGenerator.getSuperClassName(params.size() - 1, returnType != null ? 1 : 0); var superClassName = FunNGenerator.getSuperClassName(params.size() - 1, returnType != null ? 1 : 0);
try { try {
compiler.classLoader.findClass(superClassName); classLoader.findClass(superClassName);
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
try { try {
compiler.classLoader.loadClass(superClassName, code); classLoader.loadClass(code);
} catch (LinkageError ignored) {} } catch (LinkageError ignored) {}
} }
compiler.auxiliaries.put(superClassName, code); auxiliaries.put(superClassName, code);
} }
FunNGenerator.GenericParameters gep = null; FunNGenerator.GenericParameters gep = null;
if (!compiler.usedFunN.containsKey(className)) { if (!usedFunN.containsKey(className)) {
gep = new FunNGenerator.GenericParameters(params, returnType != null ? 1 : 0); gep = new FunNGenerator.GenericParameters(params, returnType != null ? 1 : 0);
compiler.usedFunN.put(className, gep); usedFunN.put(className, gep);
} else { } else {
gep = compiler.usedFunN.get(className); gep = usedFunN.get(className);
} }
return flattenFunNType(params, gep); return flattenFunNType(params, gep);
} }
@@ -882,7 +876,7 @@ public class ASTToTargetAST {
@Override @Override
public TargetType visit(SuperWildcardType superWildcardType) { public TargetType visit(SuperWildcardType superWildcardType) {
return new TargetSuperWildcard(convert(superWildcardType.getInnerType(), generics, compiler)); return new TargetSuperWildcard(convert(superWildcardType.getInnerType(), generics));
} }
@Override @Override
@@ -892,7 +886,7 @@ public class ASTToTargetAST {
@Override @Override
public TargetType visit(ExtendsWildcardType extendsWildcardType) { public TargetType visit(ExtendsWildcardType extendsWildcardType) {
return new TargetExtendsWildcard(convert(extendsWildcardType.getInnerType(), generics, compiler)); return new TargetExtendsWildcard(convert(extendsWildcardType.getInnerType(), generics));
} }
@Override @Override

View File

@@ -18,9 +18,9 @@ import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
public abstract class GenerateGenerics implements IGenerics { public abstract class GenerateGenerics {
private final JavaTXCompiler compiler; private final ASTToTargetAST astToTargetAST;
public class TPH { public class TPH {
private final TypePlaceholder wrap; private final TypePlaceholder wrap;
@@ -136,8 +136,8 @@ public abstract class GenerateGenerics implements IGenerics {
Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes = new HashMap<>(); Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes = new HashMap<>();
Map<TypePlaceholder, TypePlaceholder> equality = new HashMap<>(); Map<TypePlaceholder, TypePlaceholder> equality = new HashMap<>();
GenerateGenerics(JavaTXCompiler compiler, ResultSet constraints) { GenerateGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) {
this.compiler = compiler; this.astToTargetAST = astToTargetAST;
for (var constraint : constraints.results) { for (var constraint : constraints.results) {
if (constraint instanceof PairTPHsmallerTPH p) { if (constraint instanceof PairTPHsmallerTPH p) {
Target.logger.info(p.left + " " + p.left.getVariance()); Target.logger.info(p.left + " " + p.left.getVariance());
@@ -153,12 +153,22 @@ public abstract class GenerateGenerics implements IGenerics {
Target.logger.info("Simplified constraints: " + simplifiedConstraints); Target.logger.info("Simplified constraints: " + simplifiedConstraints);
} }
public record GenericsState(Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes, Map<TypePlaceholder, TypePlaceholder> equality) {} /*public record GenericsState(Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes, Map<TypePlaceholder, TypePlaceholder> equality) {}
public GenericsState store() { public GenericsState store() {
return new GenericsState(new HashMap<>(concreteTypes), new HashMap<>(equality)); return new GenericsState(new HashMap<>(concreteTypes), new HashMap<>(equality));
} }
public void restore(GenericsState state) {
this.concreteTypes = state.concreteTypes;
this.equality = state.equality;
}
public void addOverlay(TypePlaceholder from, RefTypeOrTPHOrWildcardOrGeneric to) {
if (to instanceof TypePlaceholder t) equality.put(from, t);
else if (to instanceof RefType t) concreteTypes.put(new TPH(from), t);
}*/
Set<TPH> findTypeVariables(ParameterList params) { Set<TPH> findTypeVariables(ParameterList params) {
var res = new HashSet<TPH>(); var res = new HashSet<TPH>();
for (var param : params.getFormalparalist()) { for (var param : params.getFormalparalist()) {
@@ -273,7 +283,7 @@ public abstract class GenerateGenerics implements IGenerics {
Set<TPH> typeVariablesOfClass, Set<TPH> typeVariablesOfClass,
Set<Pair> result Set<Pair> result
) { ) {
var userDefinedGenericsOfClass = owner.getUserDefinedGenerics(); var userDefinedGenericsOfClass = astToTargetAST.userDefinedGenerics.get(owner);
// Type variables with bounds that are also type variables of the method // Type variables with bounds that are also type variables of the method
for (var typeVariable : new HashSet<>(typeVariables)) { for (var typeVariable : new HashSet<>(typeVariables)) {
@@ -321,7 +331,7 @@ public abstract class GenerateGenerics implements IGenerics {
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver) { if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver) {
if (expressionReceiver.expr instanceof This) { if (expressionReceiver.expr instanceof This) {
var optMethod = ASTToTargetAST.findMethod(owner, methodCall.name, methodCall.signatureArguments().stream().map(x -> getTargetType(x)).toList(), GenerateGenerics.this, compiler); var optMethod = astToTargetAST.findMethod(owner, methodCall.name, methodCall.signatureArguments().stream().map(astToTargetAST::convert).toList());
if (optMethod.isEmpty()) return; if (optMethod.isEmpty()) return;
var method2 = optMethod.get(); var method2 = optMethod.get();
Target.logger.info("In: " + method.getName() + " Method: " + method2.getName()); Target.logger.info("In: " + method.getName() + " Method: " + method2.getName());
@@ -531,6 +541,8 @@ public abstract class GenerateGenerics implements IGenerics {
}); });
} }
abstract void generics(ClassOrInterface owner, Method method, Set<Pair> result, Set<TPH> javaTypeVariablesOfClass);
Set<Pair> family(ClassOrInterface owner, Method method) { Set<Pair> family(ClassOrInterface owner, Method method) {
Set<Pair> result = new HashSet<>(); Set<Pair> result = new HashSet<>();
if (familyOfMethods.containsKey(method)) if (familyOfMethods.containsKey(method))
@@ -554,8 +566,7 @@ public abstract class GenerateGenerics implements IGenerics {
return result; return result;
} }
@Override Set<Pair> generics(ClassOrInterface owner, Method method) {
public Set<Pair> generics(ClassOrInterface owner, Method method) {
if (computedGenericsOfMethods.containsKey(method)) { if (computedGenericsOfMethods.containsKey(method)) {
var cached = computedGenericsOfMethods.get(method); var cached = computedGenericsOfMethods.get(method);
Target.logger.info("Cached " + method.getName() + ": " + cached); Target.logger.info("Cached " + method.getName() + ": " + cached);
@@ -643,10 +654,8 @@ public abstract class GenerateGenerics implements IGenerics {
} }
abstract void generics(ClassOrInterface classOrInterface, Set<Pair> result, Set<TPH> referenced); abstract void generics(ClassOrInterface classOrInterface, Set<Pair> result, Set<TPH> referenced);
abstract void generics(ClassOrInterface owner, Method method, Set<Pair> result, Set<TPH> referenced);
@Override Set<Pair> generics(ClassOrInterface classOrInterface) {
public Set<Pair> generics(ClassOrInterface classOrInterface) {
if (computedGenericsOfClasses.containsKey(classOrInterface)) if (computedGenericsOfClasses.containsKey(classOrInterface))
return computedGenericsOfClasses.get(classOrInterface); return computedGenericsOfClasses.get(classOrInterface);
@@ -757,7 +766,7 @@ public abstract class GenerateGenerics implements IGenerics {
} }
for (var pair : elementsToAddToEquality) { for (var pair : elementsToAddToEquality) {
//System.out.println(pair); Target.logger.info(pair);
addToEquality(pair.left, pair.right, referenced); addToEquality(pair.left, pair.right, referenced);
} }
} }
@@ -910,7 +919,7 @@ public abstract class GenerateGenerics implements IGenerics {
} }
} }
if (infima.size() > 1) { if (infima.size() > 1) {
//System.out.println(infima); Target.logger.info(infima);
for (var pair : infima) { for (var pair : infima) {
var returnTypes = findTypeVariables(method.getReturnType()); var returnTypes = findTypeVariables(method.getReturnType());
var chain = findConnectionToReturnType(returnTypes, input, new HashSet<>(), pair.left); var chain = findConnectionToReturnType(returnTypes, input, new HashSet<>(), pair.left);
@@ -981,13 +990,7 @@ public abstract class GenerateGenerics implements IGenerics {
} while (foundInfima); } while (foundInfima);
} }
@Override RefTypeOrTPHOrWildcardOrGeneric getType(RefTypeOrTPHOrWildcardOrGeneric type) {
public TypePlaceholder getEqualType(TypePlaceholder tph) {
return this.equality.getOrDefault(tph, tph);
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric getType(RefTypeOrTPHOrWildcardOrGeneric type) {
if (type instanceof TypePlaceholder tph) { if (type instanceof TypePlaceholder tph) {
if (equality.containsKey(tph)) { if (equality.containsKey(tph)) {
return getType(equality.get(tph)); return getType(equality.get(tph));
@@ -997,16 +1000,15 @@ public abstract class GenerateGenerics implements IGenerics {
return type; return type;
} }
@Override TargetType getTargetType(RefTypeOrTPHOrWildcardOrGeneric in) {
public TargetType getTargetType(RefTypeOrTPHOrWildcardOrGeneric in) {
if (in instanceof TypePlaceholder tph) { if (in instanceof TypePlaceholder tph) {
if (equality.containsKey(tph)) { if (equality.containsKey(tph)) {
return getTargetType(equality.get(tph)); return getTargetType(equality.get(tph));
} }
var type = concreteTypes.get(new TPH(tph)); var type = concreteTypes.get(new TPH(tph));
if (type == null) return new TargetGenericType(tph.getName()); if (type == null) return new TargetGenericType(tph.getName());
return ASTToTargetAST.convert(type, this, compiler); return astToTargetAST.convert(type, this);
} }
return ASTToTargetAST.convert(in, this, compiler); return astToTargetAST.convert(in, this);
} }
} }

View File

@@ -9,20 +9,21 @@ import de.dhbwstuttgart.target.tree.type.TargetType;
import java.util.*; import java.util.*;
public class GenericsResult { public class GenericsResult {
private final IGenerics generics; private final GenerateGenerics generics;
GenericsResult(IGenerics generics) { GenericsResult(GenerateGenerics generics) {
this.generics = generics; this.generics = generics;
} }
public GenericsResultSet get(ClassOrInterface clazz) { public GenericsResultSet get(ClassOrInterface clazz) {
var generics = this.generics.generics(clazz); var generics = this.generics.computedGenericsOfClasses.get(clazz);
return new GenericsResultSet(generics, this.generics); return new GenericsResultSet(generics, this.generics.equality);
} }
public GenericsResultSet get(ClassOrInterface clazz, Method method) { // TODO Compute generics if not present?
var generics = this.generics.generics(clazz, method); public GenericsResultSet get(Method method) {
return new GenericsResultSet(generics, this.generics); var generics = this.generics.computedGenericsOfMethods.get(method);
return new GenericsResultSet(generics, this.generics.equality);
} }
public BoundsList getBounds(RefTypeOrTPHOrWildcardOrGeneric type, ClassOrInterface clazz) { public BoundsList getBounds(RefTypeOrTPHOrWildcardOrGeneric type, ClassOrInterface clazz) {
@@ -33,7 +34,7 @@ public class GenericsResult {
var resolvedType = resolve(type); var resolvedType = resolve(type);
type = resolvedType; type = resolvedType;
if (type instanceof TypePlaceholder) { if (type instanceof TypePlaceholder) {
var methodGenerics = get(clazz, method); var methodGenerics = get(method);
var classGenerics = get(clazz); var classGenerics = get(clazz);
List<Bound> result = new ArrayList<>(); List<Bound> result = new ArrayList<>();
@@ -68,4 +69,8 @@ public class GenericsResult {
return this.generics.getType(tph); return this.generics.getType(tph);
return type; return type;
} }
public TargetType resolveTarget(RefTypeOrTPHOrWildcardOrGeneric type) {
return this.generics.getTargetType(type);
}
} }

View File

@@ -4,18 +4,17 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.result.PairTPHequalRefTypeOrWildcardType; import de.dhbwstuttgart.typeinference.result.PairTPHequalRefTypeOrWildcardType;
import de.dhbwstuttgart.typeinference.result.PairTPHsmallerTPH; import de.dhbwstuttgart.typeinference.result.PairTPHsmallerTPH;
import de.dhbwstuttgart.typeinference.result.ResultPair; import de.dhbwstuttgart.typeinference.result.ResultPair;
import org.antlr.v4.codegen.model.decl.ContextRuleListIndexedGetterDecl;
import java.util.*; import java.util.*;
public class GenericsResultSet extends AbstractSet<GenerateGenerics.Pair> { public class GenericsResultSet extends AbstractSet<GenerateGenerics.Pair> {
final Set<GenerateGenerics.Pair> backing; final Set<GenerateGenerics.Pair> backing;
final IGenerics generics; final Map<TypePlaceholder, TypePlaceholder> equality;
public GenericsResultSet(Set<GenerateGenerics.Pair> backing, IGenerics generics) { public GenericsResultSet(Set<GenerateGenerics.Pair> backing, Map<TypePlaceholder, TypePlaceholder> equality) {
this.backing = backing == null ? new HashSet<>() : new HashSet<>(backing); this.backing = backing == null ? new HashSet<>() : new HashSet<>(backing);
this.generics = generics; this.equality = equality;
} }
@Override @Override
@@ -29,7 +28,7 @@ public class GenericsResultSet extends AbstractSet<GenerateGenerics.Pair> {
} }
public Optional<ResultPair<?, ?>> getResultPairFor(TypePlaceholder tph) { public Optional<ResultPair<?, ?>> getResultPairFor(TypePlaceholder tph) {
var tph2 = generics.getEqualType(tph); var tph2 = equality.getOrDefault(tph, tph);
return this.stream().filter(pair -> { return this.stream().filter(pair -> {
return pair.left.resolve().equals(tph2); return pair.left.resolve().equals(tph2);
}).findFirst().map(pair -> { }).findFirst().map(pair -> {

View File

@@ -1,22 +0,0 @@
package de.dhbwstuttgart.target.generate;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.target.tree.type.TargetType;
import java.util.Set;
public interface IGenerics {
Set<GenerateGenerics.Pair> generics(ClassOrInterface classOrInterface);
Set<GenerateGenerics.Pair> generics(ClassOrInterface owner, Method method);
RefTypeOrTPHOrWildcardOrGeneric getType(RefTypeOrTPHOrWildcardOrGeneric type);
TypePlaceholder getEqualType(TypePlaceholder tph);
TargetType getTargetType(RefTypeOrTPHOrWildcardOrGeneric in);
}

View File

@@ -1,6 +1,5 @@
package de.dhbwstuttgart.target.generate; package de.dhbwstuttgart.target.generate;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
@@ -8,8 +7,8 @@ import de.dhbwstuttgart.typeinference.result.ResultSet;
import java.util.Set; import java.util.Set;
final class JavaGenerics extends GenerateGenerics { final class JavaGenerics extends GenerateGenerics {
JavaGenerics(JavaTXCompiler compiler, ResultSet constraints) { JavaGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) {
super(compiler, constraints); super(astToTargetAST, constraints);
} }
@Override @Override

View File

@@ -1,60 +0,0 @@
package de.dhbwstuttgart.target.generate;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.target.tree.type.TargetGenericType;
import de.dhbwstuttgart.target.tree.type.TargetType;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class OverlayGenerics implements IGenerics {
private final IGenerics wrapped;
private final ASTToTargetAST converter;
private final Map<TypePlaceholder, TargetType> overlay;
public OverlayGenerics(IGenerics wrapped, ASTToTargetAST converter) {
this.wrapped = wrapped;
this.converter = converter;
this.overlay = new HashMap<>();
}
public void addOverlay(TypePlaceholder tph, TargetType type) {
this.overlay.put(tph, type);
}
@Override
public Set<GenerateGenerics.Pair> generics(ClassOrInterface classOrInterface) {
return wrapped.generics(classOrInterface);
}
@Override
public Set<GenerateGenerics.Pair> generics(ClassOrInterface owner, Method method) {
return wrapped.generics(owner, method);
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric getType(RefTypeOrTPHOrWildcardOrGeneric type) {
return wrapped.getType(type);
}
@Override
public TypePlaceholder getEqualType(TypePlaceholder tph) {
return wrapped.getEqualType(tph);
}
@Override
public TargetType getTargetType(RefTypeOrTPHOrWildcardOrGeneric in) {
if (in instanceof TypePlaceholder tph) {
var overlay = this.overlay.get(tph);
if (overlay != null) return overlay;
var type = getType(tph);
if (type == null) return new TargetGenericType(tph.getName());
return wrapped.getTargetType(type);
}
return ASTToTargetAST.convert(in, this, converter.compiler);
}
}

View File

@@ -1,6 +1,5 @@
package de.dhbwstuttgart.target.generate; package de.dhbwstuttgart.target.generate;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
@@ -8,26 +7,25 @@ import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.target.Target;
import de.dhbwstuttgart.target.tree.MethodParameter; import de.dhbwstuttgart.target.tree.MethodParameter;
import de.dhbwstuttgart.target.tree.TargetMethod; import de.dhbwstuttgart.target.tree.TargetMethod;
import de.dhbwstuttgart.target.tree.expression.*; import de.dhbwstuttgart.target.tree.expression.*;
import de.dhbwstuttgart.target.tree.type.*; import de.dhbwstuttgart.target.tree.type.*;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.sql.Array;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
public class StatementToTargetExpression implements ASTVisitor { public class StatementToTargetExpression implements ASTVisitor {
public StatementToTargetExpression(ASTToTargetAST converter, IGenerics generics) { public StatementToTargetExpression(ASTToTargetAST converter) {
this.converter = converter; this.converter = converter;
this.generics = generics;
} }
public TargetExpression result; public TargetExpression result;
private final IGenerics generics;
private final ASTToTargetAST converter; private final ASTToTargetAST converter;
@Override @Override
@@ -35,125 +33,105 @@ public class StatementToTargetExpression implements ASTVisitor {
throw new NotImplementedException(); throw new NotImplementedException();
} }
private class LambdaCaptureFinder extends TracingStatementVisitor {
// TODO The same mechanism is implemented in Codegen, maybe use it from there?
final Stack<Set<String>> localVariables = new Stack<>();
private final List<MethodParameter> parameters;
private final List<MethodParameter> captures;
LambdaCaptureFinder(List<MethodParameter> parameters, List<MethodParameter> captures) {
localVariables.push(new HashSet<>());
this.parameters = parameters;
this.captures = captures;
}
boolean hasLocalVar(String name) {
for (var localVariables : this.localVariables) {
if (localVariables.contains(name))
return true;
}
return false;
}
@Override
public void visit(Block block) {
localVariables.push(new HashSet<>());
super.visit(block);
localVariables.pop();
}
@Override
public void visit(LocalVar localVar) {
super.visit(localVar);
var capture = new MethodParameter(new TargetTypePattern(converter.convert(localVar.getType(), generics), localVar.name));
if (!hasLocalVar(localVar.name) && !parameters.contains(capture) && !captures.contains(capture))
captures.add(capture);
}
@Override
public void visit(LocalVarDecl varDecl) {
var localVariables = this.localVariables.peek();
localVariables.add(varDecl.getName());
}
@Override
public void visit(LambdaExpression lambda) {
var newCaptures = new ArrayList<MethodParameter>();
var captureFinder = new LambdaCaptureFinder(createParameters(lambda), newCaptures);
lambda.methodBody.accept(captureFinder);
newCaptures.removeAll(parameters);
captures.addAll(newCaptures);
}
}
private List<MethodParameter> createParameters(LambdaExpression lambda) {
return StreamSupport.stream(lambda.params.spliterator(), false)
.map(p -> (FormalParameter) p)
.map(p -> new MethodParameter(new TargetTypePattern(converter.convert(p.getType(), generics), p.getName())))
.toList();
}
@Override @Override
public void visit(LambdaExpression lambdaExpression) { public void visit(LambdaExpression lambdaExpression) {
var parameters = createParameters(lambdaExpression); var parameters = StreamSupport.stream(lambdaExpression.params.spliterator(), false)
List<MethodParameter> captures = new ArrayList<>(); .map(p -> (FormalParameter) p)
var visitor = new LambdaCaptureFinder(parameters, captures); .map(p -> new MethodParameter(new TargetTypePattern(converter.convert(p.getType()), p.getName())))
lambdaExpression.methodBody.accept(visitor); .toList();
TargetMethod.Signature signature = new TargetMethod.Signature(Set.of(), parameters, converter.convert(lambdaExpression.getReturnType(), generics));; List<MethodParameter> captures = new ArrayList<>();
var tpe = converter.convert(lambdaExpression.getType(), generics); lambdaExpression.methodBody.accept(new TracingStatementVisitor() {
result = new TargetLambdaExpression(tpe, captures, signature, converter.convert(lambdaExpression.methodBody, this.generics)); // TODO The same mechanism is implemented in Codegen, maybe use it from there?
final Stack<Set<String>> localVariables = new Stack<>();
{
localVariables.push(new HashSet<>());
}
boolean hasLocalVar(String name) {
for (var localVariables : this.localVariables) {
if (localVariables.contains(name))
return true;
}
return false;
}
@Override
public void visit(Block block) {
localVariables.push(new HashSet<>());
super.visit(block);
localVariables.pop();
}
@Override
public void visit(LocalVar localVar) {
super.visit(localVar);
var capture = new MethodParameter(new TargetTypePattern(converter.convert(localVar.getType()), localVar.name));
if (!hasLocalVar(localVar.name) && !parameters.contains(capture) && !captures.contains(capture))
captures.add(capture);
}
@Override
public void visit(LocalVarDecl varDecl) {
var localVariables = this.localVariables.peek();
localVariables.add(varDecl.getName());
}
@Override
public void visit(LambdaExpression lambda) {
} // Don't look at lambda expressions
});
TargetMethod.Signature signature = new TargetMethod.Signature(Set.of(), parameters, converter.convert(lambdaExpression.getReturnType()));;
var tpe = converter.convert(lambdaExpression.getType());
result = new TargetLambdaExpression(tpe, captures, signature, converter.convert(lambdaExpression.methodBody));
} }
@Override @Override
public void visit(Assign assign) { public void visit(Assign assign) {
TargetExpression left; TargetExpression left;
if (assign.lefSide instanceof AssignToLocal) { if (assign.lefSide instanceof AssignToLocal) {
left = converter.convert(((AssignToLocal) assign.lefSide).localVar, this.generics); left = converter.convert(((AssignToLocal) assign.lefSide).localVar);
} else { } else {
left = converter.convert(((AssignToField) assign.lefSide).field, this.generics); left = converter.convert(((AssignToField) assign.lefSide).field);
} }
result = new TargetAssign(converter.convert(assign.getType(), generics), left, converter.convert(assign.rightSide, this.generics)); result = new TargetAssign(converter.convert(assign.getType()), left, converter.convert(assign.rightSide));
} }
@Override @Override
public void visit(BinaryExpr binary) { public void visit(BinaryExpr binary) {
result = switch (binary.operation) { result = switch (binary.operation) {
case ADD -> new TargetBinaryOp.Add(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics)); case ADD -> new TargetBinaryOp.Add(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case SUB -> new TargetBinaryOp.Sub(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics)); case SUB -> new TargetBinaryOp.Sub(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case MUL -> new TargetBinaryOp.Mul(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics)); case MUL -> new TargetBinaryOp.Mul(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case MOD -> new TargetBinaryOp.Rem(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics)); case MOD -> new TargetBinaryOp.Rem(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case AND -> new TargetBinaryOp.BAnd(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics)); case AND -> new TargetBinaryOp.BAnd(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case OR -> new TargetBinaryOp.BOr(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics)); case OR -> new TargetBinaryOp.BOr(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case XOR -> new TargetBinaryOp.XOr(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics)); case XOR -> new TargetBinaryOp.XOr(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case DIV -> new TargetBinaryOp.Div(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics)); case DIV -> new TargetBinaryOp.Div(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case LESSTHAN -> new TargetBinaryOp.Less(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics)); case LESSTHAN -> new TargetBinaryOp.Less(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case BIGGERTHAN -> new TargetBinaryOp.Greater(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics)); case BIGGERTHAN -> new TargetBinaryOp.Greater(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case LESSEQUAL -> new TargetBinaryOp.LessOrEqual(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics)); case LESSEQUAL -> new TargetBinaryOp.LessOrEqual(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case BIGGEREQUAL -> new TargetBinaryOp.GreaterOrEqual(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics)); case BIGGEREQUAL -> new TargetBinaryOp.GreaterOrEqual(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case EQUAL -> new TargetBinaryOp.Equal(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics)); case EQUAL -> new TargetBinaryOp.Equal(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case NOTEQUAL -> new TargetBinaryOp.NotEqual(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics)); case NOTEQUAL -> new TargetBinaryOp.NotEqual(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
}; };
} }
@Override @Override
public void visit(BoolExpression bool) { public void visit(BoolExpression bool) {
result = switch(bool.operation) { Target.logger.info("BoolExpression");
case OR -> new TargetBinaryOp.Or(converter.convert(bool.getType(), generics), converter.convert(bool.lexpr, generics), converter.convert(bool.rexpr, generics));
case AND -> new TargetBinaryOp.And(converter.convert(bool.getType(), generics), converter.convert(bool.lexpr, generics), converter.convert(bool.rexpr, generics));
};
} }
@Override @Override
public void visit(Block block) { public void visit(Block block) {
result = converter.convert(block, generics); result = converter.convert(block);
} }
@Override @Override
public void visit(CastExpr castExpr) { public void visit(CastExpr castExpr) {
result = new TargetCast(converter.convert(castExpr.getType(), generics), converter.convert(castExpr.expr, generics)); result = new TargetCast(converter.convert(castExpr.getType()), converter.convert(castExpr.expr));
} }
@Override @Override
@@ -164,46 +142,46 @@ public class StatementToTargetExpression implements ASTVisitor {
@Override @Override
public void visit(FieldVar fieldVar) { public void visit(FieldVar fieldVar) {
var isStatic = false; var isStatic = false;
var type = converter.convert(fieldVar.receiver.getType(), generics); var type = converter.convert(fieldVar.receiver.getType());
var clazz = converter.compiler.getClass(new JavaClassName(type.name())); var clazz = converter.compiler.getClass(new JavaClassName(type.name()));
var field = clazz.getField(fieldVar.fieldVarName).orElseThrow(); var field = clazz.getField(fieldVar.fieldVarName).orElseThrow();
result = new TargetFieldVar(converter.convert(fieldVar.getType(), generics), type, Modifier.isStatic(field.modifier), converter.convert(fieldVar.receiver, this.generics), fieldVar.fieldVarName); result = new TargetFieldVar(converter.convert(fieldVar.getType()), type, Modifier.isStatic(field.modifier), converter.convert(fieldVar.receiver), fieldVar.fieldVarName);
} }
@Override @Override
public void visit(ForStmt forStmt) { public void visit(ForStmt forStmt) {
result = new TargetFor( result = new TargetFor(
forStmt.initializer.stream().map(c -> converter.convert(c, generics)).toList(), forStmt.initializer.stream().map(converter::convert).toList(),
forStmt.condition != null ? converter.convert(forStmt.condition, generics) : null, forStmt.condition != null ? converter.convert(forStmt.condition) : null,
forStmt.loopExpr.stream().map(e -> converter.convert(e, generics)).toList(), forStmt.loopExpr.stream().map(converter::convert).toList(),
converter.convertWrapInBlock(forStmt.block, generics) converter.convertWrapInBlock(forStmt.block)
); );
} }
@Override @Override
public void visit(ForEachStmt forEachStmt) { public void visit(ForEachStmt forEachStmt) {
result = new TargetForEach(converter.convert(forEachStmt.statement, generics), converter.convert(forEachStmt.expression, generics), converter.convertWrapInBlock(forEachStmt.block, generics)); result = new TargetForEach(converter.convert(forEachStmt.statement), converter.convert(forEachStmt.expression), converter.convertWrapInBlock(forEachStmt.block));
} }
@Override @Override
public void visit(IfStmt ifStmt) { public void visit(IfStmt ifStmt) {
result = new TargetIf(converter.convert(ifStmt.expr, generics), converter.convertWrapInBlock(ifStmt.then_block, generics), ifStmt.else_block != null ? converter.convertWrapInBlock(ifStmt.else_block, generics) : null); result = new TargetIf(converter.convert(ifStmt.expr), converter.convertWrapInBlock(ifStmt.then_block), ifStmt.else_block != null ? converter.convertWrapInBlock(ifStmt.else_block) : null);
} }
@Override @Override
public void visit(InstanceOf instanceOf) { public void visit(InstanceOf instanceOf) {
result = new TargetInstanceOf(converter.convert(instanceOf.getExpression(), generics), converter.convert(instanceOf.getPattern(), this.generics)); result = new TargetInstanceOf(converter.convert(instanceOf.getExpression()), converter.convert(instanceOf.getPattern()));
} }
@Override @Override
public void visit(LocalVar localVar) { public void visit(LocalVar localVar) {
result = new TargetLocalVar(converter.convert(localVar.getType(), generics), localVar.name); result = new TargetLocalVar(converter.convert(localVar.getType()), localVar.name);
} }
@Override @Override
public void visit(LocalVarDecl localVarDecl) { public void visit(LocalVarDecl localVarDecl) {
// TODO No value, is this correct? // TODO No value, is this correct?
result = new TargetVarDecl(converter.convert(localVarDecl.getType(), generics), localVarDecl.getName(), null); result = new TargetVarDecl(converter.convert(localVarDecl.getType()), localVarDecl.getName(), null);
} }
static boolean convertsTo(TargetType from, TargetType to) { static boolean convertsTo(TargetType from, TargetType to) {
@@ -212,25 +190,25 @@ public class StatementToTargetExpression implements ASTVisitor {
return to.equals(from); return to.equals(from);
} }
Optional<Method> findMethod(JavaClassName className, String name, List<TargetType> args, IGenerics generics, JavaTXCompiler compiler) { Optional<Method> findMethod(JavaClassName className, String name, List<TargetType> args) {
return ASTToTargetAST.findMethod(converter.compiler.getClass(className), name, args, generics, compiler); return converter.findMethod(converter.compiler.getClass(className), name, args);
} }
@Override @Override
public void visit(MethodCall methodCall) { public void visit(MethodCall methodCall) {
var receiverType = converter.convert(methodCall.receiver.getType(), generics); var receiverType = converter.convert(methodCall.receiver.getType());
var isFunNType = receiverType instanceof TargetFunNType; var isFunNType = receiverType instanceof TargetFunNType;
var returnType = isFunNType ? TargetType.Object : converter.convert(methodCall.signature.getLast(), generics); var returnType = isFunNType ? TargetType.Object : converter.convert(methodCall.signature.get(methodCall.signature.size() - 1));
var receiverName = new JavaClassName(converter.convert(methodCall.receiver.getType(), generics).name()); var receiverName = new JavaClassName(converter.convert(methodCall.receiver.getType()).name());
var argList = methodCall.signature.stream().map(sig -> converter.convert(sig, generics)).toList(); var argList = methodCall.signature.stream().map(converter::convert).toList();
argList = argList.subList(0, argList.size() - 1); argList = argList.subList(0, argList.size() - 1);
Method foundMethod = null; Method foundMethod = null;
var isStatic = false; var isStatic = false;
var isInterface = true; var isInterface = true;
var isPrivate = false; var isPrivate = false;
var signature = methodCall.signatureArguments().stream().map(sig -> converter.convert(sig, generics)).toList(); var signature = methodCall.signatureArguments().stream().map(converter::convert).toList();
// Add used TPHs to containing method // Add used TPHs to containing method
for (var i = 0; i < methodCall.signatureArguments().size(); i++) { for (var i = 0; i < methodCall.signatureArguments().size(); i++) {
@@ -240,38 +218,49 @@ public class StatementToTargetExpression implements ASTVisitor {
var receiverClass = converter.compiler.getClass(receiverName); var receiverClass = converter.compiler.getClass(receiverName);
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver && expressionReceiver.expr instanceof This) { if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver && expressionReceiver.expr instanceof This) {
if (receiverClass == null) throw new DebugException("Class " + receiverName + " does not exist!"); if (receiverClass == null) throw new DebugException("Class " + receiverName + " does not exist!");
var thisMethod = ASTToTargetAST.findMethod(receiverClass, methodCall.name, signature, generics, converter.compiler); var thisMethod = converter.findMethod(receiverClass, methodCall.name, signature);
if (thisMethod.isEmpty()) {
Target.logger.error("Expected: " + receiverClass.getClassName() + "." + methodCall.name + "(" +
signature.stream().map(TargetType::toSignature).collect(Collectors.joining())+ ")" );
AtomicBoolean hasM = new AtomicBoolean(false);
receiverClass.getMethods().forEach(m -> {
if (Objects.equals(m.getName(), methodCall.name)) {
hasM.set(true);
Target.logger.error("But only has: " + m.name + "(" +
m.getParameterList().getFormalparalist().stream().map(t -> t.getType().toString()).collect(Collectors.joining())+ ")" );
}
});
if (!hasM.get())
Target.logger.error("But does not contain method at all");
}
ClassOrInterface finalReceiverClass = receiverClass; ClassOrInterface finalReceiverClass = receiverClass;
foundMethod = thisMethod.orElseGet(() -> findMethod(finalReceiverClass.getSuperClass().getName(), methodCall.name, signature, generics, converter.compiler).orElseThrow()); foundMethod = thisMethod.orElseGet(() -> findMethod(finalReceiverClass.getSuperClass().getName(), methodCall.name, signature).orElseThrow());
} else if (!isFunNType) { } else if (!isFunNType) {
receiverClass = converter.compiler.getClass(receiverName); receiverClass = converter.compiler.getClass(receiverName);
if (receiverClass == null) throw new DebugException("Class " + receiverName + " does not exist!"); if (receiverClass == null) throw new DebugException("Class " + receiverName + " does not exist!");
foundMethod = findMethod(receiverName, methodCall.name, signature, generics, converter.compiler).orElseThrow(); foundMethod = findMethod(receiverName, methodCall.name, signature).orElseThrow();
} }
if (!isFunNType) { if (!isFunNType) {
returnType = converter.convert(foundMethod.getReturnType(), generics); returnType = converter.convert(foundMethod.getReturnType());
argList = foundMethod.getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType(), generics)).toList(); argList = foundMethod.getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType())).toList();
isStatic = Modifier.isStatic(foundMethod.modifier); isStatic = Modifier.isStatic(foundMethod.modifier);
isPrivate = Modifier.isPrivate(foundMethod.modifier); isPrivate = Modifier.isPrivate(foundMethod.modifier);
isInterface = receiverClass.isInterface(); isInterface = receiverClass.isInterface();
} }
//System.out.println(argList); Target.logger.info(argList);
result = new TargetMethodCall( result = new TargetMethodCall(converter.convert(methodCall.getType()), returnType, argList, converter.convert(methodCall.receiver), methodCall.getArgumentList().getArguments().stream().map(converter::convert).toList(), receiverType, methodCall.name, isStatic, isInterface, isPrivate);
converter.convert(methodCall.getType(), generics), returnType, argList,
converter.convert(methodCall.receiver, generics),
methodCall.getArgumentList().getArguments().stream().map(arg -> converter.convert(arg, generics)).toList(),
receiverType, methodCall.name, isStatic, isInterface, isPrivate
);
} }
@Override @Override
public void visit(NewClass newClass) { public void visit(NewClass newClass) {
var receiverName = new JavaClassName(newClass.name); var receiverName = new JavaClassName(newClass.name);
var ctor = converter.findConstructor(converter.compiler.getClass(receiverName), newClass.signatureArguments().stream().map(arg -> converter.convert(arg, generics)).toList(), generics); var ctor = converter.findConstructor(converter.compiler.getClass(receiverName), newClass.signatureArguments().stream().map(converter::convert).toList());
var signature = ctor.orElseThrow().getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType(), generics)).toList(); var signature = ctor.orElseThrow().getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType())).toList();
result = new TargetNew(new TargetRefType(newClass.name), signature, newClass.getArgumentList().getArguments().stream().map(arg -> converter.convert(arg, generics)).toList()); result = new TargetNew(new TargetRefType(newClass.name), signature, newClass.getArgumentList().getArguments().stream().map(converter::convert).toList());
} }
@Override @Override
@@ -282,7 +271,7 @@ public class StatementToTargetExpression implements ASTVisitor {
@Override @Override
public void visit(Return aReturn) { public void visit(Return aReturn) {
result = new TargetReturn(converter.convert(aReturn.retexpr, generics)); result = new TargetReturn(converter.convert(aReturn.retexpr));
} }
@Override @Override
@@ -302,53 +291,53 @@ public class StatementToTargetExpression implements ASTVisitor {
@Override @Override
public void visit(StaticClassName staticClassName) { public void visit(StaticClassName staticClassName) {
result = new TargetClassName(converter.convert(staticClassName.getType(), generics)); result = new TargetClassName(converter.convert(staticClassName.getType()));
} }
@Override @Override
public void visit(Super aSuper) { public void visit(Super aSuper) {
result = new TargetSuper(converter.convert(aSuper.getType(), generics)); result = new TargetSuper(converter.convert(aSuper.getType()));
} }
@Override @Override
public void visit(This aThis) { public void visit(This aThis) {
result = new TargetThis(converter.convert(aThis.getType(), generics)); result = new TargetThis(converter.convert(aThis.getType()));
} }
@Override @Override
public void visit(WhileStmt whileStmt) { public void visit(WhileStmt whileStmt) {
result = new TargetWhile(converter.convert(whileStmt.expr, generics), converter.convert(whileStmt.loopBlock, generics)); result = new TargetWhile(converter.convert(whileStmt.expr), converter.convert(whileStmt.loopBlock));
} }
@Override @Override
public void visit(DoStmt whileStmt) { public void visit(DoStmt whileStmt) {
result = new TargetDo(converter.convert(whileStmt.expr, generics), converter.convert(whileStmt.loopBlock, generics)); result = new TargetDo(converter.convert(whileStmt.expr), converter.convert(whileStmt.loopBlock));
} }
// TODO These two might not be necessary // TODO These two might not be necessary
@Override @Override
public void visit(AssignToField assignLeftSide) { public void visit(AssignToField assignLeftSide) {
result = converter.convert(assignLeftSide.field, generics); result = converter.convert(assignLeftSide.field);
} }
@Override @Override
public void visit(AssignToLocal assignLeftSide) { public void visit(AssignToLocal assignLeftSide) {
result = converter.convert(assignLeftSide.localVar, generics); result = converter.convert(assignLeftSide.localVar);
} }
@Override @Override
public void visit(SuperCall superCall) { public void visit(SuperCall superCall) {
var aSuper = converter.convert(superCall.receiver.getType(), generics); var aSuper = converter.convert(superCall.receiver.getType());
var type = converter.convert(superCall.getType(), generics); var type = converter.convert(superCall.getType());
var receiverName = new JavaClassName(converter.convert(superCall.receiver.getType(), generics).name()); var receiverName = new JavaClassName(converter.convert(superCall.receiver.getType()).name());
var clazz = converter.compiler.getClass(receiverName); var clazz = converter.compiler.getClass(receiverName);
var signature = superCall.signatureArguments().stream().map(arg -> converter.convert(arg, generics)).toList(); var signature = superCall.signatureArguments().stream().map(converter::convert).toList();
var method = converter.findConstructor(clazz, signature, generics); var method = converter.findConstructor(clazz, signature);
var params = superCall.getArgumentList().getArguments().stream().map(arg -> converter.convert(arg, generics)).toList(); var params = superCall.getArgumentList().getArguments().stream().map(converter::convert).toList();
List<TargetType> argList; List<TargetType> argList;
if (method.isPresent()) { if (method.isPresent()) {
argList = method.get().getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType(), generics)).toList(); argList = method.get().getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType())).toList();
} else { } else {
argList = params.stream().map(TargetExpression::type).toList(); argList = params.stream().map(TargetExpression::type).toList();
} }
@@ -358,28 +347,28 @@ public class StatementToTargetExpression implements ASTVisitor {
@Override @Override
public void visit(ThisCall thisCall) { public void visit(ThisCall thisCall) {
var aThis = converter.convert(thisCall.receiver.getType(), generics); var aThis = converter.convert(thisCall.receiver.getType());
var type = converter.convert(thisCall.getType(), generics); var type = converter.convert(thisCall.getType());
var parameters = thisCall.arglist.getArguments().stream().map(par -> converter.convert(par.getType(), generics)).toList(); var parameters = thisCall.arglist.getArguments().stream().map(par -> converter.convert(par.getType())).toList();
result = new TargetMethodCall(type, type, parameters, new TargetThis(aThis), thisCall.getArgumentList().getArguments().stream().map(arg -> converter.convert(arg, generics)).toList(), aThis, thisCall.name, false, false, false); result = new TargetMethodCall(type, type, parameters, new TargetThis(aThis), thisCall.getArgumentList().getArguments().stream().map(converter::convert).toList(), aThis, thisCall.name, false, false, false);
} }
@Override @Override
public void visit(ExpressionReceiver expressionReceiver) { public void visit(ExpressionReceiver expressionReceiver) {
result = converter.convert(expressionReceiver.expr, generics); result = converter.convert(expressionReceiver.expr);
} }
@Override @Override
public void visit(UnaryExpr unaryExpr) { public void visit(UnaryExpr unaryExpr) {
result = switch (unaryExpr.operation) { result = switch (unaryExpr.operation) {
case NOT -> new TargetUnaryOp.Not(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics)); case NOT -> new TargetUnaryOp.Not(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
case MINUS -> new TargetUnaryOp.Negate(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics)); case MINUS -> new TargetUnaryOp.Negate(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
case PREINCREMENT -> new TargetUnaryOp.PreIncrement(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics)); case PREINCREMENT -> new TargetUnaryOp.PreIncrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
case PREDECREMENT -> new TargetUnaryOp.PreDecrement(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics)); case PREDECREMENT -> new TargetUnaryOp.PreDecrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
case POSTINCREMENT -> new TargetUnaryOp.PostIncrement(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics)); case POSTINCREMENT -> new TargetUnaryOp.PostIncrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
case PLUS -> new TargetUnaryOp.Add(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics)); case PLUS -> new TargetUnaryOp.Add(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
case POSTDECREMENT -> new TargetUnaryOp.PostDecrement(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics)); case POSTDECREMENT -> new TargetUnaryOp.PostDecrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
}; };
} }
@@ -407,12 +396,12 @@ public class StatementToTargetExpression implements ASTVisitor {
@Override @Override
public void visit(Throw aThrow) { public void visit(Throw aThrow) {
result = new TargetThrow(converter.convert(aThrow.expr, generics)); result = new TargetThrow(converter.convert(aThrow.expr));
} }
@Override @Override
public void visit(Ternary ternary) { public void visit(Ternary ternary) {
result = new TargetTernary(converter.convert(ternary.getType(), generics), converter.convert(ternary.cond, generics), converter.convert(ternary.iftrue, generics), converter.convert(ternary.iffalse, generics)); result = new TargetTernary(converter.convert(ternary.getType()), converter.convert(ternary.cond), converter.convert(ternary.iftrue), converter.convert(ternary.iffalse));
} }
record TypeVariants(RefTypeOrTPHOrWildcardOrGeneric in, List<RefTypeOrTPHOrWildcardOrGeneric> types) {} record TypeVariants(RefTypeOrTPHOrWildcardOrGeneric in, List<RefTypeOrTPHOrWildcardOrGeneric> types) {}
@@ -476,8 +465,10 @@ public class StatementToTargetExpression implements ASTVisitor {
var product = cartesianProduct(extractAllPatterns(label.getPattern())); var product = cartesianProduct(extractAllPatterns(label.getPattern()));
for (var l : product) { for (var l : product) {
var oldGenerics = converter.generics;
// Set the generics to matching result set // Set the generics to matching result set
/*for (var generics : converter.currentMethodOverloads) { for (var generics : converter.currentMethodOverloads) {
var java = generics.javaGenerics(); var java = generics.javaGenerics();
var equals = true; var equals = true;
for (var pair : l) { for (var pair : l) {
@@ -486,15 +477,17 @@ public class StatementToTargetExpression implements ASTVisitor {
} }
} }
if (equals) { if (equals) {
converter.generics = generics;
break; break;
} }
}*/ }
overloads.add(converter.convert(case_, generics)); overloads.add(converter.convert(case_));
converter.generics = oldGenerics;
} }
} }
} else { } else {
overloads.add(converter.convert(case_, generics)); overloads.add(converter.convert(case_));
} }
return overloads; return overloads;
@@ -503,10 +496,10 @@ public class StatementToTargetExpression implements ASTVisitor {
TargetSwitch.Case default_ = null; TargetSwitch.Case default_ = null;
for (var block : switchStmt.getBlocks()) { for (var block : switchStmt.getBlocks()) {
if (block.isDefault()) { if (block.isDefault()) {
default_ = new TargetSwitch.Case(converter.convert((Block) block, generics), block.isExpression); default_ = new TargetSwitch.Case(converter.convert((Block) block), block.isExpression);
} }
} }
result = new TargetSwitch(converter.convert(switchStmt.getSwitch(), generics), cases, default_ , converter.convert(switchStmt.getType(), generics), !switchStmt.getStatement()); result = new TargetSwitch(converter.convert(switchStmt.getSwitch()), cases, default_ , converter.convert(switchStmt.getType()), !switchStmt.getStatement());
} }
@Override @Override
@@ -514,12 +507,12 @@ public class StatementToTargetExpression implements ASTVisitor {
@Override @Override
public void visit(SwitchLabel switchLabel) { public void visit(SwitchLabel switchLabel) {
result = converter.convert(switchLabel.getPattern(), this.generics); result = converter.convert(switchLabel.getPattern());
} }
@Override @Override
public void visit(Yield aYield) { public void visit(Yield aYield) {
result = new TargetYield(converter.convert(aYield.retexpr, generics)); result = new TargetYield(converter.convert(aYield.retexpr));
} }
@Override @Override
@@ -589,30 +582,30 @@ public class StatementToTargetExpression implements ASTVisitor {
@Override @Override
public void visit(FormalParameter aPattern) { public void visit(FormalParameter aPattern) {
result = new TargetTypePattern(converter.convert(aPattern.getType(), generics), aPattern.getName()); result = new TargetTypePattern(converter.convert(aPattern.getType()), aPattern.getName());
} }
@Override @Override
public void visit(LiteralPattern literalPattern) { public void visit(LiteralPattern literalPattern) {
result = new TargetExpressionPattern(converter.convert(literalPattern.value, generics)); result = new TargetExpressionPattern(converter.convert(literalPattern.value));
} }
@Override @Override
public void visit(ExpressionPattern aPattern) { public void visit(ExpressionPattern aPattern) {
result = converter.convert(aPattern.getExpression(), generics); result = converter.convert(aPattern.getExpression());
} }
@Override @Override
public void visit(RecordPattern aRecordPattern) { public void visit(RecordPattern aRecordPattern) {
result = new TargetComplexPattern( result = new TargetComplexPattern(
converter.convert(aRecordPattern.getType(), generics), converter.convert(aRecordPattern.getType()),
aRecordPattern.getName(), aRecordPattern.getName(),
aRecordPattern.getSubPattern().stream().map(x -> (TargetPattern) converter.convert(x, generics)).toList() aRecordPattern.getSubPattern().stream().map(x -> (TargetPattern) converter.convert(x)).toList()
); );
} }
@Override @Override
public void visit(GuardedPattern aGuardedPattern) { public void visit(GuardedPattern aGuardedPattern) {
result = new TargetGuard((TargetPattern) converter.convert(aGuardedPattern.getNestedPattern(), generics), converter.convert(aGuardedPattern.getCondition(), generics)); result = new TargetGuard((TargetPattern) converter.convert(aGuardedPattern.getNestedPattern()), converter.convert(aGuardedPattern.getCondition()));
} }
} }

View File

@@ -1,6 +1,5 @@
package de.dhbwstuttgart.target.generate; package de.dhbwstuttgart.target.generate;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
@@ -8,8 +7,8 @@ import de.dhbwstuttgart.typeinference.result.ResultSet;
import java.util.Set; import java.util.Set;
final class TxGenerics extends GenerateGenerics { final class TxGenerics extends GenerateGenerics {
TxGenerics(JavaTXCompiler compiler, ResultSet constraints) { TxGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) {
super(compiler, constraints); super(astToTargetAST, constraints);
} }
@Override @Override

View File

@@ -15,9 +15,4 @@ public record MethodParameter(TargetPattern pattern) {
public MethodParameter withName(String name) { public MethodParameter withName(String name) {
return new MethodParameter(pattern.withName(name)); return new MethodParameter(pattern.withName(name));
} }
@Override
public String toString() {
return pattern.toString();
}
} }

View File

@@ -36,30 +36,30 @@ public record TargetMethod(int access, String name, TargetBlock block, Signature
public static String getDescriptor(TargetType returnType, TargetType... parameters) { public static String getDescriptor(TargetType returnType, TargetType... parameters) {
String ret = "("; String ret = "(";
for (var parameterType : parameters) { for (var parameterType : parameters) {
ret += parameterType.toDescriptor(); ret += parameterType.toSignature();
} }
ret += ")"; ret += ")";
if (returnType == null) ret += "V"; if (returnType == null) ret += "V";
else ret += returnType.toDescriptor(); else ret += returnType.toSignature();
return ret; return ret;
} }
public static String getSignature(Set<TargetGeneric> generics, List<MethodParameter> parameters, TargetType returnType) { public static String getSignature(Set<TargetGeneric> generics, List<MethodParameter> parameters, TargetType returnType) {
String ret = ""; String ret = "";
if (!generics.isEmpty()) { if (generics.size() > 0) {
ret += "<"; ret += "<";
for (var generic : generics) { for (var generic : generics) {
ret += generic.name() + ":" + generic.bound().toSignature(); ret += generic.name() + ":" + generic.bound().toDescriptor();
} }
ret += ">"; ret += ">";
} }
ret += "("; ret += "(";
for (var param : parameters) { for (var param : parameters) {
ret += param.pattern().type().toSignature(); ret += param.pattern().type().toDescriptor();
} }
ret += ")"; ret += ")";
if (returnType == null) ret += "V"; if (returnType == null) ret += "V";
else ret += returnType.toSignature(); else ret += returnType.toDescriptor();
return ret; return ret;
} }

View File

@@ -14,9 +14,4 @@ public record TargetComplexPattern(TargetType type, String name, List<TargetPatt
public TargetComplexPattern withName(String name) { public TargetComplexPattern withName(String name) {
return new TargetComplexPattern(type, name, subPatterns); return new TargetComplexPattern(type, name, subPatterns);
} }
@Override
public String toString() {
return type + "(" + String.join(", ", subPatterns.stream().map(Object::toString).toList()) + ") " + name;
}
} }

View File

@@ -8,42 +8,42 @@ public sealed interface TargetLiteral extends TargetExpression {
record BooleanLiteral(Boolean value) implements TargetLiteral { record BooleanLiteral(Boolean value) implements TargetLiteral {
@Override @Override
public TargetType type() { public TargetType type() {
return TargetType.boolean_; return TargetType.Boolean;
} }
} }
record CharLiteral(Character value) implements TargetLiteral { record CharLiteral(Character value) implements TargetLiteral {
@Override @Override
public TargetType type() { public TargetType type() {
return TargetType.char_; return TargetType.Char;
} }
} }
record IntLiteral(Integer value) implements TargetLiteral { record IntLiteral(Integer value) implements TargetLiteral {
@Override @Override
public TargetType type() { public TargetType type() {
return TargetType.int_; return TargetType.Integer;
} }
} }
record LongLiteral(Long value) implements TargetLiteral { record LongLiteral(Long value) implements TargetLiteral {
@Override @Override
public TargetType type() { public TargetType type() {
return TargetType.long_; return TargetType.Long;
} }
} }
record FloatLiteral(Float value) implements TargetLiteral { record FloatLiteral(Float value) implements TargetLiteral {
@Override @Override
public TargetType type() { public TargetType type() {
return TargetType.float_; return TargetType.Float;
} }
} }
record DoubleLiteral(Double value) implements TargetLiteral { record DoubleLiteral(Double value) implements TargetLiteral {
@Override @Override
public TargetType type() { public TargetType type() {
return TargetType.double_; return TargetType.Double;
} }
} }

View File

@@ -12,9 +12,4 @@ public record TargetTypePattern(TargetType type, String name) implements TargetP
public TargetTypePattern withName(String name) { public TargetTypePattern withName(String name) {
return new TargetTypePattern(type, name); return new TargetTypePattern(type, name);
} }
@Override
public String toString() {
return type + " " + name;
}
} }

View File

@@ -3,12 +3,12 @@ package de.dhbwstuttgart.target.tree.type;
public record TargetExtendsWildcard(TargetType innerType) implements TargetType { public record TargetExtendsWildcard(TargetType innerType) implements TargetType {
@Override @Override
public String toSignature() { public String toSignature() {
return "+" + innerType.toSignature(); return innerType.toSignature();
} }
@Override @Override
public String toDescriptor() { public String toDescriptor() {
return innerType.toDescriptor(); return "+" + innerType.toDescriptor();
} }
@Override @Override
@@ -20,10 +20,5 @@ public record TargetExtendsWildcard(TargetType innerType) implements TargetType
public String name() { public String name() {
return innerType.name(); return innerType.name();
} }
@Override
public String toString() {
return "? extends " + innerType;
}
} }

View File

@@ -36,7 +36,6 @@ public record TargetFunNType(String name, List<TargetType> funNParams, List<Targ
@Override @Override
public String toSignature() { public String toSignature() {
var args = FunNGenerator.getArguments(funNParams); return "L" + getInternalName() + ";";
return "LFun" + args.size() + "$$" + TargetSpecializedType.signatureParameters(funNParams) + ";";
} }
} }

View File

@@ -2,12 +2,12 @@ package de.dhbwstuttgart.target.tree.type;
public record TargetGenericType(String name) implements TargetType { public record TargetGenericType(String name) implements TargetType {
@Override @Override
public String toDescriptor() { public String toSignature() {
return "Ljava/lang/Object;"; // TODO Use bounds for this? return "Ljava/lang/Object;"; // TODO Use bounds for this?
} }
@Override @Override
public String toSignature() { public String toDescriptor() {
return "T" + getInternalName() + ";"; return "T" + getInternalName() + ";";
} }
@@ -15,9 +15,4 @@ public record TargetGenericType(String name) implements TargetType {
public String getInternalName() { public String getInternalName() {
return name; return name;
} }
@Override
public String toString() {
return "'" + name;
}
} }

View File

@@ -12,6 +12,11 @@ public record TargetRefType(String name, List<TargetType> params) implements Tar
return this.name.replaceAll("\\.", "/"); return this.name.replaceAll("\\.", "/");
} }
@Override
public String toSignature() {
return "L" + getInternalName() + ";";
}
// Type erasure means we need to override hashCode and equals to only consider the name // Type erasure means we need to override hashCode and equals to only consider the name
@Override @Override
public int hashCode() { public int hashCode() {
@@ -25,10 +30,4 @@ public record TargetRefType(String name, List<TargetType> params) implements Tar
} }
return false; return false;
} }
@Override
public String toString() {
if (params.isEmpty()) return name;
else return name + "<" + java.lang.String.join(", ", params.stream().map(java.lang.Object::toString).toList()) + ">";
}
} }

View File

@@ -6,27 +6,16 @@ public sealed interface TargetSpecializedType extends TargetType permits TargetF
List<TargetType> params(); List<TargetType> params();
@Override @Override
default String toSignature() { default String toDescriptor() {
String ret = "L" + getInternalName(); String ret = "L" + getInternalName();
ret += signatureParameters(params()); if (params().size() > 0) {
ret += ";";
return ret;
}
static String signatureParameters(List<TargetType> params) {
var ret = "";
if (!params.isEmpty()) {
ret += "<"; ret += "<";
for (var param : params) { for (var param : params()) {
ret += param.toSignature(); ret += param.toDescriptor();
} }
ret += ">"; ret += ">";
} }
ret += ";";
return ret; return ret;
} }
@Override
default String toDescriptor() {
return "L" + getInternalName() + ";";
}
} }

View File

@@ -3,12 +3,12 @@ package de.dhbwstuttgart.target.tree.type;
public record TargetSuperWildcard(TargetType innerType) implements TargetType { public record TargetSuperWildcard(TargetType innerType) implements TargetType {
@Override @Override
public String toSignature() { public String toSignature() {
return "-" + innerType.toSignature(); return innerType.toSignature();
} }
@Override @Override
public String toDescriptor() { public String toDescriptor() {
return innerType.toDescriptor(); return "-" + innerType.toDescriptor();
} }
@Override @Override
@@ -20,11 +20,6 @@ public record TargetSuperWildcard(TargetType innerType) implements TargetType {
public String name() { public String name() {
return innerType.name(); return innerType.name();
} }
@Override
public String toString() {
return "? super " + innerType;
}
} }

View File

@@ -55,7 +55,7 @@ class TypeInsertPlacerClass extends AbstractASTWalker{
@Override @Override
public void visit(Method method) { public void visit(Method method) {
this.method = method; this.method = method;
constraints = generatedGenerics.get(cl, method); constraints = generatedGenerics.get(method);
classConstraints = generatedGenerics.get(cl); classConstraints = generatedGenerics.get(cl);
if(method.getReturnType() instanceof TypePlaceholder) if(method.getReturnType() instanceof TypePlaceholder)
inserts.add(TypeInsertFactory.createInsertPoints( inserts.add(TypeInsertFactory.createInsertPoints(

View File

@@ -9,72 +9,77 @@ import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialUUID;
import de.dhbwstuttgart.typeinference.unify.UnifyContext; import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.annotation.Nullable;
public class Constraint<A extends IConstraintElement> extends HashSet<A> implements Comparable<Constraint<A>>, ISerializableData { public class Constraint<A extends IConstraintElement> extends HashSet<A> implements ISerializableData {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private boolean isInherited = false;//wird beides nur für die Method-Constraints benoetigt private boolean isInherited = false;//wird beides nur für die Method-Constraints benoetigt
private boolean isImplemented = false; private boolean isImplemented = false;
/* /*
* wird verwendet um bei der Codegenerierung die richtige Methoden - Signatur * wird verwendet um bei der Codegenerierung die richtige Methoden - Signatur
* auszuwaehlen * auszuwaehlen
*/ */
/*private*/ Set<A> methodSignatureConstraint = new HashSet<>(); /*private*/ Set<A> methodSignatureConstraint = new HashSet<>();
private Constraint<A> extendConstraint = null; private Constraint<A> extendConstraint = null;
public Constraint() { public Constraint() {
super(); super();
} }
public Constraint(int initialCapacity) { public Constraint(int initialCapacity) {
super(initialCapacity); super(initialCapacity);
} }
public Constraint(boolean isInherited, boolean isImplemented) { public Constraint(boolean isInherited, boolean isImplemented) {
this.isInherited = isInherited; this.isInherited = isInherited;
this.isImplemented = isImplemented; this.isImplemented = isImplemented;
} }
public Constraint(boolean isInherited, boolean isImplemented, Constraint<A> extendConstraint, Set<A> methodSignatureConstraint) { public Constraint(boolean isInherited, boolean isImplemented, Constraint<A> extendConstraint, Set<A> methodSignatureConstraint) {
this.isInherited = isInherited; this.isInherited = isInherited;
this.isImplemented = isImplemented; this.isImplemented = isImplemented;
this.extendConstraint = extendConstraint; this.extendConstraint = extendConstraint;
this.methodSignatureConstraint = methodSignatureConstraint; this.methodSignatureConstraint = methodSignatureConstraint;
} }
public void setIsInherited(boolean isInherited) { public void setIsInherited(boolean isInherited) {
this.isInherited = isInherited; this.isInherited = isInherited;
} }
public boolean isInherited() { public boolean isInherited() {
return isInherited; return isInherited;
} }
public boolean isImplemented() { public boolean isImplemented() {
return isImplemented; return isImplemented;
} }
public Constraint<A> getExtendConstraint() { public Constraint<A> getExtendConstraint() {
return extendConstraint; return extendConstraint;
} }
public void setExtendConstraint(Constraint<A> c) { public void setExtendConstraint(Constraint<A> c) {
extendConstraint = c; extendConstraint = c;
} }
public Set<A> getmethodSignatureConstraint() { public Set<A> getmethodSignatureConstraint() {
return methodSignatureConstraint; return methodSignatureConstraint;
} }
public void setmethodSignatureConstraint(Set<A> c) { public void setmethodSignatureConstraint(Set<A> c) {
methodSignatureConstraint = c; methodSignatureConstraint = c;
} }
public <B extends IConstraintElement> Constraint<B> createdMapped(Function<A,B> mapper) { public <B extends IConstraintElement> Constraint<B> createdMapped(Function<A,B> mapper) {
Constraint<B> result = new Constraint<>(this.size()); Constraint<B> result = new Constraint<>(this.size());
@@ -84,23 +89,16 @@ public class Constraint<A extends IConstraintElement> extends HashSet<A> impleme
return result; return result;
} }
public String toString() { public String toString() {
return super.toString() + "\nisInherited = " + isInherited
+ " isOveridden = " + isImplemented
+ " msc[" + methodSignatureConstraint.size() + "] = " + methodSignatureConstraint
//" + extendsContraint: " + (extendConstraint != null ? extendConstraint.toStringBase() : "null" )
+ "\n";
}
public String toStringBase() {
return super.toString(); return super.toString();
// + "\nisInherited = " + isInherited
// + " isOveridden = " + isImplemented
// + " msc[" + methodSignatureConstraint.size() + "] = " + methodSignatureConstraint
// //" + extendsContraint: " + (extendConstraint != null ? extendConstraint.toStringBase() : "null" )
// + "\n";
}
public String toStringBase() {
return super.toString();
}
@Override
public int compareTo(Constraint<A> o) {
return this.toString().compareTo(o.toString());
} }
private String serialUUID = null; private String serialUUID = null;
@@ -169,4 +167,5 @@ public class Constraint<A extends IConstraintElement> extends HashSet<A> impleme
return keyStorage.getUnserialized(uuid, Constraint.class); return keyStorage.getUnserialized(uuid, Constraint.class);
} }
} }

View File

@@ -4,7 +4,6 @@ import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage; import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap; import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.typeinference.unify.UnifyContext; import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -14,60 +13,58 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import static de.dhbwstuttgart.core.JavaTXCompiler.q;
public class Pair implements Serializable, IConstraintElement, ISerializableData { public class Pair implements Serializable, IConstraintElement, ISerializableData {
public final RefTypeOrTPHOrWildcardOrGeneric TA1; public final RefTypeOrTPHOrWildcardOrGeneric TA1;
public final RefTypeOrTPHOrWildcardOrGeneric TA2; public final RefTypeOrTPHOrWildcardOrGeneric TA2;
private SourceLoc location; private SourceLoc location;
private PairOperator eOperator = PairOperator.SMALLER; private PairOperator eOperator = PairOperator.SMALLER;
private boolean noUnification = false; private boolean noUnification = false;
private Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2) { private Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2) {
this.TA1 = TA1; this.TA1 = TA1;
this.TA2 = TA2; this.TA2 = TA2;
if (TA1 == null || TA2 == null) if (TA1 == null || TA2 == null)
throw new NullPointerException(); throw new NullPointerException();
eOperator = PairOperator.SMALLER; eOperator = PairOperator.SMALLER;
} }
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp) { public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp) {
// Konstruktor // Konstruktor
this(TA1, TA2); this(TA1, TA2);
this.eOperator = eOp; this.eOperator = eOp;
} }
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator e0p, SourceLoc location) { public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator e0p, SourceLoc location) {
this(TA1, TA2, e0p); this(TA1, TA2, e0p);
this.location = location; this.location = location;
} }
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp, boolean noUnification) { public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp, boolean noUnification) {
// Konstruktor // Konstruktor
this(TA1, TA2); this(TA1, TA2);
this.eOperator = eOp; this.eOperator = eOp;
this.noUnification = noUnification; this.noUnification = noUnification;
} }
public SourceLoc getLocation() { public SourceLoc getLocation() {
return this.location; return this.location;
} }
public String toString() { public String toString() {
// otth: Gibt ein Paar als String aus --> zum Debuggen und Vergleichen // otth: Gibt ein Paar als String aus --> zum Debuggen und Vergleichen
String strElement1 = "NULL"; String strElement1 = "NULL";
String strElement2 = "NULL"; String strElement2 = "NULL";
String Operator = "<."; String Operator = "<.";
if (TA1 != null) if (TA1 != null)
strElement1 = TA1.toString(); strElement1 = TA1.toString();
if (TA2 != null) if (TA2 != null)
strElement2 = TA2.toString(); strElement2 = TA2.toString();
/* PL ausskommentiert 2018-05-24 /* PL ausskommentiert 2018-05-24
if(OperatorEqual()) if(OperatorEqual())
@@ -78,125 +75,103 @@ public class Pair implements Serializable, IConstraintElement, ISerializableData
Operator = "<?"; Operator = "<?";
*/ */
return "\n(P: " + strElement1 + " " + eOperator.toString() + " " + strElement2 + ")"; return "\n(P: " + strElement1 + " " + eOperator.toString() + " " + strElement2 + ")";
/*- Equals: " + bEqual*/ /*- Equals: " + bEqual*/
} }
/** /**
* <br/>Author: J�rg B�uerle * <br/>Author: J�rg B�uerle
* *
* @param obj * @param obj
* @return * @return
*/ */
public boolean equals(Object obj) { public boolean equals(Object obj) {
return ( return (
(obj instanceof Pair pairObj) && (obj instanceof Pair pairObj) &&
pairObj.TA1.equals(this.TA1) && pairObj.TA1.equals(this.TA1) &&
pairObj.TA2.equals(this.TA2) pairObj.TA2.equals(this.TA2)
); );
} }
/** /**
* Author: Arne Lüdtke<br/> * Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ Equal ist. * Abfrage, ob Operator vom Typ Equal ist.
*/ */
public boolean OperatorEqual() { public boolean OperatorEqual() {
return eOperator == PairOperator.EQUALSDOT; return eOperator == PairOperator.EQUALSDOT;
} }
/** /**
* Author: Arne Lüdtke<br/> * Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ Smaller ist. * Abfrage, ob Operator vom Typ Smaller ist.
*/ */
public boolean OperatorSmaller() { public boolean OperatorSmaller() {
return eOperator == PairOperator.SMALLER; return eOperator == PairOperator.SMALLER;
} }
/** /**
* Author: Arne Lüdtke<br/> * Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ SmallerExtends ist. * Abfrage, ob Operator vom Typ SmallerExtends ist.
*/ */
public boolean OperatorSmallerExtends() { public boolean OperatorSmallerExtends() {
return eOperator == PairOperator.SMALLERDOTWC; return eOperator == PairOperator.SMALLERDOTWC;
} }
/** /**
* Author: Arne Lüdtke<br/> * Author: Arne Lüdtke<br/>
* Gibt den Operator zurück. * Gibt den Operator zurück.
*/ */
public PairOperator GetOperator() { public PairOperator GetOperator() {
return eOperator; return eOperator;
} }
public boolean OperatorSmallerDot() { public boolean OperatorSmallerDot() {
return eOperator == PairOperator.SMALLERDOT; return eOperator == PairOperator.SMALLERDOT;
} }
static public Map<String, TypePlaceholder> generateTPHMap(ConstraintSet<Pair> constraints) { static public Map<String, TypePlaceholder> generateTPHMap(ConstraintSet<Pair> constraints) {
HashMap<String, TypePlaceholder> ret = new HashMap<>(); HashMap<String, TypePlaceholder> ret = new HashMap<>();
constraints.map((Pair p) -> { constraints.map((Pair p) -> {
if (p.TA1 instanceof TypePlaceholder) { if (p.TA1 instanceof TypePlaceholder) {
ret.put(((TypePlaceholder) p.TA1).getName(), (TypePlaceholder) p.TA1); ret.put(((TypePlaceholder) p.TA1).getName(), (TypePlaceholder) p.TA1);
} }
if (p.TA2 instanceof TypePlaceholder) { if (p.TA2 instanceof TypePlaceholder) {
ret.put(((TypePlaceholder) p.TA2).getName(), (TypePlaceholder) p.TA2); ret.put(((TypePlaceholder) p.TA2).getName(), (TypePlaceholder) p.TA2);
} }
return null; return null;
}); });
return ret; return ret;
} }
@Override @Override
public SerialMap toSerial(KeyStorage keyStorage) { public SerialMap toSerial(KeyStorage keyStorage) {
// because toString() will output TA1 and TA2 recursively, we can ignore potential infinite recursion here too // because toString() will output TA1 and TA2 recursively, we can ignore potential infinite recursion here too
SerialMap serialized = new SerialMap(); SerialMap serialized = new SerialMap();
serialized.put("ta1", this.TA1.toSerial(keyStorage)); serialized.put("ta1", this.TA1.toSerial(keyStorage));
serialized.put("ta2", this.TA2.toSerial(keyStorage)); serialized.put("ta2", this.TA2.toSerial(keyStorage));
serialized.put("op", this.eOperator.toString()); serialized.put("op", this.eOperator.toString());
serialized.put("noUnification", this.noUnification ? 1 : 0); serialized.put("noUnification", this.noUnification ? 1 : 0);
serialized.put("location", this.location == null ? null : this.location.toSerial(keyStorage)); serialized.put("location", this.location == null ? null : this.location.toSerial(keyStorage));
return serialized; return serialized;
} }
public static Pair fromSerial(SerialMap data, UnifyContext context) { public static Pair fromSerial(SerialMap data, UnifyContext context) {
String op = data.getValue("op").getOf(String.class); String op = data.getValue("op").getOf(String.class);
SerialMap ta1 = data.getMap("ta1"); SerialMap ta1 = data.getMap("ta1");
SerialMap ta2 = data.getMap("ta2"); SerialMap ta2 = data.getMap("ta2");
boolean noUnification = data.getValue("noUnification").getOf(Integer.class) == 1; boolean noUnification = data.getValue("noUnification").getOf(Integer.class) == 1;
SerialMap location = data.getMapOrNull("location"); SerialMap location = data.getMapOrNull("location");
var pair = new Pair( var pair = new Pair(
RefTypeOrTPHOrWildcardOrGeneric.fromSerial(ta1, context), RefTypeOrTPHOrWildcardOrGeneric.fromSerial(ta1, context),
RefTypeOrTPHOrWildcardOrGeneric.fromSerial(ta2, context), RefTypeOrTPHOrWildcardOrGeneric.fromSerial(ta2, context),
PairOperator.fromString(op), PairOperator.fromString(op),
noUnification noUnification
); );
if (location != null) pair.location = SourceLoc.fromSerial(location); if (location != null) pair.location = SourceLoc.fromSerial(location);
return pair; return pair;
} }
public String toDot(String color) {
return q(this.TA1.toString()) +
" -> " +
q(this.TA2.toString()) +
" [label=" +
q(this.GetOperator().toString()) +
",color=" + q(color) + "]" +
";\n";
}
public String toDot() {
return q(this.TA1.toString()) +
" -> " +
q(this.TA2.toString()) +
" [label=" +
q(this.GetOperator().toString()) +
"]" +
";\n";
}
} }
// ino.end // ino.end

View File

@@ -11,7 +11,7 @@ import de.dhbwstuttgart.typeinference.unify.UnifyContext;
* Paare, welche das Unifikationsergebnis darstellen * Paare, welche das Unifikationsergebnis darstellen
*/ */
public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B extends RefTypeOrTPHOrWildcardOrGeneric> public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B extends RefTypeOrTPHOrWildcardOrGeneric>
implements Comparable<ResultPair<A,B>>, ISerializableData { implements ISerializableData {
private final A left; private final A left;
private final B right; private final B right;
@@ -65,16 +65,6 @@ public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B ext
return true; return true;
} }
@Override
public int compareTo(ResultPair<A, B> o) {
if (o == null) {
return 1; // this is greater than null
}
return o.left.toString().compareTo(this.left.toString());
}
@Override @Override
public SerialMap toSerial(KeyStorage keyStorage) { public SerialMap toSerial(KeyStorage keyStorage) {

View File

@@ -11,7 +11,6 @@ import de.dhbwstuttgart.util.Logger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
@@ -24,32 +23,28 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public class ResultSet implements Comparable<ResultSet>, ISerializableData { public class ResultSet implements ISerializableData {
public final Set<ResultPair> results; public final Set<ResultPair> results;
public Set<ResultPair<TypePlaceholder, TypePlaceholder>> genIns; public Set<ResultPair<TypePlaceholder, TypePlaceholder>> genIns;
public ResultSet(Set<ResultPair> set){ public ResultSet(Set<ResultPair> set) {
this.results = set; this.results = set;
this.genIns = TypeUnifyTaskHelper.getPresizedHashSet(results.size()); this.genIns = TypeUnifyTaskHelper.getPresizedHashSet(results.size());
results.forEach(x -> { results.forEach(x -> {
if (x instanceof PairTPHsmallerTPH) { if (x instanceof PairTPHsmallerTPH) {
this.genIns.add(x); this.genIns.add(x);
} }
}); });
} }
public List<ResultPair> getSortedResults() { public boolean contains(ResultPair toCheck) {
return results.stream().sorted().toList(); return this.results.contains(toCheck);
} }
public boolean contains(ResultPair toCheck) { public void remove(ResultPair toCheck) {
return this.results.contains(toCheck); results.remove(toCheck);
} }
public void remove(ResultPair toCheck) {
results.remove(toCheck);
}
public ResolvedType resolveType(RefTypeOrTPHOrWildcardOrGeneric type) { public ResolvedType resolveType(RefTypeOrTPHOrWildcardOrGeneric type) {
if (type instanceof TypePlaceholder) if (type instanceof TypePlaceholder)
@@ -92,24 +87,9 @@ public class ResultSet implements Comparable<ResultSet>, ISerializableData {
} }
} }
@Override
public int hashCode() {
return results.hashCode();
}
@Override @Override
public int compareTo(ResultSet o) { public int hashCode() {
List<ResultPair> thisSorted = this.getSortedResults(); return results.hashCode();
List<ResultPair> otherSorted = o.getSortedResults();
int sizeCompare = Integer.compare(thisSorted.size(), otherSorted.size());
if (sizeCompare != 0) return sizeCompare;
for (int i = 0; i < thisSorted.size(); i++) {
int cmp = thisSorted.get(i).compareTo(otherSorted.get(i));
if (cmp != 0) return cmp;
}
return 0;
} }
@Override @Override

View File

@@ -1,7 +1,6 @@
package de.dhbwstuttgart.typeinference.typeAlgo; package de.dhbwstuttgart.typeinference.typeAlgo;
import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.SourceLoc; import de.dhbwstuttgart.parser.SourceLoc;
import de.dhbwstuttgart.parser.antlr.Java17Parser; import de.dhbwstuttgart.parser.antlr.Java17Parser;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
@@ -10,11 +9,9 @@ import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.statement.Statement; import de.dhbwstuttgart.syntaxtree.statement.Statement;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.target.tree.type.TargetRefType;
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption; import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTaskHelper; import de.dhbwstuttgart.typeinference.unify.TypeUnifyTaskHelper;
@@ -22,32 +19,32 @@ import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.util.BiRelation; import de.dhbwstuttgart.util.BiRelation;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import java.lang.reflect.Modifier;
import java.util.*; import java.util.*;
public class TYPE { public class TYPE {
private final SourceFile sf;
private final Set<ClassOrInterface> allAvailableClasses; private final Set<ClassOrInterface> allAvailableClasses;
private final Set<ClassOrInterface> definedClasses;
public TYPE(SourceFile sf, Set<ClassOrInterface> allAvailableClasses){
public TYPE(Set<ClassOrInterface> definedClasses, Set<ClassOrInterface> allAvailableClasses){ this.sf = sf;
this.allAvailableClasses = allAvailableClasses; this.allAvailableClasses = allAvailableClasses;
this.definedClasses = definedClasses;
} }
public ConstraintSet<Pair> getConstraints() { public ConstraintSet getConstraints() {
ConstraintSet<Pair> ret = new ConstraintSet<>(); ConstraintSet ret = new ConstraintSet();
for (ClassOrInterface cl : definedClasses) { for (ClassOrInterface cl : sf.KlassenVektor) {
Set<ClassOrInterface> allClasses = TypeUnifyTaskHelper.getPresizedHashSet(allAvailableClasses.size()); Set<ClassOrInterface> allClasses = TypeUnifyTaskHelper.getPresizedHashSet(allAvailableClasses.size() + sf.availableClasses.size());
allClasses.addAll(allAvailableClasses); allClasses.addAll(allAvailableClasses);
allClasses.addAll(sf.availableClasses);
ret.addAll(getConstraintsClass(cl, new TypeInferenceInformation(allClasses))); ret.addAll(getConstraintsClass(cl, new TypeInferenceInformation(allClasses)));
} }
return ret; return ret;
} }
private ConstraintSet<Pair> getConstraintsClass(ClassOrInterface cl, TypeInferenceInformation info) { private ConstraintSet getConstraintsClass(ClassOrInterface cl, TypeInferenceInformation info) {
ConstraintSet<Pair> ret = new ConstraintSet<>(); ConstraintSet ret = new ConstraintSet();
ConstraintSet<Pair> methConstrains; ConstraintSet methConstrains;
for(Method m : cl.getMethods()){ for(Method m : cl.getMethods()){
ret.addAll(methConstrains = getConstraintsMethod(m,info, cl)); ret.addAll(methConstrains = getConstraintsMethod(m,info, cl));
m.constraints.addAll(methConstrains); m.constraints.addAll(methConstrains);
@@ -86,30 +83,17 @@ public class TYPE {
} }
*/ */
private ConstraintSet<Pair> getConstraintsMethod(Method m, TypeInferenceInformation info, ClassOrInterface currentClass) { private ConstraintSet getConstraintsMethod(Method m, TypeInferenceInformation info, ClassOrInterface currentClass) {
if(m.block == null)return new ConstraintSet<Pair>(); //Abstrakte Methoden generieren keine Constraints if(m.block == null)return new ConstraintSet(); //Abstrakte Methoden generieren keine Constraints
TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m); TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m);
TYPEStmt methodScope = new TYPEStmt(blockInfo); TYPEStmt methodScope = new TYPEStmt(blockInfo);
ConstraintSet<Pair> constraintSet = new ConstraintSet<>(); ConstraintSet constraintSet = new ConstraintSet();
m.getParameterList().getFormalparalist().forEach(el -> {
if (m.name.equals("main") && Modifier.isStatic(m.modifier) && m.getParameterList().getFormalparalist().size() == 1) { if(el instanceof RecordPattern){
// Add constraint for main method constraintSet.addAll(addRecursiveParameterConstraints((RecordPattern) el, blockInfo));
var firstParam = m.getParameterList().getParameterAt(0);
constraintSet.addUndConstraint(new Pair(firstParam.getType(),
new RefType(new JavaClassName("java.util.List"),
List.of(new RefType(new JavaClassName("java.lang.String"), new NullToken())),
new NullToken()),
PairOperator.EQUALSDOT));
} else {
m.getParameterList().getFormalparalist().forEach(el -> {
if (el instanceof RecordPattern rp){
constraintSet.addAll(addRecursiveParameterConstraints(rp, blockInfo));
}
});
}
}
});
m.block.accept(methodScope); m.block.accept(methodScope);
constraintSet.addAll(methodScope.getConstraints()); constraintSet.addAll(methodScope.getConstraints());
return constraintSet; return constraintSet;

View File

@@ -75,7 +75,7 @@ public class TYPEStmt implements StatementVisitor {
@Override @Override
public void visit(LambdaExpression lambdaExpression) { public void visit(LambdaExpression lambdaExpression) {
TypePlaceholder tphRetType = TypePlaceholder.fresh(new NullToken(), -1, false); TypePlaceholder tphRetType = TypePlaceholder.fresh(new NullToken());
List<RefTypeOrTPHOrWildcardOrGeneric> lambdaParams = lambdaExpression.params.getFormalparalist().stream().map((formalParameter -> formalParameter.getType())).collect(Collectors.toList()); List<RefTypeOrTPHOrWildcardOrGeneric> lambdaParams = lambdaExpression.params.getFormalparalist().stream().map((formalParameter -> formalParameter.getType())).collect(Collectors.toList());
lambdaParams.add(tphRetType); lambdaParams.add(tphRetType);
// lambdaParams.add(0,tphRetType); // lambdaParams.add(0,tphRetType);
@@ -643,7 +643,6 @@ public class TYPEStmt implements StatementVisitor {
params.add(resolver.resolve(new GenericRefType(gtv.getName(), new NullToken()))); params.add(resolver.resolve(new GenericRefType(gtv.getName(), new NullToken())));
} }
RefTypeOrTPHOrWildcardOrGeneric receiverType; RefTypeOrTPHOrWildcardOrGeneric receiverType;
if (receiver instanceof FunNClass) { if (receiver instanceof FunNClass) {
receiverType = new RefType(new JavaClassName(receiver.getClassName().toString() + "$$"), params, new NullToken()); // new FunN(params); receiverType = new RefType(new JavaClassName(receiver.getClassName().toString() + "$$"), params, new NullToken()); // new FunN(params);
} else { } else {
@@ -939,7 +938,7 @@ public class TYPEStmt implements StatementVisitor {
@Override @Override
public void visit(Yield aYield) { public void visit(Yield aYield) {
aYield.retexpr.accept(this); aYield.retexpr.accept(this);
constraintsSet.addUndConstraint(new Pair(aYield.getType(), switchStack.peek().getType(), PairOperator.SMALLERDOT, loc(aYield.getOffset()))); constraintsSet.addUndConstraint(new Pair(aYield.getType(), switchStack.peek().getType(), PairOperator.EQUALSDOT, loc(aYield.getOffset())));
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
} }

View File

@@ -1,7 +1,6 @@
//PL 2018-12-19: Merge checken //PL 2018-12-19: Merge checken
package de.dhbwstuttgart.typeinference.unify; package de.dhbwstuttgart.typeinference.unify;
import de.dhbwstuttgart.core.ConsoleInterface;
import de.dhbwstuttgart.exceptions.TypeinferenceException; import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.server.ServerTaskLogger; import de.dhbwstuttgart.server.ServerTaskLogger;
@@ -150,7 +149,7 @@ public class TypeUnifyTask extends CancellableTask<CompletableFuture<Set<Set<Uni
this.fc = fc; this.fc = fc;
this.oup = new OrderingUnifyPair(fc, context); this.oup = new OrderingUnifyPair(fc, context);
this.context = (!ConsoleInterface.writeLogFiles || context.logger() instanceof ServerTaskLogger) ? context : context.newWithLogger( this.context = (context.logger() instanceof ServerTaskLogger) ? context : context.newWithLogger(
Logger.forFile( Logger.forFile(
System.getProperty("user.dir") + "/logFiles/" + "Thread", System.getProperty("user.dir") + "/logFiles/" + "Thread",
"Unify" "Unify"

View File

@@ -1,6 +1,8 @@
package de.dhbwstuttgart.typeinference.unify.cartesianproduct; package de.dhbwstuttgart.typeinference.unify.cartesianproduct;
import de.dhbwstuttgart.exceptions.UnifyCancelException;
import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.unify.TypeUnify2Task;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask; import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
import de.dhbwstuttgart.typeinference.unify.UnifyContext; import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
@@ -13,12 +15,15 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class UnknownVarianceCase extends VarianceCase { public class UnknownVarianceCase extends VarianceCase {
protected final int variance = 0; protected final int variance = 0;
protected final AtomicBoolean shouldBreak = new AtomicBoolean(false);
protected UnknownVarianceCase(boolean isOderConstraint, TypeUnifyTask typeUnifyTask, UnifyContext context) { protected UnknownVarianceCase(boolean isOderConstraint, TypeUnifyTask typeUnifyTask, UnifyContext context) {
super(isOderConstraint, typeUnifyTask, context); super(isOderConstraint, typeUnifyTask, context);
} }
@@ -46,6 +51,28 @@ public class UnknownVarianceCase extends VarianceCase {
} else { } else {
a = nextSetAsList.removeFirst(); a = nextSetAsList.removeFirst();
} }
Set<UnifyPair> finalA = a;
if (!this.isOderConstraint && optOrigPair != null && optOrigPair.isPresent()) {
if (optOrigPair.get().getBasePair().getLhsType() instanceof PlaceholderType) {
nextSetasListRest = typeUnifyTask.oup.maxElements(
nextSetAsList.stream().filter(a_next -> typeUnifyTask.oup.compare(finalA, a_next) != 1).toList()
);
} else {
nextSetasListRest = typeUnifyTask.oup.minElements(
nextSetAsList.stream().filter(a_next -> typeUnifyTask.oup.compare(finalA, a_next) != -1).toList()
);
}
} else if (this.isOderConstraint) {
nextSetasListRest = typeUnifyTask.oup.maxElements(
nextSetAsList.stream().filter(a_next -> typeUnifyTask.oup.compare(finalA, a_next) != 1).toList()
);
} else {
nextSetasListRest = (nextSetAsList.size() > 5) ? nextSetAsList.subList(0, 5) : nextSetAsList;
}
nextSetAsList.removeAll(nextSetasListRest);
// */
} }
@Override @Override
@@ -61,9 +88,98 @@ public class UnknownVarianceCase extends VarianceCase {
Set<Set<UnifyPair>> result, Set<Set<UnifyPair>> result,
Set<Set<UnifyPair>> aParDef Set<Set<UnifyPair>> aParDef
) { ) {
elems.add(a); Set<UnifyPair> newEqOrig = new HashSet<>(eq);
return typeUnifyTask.unify2(elems, eq, oderConstraints, fc, context.parallel(), rekTiefe, new HashSet<>(methodSignatureConstraint)) Set<Set<UnifyPair>> newElemsOrig = new HashSet<>(elems);
.thenApply(ComputationResults::new); List<Set<Constraint<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints);
newElemsOrig.add(a);
Set<UnifyPair> newMethodSignatureConstraintOrig = new HashSet<>(methodSignatureConstraint);
if (isOderConstraint) {
methodSignatureConstraint.addAll(((Constraint<UnifyPair>) a).getmethodSignatureConstraint());
}
TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, context, rekTiefe, newMethodSignatureConstraintOrig);
typeUnifyTask.addChildTask(forkOrig);
CompletableFuture<Set<Set<UnifyPair>>> forkOrigFuture = CompletableFuture.supplyAsync(forkOrig::compute, context.executor()).thenCompose(f -> f);
CompletableFuture<ComputationResults> resultValues = forkOrigFuture.thenApply(
(currentThreadResult) -> {
forkOrig.context.logger().debug("final Orig 0");
forkOrig.closeLogFile();
return new ComputationResults(currentThreadResult);
});
int i = 0;
Set<Set<UnifyPair>>[] additionalResults = new HashSet[nextSetasListRest.size()];
Constraint<UnifyPair>[] extendConstraints = new Constraint[nextSetasListRest.size()];
while (!nextSetasListRest.isEmpty()) {
final int finalI = i++;
Set<UnifyPair> nSaL = nextSetasListRest.removeFirst();
context.logger().debug(() -> "0 RM" + nSaL.toString());
if (this.isOderConstraint) {
Constraint<UnifyPair> extendConstraint = ((Constraint<UnifyPair>) nSaL).getExtendConstraint();
extendConstraints[finalI] = extendConstraint;
}
else if (!sameEqSet.isEmpty() && !typeUnifyTask.checkNoContradiction(nSaL, sameEqSet, result)) {
TypeUnifyTask.noShortendElements++;
continue;
}
Set<UnifyPair> newEq = new HashSet<>(eq);
Set<Set<UnifyPair>> newElems = new HashSet<>(elems);
List<Set<Constraint<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints);
newElems.add(nSaL);
Set<UnifyPair> newMethodSignatureConstraint = new HashSet<>(methodSignatureConstraint);
if (isOderConstraint) {
methodSignatureConstraint.addAll(((Constraint<UnifyPair>) nSaL).getmethodSignatureConstraint());
}
TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, context, rekTiefe, newMethodSignatureConstraint);
typeUnifyTask.addChildTask(fork);
// schedule compute() on another thread
CompletableFuture<Set<Set<UnifyPair>>> forkFuture = CompletableFuture.supplyAsync(fork::compute, context.executor()).thenCompose(f -> f);
resultValues = resultValues.thenCombine(forkFuture, (compResult, forkResult) -> {
additionalResults[finalI] = forkResult;
context.logger().error("finalI: " + finalI);
return compResult;
});
}
int finalI1 = i;
return resultValues.thenCompose(compResult -> {
var oldResult = compResult.mainResult;
for (int e = 0; e < finalI1; e++) {
Set<Set<UnifyPair>> currentResult = additionalResults[e];
boolean oldResultInvalid = typeUnifyTask.isUndefinedPairSetSet(oldResult);
boolean currentResultInvalid = typeUnifyTask.isUndefinedPairSetSet(currentResult);
if (!oldResult.isEmpty() && !oldResultInvalid) {
boolean shouldBreak = this.eraseInvalidSets(rekTiefe, new HashSet<>(), nextSetAsList);
if (shouldBreak) {
return CompletableFuture.completedFuture(compResult);
}
}
if (this.isOderConstraint) {
nextSetasListOderConstraints.add(extendConstraints[e]);
}
if (!currentResultInvalid && oldResultInvalid) {
//wenn korrektes Ergebnis gefunden alle Fehlerfaelle loeschen
oldResult = currentResult;
} else if (oldResultInvalid == currentResultInvalid || oldResult.isEmpty()) {
//alle Fehlerfaelle und alle korrekten Ergebnis jeweils adden
Set<Set<UnifyPair>> finalOldResult = oldResult;
context.logger().debug(() -> "RES var1 ADD:" + finalOldResult.toString() + " " + currentResult.toString());
oldResult.addAll(currentResult);
}
}
compResult.mainResult = oldResult;
return CompletableFuture.completedFuture(compResult);
});
} }
@Override @Override
@@ -100,10 +216,25 @@ public class UnknownVarianceCase extends VarianceCase {
nextSetAsList.removeAll(erased); nextSetAsList.removeAll(erased);
context.logger().debug("Removed: " + erased); context.logger().debug("Removed: " + erased);
context.logger().debug("Not Removed: " + nextSetAsList); context.logger().debug("Not Removed: " + nextSetAsList);
for (Set<UnifyPair> aPar : aParDef) {
smallerSetasList.clear();
smallerSetasList.addAll(typeUnifyTask.oup.smallerThan(aPar, nextSetAsList));
notInherited = smallerSetasList.stream()
.filter(x -> !((Constraint<UnifyPair>) x).isInherited())
.collect(Collectors.toCollection(ArrayList::new));
notErased.clear();
notInherited.forEach(x -> notErased.addAll(typeUnifyTask.oup.smallerEqThan(x, smallerSetasList)));
erased = new ArrayList<>(smallerSetasList);
erased.removeAll(notErased);
nextSetAsList.removeAll(erased);
context.logger().debug("Removed: " + erased);
context.logger().debug("Not Removed: " + nextSetAsList);
}
} }
return false; return false;
} }

View File

@@ -53,7 +53,7 @@ class Node<T> {
addDescendant(descendant); addDescendant(descendant);
} }
} }
/** /**
* Adds a directed edge from the predecessor to this node (predecessor -> this) * Adds a directed edge from the predecessor to this node (predecessor -> this)
*/ */
@@ -73,7 +73,7 @@ class Node<T> {
addPredecessor(predecessor); addPredecessor(predecessor);
} }
} }
/** /**
* The content of this node. * The content of this node.
*/ */

View File

@@ -126,6 +126,20 @@ public class Logger {
} }
} }
public String findLogCaller() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
final String thisFileName = stackTrace[0].getFileName();
int i = 0;
StackTraceElement currentElement = stackTrace[i];
while (++i < stackTrace.length) {
currentElement = stackTrace[i];
if (!Objects.equals(thisFileName, currentElement.getFileName())) {
break;
}
}
return ".(" + currentElement.getFileName() + ":" + currentElement.getLineNumber() + ")";
}
/** /**
* Base method for logging a string value. Should mostly be used by the Logger internal functions that * Base method for logging a string value. Should mostly be used by the Logger internal functions that
* abstract the logLevel away from the parameters * abstract the logLevel away from the parameters
@@ -136,6 +150,8 @@ public class Logger {
*/ */
public void log(String s, LogLevel logLevel) { public void log(String s, LogLevel logLevel) {
if (isLogLevelActive(logLevel)) { if (isLogLevelActive(logLevel)) {
// prepend the call to the logger instance
// s = findLogCaller() + "\n" + s;
this.print(s, logLevel); this.print(s, logLevel);
this.write(s); this.write(s);
} }

View File

@@ -1,6 +1,6 @@
import static org.junit.jupiter.api.Assertions.*; import static org.junit.Assert.*;
import static targetast.TestCodegen.generateClassFiles; import static targetast.TestCodegen.generateClassFiles;
import java.io.File; import java.io.File;
@@ -9,12 +9,13 @@ import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.util.Arrays; import java.util.Arrays;
import org.junit.jupiter.api.BeforeAll; import org.junit.BeforeClass;
import org.junit.jupiter.api.Test; import org.junit.Test;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
public class AllgemeinTest { public class AllgemeinTest {
@@ -77,7 +78,7 @@ public class AllgemeinTest {
compiler = new JavaTXCompiler( compiler = new JavaTXCompiler(
Lists.newArrayList(new File(path)), Lists.newArrayList(new File(path)),
Lists.newArrayList(new File(System.getProperty("user.dir")+"/resources/bytecode/classFiles/")), Lists.newArrayList(new File(System.getProperty("user.dir")+"/resources/bytecode/classFiles/")),
new File(System.getProperty("user.dir")+"/resources/bytecode/classFiles/"), true); new File(System.getProperty("user.dir")+"/resources/bytecode/classFiles/"));
//*/ //*/
compiler.generateBytecode(); compiler.generateBytecode();
pathToClassFile = System.getProperty("user.dir")+"/resources/bytecode/classFiles/"; pathToClassFile = System.getProperty("user.dir")+"/resources/bytecode/classFiles/";

View File

@@ -6,12 +6,12 @@ import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.target.generate.ASTToTargetAST; import de.dhbwstuttgart.target.generate.ASTToTargetAST;
import org.junit.jupiter.api.Test; import org.junit.Test;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.Assert.*;
public class GenericsParserTest { public class GenericsParserTest {

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,6 @@
import de.dhbwstuttgart.core.ConsoleInterface;
import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.core.JavaTXCompiler;
import org.junit.jupiter.api.Disabled; import org.junit.Ignore;
import org.junit.jupiter.api.Test; import org.junit.Test;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
@@ -14,25 +13,26 @@ public class TestPackages {
public void testPackages() throws Exception { public void testPackages() throws Exception {
var cmp = new JavaTXCompiler( var cmp = new JavaTXCompiler(
List.of( List.of(
new File("resources/packageTest/pkg/sub/Test1.jav"), new File("resources/packageTest/pkg/sub/Test1.jav") // This should pull in Test2
new File("resources/packageTest/pkg/sub2/Test2.jav") //new File("resources/packageTest/pkg/sub2/Test2.jav")
), ),
List.of(new File("resources/packageTest")), List.of(new File("resources/packageTest")),
new File(bytecodeDirectory), true new File(bytecodeDirectory)
); );
cmp.generateBytecode(); cmp.generateBytecode();
} }
@Test @Test
@Ignore("This doesn't work")
public void testPackagesCircular() throws Exception { public void testPackagesCircular() throws Exception {
var cmp = new JavaTXCompiler( var cmp = new JavaTXCompiler(
List.of( List.of(
new File("resources/packageTest/pkg/sub/Cycle1.jav"), new File("resources/packageTest/pkg/sub/Cycle1.jav")
new File("resources/packageTest/pkg/sub2/Cycle2.jav") //new File("resources/packageTest/pkg/sub2/Cycle2.jav")
), ),
List.of(new File("resources/packageTest")), List.of(new File("resources/packageTest")),
new File(bytecodeDirectory), true new File(bytecodeDirectory)
); );
cmp.generateBytecode(); cmp.generateBytecode();
@@ -43,7 +43,7 @@ public class TestPackages {
var cmp = new JavaTXCompiler( var cmp = new JavaTXCompiler(
List.of(new File("resources/packageTest/pkg/sub/Interface.jav")), List.of(new File("resources/packageTest/pkg/sub/Interface.jav")),
List.of(new File("resources/packageTest")), List.of(new File("resources/packageTest")),
new File(bytecodeDirectory), true new File(bytecodeDirectory)
); );
cmp.generateBytecode(); cmp.generateBytecode();

View File

@@ -4,7 +4,7 @@ import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.typedeployment.TypeInsert; import de.dhbwstuttgart.typedeployment.TypeInsert;
import de.dhbwstuttgart.typedeployment.TypeInsertFactory; import de.dhbwstuttgart.typedeployment.TypeInsertFactory;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
import org.junit.jupiter.api.Test; import org.junit.Test;
import java.io.File; import java.io.File;
import java.nio.file.Path; import java.nio.file.Path;

View File

@@ -4,7 +4,7 @@ package astfactory;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import org.junit.jupiter.api.Test; import org.junit.Test;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
@@ -12,8 +12,7 @@ import java.lang.reflect.TypeVariable;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.Assert.*;
public class ASTFactoryTest<A> extends HashMap<String, A>{ public class ASTFactoryTest<A> extends HashMap<String, A>{
@Test @Test

View File

@@ -4,10 +4,12 @@ import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.FCGenerator; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.FCGenerator;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import org.junit.jupiter.api.Test; import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
import org.junit.Test;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List;
public class SuperInterfacesTest { public class SuperInterfacesTest {
@Test @Test

View File

@@ -1,5 +0,0 @@
public class t{
public mofus(){
return 1;
}
}

View File

@@ -1,7 +1,7 @@
package server; package server;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.environment.ByteArrayClassLoader;
import de.dhbwstuttgart.parser.SourceLoc; import de.dhbwstuttgart.parser.SourceLoc;
import de.dhbwstuttgart.server.packet.DebugPacket; import de.dhbwstuttgart.server.packet.DebugPacket;
import de.dhbwstuttgart.server.packet.IPacket; import de.dhbwstuttgart.server.packet.IPacket;
@@ -16,11 +16,18 @@ import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialUUID;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialValue; import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialValue;
import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
import de.dhbwstuttgart.typeinference.unify.UnifyContext; import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import de.dhbwstuttgart.typeinference.unify.UnifyResultModel;
import de.dhbwstuttgart.typeinference.unify.UnifyTaskModel;
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import java.io.Writer;
import java.util.HashSet;
import java.util.concurrent.ForkJoinPool;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import org.junit.jupiter.api.Test; import org.junit.Test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.Assert.*;
public class PacketTest { public class PacketTest {

View File

@@ -35,21 +35,24 @@ import java.util.Set;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.junit.Ignore;
import org.junit.Test;
import targetast.TestCodegen; import targetast.TestCodegen;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.Assert.*;
@Ignore("Server tests create huge overhead, so they are ignored until required")
public class ServerTest { public class ServerTest {
public ServerTest() { public ServerTest() {
ConsoleInterface.unifyServerUrl = Optional.of("ws://localhost:5000"); ConsoleInterface.unifyServerUrl = Optional.of("ws://localhost:5000");
} }
//@Test @Test
public void checkServer_Scalar() throws IOException, ClassNotFoundException { public void checkServer_Scalar() throws IOException, ClassNotFoundException {
compareLocalAndServerResult("Scalar.jav"); compareLocalAndServerResult("Scalar.jav");
} }
//@Test @Test
public void checkServer_Matrix() throws IOException, ClassNotFoundException { public void checkServer_Matrix() throws IOException, ClassNotFoundException {
compareLocalAndServerResult("Matrix.jav"); compareLocalAndServerResult("Matrix.jav");
} }

View File

@@ -1,5 +1,9 @@
package syntaxtreegenerator; package syntaxtreegenerator;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File; import java.io.File;
import java.io.FileFilter; import java.io.FileFilter;
import java.io.FileInputStream; import java.io.FileInputStream;
@@ -8,23 +12,21 @@ import java.io.ObjectOutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import org.junit.jupiter.api.BeforeAll; import org.junit.BeforeClass;
import org.junit.jupiter.api.Test; import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.SourceFile; import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter; import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
import static org.junit.jupiter.api.Assertions.*;
/** /**
* Unit-Tests für den 'SyntaxTreeGenerator' aus dem Package 'parser' nach Vorbild der Klasse 'TestComplete' aus dem Test-Package 'targetast' * Unit-Tests für den 'SyntaxTreeGenerator' aus dem Package 'parser' nach Vorbild der Klasse 'TestComplete' aus dem Test-Package 'targetast'
*/ */
public class TestComplete { public class TestComplete {
private static HashMap<String, File[]> javFiles = new HashMap<>(); private static HashMap<String, File[]> javFiles = new HashMap<>();
@BeforeAll @BeforeClass
public static void setUp() { public static void setUp() {
final String testFileDirectory = "resources/bytecode/javFiles/"; final String testFileDirectory = "resources/bytecode/javFiles/";
final String expectedASTDirectory = "resources/syntaxtreegenerator/"; final String expectedASTDirectory = "resources/syntaxtreegenerator/";
@@ -351,7 +353,7 @@ public class TestComplete {
assertEquals("Comparing expected and resulting AST for mathStrucInteger.jav", expectedAST, resultingAST); assertEquals("Comparing expected and resulting AST for mathStrucInteger.jav", expectedAST, resultingAST);
} catch (Exception exc) { } catch (Exception exc) {
exc.printStackTrace(); exc.printStackTrace();
assertInstanceOf(NotImplementedException.class, exc); assertTrue("An error occured while generating the AST for mathStrucInteger.jav", exc instanceof NotImplementedException);
} }
} }

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