Compare commits
4 Commits
master
...
feat/unify
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1af31e4513 | ||
|
|
5b06f0a249 | ||
|
|
512b10542e | ||
|
|
3b1185d9d0 |
@@ -1,8 +1,5 @@
|
||||
name: Build and Test with Maven
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- master
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
Build-and-test-with-Maven:
|
||||
@@ -18,11 +15,11 @@ jobs:
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '25'
|
||||
java-version: '23'
|
||||
cache: 'maven'
|
||||
- name: Compile project
|
||||
run: |
|
||||
mvn compile
|
||||
- name: Run tests
|
||||
run: |
|
||||
mvn test
|
||||
mvn test
|
||||
@@ -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
|
||||
@@ -1,7 +0,0 @@
|
||||
## Java-TX Compiler
|
||||
|
||||
[](https://gitea.hb.dhbw-stuttgart.de/sonarqube/dashboard?id=Java-TX)
|
||||
[](https://gitea.hb.dhbw-stuttgart.de/sonarqube/dashboard?id=Java-TX)
|
||||
[](https://gitea.hb.dhbw-stuttgart.de/sonarqube/dashboard?id=Java-TX)
|
||||
|
||||
Work in Progress Java-TX Compiler repository!
|
||||
55
pom.xml
55
pom.xml
@@ -12,37 +12,37 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<url>http://maven.apache.org</url>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.13.2</version>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.antlr/antlr4 -->
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4</artifactId>
|
||||
<version>4.13.2</version>
|
||||
<version>4.11.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.19.0</version>
|
||||
<version>2.16.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.classgraph</groupId>
|
||||
<artifactId>classgraph</artifactId>
|
||||
<version>4.8.180</version>
|
||||
<version>4.8.172</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>33.4.8-jre</version>
|
||||
<version>33.2.0-jre</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.ow2.asm/asm -->
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
<version>9.8</version>
|
||||
<version>9.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.java-websocket</groupId>
|
||||
@@ -64,51 +64,28 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<artifactId>JColor</artifactId>
|
||||
<version>5.5.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jcommander</groupId>
|
||||
<artifactId>jcommander</artifactId>
|
||||
<version>3.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<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>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.14.0</version>
|
||||
<version>3.11.0</version>
|
||||
<configuration>
|
||||
<source>25</source>
|
||||
<target>25</target>
|
||||
<compilerArgs>--enable-preview</compilerArgs>
|
||||
<source>23</source>
|
||||
<target>23</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.5.3</version>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<redirectTestOutputToFile>true</redirectTestOutputToFile>
|
||||
<reportsDirectory>${project.build.directory}/test-reports</reportsDirectory>
|
||||
<argLine>${argLine} --enable-preview</argLine>
|
||||
<argLine>--enable-preview</argLine>
|
||||
<trimStackTrace>false</trimStackTrace>
|
||||
<excludes>
|
||||
<exclude>**/JavaTXCompilerTest.java</exclude>
|
||||
@@ -120,7 +97,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<plugin>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4-maven-plugin</artifactId>
|
||||
<version>4.13.2</version>
|
||||
<version>4.11.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>antlr</id>
|
||||
@@ -133,7 +110,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.4.2</version>
|
||||
<version>3.3.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
|
||||
51
resources/LaufzeitTests/DeeplyNested.jav
Normal file
51
resources/LaufzeitTests/DeeplyNested.jav
Normal 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();
|
||||
}
|
||||
}
|
||||
43
resources/LaufzeitTests/GridSearch.jav
Normal file
43
resources/LaufzeitTests/GridSearch.jav
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
42
resources/LaufzeitTests/Mask.jav
Normal file
42
resources/LaufzeitTests/Mask.jav
Normal 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;
|
||||
}
|
||||
}
|
||||
39
resources/LaufzeitTests/PascalsTriangle.jav
Normal file
39
resources/LaufzeitTests/PascalsTriangle.jav
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import java.util.stream.Stream;
|
||||
|
||||
public class Bug325 {
|
||||
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;
|
||||
return list.stream().map(func).toList();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
class Bug378Id {
|
||||
id2 = x -> x;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
16
resources/bytecode/javFiles/BugXXX.jav
Normal file
16
resources/bytecode/javFiles/BugXXX.jav
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import java.lang.Integer;
|
||||
import java.lang.Boolean;
|
||||
|
||||
public class MatrixOP extends Vector<Vector<Integer>> {
|
||||
|
||||
|
||||
MatrixOP () {
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ public class MatrixOP extends Vector<Vector<Integer>> {
|
||||
v2.addElement(erg);
|
||||
j++; }
|
||||
ret.addElement(v2);
|
||||
i++;
|
||||
i++;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
17
resources/bytecode/javFiles/Merge2.jav
Normal file
17
resources/bytecode/javFiles/Merge2.jav
Normal 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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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))
|
||||
*/
|
||||
}
|
||||
@@ -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<>(); }
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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) {}
|
||||
@@ -1,18 +1,17 @@
|
||||
import java.lang.Integer;
|
||||
import java.lang.Double;
|
||||
import java.lang.Number;
|
||||
import java.lang.String;
|
||||
|
||||
public record R(String n) {}
|
||||
public record R(Number n) {}
|
||||
|
||||
public class SwitchOverload {
|
||||
|
||||
f() { return 10; }
|
||||
g() { return 20; }
|
||||
public f(){}
|
||||
|
||||
public m(r) {
|
||||
return switch(r) {
|
||||
case R("test") -> f();
|
||||
case R("foo") -> g();
|
||||
case R r -> 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,10 +39,6 @@ public class FunNGenerator {
|
||||
public final List<TargetType> inParams;
|
||||
public final List<TargetType> realParams;
|
||||
|
||||
public GenericParameters(TargetFunNType funNType) {
|
||||
this(funNType.funNParams(), funNType.returnArguments());
|
||||
}
|
||||
|
||||
public GenericParameters(List<TargetType> params, int numReturns) {
|
||||
this.realParams = params;
|
||||
this.inParams = flattenTypeParams(params);
|
||||
@@ -75,7 +71,7 @@ public class FunNGenerator {
|
||||
if (type == null) return VOID;
|
||||
var res = "L" + type.getInternalName();
|
||||
if (type instanceof TargetSpecializedType a) {
|
||||
if (!a.params().isEmpty() && !(a.params().size() == 1 && a.params().getFirst() == null)) {
|
||||
if (a.params().size() > 0) {
|
||||
res += "<";
|
||||
for (var param : a.params()) {
|
||||
if (param instanceof TargetGenericType gp) {
|
||||
@@ -98,7 +94,7 @@ public class FunNGenerator {
|
||||
}
|
||||
|
||||
private static String applySignature(TargetType a) { return a.toSignature(); }
|
||||
private static String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("%s", a.toDescriptor()); }
|
||||
private static String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("%s", applySignature(a)); }
|
||||
|
||||
public static String encodeType(TargetType type) {
|
||||
if (type == null) return VOID;
|
||||
@@ -115,12 +111,11 @@ public class FunNGenerator {
|
||||
superFunNMethodSignature.append(String.format("T%s;", argumentGenericBase + currentParameter));
|
||||
superFunNMethodDescriptor.append(objectSignature);
|
||||
}
|
||||
superFunNClassSignature.append(String.format("%s:%s>%s", returnGeneric, objectSignature, objectSignature));
|
||||
if (numReturnTypes > 0) {
|
||||
superFunNClassSignature.append(String.format("%s:%s>%s", returnGeneric, objectSignature, objectSignature));
|
||||
superFunNMethodSignature.append(String.format(")T%s;", returnGeneric));
|
||||
superFunNMethodDescriptor.append(String.format(")%s", objectSignature));
|
||||
} else {
|
||||
superFunNClassSignature = new StringBuilder(objectSignature);
|
||||
superFunNMethodSignature.append(")V");
|
||||
superFunNMethodDescriptor.append(")V");
|
||||
}
|
||||
|
||||
@@ -1,83 +1,81 @@
|
||||
package de.dhbwstuttgart.core;
|
||||
|
||||
import com.beust.jcommander.JCommander;
|
||||
import com.beust.jcommander.Parameter;
|
||||
import com.beust.jcommander.ParameterException;
|
||||
import de.dhbwstuttgart.server.SocketClient;
|
||||
import de.dhbwstuttgart.util.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
class Args {
|
||||
@Parameter(description = "Set destination directory", names = "-d")
|
||||
File outputPath;
|
||||
@Parameter(description = "Set class path", names = {"-cp", "-classpath"})
|
||||
String classpath;
|
||||
@Parameter(description = "[FILE]...")
|
||||
List<File> input;
|
||||
@Parameter(description = "Server mode", names = "--server-port")
|
||||
Integer serverPort;
|
||||
@Parameter(description = "Unify server url", names = "--unify-server")
|
||||
String serverUrl;
|
||||
@Parameter(description = "Write logs", names = "--write-logs")
|
||||
boolean writeLogs = false;
|
||||
@Parameter(names = "-v", description = "Verbosity level")
|
||||
int verbosity = 0;
|
||||
@Parameter(names = "--infer-together", description = "Runs the type inference on all input files together instead of sequentially")
|
||||
boolean inferTogether = false;
|
||||
@Parameter(names = "--help", help = true)
|
||||
boolean help;
|
||||
}
|
||||
|
||||
public class ConsoleInterface {
|
||||
public static Logger.LogLevel logLevel = Logger.LogLevel.ERROR;
|
||||
public static boolean writeLogFiles = false;
|
||||
public static boolean inferTogether = false;
|
||||
public static Optional<String> unifyServerUrl = Optional.empty();
|
||||
|
||||
public static void main(String[] argv) throws IOException, ClassNotFoundException {
|
||||
var args = new Args();
|
||||
var builder = JCommander.newBuilder().addObject(args).build();
|
||||
builder.setProgramName("javatx");
|
||||
try {
|
||||
builder.parse(argv);
|
||||
if (args.help) {
|
||||
builder.usage();
|
||||
return;
|
||||
}
|
||||
} catch (ParameterException e) {
|
||||
System.err.println(e.getMessage());
|
||||
System.err.println();
|
||||
builder.usage();
|
||||
System.exit(1);
|
||||
/**
|
||||
* Leave the argument configurations here for the rest of the code to read
|
||||
*/
|
||||
public static Logger.LogLevel logLevel = Logger.LogLevel.ERROR;
|
||||
public static boolean writeLogFiles = false;
|
||||
public static Optional<String> unifyServerUrl = Optional.empty();
|
||||
|
||||
public static void main(String[] args) throws IOException, ClassNotFoundException {
|
||||
List<File> input = new ArrayList<>();
|
||||
List<File> classpath = new ArrayList<>();
|
||||
String outputPath = null;
|
||||
Iterator<String> it = Arrays.asList(args).iterator();
|
||||
Optional<Integer> serverPort = Optional.empty();
|
||||
|
||||
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;
|
||||
unifyServerUrl = Optional.ofNullable(args.serverUrl);
|
||||
writeLogFiles = args.writeLogs;
|
||||
switch (args.verbosity) {
|
||||
case 1 -> logLevel = Logger.LogLevel.WARNING;
|
||||
case 2 -> logLevel = Logger.LogLevel.INFO;
|
||||
case 3 -> logLevel = Logger.LogLevel.DEBUG;
|
||||
default -> logLevel = Logger.LogLevel.ERROR;
|
||||
}
|
||||
if (serverPort.isPresent()) {
|
||||
if (unifyServerUrl.isPresent()) throw new RuntimeException("Cannot use unifyServer when in server mode!");
|
||||
JavaTXServer server = new JavaTXServer(serverPort.get());
|
||||
server.listen();
|
||||
}
|
||||
else {
|
||||
JavaTXCompiler compiler = new JavaTXCompiler(input, classpath, outputPath != null ? new File(outputPath) : null);
|
||||
//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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,11 @@
|
||||
package de.dhbwstuttgart.core;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.Codegen;
|
||||
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
||||
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
||||
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.languageServerInterface.model.LanguageServerTransferObject;
|
||||
import de.dhbwstuttgart.parser.JavaTXParser;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
||||
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
|
||||
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.GenericDeclarationList;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||
@@ -64,7 +62,6 @@ import de.dhbwstuttgart.util.Logger;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.file.Path;
|
||||
import java.sql.Array;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.function.Function;
|
||||
@@ -77,13 +74,11 @@ public class JavaTXCompiler {
|
||||
// do not use this in any code, that can be executed serverside!
|
||||
public static PlaceholderRegistry defaultClientPlaceholderRegistry = new PlaceholderRegistry();
|
||||
public static Logger defaultLogger = new Logger();
|
||||
private final boolean inferTogether;
|
||||
|
||||
// public static JavaTXCompiler INSTANCE;
|
||||
final CompilationEnvironment environment;
|
||||
Boolean resultmodel = true;
|
||||
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
||||
public final Set<JavaClassName> input = new HashSet<>();
|
||||
|
||||
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
||||
public final DirectoryClassLoader classLoader;
|
||||
@@ -91,28 +86,23 @@ public class JavaTXCompiler {
|
||||
public final List<File> classPath;
|
||||
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() {
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
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 {
|
||||
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
|
||||
defaultClientPlaceholderRegistry = new PlaceholderRegistry();
|
||||
this.inferTogether = inferTogether;
|
||||
NameGenerator.reset();
|
||||
ASTToTargetAST.OBJECT = ASTFactory.createObjectType();
|
||||
|
||||
var path = new ArrayList<>(contextPath);
|
||||
if (contextPath.isEmpty()) {
|
||||
@@ -120,43 +110,13 @@ public class JavaTXCompiler {
|
||||
path.add(new File(System.getProperty("user.dir")));
|
||||
}
|
||||
if (outputPath != null) path.add(outputPath);
|
||||
classLoader = new DirectoryClassLoader(path, ClassLoader.getSystemClassLoader().getParent());
|
||||
classLoader = new DirectoryClassLoader(path, ClassLoader.getSystemClassLoader());
|
||||
environment = new CompilationEnvironment(sources, classLoader);
|
||||
classPath = path;
|
||||
this.outputPath = outputPath;
|
||||
|
||||
// TODO This should maybe be moved elsewhere
|
||||
var treeList = new ArrayList<SourceFileContext>(sources.size());
|
||||
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));
|
||||
for (File s : sources) {
|
||||
parse(s);
|
||||
}
|
||||
// INSTANCE = this;
|
||||
}
|
||||
@@ -166,26 +126,21 @@ public class JavaTXCompiler {
|
||||
}
|
||||
|
||||
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 clazz : sf.KlassenVektor) {
|
||||
if (clazz.getClassName().equals(name)) return clazz;
|
||||
}
|
||||
}
|
||||
if (input.contains(name)) return null;
|
||||
try {
|
||||
var clazz = classLoader.loadClass(name.toString());
|
||||
ClassOrInterface cif = null;
|
||||
if (clazz != null) {
|
||||
cif = ASTFactory.createClass(clazz);
|
||||
loadedClasses.put(name, cif);
|
||||
}
|
||||
return cif;
|
||||
if (clazz != null)
|
||||
return ASTFactory.createClass(clazz);
|
||||
} catch (ClassNotFoundException ignored) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Set<ClassOrInterface> getAvailableClasses(File sourceFile) throws ClassNotFoundException, IOException {
|
||||
public ConstraintSet<Pair> getConstraints(File sourceFile) throws ClassNotFoundException, IOException {
|
||||
Set<ClassOrInterface> allClasses = new HashSet<>();// environment.getAllAvailableClasses();
|
||||
ClassOrInterface objectClass = ASTFactory.createClass(Object.class);
|
||||
var recordClass = ASTFactory.createClass(Record.class);
|
||||
@@ -211,7 +166,7 @@ public class JavaTXCompiler {
|
||||
for (var clazz : sf.availableClasses) {
|
||||
if (loadedClasses.containsKey(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);
|
||||
isCached = true;
|
||||
}
|
||||
@@ -224,13 +179,7 @@ public class JavaTXCompiler {
|
||||
|
||||
allClasses.addAll(sf.KlassenVektor);
|
||||
|
||||
return allClasses;
|
||||
}
|
||||
|
||||
public ConstraintSet<Pair> getConstraints(File sourceFile) throws ClassNotFoundException, IOException {
|
||||
var sf = sourceFiles.get(sourceFile);
|
||||
var allClasses = getAvailableClasses(sourceFile);
|
||||
TYPE ty = new TYPE(new HashSet<>(sf.availableClasses), allClasses);
|
||||
TYPE ty = new TYPE(sf, allClasses);
|
||||
var constraints = ty.getConstraints();
|
||||
return constraints;
|
||||
}
|
||||
@@ -250,9 +199,8 @@ public class JavaTXCompiler {
|
||||
try {
|
||||
var className = cl.getSuperClass().getName().toString();
|
||||
superclass = ASTFactory.createClass(classLoader.loadClass(className));
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} catch (ClassNotFoundException ignored) {}
|
||||
// throw new ClassNotFoundException("");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,18 +229,13 @@ public class JavaTXCompiler {
|
||||
|
||||
private Set<ClassOrInterface> getAvailableClasses(JavaClassName name) throws ClassNotFoundException {
|
||||
Set<ClassOrInterface> allClasses = new HashSet<>();
|
||||
if (input.contains(name)) {
|
||||
for (var sf : sourceFiles.values()) {
|
||||
for (var cif : sf.KlassenVektor) {
|
||||
if (cif.getClassName().equals(name)) {
|
||||
allClasses.add(cif);
|
||||
return allClasses;
|
||||
}
|
||||
}
|
||||
}
|
||||
var clazz = loadJavaTXClass(name);
|
||||
if (clazz == null) {
|
||||
ClassOrInterface importedClass = ASTFactory.createClass(classLoader.loadClass(name.toString()));
|
||||
allClasses.add(importedClass);
|
||||
} else {
|
||||
allClasses.add(clazz);
|
||||
}
|
||||
ClassOrInterface importedClass = ASTFactory.createClass(classLoader.loadClass(name.toString()));
|
||||
allClasses.add(importedClass);
|
||||
return allClasses;
|
||||
}
|
||||
|
||||
@@ -419,30 +362,25 @@ public class JavaTXCompiler {
|
||||
}
|
||||
|
||||
public List<ResultSet> typeInference(File file) throws ClassNotFoundException, IOException {
|
||||
return typeInference(List.of(file));
|
||||
}
|
||||
|
||||
public List<ResultSet> typeInference(List<File> files) throws ClassNotFoundException, IOException {
|
||||
Set<ClassOrInterface> allClasses = new HashSet<>();
|
||||
|
||||
var ressf = new ArrayList<SourceFile>();
|
||||
var definedClasses = new HashSet<ClassOrInterface>();
|
||||
for (var file : files) {
|
||||
var sf = sourceFiles.get(file);
|
||||
definedClasses.addAll(sf.KlassenVektor);
|
||||
ressf.add(sf);
|
||||
allClasses.addAll(getAvailableClasses(file));
|
||||
allClasses.addAll(sf.availableClasses);
|
||||
var sf = sourceFiles.get(file);
|
||||
Set<ClassOrInterface> allClasses = new HashSet<>();// environment.getAllAvailableClasses();
|
||||
allClasses.addAll(getAvailableClasses(sf));
|
||||
allClasses.addAll(sf.getClasses());
|
||||
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), file, this).stream().map(ASTFactory::createClass).collect(Collectors.toSet());
|
||||
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);
|
||||
}
|
||||
|
||||
TYPE ty = new TYPE(definedClasses, allClasses);
|
||||
var cons = ty.getConstraints();
|
||||
|
||||
final ConstraintSet<Pair> cons = getConstraints(file);
|
||||
Set<Set<UnifyPair>> results = new HashSet<>();
|
||||
PlaceholderRegistry placeholderRegistry = new PlaceholderRegistry();
|
||||
|
||||
var logFolder = new File(System.getProperty("user.dir") + "/logFiles/");
|
||||
if (ConsoleInterface.writeLogFiles && !logFolder.mkdirs()) throw new RuntimeException("Could not create directory for log files: " + logFolder);
|
||||
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());
|
||||
Logger logger = new Logger(logFile, "TypeInference");
|
||||
|
||||
@@ -460,175 +398,89 @@ public class JavaTXCompiler {
|
||||
|
||||
};
|
||||
|
||||
logger.debug("Unify:" + unifyCons.toString());
|
||||
logger.info("Unify:" + unifyCons.toString());
|
||||
unifyCons = unifyCons.map(distributeInnerVars);
|
||||
logger.debug("\nUnify_distributeInnerVars: " + unifyCons.toString());
|
||||
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
|
||||
logger.debug("FC:\\" + finiteClosure.toString() + "\n");
|
||||
for (var sf : ressf) logger.info(ASTTypePrinter.print(sf));
|
||||
// logFile.flush();
|
||||
List<UnifyPair> andConstraintsSorted = unifyCons.getUndConstraints().stream()
|
||||
.sorted(Comparator.comparing(UnifyPair::getPairOp).thenComparing(UnifyPair::getLhsType, Comparator.comparing(UnifyType::getName)))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
logger.info(andConstraintsSorted);
|
||||
|
||||
Set<PlaceholderType> varianceTPHold;
|
||||
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
||||
logger.debug("Unify:" + unifyCons.toString());
|
||||
logger.info("Unify:" + unifyCons.toString());
|
||||
unifyCons = unifyCons.map(distributeInnerVars);
|
||||
logger.debug("\nUnify_distributeInnerVars: " + unifyCons.toString());
|
||||
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
|
||||
logger.debug("FC:\\" + finiteClosure.toString() + "\n");
|
||||
logger.debug(ASTTypePrinter.print(sf));
|
||||
logger.info(ASTTypePrinter.print(sf));
|
||||
// logFile.flush();
|
||||
logger.info("Unify nach Oder-Constraints-Anpassung:" + unifyCons.toString());
|
||||
Set<PlaceholderType> varianceTPHold;
|
||||
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
||||
|
||||
/*
|
||||
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH); varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { if (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
|
||||
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) { ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType( )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType( )).getVariance()); } } return y; } ); } while (!varianceTPHold.equals(varianceTPH));
|
||||
*/
|
||||
|
||||
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
|
||||
// logFile, log);
|
||||
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
|
||||
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()// .stream().map(x -> {
|
||||
/*
|
||||
* Set<Set<UnifyPair>> ret = new HashSet<>(); for (Constraint<UnifyPair> y : x) { ret.add(new HashSet<>(y)); } return ret; }).collect(Collectors.toCollection(ArrayList::new))
|
||||
*/;
|
||||
if (ConsoleInterface.unifyServerUrl.isPresent()) {
|
||||
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
|
||||
UnifyContext context = new UnifyContext(logger, true, urm, usedTasks, placeholderRegistry);
|
||||
SocketFuture<UnifyResultPacket> future = SocketClient.execute(
|
||||
UnifyRequestPacket.create(finiteClosure, cons, unifyCons, context.placeholderRegistry())
|
||||
);
|
||||
SocketClient.execute(SetAutoclosePacket.create());
|
||||
return future.get().getResultSet(context);
|
||||
}
|
||||
else if (resultmodel) {
|
||||
/* UnifyResultModel Anfang */
|
||||
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
|
||||
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
|
||||
urm.addUnifyResultListener(li);
|
||||
UnifyContext context = new UnifyContext(logger, true, urm, usedTasks, placeholderRegistry);
|
||||
TypeUnify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
|
||||
var finalResults = li.getResults().stream().sorted().toList();
|
||||
int i = 0;
|
||||
logger.info("RESULT Final: ");
|
||||
for (var result : finalResults){
|
||||
logger.info("Result: " + i++);
|
||||
logger.info(result.getSortedResults());
|
||||
}
|
||||
logger.info("RES_FINAL: " + li.getResults().toString() + "\n");
|
||||
return li.getResults();
|
||||
}
|
||||
/* UnifyResultModel End */
|
||||
else {
|
||||
// Set<Set<UnifyPair>> result = unify.unify(unifyCons.getUndConstraints(),
|
||||
// oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons,
|
||||
// finiteClosure));
|
||||
UnifyContext context = new UnifyContext(logger, false, new UnifyResultModel(cons, finiteClosure), usedTasks, placeholderRegistry);
|
||||
Set<Set<UnifyPair>> result = TypeUnify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
|
||||
logger.info("RESULT: " + result);
|
||||
results.addAll(result);
|
||||
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
|
||||
// logFile, log);
|
||||
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
|
||||
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()// .stream().map(x -> {
|
||||
/*
|
||||
* Set<Set<UnifyPair>> ret = new HashSet<>(); for (Constraint<UnifyPair> y : x) { ret.add(new HashSet<>(y)); } return ret; }).collect(Collectors.toCollection(ArrayList::new))
|
||||
*/;
|
||||
|
||||
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();
|
||||
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);
|
||||
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());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
@@ -686,36 +538,75 @@ public class JavaTXCompiler {
|
||||
|
||||
public final JavaClassRegistry classRegistry = new JavaClassRegistry();
|
||||
|
||||
private void parse(SourceFileContext tree, File sourceFile) throws IOException, java.lang.ClassNotFoundException {
|
||||
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null), sourceFile.getName());
|
||||
public record ClassEntry(File classFile, ClassOrInterface cif) {}
|
||||
|
||||
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);
|
||||
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null), sourceFile.getName());
|
||||
var classes = new ArrayList<ClassOrInterface>();
|
||||
var sf = new SourceFile("", classes, generator.imports);
|
||||
addSourceFile(sourceFile, sf);
|
||||
generator.convert(classes, tree, environment.packageCrawler);
|
||||
sf.setPackageName(generator.pkgName);
|
||||
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 {
|
||||
if (inferTogether) {
|
||||
var files = sourceFiles.keySet().stream().toList();
|
||||
var typeinferenceResult = this.typeInference(files);
|
||||
for (var file : files) {
|
||||
var sf = sourceFiles.get(file);
|
||||
if (sf.isGenerated()) continue;
|
||||
var classes = generateBytecode(sf, typeinferenceResult);
|
||||
sf.setGenerated();
|
||||
writeClassFile(classes, outputPath == null ? file.getParentFile() : outputPath, outputPath == null);
|
||||
}
|
||||
} else {
|
||||
for (var file : sourceFiles.keySet()) {
|
||||
var sf = sourceFiles.get(file);
|
||||
if (sf.isGenerated()) continue;
|
||||
var classes = generateBytecode(file);
|
||||
sf.setGenerated();
|
||||
writeClassFile(classes, outputPath == null ? file.getParentFile() : outputPath, outputPath == null);
|
||||
}
|
||||
for (var file : sourceFiles.keySet()) {
|
||||
var sf = sourceFiles.get(file);
|
||||
if (sf.isGenerated()) continue;
|
||||
var classes = generateBytecode(file);
|
||||
sf.setGenerated();
|
||||
writeClassFile(classes, outputPath == null ? file.getParentFile() : outputPath, outputPath == null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -760,12 +651,12 @@ public class JavaTXCompiler {
|
||||
var codegen = new Codegen(converter.convert(clazz), this, converter);
|
||||
var code = codegen.generate();
|
||||
generatedClasses.put(clazz.getClassName(), code);
|
||||
converter.auxiliaries.forEach((name, source) -> {
|
||||
generatedClasses.put(new JavaClassName(name), source);
|
||||
});
|
||||
}
|
||||
generatedGenerics.put(sf, converter.javaGenerics());
|
||||
converter.generateFunNTypes();
|
||||
auxiliaries.forEach((name, source) -> {
|
||||
generatedClasses.put(new JavaClassName(name), source);
|
||||
});
|
||||
return generatedClasses;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import java.util.*;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
|
||||
@@ -31,7 +30,7 @@ public class CompilationEnvironment {
|
||||
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
|
||||
*/
|
||||
@@ -88,8 +87,6 @@ public class CompilationEnvironment {
|
||||
if (files != null)
|
||||
for (File classFile : files) {
|
||||
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+\\$\\$.*"))
|
||||
continue;
|
||||
var name = packageName;
|
||||
|
||||
@@ -16,7 +16,7 @@ public class DirectoryClassLoader extends URLClassLoader implements IByteArrayCl
|
||||
// }
|
||||
|
||||
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) {
|
||||
|
||||
@@ -6,22 +6,18 @@ import java.nio.file.Path;
|
||||
|
||||
public interface IByteArrayClassLoader {
|
||||
|
||||
Class<?> loadClass(String path) throws ClassNotFoundException;
|
||||
Class loadClass(String path) throws ClassNotFoundException;
|
||||
|
||||
default Class<?> loadClass(byte[] code) {
|
||||
return this.loadClass(null, code);
|
||||
default Class loadClass(byte[] code) {
|
||||
return this._defineClass(null, code, 0, code.length);
|
||||
}
|
||||
|
||||
default Class<?> loadClass(String name, byte[] code) {
|
||||
return this._defineClass(name, code, 0, code.length);
|
||||
}
|
||||
|
||||
default Class<?> loadClass(Path path) throws IOException {
|
||||
default Class loadClass(Path path) throws IOException {
|
||||
var code = Files.readAllBytes(path);
|
||||
return this._defineClass(null, code, 0, code.length);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -151,7 +151,7 @@ public class StatementGenerator {
|
||||
} else {
|
||||
type = methodparameters?
|
||||
TypePlaceholder.fresh(fp.getStart(), 1, false)
|
||||
: TypePlaceholder.fresh(fp.getStart(), 1, false);
|
||||
: TypePlaceholder.fresh(fp.getStart());
|
||||
}
|
||||
ret.add(new FormalParameter(paramName, type, fp.getStart()));
|
||||
localVars.put(paramName, type);
|
||||
@@ -1066,7 +1066,7 @@ public class StatementGenerator {
|
||||
List<Pattern> parameterList = new ArrayList<>();
|
||||
for (IdentifierContext identifier : lambdaParams.identifier()) {
|
||||
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());
|
||||
} else if (lambdaParams.formalParameterList() != null) {
|
||||
@@ -1076,7 +1076,7 @@ public class StatementGenerator {
|
||||
List<Pattern> parameterList = new ArrayList<>();
|
||||
for (LambdaLVTIParameterContext param : lambdaParams.lambdaLVTIList().lambdaLVTIParameter()) {
|
||||
Token offset = param.getStart();
|
||||
parameterList.add(new FormalParameter(param.identifier().getText(), TypePlaceholder.fresh(offset, 1, false), offset));
|
||||
parameterList.add(new FormalParameter(param.identifier().getText(), TypePlaceholder.fresh(offset), offset));
|
||||
}
|
||||
params = new ParameterList(parameterList, lambdaParams.getStart());
|
||||
} else {
|
||||
@@ -1100,9 +1100,9 @@ public class StatementGenerator {
|
||||
block = lambdaGenerator.convert(expression.lambdaBody().block(), true);
|
||||
}
|
||||
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:
|
||||
funNParams.add(TypePlaceholder.fresh(expression.getStart(), 1, false)));
|
||||
funNParams.add(TypePlaceholder.fresh(expression.getStart())));
|
||||
RefTypeOrTPHOrWildcardOrGeneric lambdaType = TypePlaceholder.fresh(expression.getStart());
|
||||
// RefType lambdaType = new
|
||||
// RefType(reg.getName("Fun"+params.getFormalparalist().size()),
|
||||
|
||||
@@ -111,7 +111,7 @@ public class SyntaxTreeGenerator {
|
||||
this.allmodifiers.put(Modifier.toString(Modifier.INTERFACE), Modifier.INTERFACE);
|
||||
this.allmodifiers.put("sealed", 4096);
|
||||
this.allmodifiers.put("non-sealed", 8192);
|
||||
this.allmodifiers.put("default", 0); // Doesn't exist
|
||||
this.allmodifiers.put("default", 16384);
|
||||
this.allmodifiers.put("strictfp", 32768);
|
||||
|
||||
this.compiler = compiler;
|
||||
|
||||
@@ -168,7 +168,7 @@ public class TypeGenerator {
|
||||
if (generics.contains(name)) {
|
||||
return new GenericRefType(name, offset);
|
||||
} else {
|
||||
Pattern p = Pattern.compile("Fun(Void|VoidImpl|Wrapper)?(\\d+)[$][$]"); // TODO Regex shenanigans
|
||||
Pattern p = Pattern.compile("Fun(\\d+)[$][$]");
|
||||
Matcher m = p.matcher(name);
|
||||
if (m.matches()) {// es ist FunN$$-Type
|
||||
return new RefType(new JavaClassName(name), convert(typeArguments, reg, generics), offset);
|
||||
|
||||
@@ -140,7 +140,8 @@ public class GatherNames {
|
||||
if (importDeclCtx.MUL() == null) {
|
||||
var name = importDeclCtx.qualifiedName().getText();
|
||||
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));
|
||||
} else {
|
||||
Class<?> cl = compiler.getClassLoader().loadClass(name);
|
||||
|
||||
@@ -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:
|
||||
* java.lang.Object wird zu: Object
|
||||
*/
|
||||
|
||||
@@ -5,9 +5,9 @@ import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
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<>();
|
||||
|
||||
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) {
|
||||
existingClasses.put(new JavaClassName(className), numberOfGenerics);
|
||||
}
|
||||
@@ -64,6 +60,6 @@ public class JavaClassRegistry{
|
||||
}
|
||||
|
||||
public int getNumberOfGenerics(String name) {
|
||||
return existingClasses.getOrDefault(new JavaClassName(name), 0);
|
||||
return existingClasses.get(new JavaClassName(name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package de.dhbwstuttgart.server.packet.dataContainers.serialized;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class SerialMap extends HashMap<String, ISerialNode> implements ISerialNode {
|
||||
|
||||
|
||||
@@ -6,12 +6,10 @@ import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.target.tree.TargetGeneric;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 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> permittedSubtypes;
|
||||
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) {
|
||||
super(offset);
|
||||
@@ -202,22 +199,4 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
||||
public int hashCode() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,8 @@ import java.util.*;
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
//import sun.security.x509.X509CertInfo;
|
||||
|
||||
public class SourceFile extends SyntaxTreeNode {
|
||||
@@ -20,7 +18,6 @@ public class SourceFile extends SyntaxTreeNode {
|
||||
private boolean isGenerated;
|
||||
|
||||
public List<ClassOrInterface> availableClasses = new ArrayList<>();
|
||||
public List<ASTToTargetAST.Generics> generics = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
public void addResultSet(ResultSet rs) {
|
||||
|
||||
}
|
||||
|
||||
public void setPackageName(String packageName) {
|
||||
this.pkgName = packageName;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.*;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import de.dhbwstuttgart.bytecode.JavaTXSignatureAttribute;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
@@ -154,13 +153,15 @@ public class ASTFactory {
|
||||
int modifier = jreClass.getModifiers();
|
||||
boolean isInterface = jreClass.isInterface();
|
||||
List<Annotation> aLA;
|
||||
boolean isFunctionalInterface =
|
||||
!(aLA = Arrays.asList(jreClass.getAnnotations())).isEmpty() &&
|
||||
aLA.get(0) instanceof FunctionalInterface;
|
||||
boolean isFunctionalInterface =
|
||||
(aLA = Arrays.asList(jreClass.getAnnotations())).size() > 0 &&
|
||||
aLA.get(0) instanceof FunctionalInterface ?
|
||||
true :
|
||||
false;
|
||||
// see: https://stackoverflow.com/questions/9934774/getting-generic-parameter-from-supertype-class
|
||||
ParameterizedType parameterSuperClass = null;
|
||||
Type tempSuperClass = jreClass.getGenericSuperclass();
|
||||
if (tempSuperClass instanceof ParameterizedType)
|
||||
if (tempSuperClass != null && tempSuperClass instanceof ParameterizedType)
|
||||
parameterSuperClass = (ParameterizedType) tempSuperClass;
|
||||
java.lang.Class superjreClass = jreClass.getSuperclass();
|
||||
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
|
||||
|
||||
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);
|
||||
|
||||
@@ -16,10 +16,6 @@ public class NameGenerator {
|
||||
public static void reset() {
|
||||
strNextName = "A";
|
||||
}
|
||||
|
||||
public static void resetTo(String name) {
|
||||
strNextName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Berechnet einen neuen, eindeutigen Namen f�r eine neue
|
||||
|
||||
@@ -2,6 +2,7 @@ package de.dhbwstuttgart.target.generate;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
@@ -11,14 +12,12 @@ import de.dhbwstuttgart.syntaxtree.Record;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
|
||||
import de.dhbwstuttgart.syntaxtree.visual.OutputGenerator;
|
||||
import de.dhbwstuttgart.target.Target;
|
||||
import de.dhbwstuttgart.target.tree.*;
|
||||
import de.dhbwstuttgart.target.tree.expression.*;
|
||||
import de.dhbwstuttgart.target.tree.type.*;
|
||||
import de.dhbwstuttgart.typeinference.result.*;
|
||||
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
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 List<Generics> all;
|
||||
//public Generics generics;
|
||||
//public List<Generics> currentMethodOverloads;
|
||||
protected List<Generics> all;
|
||||
public Generics generics;
|
||||
public List<Generics> currentMethodOverloads;
|
||||
|
||||
final Map<ClassOrInterface, Set<GenericTypeVar>> userDefinedGenerics = 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();
|
||||
}
|
||||
|
||||
public TargetExpression convert(Pattern pattern, IGenerics generics) {
|
||||
var converter = new StatementToTargetExpression(this, generics);
|
||||
public TargetExpression convert(Pattern pattern) {
|
||||
var converter = new StatementToTargetExpression(this);
|
||||
pattern.accept(converter);
|
||||
return converter.result;
|
||||
}
|
||||
|
||||
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;
|
||||
protected SourceFile sourceFile;
|
||||
|
||||
public ASTToTargetAST(List<ResultSet> resultSets, IByteArrayClassLoader classLoader) {
|
||||
this(null, resultSets, classLoader);
|
||||
public ASTToTargetAST(List<ResultSet> resultSets) {
|
||||
this(null, resultSets);
|
||||
}
|
||||
public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets, IByteArrayClassLoader classLoader) {
|
||||
this(compiler, resultSets, null, classLoader);
|
||||
public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets) {
|
||||
this(compiler, resultSets, null, new ByteArrayClassLoader());
|
||||
}
|
||||
|
||||
public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets, SourceFile sourceFile, IByteArrayClassLoader classLoader) {
|
||||
@@ -84,8 +81,9 @@ public class ASTToTargetAST {
|
||||
|
||||
all = new ArrayList<>();
|
||||
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) {
|
||||
@@ -94,27 +92,27 @@ public class ASTToTargetAST {
|
||||
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();
|
||||
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;
|
||||
owner = compiler.getClass(owner.getSuperClass().getName());
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
Optional<Constructor> findConstructor(ClassOrInterface owner, List<TargetType> argumentList, IGenerics generics) {
|
||||
return owner.getConstructors().stream().filter(c -> parameterEquals(c.getParameterList(), argumentList, generics)).findFirst();
|
||||
Optional<Constructor> findConstructor(ClassOrInterface owner, List<TargetType> argumentList) {
|
||||
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();
|
||||
if (pars.size() != arguments.size())
|
||||
return false;
|
||||
|
||||
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);
|
||||
if (type1 instanceof TargetGenericType)
|
||||
return true;
|
||||
@@ -127,19 +125,19 @@ public class ASTToTargetAST {
|
||||
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 -> {
|
||||
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) {
|
||||
return new TargetGeneric(pair.left.resolve().getName(), convert(pair.right, generics, compiler));
|
||||
return new TargetGeneric(pair.left.resolve().getName(), convert(pair.right, generics));
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public List<TargetGeneric> convert(GenericTypeVar typeVar, IGenerics generics) {
|
||||
public List<TargetGeneric> convert(GenericTypeVar typeVar, GenerateGenerics generics) {
|
||||
var ret = new ArrayList<TargetGeneric>();
|
||||
for (var bound : typeVar.getBounds()) {
|
||||
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 function should do matching or unification
|
||||
private List<ClassOrInterface> commonSuperInterfaceTypes(TargetType a, TargetType b) {
|
||||
if (a instanceof TargetGenericType && b instanceof TargetGenericType) return List.of(ASTFactory.createObjectClass());
|
||||
if (a instanceof TargetRefType ta && b instanceof TargetGenericType)
|
||||
@@ -186,28 +183,44 @@ public class ASTToTargetAST {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
private boolean canCombine(Signature m1, Signature m2) {
|
||||
var pl1 = m1.java.parameters();
|
||||
var pl2 = m2.java.parameters();
|
||||
if (pl1.size() != pl2.size()) return false;
|
||||
if (pl1.isEmpty()) return false;
|
||||
for (var i = 0; i < pl1.size(); i++) {
|
||||
var p1 = pl1.get(i).pattern();
|
||||
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
|
||||
// TODO This is ugly and probably doesn't work right
|
||||
private boolean patternStrictlyEquals(TargetComplexPattern a, TargetComplexPattern b) {
|
||||
if (!a.name().equals(b.name())) return false;
|
||||
if (a.subPatterns().size() != b.subPatterns().size()) return false;
|
||||
for (var i = 0; i < a.subPatterns().size(); i++) {
|
||||
var p1 = a.subPatterns().get(i);
|
||||
var p2 = b.subPatterns().get(i);
|
||||
if (p1 instanceof TargetComplexPattern pc1 && p2 instanceof TargetComplexPattern pc2 &&
|
||||
pc1.type().equals(pc2.type())) continue;
|
||||
if (!p1.equals(p2)) return false;
|
||||
patternStrictlyEquals(pc1, pc2)) 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;
|
||||
}
|
||||
|
||||
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
|
||||
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) ||
|
||||
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) {
|
||||
var mapOfTargetMethods = new HashMap<Generics, MethodWithTphs[]>();
|
||||
for (var gen : all) {
|
||||
mapOfTargetMethods.put(gen, new MethodWithTphs[methods.size()]);
|
||||
public List<List<TargetMethod>> groupOverloads(ClassOrInterface input, List<Method> methods) {
|
||||
var mapOfTargetMethods = new HashMap<Generics, TargetMethod[]>();
|
||||
for (var generics : all) {
|
||||
mapOfTargetMethods.put(generics, new TargetMethod[methods.size()]);
|
||||
}
|
||||
|
||||
for (var i = 0; i < methods.size(); i++) {
|
||||
@@ -230,14 +243,14 @@ public class ASTToTargetAST {
|
||||
var methodsWithTphs = convert(input, method);
|
||||
for (var m : methodsWithTphs) {
|
||||
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 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();
|
||||
}
|
||||
}*/
|
||||
|
||||
var allCombinations = new HashSet<Set<Combination>>();
|
||||
// Combine methods based on their signature and position in the result set
|
||||
@@ -255,8 +268,8 @@ public class ASTToTargetAST {
|
||||
|
||||
var combinations = new HashSet<Combination>();
|
||||
|
||||
if (canCombine(m1.signature, m2.signature)) {
|
||||
//System.out.println(" Combining " + m1.signature.java.getSignature() + " and " + m2.signature.java.getSignature());
|
||||
if (canCombine(m1, m2)) {
|
||||
//System.out.println(" Combining " + m1.getSignature() + " and " + m2.getSignature());
|
||||
combinations.add(new Combination(m1, m2));
|
||||
for (var j = 0; j < methods.size(); j++) {
|
||||
if (j == i) continue;
|
||||
@@ -265,10 +278,10 @@ public class ASTToTargetAST {
|
||||
var m4 = resMeth1[j];
|
||||
if (m4 == null) continue;
|
||||
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 {
|
||||
//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);
|
||||
}
|
||||
@@ -278,14 +291,14 @@ public class ASTToTargetAST {
|
||||
if (allCombinations.isEmpty()) allCombinations.add(new HashSet<>());
|
||||
|
||||
// Combine back into output format
|
||||
var r0 = new HashSet<Set<MethodWithTphs>>();
|
||||
var r0 = new HashSet<Set<TargetMethod>>();
|
||||
for (var combinations : allCombinations) {
|
||||
var r1 = new HashSet<Set<MethodWithTphs>>();
|
||||
var r1 = new HashSet<Set<TargetMethod>>();
|
||||
// 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
|
||||
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];
|
||||
if (m == null) continue;
|
||||
if (!uniqued.contains(m)) {
|
||||
@@ -325,16 +338,15 @@ public class ASTToTargetAST {
|
||||
|
||||
var result = r0.stream().map(l -> l.stream().toList()).toList();
|
||||
|
||||
//System.out.println("============== OUTPUT ==============");
|
||||
//for (var l : result) {
|
||||
// for (var m : l) System.out.println(m.method.name + " " + m.signature.java.getSignature());
|
||||
// System.out.println();
|
||||
//}
|
||||
Target.logger.info("============== OUTPUT ==============");
|
||||
for (var l : result) {
|
||||
for (var m : l) Target.logger.info(m.name() + " " + m.getSignature());
|
||||
Target.logger.info("");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public TargetStructure convert(ClassOrInterface input) {
|
||||
var generics = all.getFirst();
|
||||
Set<TargetGeneric> javaGenerics = new HashSet<>();
|
||||
Set<TargetGeneric> txGenerics = new HashSet<>();
|
||||
|
||||
@@ -347,7 +359,7 @@ public class ASTToTargetAST {
|
||||
var next = genericsIter.next();
|
||||
userDefinedGenerics.add(next);
|
||||
// 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 {
|
||||
this.userDefinedGenerics.put(input, new HashSet<>());
|
||||
@@ -358,38 +370,31 @@ public class ASTToTargetAST {
|
||||
|
||||
TargetBlock fieldInitializer = null;
|
||||
if (input.getfieldInitializations().isPresent())
|
||||
fieldInitializer = convert(input.getfieldInitializations().get().block, generics.javaGenerics);
|
||||
fieldInitializer = convert(input.getfieldInitializations().get().block);
|
||||
TargetBlock finalFieldInitializer = fieldInitializer;
|
||||
|
||||
var superInterfaces = input.getSuperInterfaces().stream().map(clazz -> convert(clazz, generics.javaGenerics, compiler)).toList();
|
||||
var constructors = input.getConstructors().stream().map(constructor -> this.convert(input, constructor, finalFieldInitializer, generics)).flatMap(List::stream).toList();
|
||||
var fields = input.getFieldDecl().stream().map(f -> convert(f, generics.javaGenerics)).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)).flatMap(List::stream).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)
|
||||
.collect(Collectors.toSet()).stream().toList(); // Unique generated methods
|
||||
|
||||
TargetMethod staticConstructor = null;
|
||||
if (input.getStaticInitializer().isPresent()) {
|
||||
var init = this.convert(input, input.getStaticInitializer().get()).stream().findFirst().orElseThrow();
|
||||
staticConstructor = this.convert(init, init.generics.javaGenerics);
|
||||
}
|
||||
if (input.getStaticInitializer().isPresent())
|
||||
staticConstructor = this.convert(input, input.getStaticInitializer().get()).stream().findFirst().orElseThrow().method;
|
||||
|
||||
if (input instanceof Record)
|
||||
return new TargetRecord(input.getModifiers(), input.getClassName(), javaGenerics, txGenerics, superInterfaces, constructors, staticConstructor, fields, methods);
|
||||
else if (input.isInterface())
|
||||
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) {
|
||||
return convert(input, all.getFirst().javaGenerics);
|
||||
}
|
||||
|
||||
public List<MethodParameter> convert(ParameterList input, IGenerics generics) {
|
||||
public List<MethodParameter> convert(ParameterList input, GenerateGenerics generics) {
|
||||
var res = new ArrayList<MethodParameter>();
|
||||
for (var i = 0; i < input.getFormalparalist().size(); 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);
|
||||
res.add(new MethodParameter(pattern));
|
||||
}
|
||||
@@ -400,7 +405,7 @@ public class ASTToTargetAST {
|
||||
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));
|
||||
outer: for (GenericTypeVar typeVar : input.getGenerics()) {
|
||||
for (var classGeneric : clazz.getGenerics()) {
|
||||
@@ -418,7 +423,7 @@ public class ASTToTargetAST {
|
||||
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);
|
||||
List<TargetConstructor> result = new ArrayList<>();
|
||||
Set<List<MethodParameter>> parameterSet = new HashSet<>();
|
||||
@@ -426,15 +431,15 @@ public class ASTToTargetAST {
|
||||
|
||||
for (var s : all) {
|
||||
generics = s;
|
||||
var javaGenerics = generics.javaGenerics.generics(currentClass, input);
|
||||
var txGenerics = generics.txGenerics.generics(currentClass, input);
|
||||
List<MethodParameter> params = convert(input.getParameterList(), generics.javaGenerics);
|
||||
var javaGenerics = this.generics.javaGenerics.generics(currentClass, input);
|
||||
var txGenerics = this.generics.txGenerics.generics(currentClass, input);
|
||||
List<MethodParameter> params = convert(input.getParameterList(), this.generics.javaGenerics);
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
@@ -442,13 +447,10 @@ public class ASTToTargetAST {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int counter = 0;
|
||||
private String encodeName(String name, TargetMethod.Signature params) {
|
||||
var res = new StringBuilder();
|
||||
res.append(name);
|
||||
res.append('$');
|
||||
res.append(counter++);
|
||||
res.append('$');
|
||||
for (var param : params.parameters()) {
|
||||
encodeName(param.pattern(), res);
|
||||
}
|
||||
@@ -524,14 +526,12 @@ public class ASTToTargetAST {
|
||||
var j = 0;
|
||||
for (var param : m.signature().parameters()) {
|
||||
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++;
|
||||
}
|
||||
return true;
|
||||
}).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 body = new TargetBlock(List.of(caseBody));
|
||||
var case_ = new TargetSwitch.Case(List.of(lastPattern), body);
|
||||
@@ -542,14 +542,19 @@ public class ASTToTargetAST {
|
||||
return new TargetSwitch(switchExpr, cases, null, true);
|
||||
}
|
||||
|
||||
private List<TargetMethod> generatePatternOverloads(ClassOrInterface clazz, List<MethodWithTphs> overloadedMethods) {
|
||||
if (overloadedMethods.isEmpty()) return List.of();
|
||||
private List<TargetMethod> generatePatternOverloads(ClassOrInterface clazz, List<TargetMethod> overloadedMethods) {
|
||||
if (overloadedMethods.size() <= 1) return overloadedMethods;
|
||||
// Check if we have a pattern as a parameter
|
||||
var firstMethod = convert(overloadedMethods.getFirst(), overloadedMethods.getFirst().generics.javaGenerics);
|
||||
if (overloadedMethods.size() == 1) return List.of(firstMethod);
|
||||
var secondMethod = convert(overloadedMethods.get(1), overloadedMethods.get(1).generics.javaGenerics);
|
||||
if (firstMethod.signature().parameters().stream().noneMatch(mp -> mp.pattern() instanceof TargetComplexPattern))
|
||||
return overloadedMethods.stream().map(m -> convert(m, m.generics.javaGenerics)).toList();
|
||||
var firstMethod = overloadedMethods.getFirst();
|
||||
var secondMethod = overloadedMethods.get(1);
|
||||
if (firstMethod.signature().parameters().stream().noneMatch(mp -> mp.pattern() instanceof TargetComplexPattern)) return overloadedMethods;
|
||||
// Rename existing methods
|
||||
|
||||
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>();
|
||||
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 commonSubTypes = new HashSet<>(commonSuperInterfaceTypes(t1, t2));
|
||||
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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
// 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()));
|
||||
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());
|
||||
|
||||
@@ -615,7 +601,7 @@ public class ASTToTargetAST {
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
var cases = new ArrayList<SwitchBlock>();
|
||||
@@ -635,7 +621,7 @@ public class ASTToTargetAST {
|
||||
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 methodStream = superClass.getMethods().stream();
|
||||
for (var superInterface : currentClass.getSuperInterfaces()) {
|
||||
@@ -648,106 +634,124 @@ public class ASTToTargetAST {
|
||||
if (sParams.getFormalparalist().size() != params.size()) return false;
|
||||
for (var i = 0; i < params.size(); i++) {
|
||||
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;
|
||||
}
|
||||
return true;
|
||||
}).findFirst();
|
||||
}
|
||||
|
||||
record MethodWithTphs(Method method, Generics generics, Signature signature) {
|
||||
record MethodWithTphs(TargetMethod method, Generics generics, List<SignaturePairTarget> args) {
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
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
|
||||
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) {}
|
||||
|
||||
private List<MethodWithTphs> convert(ClassOrInterface currentClass, Method method) {
|
||||
generics = all.getFirst();
|
||||
List<MethodWithTphs> result = new ArrayList<>();
|
||||
this.currentMethod = method;
|
||||
|
||||
List<Signature> signatures = new ArrayList<>();
|
||||
for (var generics : all) {
|
||||
var javaGenerics = generics.javaGenerics.generics(currentClass, method);
|
||||
var txGenerics = generics.txGenerics.generics(currentClass, method);
|
||||
List<MethodParameter> params = convert(method.getParameterList(), generics.javaGenerics);
|
||||
var returnType = convert(method.getReturnType(), generics.javaGenerics, compiler);
|
||||
var superMethod = findSuperMethodToOverride(currentClass, method.getName(), params, generics.javaGenerics);
|
||||
HashMap<TargetMethod.Signature, List<Generics>> collectedGenerics = new HashMap<>();
|
||||
|
||||
for (var s : all) {
|
||||
generics = s;
|
||||
var javaGenerics = this.generics.javaGenerics.generics(currentClass, method);
|
||||
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 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)) {
|
||||
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 txMethodGenerics = collectMethodGenerics(currentClass, generics.txGenerics(), txGenerics, method);
|
||||
|
||||
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));
|
||||
var listOfGenerics = collectedGenerics.getOrDefault(javaSignature, new ArrayList<>());
|
||||
listOfGenerics.add(generics);
|
||||
collectedGenerics.put(javaSignature, listOfGenerics);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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>();
|
||||
for (var i = 0; i < paraList.getFormalparalist().size(); 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);
|
||||
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;
|
||||
}
|
||||
|
||||
protected TargetSwitch.Case convert(SwitchBlock block, IGenerics generics) {
|
||||
return new TargetSwitch.Case(block.getLabels().stream().map(s -> convert(s, generics)).toList(), convert((Block) block, generics), block.isExpression);
|
||||
protected TargetSwitch.Case convert(SwitchBlock block) {
|
||||
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;
|
||||
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) {
|
||||
var res = convert(expression, generics);
|
||||
protected TargetBlock convertWrapInBlock(Expression expression) {
|
||||
var res = convert(expression);
|
||||
if (!(res instanceof TargetBlock))
|
||||
return new TargetBlock(List.of(res));
|
||||
return (TargetBlock) res;
|
||||
}
|
||||
|
||||
protected TargetExpression convert(Expression expr, IGenerics generics) {
|
||||
var converter = new StatementToTargetExpression(this, generics);
|
||||
protected TargetExpression convert(Expression expr) {
|
||||
var converter = new StatementToTargetExpression(this);
|
||||
expr.accept(converter);
|
||||
return converter.result;
|
||||
}
|
||||
|
||||
private TargetField convert(Field input, IGenerics generics) {
|
||||
return new TargetField(input.modifier, convert(input.getType(), generics, compiler), input.getName());
|
||||
private TargetField convert(Field input) {
|
||||
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) {
|
||||
@@ -778,15 +782,7 @@ public class ASTToTargetAST {
|
||||
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) {
|
||||
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 otherClass = compiler.getClass(new JavaClassName(other.name()));
|
||||
if (testClass == null) return false;
|
||||
@@ -814,30 +810,28 @@ public class ASTToTargetAST {
|
||||
}
|
||||
|
||||
public void generateFunNTypes() {
|
||||
for (var entry : compiler.usedFunN.entrySet()) {
|
||||
for (var entry : usedFunN.entrySet()) {
|
||||
var gep = entry.getValue();
|
||||
var superInterfaces = compiler.usedFunN.values().stream()
|
||||
var superInterfaces = usedFunN.values().stream()
|
||||
.filter(g -> !g.equals(gep))
|
||||
.filter(genericParameters -> isSubtype(gep, genericParameters))
|
||||
.map(FunNGenerator::getSpecializedClassName)
|
||||
.toList();
|
||||
|
||||
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
|
||||
@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) {
|
||||
protected TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, GenerateGenerics generics) {
|
||||
return input.acceptTV(new TypeVisitor<>() {
|
||||
@Override
|
||||
public TargetType visit(RefType refType) {
|
||||
@@ -849,31 +843,31 @@ public class ASTToTargetAST {
|
||||
}
|
||||
|
||||
var params = refType.getParaList().stream().map(type -> {
|
||||
return convert(type, generics, compiler);
|
||||
return convert(type, generics);
|
||||
}).toList();
|
||||
|
||||
if (name.matches("Fun\\d+\\$\\$")) { // TODO This seems like a bad idea
|
||||
var returnType = FunNGenerator.getReturnType(params);
|
||||
var className = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), returnType);
|
||||
if (!compiler.usedFunNSuperTypes.contains(params.size())) {
|
||||
compiler.usedFunNSuperTypes.add(params.size());
|
||||
if (!usedFunNSuperTypes.contains(params.size())) {
|
||||
usedFunNSuperTypes.add(params.size());
|
||||
var code = FunNGenerator.generateSuperBytecode(params.size() - 1, returnType != null ? 1 : 0);
|
||||
var superClassName = FunNGenerator.getSuperClassName(params.size() - 1, returnType != null ? 1 : 0);
|
||||
try {
|
||||
compiler.classLoader.findClass(superClassName);
|
||||
classLoader.findClass(superClassName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
try {
|
||||
compiler.classLoader.loadClass(superClassName, code);
|
||||
classLoader.loadClass(code);
|
||||
} catch (LinkageError ignored) {}
|
||||
}
|
||||
compiler.auxiliaries.put(superClassName, code);
|
||||
auxiliaries.put(superClassName, code);
|
||||
}
|
||||
FunNGenerator.GenericParameters gep = null;
|
||||
if (!compiler.usedFunN.containsKey(className)) {
|
||||
if (!usedFunN.containsKey(className)) {
|
||||
gep = new FunNGenerator.GenericParameters(params, returnType != null ? 1 : 0);
|
||||
compiler.usedFunN.put(className, gep);
|
||||
usedFunN.put(className, gep);
|
||||
} else {
|
||||
gep = compiler.usedFunN.get(className);
|
||||
gep = usedFunN.get(className);
|
||||
}
|
||||
return flattenFunNType(params, gep);
|
||||
}
|
||||
@@ -882,7 +876,7 @@ public class ASTToTargetAST {
|
||||
|
||||
@Override
|
||||
public TargetType visit(SuperWildcardType superWildcardType) {
|
||||
return new TargetSuperWildcard(convert(superWildcardType.getInnerType(), generics, compiler));
|
||||
return new TargetSuperWildcard(convert(superWildcardType.getInnerType(), generics));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -892,7 +886,7 @@ public class ASTToTargetAST {
|
||||
|
||||
@Override
|
||||
public TargetType visit(ExtendsWildcardType extendsWildcardType) {
|
||||
return new TargetExtendsWildcard(convert(extendsWildcardType.getInnerType(), generics, compiler));
|
||||
return new TargetExtendsWildcard(convert(extendsWildcardType.getInnerType(), generics));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -18,9 +18,9 @@ import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
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 {
|
||||
private final TypePlaceholder wrap;
|
||||
@@ -136,8 +136,8 @@ public abstract class GenerateGenerics implements IGenerics {
|
||||
Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes = new HashMap<>();
|
||||
Map<TypePlaceholder, TypePlaceholder> equality = new HashMap<>();
|
||||
|
||||
GenerateGenerics(JavaTXCompiler compiler, ResultSet constraints) {
|
||||
this.compiler = compiler;
|
||||
GenerateGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) {
|
||||
this.astToTargetAST = astToTargetAST;
|
||||
for (var constraint : constraints.results) {
|
||||
if (constraint instanceof PairTPHsmallerTPH p) {
|
||||
Target.logger.info(p.left + " " + p.left.getVariance());
|
||||
@@ -153,12 +153,22 @@ public abstract class GenerateGenerics implements IGenerics {
|
||||
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() {
|
||||
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) {
|
||||
var res = new HashSet<TPH>();
|
||||
for (var param : params.getFormalparalist()) {
|
||||
@@ -273,7 +283,7 @@ public abstract class GenerateGenerics implements IGenerics {
|
||||
Set<TPH> typeVariablesOfClass,
|
||||
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
|
||||
for (var typeVariable : new HashSet<>(typeVariables)) {
|
||||
@@ -321,7 +331,7 @@ public abstract class GenerateGenerics implements IGenerics {
|
||||
|
||||
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver) {
|
||||
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;
|
||||
var method2 = optMethod.get();
|
||||
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> result = new HashSet<>();
|
||||
if (familyOfMethods.containsKey(method))
|
||||
@@ -554,8 +566,7 @@ public abstract class GenerateGenerics implements IGenerics {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Pair> generics(ClassOrInterface owner, Method method) {
|
||||
Set<Pair> generics(ClassOrInterface owner, Method method) {
|
||||
if (computedGenericsOfMethods.containsKey(method)) {
|
||||
var cached = computedGenericsOfMethods.get(method);
|
||||
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 owner, Method method, Set<Pair> result, Set<TPH> referenced);
|
||||
|
||||
@Override
|
||||
public Set<Pair> generics(ClassOrInterface classOrInterface) {
|
||||
Set<Pair> generics(ClassOrInterface classOrInterface) {
|
||||
if (computedGenericsOfClasses.containsKey(classOrInterface))
|
||||
return computedGenericsOfClasses.get(classOrInterface);
|
||||
|
||||
@@ -757,7 +766,7 @@ public abstract class GenerateGenerics implements IGenerics {
|
||||
}
|
||||
|
||||
for (var pair : elementsToAddToEquality) {
|
||||
//System.out.println(pair);
|
||||
Target.logger.info(pair);
|
||||
addToEquality(pair.left, pair.right, referenced);
|
||||
}
|
||||
}
|
||||
@@ -910,7 +919,7 @@ public abstract class GenerateGenerics implements IGenerics {
|
||||
}
|
||||
}
|
||||
if (infima.size() > 1) {
|
||||
//System.out.println(infima);
|
||||
Target.logger.info(infima);
|
||||
for (var pair : infima) {
|
||||
var returnTypes = findTypeVariables(method.getReturnType());
|
||||
var chain = findConnectionToReturnType(returnTypes, input, new HashSet<>(), pair.left);
|
||||
@@ -981,13 +990,7 @@ public abstract class GenerateGenerics implements IGenerics {
|
||||
} while (foundInfima);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypePlaceholder getEqualType(TypePlaceholder tph) {
|
||||
return this.equality.getOrDefault(tph, tph);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric getType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||
RefTypeOrTPHOrWildcardOrGeneric getType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||
if (type instanceof TypePlaceholder tph) {
|
||||
if (equality.containsKey(tph)) {
|
||||
return getType(equality.get(tph));
|
||||
@@ -997,16 +1000,15 @@ public abstract class GenerateGenerics implements IGenerics {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetType getTargetType(RefTypeOrTPHOrWildcardOrGeneric in) {
|
||||
TargetType getTargetType(RefTypeOrTPHOrWildcardOrGeneric in) {
|
||||
if (in instanceof TypePlaceholder tph) {
|
||||
if (equality.containsKey(tph)) {
|
||||
return getTargetType(equality.get(tph));
|
||||
}
|
||||
var type = concreteTypes.get(new TPH(tph));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,20 +9,21 @@ import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||
import java.util.*;
|
||||
|
||||
public class GenericsResult {
|
||||
private final IGenerics generics;
|
||||
private final GenerateGenerics generics;
|
||||
|
||||
GenericsResult(IGenerics generics) {
|
||||
GenericsResult(GenerateGenerics generics) {
|
||||
this.generics = generics;
|
||||
}
|
||||
|
||||
public GenericsResultSet get(ClassOrInterface clazz) {
|
||||
var generics = this.generics.generics(clazz);
|
||||
return new GenericsResultSet(generics, this.generics);
|
||||
var generics = this.generics.computedGenericsOfClasses.get(clazz);
|
||||
return new GenericsResultSet(generics, this.generics.equality);
|
||||
}
|
||||
|
||||
public GenericsResultSet get(ClassOrInterface clazz, Method method) {
|
||||
var generics = this.generics.generics(clazz, method);
|
||||
return new GenericsResultSet(generics, this.generics);
|
||||
// TODO Compute generics if not present?
|
||||
public GenericsResultSet get(Method method) {
|
||||
var generics = this.generics.computedGenericsOfMethods.get(method);
|
||||
return new GenericsResultSet(generics, this.generics.equality);
|
||||
}
|
||||
|
||||
public BoundsList getBounds(RefTypeOrTPHOrWildcardOrGeneric type, ClassOrInterface clazz) {
|
||||
@@ -33,7 +34,7 @@ public class GenericsResult {
|
||||
var resolvedType = resolve(type);
|
||||
type = resolvedType;
|
||||
if (type instanceof TypePlaceholder) {
|
||||
var methodGenerics = get(clazz, method);
|
||||
var methodGenerics = get(method);
|
||||
var classGenerics = get(clazz);
|
||||
List<Bound> result = new ArrayList<>();
|
||||
|
||||
@@ -68,4 +69,8 @@ public class GenericsResult {
|
||||
return this.generics.getType(tph);
|
||||
return type;
|
||||
}
|
||||
|
||||
public TargetType resolveTarget(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||
return this.generics.getTargetType(type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,18 +4,17 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.result.PairTPHequalRefTypeOrWildcardType;
|
||||
import de.dhbwstuttgart.typeinference.result.PairTPHsmallerTPH;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultPair;
|
||||
import org.antlr.v4.codegen.model.decl.ContextRuleListIndexedGetterDecl;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class GenericsResultSet extends AbstractSet<GenerateGenerics.Pair> {
|
||||
|
||||
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.generics = generics;
|
||||
this.equality = equality;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -29,7 +28,7 @@ public class GenericsResultSet extends AbstractSet<GenerateGenerics.Pair> {
|
||||
}
|
||||
|
||||
public Optional<ResultPair<?, ?>> getResultPairFor(TypePlaceholder tph) {
|
||||
var tph2 = generics.getEqualType(tph);
|
||||
var tph2 = equality.getOrDefault(tph, tph);
|
||||
return this.stream().filter(pair -> {
|
||||
return pair.left.resolve().equals(tph2);
|
||||
}).findFirst().map(pair -> {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package de.dhbwstuttgart.target.generate;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
@@ -8,8 +7,8 @@ import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import java.util.Set;
|
||||
|
||||
final class JavaGenerics extends GenerateGenerics {
|
||||
JavaGenerics(JavaTXCompiler compiler, ResultSet constraints) {
|
||||
super(compiler, constraints);
|
||||
JavaGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) {
|
||||
super(astToTargetAST, constraints);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package de.dhbwstuttgart.target.generate;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||
@@ -8,26 +7,25 @@ import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
import de.dhbwstuttgart.target.Target;
|
||||
import de.dhbwstuttgart.target.tree.MethodParameter;
|
||||
import de.dhbwstuttgart.target.tree.TargetMethod;
|
||||
import de.dhbwstuttgart.target.tree.expression.*;
|
||||
import de.dhbwstuttgart.target.tree.type.*;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.sql.Array;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
public class StatementToTargetExpression implements ASTVisitor {
|
||||
|
||||
public StatementToTargetExpression(ASTToTargetAST converter, IGenerics generics) {
|
||||
public StatementToTargetExpression(ASTToTargetAST converter) {
|
||||
this.converter = converter;
|
||||
this.generics = generics;
|
||||
}
|
||||
|
||||
public TargetExpression result;
|
||||
private final IGenerics generics;
|
||||
private final ASTToTargetAST converter;
|
||||
|
||||
@Override
|
||||
@@ -35,125 +33,105 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
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
|
||||
public void visit(LambdaExpression lambdaExpression) {
|
||||
var parameters = createParameters(lambdaExpression);
|
||||
List<MethodParameter> captures = new ArrayList<>();
|
||||
var visitor = new LambdaCaptureFinder(parameters, captures);
|
||||
lambdaExpression.methodBody.accept(visitor);
|
||||
var parameters = StreamSupport.stream(lambdaExpression.params.spliterator(), false)
|
||||
.map(p -> (FormalParameter) p)
|
||||
.map(p -> new MethodParameter(new TargetTypePattern(converter.convert(p.getType()), p.getName())))
|
||||
.toList();
|
||||
|
||||
TargetMethod.Signature signature = new TargetMethod.Signature(Set.of(), parameters, converter.convert(lambdaExpression.getReturnType(), generics));;
|
||||
var tpe = converter.convert(lambdaExpression.getType(), generics);
|
||||
result = new TargetLambdaExpression(tpe, captures, signature, converter.convert(lambdaExpression.methodBody, this.generics));
|
||||
List<MethodParameter> captures = new ArrayList<>();
|
||||
lambdaExpression.methodBody.accept(new TracingStatementVisitor() {
|
||||
// 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
|
||||
public void visit(Assign assign) {
|
||||
TargetExpression left;
|
||||
if (assign.lefSide instanceof AssignToLocal) {
|
||||
left = converter.convert(((AssignToLocal) assign.lefSide).localVar, this.generics);
|
||||
left = converter.convert(((AssignToLocal) assign.lefSide).localVar);
|
||||
} 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
|
||||
public void visit(BinaryExpr binary) {
|
||||
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 SUB -> new TargetBinaryOp.Sub(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(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||
case MOD -> new TargetBinaryOp.Rem(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(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||
case OR -> new TargetBinaryOp.BOr(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(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||
case DIV -> new TargetBinaryOp.Div(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(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||
case BIGGERTHAN -> new TargetBinaryOp.Greater(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(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||
case BIGGEREQUAL -> new TargetBinaryOp.GreaterOrEqual(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(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||
case NOTEQUAL -> new TargetBinaryOp.NotEqual(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()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
||||
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()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
||||
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()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
||||
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()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
||||
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()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
||||
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()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
||||
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()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(BoolExpression bool) {
|
||||
result = switch(bool.operation) {
|
||||
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));
|
||||
};
|
||||
Target.logger.info("BoolExpression");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Block block) {
|
||||
result = converter.convert(block, generics);
|
||||
result = converter.convert(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
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
|
||||
@@ -164,46 +142,46 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
@Override
|
||||
public void visit(FieldVar fieldVar) {
|
||||
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 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
|
||||
public void visit(ForStmt forStmt) {
|
||||
result = new TargetFor(
|
||||
forStmt.initializer.stream().map(c -> converter.convert(c, generics)).toList(),
|
||||
forStmt.condition != null ? converter.convert(forStmt.condition, generics) : null,
|
||||
forStmt.loopExpr.stream().map(e -> converter.convert(e, generics)).toList(),
|
||||
converter.convertWrapInBlock(forStmt.block, generics)
|
||||
forStmt.initializer.stream().map(converter::convert).toList(),
|
||||
forStmt.condition != null ? converter.convert(forStmt.condition) : null,
|
||||
forStmt.loopExpr.stream().map(converter::convert).toList(),
|
||||
converter.convertWrapInBlock(forStmt.block)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
public void visit(LocalVarDecl localVarDecl) {
|
||||
// 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) {
|
||||
@@ -212,25 +190,25 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
return to.equals(from);
|
||||
}
|
||||
|
||||
Optional<Method> findMethod(JavaClassName className, String name, List<TargetType> args, IGenerics generics, JavaTXCompiler compiler) {
|
||||
return ASTToTargetAST.findMethod(converter.compiler.getClass(className), name, args, generics, compiler);
|
||||
Optional<Method> findMethod(JavaClassName className, String name, List<TargetType> args) {
|
||||
return converter.findMethod(converter.compiler.getClass(className), name, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
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 returnType = isFunNType ? TargetType.Object : converter.convert(methodCall.signature.getLast(), generics);
|
||||
var receiverName = new JavaClassName(converter.convert(methodCall.receiver.getType(), generics).name());
|
||||
var argList = methodCall.signature.stream().map(sig -> converter.convert(sig, generics)).toList();
|
||||
var returnType = isFunNType ? TargetType.Object : converter.convert(methodCall.signature.get(methodCall.signature.size() - 1));
|
||||
var receiverName = new JavaClassName(converter.convert(methodCall.receiver.getType()).name());
|
||||
var argList = methodCall.signature.stream().map(converter::convert).toList();
|
||||
argList = argList.subList(0, argList.size() - 1);
|
||||
|
||||
Method foundMethod = null;
|
||||
var isStatic = false;
|
||||
var isInterface = true;
|
||||
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
|
||||
for (var i = 0; i < methodCall.signatureArguments().size(); i++) {
|
||||
@@ -240,38 +218,49 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
var receiverClass = converter.compiler.getClass(receiverName);
|
||||
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver && expressionReceiver.expr instanceof This) {
|
||||
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;
|
||||
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) {
|
||||
receiverClass = converter.compiler.getClass(receiverName);
|
||||
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) {
|
||||
returnType = converter.convert(foundMethod.getReturnType(), generics);
|
||||
argList = foundMethod.getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType(), generics)).toList();
|
||||
returnType = converter.convert(foundMethod.getReturnType());
|
||||
argList = foundMethod.getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType())).toList();
|
||||
isStatic = Modifier.isStatic(foundMethod.modifier);
|
||||
isPrivate = Modifier.isPrivate(foundMethod.modifier);
|
||||
isInterface = receiverClass.isInterface();
|
||||
}
|
||||
|
||||
//System.out.println(argList);
|
||||
result = new TargetMethodCall(
|
||||
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
|
||||
);
|
||||
Target.logger.info(argList);
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(NewClass newClass) {
|
||||
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 signature = ctor.orElseThrow().getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType(), generics)).toList();
|
||||
result = new TargetNew(new TargetRefType(newClass.name), signature, newClass.getArgumentList().getArguments().stream().map(arg -> converter.convert(arg, generics)).toList());
|
||||
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())).toList();
|
||||
result = new TargetNew(new TargetRefType(newClass.name), signature, newClass.getArgumentList().getArguments().stream().map(converter::convert).toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -282,7 +271,7 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(Return aReturn) {
|
||||
result = new TargetReturn(converter.convert(aReturn.retexpr, generics));
|
||||
result = new TargetReturn(converter.convert(aReturn.retexpr));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -302,53 +291,53 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(StaticClassName staticClassName) {
|
||||
result = new TargetClassName(converter.convert(staticClassName.getType(), generics));
|
||||
result = new TargetClassName(converter.convert(staticClassName.getType()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Super aSuper) {
|
||||
result = new TargetSuper(converter.convert(aSuper.getType(), generics));
|
||||
result = new TargetSuper(converter.convert(aSuper.getType()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(This aThis) {
|
||||
result = new TargetThis(converter.convert(aThis.getType(), generics));
|
||||
result = new TargetThis(converter.convert(aThis.getType()));
|
||||
}
|
||||
|
||||
@Override
|
||||
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
|
||||
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
|
||||
@Override
|
||||
public void visit(AssignToField assignLeftSide) {
|
||||
result = converter.convert(assignLeftSide.field, generics);
|
||||
result = converter.convert(assignLeftSide.field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(AssignToLocal assignLeftSide) {
|
||||
result = converter.convert(assignLeftSide.localVar, generics);
|
||||
result = converter.convert(assignLeftSide.localVar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(SuperCall superCall) {
|
||||
var aSuper = converter.convert(superCall.receiver.getType(), generics);
|
||||
var type = converter.convert(superCall.getType(), generics);
|
||||
var receiverName = new JavaClassName(converter.convert(superCall.receiver.getType(), generics).name());
|
||||
var aSuper = converter.convert(superCall.receiver.getType());
|
||||
var type = converter.convert(superCall.getType());
|
||||
var receiverName = new JavaClassName(converter.convert(superCall.receiver.getType()).name());
|
||||
var clazz = converter.compiler.getClass(receiverName);
|
||||
var signature = superCall.signatureArguments().stream().map(arg -> converter.convert(arg, generics)).toList();
|
||||
var method = converter.findConstructor(clazz, signature, generics);
|
||||
var params = superCall.getArgumentList().getArguments().stream().map(arg -> converter.convert(arg, generics)).toList();
|
||||
var signature = superCall.signatureArguments().stream().map(converter::convert).toList();
|
||||
var method = converter.findConstructor(clazz, signature);
|
||||
var params = superCall.getArgumentList().getArguments().stream().map(converter::convert).toList();
|
||||
|
||||
List<TargetType> argList;
|
||||
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 {
|
||||
argList = params.stream().map(TargetExpression::type).toList();
|
||||
}
|
||||
@@ -358,28 +347,28 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(ThisCall thisCall) {
|
||||
var aThis = converter.convert(thisCall.receiver.getType(), generics);
|
||||
var type = converter.convert(thisCall.getType(), generics);
|
||||
var parameters = thisCall.arglist.getArguments().stream().map(par -> converter.convert(par.getType(), generics)).toList();
|
||||
var aThis = converter.convert(thisCall.receiver.getType());
|
||||
var type = converter.convert(thisCall.getType());
|
||||
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
|
||||
public void visit(ExpressionReceiver expressionReceiver) {
|
||||
result = converter.convert(expressionReceiver.expr, generics);
|
||||
result = converter.convert(expressionReceiver.expr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(UnaryExpr unaryExpr) {
|
||||
result = switch (unaryExpr.operation) {
|
||||
case NOT -> new TargetUnaryOp.Not(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics));
|
||||
case MINUS -> new TargetUnaryOp.Negate(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics));
|
||||
case PREINCREMENT -> new TargetUnaryOp.PreIncrement(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics));
|
||||
case PREDECREMENT -> new TargetUnaryOp.PreDecrement(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics));
|
||||
case POSTINCREMENT -> new TargetUnaryOp.PostIncrement(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics));
|
||||
case PLUS -> new TargetUnaryOp.Add(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics));
|
||||
case POSTDECREMENT -> new TargetUnaryOp.PostDecrement(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()), converter.convert(unaryExpr.expr));
|
||||
case PREINCREMENT -> new TargetUnaryOp.PreIncrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
|
||||
case PREDECREMENT -> new TargetUnaryOp.PreDecrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
|
||||
case POSTINCREMENT -> new TargetUnaryOp.PostIncrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
|
||||
case PLUS -> new TargetUnaryOp.Add(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
|
||||
case POSTDECREMENT -> new TargetUnaryOp.PostDecrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -407,12 +396,12 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(Throw aThrow) {
|
||||
result = new TargetThrow(converter.convert(aThrow.expr, generics));
|
||||
result = new TargetThrow(converter.convert(aThrow.expr));
|
||||
}
|
||||
|
||||
@Override
|
||||
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) {}
|
||||
@@ -476,8 +465,10 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
var product = cartesianProduct(extractAllPatterns(label.getPattern()));
|
||||
|
||||
for (var l : product) {
|
||||
var oldGenerics = converter.generics;
|
||||
|
||||
// Set the generics to matching result set
|
||||
/*for (var generics : converter.currentMethodOverloads) {
|
||||
for (var generics : converter.currentMethodOverloads) {
|
||||
var java = generics.javaGenerics();
|
||||
var equals = true;
|
||||
for (var pair : l) {
|
||||
@@ -486,15 +477,17 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
}
|
||||
}
|
||||
if (equals) {
|
||||
converter.generics = generics;
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
overloads.add(converter.convert(case_, generics));
|
||||
overloads.add(converter.convert(case_));
|
||||
converter.generics = oldGenerics;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
overloads.add(converter.convert(case_, generics));
|
||||
overloads.add(converter.convert(case_));
|
||||
}
|
||||
|
||||
return overloads;
|
||||
@@ -503,10 +496,10 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
TargetSwitch.Case default_ = null;
|
||||
for (var block : switchStmt.getBlocks()) {
|
||||
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
|
||||
@@ -514,12 +507,12 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(SwitchLabel switchLabel) {
|
||||
result = converter.convert(switchLabel.getPattern(), this.generics);
|
||||
result = converter.convert(switchLabel.getPattern());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Yield aYield) {
|
||||
result = new TargetYield(converter.convert(aYield.retexpr, generics));
|
||||
result = new TargetYield(converter.convert(aYield.retexpr));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -589,30 +582,30 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
|
||||
@Override
|
||||
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
|
||||
public void visit(LiteralPattern literalPattern) {
|
||||
result = new TargetExpressionPattern(converter.convert(literalPattern.value, generics));
|
||||
result = new TargetExpressionPattern(converter.convert(literalPattern.value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ExpressionPattern aPattern) {
|
||||
result = converter.convert(aPattern.getExpression(), generics);
|
||||
result = converter.convert(aPattern.getExpression());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RecordPattern aRecordPattern) {
|
||||
result = new TargetComplexPattern(
|
||||
converter.convert(aRecordPattern.getType(), generics),
|
||||
converter.convert(aRecordPattern.getType()),
|
||||
aRecordPattern.getName(),
|
||||
aRecordPattern.getSubPattern().stream().map(x -> (TargetPattern) converter.convert(x, generics)).toList()
|
||||
aRecordPattern.getSubPattern().stream().map(x -> (TargetPattern) converter.convert(x)).toList()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package de.dhbwstuttgart.target.generate;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
@@ -8,8 +7,8 @@ import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import java.util.Set;
|
||||
|
||||
final class TxGenerics extends GenerateGenerics {
|
||||
TxGenerics(JavaTXCompiler compiler, ResultSet constraints) {
|
||||
super(compiler, constraints);
|
||||
TxGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) {
|
||||
super(astToTargetAST, constraints);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,9 +15,4 @@ public record MethodParameter(TargetPattern pattern) {
|
||||
public MethodParameter withName(String name) {
|
||||
return new MethodParameter(pattern.withName(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return pattern.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,30 +36,30 @@ public record TargetMethod(int access, String name, TargetBlock block, Signature
|
||||
public static String getDescriptor(TargetType returnType, TargetType... parameters) {
|
||||
String ret = "(";
|
||||
for (var parameterType : parameters) {
|
||||
ret += parameterType.toDescriptor();
|
||||
ret += parameterType.toSignature();
|
||||
}
|
||||
ret += ")";
|
||||
if (returnType == null) ret += "V";
|
||||
else ret += returnType.toDescriptor();
|
||||
else ret += returnType.toSignature();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static String getSignature(Set<TargetGeneric> generics, List<MethodParameter> parameters, TargetType returnType) {
|
||||
String ret = "";
|
||||
if (!generics.isEmpty()) {
|
||||
if (generics.size() > 0) {
|
||||
ret += "<";
|
||||
for (var generic : generics) {
|
||||
ret += generic.name() + ":" + generic.bound().toSignature();
|
||||
ret += generic.name() + ":" + generic.bound().toDescriptor();
|
||||
}
|
||||
ret += ">";
|
||||
}
|
||||
ret += "(";
|
||||
for (var param : parameters) {
|
||||
ret += param.pattern().type().toSignature();
|
||||
ret += param.pattern().type().toDescriptor();
|
||||
}
|
||||
ret += ")";
|
||||
if (returnType == null) ret += "V";
|
||||
else ret += returnType.toSignature();
|
||||
else ret += returnType.toDescriptor();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,9 +14,4 @@ public record TargetComplexPattern(TargetType type, String name, List<TargetPatt
|
||||
public TargetComplexPattern withName(String name) {
|
||||
return new TargetComplexPattern(type, name, subPatterns);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return type + "(" + String.join(", ", subPatterns.stream().map(Object::toString).toList()) + ") " + name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,42 +8,42 @@ public sealed interface TargetLiteral extends TargetExpression {
|
||||
record BooleanLiteral(Boolean value) implements TargetLiteral {
|
||||
@Override
|
||||
public TargetType type() {
|
||||
return TargetType.boolean_;
|
||||
return TargetType.Boolean;
|
||||
}
|
||||
}
|
||||
|
||||
record CharLiteral(Character value) implements TargetLiteral {
|
||||
@Override
|
||||
public TargetType type() {
|
||||
return TargetType.char_;
|
||||
return TargetType.Char;
|
||||
}
|
||||
}
|
||||
|
||||
record IntLiteral(Integer value) implements TargetLiteral {
|
||||
@Override
|
||||
public TargetType type() {
|
||||
return TargetType.int_;
|
||||
return TargetType.Integer;
|
||||
}
|
||||
}
|
||||
|
||||
record LongLiteral(Long value) implements TargetLiteral {
|
||||
@Override
|
||||
public TargetType type() {
|
||||
return TargetType.long_;
|
||||
return TargetType.Long;
|
||||
}
|
||||
}
|
||||
|
||||
record FloatLiteral(Float value) implements TargetLiteral {
|
||||
@Override
|
||||
public TargetType type() {
|
||||
return TargetType.float_;
|
||||
return TargetType.Float;
|
||||
}
|
||||
}
|
||||
|
||||
record DoubleLiteral(Double value) implements TargetLiteral {
|
||||
@Override
|
||||
public TargetType type() {
|
||||
return TargetType.double_;
|
||||
return TargetType.Double;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,4 @@ public record TargetTypePattern(TargetType type, String name) implements TargetP
|
||||
public TargetTypePattern withName(String name) {
|
||||
return new TargetTypePattern(type, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return type + " " + name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ package de.dhbwstuttgart.target.tree.type;
|
||||
public record TargetExtendsWildcard(TargetType innerType) implements TargetType {
|
||||
@Override
|
||||
public String toSignature() {
|
||||
return "+" + innerType.toSignature();
|
||||
return innerType.toSignature();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toDescriptor() {
|
||||
return innerType.toDescriptor();
|
||||
return "+" + innerType.toDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -20,10 +20,5 @@ public record TargetExtendsWildcard(TargetType innerType) implements TargetType
|
||||
public String name() {
|
||||
return innerType.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "? extends " + innerType;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ public record TargetFunNType(String name, List<TargetType> funNParams, List<Targ
|
||||
|
||||
@Override
|
||||
public String toSignature() {
|
||||
var args = FunNGenerator.getArguments(funNParams);
|
||||
return "LFun" + args.size() + "$$" + TargetSpecializedType.signatureParameters(funNParams) + ";";
|
||||
return "L" + getInternalName() + ";";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@ package de.dhbwstuttgart.target.tree.type;
|
||||
|
||||
public record TargetGenericType(String name) implements TargetType {
|
||||
@Override
|
||||
public String toDescriptor() {
|
||||
public String toSignature() {
|
||||
return "Ljava/lang/Object;"; // TODO Use bounds for this?
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toSignature() {
|
||||
public String toDescriptor() {
|
||||
return "T" + getInternalName() + ";";
|
||||
}
|
||||
|
||||
@@ -15,9 +15,4 @@ public record TargetGenericType(String name) implements TargetType {
|
||||
public String getInternalName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "'" + name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,11 @@ public record TargetRefType(String name, List<TargetType> params) implements Tar
|
||||
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
|
||||
@Override
|
||||
public int hashCode() {
|
||||
@@ -25,10 +30,4 @@ public record TargetRefType(String name, List<TargetType> params) implements Tar
|
||||
}
|
||||
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()) + ">";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,27 +6,16 @@ public sealed interface TargetSpecializedType extends TargetType permits TargetF
|
||||
List<TargetType> params();
|
||||
|
||||
@Override
|
||||
default String toSignature() {
|
||||
default String toDescriptor() {
|
||||
String ret = "L" + getInternalName();
|
||||
ret += signatureParameters(params());
|
||||
ret += ";";
|
||||
return ret;
|
||||
}
|
||||
|
||||
static String signatureParameters(List<TargetType> params) {
|
||||
var ret = "";
|
||||
if (!params.isEmpty()) {
|
||||
if (params().size() > 0) {
|
||||
ret += "<";
|
||||
for (var param : params) {
|
||||
ret += param.toSignature();
|
||||
for (var param : params()) {
|
||||
ret += param.toDescriptor();
|
||||
}
|
||||
ret += ">";
|
||||
}
|
||||
ret += ";";
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
default String toDescriptor() {
|
||||
return "L" + getInternalName() + ";";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ package de.dhbwstuttgart.target.tree.type;
|
||||
public record TargetSuperWildcard(TargetType innerType) implements TargetType {
|
||||
@Override
|
||||
public String toSignature() {
|
||||
return "-" + innerType.toSignature();
|
||||
return innerType.toSignature();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toDescriptor() {
|
||||
return innerType.toDescriptor();
|
||||
return "-" + innerType.toDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -20,11 +20,6 @@ public record TargetSuperWildcard(TargetType innerType) implements TargetType {
|
||||
public String name() {
|
||||
return innerType.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "? super " + innerType;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ class TypeInsertPlacerClass extends AbstractASTWalker{
|
||||
@Override
|
||||
public void visit(Method method) {
|
||||
this.method = method;
|
||||
constraints = generatedGenerics.get(cl, method);
|
||||
constraints = generatedGenerics.get(method);
|
||||
classConstraints = generatedGenerics.get(cl);
|
||||
if(method.getReturnType() instanceof TypePlaceholder)
|
||||
inserts.add(TypeInsertFactory.createInsertPoints(
|
||||
|
||||
@@ -9,72 +9,77 @@ import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialUUID;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class Constraint<A extends IConstraintElement> extends HashSet<A> implements Comparable<Constraint<A>>, ISerializableData {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private boolean isInherited = false;//wird beides nur für die Method-Constraints benoetigt
|
||||
private boolean isImplemented = false;
|
||||
|
||||
/*
|
||||
* wird verwendet um bei der Codegenerierung die richtige Methoden - Signatur
|
||||
* auszuwaehlen
|
||||
*/
|
||||
/*private*/ Set<A> methodSignatureConstraint = new HashSet<>();
|
||||
|
||||
private Constraint<A> extendConstraint = null;
|
||||
|
||||
public Constraint() {
|
||||
super();
|
||||
}
|
||||
public class Constraint<A extends IConstraintElement> extends HashSet<A> implements ISerializableData {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private boolean isInherited = false;//wird beides nur für die Method-Constraints benoetigt
|
||||
private boolean isImplemented = false;
|
||||
|
||||
/*
|
||||
* wird verwendet um bei der Codegenerierung die richtige Methoden - Signatur
|
||||
* auszuwaehlen
|
||||
*/
|
||||
/*private*/ Set<A> methodSignatureConstraint = new HashSet<>();
|
||||
|
||||
private Constraint<A> extendConstraint = null;
|
||||
|
||||
public Constraint() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Constraint(int initialCapacity) {
|
||||
super(initialCapacity);
|
||||
}
|
||||
|
||||
public Constraint(boolean isInherited, boolean isImplemented) {
|
||||
this.isInherited = isInherited;
|
||||
this.isImplemented = isImplemented;
|
||||
}
|
||||
|
||||
public Constraint(boolean isInherited, boolean isImplemented, Constraint<A> extendConstraint, Set<A> methodSignatureConstraint) {
|
||||
this.isInherited = isInherited;
|
||||
this.isImplemented = isImplemented;
|
||||
this.extendConstraint = extendConstraint;
|
||||
this.methodSignatureConstraint = methodSignatureConstraint;
|
||||
}
|
||||
|
||||
public void setIsInherited(boolean isInherited) {
|
||||
this.isInherited = isInherited;
|
||||
}
|
||||
|
||||
public boolean isInherited() {
|
||||
return isInherited;
|
||||
}
|
||||
|
||||
public boolean isImplemented() {
|
||||
return isImplemented;
|
||||
}
|
||||
|
||||
public Constraint<A> getExtendConstraint() {
|
||||
return extendConstraint;
|
||||
}
|
||||
|
||||
public void setExtendConstraint(Constraint<A> c) {
|
||||
extendConstraint = c;
|
||||
}
|
||||
|
||||
public Set<A> getmethodSignatureConstraint() {
|
||||
return methodSignatureConstraint;
|
||||
}
|
||||
|
||||
public void setmethodSignatureConstraint(Set<A> c) {
|
||||
methodSignatureConstraint = c;
|
||||
}
|
||||
public Constraint(boolean isInherited, boolean isImplemented) {
|
||||
this.isInherited = isInherited;
|
||||
this.isImplemented = isImplemented;
|
||||
}
|
||||
|
||||
public Constraint(boolean isInherited, boolean isImplemented, Constraint<A> extendConstraint, Set<A> methodSignatureConstraint) {
|
||||
this.isInherited = isInherited;
|
||||
this.isImplemented = isImplemented;
|
||||
this.extendConstraint = extendConstraint;
|
||||
this.methodSignatureConstraint = methodSignatureConstraint;
|
||||
}
|
||||
|
||||
public void setIsInherited(boolean isInherited) {
|
||||
this.isInherited = isInherited;
|
||||
}
|
||||
|
||||
public boolean isInherited() {
|
||||
return isInherited;
|
||||
}
|
||||
|
||||
public boolean isImplemented() {
|
||||
return isImplemented;
|
||||
}
|
||||
|
||||
public Constraint<A> getExtendConstraint() {
|
||||
return extendConstraint;
|
||||
}
|
||||
|
||||
public void setExtendConstraint(Constraint<A> c) {
|
||||
extendConstraint = c;
|
||||
}
|
||||
|
||||
public Set<A> getmethodSignatureConstraint() {
|
||||
return methodSignatureConstraint;
|
||||
}
|
||||
|
||||
public void setmethodSignatureConstraint(Set<A> c) {
|
||||
methodSignatureConstraint = c;
|
||||
}
|
||||
|
||||
public <B extends IConstraintElement> Constraint<B> createdMapped(Function<A,B> mapper) {
|
||||
Constraint<B> result = new Constraint<>(this.size());
|
||||
@@ -84,22 +89,16 @@ public class Constraint<A extends IConstraintElement> extends HashSet<A> impleme
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int compareTo(Constraint<A> o) {
|
||||
return this.toString().compareTo(o.toString());
|
||||
public String toStringBase() {
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
private String serialUUID = null;
|
||||
@@ -168,4 +167,5 @@ public class Constraint<A extends IConstraintElement> extends HashSet<A> impleme
|
||||
|
||||
return keyStorage.getUnserialized(uuid, Constraint.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
* Paare, welche das Unifikationsergebnis darstellen
|
||||
*/
|
||||
public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B extends RefTypeOrTPHOrWildcardOrGeneric>
|
||||
implements Comparable<ResultPair<A,B>>, ISerializableData {
|
||||
implements ISerializableData {
|
||||
private final A left;
|
||||
private final B right;
|
||||
|
||||
@@ -65,16 +65,6 @@ public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B ext
|
||||
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
|
||||
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||
|
||||
@@ -11,7 +11,6 @@ import de.dhbwstuttgart.util.Logger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
@@ -24,32 +23,28 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class ResultSet implements Comparable<ResultSet>, ISerializableData {
|
||||
public class ResultSet implements ISerializableData {
|
||||
|
||||
public final Set<ResultPair> results;
|
||||
public Set<ResultPair<TypePlaceholder, TypePlaceholder>> genIns;
|
||||
|
||||
public ResultSet(Set<ResultPair> set){
|
||||
this.results = set;
|
||||
this.genIns = TypeUnifyTaskHelper.getPresizedHashSet(results.size());
|
||||
results.forEach(x -> {
|
||||
if (x instanceof PairTPHsmallerTPH) {
|
||||
this.genIns.add(x);
|
||||
}
|
||||
});
|
||||
}
|
||||
public ResultSet(Set<ResultPair> set) {
|
||||
this.results = set;
|
||||
this.genIns = TypeUnifyTaskHelper.getPresizedHashSet(results.size());
|
||||
results.forEach(x -> {
|
||||
if (x instanceof PairTPHsmallerTPH) {
|
||||
this.genIns.add(x);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<ResultPair> getSortedResults() {
|
||||
return results.stream().sorted().toList();
|
||||
}
|
||||
public boolean contains(ResultPair toCheck) {
|
||||
return this.results.contains(toCheck);
|
||||
}
|
||||
|
||||
public boolean contains(ResultPair toCheck) {
|
||||
return this.results.contains(toCheck);
|
||||
}
|
||||
|
||||
public void remove(ResultPair toCheck) {
|
||||
results.remove(toCheck);
|
||||
}
|
||||
public void remove(ResultPair toCheck) {
|
||||
results.remove(toCheck);
|
||||
}
|
||||
|
||||
public ResolvedType resolveType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||
if (type instanceof TypePlaceholder)
|
||||
@@ -92,24 +87,9 @@ public class ResultSet implements Comparable<ResultSet>, ISerializableData {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return results.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ResultSet o) {
|
||||
List<ResultPair> thisSorted = this.getSortedResults();
|
||||
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;
|
||||
public int hashCode() {
|
||||
return results.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package de.dhbwstuttgart.typeinference.typeAlgo;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.SourceLoc;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
||||
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.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.target.tree.type.TargetRefType;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTaskHelper;
|
||||
@@ -22,24 +19,24 @@ import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||
import de.dhbwstuttgart.util.BiRelation;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
|
||||
public class TYPE {
|
||||
|
||||
private final SourceFile sf;
|
||||
private final Set<ClassOrInterface> allAvailableClasses;
|
||||
private final Set<ClassOrInterface> definedClasses;
|
||||
|
||||
public TYPE(Set<ClassOrInterface> definedClasses, Set<ClassOrInterface> allAvailableClasses){
|
||||
|
||||
public TYPE(SourceFile sf, Set<ClassOrInterface> allAvailableClasses){
|
||||
this.sf = sf;
|
||||
this.allAvailableClasses = allAvailableClasses;
|
||||
this.definedClasses = definedClasses;
|
||||
}
|
||||
|
||||
public ConstraintSet getConstraints() {
|
||||
ConstraintSet ret = new ConstraintSet();
|
||||
for (ClassOrInterface cl : definedClasses) {
|
||||
Set<ClassOrInterface> allClasses = TypeUnifyTaskHelper.getPresizedHashSet(allAvailableClasses.size());
|
||||
for (ClassOrInterface cl : sf.KlassenVektor) {
|
||||
Set<ClassOrInterface> allClasses = TypeUnifyTaskHelper.getPresizedHashSet(allAvailableClasses.size() + sf.availableClasses.size());
|
||||
allClasses.addAll(allAvailableClasses);
|
||||
allClasses.addAll(sf.availableClasses);
|
||||
ret.addAll(getConstraintsClass(cl, new TypeInferenceInformation(allClasses)));
|
||||
}
|
||||
return ret;
|
||||
@@ -91,25 +88,12 @@ public class TYPE {
|
||||
TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m);
|
||||
TYPEStmt methodScope = new TYPEStmt(blockInfo);
|
||||
ConstraintSet constraintSet = new ConstraintSet();
|
||||
m.getParameterList().getFormalparalist().forEach(el -> {
|
||||
if(el instanceof RecordPattern){
|
||||
constraintSet.addAll(addRecursiveParameterConstraints((RecordPattern) el, blockInfo));
|
||||
|
||||
if (m.name.equals("main") && Modifier.isStatic(m.modifier) && m.getParameterList().getFormalparalist().size() == 1) {
|
||||
// Add constraint for main method
|
||||
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);
|
||||
constraintSet.addAll(methodScope.getConstraints());
|
||||
return constraintSet;
|
||||
|
||||
@@ -75,7 +75,7 @@ public class TYPEStmt implements StatementVisitor {
|
||||
|
||||
@Override
|
||||
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());
|
||||
lambdaParams.add(tphRetType);
|
||||
// lambdaParams.add(0,tphRetType);
|
||||
@@ -643,7 +643,6 @@ public class TYPEStmt implements StatementVisitor {
|
||||
params.add(resolver.resolve(new GenericRefType(gtv.getName(), new NullToken())));
|
||||
}
|
||||
RefTypeOrTPHOrWildcardOrGeneric receiverType;
|
||||
|
||||
if (receiver instanceof FunNClass) {
|
||||
receiverType = new RefType(new JavaClassName(receiver.getClassName().toString() + "$$"), params, new NullToken()); // new FunN(params);
|
||||
} else {
|
||||
@@ -939,7 +938,7 @@ public class TYPEStmt implements StatementVisitor {
|
||||
@Override
|
||||
public void visit(Yield aYield) {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
//PL 2018-12-19: Merge checken
|
||||
package de.dhbwstuttgart.typeinference.unify;
|
||||
|
||||
import de.dhbwstuttgart.core.ConsoleInterface;
|
||||
import de.dhbwstuttgart.exceptions.TypeinferenceException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.server.ServerTaskLogger;
|
||||
@@ -150,7 +149,7 @@ public class TypeUnifyTask extends CancellableTask<CompletableFuture<Set<Set<Uni
|
||||
this.fc = fc;
|
||||
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(
|
||||
System.getProperty("user.dir") + "/logFiles/" + "Thread",
|
||||
"Unify"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package de.dhbwstuttgart.typeinference.unify.cartesianproduct;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.UnifyCancelException;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
||||
import de.dhbwstuttgart.typeinference.unify.TypeUnify2Task;
|
||||
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||
@@ -13,12 +15,15 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class UnknownVarianceCase extends VarianceCase {
|
||||
|
||||
protected final int variance = 0;
|
||||
|
||||
protected final AtomicBoolean shouldBreak = new AtomicBoolean(false);
|
||||
|
||||
protected UnknownVarianceCase(boolean isOderConstraint, TypeUnifyTask typeUnifyTask, UnifyContext context) {
|
||||
super(isOderConstraint, typeUnifyTask, context);
|
||||
}
|
||||
@@ -46,6 +51,28 @@ public class UnknownVarianceCase extends VarianceCase {
|
||||
} else {
|
||||
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
|
||||
@@ -61,9 +88,98 @@ public class UnknownVarianceCase extends VarianceCase {
|
||||
Set<Set<UnifyPair>> result,
|
||||
Set<Set<UnifyPair>> aParDef
|
||||
) {
|
||||
elems.add(a);
|
||||
return typeUnifyTask.unify2(elems, eq, oderConstraints, fc, context.parallel(), rekTiefe, new HashSet<>(methodSignatureConstraint))
|
||||
.thenApply(ComputationResults::new);
|
||||
Set<UnifyPair> newEqOrig = new HashSet<>(eq);
|
||||
Set<Set<UnifyPair>> newElemsOrig = new HashSet<>(elems);
|
||||
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
|
||||
@@ -100,10 +216,25 @@ public class UnknownVarianceCase extends VarianceCase {
|
||||
nextSetAsList.removeAll(erased);
|
||||
|
||||
context.logger().debug("Removed: " + erased);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -53,7 +53,7 @@ class Node<T> {
|
||||
addDescendant(descendant);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a directed edge from the predecessor to this node (predecessor -> this)
|
||||
*/
|
||||
@@ -73,7 +73,7 @@ class Node<T> {
|
||||
addPredecessor(predecessor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The content of this node.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
* abstract the logLevel away from the parameters
|
||||
@@ -136,6 +150,8 @@ public class Logger {
|
||||
*/
|
||||
public void log(String s, LogLevel logLevel) {
|
||||
if (isLogLevelActive(logLevel)) {
|
||||
// prepend the call to the logger instance
|
||||
// s = findLogCaller() + "\n" + s;
|
||||
this.print(s, logLevel);
|
||||
this.write(s);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static targetast.TestCodegen.generateClassFiles;
|
||||
|
||||
import java.io.File;
|
||||
@@ -9,12 +9,13 @@ import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
|
||||
public class AllgemeinTest {
|
||||
|
||||
@@ -77,7 +78,7 @@ public class AllgemeinTest {
|
||||
compiler = new JavaTXCompiler(
|
||||
Lists.newArrayList(new File(path)),
|
||||
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();
|
||||
pathToClassFile = System.getProperty("user.dir")+"/resources/bytecode/classFiles/";
|
||||
|
||||
@@ -6,12 +6,12 @@ import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class GenericsParserTest {
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,6 @@
|
||||
import de.dhbwstuttgart.core.ConsoleInterface;
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
@@ -14,25 +13,26 @@ public class TestPackages {
|
||||
public void testPackages() throws Exception {
|
||||
var cmp = new JavaTXCompiler(
|
||||
List.of(
|
||||
new File("resources/packageTest/pkg/sub/Test1.jav"),
|
||||
new File("resources/packageTest/pkg/sub2/Test2.jav")
|
||||
new File("resources/packageTest/pkg/sub/Test1.jav") // This should pull in Test2
|
||||
//new File("resources/packageTest/pkg/sub2/Test2.jav")
|
||||
),
|
||||
List.of(new File("resources/packageTest")),
|
||||
new File(bytecodeDirectory), true
|
||||
new File(bytecodeDirectory)
|
||||
);
|
||||
|
||||
cmp.generateBytecode();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("This doesn't work")
|
||||
public void testPackagesCircular() throws Exception {
|
||||
var cmp = new JavaTXCompiler(
|
||||
List.of(
|
||||
new File("resources/packageTest/pkg/sub/Cycle1.jav"),
|
||||
new File("resources/packageTest/pkg/sub2/Cycle2.jav")
|
||||
new File("resources/packageTest/pkg/sub/Cycle1.jav")
|
||||
//new File("resources/packageTest/pkg/sub2/Cycle2.jav")
|
||||
),
|
||||
List.of(new File("resources/packageTest")),
|
||||
new File(bytecodeDirectory), true
|
||||
new File(bytecodeDirectory)
|
||||
);
|
||||
|
||||
cmp.generateBytecode();
|
||||
@@ -43,7 +43,7 @@ public class TestPackages {
|
||||
var cmp = new JavaTXCompiler(
|
||||
List.of(new File("resources/packageTest/pkg/sub/Interface.jav")),
|
||||
List.of(new File("resources/packageTest")),
|
||||
new File(bytecodeDirectory), true
|
||||
new File(bytecodeDirectory)
|
||||
);
|
||||
|
||||
cmp.generateBytecode();
|
||||
|
||||
@@ -4,7 +4,7 @@ import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||
import de.dhbwstuttgart.typedeployment.TypeInsert;
|
||||
import de.dhbwstuttgart.typedeployment.TypeInsertFactory;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
|
||||
@@ -4,7 +4,7 @@ package astfactory;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
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.Type;
|
||||
@@ -12,8 +12,7 @@ import java.lang.reflect.TypeVariable;
|
||||
import java.util.Arrays;
|
||||
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>{
|
||||
@Test
|
||||
|
||||
@@ -4,10 +4,12 @@ import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.FCGenerator;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
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.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class SuperInterfacesTest {
|
||||
@Test
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
public class t{
|
||||
public mofus(){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package server;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import de.dhbwstuttgart.parser.SourceLoc;
|
||||
import de.dhbwstuttgart.server.packet.DebugPacket;
|
||||
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.typeinference.constraints.Constraint;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
|
||||
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 java.io.Writer;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.function.BiFunction;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class PacketTest {
|
||||
|
||||
|
||||
@@ -35,21 +35,24 @@ import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.stream.Collectors;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
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 ServerTest() {
|
||||
ConsoleInterface.unifyServerUrl = Optional.of("ws://localhost:5000");
|
||||
}
|
||||
|
||||
//@Test
|
||||
@Test
|
||||
public void checkServer_Scalar() throws IOException, ClassNotFoundException {
|
||||
compareLocalAndServerResult("Scalar.jav");
|
||||
}
|
||||
|
||||
//@Test
|
||||
@Test
|
||||
public void checkServer_Matrix() throws IOException, ClassNotFoundException {
|
||||
compareLocalAndServerResult("Matrix.jav");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
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.FileFilter;
|
||||
import java.io.FileInputStream;
|
||||
@@ -8,23 +12,21 @@ import java.io.ObjectOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||
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'
|
||||
*/
|
||||
public class TestComplete {
|
||||
private static HashMap<String, File[]> javFiles = new HashMap<>();
|
||||
|
||||
@BeforeAll
|
||||
@BeforeClass
|
||||
public static void setUp() {
|
||||
final String testFileDirectory = "resources/bytecode/javFiles/";
|
||||
final String expectedASTDirectory = "resources/syntaxtreegenerator/";
|
||||
@@ -351,7 +353,7 @@ public class TestComplete {
|
||||
assertEquals("Comparing expected and resulting AST for mathStrucInteger.jav", expectedAST, resultingAST);
|
||||
} catch (Exception exc) {
|
||||
exc.printStackTrace();
|
||||
assertInstanceOf(NotImplementedException.class, exc);
|
||||
assertTrue("An error occured while generating the AST for mathStrucInteger.jav", exc instanceof NotImplementedException);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package syntaxtreegenerator;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileInputStream;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
|
||||
@@ -17,7 +17,7 @@ import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
|
||||
public class TestNewFeatures {
|
||||
private static HashMap<String, File[]> javFiles = new HashMap<>();
|
||||
|
||||
@BeforeAll
|
||||
@BeforeClass
|
||||
public static void setUp() {
|
||||
final String testFileDirectory = "resources/syntaxtreegenerator/javFiles/";
|
||||
final String expectedASTDirectory = "resources/syntaxtreegenerator/";
|
||||
|
||||
@@ -2,6 +2,7 @@ package targetast;
|
||||
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
@@ -9,13 +10,13 @@ import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||
import de.dhbwstuttgart.target.tree.TargetStructure;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class ASTToTypedTargetAST {
|
||||
|
||||
@@ -23,7 +24,7 @@ public class ASTToTypedTargetAST {
|
||||
public void emptyClass() {
|
||||
ClassOrInterface emptyClass = new ClassOrInterface(0, new JavaClassName("EmptyClass"), new ArrayList<>(), Optional.empty(), Optional.empty(), new ArrayList<>(), new ArrayList<>(), new GenericDeclarationList(new ArrayList<>(), new NullToken()), new RefType(new JavaClassName("Object"), new NullToken()), false, false, new ArrayList<>(), new ArrayList<>(), new NullToken(), null);
|
||||
ResultSet emptyResultSet = new ResultSet(new HashSet<>());
|
||||
TargetStructure emptyTargetClass = new ASTToTargetAST(List.of(emptyResultSet), TestCodegen.createClassLoader()).convert(emptyClass);
|
||||
TargetStructure emptyTargetClass = new ASTToTargetAST(List.of(emptyResultSet)).convert(emptyClass);
|
||||
assert emptyTargetClass.getName().equals("EmptyClass");
|
||||
assert emptyTargetClass.methods().size() == 0;
|
||||
assert emptyTargetClass.fields().size() == 0;
|
||||
@@ -31,14 +32,13 @@ public class ASTToTypedTargetAST {
|
||||
|
||||
@Test
|
||||
public void overloading() throws Exception {
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
|
||||
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Overloading.jav").toFile();
|
||||
var compiler = new JavaTXCompiler(file);
|
||||
var resultSet = compiler.typeInference(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, classLoader);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var classLoader = new ByteArrayClassLoader();
|
||||
var overloading = TestCodegen.generateClass(converter.convert(classes.get(0)), classLoader);
|
||||
var overloading2 = TestCodegen.generateClass(converter.convert(classes.get(1)), classLoader);
|
||||
|
||||
@@ -54,54 +54,46 @@ public class ASTToTypedTargetAST {
|
||||
|
||||
@Test
|
||||
public void tphsAndGenerics() throws Exception {
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
|
||||
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Tph2.jav").toFile();
|
||||
var compiler = new JavaTXCompiler(file);
|
||||
var resultSet = compiler.typeInference(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, classLoader);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var tphAndGenerics = TestCodegen.generateClass(converter.convert(classes.get(0)), classLoader);
|
||||
var tphAndGenerics = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cycles() throws Exception {
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
|
||||
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Cycle.jav").toFile();
|
||||
var compiler = new JavaTXCompiler(file);
|
||||
var resultSet = compiler.typeInference(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, classLoader);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var cycle = TestCodegen.generateClass(converter.convert(classes.get(0)), classLoader);
|
||||
var cycle = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void infimum() throws Exception {
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
|
||||
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Infimum.jav").toFile();
|
||||
var compiler = new JavaTXCompiler(file);
|
||||
var resultSet = compiler.typeInference(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, classLoader);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var infimum = TestCodegen.generateClass(converter.convert(classes.get(0)), classLoader);
|
||||
var infimum = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void gen() throws Exception {
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
|
||||
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Gen.jav").toFile();
|
||||
var compiler = new JavaTXCompiler(file);
|
||||
var resultSet = compiler.typeInference(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, classLoader);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var generics = TestCodegen.generateClass(converter.convert(classes.get(0)), TestCodegen.createClassLoader());
|
||||
var generics = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
|
||||
var m = generics.getDeclaredMethod("m", Vector.class);
|
||||
var mReturnType = m.getGenericReturnType();
|
||||
assertEquals(mReturnType, m.getParameters()[0].getParameterizedType());
|
||||
@@ -111,15 +103,13 @@ public class ASTToTypedTargetAST {
|
||||
|
||||
@Test
|
||||
public void definedGenerics() throws Exception {
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
|
||||
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Generics.jav").toFile();
|
||||
var compiler = new JavaTXCompiler(file);
|
||||
var resultSet = compiler.typeInference(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, classLoader);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var generics = TestCodegen.generateClass(converter.convert(classes.get(0)), classLoader);
|
||||
var generics = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
|
||||
var B = generics.getTypeParameters()[0];
|
||||
var mt1 = generics.getDeclaredMethod("mt1", Object.class);
|
||||
var constructor = generics.getDeclaredConstructor(Object.class);
|
||||
@@ -131,15 +121,13 @@ public class ASTToTypedTargetAST {
|
||||
|
||||
@Test
|
||||
public void definedGenerics2() throws Exception {
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
|
||||
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Generics2.jav").toFile();
|
||||
var compiler = new JavaTXCompiler(file);
|
||||
var resultSet = compiler.typeInference(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, classLoader);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var generics2 = TestCodegen.generateClass(converter.convert(classes.get(0)), classLoader);
|
||||
var generics2 = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
|
||||
assertEquals(generics2.getTypeParameters()[0].getBounds()[0], String.class);
|
||||
var m = generics2.getDeclaredMethod("m1", Object.class);
|
||||
assertEquals(m.getTypeParameters()[0].getBounds()[0], Integer.class);
|
||||
@@ -147,30 +135,26 @@ public class ASTToTypedTargetAST {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("Not implemented")
|
||||
@Ignore("Not implemented")
|
||||
public void definedGenerics3() throws Exception {
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
|
||||
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Generics3.jav").toFile();
|
||||
var compiler = new JavaTXCompiler(file);
|
||||
var resultSet = compiler.typeInference(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, classLoader);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var generics3 = TestCodegen.generateClass(converter.convert(classes.get(0)), classLoader);
|
||||
var generics3 = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void definedGenerics4() throws Exception {
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
|
||||
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Generics4.jav").toFile();
|
||||
var compiler = new JavaTXCompiler(file);
|
||||
var resultSet = compiler.typeInference(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, classLoader);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var generics4 = TestCodegen.generateClass(converter.convert(classes.get(0)), classLoader);
|
||||
var generics4 = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
|
||||
|
||||
// var instance = generics4.getDeclaredConstructor().newInstance();
|
||||
// var method = generics4.getDeclaredMethod("m2", Object.class);
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
package targetast;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class GreaterEqualTest {
|
||||
static Class<?> classToTest;
|
||||
static Object instance;
|
||||
|
||||
@BeforeAll
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
var classFiles = TestCodegen.generateClassFiles(TestCodegen.createClassLoader(), "GreaterEqual.jav");
|
||||
var classFiles = TestCodegen.generateClassFiles(new ByteArrayClassLoader(), "GreaterEqual.jav");
|
||||
classToTest = classFiles.get("GreaterEqual");
|
||||
instance = classToTest.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
package targetast;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class GreaterThanTest {
|
||||
static Class<?> classToTest;
|
||||
static Object instance;
|
||||
|
||||
@BeforeAll
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
var classFiles = TestCodegen.generateClassFiles(TestCodegen.createClassLoader(), "GreaterThan.jav");
|
||||
var classFiles = TestCodegen.generateClassFiles(new ByteArrayClassLoader(), "GreaterThan.jav");
|
||||
classToTest = classFiles.get("GreaterThan");
|
||||
instance = classToTest.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user