Compare commits
57 Commits
KPS2025
...
e8335715fb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8335715fb | ||
|
|
e574174962 | ||
|
|
6df99fcacb | ||
|
|
d3fbaea8c7 | ||
|
|
3415c250a3 | ||
|
|
1b905cb3e2 | ||
|
|
d02c3583e9 | ||
|
|
ca98e83fd2 | ||
|
|
9ec32970ee | ||
|
|
c54e012426 | ||
|
|
52f6ebcf3c | ||
|
|
c80a0c8596 | ||
|
|
2278fb1b91 | ||
|
|
32b16cd5fd | ||
|
|
fd30c5f63f | ||
|
|
8bfd6ae255 | ||
|
|
ad2dfb13bd | ||
|
|
501633a90c | ||
|
|
4defa50ca2 | ||
|
|
d65e90536a | ||
|
|
3de7f1aa61 | ||
|
|
029e40b775 | ||
|
|
459bfcdd5f | ||
|
|
02886c38ea | ||
|
|
57ffae0481 | ||
|
|
d084d74a25 | ||
|
|
cd15016f61 | ||
|
|
b0e5eee25c | ||
|
|
d1bd285be7 | ||
|
|
a902fd5bee | ||
|
|
ced9fdc9f7 | ||
|
|
53417bf298 | ||
|
|
2d4da03f00 | ||
|
|
f7a13f5faa | ||
|
|
8fe80b4396 | ||
|
|
eb1201ae5e | ||
|
|
963ad76593 | ||
|
|
1eba09e3b0 | ||
|
|
fc82125d14 | ||
|
|
dad468368b | ||
|
|
fdd4f3aa59 | ||
|
|
a0c11b60e8 | ||
|
|
4cddf73e6d | ||
|
|
5024a02447 | ||
|
|
6c2d97b770 | ||
|
|
426c2916d3 | ||
|
|
f722a00fbb | ||
|
|
32797c9b9f | ||
|
|
87f655c85a | ||
|
|
613dceae1d | ||
|
|
81cac06e16 | ||
|
|
a47d5bc024 | ||
|
|
e5916d455a | ||
|
|
ebb639e72e | ||
|
|
f0a4a51ce6 | ||
|
|
7442880452 | ||
|
|
c4dc3b4245 |
@@ -1,8 +1,5 @@
|
|||||||
name: Build and Test with Maven
|
name: Build and Test with Maven
|
||||||
on:
|
on: [push]
|
||||||
push:
|
|
||||||
branches-ignore:
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Build-and-test-with-Maven:
|
Build-and-test-with-Maven:
|
||||||
@@ -18,7 +15,7 @@ jobs:
|
|||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
java-version: '24'
|
java-version: '23'
|
||||||
cache: 'maven'
|
cache: 'maven'
|
||||||
- name: Compile project
|
- name: Compile project
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -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: '24'
|
|
||||||
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!
|
|
||||||
40
independentTest.sh
Executable file
40
independentTest.sh
Executable file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
|
||||||
|
REPO="https://gitea.hb.dhbw-stuttgart.de/f.holzwarth/JavaCompilerCore.git"
|
||||||
|
TDIR="./testBuild"
|
||||||
|
|
||||||
|
rm -rf "$TDIR" 2>/dev/null
|
||||||
|
mkdir $TDIR
|
||||||
|
|
||||||
|
cd $TDIR
|
||||||
|
git clone $REPO .
|
||||||
|
git checkout feat/unify-server
|
||||||
|
# git checkout dad468368b86bdd5a3d3b2754b17617cee0a9107 # 1:55
|
||||||
|
# git checkout a0c11b60e8c9d7addcbe0d3a09c9ce2924e9d5c0 # 2:25
|
||||||
|
# git checkout 4cddf73e6d6c9116d3e1705c4b27a8e7f18d80c3 # 2:27
|
||||||
|
# git checkout 6c2d97b7703d954e4a42eef3ec374bcf313af75c # 2:13
|
||||||
|
# git checkout f722a00fbb6e69423d48a890e4a6283471763e64 # 1:35
|
||||||
|
# git checkout f0a4a51ce65639ce9a9470ff0fdb538fdf9c02cc # 2:19
|
||||||
|
# git checkout 1391206dfe59263cdb22f93371cfd1dd5465d97f # 1:29
|
||||||
|
|
||||||
|
date "+%Y.%m.%d %H:%M:%S"
|
||||||
|
|
||||||
|
# mvn clean compile -DskipTests package
|
||||||
|
## prefix each stderr line with " | "
|
||||||
|
# exec 2> >(trap "" INT TERM; sed 's/^/ | /' >&2)
|
||||||
|
# echo -e "\nMatrix test:\n |"
|
||||||
|
# time java -jar target/JavaTXcompiler-0.1-jar-with-dependencies.jar resources/bytecode/javFiles/Matrix.jav >/dev/null;
|
||||||
|
|
||||||
|
|
||||||
|
mvn clean compile test
|
||||||
|
|
||||||
|
|
||||||
|
echo -e "\nCleanup... "
|
||||||
|
cd -
|
||||||
|
rm -rf "$TDIR" 2>/dev/null
|
||||||
|
|
||||||
|
echo -e "\nFinished "
|
||||||
|
date "+%Y.%m.%d %H:%M:%S"
|
||||||
|
echo -e "\n "
|
||||||
|
|
||||||
69
pom.xml
69
pom.xml
@@ -12,79 +12,80 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
|||||||
<url>http://maven.apache.org</url>
|
<url>http://maven.apache.org</url>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit-jupiter-api</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>5.13.2</version>
|
<version>4.13.2</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.antlr/antlr4 -->
|
<!-- https://mvnrepository.com/artifact/org.antlr/antlr4 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.antlr</groupId>
|
<groupId>org.antlr</groupId>
|
||||||
<artifactId>antlr4</artifactId>
|
<artifactId>antlr4</artifactId>
|
||||||
<version>4.13.2</version>
|
<version>4.11.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
<version>2.19.0</version>
|
<version>2.16.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.github.classgraph</groupId>
|
<groupId>io.github.classgraph</groupId>
|
||||||
<artifactId>classgraph</artifactId>
|
<artifactId>classgraph</artifactId>
|
||||||
<version>4.8.180</version>
|
<version>4.8.172</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<version>33.4.8-jre</version>
|
<version>33.2.0-jre</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.ow2.asm/asm -->
|
<!-- https://mvnrepository.com/artifact/org.ow2.asm/asm -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.ow2.asm</groupId>
|
<groupId>org.ow2.asm</groupId>
|
||||||
<artifactId>asm</artifactId>
|
<artifactId>asm</artifactId>
|
||||||
<version>9.8</version>
|
<version>9.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.java-websocket</groupId>
|
||||||
|
<artifactId>Java-WebSocket</artifactId>
|
||||||
|
<version>1.5.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-simple</artifactId>
|
||||||
|
<version>1.7.25</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>2.17.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.diogonunes</groupId>
|
||||||
|
<artifactId>JColor</artifactId>
|
||||||
|
<version>5.5.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
|
||||||
<groupId>org.jacoco</groupId>
|
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
|
||||||
<version>0.8.13</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<goals>
|
|
||||||
<goal>prepare-agent</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>report</id>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>report</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.14.0</version>
|
<version>3.11.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<compilerArgs>--enable-preview</compilerArgs>
|
<compilerArgs>--enable-preview</compilerArgs>
|
||||||
<source>24</source>
|
<source>23</source>
|
||||||
<target>24</target>
|
<target>23</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>3.5.3</version>
|
<version>3.1.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<redirectTestOutputToFile>true</redirectTestOutputToFile>
|
<redirectTestOutputToFile>true</redirectTestOutputToFile>
|
||||||
<reportsDirectory>${project.build.directory}/test-reports</reportsDirectory>
|
<reportsDirectory>${project.build.directory}/test-reports</reportsDirectory>
|
||||||
<argLine>${argLine} --enable-preview</argLine>
|
<argLine>--enable-preview</argLine>
|
||||||
<trimStackTrace>false</trimStackTrace>
|
<trimStackTrace>false</trimStackTrace>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/JavaTXCompilerTest.java</exclude>
|
<exclude>**/JavaTXCompilerTest.java</exclude>
|
||||||
@@ -96,7 +97,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.antlr</groupId>
|
<groupId>org.antlr</groupId>
|
||||||
<artifactId>antlr4-maven-plugin</artifactId>
|
<artifactId>antlr4-maven-plugin</artifactId>
|
||||||
<version>4.13.2</version>
|
<version>4.11.1</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>antlr</id>
|
<id>antlr</id>
|
||||||
@@ -109,7 +110,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.3.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<archive>
|
<archive>
|
||||||
<manifest>
|
<manifest>
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
public class Uncurrier{
|
|
||||||
uncurry (f){
|
|
||||||
return x -> f.apply(x);}
|
|
||||||
uncurry (f){
|
|
||||||
return (x, y) -> f.apply(x).apply(y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import Uncurrier;
|
|
||||||
import java.lang.Integer;
|
|
||||||
|
|
||||||
class UncurrierMain {
|
|
||||||
meth(y) {
|
|
||||||
var uc = new Uncurrier() ;
|
|
||||||
uc.uncurry(x -> x+1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import java.util.Vector;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
class AddEle {
|
|
||||||
addEle(x, y) {
|
|
||||||
x.add(y);
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
import java.lang.Double;
|
|
||||||
import java.lang.Integer;
|
|
||||||
|
|
||||||
public class Fac {
|
|
||||||
|
|
||||||
getFac(n){
|
|
||||||
var res = 1;
|
|
||||||
var i = 1;
|
|
||||||
while(i<=n) {
|
|
||||||
res = res * i;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
import java.lang.Integer;
|
|
||||||
import java.lang.Double;
|
|
||||||
import java.lang.System;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
|
|
||||||
public class Faculty {
|
|
||||||
public Fun1$$<Double, Double> fact = (x) -> {
|
|
||||||
if (x == 1) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return x * (fact.apply(x-1.0));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public getFact(x) {
|
|
||||||
return fact.apply(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(x) {
|
|
||||||
var f = new Faculty();
|
|
||||||
var intRes = f.getFact(3.0);
|
|
||||||
System.out.println(intRes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import java.lang.Integer;
|
|
||||||
import java.lang.Float;
|
|
||||||
|
|
||||||
public class FacultyBug {
|
|
||||||
public Fun1$$<Float, Float> fact = (x) -> {
|
|
||||||
if (x == 1) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return x * (fact.apply(x-1));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public getFact(x) {
|
|
||||||
return fact.apply(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
class Id {
|
|
||||||
id2 = x -> x;
|
|
||||||
|
|
||||||
id(x) {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
id3(x) {
|
|
||||||
return id(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import java.lang.Integer;
|
|
||||||
|
|
||||||
public class Lambda {
|
|
||||||
|
|
||||||
m () {
|
|
||||||
var lam1 = (x) -> {
|
|
||||||
return x * x;
|
|
||||||
};
|
|
||||||
return lam1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
import java.lang.String ;
|
|
||||||
import java.lang.System;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.lang.Character;
|
|
||||||
import java.lang.Object;
|
|
||||||
import java.lang.Integer;
|
|
||||||
import fst;
|
|
||||||
import Id;
|
|
||||||
import OLMain;
|
|
||||||
import Fac;
|
|
||||||
import Faculty;
|
|
||||||
import applyLambda;
|
|
||||||
import java.util.Vector;
|
|
||||||
import Matrix;
|
|
||||||
import MatrixOP;
|
|
||||||
|
|
||||||
public class Main {
|
|
||||||
public static main(x) {
|
|
||||||
/*
|
|
||||||
new fst().main(5);
|
|
||||||
System.out.println(new fst().main(5));
|
|
||||||
|
|
||||||
//Id.jav: the identity-function
|
|
||||||
//applied to an integer
|
|
||||||
System.out.println(new Id().id(1));
|
|
||||||
//applied to a string
|
|
||||||
System.out.println(new Id().id("hallo"));
|
|
||||||
//lamda-Expr
|
|
||||||
//System.out.println(new Id().id2.apply(1));
|
|
||||||
//Bug: https://gitea.hb.dhbw-stuttgart.de/JavaTX/JavaCompilerCore/issues/378
|
|
||||||
|
|
||||||
//OL.jav: Overloading
|
|
||||||
OLMain ol = new OLMain();
|
|
||||||
|
|
||||||
//the function main is applied to an integer
|
|
||||||
System.out.println(ol.main(2));
|
|
||||||
//the main is applied to a double
|
|
||||||
System.out.println(ol.main(2.0));
|
|
||||||
System.out.println(ol.main("Hallo"));
|
|
||||||
//Fac.jav
|
|
||||||
System.out.println(new Fac().getFac(6));
|
|
||||||
|
|
||||||
|
|
||||||
//Faculty.jav
|
|
||||||
//System.out.println(new Faculty().fact.apply(6));
|
|
||||||
//Bug: https://gitea.hb.dhbw-stuttgart.de/JavaTX/JavaCompilerCore/issues/378
|
|
||||||
System.out.println(new Faculty().getFact(3));
|
|
||||||
|
|
||||||
//Lambda.jav: An lambda expression applied by the method apply
|
|
||||||
//System.out.println(new Lambda().m().apply(77));
|
|
||||||
//Bug: https://gitea.hb.dhbw-stuttgart.de/JavaTX/JavaCompilerCore/issues/378
|
|
||||||
|
|
||||||
//applyLambda.jav: A defined lambda expression is applied
|
|
||||||
System.out.println(new applyLambda().m());
|
|
||||||
*/
|
|
||||||
Vector<Vector<Integer>> vv = new Vector<Vector<Integer>>();
|
|
||||||
Vector<Integer> v1 = new Vector<Integer> ();
|
|
||||||
v1.addElement(2);
|
|
||||||
v1.addElement(2);
|
|
||||||
Vector<Integer> v2 = new Vector<Integer> ();
|
|
||||||
v2.addElement(3);
|
|
||||||
v2.addElement(3);
|
|
||||||
Matrix m1 = new Matrix();
|
|
||||||
m1.addElement(v1);
|
|
||||||
m1.addElement(v2);
|
|
||||||
//vv.addElement(v1);
|
|
||||||
//vv.addElement(v2);
|
|
||||||
//Matrix m1 = new Matrix(vv);
|
|
||||||
|
|
||||||
Vector<Vector<Integer>> vv1 = new Vector<Vector<Integer>>();
|
|
||||||
Vector<Integer> v3 = new Vector<Integer> ();
|
|
||||||
v3.addElement(2);
|
|
||||||
v3.addElement(2);
|
|
||||||
Vector<Integer> v4 = new Vector<Integer> ();
|
|
||||||
v4.addElement(3);
|
|
||||||
v4.addElement(3);
|
|
||||||
Matrix m2 = new Matrix();
|
|
||||||
m2.addElement(v3);
|
|
||||||
m2.addElement(v4);
|
|
||||||
//vv1.addElement(v3);
|
|
||||||
//vv1.addElement(v4);
|
|
||||||
//Matrix m2 = new Matrix(vv1);
|
|
||||||
|
|
||||||
|
|
||||||
//Matrix m3 = m1.mul(vv1);
|
|
||||||
Matrix m3 = m1.mul(m2);
|
|
||||||
System.out.println(m1.toString() + " * " + m2.toString() + " = " + m3.toString());
|
|
||||||
|
|
||||||
//MatrixOP
|
|
||||||
MatrixOP mOp1 = new MatrixOP();
|
|
||||||
mOp1.addElement(v1);
|
|
||||||
mOp1.addElement(v2);
|
|
||||||
MatrixOP mOp2 = mOp1.mul.apply(mOp1, mOp1);
|
|
||||||
System.out.println(m1.toString() + " * " + m2.toString() + " = " + mOp2.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
public class MainBug {
|
|
||||||
public static main(x) {
|
|
||||||
System.out.println(new fst().main(5));
|
|
||||||
//System.out.println(new FacultyBug().getFact(3));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import java.lang.System;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import Faculty;
|
|
||||||
|
|
||||||
public class MainFaculty {
|
|
||||||
public static void main(x) {
|
|
||||||
//var f = new Faculty();
|
|
||||||
//var intRes = f.getFact(3);
|
|
||||||
//System.out.println(intRes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import java.lang.String ;
|
|
||||||
import java.lang.System;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.lang.Float;
|
|
||||||
import OL2;
|
|
||||||
|
|
||||||
class MainOL {
|
|
||||||
public static main(x) {
|
|
||||||
var ol = new OL2();
|
|
||||||
|
|
||||||
//the function main is applied to an integer
|
|
||||||
//var res1 = ol.m2(2);
|
|
||||||
//the main is applied to a double
|
|
||||||
//System.out.println(ol.m2(2.0));
|
|
||||||
//System.out.println(ol.m2("Hallo").toString());
|
|
||||||
var res2 = ol.m2("Hallo").toString();
|
|
||||||
System.out.println(res2);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
import java.util.Vector;
|
|
||||||
import java.lang.Integer;
|
|
||||||
import java.lang.Boolean;
|
|
||||||
|
|
||||||
public class Matrix extends Vector<Vector<Integer>> {
|
|
||||||
|
|
||||||
|
|
||||||
public Matrix () {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Matrix(vv) {
|
|
||||||
var i = 0;
|
|
||||||
while(i < vv.size()) {
|
|
||||||
this.add(vv.elementAt(i));
|
|
||||||
i=i+1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
mul(m) {
|
|
||||||
var ret = new Matrix();
|
|
||||||
var i = 0;
|
|
||||||
while(i < size()) {
|
|
||||||
var v1 = this.elementAt(i);
|
|
||||||
var v2 = new Vector<Integer>();
|
|
||||||
var j = 0;
|
|
||||||
while(j < v1.size()) {
|
|
||||||
var erg = 0;
|
|
||||||
var k = 0;
|
|
||||||
while(k < v1.size()) {
|
|
||||||
erg = erg + v1.elementAt(k)
|
|
||||||
* m.elementAt(k).elementAt(j);
|
|
||||||
k++; }
|
|
||||||
v2.addElement(erg);
|
|
||||||
j++; }
|
|
||||||
ret.addElement(v2);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
import java.util.Vector;
|
|
||||||
import java.lang.Integer;
|
|
||||||
//import java.lang.Byte;
|
|
||||||
import java.lang.Boolean;
|
|
||||||
import java.lang.String;
|
|
||||||
import java.lang.System;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
|
|
||||||
public class MatrixOP extends Vector<Vector<Integer>> {
|
|
||||||
|
|
||||||
public MatrixOP () {
|
|
||||||
}
|
|
||||||
|
|
||||||
public MatrixOP(vv) {
|
|
||||||
Integer i;
|
|
||||||
i = 0;
|
|
||||||
while(i < vv.size()) {
|
|
||||||
this.add(vv.elementAt(i));
|
|
||||||
i=i+1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mul = (m1, m2) -> {
|
|
||||||
var ret = new MatrixOP();
|
|
||||||
var i = 0;
|
|
||||||
while(i < m1.size()) {
|
|
||||||
var v1 = m1.elementAt(i);
|
|
||||||
var v2 = new Vector<Integer>();
|
|
||||||
var j = 0;
|
|
||||||
while(j < v1.size()) {
|
|
||||||
var erg = 0;
|
|
||||||
var k = 0;
|
|
||||||
while(k < v1.size()) {
|
|
||||||
erg = erg + v1.elementAt(k)
|
|
||||||
* m2.elementAt(k).elementAt(j);
|
|
||||||
k++; }
|
|
||||||
// v2.addElement(new Integer(erg));
|
|
||||||
v2.addElement(erg);
|
|
||||||
j++; }
|
|
||||||
ret.addElement(v2);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
public static main(x) {
|
|
||||||
var vv = new Vector<Vector<Integer>>();
|
|
||||||
var v1 = new Vector<Integer> ();
|
|
||||||
v1.addElement(2);
|
|
||||||
v1.addElement(2);
|
|
||||||
var v2 = new Vector<Integer> ();
|
|
||||||
v2.addElement(3);
|
|
||||||
v2.addElement(3);
|
|
||||||
|
|
||||||
//MatrixOP
|
|
||||||
MatrixOP mOp1 = new MatrixOP();
|
|
||||||
mOp1.addElement(v1);
|
|
||||||
mOp1.addElement(v2);
|
|
||||||
MatrixOP mOp2 = mOp1.mul.apply(mOp1, mOp1);
|
|
||||||
System.out.print(mOp1); System.out.print(" * "); System.out.print(mOp1); System.out.print(" = "); System.out.println(mOp2);
|
|
||||||
//System.out.print(mOp1 + " * " + mOp1 + " = " + mOp2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
import java.lang.String;
|
|
||||||
import java.lang.Integer;
|
|
||||||
import java.lang.Double;
|
|
||||||
import java.lang.Boolean;
|
|
||||||
import java.lang.Object;
|
|
||||||
import java.lang.System;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class OL1 {
|
|
||||||
|
|
||||||
m1( x) { return x + x; }
|
|
||||||
|
|
||||||
|
|
||||||
m1(x) { return x || x; }
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class OL2 {
|
|
||||||
|
|
||||||
m2(x) {
|
|
||||||
var ol;
|
|
||||||
ol = new OL1();
|
|
||||||
return ol.m1(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import java.lang.String;
|
|
||||||
import java.lang.Integer;
|
|
||||||
import java.lang.Double;
|
|
||||||
import java.util.Vector;
|
|
||||||
import java.lang.Boolean;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class OLFun {
|
|
||||||
x;
|
|
||||||
|
|
||||||
|
|
||||||
m(f, y) {
|
|
||||||
y = f.apply(x+x);
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
class Pair {
|
|
||||||
fst;
|
|
||||||
snd;
|
|
||||||
|
|
||||||
Pair(fst, snd) { this.fst=fst; this.snd=snd; }
|
|
||||||
|
|
||||||
getfst() { return this.fst; }
|
|
||||||
|
|
||||||
swap() {
|
|
||||||
return new Pair<>(this.snd, this.fst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import java.lang.Integer;
|
|
||||||
import java.lang.String;
|
|
||||||
|
|
||||||
public class Plus {
|
|
||||||
|
|
||||||
m(a, b) {
|
|
||||||
return a+b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
import java.util.List;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.lang.String;
|
|
||||||
|
|
||||||
public class Sorting{
|
|
||||||
merge(a, b){
|
|
||||||
a.addAll(b);
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sort(in){
|
|
||||||
var firstHalf = in;
|
|
||||||
var secondHalf = in;
|
|
||||||
return merge(sort(firstHalf), sort(secondHalf));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
void sort(a){
|
|
||||||
a = merge(a,a);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import java.lang.String;
|
|
||||||
import java.lang.Object;
|
|
||||||
import java.lang.System;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.lang.Character;
|
|
||||||
|
|
||||||
public class Swap{
|
|
||||||
<ZDP, ZEA, ZDO, YZP, ZCY, ZDZ> Fun1$$<ZCY, Fun1$$<ZDZ, ZEA>> swap(f){
|
|
||||||
return x->y->f.apply(y).apply(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
Fun1$$<String, Fun1$$<String, Fun1$$<String, String>>> swap(f){
|
|
||||||
return x -> y -> z -> f.apply(z).apply(x).apply(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static main (y) {
|
|
||||||
var func = x -> y -> z -> x + y + z;
|
|
||||||
var res = new Swap().swap(func).apply("A").apply("B").apply("C");
|
|
||||||
System.out.println(res);}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
class TPHMethod {
|
|
||||||
void m(a, b) {
|
|
||||||
a = b;
|
|
||||||
b=a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
class Test{
|
|
||||||
void m( op, a, b ){
|
|
||||||
op.myapply(a, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Atype{}
|
|
||||||
class Btype{}
|
|
||||||
|
|
||||||
class Operator1{
|
|
||||||
void myapply(Atype p1, Atype p2){...}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Operator2{
|
|
||||||
void myapply(Btype p1, Btype p2){...}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
public class Uncurrier{
|
|
||||||
uncurry (f){
|
|
||||||
return x -> f.apply(x);}
|
|
||||||
uncurry (f){
|
|
||||||
return (x, y) -> f.apply(x).apply(y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import Uncurrier;
|
|
||||||
|
|
||||||
class UncurrierMain {
|
|
||||||
public static main(x) {
|
|
||||||
var uc = new Uncurrier() ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import java.lang.Integer;
|
|
||||||
import java.lang.String;
|
|
||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
class VectorAdd {
|
|
||||||
vectorAdd(v1, v2) {
|
|
||||||
var i = 0;
|
|
||||||
var erg = new Vector<>();
|
|
||||||
while (i < v1.size()) {
|
|
||||||
erg.addElement(v1.elementAt(i) + v2.elementAt(i));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return erg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import java.util.Vector;
|
|
||||||
class Apply { }
|
|
||||||
|
|
||||||
public class applyLambda {
|
|
||||||
|
|
||||||
public m () {
|
|
||||||
var lam1 = (x) -> {
|
|
||||||
return x;
|
|
||||||
};
|
|
||||||
|
|
||||||
return lam1.apply(new Apply());
|
|
||||||
//return lam1;
|
|
||||||
//return new Vector();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
//import java.lang.Integer;
|
|
||||||
|
|
||||||
class fst {
|
|
||||||
main(x) {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
class genVector {
|
|
||||||
|
|
||||||
m(v) {
|
|
||||||
return v.elementAt(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
import java.lang.Integer;
|
|
||||||
import Id;
|
|
||||||
|
|
||||||
class Test {
|
|
||||||
m() {
|
|
||||||
Integer o1 = new Id<Integer,Integer>().id2.apply(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
public class lambdaId {
|
|
||||||
lambdaId = x -> x;
|
|
||||||
|
|
||||||
/*
|
|
||||||
id3 (x) {
|
|
||||||
return lambdaId.apply(x);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
class mathStruc {
|
|
||||||
model;
|
|
||||||
|
|
||||||
innerOp = (o) -> (ms) -> new mathStruc<>(o.apply(model,ms.model));
|
|
||||||
|
|
||||||
mathStruc(m) {
|
|
||||||
model =m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import java.lang.Integer;
|
|
||||||
|
|
||||||
class mathStruc {
|
|
||||||
model;
|
|
||||||
|
|
||||||
innerOp = (o) -> (ms) -> new mathStruc<>(o.apply(model,ms.model));
|
|
||||||
|
|
||||||
mathStruc(m) {
|
|
||||||
model =m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class mathStrucIntegerUse {
|
|
||||||
main() {
|
|
||||||
var ms = new mathStruc<>(2);
|
|
||||||
return ms.innerOp.apply((x,y) -> x+y).apply(ms);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
import java.util.Vector;
|
|
||||||
import java.lang.Integer;
|
|
||||||
import java.lang.Boolean;
|
|
||||||
|
|
||||||
public class mathStrucMatrixOP {
|
|
||||||
model;
|
|
||||||
|
|
||||||
innerOp = (o) -> (ms) -> new mathStrucMatrixOP<>(o.apply(model,ms.model));
|
|
||||||
|
|
||||||
public mathStrucMatrixOP(m) {
|
|
||||||
model =m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MatrixOP extends Vector<Vector<Integer>> {
|
|
||||||
|
|
||||||
MatrixOP () {
|
|
||||||
}
|
|
||||||
|
|
||||||
MatrixOP(vv) {
|
|
||||||
Integer i;
|
|
||||||
i = 0;
|
|
||||||
while(i < vv.size()) {
|
|
||||||
// Boolean a = this.add(vv.elementAt(i));
|
|
||||||
this.add(vv.elementAt(i));
|
|
||||||
i=i+1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public mul = (m1, m2) -> {
|
|
||||||
var ret = new MatrixOP();
|
|
||||||
var i = 0;
|
|
||||||
while(i < m1.size()) {
|
|
||||||
var v1 = m1.elementAt(i);
|
|
||||||
var v2 = new Vector<Integer>();
|
|
||||||
var j = 0;
|
|
||||||
while(j < v1.size()) {
|
|
||||||
var erg = 0;
|
|
||||||
var k = 0;
|
|
||||||
while(k < v1.size()) {
|
|
||||||
erg = erg + v1.elementAt(k)
|
|
||||||
* m2.elementAt(k).elementAt(j);
|
|
||||||
k++; }
|
|
||||||
// v2.addElement(new Integer(erg));
|
|
||||||
v2.addElement(erg);
|
|
||||||
j++; }
|
|
||||||
ret.addElement(v2);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class mathStrucUseMatrixOP {
|
|
||||||
|
|
||||||
main() {
|
|
||||||
Vector<Vector<Integer>> vv = new Vector<Vector<Integer>>();
|
|
||||||
Vector<Integer> v1 = new Vector<Integer>();
|
|
||||||
v1.addElement(2);
|
|
||||||
v1.addElement(2);
|
|
||||||
Vector<Integer> v2 = new Vector<Integer>();
|
|
||||||
v2.addElement(3);
|
|
||||||
v2.addElement(3);
|
|
||||||
vv.addElement(v1);
|
|
||||||
vv.addElement(v2);
|
|
||||||
|
|
||||||
MatrixOP m1 = new MatrixOP(vv);
|
|
||||||
|
|
||||||
Vector<Vector<Integer>> vv1 = new Vector<Vector<Integer>>();
|
|
||||||
Vector<Integer> v3 = new Vector<Integer>();
|
|
||||||
v3.addElement(2);
|
|
||||||
v3.addElement(2);
|
|
||||||
Vector<Integer> v4 = new Vector<Integer>();
|
|
||||||
v4.addElement(3);
|
|
||||||
v4.addElement(3);
|
|
||||||
vv1.addElement(v3);
|
|
||||||
vv1.addElement(v4);
|
|
||||||
|
|
||||||
MatrixOP m2 = new MatrixOP(vv1);
|
|
||||||
|
|
||||||
var mms;
|
|
||||||
mms = new mathStrucMatrixOP<>(m1);
|
|
||||||
var mms2;
|
|
||||||
mms2 = new mathStrucMatrixOP<>(m2);
|
|
||||||
var mms3;
|
|
||||||
mms3 = mms.innerOp.apply(m1.mul).apply(mms2);
|
|
||||||
return mms3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import java.lang.String;
|
|
||||||
import java.lang.Boolean;
|
|
||||||
import java.lang.Integer;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public class testclass{
|
|
||||||
|
|
||||||
public testMethod(ele){
|
|
||||||
if(ele){
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,7 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
public class Bug325 {
|
public class Bug325 {
|
||||||
public main() {
|
public main() {
|
||||||
var list = new ArrayList<>(List.of(1,2,3,4,5));
|
List<Integer> list = new ArrayList<>(List.of(1,2,3,4,5));
|
||||||
var func = x -> x*2;
|
var func = x -> x*2;
|
||||||
return list.stream().map(func).toList();
|
return list.stream().map(func).toList();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,6 @@ import java.util.Vector;
|
|||||||
import java.lang.Integer;
|
import java.lang.Integer;
|
||||||
//import java.lang.Byte;
|
//import java.lang.Byte;
|
||||||
import java.lang.Boolean;
|
import java.lang.Boolean;
|
||||||
import java.util.function.BiFunction;
|
|
||||||
|
|
||||||
public class MatrixOP extends Vector<Vector<Integer>> {
|
public class MatrixOP extends Vector<Vector<Integer>> {
|
||||||
|
|
||||||
|
|||||||
@@ -8,18 +8,20 @@ import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
|||||||
import de.dhbwstuttgart.target.tree.*;
|
import de.dhbwstuttgart.target.tree.*;
|
||||||
import de.dhbwstuttgart.target.tree.expression.*;
|
import de.dhbwstuttgart.target.tree.expression.*;
|
||||||
import de.dhbwstuttgart.target.tree.type.*;
|
import de.dhbwstuttgart.target.tree.type.*;
|
||||||
|
import de.dhbwstuttgart.util.Logger;
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
import java.lang.invoke.*;
|
import java.lang.invoke.*;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static org.objectweb.asm.Opcodes.*;
|
import static org.objectweb.asm.Opcodes.*;
|
||||||
import static de.dhbwstuttgart.target.tree.expression.TargetBinaryOp.*;
|
import static de.dhbwstuttgart.target.tree.expression.TargetBinaryOp.*;
|
||||||
import static de.dhbwstuttgart.target.tree.expression.TargetLiteral.*;
|
import static de.dhbwstuttgart.target.tree.expression.TargetLiteral.*;
|
||||||
|
|
||||||
public class Codegen {
|
public class Codegen {
|
||||||
|
public static Logger logger = new Logger("codegen");
|
||||||
|
|
||||||
private final TargetStructure clazz;
|
private final TargetStructure clazz;
|
||||||
private final ClassWriter cw;
|
private final ClassWriter cw;
|
||||||
public final String className;
|
public final String className;
|
||||||
@@ -85,16 +87,14 @@ public class Codegen {
|
|||||||
int localCounter;
|
int localCounter;
|
||||||
MethodVisitor mv;
|
MethodVisitor mv;
|
||||||
TargetType returnType;
|
TargetType returnType;
|
||||||
boolean isStatic = false;
|
|
||||||
|
|
||||||
Stack<BreakEnv> breakStack = new Stack<>();
|
Stack<BreakEnv> breakStack = new Stack<>();
|
||||||
Stack<Integer> switchResultValue = new Stack<>();
|
Stack<Integer> switchResultValue = new Stack<>();
|
||||||
|
|
||||||
State(TargetType returnType, MethodVisitor mv, int localCounter, boolean isStatic) {
|
State(TargetType returnType, MethodVisitor mv, int localCounter) {
|
||||||
this.returnType = returnType;
|
this.returnType = returnType;
|
||||||
this.mv = mv;
|
this.mv = mv;
|
||||||
this.localCounter = localCounter;
|
this.localCounter = localCounter;
|
||||||
this.isStatic = isStatic;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void enterScope() {
|
void enterScope() {
|
||||||
@@ -132,7 +132,6 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void boxPrimitive(State state, TargetType type) {
|
private void boxPrimitive(State state, TargetType type) {
|
||||||
if (type instanceof TargetExtendsWildcard ew) type = ew.innerType();
|
|
||||||
var mv = state.mv;
|
var mv = state.mv;
|
||||||
if (type.equals(TargetType.Boolean) || type.equals(TargetType.boolean_)) {
|
if (type.equals(TargetType.Boolean) || type.equals(TargetType.boolean_)) {
|
||||||
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
|
||||||
@@ -154,7 +153,6 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void unboxPrimitive(State state, TargetType type) {
|
private void unboxPrimitive(State state, TargetType type) {
|
||||||
if (type instanceof TargetExtendsWildcard ew) type = ew.innerType();
|
|
||||||
var mv = state.mv;
|
var mv = state.mv;
|
||||||
if (type.equals(TargetType.Boolean)) {
|
if (type.equals(TargetType.Boolean)) {
|
||||||
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
|
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
|
||||||
@@ -230,16 +228,13 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void convertTo(State state, TargetType source, TargetType dest) {
|
private void convertTo(State state, TargetType source, TargetType dest) {
|
||||||
if (source instanceof TargetExtendsWildcard ew) source = ew.innerType();
|
|
||||||
if (dest instanceof TargetExtendsWildcard ew) dest = ew.innerType();
|
|
||||||
|
|
||||||
var mv = state.mv;
|
var mv = state.mv;
|
||||||
if (source.equals(dest))
|
if (source.equals(dest))
|
||||||
return;
|
return;
|
||||||
if (source.equals(TargetType.Long)) {
|
if (source.equals(TargetType.Long)) {
|
||||||
if (dest.equals(TargetType.Integer))
|
if (dest.equals(TargetType.Integer)) {
|
||||||
mv.visitInsn(L2I);
|
mv.visitInsn(L2I);
|
||||||
else if (dest.equals(TargetType.Float))
|
} else if (dest.equals(TargetType.Float))
|
||||||
mv.visitInsn(L2F);
|
mv.visitInsn(L2F);
|
||||||
else if (dest.equals(TargetType.Double))
|
else if (dest.equals(TargetType.Double))
|
||||||
mv.visitInsn(L2D);
|
mv.visitInsn(L2D);
|
||||||
@@ -282,8 +277,6 @@ public class Codegen {
|
|||||||
mv.visitInsn(I2F);
|
mv.visitInsn(I2F);
|
||||||
else if (dest.equals(TargetType.Double))
|
else if (dest.equals(TargetType.Double))
|
||||||
mv.visitInsn(I2D);
|
mv.visitInsn(I2D);
|
||||||
} else if (source.equals(TargetType.Boolean)) {
|
|
||||||
unboxPrimitive(state, dest);
|
|
||||||
} else if (isFunctionalInterface(source) && isFunctionalInterface(dest) &&
|
} else if (isFunctionalInterface(source) && isFunctionalInterface(dest) &&
|
||||||
!(source instanceof TargetFunNType && dest instanceof TargetFunNType)) {
|
!(source instanceof TargetFunNType && dest instanceof TargetFunNType)) {
|
||||||
boxFunctionalInterface(state, source, dest);
|
boxFunctionalInterface(state, source, dest);
|
||||||
@@ -645,7 +638,7 @@ public class Codegen {
|
|||||||
} else if (op.expr() instanceof TargetFieldVar fieldVar) {
|
} else if (op.expr() instanceof TargetFieldVar fieldVar) {
|
||||||
generate(state, fieldVar.left());
|
generate(state, fieldVar.left());
|
||||||
mv.visitInsn(SWAP);
|
mv.visitInsn(SWAP);
|
||||||
mv.visitFieldInsn(PUTFIELD, fieldVar.owner().getInternalName(), fieldVar.right(), fieldVar.type().toDescriptor());
|
mv.visitFieldInsn(PUTFIELD, fieldVar.owner().getInternalName(), fieldVar.right(), fieldVar.type().toSignature());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -767,16 +760,6 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TargetType removeGenerics(TargetType param) {
|
|
||||||
return switch (param) {
|
|
||||||
case null -> null;
|
|
||||||
case TargetFunNType funNType -> new TargetFunNType(funNType.name(), funNType.funNParams(), List.of(), funNType.returnArguments());
|
|
||||||
case TargetRefType refType -> new TargetRefType(refType.name());
|
|
||||||
case TargetGenericType targetGenericType -> TargetType.Object;
|
|
||||||
default -> param;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateLambdaExpression(State state, TargetLambdaExpression lambda) {
|
private void generateLambdaExpression(State state, TargetLambdaExpression lambda) {
|
||||||
var mv = state.mv;
|
var mv = state.mv;
|
||||||
|
|
||||||
@@ -788,8 +771,7 @@ public class Codegen {
|
|||||||
|
|
||||||
var parameters = new ArrayList<>(lambda.captures());
|
var parameters = new ArrayList<>(lambda.captures());
|
||||||
parameters.addAll(signature.parameters());
|
parameters.addAll(signature.parameters());
|
||||||
parameters = parameters.stream().map(param -> param.withType(removeGenerics(param.pattern().type()))).collect(Collectors.toCollection(ArrayList::new));
|
var implSignature = new TargetMethod.Signature(Set.of(), parameters, lambda.signature().returnType());
|
||||||
var implSignature = new TargetMethod.Signature(Set.of(), parameters, removeGenerics(lambda.signature().returnType()));
|
|
||||||
|
|
||||||
TargetMethod impl;
|
TargetMethod impl;
|
||||||
if (lambdas.containsKey(lambda)) {
|
if (lambdas.containsKey(lambda)) {
|
||||||
@@ -797,22 +779,21 @@ public class Codegen {
|
|||||||
} else {
|
} else {
|
||||||
var name = "lambda$" + lambdaCounter++;
|
var name = "lambda$" + lambdaCounter++;
|
||||||
|
|
||||||
impl = new TargetMethod(state.isStatic ? ACC_STATIC : 0, name, lambda.block(), implSignature, null);
|
impl = new TargetMethod(0, name, lambda.block(), implSignature, null);
|
||||||
generateMethod(impl, state);
|
generateMethod(impl);
|
||||||
lambdas.put(lambda, impl);
|
lambdas.put(lambda, impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
var mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodType.class, MethodHandle.class, MethodType.class);
|
var mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodType.class, MethodHandle.class, MethodType.class);
|
||||||
|
|
||||||
var bootstrap = new Handle(H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory", mt.toMethodDescriptorString(), false);
|
var bootstrap = new Handle(H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory", mt.toMethodDescriptorString(), false);
|
||||||
var handle = new Handle(state.isStatic ? H_INVOKESTATIC : H_INVOKEVIRTUAL, clazz.getName(), impl.name(), implSignature.getDescriptor(), false);
|
var handle = new Handle(H_INVOKEVIRTUAL, clazz.getName(), impl.name(), implSignature.getDescriptor(), false);
|
||||||
|
|
||||||
var params = new ArrayList<TargetType>();
|
var params = new ArrayList<TargetType>();
|
||||||
if(!state.isStatic) params.add(new TargetRefType(clazz.qualifiedName().toString()));
|
params.add(new TargetRefType(clazz.qualifiedName().getClassName()));
|
||||||
params.addAll(lambda.captures().stream().map(mp -> mp.pattern().type()).toList());
|
params.addAll(lambda.captures().stream().map(mp -> mp.pattern().type()).toList());
|
||||||
|
|
||||||
if (!state.isStatic)
|
mv.visitVarInsn(ALOAD, 0);
|
||||||
mv.visitVarInsn(ALOAD, 0);
|
|
||||||
for (var index = 0; index < lambda.captures().size(); index++) {
|
for (var index = 0; index < lambda.captures().size(); index++) {
|
||||||
var capture = lambda.captures().get(index);
|
var capture = lambda.captures().get(index);
|
||||||
var pattern = (TargetTypePattern) capture.pattern();
|
var pattern = (TargetTypePattern) capture.pattern();
|
||||||
@@ -947,7 +928,7 @@ public class Codegen {
|
|||||||
mv.visitInsn(DUP);
|
mv.visitInsn(DUP);
|
||||||
else
|
else
|
||||||
mv.visitInsn(DUP_X1);
|
mv.visitInsn(DUP_X1);
|
||||||
mv.visitFieldInsn(dot.isStatic() ? PUTSTATIC : PUTFIELD, dot.owner().getInternalName(), dot.right(), fieldType.toDescriptor());
|
mv.visitFieldInsn(dot.isStatic() ? PUTSTATIC : PUTFIELD, dot.owner().getInternalName(), dot.right(), fieldType.toSignature());
|
||||||
}
|
}
|
||||||
default -> throw new CodeGenException("Invalid assignment");
|
default -> throw new CodeGenException("Invalid assignment");
|
||||||
}
|
}
|
||||||
@@ -964,7 +945,7 @@ public class Codegen {
|
|||||||
case TargetFieldVar dot: {
|
case TargetFieldVar dot: {
|
||||||
if (!dot.isStatic())
|
if (!dot.isStatic())
|
||||||
generate(state, dot.left());
|
generate(state, dot.left());
|
||||||
mv.visitFieldInsn(dot.isStatic() ? GETSTATIC : GETFIELD, dot.left().type().getInternalName(), dot.right(), dot.type().toDescriptor());
|
mv.visitFieldInsn(dot.isStatic() ? GETSTATIC : GETFIELD, dot.left().type().getInternalName(), dot.right(), dot.type().toSignature());
|
||||||
unboxPrimitive(state, dot.type());
|
unboxPrimitive(state, dot.type());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1339,7 +1320,7 @@ public class Codegen {
|
|||||||
types.add(Type.getObjectType(guard.inner().type().getInternalName()));
|
types.add(Type.getObjectType(guard.inner().type().getInternalName()));
|
||||||
// TODO Same here we need to evaluate constant;
|
// TODO Same here we need to evaluate constant;
|
||||||
} else {
|
} else {
|
||||||
System.out.println(label);
|
logger.info(label);
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1428,7 +1409,7 @@ public class Codegen {
|
|||||||
throw new CodeGenException("Couldn't find suitable field accessor for '" + type.name() + "'");
|
throw new CodeGenException("Couldn't find suitable field accessor for '" + type.name() + "'");
|
||||||
var field = clazz.getFieldDecl().get(i);
|
var field = clazz.getFieldDecl().get(i);
|
||||||
var fieldType = converter.convert(field.getType());
|
var fieldType = converter.convert(field.getType());
|
||||||
state.mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), field.getName(), "()" + fieldType.toDescriptor(), false);
|
state.mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), field.getName(), "()" + fieldType.toSignature(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindPattern(State state, TargetType type, TargetPattern pat, Label start, int index, int depth) {
|
private void bindPattern(State state, TargetType type, TargetPattern pat, Label start, int index, int depth) {
|
||||||
@@ -1533,14 +1514,14 @@ public class Codegen {
|
|||||||
//if ((access & ACC_PRIVATE) == 0 && (access & ACC_PROTECTED) == 0) // TODO Implement access modifiers properly
|
//if ((access & ACC_PRIVATE) == 0 && (access & ACC_PROTECTED) == 0) // TODO Implement access modifiers properly
|
||||||
// access |= ACC_PUBLIC;
|
// access |= ACC_PUBLIC;
|
||||||
|
|
||||||
cw.visitField(access, field.name(), field.type().toDescriptor(), field.type().toSignature(), null);
|
cw.visitField(access, field.name(), field.type().toSignature(), field.type().toDescriptor(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateStaticConstructor(TargetMethod constructor) {
|
private void generateStaticConstructor(TargetMethod constructor) {
|
||||||
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "<clinit>", "()V", null, null);
|
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "<clinit>", "()V", null, null);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
|
|
||||||
var state = new State(null, mv, 0, true);
|
var state = new State(null, mv, 0);
|
||||||
generate(state, constructor.block());
|
generate(state, constructor.block());
|
||||||
|
|
||||||
mv.visitInsn(RETURN);
|
mv.visitInsn(RETURN);
|
||||||
@@ -1554,7 +1535,7 @@ public class Codegen {
|
|||||||
mv.visitAttribute(new JavaTXSignatureAttribute(constructor.getTXSignature()));
|
mv.visitAttribute(new JavaTXSignatureAttribute(constructor.getTXSignature()));
|
||||||
|
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
var state = new State(null, mv, 1, false);
|
var state = new State(null, mv, 1);
|
||||||
for (var param : constructor.parameters()) {
|
for (var param : constructor.parameters()) {
|
||||||
var pattern = param.pattern();
|
var pattern = param.pattern();
|
||||||
if (pattern instanceof TargetTypePattern tp)
|
if (pattern instanceof TargetTypePattern tp)
|
||||||
@@ -1600,31 +1581,9 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateMethod(TargetMethod method) {
|
private void generateMethod(TargetMethod method) {
|
||||||
generateMethod(method, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateMainMethod() {
|
|
||||||
var mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
|
|
||||||
mv.visitCode();
|
|
||||||
mv.visitVarInsn(ALOAD, 0);
|
|
||||||
mv.visitMethodInsn(INVOKESTATIC, "java/util/List", "of", "([Ljava/lang/Object;)Ljava/util/List;", true);
|
|
||||||
mv.visitMethodInsn(INVOKESTATIC, new TargetRefType(clazz.qualifiedName().toString()).getInternalName(), "main", "(Ljava/util/List;)V", false);
|
|
||||||
mv.visitInsn(RETURN);
|
|
||||||
mv.visitMaxs(0, 0);
|
|
||||||
mv.visitEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateMethod(TargetMethod method, State parent) {
|
|
||||||
var access = method.access();
|
var access = method.access();
|
||||||
|
|
||||||
var params = method.signature().parameters();
|
|
||||||
if (method.name().equals("main") && method.isStatic() && params.size() == 1 &&
|
|
||||||
params.getFirst().pattern().type().equals(new TargetRefType("java.util.List", List.of(new TargetRefType("java.lang.String"))))) {
|
|
||||||
|
|
||||||
generateMainMethod();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method.block() == null)
|
if (method.block() == null)
|
||||||
access |= ACC_ABSTRACT;
|
access |= ACC_ABSTRACT;
|
||||||
if (clazz instanceof TargetInterface)
|
if (clazz instanceof TargetInterface)
|
||||||
@@ -1638,10 +1597,7 @@ public class Codegen {
|
|||||||
|
|
||||||
if (method.block() != null) {
|
if (method.block() != null) {
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
var state = new State(method.signature().returnType(), mv, method.isStatic() ? 0 : 1, method.isStatic());
|
var state = new State(method.signature().returnType(), mv, method.isStatic() ? 0 : 1);
|
||||||
if (parent != null) {
|
|
||||||
state.scope.parent = parent.scope;
|
|
||||||
}
|
|
||||||
var offset = 1;
|
var offset = 1;
|
||||||
for (var param : method.signature().parameters()) {
|
for (var param : method.signature().parameters()) {
|
||||||
state.createVariable(param.pattern().name(), param.pattern().type());
|
state.createVariable(param.pattern().name(), param.pattern().type());
|
||||||
@@ -1651,8 +1607,6 @@ public class Codegen {
|
|||||||
bindLocalVariables(state, cp, offset);
|
bindLocalVariables(state, cp, offset);
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
//if (parent != null) System.out.println("parent: " + parent.scope.locals.keySet());
|
|
||||||
//System.out.println(state.scope.locals.keySet());
|
|
||||||
generate(state, method.block());
|
generate(state, method.block());
|
||||||
if (method.signature().returnType() == null)
|
if (method.signature().returnType() == null)
|
||||||
mv.visitInsn(RETURN);
|
mv.visitInsn(RETURN);
|
||||||
@@ -1666,12 +1620,12 @@ public class Codegen {
|
|||||||
if (!generics.isEmpty()) {
|
if (!generics.isEmpty()) {
|
||||||
ret += "<";
|
ret += "<";
|
||||||
for (var generic : generics) {
|
for (var generic : generics) {
|
||||||
ret += generic.name() + ":" + generic.bound().toSignature();
|
ret += generic.name() + ":" + generic.bound().toDescriptor();
|
||||||
}
|
}
|
||||||
ret += ">";
|
ret += ">";
|
||||||
}
|
}
|
||||||
if (clazz.superType() != null)
|
if (clazz.superType() != null)
|
||||||
ret += clazz.superType().toSignature();
|
ret += clazz.superType().toDescriptor();
|
||||||
for (var intf : clazz.implementingInterfaces()) {
|
for (var intf : clazz.implementingInterfaces()) {
|
||||||
ret += intf.toSignature();
|
ret += intf.toSignature();
|
||||||
}
|
}
|
||||||
@@ -1759,7 +1713,7 @@ public class Codegen {
|
|||||||
|
|
||||||
// Generate wrapper method
|
// Generate wrapper method
|
||||||
var mv = cw2.visitMethod(ACC_PUBLIC, toMethod.name, toDescriptor, null, null);
|
var mv = cw2.visitMethod(ACC_PUBLIC, toMethod.name, toDescriptor, null, null);
|
||||||
var state = new State(null, mv, 0, false);
|
var state = new State(null, mv, 0);
|
||||||
|
|
||||||
mv.visitVarInsn(ALOAD, 0);
|
mv.visitVarInsn(ALOAD, 0);
|
||||||
mv.visitFieldInsn(GETFIELD, className, "wrapped", pair.from.toDescriptor());
|
mv.visitFieldInsn(GETFIELD, className, "wrapped", pair.from.toDescriptor());
|
||||||
@@ -1783,7 +1737,7 @@ public class Codegen {
|
|||||||
|
|
||||||
cw2.visitEnd();
|
cw2.visitEnd();
|
||||||
var bytes = cw2.toByteArray();
|
var bytes = cw2.toByteArray();
|
||||||
compiler.auxiliaries.put(className, bytes);
|
converter.auxiliaries.put(className, bytes);
|
||||||
|
|
||||||
// TODO These class loading shenanigans happen in a few places, the tests load the classes individually.
|
// TODO These class loading shenanigans happen in a few places, the tests load the classes individually.
|
||||||
// Instead we should just look at the folder.
|
// Instead we should just look at the folder.
|
||||||
@@ -1791,7 +1745,7 @@ public class Codegen {
|
|||||||
converter.classLoader.findClass(className);
|
converter.classLoader.findClass(className);
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
try {
|
try {
|
||||||
converter.classLoader.loadClass(className, bytes);
|
converter.classLoader.loadClass(bytes);
|
||||||
} catch (LinkageError ignored) {}
|
} catch (LinkageError ignored) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1826,7 +1780,7 @@ public class Codegen {
|
|||||||
bootstrapArgs[1] = String.join(";", clazz.fields().stream().map(TargetField::name).toArray(String[]::new));
|
bootstrapArgs[1] = String.join(";", clazz.fields().stream().map(TargetField::name).toArray(String[]::new));
|
||||||
for (var i = 0; i < clazz.fields().size(); i++) {
|
for (var i = 0; i < clazz.fields().size(); i++) {
|
||||||
var field = clazz.fields().get(i);
|
var field = clazz.fields().get(i);
|
||||||
var fieldRef = new Handle(H_GETFIELD, clazz.getName(), field.name(), field.type().toDescriptor(), false);
|
var fieldRef = new Handle(H_GETFIELD, clazz.getName(), field.name(), field.type().toSignature(), false);
|
||||||
bootstrapArgs[i + 2] = fieldRef;
|
bootstrapArgs[i + 2] = fieldRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,10 +39,6 @@ public class FunNGenerator {
|
|||||||
public final List<TargetType> inParams;
|
public final List<TargetType> inParams;
|
||||||
public final List<TargetType> realParams;
|
public final List<TargetType> realParams;
|
||||||
|
|
||||||
public GenericParameters(TargetFunNType funNType) {
|
|
||||||
this(funNType.funNParams(), funNType.returnArguments());
|
|
||||||
}
|
|
||||||
|
|
||||||
public GenericParameters(List<TargetType> params, int numReturns) {
|
public GenericParameters(List<TargetType> params, int numReturns) {
|
||||||
this.realParams = params;
|
this.realParams = params;
|
||||||
this.inParams = flattenTypeParams(params);
|
this.inParams = flattenTypeParams(params);
|
||||||
@@ -98,7 +94,7 @@ public class FunNGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static String applySignature(TargetType a) { return a.toSignature(); }
|
private static String applySignature(TargetType a) { return a.toSignature(); }
|
||||||
private static String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("%s", a.toDescriptor()); }
|
private static String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("%s", applySignature(a)); }
|
||||||
|
|
||||||
public static String encodeType(TargetType type) {
|
public static String encodeType(TargetType type) {
|
||||||
if (type == null) return VOID;
|
if (type == null) return VOID;
|
||||||
@@ -124,7 +120,7 @@ public class FunNGenerator {
|
|||||||
superFunNMethodDescriptor.append(")V");
|
superFunNMethodDescriptor.append(")V");
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println(superFunNMethodSignature);
|
Codegen.logger.info(superFunNMethodSignature);
|
||||||
|
|
||||||
ClassWriter classWriter = new ClassWriter(0);
|
ClassWriter classWriter = new ClassWriter(0);
|
||||||
MethodVisitor methodVisitor;
|
MethodVisitor methodVisitor;
|
||||||
|
|||||||
@@ -1,46 +1,77 @@
|
|||||||
package de.dhbwstuttgart.core;
|
package de.dhbwstuttgart.core;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.util.Logger;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
public class ConsoleInterface {
|
|
||||||
private static final String directory = System.getProperty("user.dir");
|
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException, ClassNotFoundException {
|
public class ConsoleInterface {
|
||||||
List<File> input = new ArrayList<>();
|
|
||||||
List<File> classpath = new ArrayList<>();
|
public static Logger.LogLevel logLevel = Logger.LogLevel.ERROR;
|
||||||
String outputPath = null;
|
public static boolean writeLogFiles = false;
|
||||||
Iterator<String> it = Arrays.asList(args).iterator();
|
|
||||||
if(args.length == 0){
|
public static void main(String[] args) throws IOException, ClassNotFoundException {
|
||||||
System.out.println("No input files given. Get help with --help");
|
List<File> input = new ArrayList<>();
|
||||||
System.exit(1);
|
List<File> classpath = new ArrayList<>();
|
||||||
}else if(args.length == 1 && args[0].equals("--help")){
|
String outputPath = null;
|
||||||
System.out.println("Usage: javatx [OPTION]... [FILE]...\n" +
|
Iterator<String> it = Arrays.asList(args).iterator();
|
||||||
"\t-cp\tSet Classpath\n" +
|
Optional<Integer> serverPort = Optional.empty();
|
||||||
"\t-d\tSet destination directory");
|
Optional<String> unifyServer = Optional.empty();
|
||||||
System.exit(1);
|
|
||||||
|
if (args.length == 0) {
|
||||||
|
System.out.println("No input files given. Get help with --help");
|
||||||
|
System.exit(1);
|
||||||
|
} else if (args.length == 1 && args[0].equals("--help")) {
|
||||||
|
System.out.println("Usage: javatx [OPTION]... [FILE]...\n" +
|
||||||
|
"\t-cp\tSet Classpath\n" +
|
||||||
|
"\t-d\tSet destination directory\n" +
|
||||||
|
"\t[--server-mode <port>]\n" +
|
||||||
|
"\t[--unify-server <url>]\n" +
|
||||||
|
"\t[--write-logs]\n" +
|
||||||
|
"\t[-v|-vv-|-vvv]");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
while (it.hasNext()) {
|
||||||
|
String arg = it.next();
|
||||||
|
if (arg.equals("-d")) {
|
||||||
|
outputPath = it.next();
|
||||||
|
} else if (arg.startsWith("-d")) {
|
||||||
|
outputPath = arg.substring(2);
|
||||||
|
} else if (arg.equals("-cp") || arg.equals("-classpath")) {
|
||||||
|
String[] cps = it.next().split(":");
|
||||||
|
for (String cp : cps) {
|
||||||
|
classpath.add(new File(cp));
|
||||||
}
|
}
|
||||||
while(it.hasNext()){
|
} else if (arg.equals("--server-mode")) {
|
||||||
String arg = it.next();
|
serverPort = Optional.of(Integer.parseInt(it.next()));
|
||||||
if(arg.equals("-d")){
|
} else if (arg.equals("--unify-server")) {
|
||||||
outputPath = it.next();
|
unifyServer = Optional.of(it.next());
|
||||||
}else if(arg.startsWith("-d")) {
|
} else if (arg.equals("--write-logs")) {
|
||||||
outputPath = arg.substring(2);
|
ConsoleInterface.writeLogFiles = true;
|
||||||
}else if(arg.equals("-cp") || arg.equals("-classpath")){
|
} else if (arg.startsWith("-v")) {
|
||||||
String[] cps = it.next().split(":");
|
logLevel = switch (arg) {
|
||||||
for(String cp : cps){
|
case "-v" -> Logger.LogLevel.WARNING;
|
||||||
classpath.add(new File(cp));
|
case "-vv" -> Logger.LogLevel.INFO;
|
||||||
}
|
case "-vvv" -> Logger.LogLevel.DEBUG;
|
||||||
}else{
|
default -> throw new IllegalArgumentException("Argument " + arg + " is not a valid verbosity level");
|
||||||
input.add(new File(arg));
|
};
|
||||||
}
|
} else {
|
||||||
}
|
input.add(new File(arg));
|
||||||
JavaTXCompiler compiler = new JavaTXCompiler(input, classpath, outputPath != null ? new File(outputPath) : null);
|
}
|
||||||
//compiler.typeInference();
|
}
|
||||||
compiler.generateBytecode();
|
|
||||||
}
|
if (serverPort.isPresent()) {
|
||||||
|
if (unifyServer.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, unifyServer);
|
||||||
|
//compiler.typeInference();
|
||||||
|
compiler.generateBytecode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
package de.dhbwstuttgart.core;
|
package de.dhbwstuttgart.core;
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.Codegen;
|
import de.dhbwstuttgart.bytecode.Codegen;
|
||||||
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
|
||||||
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
||||||
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
||||||
import de.dhbwstuttgart.exceptions.DebugException;
|
import de.dhbwstuttgart.exceptions.DebugException;
|
||||||
@@ -13,6 +12,7 @@ import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
|
|||||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SourceFileContext;
|
import de.dhbwstuttgart.parser.antlr.Java17Parser.SourceFileContext;
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
||||||
|
import de.dhbwstuttgart.server.SocketClient;
|
||||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
@@ -36,10 +36,13 @@ import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
|||||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
import de.dhbwstuttgart.typeinference.typeAlgo.TYPE;
|
import de.dhbwstuttgart.typeinference.typeAlgo.TYPE;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
|
||||||
import de.dhbwstuttgart.typeinference.unify.RuleSet;
|
import de.dhbwstuttgart.typeinference.unify.RuleSet;
|
||||||
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
|
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||||
import de.dhbwstuttgart.typeinference.unify.distributeVariance;
|
import de.dhbwstuttgart.typeinference.unify.distributeVariance;
|
||||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
|
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||||
@@ -50,6 +53,7 @@ import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl;
|
|||||||
import de.dhbwstuttgart.typeinference.unify.UnifyResultModel;
|
import de.dhbwstuttgart.typeinference.unify.UnifyResultModel;
|
||||||
import de.dhbwstuttgart.typeinference.unify.UnifyTaskModel;
|
import de.dhbwstuttgart.typeinference.unify.UnifyTaskModel;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.util.Logger;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@@ -62,41 +66,44 @@ import org.apache.commons.io.output.NullOutputStream;
|
|||||||
|
|
||||||
public class JavaTXCompiler {
|
public class JavaTXCompiler {
|
||||||
|
|
||||||
|
// do not use this in any code, that can be executed serverside!
|
||||||
|
public static PlaceholderRegistry defaultClientPlaceholderRegistry = new PlaceholderRegistry();
|
||||||
|
public static Logger defaultLogger = new Logger();
|
||||||
|
|
||||||
// public static JavaTXCompiler INSTANCE;
|
// public static JavaTXCompiler INSTANCE;
|
||||||
final CompilationEnvironment environment;
|
final CompilationEnvironment environment;
|
||||||
Boolean resultmodel = true;
|
Boolean resultmodel = true;
|
||||||
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
||||||
|
|
||||||
Boolean log = false; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll?
|
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
||||||
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
public final DirectoryClassLoader classLoader;
|
||||||
public final DirectoryClassLoader classLoader;
|
|
||||||
|
|
||||||
public final List<File> classPath;
|
public final List<File> classPath;
|
||||||
private final File outputPath;
|
private final File outputPath;
|
||||||
|
|
||||||
public final Map<String, FunNGenerator.GenericParameters> usedFunN = new HashMap<>();
|
private final Optional<String> unifyServer;
|
||||||
public final Set<Integer> usedFunNSuperTypes = new HashSet<>();
|
|
||||||
|
|
||||||
public Map<String, byte[]> auxiliaries = new HashMap<>();
|
|
||||||
|
|
||||||
public DirectoryClassLoader getClassLoader() {
|
public DirectoryClassLoader getClassLoader() {
|
||||||
return classLoader;
|
return classLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
|
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
|
||||||
this(Arrays.asList(sourceFile), List.of(), new File("."));
|
this(Arrays.asList(sourceFile), List.of(), new File("."), Optional.empty());
|
||||||
}
|
|
||||||
|
|
||||||
public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
|
|
||||||
this(sourceFile);
|
|
||||||
this.log = log;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException {
|
public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException {
|
||||||
this(sourceFiles, List.of(), new File("."));
|
this(sourceFiles, List.of(), new File("."), Optional.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
public JavaTXCompiler(List<File> sources, List<File> contextPath, File outputPath) throws IOException, ClassNotFoundException {
|
public JavaTXCompiler(List<File> sources, List<File> contextPath, File outputPath) throws IOException, ClassNotFoundException {
|
||||||
|
this(sources, contextPath, outputPath, Optional.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public JavaTXCompiler(List<File> sources, List<File> contextPath, File outputPath, Optional<String> unifyServer) throws IOException, ClassNotFoundException {
|
||||||
|
// ensure new default placeholder registry for tests
|
||||||
|
defaultClientPlaceholderRegistry = new PlaceholderRegistry();
|
||||||
|
|
||||||
|
this.unifyServer = unifyServer;
|
||||||
var path = new ArrayList<>(contextPath);
|
var path = new ArrayList<>(contextPath);
|
||||||
if (contextPath.isEmpty()) {
|
if (contextPath.isEmpty()) {
|
||||||
// When no contextPaths are given, the working directory is the sources root
|
// When no contextPaths are given, the working directory is the sources root
|
||||||
@@ -306,52 +313,51 @@ public class JavaTXCompiler {
|
|||||||
Set<Set<UnifyPair>> results = new HashSet<>();
|
Set<Set<UnifyPair>> results = new HashSet<>();
|
||||||
UnifyResultModel urm = null;
|
UnifyResultModel urm = null;
|
||||||
// urm.addUnifyResultListener(resultListener);
|
// urm.addUnifyResultListener(resultListener);
|
||||||
try {
|
logFile = logFile == null ? new FileWriter("log_" + sourceFiles.keySet().iterator().next().getName()) : logFile;
|
||||||
logFile = logFile == null ? new FileWriter(new File("log_" + sourceFiles.keySet().iterator().next().getName())) : logFile;
|
Logger logger = new Logger(logFile, "TypeInferenceAsync");
|
||||||
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, getClassLoader(), this);
|
UnifyContext context = new UnifyContext(logger, true, urm, usedTasks, defaultClientPlaceholderRegistry);
|
||||||
System.out.println(finiteClosure);
|
|
||||||
urm = new UnifyResultModel(cons, finiteClosure);
|
|
||||||
urm.addUnifyResultListener(resultListener);
|
|
||||||
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons);
|
|
||||||
|
|
||||||
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
|
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logger, getClassLoader(), this, context.placeholderRegistry());
|
||||||
UnifyType lhs, rhs;
|
logger.info(finiteClosure.toString());
|
||||||
if (((lhs = x.getLhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType) && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
|
urm = new UnifyResultModel(cons, finiteClosure);
|
||||||
((PlaceholderType) lhs).setInnerType(true);
|
urm.addUnifyResultListener(resultListener);
|
||||||
((PlaceholderType) rhs).setInnerType(true);
|
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons, context.placeholderRegistry());
|
||||||
}
|
|
||||||
return x;
|
|
||||||
|
|
||||||
};
|
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
|
||||||
logFile.write(unifyCons.toString());
|
UnifyType lhs, rhs;
|
||||||
unifyCons = unifyCons.map(distributeInnerVars);
|
if (((lhs = x.getLhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType) && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
|
||||||
logFile.write(unifyCons.toString());
|
((PlaceholderType) lhs).setInnerType(true);
|
||||||
TypeUnify unify = new TypeUnify();
|
((PlaceholderType) rhs).setInnerType(true);
|
||||||
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
|
|
||||||
logFile.write("FC:\\" + finiteClosure.toString() + "\n");
|
|
||||||
for (SourceFile f : this.sourceFiles.values()) {
|
|
||||||
logFile.write(ASTTypePrinter.print(f));
|
|
||||||
}
|
}
|
||||||
logFile.flush();
|
return x;
|
||||||
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 &&
|
logger.debug(unifyCons.toString());
|
||||||
* ((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));
|
unifyCons = unifyCons.map(distributeInnerVars);
|
||||||
*/
|
logger.debug(unifyCons.toString());
|
||||||
|
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
|
||||||
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
|
logger.debug("FC:\\" + finiteClosure.toString() + "\n");
|
||||||
// logFile, log);
|
for (SourceFile f : this.sourceFiles.values()) {
|
||||||
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
|
logger.debug(ASTTypePrinter.print(f));
|
||||||
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()/*
|
|
||||||
* .stream().map(x -> { Set<Set<UnifyPair>> ret = new HashSet<>(); for (Constraint<UnifyPair> y : x) { ret.add(new HashSet<>(y)); } return ret; }).collect(Collectors. toCollection(ArrayList::new))
|
|
||||||
*/;
|
|
||||||
unify.unifyAsync(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm, usedTasks);
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.err.println("kein LogFile");
|
|
||||||
}
|
}
|
||||||
|
// logFile.flush();
|
||||||
|
Set<PlaceholderType> varianceTPHold;
|
||||||
|
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||||
|
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH); varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { if (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
|
||||||
|
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) { ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType( )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType( )).getVariance()); } } return y; } ); } while (!varianceTPHold.equals(varianceTPH));
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
|
||||||
|
// logFile, log);
|
||||||
|
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
|
||||||
|
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()/*
|
||||||
|
* .stream().map(x -> { Set<Set<UnifyPair>> ret = new HashSet<>(); for (Constraint<UnifyPair> y : x) { ret.add(new HashSet<>(y)); } return ret; }).collect(Collectors. toCollection(ArrayList::new))
|
||||||
|
*/;
|
||||||
|
TypeUnify.unifyAsync(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
|
||||||
|
|
||||||
return urm;
|
return urm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,108 +377,105 @@ public class JavaTXCompiler {
|
|||||||
|
|
||||||
final ConstraintSet<Pair> cons = getConstraints(file);
|
final ConstraintSet<Pair> cons = getConstraints(file);
|
||||||
Set<Set<UnifyPair>> results = new HashSet<>();
|
Set<Set<UnifyPair>> results = new HashSet<>();
|
||||||
try {
|
PlaceholderRegistry placeholderRegistry = new PlaceholderRegistry();
|
||||||
var logFolder = new File(System.getProperty("user.dir") + "/logFiles/");
|
|
||||||
if (log) logFolder.mkdirs();
|
|
||||||
Writer logFile = log ? new FileWriter(new File(logFolder, "log_" + sourceFiles.keySet().iterator().next().getName())) : new OutputStreamWriter(new NullOutputStream());
|
|
||||||
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses.stream().toList(), logFile, classLoader, this);
|
|
||||||
System.out.println(finiteClosure);
|
|
||||||
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons);
|
|
||||||
System.out.println("xxx1");
|
|
||||||
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
|
|
||||||
UnifyType lhs, rhs;
|
|
||||||
if (((lhs = x.getLhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType) && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
|
|
||||||
((PlaceholderType) lhs).setInnerType(true);
|
|
||||||
((PlaceholderType) rhs).setInnerType(true);
|
|
||||||
}
|
|
||||||
return x;
|
|
||||||
|
|
||||||
};
|
var logFolder = new File(System.getProperty("user.dir") + "/logFiles/");
|
||||||
|
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");
|
||||||
|
|
||||||
logFile.write("Unify:" + unifyCons.toString());
|
FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses.stream().toList(), logger, classLoader, this, placeholderRegistry);
|
||||||
System.out.println("Unify:" + unifyCons.toString());
|
logger.info(finiteClosure.toString());
|
||||||
unifyCons = unifyCons.map(distributeInnerVars);
|
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons, placeholderRegistry);
|
||||||
logFile.write("\nUnify_distributeInnerVars: " + unifyCons.toString());
|
logger.info("xxx1");
|
||||||
TypeUnify unify = new TypeUnify();
|
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
|
||||||
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
|
UnifyType lhs, rhs;
|
||||||
logFile.write("FC:\\" + finiteClosure.toString() + "\n");
|
if (((lhs = x.getLhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType) && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
|
||||||
logFile.write(ASTTypePrinter.print(sf));
|
((PlaceholderType) lhs).setInnerType(true);
|
||||||
System.out.println(ASTTypePrinter.print(sf));
|
((PlaceholderType) rhs).setInnerType(true);
|
||||||
logFile.flush();
|
|
||||||
List<UnifyPair> andConstraintsSorted = unifyCons.getUndConstraints().stream()
|
|
||||||
.sorted(Comparator.comparing(UnifyPair::getPairOp).thenComparing(UnifyPair::getLhsType, Comparator.comparing(UnifyType::getName)))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
System.out.println(andConstraintsSorted);
|
|
||||||
|
|
||||||
Set<PlaceholderType> varianceTPHold;
|
|
||||||
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
|
||||||
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH); varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { if (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
|
|
||||||
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) { ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType( )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType( )).getVariance()); } } return y; } ); } while (!varianceTPHold.equals(varianceTPH));
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
|
|
||||||
// logFile, log);
|
|
||||||
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
|
|
||||||
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()// .stream().map(x -> {
|
|
||||||
/*
|
|
||||||
* Set<Set<UnifyPair>> ret = new HashSet<>(); for (Constraint<UnifyPair> y : x) { ret.add(new HashSet<>(y)); } return ret; }).collect(Collectors.toCollection(ArrayList::new))
|
|
||||||
*/;
|
|
||||||
if (resultmodel) {
|
|
||||||
/* UnifyResultModel Anfang */
|
|
||||||
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
|
|
||||||
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
|
|
||||||
urm.addUnifyResultListener(li);
|
|
||||||
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm, usedTasks);
|
|
||||||
//System.out.println("RESULT Final: " + li.getResults());
|
|
||||||
var finalResults = li.getResults().stream().sorted().toList();
|
|
||||||
int i = 0;
|
|
||||||
System.out.println("RESULT Final: ");
|
|
||||||
for (var result : finalResults){
|
|
||||||
System.out.println("Result: " + i++);
|
|
||||||
System.out.println(result.getSortedResults());
|
|
||||||
}
|
|
||||||
System.out.println("Constraints for Generated Generics: " + " ???");
|
|
||||||
logFile.write("RES_FINAL: " + li.getResults().toString() + "\n");
|
|
||||||
logFile.flush();
|
|
||||||
return li.getResults();
|
|
||||||
}
|
}
|
||||||
/* UnifyResultModel End */
|
return x;
|
||||||
else {
|
|
||||||
// Set<Set<UnifyPair>> result = unify.unify(unifyCons.getUndConstraints(),
|
|
||||||
// oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons,
|
|
||||||
// finiteClosure));
|
|
||||||
Set<Set<UnifyPair>> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons, finiteClosure), usedTasks);
|
|
||||||
System.out.println("RESULT: " + result);
|
|
||||||
logFile.write("RES: " + result.toString() + "\n");
|
|
||||||
logFile.flush();
|
|
||||||
results.addAll(result);
|
|
||||||
|
|
||||||
results = results.stream().map(x -> {
|
};
|
||||||
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> {
|
|
||||||
if (y.getPairOp() == PairOperator.SMALLERDOTWC)
|
logger.debug("Unify:" + unifyCons.toString());
|
||||||
y.setPairOp(PairOperator.EQUALSDOT);
|
logger.info("Unify:" + unifyCons.toString());
|
||||||
return y; // alle Paare a <.? b erden durch a =. b ersetzt
|
unifyCons = unifyCons.map(distributeInnerVars);
|
||||||
}).collect(Collectors.toCollection(HashSet::new)));
|
logger.debug("\nUnify_distributeInnerVars: " + unifyCons.toString());
|
||||||
if (res.isPresent()) {// wenn subst ein Erg liefert wurde was veraendert
|
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
|
||||||
return new TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure);
|
logger.debug("FC:\\" + finiteClosure.toString() + "\n");
|
||||||
} else
|
logger.debug(ASTTypePrinter.print(sf));
|
||||||
return x; // wenn nichts veraendert wurde wird x zurueckgegeben
|
logger.info(ASTTypePrinter.print(sf));
|
||||||
}).collect(Collectors.toCollection(HashSet::new));
|
// logFile.flush();
|
||||||
System.out.println("RESULT Final: " + results);
|
logger.info("Unify nach Oder-Constraints-Anpassung:" + unifyCons.toString());
|
||||||
System.out.println("Constraints for Generated Generics: " + " ???");
|
Set<PlaceholderType> varianceTPHold;
|
||||||
logFile.write("RES_FINAL: " + results.toString() + "\n");
|
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||||
logFile.flush();
|
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
||||||
logFile.write("PLACEHOLDERS: " + PlaceholderType.EXISTING_PLACEHOLDERS);
|
|
||||||
logFile.flush();
|
/*
|
||||||
}
|
* 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 &&
|
||||||
} catch (IOException e) {
|
* ((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));
|
||||||
System.err.println("kein LogFile");
|
*/
|
||||||
|
|
||||||
|
// 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 (unifyServer.isPresent()) {
|
||||||
|
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
|
||||||
|
UnifyContext context = new UnifyContext(logger, true, urm, usedTasks, placeholderRegistry);
|
||||||
|
SocketClient socketClient = new SocketClient(unifyServer.get());
|
||||||
|
return socketClient.execute(finiteClosure, cons, unifyCons, context);
|
||||||
}
|
}
|
||||||
return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList());
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -604,10 +607,6 @@ public class JavaTXCompiler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param path - output-Directory can be null, then class file output is in the same directory as the parsed source files
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public Map<JavaClassName, byte[]> generateBytecode(File sourceFile) throws ClassNotFoundException, IOException {
|
public Map<JavaClassName, byte[]> generateBytecode(File sourceFile) throws ClassNotFoundException, IOException {
|
||||||
var sf = sourceFiles.get(sourceFile);
|
var sf = sourceFiles.get(sourceFile);
|
||||||
if (sf.isGenerated()) return null;
|
if (sf.isGenerated()) return null;
|
||||||
@@ -649,12 +648,12 @@ public class JavaTXCompiler {
|
|||||||
var codegen = new Codegen(converter.convert(clazz), this, converter);
|
var codegen = new Codegen(converter.convert(clazz), this, converter);
|
||||||
var code = codegen.generate();
|
var code = codegen.generate();
|
||||||
generatedClasses.put(clazz.getClassName(), code);
|
generatedClasses.put(clazz.getClassName(), code);
|
||||||
|
converter.auxiliaries.forEach((name, source) -> {
|
||||||
|
generatedClasses.put(new JavaClassName(name), source);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
generatedGenerics.put(sf, converter.javaGenerics());
|
generatedGenerics.put(sf, converter.javaGenerics());
|
||||||
converter.generateFunNTypes();
|
converter.generateFunNTypes();
|
||||||
auxiliaries.forEach((name, source) -> {
|
|
||||||
generatedClasses.put(new JavaClassName(name), source);
|
|
||||||
});
|
|
||||||
return generatedClasses;
|
return generatedClasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -662,15 +661,15 @@ public class JavaTXCompiler {
|
|||||||
FileOutputStream output;
|
FileOutputStream output;
|
||||||
for (JavaClassName name : classFiles.keySet()) {
|
for (JavaClassName name : classFiles.keySet()) {
|
||||||
byte[] bytecode = classFiles.get(name);
|
byte[] bytecode = classFiles.get(name);
|
||||||
System.out.println("generating " + name + ".class file ...");
|
defaultLogger.info("generating " + name + ".class file ...");
|
||||||
var subPath = preserveHierarchy ? path : Path.of(path.toString(), name.getPackageName().split("\\.")).toFile();
|
var subPath = preserveHierarchy ? path : Path.of(path.toString(), name.getPackageName().split("\\.")).toFile();
|
||||||
File outputFile = new File(subPath, name.getClassName() + ".class");
|
File outputFile = new File(subPath, name.getClassName() + ".class");
|
||||||
outputFile.getAbsoluteFile().getParentFile().mkdirs();
|
outputFile.getAbsoluteFile().getParentFile().mkdirs();
|
||||||
System.out.println(outputFile);
|
defaultLogger.info(outputFile.toString());
|
||||||
output = new FileOutputStream(outputFile);
|
output = new FileOutputStream(outputFile);
|
||||||
output.write(bytecode);
|
output.write(bytecode);
|
||||||
output.close();
|
output.close();
|
||||||
System.out.println(name + ".class file generated");
|
defaultLogger.info(name + ".class file generated");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
31
src/main/java/de/dhbwstuttgart/core/JavaTXServer.java
Normal file
31
src/main/java/de/dhbwstuttgart/core/JavaTXServer.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package de.dhbwstuttgart.core;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.server.SocketServer;
|
||||||
|
|
||||||
|
public class JavaTXServer {
|
||||||
|
|
||||||
|
public static boolean isRunning = false;
|
||||||
|
|
||||||
|
final SocketServer socketServer;
|
||||||
|
|
||||||
|
public JavaTXServer(int port) {
|
||||||
|
this.socketServer = new SocketServer(port);
|
||||||
|
isRunning = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void listen() {
|
||||||
|
socketServer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void forceStop() {
|
||||||
|
try {
|
||||||
|
socketServer.stop();
|
||||||
|
}
|
||||||
|
catch (InterruptedException exception) {
|
||||||
|
System.err.println("Interrupted socketServer: " + exception);
|
||||||
|
}
|
||||||
|
isRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,7 +30,7 @@ public class CompilationEnvironment {
|
|||||||
public final PackageCrawler packageCrawler;
|
public final PackageCrawler packageCrawler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Imitiert die Environment beim Aufruf des JavaCompilers auf einer Menge von java-Dateien Die Environment enthält automatisch die Java Standard Library
|
* Imitiert die Environment beim Aufruf des JavaCompilers auf einer Menge von java-Dateien Die Environment enth<EFBFBD>lt automatisch die Java Standard Library
|
||||||
*
|
*
|
||||||
* @param sourceFiles die zu kompilierenden Dateien
|
* @param sourceFiles die zu kompilierenden Dateien
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -6,22 +6,18 @@ import java.nio.file.Path;
|
|||||||
|
|
||||||
public interface IByteArrayClassLoader {
|
public interface IByteArrayClassLoader {
|
||||||
|
|
||||||
Class<?> loadClass(String path) throws ClassNotFoundException;
|
Class loadClass(String path) throws ClassNotFoundException;
|
||||||
|
|
||||||
default Class<?> loadClass(byte[] code) {
|
default Class loadClass(byte[] code) {
|
||||||
return this.loadClass(null, code);
|
return this._defineClass(null, code, 0, code.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
default Class<?> loadClass(String name, byte[] code) {
|
default Class loadClass(Path path) throws IOException {
|
||||||
return this._defineClass(name, code, 0, code.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
default Class<?> loadClass(Path path) throws IOException {
|
|
||||||
var code = Files.readAllBytes(path);
|
var code = Files.readAllBytes(path);
|
||||||
return this._defineClass(null, code, 0, code.length);
|
return this._defineClass(null, code, 0, code.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class<?> findClass(String name) throws ClassNotFoundException;
|
public Class<?> findClass(String name) throws ClassNotFoundException;
|
||||||
|
|
||||||
Class<?> _defineClass(String name, byte[] code, int i, int length) throws ClassFormatError;
|
Class _defineClass(String name, byte[] code, int i, int length) throws ClassFormatError;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package de.dhbwstuttgart.exceptions;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Eine Runtime Exception, die für den Fall genutzt wird, dass eine Unifikation abgebrochen wird.
|
||||||
|
* Durch das Werfen einer Exception können Abbrüche auch aus Methodenaufrufen heraus
|
||||||
|
* geprüft werden, da zuvor nur ein return X; stattfinden würde.
|
||||||
|
*/
|
||||||
|
public class UnifyCancelException extends RuntimeException {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
|||||||
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
||||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.util.Logger;
|
||||||
import org.antlr.v4.runtime.CharStream;
|
import org.antlr.v4.runtime.CharStream;
|
||||||
import org.antlr.v4.runtime.CharStreams;
|
import org.antlr.v4.runtime.CharStreams;
|
||||||
import org.antlr.v4.runtime.CommonTokenStream;
|
import org.antlr.v4.runtime.CommonTokenStream;
|
||||||
@@ -17,6 +18,9 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class JavaTXParser {
|
public class JavaTXParser {
|
||||||
|
|
||||||
|
public static Logger logger = new Logger("Parser");
|
||||||
|
|
||||||
public static Java17Parser.SourceFileContext parse(File source) throws IOException, java.lang.ClassNotFoundException {
|
public static Java17Parser.SourceFileContext parse(File source) throws IOException, java.lang.ClassNotFoundException {
|
||||||
InputStream stream = new FileInputStream(source);
|
InputStream stream = new FileInputStream(source);
|
||||||
// DEPRECATED: ANTLRInputStream input = new ANTLRInputStream(stream);
|
// DEPRECATED: ANTLRInputStream input = new ANTLRInputStream(stream);
|
||||||
|
|||||||
@@ -1,4 +1,25 @@
|
|||||||
package de.dhbwstuttgart.parser;
|
package de.dhbwstuttgart.parser;
|
||||||
|
|
||||||
public record SourceLoc(String file, int line) {
|
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||||
|
|
||||||
|
public record SourceLoc(String file, int line) implements ISerializableData {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||||
|
var serialized = new SerialMap();
|
||||||
|
serialized.put("file", file);
|
||||||
|
serialized.put("line", line);
|
||||||
|
return serialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SourceLoc fromSerial(SerialMap data) {
|
||||||
|
return new SourceLoc(
|
||||||
|
data.getValue("file").getOf(String.class),
|
||||||
|
data.getValue("line").getOf(Integer.class)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
|||||||
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
|
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.*;
|
import de.dhbwstuttgart.typeinference.unify.model.*;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -26,16 +27,21 @@ public class FCGenerator {
|
|||||||
*
|
*
|
||||||
* @param availableClasses - Alle geparsten Klassen
|
* @param availableClasses - Alle geparsten Klassen
|
||||||
*/
|
*/
|
||||||
public static Set<UnifyPair> toUnifyFC(JavaTXCompiler compiler, Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException {
|
public static Set<UnifyPair> toUnifyFC(JavaTXCompiler compiler, Collection<ClassOrInterface> availableClasses, ClassLoader classLoader, PlaceholderRegistry placeholderRegistry) throws ClassNotFoundException {
|
||||||
return toFC(availableClasses, classLoader).stream().map(t -> UnifyTypeFactory.convert(compiler, t)).collect(Collectors.toSet());
|
return toFC(
|
||||||
|
availableClasses,
|
||||||
|
classLoader,
|
||||||
|
placeholderRegistry
|
||||||
|
).stream().map(t -> UnifyTypeFactory.convert(compiler, t, placeholderRegistry))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Set<Pair> toFC(Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException {
|
public static Set<Pair> toFC(Collection<ClassOrInterface> availableClasses, ClassLoader classLoader, PlaceholderRegistry placeholderRegistry) throws ClassNotFoundException {
|
||||||
HashSet<Pair> pairs = new HashSet<>();
|
HashSet<Pair> pairs = new HashSet<>();
|
||||||
//PL 2018-09-18: gtvs vor die for-Schleife gezogen, damit immer die gleichen Typeplaceholder eingesetzt werden.
|
//PL 2018-09-18: gtvs vor die for-Schleife gezogen, damit immer die gleichen Typeplaceholder eingesetzt werden.
|
||||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>();
|
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>();
|
||||||
for(ClassOrInterface cly : availableClasses){
|
for(ClassOrInterface cly : availableClasses){
|
||||||
List<Pair> newPairs = getSuperTypes(cly, availableClasses, gtvs, classLoader);
|
List<Pair> newPairs = getSuperTypes(cly, availableClasses, gtvs, classLoader, placeholderRegistry);
|
||||||
pairs.addAll(newPairs);
|
pairs.addAll(newPairs);
|
||||||
|
|
||||||
//For all Functional Interfaces FI: FunN$$<... args auf dem Functional Interface ...> <. FI is added to FC
|
//For all Functional Interfaces FI: FunN$$<... args auf dem Functional Interface ...> <. FI is added to FC
|
||||||
@@ -75,8 +81,13 @@ public class FCGenerator {
|
|||||||
* @param forType
|
* @param forType
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private static List<Pair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException {
|
private static List<Pair> getSuperTypes(
|
||||||
return getSuperTypes(forType, availableClasses, new HashMap<>(), classLoader);
|
ClassOrInterface forType,
|
||||||
|
Collection<ClassOrInterface> availableClasses,
|
||||||
|
ClassLoader classLoader,
|
||||||
|
PlaceholderRegistry placeholderRegistry
|
||||||
|
) throws ClassNotFoundException {
|
||||||
|
return getSuperTypes(forType, availableClasses, new HashMap<>(), classLoader, placeholderRegistry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -87,8 +98,13 @@ public class FCGenerator {
|
|||||||
* @return
|
* @return
|
||||||
* @throws ClassNotFoundException
|
* @throws ClassNotFoundException
|
||||||
*/
|
*/
|
||||||
private static List<Pair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses,
|
private static List<Pair> getSuperTypes(
|
||||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs, ClassLoader classLoader) throws ClassNotFoundException {
|
ClassOrInterface forType,
|
||||||
|
Collection<ClassOrInterface> availableClasses,
|
||||||
|
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs,
|
||||||
|
ClassLoader classLoader,
|
||||||
|
PlaceholderRegistry placeholderRegistry
|
||||||
|
) throws ClassNotFoundException {
|
||||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||||
//Die GTVs, die in forType hinzukommen:
|
//Die GTVs, die in forType hinzukommen:
|
||||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> newGTVs = new HashMap<>();
|
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> newGTVs = new HashMap<>();
|
||||||
@@ -147,7 +163,7 @@ public class FCGenerator {
|
|||||||
if(superClass.getClassName().equals(ASTFactory.createObjectClass().getClassName())){
|
if(superClass.getClassName().equals(ASTFactory.createObjectClass().getClassName())){
|
||||||
superTypes = Arrays.asList(new Pair(ASTFactory.createObjectType(), ASTFactory.createObjectType(), PairOperator.SMALLER));
|
superTypes = Arrays.asList(new Pair(ASTFactory.createObjectType(), ASTFactory.createObjectType(), PairOperator.SMALLER));
|
||||||
}else{
|
}else{
|
||||||
superTypes = getSuperTypes(superClass, availableClasses, newGTVs, classLoader);
|
superTypes = getSuperTypes(superClass, availableClasses, newGTVs, classLoader, placeholderRegistry);
|
||||||
}
|
}
|
||||||
|
|
||||||
retList.add(ret);
|
retList.add(ret);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
|
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.parser.JavaTXParser;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -150,7 +151,7 @@ public class StatementGenerator {
|
|||||||
} else {
|
} else {
|
||||||
type = methodparameters?
|
type = methodparameters?
|
||||||
TypePlaceholder.fresh(fp.getStart(), 1, false)
|
TypePlaceholder.fresh(fp.getStart(), 1, false)
|
||||||
: TypePlaceholder.fresh(fp.getStart(), 1, false);
|
: TypePlaceholder.fresh(fp.getStart());
|
||||||
}
|
}
|
||||||
ret.add(new FormalParameter(paramName, type, fp.getStart()));
|
ret.add(new FormalParameter(paramName, type, fp.getStart()));
|
||||||
localVars.put(paramName, type);
|
localVars.put(paramName, type);
|
||||||
@@ -259,7 +260,7 @@ public class StatementGenerator {
|
|||||||
ret.setStatement();
|
ret.setStatement();
|
||||||
return ret;
|
return ret;
|
||||||
default:
|
default:
|
||||||
System.out.println(stmt.getClass());
|
JavaTXParser.logger.info(stmt.getClass());
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1065,7 +1066,7 @@ public class StatementGenerator {
|
|||||||
List<Pattern> parameterList = new ArrayList<>();
|
List<Pattern> parameterList = new ArrayList<>();
|
||||||
for (IdentifierContext identifier : lambdaParams.identifier()) {
|
for (IdentifierContext identifier : lambdaParams.identifier()) {
|
||||||
Token offset = identifier.getStart();
|
Token offset = identifier.getStart();
|
||||||
parameterList.add(new FormalParameter(identifier.getText(), TypePlaceholder.fresh(offset, 1, false), offset));
|
parameterList.add(new FormalParameter(identifier.getText(), TypePlaceholder.fresh(offset), offset));
|
||||||
}
|
}
|
||||||
params = new ParameterList(parameterList, lambdaParams.getStart());
|
params = new ParameterList(parameterList, lambdaParams.getStart());
|
||||||
} else if (lambdaParams.formalParameterList() != null) {
|
} else if (lambdaParams.formalParameterList() != null) {
|
||||||
@@ -1075,7 +1076,7 @@ public class StatementGenerator {
|
|||||||
List<Pattern> parameterList = new ArrayList<>();
|
List<Pattern> parameterList = new ArrayList<>();
|
||||||
for (LambdaLVTIParameterContext param : lambdaParams.lambdaLVTIList().lambdaLVTIParameter()) {
|
for (LambdaLVTIParameterContext param : lambdaParams.lambdaLVTIList().lambdaLVTIParameter()) {
|
||||||
Token offset = param.getStart();
|
Token offset = param.getStart();
|
||||||
parameterList.add(new FormalParameter(param.identifier().getText(), TypePlaceholder.fresh(offset, 1, false), offset));
|
parameterList.add(new FormalParameter(param.identifier().getText(), TypePlaceholder.fresh(offset), offset));
|
||||||
}
|
}
|
||||||
params = new ParameterList(parameterList, lambdaParams.getStart());
|
params = new ParameterList(parameterList, lambdaParams.getStart());
|
||||||
} else {
|
} else {
|
||||||
@@ -1099,9 +1100,9 @@ public class StatementGenerator {
|
|||||||
block = lambdaGenerator.convert(expression.lambdaBody().block(), true);
|
block = lambdaGenerator.convert(expression.lambdaBody().block(), true);
|
||||||
}
|
}
|
||||||
List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>();
|
List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>();
|
||||||
funNParams.add(TypePlaceholder.fresh(expression.getStart(), -1, false));// ret-Type
|
funNParams.add(TypePlaceholder.fresh(expression.getStart()));// ret-Type
|
||||||
params.getFormalparalist().forEach(formalParameter -> // Für jeden Parameter einen TPH anfügen:
|
params.getFormalparalist().forEach(formalParameter -> // Für jeden Parameter einen TPH anfügen:
|
||||||
funNParams.add(TypePlaceholder.fresh(expression.getStart(), 1, false)));
|
funNParams.add(TypePlaceholder.fresh(expression.getStart())));
|
||||||
RefTypeOrTPHOrWildcardOrGeneric lambdaType = TypePlaceholder.fresh(expression.getStart());
|
RefTypeOrTPHOrWildcardOrGeneric lambdaType = TypePlaceholder.fresh(expression.getStart());
|
||||||
// RefType lambdaType = new
|
// RefType lambdaType = new
|
||||||
// RefType(reg.getName("Fun"+params.getFormalparalist().size()),
|
// RefType(reg.getName("Fun"+params.getFormalparalist().size()),
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public class TypeGenerator {
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
} else if (!typeContext.LBRACK().isEmpty()) { // ArrayType über eckige Klammer prüfen
|
} else if (!typeContext.LBRACK().isEmpty()) { // ArrayType über eckige Klammer prüfen
|
||||||
// System.out.println(unannTypeContext.getText());
|
// JavaTXParser.logger.info(unannTypeContext.getText());
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class JavaClassName {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gibt von einem Klassennamen nur den Namen der Klasse zurück
|
* Gibt von einem Klassennamen nur den Namen der Klasse zur<EFBFBD>ck
|
||||||
* Beispiel:
|
* Beispiel:
|
||||||
* java.lang.Object wird zu: Object
|
* java.lang.Object wird zu: Object
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import de.dhbwstuttgart.exceptions.NotImplementedException;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Speichert die Klassen für einen bestimmten Projektscope
|
* Speichert die Klassen f<EFBFBD>r einen bestimmten Projektscope
|
||||||
*/
|
*/
|
||||||
public class JavaClassRegistry{
|
public class JavaClassRegistry {
|
||||||
final Map<JavaClassName, Integer> existingClasses = new HashMap<>();
|
final Map<JavaClassName, Integer> existingClasses = new HashMap<>();
|
||||||
|
|
||||||
public JavaClassRegistry(Map<String, Integer> initialNames) {
|
public JavaClassRegistry(Map<String, Integer> initialNames) {
|
||||||
@@ -22,10 +22,6 @@ public class JavaClassRegistry{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<JavaClassName> getAllClassNames(){
|
|
||||||
return existingClasses.keySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addName(String className, int numberOfGenerics) {
|
public void addName(String className, int numberOfGenerics) {
|
||||||
existingClasses.put(new JavaClassName(className), numberOfGenerics);
|
existingClasses.put(new JavaClassName(className), numberOfGenerics);
|
||||||
}
|
}
|
||||||
|
|||||||
161
src/main/java/de/dhbwstuttgart/server/SocketClient.java
Normal file
161
src/main/java/de/dhbwstuttgart/server/SocketClient.java
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
package de.dhbwstuttgart.server;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import de.dhbwstuttgart.server.packet.IPacket;
|
||||||
|
import de.dhbwstuttgart.server.packet.IServerToClientPacket;
|
||||||
|
import de.dhbwstuttgart.server.packet.PacketContainer;
|
||||||
|
import de.dhbwstuttgart.server.packet.UnifyRequestPacket;
|
||||||
|
import de.dhbwstuttgart.server.packet.UnifyResultPacket;
|
||||||
|
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||||
|
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||||
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||||
|
import de.dhbwstuttgart.util.Logger;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import org.java_websocket.client.WebSocketClient;
|
||||||
|
import org.java_websocket.enums.ReadyState;
|
||||||
|
import org.java_websocket.handshake.ServerHandshake;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Client-side of the websocket
|
||||||
|
*/
|
||||||
|
public class SocketClient extends WebSocketClient {
|
||||||
|
|
||||||
|
public static Logger logger = new Logger("SocketClient");
|
||||||
|
|
||||||
|
// use a latch to wait until the connection is closed by the remote host
|
||||||
|
private final CountDownLatch closeLatch = new CountDownLatch(1);
|
||||||
|
// temporarily: The received unify result
|
||||||
|
// TODO: replace with uuid and future system, such that responses can be mapped by a uuid to fulfill a Future
|
||||||
|
private UnifyResultPacket unifyResultPacket;
|
||||||
|
|
||||||
|
public SocketClient(String url) {
|
||||||
|
super(URI.create(url), Map.of(
|
||||||
|
"packetProtocolVersion", SocketServer.packetProtocolVersion
|
||||||
|
));
|
||||||
|
// make sure, the url is in a valid format
|
||||||
|
final String regex = "^wss?://(\\w+(\\.\\w+)?)*:(\\d+)$";
|
||||||
|
final Matcher matcher = Pattern.compile(regex).matcher(url);
|
||||||
|
if (!matcher.find()) {
|
||||||
|
throw new RuntimeException("Provided string \"" + url + "\" is not a valid server URL! Use pattern ws(s?)://<host.name>:<port>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SocketClient(String host, int port, boolean secure) {
|
||||||
|
super(URI.create(String.format("%s://%s:%d/", secure ? "wss" : "ws", host, port)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main method for connecting, requesting and waiting for the server to unify.
|
||||||
|
* This is synchronized to prevent multiple webSockets connections at the moment, but it is not called from any
|
||||||
|
* thread except the main thread right now and is not necessary at all, probably. Maybe remove it later
|
||||||
|
*/
|
||||||
|
synchronized public List<ResultSet> execute(
|
||||||
|
FiniteClosure finiteClosure,
|
||||||
|
ConstraintSet<Pair> constraintSet,
|
||||||
|
ConstraintSet<UnifyPair> unifyConstraintSet,
|
||||||
|
UnifyContext context
|
||||||
|
) throws JsonProcessingException {
|
||||||
|
|
||||||
|
try {
|
||||||
|
// wait for the connection to be set up
|
||||||
|
this.connectBlocking();
|
||||||
|
// make sure the connection has been established successfully
|
||||||
|
if (this.getReadyState() != ReadyState.OPEN) {
|
||||||
|
throw new RuntimeException("WebSocket Client could not connect to remote host at " + this.uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
// send the unify task request
|
||||||
|
UnifyRequestPacket packet = new UnifyRequestPacket(finiteClosure, constraintSet, unifyConstraintSet, context.placeholderRegistry());
|
||||||
|
String json = PacketContainer.serialize(packet);
|
||||||
|
this.send(json);
|
||||||
|
|
||||||
|
// block the thread, until the connection is closed by the remote host (usually after sending the results)
|
||||||
|
this.waitUntilClosed();
|
||||||
|
// wait for the connection to fully close
|
||||||
|
this.closeBlocking();
|
||||||
|
} catch (InterruptedException exception) {
|
||||||
|
System.err.println("Server connection interrupted: " + exception);
|
||||||
|
this.notifyAll();
|
||||||
|
throw new RuntimeException("Aborted server connection", exception);
|
||||||
|
}
|
||||||
|
catch (Exception exception) {
|
||||||
|
throw new RuntimeException("Exception occurred in server connection: ", exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
// detect error cases, in which no error was thrown, but also no result was sent back from the server
|
||||||
|
if (this.unifyResultPacket == null) {
|
||||||
|
throw new RuntimeException("Did not receive server response but closed connection already");
|
||||||
|
}
|
||||||
|
|
||||||
|
return unifyResultPacket.getResultSet(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specific client-side implementations to handle incoming packets
|
||||||
|
*/
|
||||||
|
protected void handleReceivedPacket(IPacket packet) {
|
||||||
|
if (packet instanceof IServerToClientPacket serverToClientPacket) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
serverToClientPacket.onHandle(this.getConnection(), this);
|
||||||
|
}
|
||||||
|
catch (Exception exception) {
|
||||||
|
this.closeLatch.countDown();
|
||||||
|
this.close();
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.println("Received package of invalid type + " + packet.getClass().getName());
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUnifyResultSets(UnifyResultPacket unifyResultPacket) {
|
||||||
|
this.unifyResultPacket = unifyResultPacket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOpen(ServerHandshake handshakedata) {
|
||||||
|
logger.info("Connected to server with status " + handshakedata.getHttpStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMessage(String message) {
|
||||||
|
// logger.info("received: " + message);
|
||||||
|
IPacket packet = PacketContainer.deserialize(message);
|
||||||
|
this.handleReceivedPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClose(int code, String reason, boolean remote) {
|
||||||
|
logger.info(
|
||||||
|
"Disconnected from server " +
|
||||||
|
"with code " + code + " " +
|
||||||
|
(reason.isEmpty() ? "" : "and reason " + reason + " ") +
|
||||||
|
"(closed by remote: " + remote + ")"
|
||||||
|
);
|
||||||
|
this.closeLatch.countDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Exception e) {
|
||||||
|
logger.error("Error: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void waitUntilClosed() throws InterruptedException {
|
||||||
|
closeLatch.await();
|
||||||
|
}
|
||||||
|
}
|
||||||
205
src/main/java/de/dhbwstuttgart/server/SocketServer.java
Normal file
205
src/main/java/de/dhbwstuttgart/server/SocketServer.java
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
package de.dhbwstuttgart.server;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
import de.dhbwstuttgart.server.packet.ErrorPacket;
|
||||||
|
import de.dhbwstuttgart.server.packet.IClientToServerPacket;
|
||||||
|
import de.dhbwstuttgart.server.packet.IPacket;
|
||||||
|
import de.dhbwstuttgart.server.packet.MessagePacket;
|
||||||
|
import de.dhbwstuttgart.server.packet.PacketContainer;
|
||||||
|
import de.dhbwstuttgart.util.Logger;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import org.java_websocket.WebSocket;
|
||||||
|
import org.java_websocket.handshake.ClientHandshake;
|
||||||
|
import org.java_websocket.server.WebSocketServer;
|
||||||
|
|
||||||
|
public class SocketServer extends WebSocketServer {
|
||||||
|
|
||||||
|
public static Logger logger = new Logger("SocketServer");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increase this every time a breaking change to the server communication is done.
|
||||||
|
* This will prevent errors when server version and client version do not match.
|
||||||
|
*/
|
||||||
|
public static final String packetProtocolVersion = "1";
|
||||||
|
|
||||||
|
public SocketServer(int port) {
|
||||||
|
super(new InetSocketAddress(port));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOpen(WebSocket webSocket, ClientHandshake clientHandshake) {
|
||||||
|
String ppv = clientHandshake.getFieldValue("packetProtocolVersion");
|
||||||
|
if (!ppv.equals(packetProtocolVersion)) {
|
||||||
|
try {
|
||||||
|
ErrorPacket errorPacket = ErrorPacket.create(
|
||||||
|
"Mismatch in packet protocol version! Client (you): " + ppv + " and Server (me): " + packetProtocolVersion,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
webSocket.send(PacketContainer.serialize(errorPacket));
|
||||||
|
}
|
||||||
|
catch (JsonProcessingException exception) {
|
||||||
|
System.err.println("Failed to serialize json: " + exception);
|
||||||
|
}
|
||||||
|
webSocket.close(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SocketData socketData = new SocketData(UUID.randomUUID().toString());
|
||||||
|
webSocket.setAttachment(socketData);
|
||||||
|
logger.info("New connection: " + socketData.id + " (with ppv " + ppv + ")");
|
||||||
|
|
||||||
|
try {
|
||||||
|
sendMessage(webSocket, "Welcome to the server!");
|
||||||
|
|
||||||
|
// wait 10 seconds for the client to send a task and close the connection if nothing has been received until then
|
||||||
|
try (ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor()) {
|
||||||
|
Runnable task = () -> {
|
||||||
|
if (webSocket.<SocketData>getAttachment().unhandledTasks.get() == 0 || !webSocket.isOpen()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendMessage(webSocket, "No task received after 10 seconds. Closing connection...");
|
||||||
|
webSocket.close();
|
||||||
|
};
|
||||||
|
executor.schedule(task, 10, TimeUnit.SECONDS);
|
||||||
|
executor.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
// and finally, when your program wants to exit
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.exception(e);
|
||||||
|
webSocket.close(1, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClose(WebSocket webSocket, int code, String reason, boolean remote) {
|
||||||
|
SocketData socketData = webSocket.getAttachment();
|
||||||
|
logger.info("Connection closed: " + socketData.id);
|
||||||
|
logger.info(
|
||||||
|
"Disconnected client " + socketData.id + " " +
|
||||||
|
"with code " + code + " " +
|
||||||
|
(reason.isEmpty() ? "" : "and reason " + reason + " ") +
|
||||||
|
"(closed by client: " + remote + ")"
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMessage(WebSocket webSocket, String s) {
|
||||||
|
// logger.info("Received: " + s.substring(0, 50));
|
||||||
|
IPacket reconstructedPacket = PacketContainer.deserialize(s);
|
||||||
|
try {
|
||||||
|
this.onPacketReceived(webSocket, reconstructedPacket);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
logger.exception(e);
|
||||||
|
this.log("Error on processing incoming package: " + e.getMessage(), webSocket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(WebSocket webSocket, Exception e) {
|
||||||
|
logger.exception(e);
|
||||||
|
log(e.getMessage(), webSocket);
|
||||||
|
webSocket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
logger.info("Websocket server started on port " + this.getPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A shorthand method for sending informational messages to the client
|
||||||
|
*/
|
||||||
|
public void sendMessage(WebSocket webSocket, String text) {
|
||||||
|
try {
|
||||||
|
MessagePacket message = new MessagePacket();
|
||||||
|
message.message = text;
|
||||||
|
webSocket.send(PacketContainer.serialize(message));
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("Failed to send message: " + text);
|
||||||
|
logger.exception(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A shorthand method for sending error messages to the client
|
||||||
|
*/
|
||||||
|
public void sendError(WebSocket webSocket, String text) {
|
||||||
|
try {
|
||||||
|
ErrorPacket error = new ErrorPacket();
|
||||||
|
error.error = text;
|
||||||
|
webSocket.send(PacketContainer.serialize(error));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.exception(e);
|
||||||
|
log("Failed to send error: " + text, webSocket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server-side implementation on how to handle certain packets when received
|
||||||
|
*/
|
||||||
|
private void onPacketReceived(WebSocket webSocket, IPacket packet) throws JsonProcessingException {
|
||||||
|
SocketData socketData = webSocket.getAttachment();
|
||||||
|
|
||||||
|
// limit the amount of tasks per connection
|
||||||
|
final int maxTasks = 100;
|
||||||
|
if (socketData.totalTasks.get() >= maxTasks) {
|
||||||
|
sendError(webSocket, "Exceeded the maximum amount of " + maxTasks + " tasks per session");
|
||||||
|
webSocket.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// only allow packets, that are meant to be handled by the server
|
||||||
|
if (!(packet instanceof IClientToServerPacket clientToServerPacket)) {
|
||||||
|
sendMessage(webSocket, "The package of type " + packet.getClass().getName() + " is not handled by the server!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the socket data
|
||||||
|
socketData.unhandledTasks.incrementAndGet();
|
||||||
|
socketData.totalTasks.incrementAndGet();
|
||||||
|
|
||||||
|
// add the packet to the queue, so it can be started by the worker
|
||||||
|
CompletableFuture.runAsync(() -> {
|
||||||
|
clientToServerPacket.onHandle(webSocket, this);
|
||||||
|
|
||||||
|
// if the websocket has 0 unhandled Tasks, close the connection
|
||||||
|
int remainingUnhandledTasks = socketData.unhandledTasks.decrementAndGet();
|
||||||
|
if (remainingUnhandledTasks <= 0) {
|
||||||
|
sendMessage(webSocket, "All requested tasks finished! Closing connection...");
|
||||||
|
webSocket.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void log(String msg, WebSocket webSocket) {
|
||||||
|
SocketData socketData = webSocket == null ? new SocketData("???") : webSocket.getAttachment();
|
||||||
|
logger.info("["+socketData.id+"] " + msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The data that is associated server-side with any connected client.
|
||||||
|
* This makes it possible to store information that can be mapped to any existing connection.
|
||||||
|
*/
|
||||||
|
public static class SocketData {
|
||||||
|
|
||||||
|
public final String id;
|
||||||
|
public final AtomicInteger unhandledTasks = new AtomicInteger(0);
|
||||||
|
public final AtomicInteger totalTasks = new AtomicInteger(0);
|
||||||
|
|
||||||
|
public SocketData(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package de.dhbwstuttgart.server.packet;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import de.dhbwstuttgart.server.SocketClient;
|
||||||
|
import de.dhbwstuttgart.server.SocketServer;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialUUID;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialValue;
|
||||||
|
import org.java_websocket.WebSocket;
|
||||||
|
|
||||||
|
public class DebugPacket implements IClientToServerPacket, IServerToClientPacket {
|
||||||
|
|
||||||
|
public SerialUUID a1;
|
||||||
|
public SerialUUID a2;
|
||||||
|
public SerialMap b1;
|
||||||
|
public SerialMap b2;
|
||||||
|
public SerialList<? extends ISerialNode> c1;
|
||||||
|
public SerialList<? extends ISerialNode> c2;
|
||||||
|
public SerialValue<?> d1;
|
||||||
|
public SerialValue<?> d2;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void onHandle(WebSocket webSocket, SocketClient socketServer) {}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void onHandle(WebSocket webSocket, SocketServer socketServer) {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package de.dhbwstuttgart.server.packet;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import de.dhbwstuttgart.server.SocketClient;
|
||||||
|
import de.dhbwstuttgart.server.SocketServer;
|
||||||
|
import org.java_websocket.WebSocket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A packet to send simple error messages between the client and the server
|
||||||
|
*/
|
||||||
|
public class ErrorPacket implements IClientToServerPacket, IServerToClientPacket {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The error endpoint for messages from the server, that should be logged out outputted
|
||||||
|
*/
|
||||||
|
public String error;
|
||||||
|
public boolean isFatal;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public static ErrorPacket create(String error, boolean isFatal) {
|
||||||
|
ErrorPacket packet = new ErrorPacket();
|
||||||
|
packet.error = error;
|
||||||
|
packet.isFatal = isFatal;
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void onHandle(WebSocket webSocket, SocketClient socketClient) {
|
||||||
|
System.err.println("[socket] " + "ErrorPacket: " + this.error);
|
||||||
|
if (this.isFatal) {
|
||||||
|
throw new RuntimeException("Received fatal error from server: " + this.error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
|
||||||
|
socketServer.log("ErrorPacket: " + this.error, webSocket);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package de.dhbwstuttgart.server.packet;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import de.dhbwstuttgart.server.SocketServer;
|
||||||
|
import org.java_websocket.WebSocket;
|
||||||
|
|
||||||
|
public interface IClientToServerPacket extends IPacket {
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
void onHandle(WebSocket webSocket, SocketServer socketServer);
|
||||||
|
|
||||||
|
}
|
||||||
12
src/main/java/de/dhbwstuttgart/server/packet/IPacket.java
Normal file
12
src/main/java/de/dhbwstuttgart/server/packet/IPacket.java
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package de.dhbwstuttgart.server.packet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The shared interface for all packet of the client-server connection.
|
||||||
|
* A packet must always:
|
||||||
|
* - Have a default / no-parameter constructor
|
||||||
|
* - Have only serializable public properties (or disable them via jackson annotations)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface IPacket {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package de.dhbwstuttgart.server.packet;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import de.dhbwstuttgart.server.SocketClient;
|
||||||
|
import org.java_websocket.WebSocket;
|
||||||
|
|
||||||
|
public interface IServerToClientPacket extends IPacket {
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
void onHandle(WebSocket webSocket, SocketClient socketClient);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package de.dhbwstuttgart.server.packet;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import de.dhbwstuttgart.server.SocketClient;
|
||||||
|
import de.dhbwstuttgart.server.SocketServer;
|
||||||
|
import org.java_websocket.WebSocket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A fallback packet that is generated, if the received json could not be mapped to an existing package
|
||||||
|
*/
|
||||||
|
public class InvalidPacket implements IClientToServerPacket, IServerToClientPacket {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If available, the error that caused this package to appear
|
||||||
|
*/
|
||||||
|
public String error = "<unknown error>";
|
||||||
|
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void onHandle(WebSocket webSocket, SocketClient socketClient) {
|
||||||
|
System.err.println("[socket] " + "InvalidPacket: " + this.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
|
||||||
|
socketServer.log("InvalidPacket: " + this.error, webSocket);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package de.dhbwstuttgart.server.packet;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import de.dhbwstuttgart.server.SocketClient;
|
||||||
|
import de.dhbwstuttgart.server.SocketServer;
|
||||||
|
import org.java_websocket.WebSocket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A packet to send simple informational messages between the client and the server
|
||||||
|
*/
|
||||||
|
public class MessagePacket implements IClientToServerPacket, IServerToClientPacket {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The informational message from the server, that should be logged out outputted
|
||||||
|
*/
|
||||||
|
public String message;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public static MessagePacket create(String message) {
|
||||||
|
MessagePacket packet = new MessagePacket();
|
||||||
|
packet.message = message;
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void onHandle(WebSocket webSocket, SocketClient socketClient) {
|
||||||
|
System.err.println("[socket] " + this.message);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
|
||||||
|
socketServer.log(this.message, webSocket);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package de.dhbwstuttgart.server.packet;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import de.dhbwstuttgart.util.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A wrapper for the packet to ensure correct serialization/deserialization and make it possible to detect the matching
|
||||||
|
* packet type for deserialization.
|
||||||
|
*/
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
public class PacketContainer {
|
||||||
|
|
||||||
|
// The jackson serializer / deserializer tool
|
||||||
|
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The available packet types. The one type that is represented in the JSON should always be the ONLY non-null value.
|
||||||
|
* They have to be public (for the moment) to let jackson fill them in while deserializing
|
||||||
|
*/
|
||||||
|
public ErrorPacket errorPacket = null;
|
||||||
|
public MessagePacket messagePacket = null;
|
||||||
|
public InvalidPacket invalidPacket = null;
|
||||||
|
public UnifyRequestPacket unifyRequestPacket = null;
|
||||||
|
public UnifyResultPacket unifyResultPacket = null;
|
||||||
|
public DebugPacket debugPacket = null;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the JSON string for the given packet
|
||||||
|
*
|
||||||
|
* @param packet The packet to serialize
|
||||||
|
* @return The json representation of the packet
|
||||||
|
*/
|
||||||
|
public static String serialize(IPacket packet) throws JsonProcessingException {
|
||||||
|
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||||
|
PacketContainer container = new PacketContainer();
|
||||||
|
|
||||||
|
if (packet instanceof ErrorPacket)
|
||||||
|
container.errorPacket = (ErrorPacket) packet;
|
||||||
|
else if (packet instanceof MessagePacket)
|
||||||
|
container.messagePacket = (MessagePacket) packet;
|
||||||
|
else if (packet instanceof UnifyRequestPacket)
|
||||||
|
container.unifyRequestPacket = (UnifyRequestPacket) packet;
|
||||||
|
else if (packet instanceof UnifyResultPacket)
|
||||||
|
container.unifyResultPacket = (UnifyResultPacket) packet;
|
||||||
|
else if (packet instanceof DebugPacket)
|
||||||
|
container.debugPacket = (DebugPacket) packet;
|
||||||
|
// Add new packets here and in the deserialize method
|
||||||
|
|
||||||
|
return objectMapper.writeValueAsString(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the JSON string to generate the matching packet object
|
||||||
|
*
|
||||||
|
* @param json The serialized representation of a packet container
|
||||||
|
* @return The deserialized Packet object
|
||||||
|
*/
|
||||||
|
public static IPacket deserialize(String json) {
|
||||||
|
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||||
|
|
||||||
|
try {
|
||||||
|
PacketContainer container = objectMapper.readValue(json, PacketContainer.class);
|
||||||
|
|
||||||
|
if (container.errorPacket != null)
|
||||||
|
return container.errorPacket;
|
||||||
|
if (container.messagePacket != null)
|
||||||
|
return container.messagePacket;
|
||||||
|
if (container.invalidPacket != null)
|
||||||
|
return container.invalidPacket;
|
||||||
|
if (container.unifyRequestPacket != null)
|
||||||
|
return container.unifyRequestPacket;
|
||||||
|
if (container.unifyResultPacket != null)
|
||||||
|
return container.unifyResultPacket;
|
||||||
|
if (container.debugPacket != null)
|
||||||
|
return container.debugPacket;
|
||||||
|
// Add new packets here and in the serialize method
|
||||||
|
|
||||||
|
throw new RuntimeException("Cannot map received json to any known packet class");
|
||||||
|
} catch (Exception e) {
|
||||||
|
(new Logger()).exception(e);
|
||||||
|
InvalidPacket packet = new InvalidPacket();
|
||||||
|
packet.error = e.getMessage();
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
package de.dhbwstuttgart.server.packet;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import de.dhbwstuttgart.server.SocketServer;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialValue;
|
||||||
|
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||||
|
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyResultModel;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyTaskModel;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
|
||||||
|
import de.dhbwstuttgart.util.Logger;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
import org.java_websocket.WebSocket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A packet to send all required data for the unification algorithm to the server and request the unification
|
||||||
|
*/
|
||||||
|
public class UnifyRequestPacket implements IClientToServerPacket {
|
||||||
|
|
||||||
|
public SerialMap finiteClosure;
|
||||||
|
public SerialMap constraintSet;
|
||||||
|
public SerialMap unifyConstraintSet;
|
||||||
|
public SerialMap serialKeyStorage;
|
||||||
|
public SerialValue<?> placeholders;
|
||||||
|
public SerialList<SerialMap> factoryplaceholders;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private KeyStorage keyStorage = new KeyStorage();
|
||||||
|
@JsonIgnore
|
||||||
|
private boolean keyStorageLoaded = false;
|
||||||
|
|
||||||
|
public UnifyRequestPacket() {}
|
||||||
|
|
||||||
|
public UnifyRequestPacket(
|
||||||
|
FiniteClosure finiteClosure,
|
||||||
|
ConstraintSet<Pair> constraintSet,
|
||||||
|
ConstraintSet<UnifyPair> unifyConstraintSet,
|
||||||
|
PlaceholderRegistry placeholderRegistry
|
||||||
|
) {
|
||||||
|
// store contraint and finite closure
|
||||||
|
this.finiteClosure = finiteClosure.toSerial(keyStorage);
|
||||||
|
this.constraintSet = constraintSet.toSerial(keyStorage);
|
||||||
|
this.unifyConstraintSet = unifyConstraintSet.toSerial(keyStorage);
|
||||||
|
// store placeholder registry
|
||||||
|
var serialRegistry = placeholderRegistry.toSerial(keyStorage);
|
||||||
|
this.placeholders = serialRegistry.getValue("ph");
|
||||||
|
this.factoryplaceholders = serialRegistry.getList("factoryPh").assertListOfMaps();
|
||||||
|
// store referenced objects separately
|
||||||
|
this.serialKeyStorage = keyStorage.toSerial(keyStorage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void loadKeyStorage(UnifyContext context) {
|
||||||
|
if (!keyStorageLoaded) {
|
||||||
|
keyStorageLoaded = true;
|
||||||
|
keyStorage = KeyStorage.fromSerial(this.serialKeyStorage, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private FiniteClosure retrieveFiniteClosure(UnifyContext context) {
|
||||||
|
this.loadKeyStorage(context);
|
||||||
|
return FiniteClosure.fromSerial(this.finiteClosure, context, keyStorage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private ConstraintSet<Pair> retrieveConstraintSet(UnifyContext context) {
|
||||||
|
this.loadKeyStorage(context);
|
||||||
|
return ConstraintSet.fromSerial(this.constraintSet, context, Pair.class, keyStorage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private ConstraintSet<UnifyPair> retrieveUnifyConstraintSet(UnifyContext context) {
|
||||||
|
this.loadKeyStorage(context);
|
||||||
|
return ConstraintSet.fromSerial(this.unifyConstraintSet, context, UnifyPair.class, keyStorage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
|
||||||
|
socketServer.sendMessage(webSocket, "You requested a unify! Please wait until I calculated everything...");
|
||||||
|
SocketServer.logger.info("Client " + webSocket.<SocketServer.SocketData>getAttachment().id + " requested a unification. Starting now...");
|
||||||
|
|
||||||
|
try {
|
||||||
|
var placeholderRegistry = new PlaceholderRegistry();
|
||||||
|
ArrayList<String> existingPlaceholders = (ArrayList) this.placeholders.getOf(ArrayList.class);
|
||||||
|
existingPlaceholders.forEach(placeholderRegistry::addPlaceholder);
|
||||||
|
|
||||||
|
var unifyContext = new UnifyContext(Logger.NULL_LOGGER, true,
|
||||||
|
new UnifyResultModel(new ConstraintSet<>(), new FiniteClosure(new HashSet<>(), Logger.NULL_LOGGER, placeholderRegistry)),
|
||||||
|
new UnifyTaskModel(), ForkJoinPool.commonPool(), placeholderRegistry
|
||||||
|
);
|
||||||
|
|
||||||
|
this.factoryplaceholders.stream()
|
||||||
|
.map(p -> (PlaceholderType)UnifyType.fromSerial(p, unifyContext))
|
||||||
|
.forEach(placeholderRegistry.UnifyTypeFactory_PLACEHOLDERS::add);
|
||||||
|
|
||||||
|
|
||||||
|
// start the unification algorithm from the received data
|
||||||
|
IFiniteClosure finiteClosure = this.retrieveFiniteClosure(unifyContext);
|
||||||
|
ConstraintSet<Pair> constraintSet = this.retrieveConstraintSet(unifyContext);
|
||||||
|
ConstraintSet<UnifyPair> unifyConstraintSet = this.retrieveUnifyConstraintSet(unifyContext);
|
||||||
|
|
||||||
|
var resultModel = new UnifyResultModel(constraintSet, finiteClosure);
|
||||||
|
UnifyResultListenerImpl resultListener = new UnifyResultListenerImpl();
|
||||||
|
resultModel.addUnifyResultListener(resultListener);
|
||||||
|
|
||||||
|
TypeUnify.unifyParallel(
|
||||||
|
unifyConstraintSet.getUndConstraints(),
|
||||||
|
unifyConstraintSet.getOderConstraints(),
|
||||||
|
finiteClosure,
|
||||||
|
unifyContext.newWithResultModel(resultModel)
|
||||||
|
);
|
||||||
|
|
||||||
|
var resultSets = resultListener.getResults();
|
||||||
|
|
||||||
|
SocketServer.logger.info("Finished unification for client " + webSocket.<SocketServer.SocketData>getAttachment().id);
|
||||||
|
socketServer.sendMessage(webSocket, "Unification finished. Found " + resultSets.size() + " result sets");
|
||||||
|
|
||||||
|
if (webSocket.isOpen()) {
|
||||||
|
UnifyResultPacket resultPacket = UnifyResultPacket.create(resultSets);
|
||||||
|
webSocket.send(PacketContainer.serialize(resultPacket));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SocketServer.logger.exception(e);
|
||||||
|
socketServer.log(e.getMessage(), webSocket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package de.dhbwstuttgart.server.packet;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import de.dhbwstuttgart.server.SocketClient;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||||
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||||
|
import java.util.List;
|
||||||
|
import org.java_websocket.WebSocket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A packet to send all calculated data from the unification algorithm back to the client
|
||||||
|
*/
|
||||||
|
public class UnifyResultPacket implements IServerToClientPacket {
|
||||||
|
|
||||||
|
public SerialList<ISerialNode> results;
|
||||||
|
public SerialMap keyStorage;
|
||||||
|
|
||||||
|
public static UnifyResultPacket create(List<ResultSet> resultSets) {
|
||||||
|
UnifyResultPacket serialized = new UnifyResultPacket();
|
||||||
|
KeyStorage keyStorage = new KeyStorage();
|
||||||
|
serialized.results = SerialList.fromMapped(resultSets, resultSet -> resultSet.toSerial(keyStorage));
|
||||||
|
serialized.keyStorage = keyStorage.toSerial(keyStorage);
|
||||||
|
return serialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public List<ResultSet> getResultSet(UnifyContext context) {
|
||||||
|
return this.results.assertListOfMaps().stream()
|
||||||
|
.map(resultData -> ResultSet.fromSerial(resultData, context)).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void onHandle(WebSocket webSocket, SocketClient socketClient) {
|
||||||
|
SocketClient.logger.info("[socket] Received unify result");
|
||||||
|
socketClient.setUnifyResultSets(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package de.dhbwstuttgart.server.packet.dataContainers;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||||
|
|
||||||
|
public interface ISerializableData {
|
||||||
|
|
||||||
|
public abstract ISerialNode toSerial(KeyStorage keyStorage);
|
||||||
|
|
||||||
|
public static Object fromSerial(SerialMap data, UnifyContext context) {
|
||||||
|
throw new NotImplementedException("Missing implementation of \"fromSerial\" for a serializable element");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
package de.dhbwstuttgart.server.packet.dataContainers;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
public class KeyStorage implements ISerializableData {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a unique identifier for every element, so it can be referenced in the json
|
||||||
|
*/
|
||||||
|
protected AtomicInteger identifierCount = new AtomicInteger();
|
||||||
|
/**
|
||||||
|
* Store the serialized element per identifier when serializing
|
||||||
|
*/
|
||||||
|
protected SerialMap serializedElements = new SerialMap();
|
||||||
|
/**
|
||||||
|
* Store the unserialized element per identifier when unserializing
|
||||||
|
*/
|
||||||
|
protected Map<String, ISerializableData> unserializedElements = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve or generate a new identifier for a constraint
|
||||||
|
*/
|
||||||
|
public String getIdentifier() {
|
||||||
|
return this.identifierCount.incrementAndGet() + "_";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given element identifier belongs to an element that was already serialized
|
||||||
|
*/
|
||||||
|
public boolean isAlreadySerialized(String identifier) {
|
||||||
|
return this.serializedElements.containsKey(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given element identifier belongs to a element that was already unserialized
|
||||||
|
*/
|
||||||
|
public boolean isAlreadyUnserialized(String identifier) {
|
||||||
|
return this.unserializedElements.containsKey(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a serialized element to prevent it from being serialized again
|
||||||
|
*/
|
||||||
|
public void putSerialized(String identifier, SerialMap serializedElement) {
|
||||||
|
this.serializedElements.put(identifier, serializedElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a serialized element
|
||||||
|
*/
|
||||||
|
public SerialMap getSerialized(String identifier) {
|
||||||
|
if (!this.serializedElements.containsKey(identifier)) {
|
||||||
|
throw new RuntimeException("No serialized element of identifier " + identifier + " available to get");
|
||||||
|
}
|
||||||
|
return this.serializedElements.getMap(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register an unserialized element to prevent it from being unserialized again
|
||||||
|
*/
|
||||||
|
public void putUnserialized(String identifier, ISerializableData element) {
|
||||||
|
this.unserializedElements.put(identifier, element);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve an unserialized element
|
||||||
|
*/
|
||||||
|
public <T extends ISerializableData> T getUnserialized(String identifier, Class<T> target) {
|
||||||
|
if (!this.unserializedElements.containsKey(identifier)) {
|
||||||
|
throw new RuntimeException("No unserialized element of identifier " + identifier + " available to get");
|
||||||
|
}
|
||||||
|
var element = this.unserializedElements.get(identifier);
|
||||||
|
if (target.isInstance(element)) {
|
||||||
|
return (T) element;
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Failed to get unserialized element from KeyStorage. Expected instance of " +
|
||||||
|
target.getName() + " but found " + element.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||||
|
SerialMap serialized = new SerialMap();
|
||||||
|
serialized.put("serializedElements", this.serializedElements);
|
||||||
|
return serialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static KeyStorage fromSerial(SerialMap data, UnifyContext context) {
|
||||||
|
var serializedConstraintsData = data.getMap("serializedElements");
|
||||||
|
var constraintContext = new KeyStorage();
|
||||||
|
for (var entry : serializedConstraintsData.entrySet()) {
|
||||||
|
if (entry.getValue() instanceof SerialMap valueMap) {
|
||||||
|
constraintContext.putSerialized(entry.getKey(), valueMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return constraintContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package de.dhbwstuttgart.server.packet.dataContainers.serialized;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the following classes for an intermediate serialized tree structure
|
||||||
|
*/
|
||||||
|
@JsonTypeInfo(
|
||||||
|
use = JsonTypeInfo.Id.NAME,
|
||||||
|
include = JsonTypeInfo.As.PROPERTY,
|
||||||
|
property = "_t"
|
||||||
|
)
|
||||||
|
@JsonSubTypes({
|
||||||
|
@JsonSubTypes.Type(value = SerialMap.class, name = "m"),
|
||||||
|
@JsonSubTypes.Type(value = SerialList.class, name = "l"),
|
||||||
|
@JsonSubTypes.Type(value = SerialValue.class, name = "v"),
|
||||||
|
@JsonSubTypes.Type(value = SerialUUID.class, name = "u")
|
||||||
|
})
|
||||||
|
public interface ISerialNode {
|
||||||
|
|
||||||
|
default <T extends ISerialNode> T assertType(Class<T> type) {
|
||||||
|
if (type.isInstance(this)) {
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Expected ISerialNode to be of type " + type.getName()
|
||||||
|
+ " but found " + this.getClass().getName() + " instead");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package de.dhbwstuttgart.server.packet.dataContainers.serialized;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class SerialList<I extends ISerialNode> extends ArrayList<I> implements ISerialNode {
|
||||||
|
public SerialList() {}
|
||||||
|
public SerialList(Collection<I> data) {
|
||||||
|
this.addAll(data);
|
||||||
|
}
|
||||||
|
public SerialList(Stream<I> data) {
|
||||||
|
this(data.toList());
|
||||||
|
}
|
||||||
|
public SerialList(I[] data) {
|
||||||
|
this(Arrays.stream(data).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
@JsonIgnore
|
||||||
|
public static <A extends ISerialNode> ArrayList<A> from(A ...values) {
|
||||||
|
ArrayList<A> list = new SerialList<>();
|
||||||
|
Collections.addAll(list, values);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
@JsonIgnore
|
||||||
|
public static <A,B extends ISerialNode> SerialList<B> fromMapped(Stream<A> data, Function<A,B> mapper) {
|
||||||
|
return new SerialList<>(data.map(mapper).toList());
|
||||||
|
}
|
||||||
|
@JsonIgnore
|
||||||
|
public static <A,B extends ISerialNode> SerialList<B> fromMapped(Collection<A> data, Function<A,B> mapper) {
|
||||||
|
return SerialList.fromMapped(data.stream(), mapper);
|
||||||
|
}
|
||||||
|
@JsonIgnore
|
||||||
|
public static <A,B extends ISerialNode> SerialList<B> fromMapped(A[] data, Function<A,B> mapper) {
|
||||||
|
return SerialList.fromMapped(Arrays.stream(data), mapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public SerialList<SerialMap> assertListOfMaps() {
|
||||||
|
if (this.isEmpty() || this.get(0) instanceof SerialMap) {
|
||||||
|
return (SerialList<SerialMap>) this;
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Required List to contain SerialMap elements but condition failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public SerialList<SerialList<?>> assertListOfLists() {
|
||||||
|
if (this.isEmpty() || this.get(0) instanceof SerialList) {
|
||||||
|
return (SerialList<SerialList<?>>) this;
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Required List to contain SerialList elements but condition failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public SerialList<SerialValue<?>> assertListOfValues() {
|
||||||
|
if (this.isEmpty() || this.get(0) instanceof SerialValue) {
|
||||||
|
return (SerialList<SerialValue<?>>) this;
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Required List to contain SerialValue elements but condition failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public SerialList<SerialUUID> assertListOfUUIDs() {
|
||||||
|
if (this.isEmpty() || this.get(0) instanceof SerialUUID) {
|
||||||
|
return (SerialList<SerialUUID>) this;
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Required List to contain SerialUUID elements but condition failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
package de.dhbwstuttgart.server.packet.dataContainers.serialized;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class SerialMap extends HashMap<String, ISerialNode> implements ISerialNode {
|
||||||
|
|
||||||
|
public SerialMap() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SerialMap(Map<String, ISerialNode> data) {
|
||||||
|
super(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void put(String key, Boolean value) {
|
||||||
|
this.put(key, new SerialValue<>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void put(String key, String value) {
|
||||||
|
this.put(key, new SerialValue<>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void put(String key, Number value) {
|
||||||
|
this.put(key, new SerialValue<>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private <T> T get(String key, Class<T> expectedType) {
|
||||||
|
if (!this.containsKey(key)) {
|
||||||
|
throw new RuntimeException("Missing required value " + key + " in ObjectMap");
|
||||||
|
}
|
||||||
|
var element = this.get(key);
|
||||||
|
if (element != null && element.getClass() != expectedType) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"Required value " + key + " to be of type " + expectedType.getName() + " but found " + element.getClass().getName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (T)element;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public SerialList<?> getList(String key) {
|
||||||
|
return this.get(key, SerialList.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@JsonIgnore
|
||||||
|
public SerialList<?> getListOrNull(String key) {
|
||||||
|
return this.containsKey(key) ? this.getList(key) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public SerialMap getMap(String key) {
|
||||||
|
return this.get(key, SerialMap.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@JsonIgnore
|
||||||
|
public SerialMap getMapOrNull(String key) {
|
||||||
|
return this.containsKey(key) ? this.getMap(key) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public SerialValue<?> getValue(String key) {
|
||||||
|
return this.get(key, SerialValue.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public SerialUUID getUUID(String key) {
|
||||||
|
return this.get(key, SerialUUID.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@JsonIgnore
|
||||||
|
public SerialUUID getUUIDOrNull(String key) {
|
||||||
|
return this.containsKey(key) ? this.getUUID(key) : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package de.dhbwstuttgart.server.packet.dataContainers.serialized;
|
||||||
|
|
||||||
|
public class SerialUUID implements ISerialNode {
|
||||||
|
|
||||||
|
public String uuid;
|
||||||
|
|
||||||
|
public SerialUUID() {}
|
||||||
|
|
||||||
|
public SerialUUID(String uuid) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package de.dhbwstuttgart.server.packet.dataContainers.serialized;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
|
||||||
|
public class SerialValue<T> implements ISerialNode {
|
||||||
|
public T value;
|
||||||
|
public static final SerialValue<Object> NULL = new SerialValue<>(null);
|
||||||
|
|
||||||
|
public SerialValue() {}
|
||||||
|
|
||||||
|
public SerialValue(T value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public <A> SerialValue<A> assertValueOf(Class<A> targetClass) {
|
||||||
|
if (this.value == null || targetClass.isInstance(this.value)) {
|
||||||
|
return (SerialValue<A>) this;
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Required Value to contain " + targetClass.getName() + " value but condition failed on" +
|
||||||
|
" type " + this.value.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public <A> A getOf(Class<A> targetClass) {
|
||||||
|
return this.assertValueOf(targetClass).value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,12 +6,10 @@ import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
|||||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
import de.dhbwstuttgart.target.tree.TargetGeneric;
|
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces
|
* Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces
|
||||||
@@ -33,7 +31,6 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
|||||||
private List<RefType> implementedInterfaces;
|
private List<RefType> implementedInterfaces;
|
||||||
private List<RefType> permittedSubtypes;
|
private List<RefType> permittedSubtypes;
|
||||||
private List<Constructor> constructors;
|
private List<Constructor> constructors;
|
||||||
private Set<GenericTypeVar> userDefinedGenerics;
|
|
||||||
|
|
||||||
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, Optional<Method> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, Boolean isFunctionalInterface, List<RefType> implementedInterfaces, List<RefType> permittedSubtypes, Token offset, String fileName) {
|
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, Optional<Method> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, Boolean isFunctionalInterface, List<RefType> implementedInterfaces, List<RefType> permittedSubtypes, Token offset, String fileName) {
|
||||||
super(offset);
|
super(offset);
|
||||||
@@ -202,22 +199,4 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(name);
|
return Objects.hash(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<GenericTypeVar> getUserDefinedGenerics() {
|
|
||||||
if (this.userDefinedGenerics != null) return this.userDefinedGenerics;
|
|
||||||
|
|
||||||
var genericsIter = getGenerics().iterator();
|
|
||||||
if (genericsIter.hasNext()) {
|
|
||||||
// Add empty set of generics to cache so that it doesn't try to calculate it later
|
|
||||||
this.userDefinedGenerics = new HashSet<>();
|
|
||||||
while (genericsIter.hasNext()) {
|
|
||||||
var next = genericsIter.next();
|
|
||||||
userDefinedGenerics.add(next);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.userDefinedGenerics = new HashSet<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.userDefinedGenerics;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ import java.util.*;
|
|||||||
|
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
|
||||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
|
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
|
||||||
//import sun.security.x509.X509CertInfo;
|
//import sun.security.x509.X509CertInfo;
|
||||||
|
|
||||||
public class SourceFile extends SyntaxTreeNode {
|
public class SourceFile extends SyntaxTreeNode {
|
||||||
@@ -20,7 +18,6 @@ public class SourceFile extends SyntaxTreeNode {
|
|||||||
private boolean isGenerated;
|
private boolean isGenerated;
|
||||||
|
|
||||||
public List<ClassOrInterface> availableClasses = new ArrayList<>();
|
public List<ClassOrInterface> availableClasses = new ArrayList<>();
|
||||||
public List<ASTToTargetAST.Generics> generics = new ArrayList<>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Die SourceFile repräsntiert eine zu einem Syntaxbaum eingelesene Java-Datei.
|
* Die SourceFile repräsntiert eine zu einem Syntaxbaum eingelesene Java-Datei.
|
||||||
@@ -43,10 +40,6 @@ public class SourceFile extends SyntaxTreeNode {
|
|||||||
this.imports = new HashSet<>(sf.imports);
|
this.imports = new HashSet<>(sf.imports);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addResultSet(ResultSet rs) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPackageName(String packageName) {
|
public void setPackageName(String packageName) {
|
||||||
this.pkgName = packageName;
|
this.pkgName = packageName;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package de.dhbwstuttgart.syntaxtree;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.util.Logger;
|
||||||
|
|
||||||
|
public class SyntaxTree {
|
||||||
|
|
||||||
|
public static Logger logger = new Logger("SyntaxTree");
|
||||||
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
package de.dhbwstuttgart.syntaxtree.factory;
|
package de.dhbwstuttgart.syntaxtree.factory;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
import de.dhbwstuttgart.core.JavaTXServer;
|
||||||
|
|
||||||
public class NameGenerator {
|
public class NameGenerator {
|
||||||
|
|
||||||
private static String strNextName = "A";
|
private static String strNextName = "A";
|
||||||
@@ -27,6 +30,10 @@ public class NameGenerator {
|
|||||||
// n�chster Name berechnen und in strNextName speichern
|
// n�chster Name berechnen und in strNextName speichern
|
||||||
inc( strNextName.length() - 1 );
|
inc( strNextName.length() - 1 );
|
||||||
|
|
||||||
|
if (JavaTXServer.isRunning) {
|
||||||
|
throw new RuntimeException("Using the NameGenerator on a server is not allowed");
|
||||||
|
}
|
||||||
|
JavaTXCompiler.defaultClientPlaceholderRegistry.addPlaceholder(strReturn);
|
||||||
return strReturn;
|
return strReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package de.dhbwstuttgart.syntaxtree.factory;
|
package de.dhbwstuttgart.syntaxtree.factory;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.SyntaxTree;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
|
||||||
|
import de.dhbwstuttgart.util.Logger;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -31,9 +34,13 @@ import org.antlr.v4.runtime.Token;
|
|||||||
|
|
||||||
public class UnifyTypeFactory {
|
public class UnifyTypeFactory {
|
||||||
|
|
||||||
private static ArrayList<PlaceholderType> PLACEHOLDERS = new ArrayList<>();
|
public static FiniteClosure generateFC(
|
||||||
|
List<ClassOrInterface> fromClasses,
|
||||||
public static FiniteClosure generateFC(List<ClassOrInterface> fromClasses, Writer logFile, ClassLoader classLoader, JavaTXCompiler compiler) throws ClassNotFoundException {
|
Logger logger,
|
||||||
|
ClassLoader classLoader,
|
||||||
|
JavaTXCompiler compiler,
|
||||||
|
PlaceholderRegistry placeholderRegistry
|
||||||
|
) throws ClassNotFoundException {
|
||||||
/*
|
/*
|
||||||
Die transitive Hülle muss funktionieren.
|
Die transitive Hülle muss funktionieren.
|
||||||
Man darf schreiben List<A> extends AL<A>
|
Man darf schreiben List<A> extends AL<A>
|
||||||
@@ -44,7 +51,7 @@ public class UnifyTypeFactory {
|
|||||||
Generell dürfen sie immer die gleichen Namen haben.
|
Generell dürfen sie immer die gleichen Namen haben.
|
||||||
TODO: die transitive Hülle bilden
|
TODO: die transitive Hülle bilden
|
||||||
*/
|
*/
|
||||||
return new FiniteClosure(FCGenerator.toUnifyFC(compiler, fromClasses, classLoader), logFile, compiler);
|
return new FiniteClosure(FCGenerator.toUnifyFC(compiler, fromClasses, classLoader, placeholderRegistry), logger, compiler, placeholderRegistry);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr, SourceLoc location){
|
public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr, SourceLoc location){
|
||||||
@@ -67,23 +74,23 @@ public class UnifyTypeFactory {
|
|||||||
* Convert from
|
* Convert from
|
||||||
* ASTType -> UnifyType
|
* ASTType -> UnifyType
|
||||||
*/
|
*/
|
||||||
public static UnifyType convert(JavaTXCompiler compiler, RefTypeOrTPHOrWildcardOrGeneric t, Boolean innerType){
|
public static UnifyType convert(JavaTXCompiler compiler, RefTypeOrTPHOrWildcardOrGeneric t, Boolean innerType, PlaceholderRegistry placeholderRegistry){
|
||||||
if (t instanceof GenericRefType){
|
if (t instanceof GenericRefType){
|
||||||
return UnifyTypeFactory.convert(compiler, (GenericRefType)t, innerType);
|
return UnifyTypeFactory.convert(compiler, (GenericRefType)t, innerType, placeholderRegistry);
|
||||||
} else if (t instanceof TypePlaceholder){
|
} else if (t instanceof TypePlaceholder){
|
||||||
return UnifyTypeFactory.convert(compiler, (TypePlaceholder)t, innerType);
|
return UnifyTypeFactory.convert(compiler, (TypePlaceholder)t, innerType, placeholderRegistry);
|
||||||
} else if (t instanceof ExtendsWildcardType){
|
} else if (t instanceof ExtendsWildcardType){
|
||||||
return UnifyTypeFactory.convert(compiler, (ExtendsWildcardType)t, innerType);
|
return UnifyTypeFactory.convert(compiler, (ExtendsWildcardType)t, innerType, placeholderRegistry);
|
||||||
} else if (t instanceof SuperWildcardType) {
|
} else if (t instanceof SuperWildcardType) {
|
||||||
return UnifyTypeFactory.convert(compiler, (SuperWildcardType) t, innerType);
|
return UnifyTypeFactory.convert(compiler, (SuperWildcardType) t, innerType, placeholderRegistry);
|
||||||
} else if (t instanceof RefType){
|
} else if (t instanceof RefType){
|
||||||
return UnifyTypeFactory.convert(compiler, (RefType)t, innerType);
|
return UnifyTypeFactory.convert(compiler, (RefType)t, innerType, placeholderRegistry);
|
||||||
}
|
}
|
||||||
//Es wurde versucht ein Typ umzuwandeln, welcher noch nicht von der Factory abgedeckt ist
|
//Es wurde versucht ein Typ umzuwandeln, welcher noch nicht von der Factory abgedeckt ist
|
||||||
throw new NotImplementedException("Der Typ "+t+" kann nicht umgewandelt werden");
|
throw new NotImplementedException("Der Typ "+t+" kann nicht umgewandelt werden");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UnifyType convert(JavaTXCompiler compiler, RefType t, Boolean innerType){
|
public static UnifyType convert(JavaTXCompiler compiler, RefType t, Boolean innerType, PlaceholderRegistry placeholderRegistry){
|
||||||
//Check if it is a FunN Type:
|
//Check if it is a FunN Type:
|
||||||
Pattern p = Pattern.compile("Fun(\\d+)[$][$]");
|
Pattern p = Pattern.compile("Fun(\\d+)[$][$]");
|
||||||
Matcher m = p.matcher(t.getName().toString());
|
Matcher m = p.matcher(t.getName().toString());
|
||||||
@@ -91,76 +98,76 @@ public class UnifyTypeFactory {
|
|||||||
if(b){
|
if(b){
|
||||||
Integer N = Integer.valueOf(m.group(1));
|
Integer N = Integer.valueOf(m.group(1));
|
||||||
if((N + 1) == t.getParaList().size()){
|
if((N + 1) == t.getParaList().size()){
|
||||||
return convertFunN(compiler, t.getParaList(), false);
|
return convertFunN(compiler, t.getParaList(), false, placeholderRegistry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UnifyType ret;
|
UnifyType ret;
|
||||||
List<UnifyType> params = new ArrayList<>();
|
List<UnifyType> params = new ArrayList<>();
|
||||||
if (t.getParaList() != null) {
|
if (t.getParaList() != null) {
|
||||||
for (RefTypeOrTPHOrWildcardOrGeneric pT : t.getParaList()) {
|
for (RefTypeOrTPHOrWildcardOrGeneric pT : t.getParaList()) {
|
||||||
params.add(UnifyTypeFactory.convert(compiler, pT, true));
|
params.add(UnifyTypeFactory.convert(compiler, pT, true, placeholderRegistry));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var clazz = compiler.getClass(t.getName());
|
var clazz = compiler.getClass(t.getName());
|
||||||
if (clazz != null && clazz.isInterface() && clazz.isFunctionalInterface()) {
|
if (clazz != null && clazz.isInterface() && clazz.isFunctionalInterface()) {
|
||||||
var method = clazz.getMethods().stream().filter(x -> Modifier.isAbstract(x.modifier)).findFirst().orElseThrow();
|
var method = clazz.getMethods().stream().filter(x -> Modifier.isAbstract(x.modifier)).findFirst().orElseThrow();
|
||||||
var methodParams = method.getParameterList().getFormalparalist().stream().map(x -> convert(compiler, x.getType(), true)).toList();
|
var methodParams = method.getParameterList().getFormalparalist().stream().map(x -> convert(compiler, x.getType(), true, placeholderRegistry)).toList();
|
||||||
var generics = StreamSupport.stream(clazz.getGenerics().spliterator(), false).map(GenericTypeVar::getName).toList();
|
var generics = StreamSupport.stream(clazz.getGenerics().spliterator(), false).map(GenericTypeVar::getName).toList();
|
||||||
return new FunInterfaceType(t.getName().toString(), new TypeParams(params), methodParams, convert(compiler, method.getReturnType(), true), generics);
|
return new FunInterfaceType(t.getName().toString(), new TypeParams(params), methodParams, convert(compiler, method.getReturnType(), true, placeholderRegistry), generics);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ReferenceType(t.getName().toString(),new TypeParams(params));
|
return new ReferenceType(t.getName().toString(),new TypeParams(params));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UnifyType convertFunN(JavaTXCompiler compiler, List<RefTypeOrTPHOrWildcardOrGeneric> paraList, Boolean innerType){
|
public static UnifyType convertFunN(JavaTXCompiler compiler, List<RefTypeOrTPHOrWildcardOrGeneric> paraList, Boolean innerType, PlaceholderRegistry placeholderRegistry){
|
||||||
UnifyType ret;
|
UnifyType ret;
|
||||||
List<UnifyType> params = new ArrayList<>();
|
List<UnifyType> params = new ArrayList<>();
|
||||||
if(paraList != null && paraList.size() > 0){
|
if(paraList != null && paraList.size() > 0){
|
||||||
for(RefTypeOrTPHOrWildcardOrGeneric pT : paraList){
|
for(RefTypeOrTPHOrWildcardOrGeneric pT : paraList){
|
||||||
params.add(UnifyTypeFactory.convert(compiler, pT, false));
|
params.add(UnifyTypeFactory.convert(compiler, pT, false, placeholderRegistry));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret = FunNType.getFunNType(new TypeParams(params));
|
ret = FunNType.getFunNType(new TypeParams(params));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UnifyType convert(JavaTXCompiler compiler, TypePlaceholder tph, Boolean innerType){
|
public static UnifyType convert(JavaTXCompiler compiler, TypePlaceholder tph, Boolean innerType, PlaceholderRegistry placeholderRegistry) {
|
||||||
if (tph.getName().equals("AFR")) {
|
if (tph.getName().equals("AFR")) {
|
||||||
System.out.println("XXX"+innerType);
|
SyntaxTree.logger.info("XXX"+innerType);
|
||||||
}
|
}
|
||||||
PlaceholderType ntph = new PlaceholderType(tph.getName(), tph.getVariance());
|
PlaceholderType ntph = new PlaceholderType(tph.getName(), tph.getVariance(), placeholderRegistry);
|
||||||
ntph.setVariance(tph.getVariance());
|
ntph.setVariance(tph.getVariance());
|
||||||
ntph.setOrCons(tph.getOrCons());
|
ntph.setOrCons(tph.getOrCons());
|
||||||
ntph.setWildcardtable(tph.getWildcardtable());
|
ntph.setWildcardtable(tph.getWildcardtable());
|
||||||
int in = PLACEHOLDERS.indexOf(ntph);
|
int in = placeholderRegistry.UnifyTypeFactory_PLACEHOLDERS.indexOf(ntph);
|
||||||
if (in == -1) {
|
if (in == -1) {
|
||||||
PLACEHOLDERS.add(ntph);
|
placeholderRegistry.UnifyTypeFactory_PLACEHOLDERS.add(ntph);
|
||||||
ntph.setInnerType(innerType);
|
ntph.setInnerType(innerType);
|
||||||
return ntph;
|
return ntph;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PlaceholderType oldpht = PLACEHOLDERS.get(in);
|
PlaceholderType oldpht = placeholderRegistry.UnifyTypeFactory_PLACEHOLDERS.get(in);
|
||||||
oldpht.setInnerType(oldpht.isInnerType() || innerType);
|
oldpht.setInnerType(oldpht.isInnerType() || innerType);
|
||||||
return oldpht;
|
return oldpht;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UnifyType convert(JavaTXCompiler compiler, GenericRefType t, Boolean innerType){
|
public static UnifyType convert(JavaTXCompiler compiler, GenericRefType t, Boolean innerType, PlaceholderRegistry placeholderRegistry){
|
||||||
return new ReferenceType(t.getParsedName(), true);
|
return new ReferenceType(t.getParsedName(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UnifyType convert(JavaTXCompiler compiler, WildcardType t, Boolean innerType){
|
public static UnifyType convert(JavaTXCompiler compiler, WildcardType t, Boolean innerType, PlaceholderRegistry placeholderRegistry){
|
||||||
if(t.isExtends())
|
if(t.isExtends())
|
||||||
return new ExtendsType(UnifyTypeFactory.convert(compiler, t.getInnerType(), false));
|
return new ExtendsType(UnifyTypeFactory.convert(compiler, t.getInnerType(), false, placeholderRegistry));
|
||||||
else if(t.isSuper())
|
else if(t.isSuper())
|
||||||
return new SuperType(UnifyTypeFactory.convert(compiler, t.getInnerType(), false));
|
return new SuperType(UnifyTypeFactory.convert(compiler, t.getInnerType(), false, placeholderRegistry));
|
||||||
else throw new NotImplementedException();
|
else throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static ConstraintSet<UnifyPair> convert(JavaTXCompiler compiler, ConstraintSet<Pair> constraints) {
|
public static ConstraintSet<UnifyPair> convert(JavaTXCompiler compiler, ConstraintSet<Pair> constraints, PlaceholderRegistry placeholderRegistry) {
|
||||||
return constraints.map(c -> UnifyTypeFactory.convert(compiler, c));
|
return constraints.map(c -> UnifyTypeFactory.convert(compiler, c, placeholderRegistry));
|
||||||
}
|
}
|
||||||
|
|
||||||
//NEVER USED
|
//NEVER USED
|
||||||
@@ -171,30 +178,30 @@ public class UnifyTypeFactory {
|
|||||||
// return unifyPairConstraint;
|
// return unifyPairConstraint;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
public static UnifyPair convert(JavaTXCompiler compiler, Pair p) {
|
public static UnifyPair convert(JavaTXCompiler compiler, Pair p, PlaceholderRegistry placeholderRegistry) {
|
||||||
UnifyPair ret = null;
|
UnifyPair ret = null;
|
||||||
if(p.GetOperator().equals(PairOperator.SMALLERDOT)) {
|
if(p.GetOperator().equals(PairOperator.SMALLERDOT)) {
|
||||||
ret = generateSmallerDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false)
|
ret = generateSmallerDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false, placeholderRegistry)
|
||||||
, UnifyTypeFactory.convert(compiler, p.TA2, false), p.getLocation());
|
, UnifyTypeFactory.convert(compiler, p.TA2, false, placeholderRegistry), p.getLocation());
|
||||||
//return ret;
|
//return ret;
|
||||||
}else if(p.GetOperator().equals(PairOperator.SMALLERNEQDOT)) {
|
}else if(p.GetOperator().equals(PairOperator.SMALLERNEQDOT)) {
|
||||||
ret = generateSmallNotEqualDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false)
|
ret = generateSmallNotEqualDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false, placeholderRegistry)
|
||||||
, UnifyTypeFactory.convert(compiler, p.TA2, false), p.getLocation());
|
, UnifyTypeFactory.convert(compiler, p.TA2, false, placeholderRegistry), p.getLocation());
|
||||||
//return ret;
|
//return ret;
|
||||||
}else if(p.GetOperator().equals(PairOperator.EQUALSDOT)) {
|
}else if(p.GetOperator().equals(PairOperator.EQUALSDOT)) {
|
||||||
ret = generateEqualDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false)
|
ret = generateEqualDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false, placeholderRegistry)
|
||||||
, UnifyTypeFactory.convert(compiler, p.TA2, false), p.getLocation());
|
, UnifyTypeFactory.convert(compiler, p.TA2, false, placeholderRegistry), p.getLocation());
|
||||||
//return ret;
|
//return ret;
|
||||||
}else if(p.GetOperator().equals(PairOperator.SMALLER)){
|
}else if(p.GetOperator().equals(PairOperator.SMALLER)){
|
||||||
ret = generateSmallerPair(UnifyTypeFactory.convert(compiler, p.TA1, false),
|
ret = generateSmallerPair(UnifyTypeFactory.convert(compiler, p.TA1, false, placeholderRegistry),
|
||||||
UnifyTypeFactory.convert(compiler, p.TA2, false), p.getLocation());
|
UnifyTypeFactory.convert(compiler, p.TA2, false, placeholderRegistry), p.getLocation());
|
||||||
}else throw new NotImplementedException();
|
}else throw new NotImplementedException();
|
||||||
UnifyType lhs, rhs;
|
UnifyType lhs, rhs;
|
||||||
if (((lhs = ret.getLhsType()) instanceof PlaceholderType)
|
if (((lhs = ret.getLhsType()) instanceof PlaceholderType)
|
||||||
&& ((PlaceholderType)lhs).isWildcardable()
|
&& ((PlaceholderType)lhs).isWildcardable()
|
||||||
&& (rhs = ret.getLhsType()) instanceof PlaceholderType) {
|
&& (rhs = ret.getLhsType()) instanceof PlaceholderType) {
|
||||||
if (lhs.getName().equals("AQ")) {
|
if (lhs.getName().equals("AQ")) {
|
||||||
System.out.println("");
|
// SyntaxTree.logger.info("");
|
||||||
}
|
}
|
||||||
((PlaceholderType)rhs).enableWildcardtable();
|
((PlaceholderType)rhs).enableWildcardtable();
|
||||||
}
|
}
|
||||||
@@ -203,7 +210,7 @@ public class UnifyTypeFactory {
|
|||||||
&& ((PlaceholderType)rhs).isWildcardable()
|
&& ((PlaceholderType)rhs).isWildcardable()
|
||||||
&& (lhs = ret.getLhsType()) instanceof PlaceholderType) {
|
&& (lhs = ret.getLhsType()) instanceof PlaceholderType) {
|
||||||
if (rhs.getName().equals("AQ")) {
|
if (rhs.getName().equals("AQ")) {
|
||||||
System.out.println("");
|
// SyntaxTree.logger.info("");
|
||||||
}
|
}
|
||||||
((PlaceholderType)lhs).enableWildcardtable();
|
((PlaceholderType)lhs).enableWildcardtable();
|
||||||
}
|
}
|
||||||
@@ -214,16 +221,16 @@ public class UnifyTypeFactory {
|
|||||||
* Convert from
|
* Convert from
|
||||||
* UnifyType -> ASTType
|
* UnifyType -> ASTType
|
||||||
*/
|
*/
|
||||||
public static Set<ResultPair> convert(Set<UnifyPair> unifyPairSet, Map<String,TypePlaceholder> tphs) {
|
public static Set<ResultPair> convert(Set<UnifyPair> unifyPairSet, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
|
||||||
return unifyPairSet.stream().map(
|
return unifyPairSet.stream().map(
|
||||||
unifyPair -> convert(unifyPair, tphs))
|
unifyPair -> convert(unifyPair, tphs, placeholderRegistry))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ResultPair convert(UnifyPair mp, Map<String,TypePlaceholder> tphs) {
|
public static ResultPair convert(UnifyPair mp, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
|
||||||
if (mp == null) { return null;} //kann bei basePairs passieren
|
if (mp == null) { return null;} //kann bei basePairs passieren
|
||||||
RefTypeOrTPHOrWildcardOrGeneric tl = UnifyTypeFactory.convert(mp.getLhsType(), tphs);
|
RefTypeOrTPHOrWildcardOrGeneric tl = UnifyTypeFactory.convert(mp.getLhsType(), tphs, placeholderRegistry);
|
||||||
RefTypeOrTPHOrWildcardOrGeneric tr = UnifyTypeFactory.convert(mp.getRhsType(), tphs);
|
RefTypeOrTPHOrWildcardOrGeneric tr = UnifyTypeFactory.convert(mp.getRhsType(), tphs, placeholderRegistry);
|
||||||
if(tl instanceof TypePlaceholder){
|
if(tl instanceof TypePlaceholder){
|
||||||
if(tr instanceof TypePlaceholder) {
|
if(tr instanceof TypePlaceholder) {
|
||||||
|
|
||||||
@@ -232,7 +239,7 @@ public class UnifyTypeFactory {
|
|||||||
//Einfach ignorieren TODO: Das hier muss ausgebessert werden:
|
//Einfach ignorieren TODO: Das hier muss ausgebessert werden:
|
||||||
//return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, ASTFactory.createObjectType());
|
//return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, ASTFactory.createObjectType());
|
||||||
}else{
|
}else{
|
||||||
return new PairTPHsmallerTPH((TypePlaceholder)tl, (TypePlaceholder)tr, convert(mp.getBasePair(), tphs));
|
return new PairTPHsmallerTPH((TypePlaceholder)tl, (TypePlaceholder)tr, convert(mp.getBasePair(), tphs, placeholderRegistry));
|
||||||
}
|
}
|
||||||
}else if(tr instanceof RefType){
|
}else if(tr instanceof RefType){
|
||||||
return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, (RefType) tr);
|
return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, (RefType) tr);
|
||||||
@@ -244,51 +251,51 @@ public class UnifyTypeFactory {
|
|||||||
}else return new PairNoResult(tl, tr);//throw new NotImplementedException();
|
}else return new PairNoResult(tl, tr);//throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(ReferenceType t, Map<String,TypePlaceholder> tphs) {
|
public static RefTypeOrTPHOrWildcardOrGeneric convert(ReferenceType t, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
|
||||||
if(JavaClassName.Void.equals(t.getName()))return new Void(new NullToken());
|
if(JavaClassName.Void.equals(t.getName()))return new Void(new NullToken());
|
||||||
if (t.isGenTypeVar()) return new GenericRefType(t.getName(),new NullToken());
|
if (t.isGenTypeVar()) return new GenericRefType(t.getName(),new NullToken());
|
||||||
RefType ret = new RefType(new JavaClassName(t.getName()),convert(t.getTypeParams(), tphs),new NullToken());
|
RefType ret = new RefType(new JavaClassName(t.getName()),convert(t.getTypeParams(), tphs, placeholderRegistry),new NullToken());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(FunNType t, Map<String,TypePlaceholder> tphs) {
|
public static RefTypeOrTPHOrWildcardOrGeneric convert(FunNType t, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
|
||||||
RefType ret = new RefType(new JavaClassName(t.getName()), convert(t.getTypeParams(), tphs), new NullToken());
|
RefType ret = new RefType(new JavaClassName(t.getName()), convert(t.getTypeParams(), tphs, placeholderRegistry), new NullToken());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(SuperType t, Map<String,TypePlaceholder> tphs) {
|
public static RefTypeOrTPHOrWildcardOrGeneric convert(SuperType t, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
|
||||||
RefTypeOrTPHOrWildcardOrGeneric innerType = convert(t.getSuperedType(), tphs);
|
RefTypeOrTPHOrWildcardOrGeneric innerType = convert(t.getSuperedType(), tphs, placeholderRegistry);
|
||||||
return new SuperWildcardType(innerType, new NullToken());
|
return new SuperWildcardType(innerType, new NullToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(ExtendsType t, Map<String,TypePlaceholder> tphs) {
|
public static RefTypeOrTPHOrWildcardOrGeneric convert(ExtendsType t, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
|
||||||
RefTypeOrTPHOrWildcardOrGeneric innerType = convert(t.getExtendedType(), tphs);
|
RefTypeOrTPHOrWildcardOrGeneric innerType = convert(t.getExtendedType(), tphs, placeholderRegistry);
|
||||||
return new ExtendsWildcardType(innerType, new NullToken());
|
return new ExtendsWildcardType(innerType, new NullToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(PlaceholderType t, Map<String,TypePlaceholder> tphs) {
|
public static RefTypeOrTPHOrWildcardOrGeneric convert(PlaceholderType t, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
|
||||||
TypePlaceholder ret = tphs.get(t.getName());
|
TypePlaceholder ret = tphs.get(t.getName());
|
||||||
if(ret == null){ //Dieser TPH wurde vom Unifikationsalgorithmus erstellt
|
if(ret == null){ //Dieser TPH wurde vom Unifikationsalgorithmus erstellt
|
||||||
ret = TypePlaceholder.fresh(new NullToken());
|
ret = TypePlaceholder.fresh(new NullToken(), placeholderRegistry);
|
||||||
tphs.put(t.getName(), ret);
|
tphs.put(t.getName(), ret);
|
||||||
}
|
}
|
||||||
ret.setVariance(t.getVariance());
|
ret.setVariance(t.getVariance());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(UnifyType t, Map<String,TypePlaceholder> tphs) {
|
public static RefTypeOrTPHOrWildcardOrGeneric convert(UnifyType t, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
|
||||||
if(t instanceof FunNType)return convert((FunNType) t, tphs);
|
if(t instanceof FunNType)return convert((FunNType) t, tphs, placeholderRegistry);
|
||||||
if(t instanceof ReferenceType)return convert((ReferenceType) t, tphs);
|
if(t instanceof ReferenceType)return convert((ReferenceType) t, tphs, placeholderRegistry);
|
||||||
if(t instanceof SuperType)return convert((SuperType) t, tphs);
|
if(t instanceof SuperType)return convert((SuperType) t, tphs, placeholderRegistry);
|
||||||
if(t instanceof ExtendsType)return convert((ExtendsType) t, tphs);
|
if(t instanceof ExtendsType)return convert((ExtendsType) t, tphs, placeholderRegistry);
|
||||||
if(t instanceof PlaceholderType)return convert((PlaceholderType) t, tphs);
|
if(t instanceof PlaceholderType)return convert((PlaceholderType) t, tphs, placeholderRegistry);
|
||||||
throw new NotImplementedException("Der Typ "+t+" kann nicht umgewandelt werden");
|
throw new NotImplementedException("Der Typ "+t+" kann nicht umgewandelt werden");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<RefTypeOrTPHOrWildcardOrGeneric> convert(TypeParams typeParams, Map<String,TypePlaceholder> tphs) {
|
private static List<RefTypeOrTPHOrWildcardOrGeneric> convert(TypeParams typeParams, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
|
||||||
List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
|
List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
|
||||||
for(UnifyType uT : typeParams){
|
for(UnifyType uT : typeParams){
|
||||||
RefTypeOrTPHOrWildcardOrGeneric toAdd = convert(uT, tphs);
|
RefTypeOrTPHOrWildcardOrGeneric toAdd = convert(uT, tphs, placeholderRegistry);
|
||||||
ret.add(toAdd);
|
ret.add(toAdd);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
package de.dhbwstuttgart.syntaxtree.type;
|
package de.dhbwstuttgart.syntaxtree.type;
|
||||||
|
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||||
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -15,7 +20,7 @@ import java.util.Objects;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class ExtendsWildcardType extends WildcardType{
|
public class ExtendsWildcardType extends WildcardType implements ISerializableData {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Author: Arne Lüdtke<br/>
|
* Author: Arne Lüdtke<br/>
|
||||||
@@ -68,4 +73,22 @@ public class ExtendsWildcardType extends WildcardType{
|
|||||||
ExtendsWildcardType that = (ExtendsWildcardType) o;
|
ExtendsWildcardType that = (ExtendsWildcardType) o;
|
||||||
return that.innerType.equals(this.innerType);
|
return that.innerType.equals(this.innerType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||||
|
SerialMap serialized = new SerialMap();
|
||||||
|
serialized.put("innerType", this.innerType.toSerial(keyStorage));
|
||||||
|
|
||||||
|
// create the wrapper and put this as the object
|
||||||
|
var serializedWrapper = super.toSerial(keyStorage).assertType(SerialMap.class);
|
||||||
|
serializedWrapper.put("object", serialized);
|
||||||
|
return serializedWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ExtendsWildcardType fromSerial(SerialMap data, UnifyContext context) {
|
||||||
|
return new ExtendsWildcardType(
|
||||||
|
RefTypeOrTPHOrWildcardOrGeneric.fromSerial(data.getMap("innerType"), context),
|
||||||
|
new NullToken()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,57 +1,77 @@
|
|||||||
package de.dhbwstuttgart.syntaxtree.type;
|
package de.dhbwstuttgart.syntaxtree.type;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||||
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class GenericRefType extends RefTypeOrTPHOrWildcardOrGeneric
|
public class GenericRefType extends RefTypeOrTPHOrWildcardOrGeneric implements ISerializableData {
|
||||||
{
|
private String name;
|
||||||
private String name;
|
|
||||||
|
|
||||||
public GenericRefType(String name, Token offset)
|
public GenericRefType(String name, Token offset) {
|
||||||
{
|
super(offset);
|
||||||
super(offset);
|
this.name = name;
|
||||||
this.name = name;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public String getParsedName(){
|
public String getParsedName() {
|
||||||
return name.toString();
|
return name.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ASTVisitor visitor) {
|
public void accept(ASTVisitor visitor) {
|
||||||
visitor.visit(this);
|
visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <A> A acceptTV(TypeVisitor<A> visitor) {
|
public <A> A acceptTV(TypeVisitor<A> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ResultSetVisitor visitor) {
|
public void accept(ResultSetVisitor visitor) {
|
||||||
visitor.visit(this);
|
visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
GenericRefType that = (GenericRefType) o;
|
GenericRefType that = (GenericRefType) o;
|
||||||
return name.equals(that.name);
|
return name.equals(that.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(name);
|
return Objects.hash(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString() {
|
||||||
{
|
return "GTV " + this.name;
|
||||||
return "GTV " + this.name;
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||||
|
SerialMap serialized = new SerialMap();
|
||||||
|
serialized.put("name", this.name);
|
||||||
|
|
||||||
|
// create the wrapper and put this as the object
|
||||||
|
var serializedWrapper = super.toSerial(keyStorage).assertType(SerialMap.class);
|
||||||
|
serializedWrapper.put("object", serialized);
|
||||||
|
return serializedWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GenericRefType fromSerial(SerialMap data, UnifyContext context) {
|
||||||
|
return new GenericRefType(
|
||||||
|
data.getValue("name").getOf(String.class),
|
||||||
|
new NullToken()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,15 @@
|
|||||||
package de.dhbwstuttgart.syntaxtree.type;
|
package de.dhbwstuttgart.syntaxtree.type;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||||
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -11,122 +18,137 @@ import java.util.List;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
||||||
public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
|
public class RefType extends RefTypeOrTPHOrWildcardOrGeneric implements ISerializableData {
|
||||||
{
|
protected final JavaClassName name;
|
||||||
protected final JavaClassName name;
|
protected final List<RefTypeOrTPHOrWildcardOrGeneric> parameter;
|
||||||
protected final List<RefTypeOrTPHOrWildcardOrGeneric> parameter;
|
/**
|
||||||
/**
|
* Ist primitiveFlag auf true, muss beim Codegen dieser Reftype durch
|
||||||
* Ist primitiveFlag auf true, muss beim Codegen dieser Reftype durch
|
* den primitiven Datentyp ersetzt werden
|
||||||
* den primitiven Datentyp ersetzt werden
|
* <p>
|
||||||
*
|
* Bsp: java.lang.Integer mit Flag wird dann zu [int]
|
||||||
* Bsp: java.lang.Integer mit Flag wird dann zu [int]
|
*/
|
||||||
*/
|
boolean primitiveFlag = false; // TODO Should be final
|
||||||
boolean primitiveFlag = false; // TODO Should be final
|
|
||||||
|
|
||||||
public RefType(JavaClassName fullyQualifiedName, Token offset)
|
public RefType(JavaClassName fullyQualifiedName, Token offset) {
|
||||||
{
|
this(fullyQualifiedName, new ArrayList<>(), offset);
|
||||||
this(fullyQualifiedName, new ArrayList<>(), offset);
|
}
|
||||||
|
|
||||||
|
public boolean isPrimitive() {
|
||||||
|
return primitiveFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
String params = "";
|
||||||
|
if (parameter.size() > 0) {
|
||||||
|
params += "<";
|
||||||
|
Iterator<RefTypeOrTPHOrWildcardOrGeneric> it = parameter.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
RefTypeOrTPHOrWildcardOrGeneric param = it.next();
|
||||||
|
params += param.toString();
|
||||||
|
if (it.hasNext()) params += ", ";
|
||||||
|
}
|
||||||
|
params += ">";
|
||||||
|
}
|
||||||
|
return this.name.toString() + params;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return this.name.hashCode();//Nur den Name hashen. Sorgt für langsame, aber funktionierende HashMaps
|
||||||
|
}
|
||||||
|
|
||||||
|
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset) {
|
||||||
|
this(fullyQualifiedName, parameter, offset, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset, boolean primitiveFlag) {
|
||||||
|
super(offset);
|
||||||
|
this.name = (fullyQualifiedName);
|
||||||
|
this.parameter = parameter;
|
||||||
|
this.primitiveFlag = primitiveFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JavaClassName getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<RefTypeOrTPHOrWildcardOrGeneric> getParaList() {
|
||||||
|
if (this.parameter == null) return new ArrayList<>();
|
||||||
|
return this.parameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Author: Jrg Buerle<br/>
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (!(obj instanceof RefType refObj)) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPrimitive() {
|
if (!Objects.equals(this.name, refObj.name)) return false;
|
||||||
return primitiveFlag;
|
boolean ret = true;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
//if(!(super.equals(obj))) PL 2020-03-12 muss vll. einkommentiert werden
|
||||||
public String toString(){
|
// return false;
|
||||||
String params = "";
|
|
||||||
if(parameter.size()>0){
|
if (parameter == null || parameter.size() == 0) {
|
||||||
params += "<";
|
ret &= (refObj.getParaList() == null || refObj.getParaList().isEmpty());
|
||||||
Iterator<RefTypeOrTPHOrWildcardOrGeneric> it = parameter.iterator();
|
} else {
|
||||||
while(it.hasNext()){
|
if (refObj.getParaList() == null) {
|
||||||
RefTypeOrTPHOrWildcardOrGeneric param = it.next();
|
ret = false;
|
||||||
params += param.toString();
|
} else if (parameter.size() != refObj.getParaList().size()) {
|
||||||
if(it.hasNext())params += ", ";
|
ret = false;
|
||||||
}
|
} else {
|
||||||
params += ">";
|
for (int i = 0; i < parameter.size(); i++) {
|
||||||
|
ret &= parameter.get(i).equals(refObj.getParaList().get(i));
|
||||||
}
|
}
|
||||||
return this.name.toString() + params;
|
}
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
|
|
||||||
@Override
|
}
|
||||||
public int hashCode() {
|
|
||||||
return this.name.hashCode();//Nur den Name hashen. Sorgt für langsame, aber funktionierende HashMaps
|
|
||||||
}
|
|
||||||
|
|
||||||
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset) {
|
|
||||||
this(fullyQualifiedName, parameter, offset, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset, boolean primitiveFlag) {
|
|
||||||
super(offset);
|
|
||||||
this.name = (fullyQualifiedName);
|
|
||||||
this.parameter = parameter;
|
|
||||||
this.primitiveFlag = primitiveFlag;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JavaClassName getName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<RefTypeOrTPHOrWildcardOrGeneric> getParaList(){
|
|
||||||
if(this.parameter==null)return new ArrayList<>();
|
|
||||||
return this.parameter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Author: Jrg Buerle<br/>
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public boolean equals(Object obj)
|
|
||||||
{
|
|
||||||
if(obj instanceof RefType){
|
|
||||||
if (!Objects.equals(this.name, ((RefType) obj).name)) return false;
|
|
||||||
boolean ret = true;
|
|
||||||
|
|
||||||
//if(!(super.equals(obj))) PL 2020-03-12 muss vll. einkommentiert werden
|
|
||||||
// return false;
|
|
||||||
|
|
||||||
if(parameter==null || parameter.size()==0){
|
|
||||||
ret &= (((RefType)obj).getParaList()==null || ((RefType)obj).getParaList().size()==0);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if(((RefType)obj).getParaList()==null){
|
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
else if(parameter.size() != ((RefType)obj).getParaList().size())
|
|
||||||
{
|
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(int i = 0; i<parameter.size(); i++)
|
|
||||||
{
|
|
||||||
ret &= parameter.get(i).equals(((RefType)obj).getParaList().get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ASTVisitor visitor) {
|
public void accept(ASTVisitor visitor) {
|
||||||
visitor.visit(this);
|
visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <A> A acceptTV(TypeVisitor<A> visitor) {
|
public <A> A acceptTV(TypeVisitor<A> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ResultSetVisitor visitor) {
|
public void accept(ResultSetVisitor visitor) {
|
||||||
visitor.visit(this);
|
visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ISerialNode toSerial(KeyStorage keyStorage) {
|
||||||
|
SerialMap serialized = new SerialMap();
|
||||||
|
serialized.put("isPrimitive", this.primitiveFlag);
|
||||||
|
serialized.put("name", this.name.toString());
|
||||||
|
serialized.put("parameters", SerialList.fromMapped(this.parameter, param -> param.toSerial(keyStorage)));
|
||||||
|
|
||||||
|
// create the wrapper and put this as the object
|
||||||
|
var serializedWrapper = super.toSerial(keyStorage).assertType(SerialMap.class);
|
||||||
|
serializedWrapper.put("object", serialized);
|
||||||
|
return serializedWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RefType fromSerial(SerialMap data, UnifyContext context) {
|
||||||
|
return new RefType(
|
||||||
|
new JavaClassName(data.getValue("name").getOf(String.class)),
|
||||||
|
data.getList("parameters").assertListOfMaps().stream()
|
||||||
|
.map(param -> RefTypeOrTPHOrWildcardOrGeneric.fromSerial(param, context))
|
||||||
|
.toList(),
|
||||||
|
new NullToken(),
|
||||||
|
data.getValue("isPrimitive").getOf(Boolean.class)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
package de.dhbwstuttgart.syntaxtree.type;
|
package de.dhbwstuttgart.syntaxtree.type;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialValue;
|
||||||
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||||
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
|
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
public abstract class RefTypeOrTPHOrWildcardOrGeneric extends SyntaxTreeNode{
|
public abstract class RefTypeOrTPHOrWildcardOrGeneric extends SyntaxTreeNode implements ISerializableData {
|
||||||
public RefTypeOrTPHOrWildcardOrGeneric(Token offset) {
|
public RefTypeOrTPHOrWildcardOrGeneric(Token offset) {
|
||||||
super(offset);
|
super(offset);
|
||||||
}
|
}
|
||||||
@@ -19,4 +25,25 @@ public abstract class RefTypeOrTPHOrWildcardOrGeneric extends SyntaxTreeNode{
|
|||||||
@Override
|
@Override
|
||||||
public abstract boolean equals(Object o);
|
public abstract boolean equals(Object o);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ISerialNode toSerial(KeyStorage keyStorage) {
|
||||||
|
SerialMap serialized = new SerialMap();
|
||||||
|
serialized.put("type", this.getClass().getSimpleName());
|
||||||
|
// we only insert null for the object and expect the child classes to call this and override the value with themselves
|
||||||
|
serialized.put("object", SerialValue.NULL);
|
||||||
|
return serialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RefTypeOrTPHOrWildcardOrGeneric fromSerial(SerialMap data, UnifyContext context) {
|
||||||
|
String type = data.getValue("type").getOf(String.class);
|
||||||
|
SerialMap object = data.getMap("object");
|
||||||
|
|
||||||
|
if (type.equals(ExtendsWildcardType.class.getSimpleName())) return ExtendsWildcardType.fromSerial(object, context);
|
||||||
|
else if (type.equals(GenericRefType.class.getSimpleName())) return GenericRefType.fromSerial(object, context);
|
||||||
|
else if (type.equals(SuperWildcardType.class.getSimpleName())) return SuperWildcardType.fromSerial(object, context);
|
||||||
|
else if (type.equals(RefType.class.getSimpleName())) return RefType.fromSerial(object, context);
|
||||||
|
else if (type.equals(Void.class.getSimpleName())) return Void.fromSerial(object, context);
|
||||||
|
else if (type.equals(TypePlaceholder.class.getSimpleName())) return TypePlaceholder.fromSerial(object, context);
|
||||||
|
else throw new RuntimeException("Could not unserialize class of unhandled type " + type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
package de.dhbwstuttgart.syntaxtree.type;
|
package de.dhbwstuttgart.syntaxtree.type;
|
||||||
|
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||||
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -16,7 +20,7 @@ import java.util.Objects;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class SuperWildcardType extends WildcardType{
|
public class SuperWildcardType extends WildcardType implements ISerializableData {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Author: Arne Lüdtke<br/>
|
* Author: Arne Lüdtke<br/>
|
||||||
@@ -80,4 +84,22 @@ public class SuperWildcardType extends WildcardType{
|
|||||||
SuperWildcardType that = (SuperWildcardType) o;
|
SuperWildcardType that = (SuperWildcardType) o;
|
||||||
return that.innerType.equals(this.innerType);
|
return that.innerType.equals(this.innerType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||||
|
SerialMap serialized = new SerialMap();
|
||||||
|
serialized.put("innerType", this.innerType.toSerial(keyStorage));
|
||||||
|
|
||||||
|
// create the wrapper and put this as the object
|
||||||
|
var serializedWrapper = super.toSerial(keyStorage).assertType(SerialMap.class);
|
||||||
|
serializedWrapper.put("object", serialized);
|
||||||
|
return serializedWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SuperWildcardType fromSerial(SerialMap data, UnifyContext context) {
|
||||||
|
return new SuperWildcardType(
|
||||||
|
RefTypeOrTPHOrWildcardOrGeneric.fromSerial(data.getMap("innerType"), context),
|
||||||
|
new NullToken()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
package de.dhbwstuttgart.syntaxtree.type;
|
package de.dhbwstuttgart.syntaxtree.type;
|
||||||
import java.util.Hashtable;
|
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||||
|
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||||
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
@@ -16,7 +19,7 @@ import org.antlr.v4.runtime.Token;
|
|||||||
* @author J�rg B�uerle
|
* @author J�rg B�uerle
|
||||||
* @version $Date: 2013/06/19 12:45:37 $
|
* @version $Date: 2013/06/19 12:45:37 $
|
||||||
*/
|
*/
|
||||||
public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
|
public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric implements ISerializableData
|
||||||
{
|
{
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
@@ -66,6 +69,11 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
|
|||||||
return new TypePlaceholder(NameGenerator.makeNewName(), position, 0, true);
|
return new TypePlaceholder(NameGenerator.makeNewName(), position, 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TypePlaceholder fresh(Token position, PlaceholderRegistry placeholderRegistry){
|
||||||
|
String newName = placeholderRegistry.generateFreshPlaceholderName();
|
||||||
|
return new TypePlaceholder(newName, position, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
public static TypePlaceholder fresh(Token position, int variance, boolean wildcardable){
|
public static TypePlaceholder fresh(Token position, int variance, boolean wildcardable){
|
||||||
return new TypePlaceholder(NameGenerator.makeNewName(), position, variance, wildcardable);
|
return new TypePlaceholder(NameGenerator.makeNewName(), position, variance, wildcardable);
|
||||||
}
|
}
|
||||||
@@ -139,4 +147,26 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
|
|||||||
public Boolean getWildcardtable() {
|
public Boolean getWildcardtable() {
|
||||||
return wildcardable;
|
return wildcardable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||||
|
SerialMap serialized = new SerialMap();
|
||||||
|
serialized.put("name", this.name);
|
||||||
|
serialized.put("variance", this.variance);
|
||||||
|
serialized.put("wildcardable", this.wildcardable);
|
||||||
|
|
||||||
|
// create the wrapper and put this as the object
|
||||||
|
var serializedWrapper = super.toSerial(keyStorage).assertType(SerialMap.class);
|
||||||
|
serializedWrapper.put("object", serialized);
|
||||||
|
return serializedWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TypePlaceholder fromSerial(SerialMap data, UnifyContext context) {
|
||||||
|
return new TypePlaceholder(
|
||||||
|
data.getValue("name").getOf(String.class),
|
||||||
|
new NullToken(),
|
||||||
|
data.getValue("variance").getOf(Integer.class),
|
||||||
|
data.getValue("wildcardable").getOf(Boolean.class)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,32 @@
|
|||||||
package de.dhbwstuttgart.syntaxtree.type;
|
package de.dhbwstuttgart.syntaxtree.type;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
|
||||||
|
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
|
|
||||||
|
|
||||||
public class Void extends RefType
|
public class Void extends RefType implements ISerializableData
|
||||||
{
|
{
|
||||||
public Void(Token offset) {
|
public Void(Token offset) {
|
||||||
super(JavaClassName.Void, offset);
|
super(JavaClassName.Void, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ISerialNode toSerial(KeyStorage keyStorage) {
|
||||||
|
// create the wrapper and put this as the object
|
||||||
|
var serializedWrapper = super.toSerial(keyStorage).assertType(SerialMap.class);
|
||||||
|
serializedWrapper.put("object", new SerialMap());
|
||||||
|
return serializedWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Void fromSerial(SerialMap data, UnifyContext context) {
|
||||||
|
return new Void(new NullToken());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
8
src/main/java/de/dhbwstuttgart/target/Target.java
Normal file
8
src/main/java/de/dhbwstuttgart/target/Target.java
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package de.dhbwstuttgart.target;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.util.Logger;
|
||||||
|
|
||||||
|
public class Target {
|
||||||
|
public static Logger logger = new Logger("Target");
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package de.dhbwstuttgart.target.generate;
|
|||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
||||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||||
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
||||||
import de.dhbwstuttgart.exceptions.DebugException;
|
import de.dhbwstuttgart.exceptions.DebugException;
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
@@ -11,8 +12,7 @@ import de.dhbwstuttgart.syntaxtree.Record;
|
|||||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
|
import de.dhbwstuttgart.target.Target;
|
||||||
import de.dhbwstuttgart.syntaxtree.visual.OutputGenerator;
|
|
||||||
import de.dhbwstuttgart.target.tree.*;
|
import de.dhbwstuttgart.target.tree.*;
|
||||||
import de.dhbwstuttgart.target.tree.expression.*;
|
import de.dhbwstuttgart.target.tree.expression.*;
|
||||||
import de.dhbwstuttgart.target.tree.type.*;
|
import de.dhbwstuttgart.target.tree.type.*;
|
||||||
@@ -36,6 +36,7 @@ public class ASTToTargetAST {
|
|||||||
public Generics generics;
|
public Generics generics;
|
||||||
public List<Generics> currentMethodOverloads;
|
public List<Generics> currentMethodOverloads;
|
||||||
|
|
||||||
|
final Map<ClassOrInterface, Set<GenericTypeVar>> userDefinedGenerics = new HashMap<>();
|
||||||
final Map<Method, Set<SignaturePair>> tphsInMethods = new HashMap<>();
|
final Map<Method, Set<SignaturePair>> tphsInMethods = new HashMap<>();
|
||||||
private Method currentMethod;
|
private Method currentMethod;
|
||||||
|
|
||||||
@@ -60,19 +61,17 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public record Generics(JavaGenerics javaGenerics, TxGenerics txGenerics) {
|
public record Generics(JavaGenerics javaGenerics, TxGenerics txGenerics) {
|
||||||
public Generics(JavaTXCompiler compiler, ResultSet set) {
|
|
||||||
this(new JavaGenerics(compiler, set), new TxGenerics(compiler, set));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IByteArrayClassLoader classLoader;
|
public IByteArrayClassLoader classLoader;
|
||||||
protected SourceFile sourceFile;
|
protected SourceFile sourceFile;
|
||||||
|
|
||||||
public ASTToTargetAST(List<ResultSet> resultSets, IByteArrayClassLoader classLoader) {
|
public ASTToTargetAST(List<ResultSet> resultSets) {
|
||||||
this(null, resultSets, classLoader);
|
this(null, resultSets);
|
||||||
}
|
}
|
||||||
public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets, IByteArrayClassLoader classLoader) {
|
public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets) {
|
||||||
this(compiler, resultSets, null, classLoader);
|
this(compiler, resultSets, null, new ByteArrayClassLoader());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets, SourceFile sourceFile, IByteArrayClassLoader classLoader) {
|
public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets, SourceFile sourceFile, IByteArrayClassLoader classLoader) {
|
||||||
@@ -82,9 +81,9 @@ public class ASTToTargetAST {
|
|||||||
|
|
||||||
all = new ArrayList<>();
|
all = new ArrayList<>();
|
||||||
for (var set : resultSets) {
|
for (var set : resultSets) {
|
||||||
all.add(new Generics(compiler, set));
|
all.add(new Generics(new JavaGenerics(this, set), new TxGenerics(this, set)));
|
||||||
}
|
}
|
||||||
this.generics = all.getFirst();
|
this.generics = all.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addSignaturePair(TypePlaceholder signature, RefTypeOrTPHOrWildcardOrGeneric parameter) {
|
public void addSignaturePair(TypePlaceholder signature, RefTypeOrTPHOrWildcardOrGeneric parameter) {
|
||||||
@@ -94,13 +93,9 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Optional<Method> findMethod(ClassOrInterface owner, String name, List<TargetType> argumentList) {
|
Optional<Method> findMethod(ClassOrInterface owner, String name, List<TargetType> argumentList) {
|
||||||
return findMethod(owner, name, argumentList, this.generics.javaGenerics, this.compiler);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Optional<Method> findMethod(ClassOrInterface owner, String name, List<TargetType> argumentList, GenerateGenerics generics, JavaTXCompiler compiler) {
|
|
||||||
Optional<Method> method = Optional.empty();
|
Optional<Method> method = Optional.empty();
|
||||||
while (method.isEmpty()) {
|
while (method.isEmpty()) {
|
||||||
method = owner.getMethods().stream().filter(m -> m.name.equals(name) && parameterEquals(m.getParameterList(), argumentList, generics)).findFirst();
|
method = owner.getMethods().stream().filter(m -> m.name.equals(name) && parameterEquals(m.getParameterList(), argumentList)).findFirst();
|
||||||
if (owner.getClassName().toString().equals("java.lang.Object")) break;
|
if (owner.getClassName().toString().equals("java.lang.Object")) break;
|
||||||
owner = compiler.getClass(owner.getSuperClass().getName());
|
owner = compiler.getClass(owner.getSuperClass().getName());
|
||||||
}
|
}
|
||||||
@@ -108,16 +103,16 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Optional<Constructor> findConstructor(ClassOrInterface owner, List<TargetType> argumentList) {
|
Optional<Constructor> findConstructor(ClassOrInterface owner, List<TargetType> argumentList) {
|
||||||
return owner.getConstructors().stream().filter(c -> parameterEquals(c.getParameterList(), argumentList, generics.javaGenerics)).findFirst();
|
return owner.getConstructors().stream().filter(c -> parameterEquals(c.getParameterList(), argumentList)).findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean parameterEquals(ParameterList parameterList, List<TargetType> arguments, GenerateGenerics generics) {
|
boolean parameterEquals(ParameterList parameterList, List<TargetType> arguments) {
|
||||||
var pars = parameterList.getFormalparalist();
|
var pars = parameterList.getFormalparalist();
|
||||||
if (pars.size() != arguments.size())
|
if (pars.size() != arguments.size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (var i = 0; i < pars.size(); i++) {
|
for (var i = 0; i < pars.size(); i++) {
|
||||||
var type1 = generics.getTargetType(pars.get(i).getType());
|
var type1 = convert(pars.get(i).getType(), generics.javaGenerics);
|
||||||
var type2 = arguments.get(i);
|
var type2 = arguments.get(i);
|
||||||
if (type1 instanceof TargetGenericType)
|
if (type1 instanceof TargetGenericType)
|
||||||
return true;
|
return true;
|
||||||
@@ -343,10 +338,10 @@ public class ASTToTargetAST {
|
|||||||
|
|
||||||
var result = r0.stream().map(l -> l.stream().toList()).toList();
|
var result = r0.stream().map(l -> l.stream().toList()).toList();
|
||||||
|
|
||||||
System.out.println("============== OUTPUT ==============");
|
Target.logger.info("============== OUTPUT ==============");
|
||||||
for (var l : result) {
|
for (var l : result) {
|
||||||
for (var m : l) System.out.println(m.name() + " " + m.getSignature());
|
for (var m : l) Target.logger.info(m.name() + " " + m.getSignature());
|
||||||
System.out.println();
|
Target.logger.info("");
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -355,14 +350,19 @@ public class ASTToTargetAST {
|
|||||||
Set<TargetGeneric> javaGenerics = new HashSet<>();
|
Set<TargetGeneric> javaGenerics = new HashSet<>();
|
||||||
Set<TargetGeneric> txGenerics = new HashSet<>();
|
Set<TargetGeneric> txGenerics = new HashSet<>();
|
||||||
|
|
||||||
var userDefinedGenerics = input.getUserDefinedGenerics();
|
var genericsIter = input.getGenerics().iterator();
|
||||||
if (!userDefinedGenerics.isEmpty()) {
|
if (genericsIter.hasNext()) {
|
||||||
// Add empty set of generics to cache so that it doesn't try to calculate it later
|
// Add empty set of generics to cache so that it doesn't try to calculate it later
|
||||||
for (var generic : userDefinedGenerics) {
|
var userDefinedGenerics = new HashSet<GenericTypeVar>();
|
||||||
// TODO Support multiple bouds
|
this.userDefinedGenerics.put(input, userDefinedGenerics);
|
||||||
javaGenerics.add(new TargetGeneric(generic.getName(), convert(generic.getBounds().getFirst())));
|
while (genericsIter.hasNext()) {
|
||||||
|
var next = genericsIter.next();
|
||||||
|
userDefinedGenerics.add(next);
|
||||||
|
// TODO Support multiple bounds
|
||||||
|
javaGenerics.add(new TargetGeneric(next.getName(), convert(next.getBounds().get(0))));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
this.userDefinedGenerics.put(input, new HashSet<>());
|
||||||
// Generate generics only if there are no user defined ones
|
// Generate generics only if there are no user defined ones
|
||||||
javaGenerics = convert(generics.javaGenerics.generics(input), generics.javaGenerics);
|
javaGenerics = convert(generics.javaGenerics.generics(input), generics.javaGenerics);
|
||||||
txGenerics = convert(generics.txGenerics.generics(input), generics.txGenerics);
|
txGenerics = convert(generics.txGenerics.generics(input), generics.txGenerics);
|
||||||
@@ -424,7 +424,7 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<TargetConstructor> convert(ClassOrInterface currentClass, Constructor input, TargetBlock fieldInitializer) {
|
private List<TargetConstructor> convert(ClassOrInterface currentClass, Constructor input, TargetBlock fieldInitializer) {
|
||||||
generics = all.getFirst();
|
generics = all.get(0);
|
||||||
List<TargetConstructor> result = new ArrayList<>();
|
List<TargetConstructor> result = new ArrayList<>();
|
||||||
Set<List<MethodParameter>> parameterSet = new HashSet<>();
|
Set<List<MethodParameter>> parameterSet = new HashSet<>();
|
||||||
this.currentMethod = input;
|
this.currentMethod = input;
|
||||||
@@ -468,6 +468,13 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TargetType unwrap(TargetType type) {
|
||||||
|
if (type instanceof TargetRefType ref) {
|
||||||
|
if (!ref.params().isEmpty()) return new TargetRefType(ref.name());
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
private TargetExpression generatePatternOverloadsRec(int offset, TargetExpression switchExpr, List<TargetLocalVar> params, List<TargetPattern> patterns, List<TargetMethod> methods, TargetType classType) {
|
private TargetExpression generatePatternOverloadsRec(int offset, TargetExpression switchExpr, List<TargetLocalVar> params, List<TargetPattern> patterns, List<TargetMethod> methods, TargetType classType) {
|
||||||
if (methods.isEmpty()) throw new DebugException("Couldn't find a candidate for switch overloading");
|
if (methods.isEmpty()) throw new DebugException("Couldn't find a candidate for switch overloading");
|
||||||
if (methods.size() == 1) {
|
if (methods.size() == 1) {
|
||||||
@@ -738,6 +745,11 @@ public class ASTToTargetAST {
|
|||||||
return new TargetField(input.modifier, convert(input.getType(), generics.javaGenerics), input.getName());
|
return new TargetField(input.modifier, convert(input.getType(), generics.javaGenerics), input.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final Map<String, FunNGenerator.GenericParameters> usedFunN = new HashMap<>();
|
||||||
|
private final Set<Integer> usedFunNSuperTypes = new HashSet<>();
|
||||||
|
|
||||||
|
public Map<String, byte[]> auxiliaries = new HashMap<>();
|
||||||
|
|
||||||
public TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input) {
|
public TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input) {
|
||||||
return convert(input, generics.javaGenerics);
|
return convert(input, generics.javaGenerics);
|
||||||
}
|
}
|
||||||
@@ -770,15 +782,7 @@ public class ASTToTargetAST {
|
|||||||
return TargetFunNType.fromParams(params, filteredParams, gep.getReturnType() != null ? 1 : 0);
|
return TargetFunNType.fromParams(params, filteredParams, gep.getReturnType() != null ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private FunNGenerator.GenericParameters convertToParameters(TargetFunNType input) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isSubtype(TargetType test, TargetType other) {
|
private boolean isSubtype(TargetType test, TargetType other) {
|
||||||
if (other.equals(TargetType.Object)) return true;
|
|
||||||
if (test instanceof TargetFunNType tfun && other instanceof TargetFunNType ofun)
|
|
||||||
return isSubtype(new FunNGenerator.GenericParameters(tfun), new FunNGenerator.GenericParameters(ofun));
|
|
||||||
|
|
||||||
var testClass = compiler.getClass(new JavaClassName(test.name()));
|
var testClass = compiler.getClass(new JavaClassName(test.name()));
|
||||||
var otherClass = compiler.getClass(new JavaClassName(other.name()));
|
var otherClass = compiler.getClass(new JavaClassName(other.name()));
|
||||||
if (testClass == null) return false;
|
if (testClass == null) return false;
|
||||||
@@ -806,24 +810,28 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void generateFunNTypes() {
|
public void generateFunNTypes() {
|
||||||
for (var entry : compiler.usedFunN.entrySet()) {
|
for (var entry : usedFunN.entrySet()) {
|
||||||
var gep = entry.getValue();
|
var gep = entry.getValue();
|
||||||
var superInterfaces = compiler.usedFunN.values().stream()
|
var superInterfaces = usedFunN.values().stream()
|
||||||
.filter(g -> !g.equals(gep))
|
.filter(g -> !g.equals(gep))
|
||||||
.filter(genericParameters -> isSubtype(gep, genericParameters))
|
.filter(genericParameters -> isSubtype(gep, genericParameters))
|
||||||
.map(FunNGenerator::getSpecializedClassName)
|
.map(FunNGenerator::getSpecializedClassName)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
var code = FunNGenerator.generateSpecializedBytecode(gep, superInterfaces);
|
var code = FunNGenerator.generateSpecializedBytecode(gep, superInterfaces);
|
||||||
compiler.auxiliaries.put(entry.getKey(), code);
|
|
||||||
|
try {
|
||||||
|
classLoader.findClass(entry.getKey());
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
try {
|
||||||
|
classLoader.loadClass(code);
|
||||||
|
} catch (LinkageError ignored) {}
|
||||||
|
}
|
||||||
|
auxiliaries.put(entry.getKey(), code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, GenerateGenerics generics) {
|
protected TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, GenerateGenerics generics) {
|
||||||
return convert(input, generics, compiler);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, GenerateGenerics generics, JavaTXCompiler compiler) {
|
|
||||||
return input.acceptTV(new TypeVisitor<>() {
|
return input.acceptTV(new TypeVisitor<>() {
|
||||||
@Override
|
@Override
|
||||||
public TargetType visit(RefType refType) {
|
public TargetType visit(RefType refType) {
|
||||||
@@ -835,31 +843,31 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var params = refType.getParaList().stream().map(type -> {
|
var params = refType.getParaList().stream().map(type -> {
|
||||||
return convert(type, generics, compiler);
|
return convert(type, generics);
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
if (name.matches("Fun\\d+\\$\\$")) { // TODO This seems like a bad idea
|
if (name.matches("Fun\\d+\\$\\$")) { // TODO This seems like a bad idea
|
||||||
var returnType = FunNGenerator.getReturnType(params);
|
var returnType = FunNGenerator.getReturnType(params);
|
||||||
var className = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), returnType);
|
var className = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), returnType);
|
||||||
if (!compiler.usedFunNSuperTypes.contains(params.size())) {
|
if (!usedFunNSuperTypes.contains(params.size())) {
|
||||||
compiler.usedFunNSuperTypes.add(params.size());
|
usedFunNSuperTypes.add(params.size());
|
||||||
var code = FunNGenerator.generateSuperBytecode(params.size() - 1, returnType != null ? 1 : 0);
|
var code = FunNGenerator.generateSuperBytecode(params.size() - 1, returnType != null ? 1 : 0);
|
||||||
var superClassName = FunNGenerator.getSuperClassName(params.size() - 1, returnType != null ? 1 : 0);
|
var superClassName = FunNGenerator.getSuperClassName(params.size() - 1, returnType != null ? 1 : 0);
|
||||||
try {
|
try {
|
||||||
compiler.classLoader.findClass(superClassName);
|
classLoader.findClass(superClassName);
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
try {
|
try {
|
||||||
compiler.classLoader.loadClass(superClassName, code);
|
classLoader.loadClass(code);
|
||||||
} catch (LinkageError ignored) {}
|
} catch (LinkageError ignored) {}
|
||||||
}
|
}
|
||||||
compiler.auxiliaries.put(superClassName, code);
|
auxiliaries.put(superClassName, code);
|
||||||
}
|
}
|
||||||
FunNGenerator.GenericParameters gep = null;
|
FunNGenerator.GenericParameters gep = null;
|
||||||
if (!compiler.usedFunN.containsKey(className)) {
|
if (!usedFunN.containsKey(className)) {
|
||||||
gep = new FunNGenerator.GenericParameters(params, returnType != null ? 1 : 0);
|
gep = new FunNGenerator.GenericParameters(params, returnType != null ? 1 : 0);
|
||||||
compiler.usedFunN.put(className, gep);
|
usedFunN.put(className, gep);
|
||||||
} else {
|
} else {
|
||||||
gep = compiler.usedFunN.get(className);
|
gep = usedFunN.get(className);
|
||||||
}
|
}
|
||||||
return flattenFunNType(params, gep);
|
return flattenFunNType(params, gep);
|
||||||
}
|
}
|
||||||
@@ -868,7 +876,7 @@ public class ASTToTargetAST {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TargetType visit(SuperWildcardType superWildcardType) {
|
public TargetType visit(SuperWildcardType superWildcardType) {
|
||||||
return new TargetSuperWildcard(convert(superWildcardType.getInnerType(), generics, compiler));
|
return new TargetSuperWildcard(convert(superWildcardType.getInnerType(), generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -878,7 +886,7 @@ public class ASTToTargetAST {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TargetType visit(ExtendsWildcardType extendsWildcardType) {
|
public TargetType visit(ExtendsWildcardType extendsWildcardType) {
|
||||||
return new TargetExtendsWildcard(convert(extendsWildcardType.getInnerType(), generics, compiler));
|
return new TargetExtendsWildcard(convert(extendsWildcardType.getInnerType(), generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package de.dhbwstuttgart.target.generate;
|
package de.dhbwstuttgart.target.generate;
|
||||||
|
|
||||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
import de.dhbwstuttgart.parser.JavaTXParser;
|
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||||
|
import de.dhbwstuttgart.target.Target;
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetGenericType;
|
import de.dhbwstuttgart.target.tree.type.TargetGenericType;
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||||
import de.dhbwstuttgart.typeinference.result.PairTPHEqualTPH;
|
import de.dhbwstuttgart.typeinference.result.PairTPHEqualTPH;
|
||||||
@@ -20,7 +20,7 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
public abstract class GenerateGenerics {
|
public abstract class GenerateGenerics {
|
||||||
|
|
||||||
private final JavaTXCompiler compiler;
|
private final ASTToTargetAST astToTargetAST;
|
||||||
|
|
||||||
public class TPH {
|
public class TPH {
|
||||||
private final TypePlaceholder wrap;
|
private final TypePlaceholder wrap;
|
||||||
@@ -136,21 +136,21 @@ public abstract class GenerateGenerics {
|
|||||||
Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes = new HashMap<>();
|
Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes = new HashMap<>();
|
||||||
Map<TypePlaceholder, TypePlaceholder> equality = new HashMap<>();
|
Map<TypePlaceholder, TypePlaceholder> equality = new HashMap<>();
|
||||||
|
|
||||||
GenerateGenerics(JavaTXCompiler compiler, ResultSet constraints) {
|
GenerateGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) {
|
||||||
this.compiler = compiler;
|
this.astToTargetAST = astToTargetAST;
|
||||||
for (var constraint : constraints.results) {
|
for (var constraint : constraints.results) {
|
||||||
if (constraint instanceof PairTPHsmallerTPH p) {
|
if (constraint instanceof PairTPHsmallerTPH p) {
|
||||||
System.out.println(p.left + " " + p.left.getVariance());
|
Target.logger.info(p.left + " " + p.left.getVariance());
|
||||||
simplifiedConstraints.add(new PairLT(new TPH(p.left), new TPH(p.right)));
|
simplifiedConstraints.add(new PairLT(new TPH(p.left), new TPH(p.right)));
|
||||||
} else if (constraint instanceof PairTPHEqualTPH p) {
|
} else if (constraint instanceof PairTPHEqualTPH p) {
|
||||||
equality.put(p.getLeft(), p.getRight());
|
equality.put(p.getLeft(), p.getRight());
|
||||||
} else if (constraint instanceof PairTPHequalRefTypeOrWildcardType p) {
|
} else if (constraint instanceof PairTPHequalRefTypeOrWildcardType p) {
|
||||||
System.out.println(p.left + " = " + p.right);
|
Target.logger.info(p.left + " = " + p.right);
|
||||||
concreteTypes.put(new TPH(p.left), p.right);
|
concreteTypes.put(new TPH(p.left), p.right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("Simplified constraints: " + simplifiedConstraints);
|
Target.logger.info("Simplified constraints: " + simplifiedConstraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public record GenericsState(Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes, Map<TypePlaceholder, TypePlaceholder> equality) {}
|
/*public record GenericsState(Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes, Map<TypePlaceholder, TypePlaceholder> equality) {}
|
||||||
@@ -250,7 +250,7 @@ public abstract class GenerateGenerics {
|
|||||||
equality.put(entry.getKey(), to);
|
equality.put(entry.getKey(), to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.println(from + " -> " + to + " " + from.getVariance());
|
Target.logger.info(from + " -> " + to + " " + from.getVariance());
|
||||||
//from.setVariance(to.getVariance());
|
//from.setVariance(to.getVariance());
|
||||||
equality.put(from, to);
|
equality.put(from, to);
|
||||||
referenced.remove(new TPH(from));
|
referenced.remove(new TPH(from));
|
||||||
@@ -283,7 +283,7 @@ public abstract class GenerateGenerics {
|
|||||||
Set<TPH> typeVariablesOfClass,
|
Set<TPH> typeVariablesOfClass,
|
||||||
Set<Pair> result
|
Set<Pair> result
|
||||||
) {
|
) {
|
||||||
var userDefinedGenericsOfClass = owner.getUserDefinedGenerics();
|
var userDefinedGenericsOfClass = astToTargetAST.userDefinedGenerics.get(owner);
|
||||||
|
|
||||||
// Type variables with bounds that are also type variables of the method
|
// Type variables with bounds that are also type variables of the method
|
||||||
for (var typeVariable : new HashSet<>(typeVariables)) {
|
for (var typeVariable : new HashSet<>(typeVariables)) {
|
||||||
@@ -319,7 +319,7 @@ public abstract class GenerateGenerics {
|
|||||||
Set<TPH> T2s = new HashSet<>();
|
Set<TPH> T2s = new HashSet<>();
|
||||||
findTphs(superType, T2s);
|
findTphs(superType, T2s);
|
||||||
|
|
||||||
System.out.println("T1s: " + T1s + " T2s: " + T2s);
|
Target.logger.info("T1s: " + T1s + " T2s: " + T2s);
|
||||||
//Ende
|
//Ende
|
||||||
|
|
||||||
superType = methodCall.receiverType;
|
superType = methodCall.receiverType;
|
||||||
@@ -331,10 +331,10 @@ public abstract class GenerateGenerics {
|
|||||||
|
|
||||||
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver) {
|
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver) {
|
||||||
if (expressionReceiver.expr instanceof This) {
|
if (expressionReceiver.expr instanceof This) {
|
||||||
var optMethod = ASTToTargetAST.findMethod(owner, methodCall.name, methodCall.signatureArguments().stream().map(x -> getTargetType(x)).toList(), GenerateGenerics.this, compiler);
|
var optMethod = astToTargetAST.findMethod(owner, methodCall.name, methodCall.signatureArguments().stream().map(astToTargetAST::convert).toList());
|
||||||
if (optMethod.isEmpty()) return;
|
if (optMethod.isEmpty()) return;
|
||||||
var method2 = optMethod.get();
|
var method2 = optMethod.get();
|
||||||
System.out.println("In: " + method.getName() + " Method: " + method2.getName());
|
Target.logger.info("In: " + method.getName() + " Method: " + method2.getName());
|
||||||
var generics = family(owner, method2);
|
var generics = family(owner, method2);
|
||||||
|
|
||||||
// transitive and
|
// transitive and
|
||||||
@@ -367,7 +367,7 @@ public abstract class GenerateGenerics {
|
|||||||
if (!T1s.contains(R1) || !T2s.contains(R2)) continue;
|
if (!T1s.contains(R1) || !T2s.contains(R2)) continue;
|
||||||
|
|
||||||
var newPair = new PairLT(R1, R2);
|
var newPair = new PairLT(R1, R2);
|
||||||
System.out.println("New pair: " + newPair);
|
Target.logger.info("New pair: " + newPair);
|
||||||
newPairs.add(newPair);
|
newPairs.add(newPair);
|
||||||
|
|
||||||
if (!containsRelation(result, newPair))
|
if (!containsRelation(result, newPair))
|
||||||
@@ -569,7 +569,7 @@ public abstract class GenerateGenerics {
|
|||||||
Set<Pair> generics(ClassOrInterface owner, Method method) {
|
Set<Pair> generics(ClassOrInterface owner, Method method) {
|
||||||
if (computedGenericsOfMethods.containsKey(method)) {
|
if (computedGenericsOfMethods.containsKey(method)) {
|
||||||
var cached = computedGenericsOfMethods.get(method);
|
var cached = computedGenericsOfMethods.get(method);
|
||||||
System.out.println("Cached " + method.getName() + ": " + cached);
|
Target.logger.info("Cached " + method.getName() + ": " + cached);
|
||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -598,7 +598,7 @@ public abstract class GenerateGenerics {
|
|||||||
|
|
||||||
normalize(result, classGenerics, usedTphs);
|
normalize(result, classGenerics, usedTphs);
|
||||||
|
|
||||||
System.out.println(this.getClass().getSimpleName() + " " + method.name + ": " + result);
|
Target.logger.info(this.getClass().getSimpleName() + " " + method.name + ": " + result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -677,7 +677,7 @@ public abstract class GenerateGenerics {
|
|||||||
|
|
||||||
normalize(javaResult, null, referencedByClass);
|
normalize(javaResult, null, referencedByClass);
|
||||||
|
|
||||||
System.out.println(this.getClass().getSimpleName() + " Class " + classOrInterface.getClassName().getClassName() + ": " + javaResult);
|
Target.logger.info(this.getClass().getSimpleName() + " Class " + classOrInterface.getClassName().getClassName() + ": " + javaResult);
|
||||||
return javaResult;
|
return javaResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -728,7 +728,7 @@ public abstract class GenerateGenerics {
|
|||||||
if (!added) break;
|
if (!added) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println(chain + " " + chain.stream().map(e -> e.resolve().getVariance()).toList());
|
Target.logger.info(chain + " " + chain.stream().map(e -> e.resolve().getVariance()).toList());
|
||||||
var variance = chain.get(0).resolve().getVariance();
|
var variance = chain.get(0).resolve().getVariance();
|
||||||
if (variance != 1) continue;
|
if (variance != 1) continue;
|
||||||
var index = 0;
|
var index = 0;
|
||||||
@@ -766,7 +766,7 @@ public abstract class GenerateGenerics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (var pair : elementsToAddToEquality) {
|
for (var pair : elementsToAddToEquality) {
|
||||||
System.out.println(pair);
|
Target.logger.info(pair);
|
||||||
addToEquality(pair.left, pair.right, referenced);
|
addToEquality(pair.left, pair.right, referenced);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -919,11 +919,11 @@ public abstract class GenerateGenerics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (infima.size() > 1) {
|
if (infima.size() > 1) {
|
||||||
System.out.println(infima);
|
Target.logger.info(infima);
|
||||||
for (var pair : infima) {
|
for (var pair : infima) {
|
||||||
var returnTypes = findTypeVariables(method.getReturnType());
|
var returnTypes = findTypeVariables(method.getReturnType());
|
||||||
var chain = findConnectionToReturnType(returnTypes, input, new HashSet<>(), pair.left);
|
var chain = findConnectionToReturnType(returnTypes, input, new HashSet<>(), pair.left);
|
||||||
System.out.println("Find: " + pair.left + " " + chain);
|
Target.logger.info("Find: " + pair.left + " " + chain);
|
||||||
chain.remove(pair.left);
|
chain.remove(pair.left);
|
||||||
if (chain.size() > 0) {
|
if (chain.size() > 0) {
|
||||||
for (var tph : chain)
|
for (var tph : chain)
|
||||||
@@ -961,8 +961,8 @@ public abstract class GenerateGenerics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
newTph.setVariance(variance);
|
newTph.setVariance(variance);
|
||||||
System.out.println(infima + " " + infima.stream().map(i -> i.right.resolve().getVariance()).toList());
|
Target.logger.info(infima + " " + infima.stream().map(i -> i.right.resolve().getVariance()).toList());
|
||||||
System.out.println("Infima new TPH " + newTph + " variance " + variance);
|
Target.logger.info("Infima new TPH " + newTph + " variance " + variance);
|
||||||
|
|
||||||
//referenced.add(newTph);
|
//referenced.add(newTph);
|
||||||
addToPairs(input, new PairLT(left, new TPH(newTph)));
|
addToPairs(input, new PairLT(left, new TPH(newTph)));
|
||||||
@@ -1007,8 +1007,8 @@ public abstract class GenerateGenerics {
|
|||||||
}
|
}
|
||||||
var type = concreteTypes.get(new TPH(tph));
|
var type = concreteTypes.get(new TPH(tph));
|
||||||
if (type == null) return new TargetGenericType(tph.getName());
|
if (type == null) return new TargetGenericType(tph.getName());
|
||||||
return ASTToTargetAST.convert(type, this, compiler);
|
return astToTargetAST.convert(type, this);
|
||||||
}
|
}
|
||||||
return ASTToTargetAST.convert(in, this, compiler);
|
return astToTargetAST.convert(in, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,4 +69,8 @@ public class GenericsResult {
|
|||||||
return this.generics.getType(tph);
|
return this.generics.getType(tph);
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TargetType resolveTarget(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||||
|
return this.generics.getTargetType(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package de.dhbwstuttgart.target.generate;
|
package de.dhbwstuttgart.target.generate;
|
||||||
|
|
||||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
@@ -8,8 +7,8 @@ import de.dhbwstuttgart.typeinference.result.ResultSet;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
final class JavaGenerics extends GenerateGenerics {
|
final class JavaGenerics extends GenerateGenerics {
|
||||||
JavaGenerics(JavaTXCompiler compiler, ResultSet constraints) {
|
JavaGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) {
|
||||||
super(compiler, constraints);
|
super(astToTargetAST, constraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user