Compare commits
80 Commits
tryCatch
...
effc31782f
Author | SHA1 | Date | |
---|---|---|---|
|
effc31782f | ||
|
2a24eab9d3 | ||
|
b29eb71238 | ||
|
e9ce071e2b | ||
3567bae0d7 | |||
|
a314013f40 | ||
|
37c58be1f3 | ||
|
24920330c6 | ||
|
bc43ea749d | ||
9160c99cf2 | |||
c72a14cab3 | |||
10bb5d1d11 | |||
2842fc5069 | |||
5c5e0bd1e9 | |||
3d81318e01 | |||
53e2c20608 | |||
86e467fd82 | |||
25b14e9342 | |||
d0de0b31e4 | |||
dd180524b2 | |||
b3744bf5f7 | |||
fda16978c2 | |||
a485cd8fa6 | |||
f8c708f0f4 | |||
28d9946bbb | |||
7b4ca8f177 | |||
b879d7743d | |||
e26a43b400 | |||
5deed725ae | |||
8ae15f9d41 | |||
8c8e088612 | |||
2814c6538e | |||
dcbc29b49b | |||
05033bcb9d | |||
814f5dd5fa | |||
24ca985ccc | |||
d6ed0689bc | |||
d7676f36e3 | |||
|
c479b044b3 | ||
|
9046fb09e5 | ||
|
9e323759d6 | ||
558083166d | |||
|
aec2f9a399 | ||
|
31df7a65f0 | ||
|
185989ba62 | ||
|
0eb48ba425 | ||
ceee9a49c4 | |||
ee64218a5f | |||
c50f14a4a3 | |||
1f4250ff84 | |||
ae41c7f19d | |||
2416c80c20 | |||
4cc55c0059 | |||
9434facfa0 | |||
09a6b9a788 | |||
8b342c5604 | |||
cdb93b5155 | |||
b07e848fa2 | |||
313cd20f36 | |||
567fcc3b9a | |||
d9936e7197 | |||
8f194b3102 | |||
1391206dfe | |||
659bf6b500 | |||
|
42e31a3471 | ||
|
d3b3f92193 | ||
|
8208abcaea | ||
|
e4a3939ce9 | ||
|
d903ec0ebb | ||
|
61de81cf92 | ||
|
59888006e0 | ||
|
94034912b4 | ||
|
f303163118 | ||
|
7d99fba044 | ||
|
3740d34954 | ||
|
d8b861ea95 | ||
33ed22c06a | |||
70f7857661 | |||
|
cf45ea68bd | ||
|
be72e4d7fb |
@@ -1,5 +1,8 @@
|
||||
name: Build and Test with Maven
|
||||
on: [push]
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
Build-and-test-with-Maven:
|
||||
@@ -15,11 +18,11 @@ jobs:
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '22'
|
||||
java-version: '24'
|
||||
cache: 'maven'
|
||||
- name: Compile project
|
||||
run: |
|
||||
mvn compile
|
||||
- name: Run tests
|
||||
run: |
|
||||
mvn test
|
||||
mvn test
|
||||
|
45
.gitea/workflows/sonarqube.yml
Normal file
45
.gitea/workflows/sonarqube.yml
Normal file
@@ -0,0 +1,45 @@
|
||||
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
|
7
README.md
Normal file
7
README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
## 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!
|
45
pom.xml
45
pom.xml
@@ -12,46 +12,65 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<url>http://maven.apache.org</url>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.2</version>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.13.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.antlr/antlr4 -->
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4</artifactId>
|
||||
<version>4.11.1</version>
|
||||
<version>4.13.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.16.1</version>
|
||||
<version>2.19.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.classgraph</groupId>
|
||||
<artifactId>classgraph</artifactId>
|
||||
<version>4.8.172</version>
|
||||
<version>4.8.180</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>33.2.0-jre</version>
|
||||
<version>33.4.8-jre</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.ow2.asm/asm -->
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
<version>9.5</version>
|
||||
<version>9.8</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.8.13</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>report</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
<version>3.14.0</version>
|
||||
<configuration>
|
||||
<compilerArgs>--enable-preview</compilerArgs>
|
||||
<source>23</source>
|
||||
@@ -61,11 +80,11 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<version>3.5.3</version>
|
||||
<configuration>
|
||||
<redirectTestOutputToFile>true</redirectTestOutputToFile>
|
||||
<reportsDirectory>${project.build.directory}/test-reports</reportsDirectory>
|
||||
<argLine>--enable-preview</argLine>
|
||||
<argLine>${argLine} --enable-preview</argLine>
|
||||
<trimStackTrace>false</trimStackTrace>
|
||||
<excludes>
|
||||
<exclude>**/JavaTXCompilerTest.java</exclude>
|
||||
@@ -77,7 +96,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<plugin>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4-maven-plugin</artifactId>
|
||||
<version>4.11.1</version>
|
||||
<version>4.13.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>antlr</id>
|
||||
@@ -90,7 +109,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<version>3.4.2</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
|
@@ -6,7 +6,7 @@ import java.util.stream.Stream;
|
||||
|
||||
public class Bug325 {
|
||||
public main() {
|
||||
List<Integer> list = new ArrayList<>(List.of(1,2,3,4,5));
|
||||
var list = new ArrayList<>(List.of(1,2,3,4,5));
|
||||
var func = x -> x*2;
|
||||
return list.stream().map(func).toList();
|
||||
}
|
||||
|
22
resources/bytecode/javFiles/Bug363.jav
Normal file
22
resources/bytecode/javFiles/Bug363.jav
Normal file
@@ -0,0 +1,22 @@
|
||||
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
|
||||
}
|
||||
}
|
8
resources/bytecode/javFiles/Bug364.jav
Normal file
8
resources/bytecode/javFiles/Bug364.jav
Normal file
@@ -0,0 +1,8 @@
|
||||
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");
|
||||
}
|
||||
}
|
21
resources/bytecode/javFiles/Bug365.jav
Normal file
21
resources/bytecode/javFiles/Bug365.jav
Normal file
@@ -0,0 +1,21 @@
|
||||
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");
|
||||
}
|
||||
}
|
12
resources/bytecode/javFiles/Bug366.jav
Normal file
12
resources/bytecode/javFiles/Bug366.jav
Normal file
@@ -0,0 +1,12 @@
|
||||
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);
|
||||
}
|
||||
}
|
10
resources/bytecode/javFiles/Bug371.jav
Normal file
10
resources/bytecode/javFiles/Bug371.jav
Normal file
@@ -0,0 +1,10 @@
|
||||
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);
|
||||
}
|
||||
}
|
17
resources/bytecode/javFiles/Bug373.jav
Normal file
17
resources/bytecode/javFiles/Bug373.jav
Normal file
@@ -0,0 +1,17 @@
|
||||
import java.lang.Boolean;
|
||||
import java.lang.Integer;
|
||||
import java.lang.System;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.Character;
|
||||
|
||||
public class Bug373 {
|
||||
public static main() {
|
||||
System.out.println(true);
|
||||
System.out.println(false);
|
||||
System.out.println(1);
|
||||
System.out.println(1l);
|
||||
System.out.println(1.0);
|
||||
System.out.println(1.0f);
|
||||
System.out.println('a');
|
||||
}
|
||||
}
|
@@ -1,16 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
14
resources/bytecode/javFiles/Main.jav
Normal file
14
resources/bytecode/javFiles/Main.jav
Normal file
@@ -0,0 +1,14 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -539,7 +539,7 @@ catchClause
|
||||
;
|
||||
|
||||
catchType
|
||||
: typeType ('|' typeType)*
|
||||
: qualifiedName ('|' qualifiedName)*
|
||||
;
|
||||
|
||||
finallyBlock
|
||||
|
@@ -10,10 +10,10 @@ import de.dhbwstuttgart.target.tree.expression.*;
|
||||
import de.dhbwstuttgart.target.tree.type.*;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.invoke.*;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.objectweb.asm.Opcodes.*;
|
||||
import static de.dhbwstuttgart.target.tree.expression.TargetBinaryOp.*;
|
||||
@@ -85,14 +85,16 @@ public class Codegen {
|
||||
int localCounter;
|
||||
MethodVisitor mv;
|
||||
TargetType returnType;
|
||||
boolean isStatic = false;
|
||||
|
||||
Stack<BreakEnv> breakStack = new Stack<>();
|
||||
Stack<Integer> switchResultValue = new Stack<>();
|
||||
|
||||
State(TargetType returnType, MethodVisitor mv, int localCounter) {
|
||||
State(TargetType returnType, MethodVisitor mv, int localCounter, boolean isStatic) {
|
||||
this.returnType = returnType;
|
||||
this.mv = mv;
|
||||
this.localCounter = localCounter;
|
||||
this.isStatic = isStatic;
|
||||
}
|
||||
|
||||
void enterScope() {
|
||||
@@ -230,9 +232,9 @@ public class Codegen {
|
||||
if (source.equals(dest))
|
||||
return;
|
||||
if (source.equals(TargetType.Long)) {
|
||||
if (dest.equals(TargetType.Integer)) {
|
||||
if (dest.equals(TargetType.Integer))
|
||||
mv.visitInsn(L2I);
|
||||
} else if (dest.equals(TargetType.Float))
|
||||
else if (dest.equals(TargetType.Float))
|
||||
mv.visitInsn(L2F);
|
||||
else if (dest.equals(TargetType.Double))
|
||||
mv.visitInsn(L2D);
|
||||
@@ -275,6 +277,8 @@ public class Codegen {
|
||||
mv.visitInsn(I2F);
|
||||
else if (dest.equals(TargetType.Double))
|
||||
mv.visitInsn(I2D);
|
||||
} else if (source.equals(TargetType.Boolean)) {
|
||||
unboxPrimitive(state, dest);
|
||||
} else if (isFunctionalInterface(source) && isFunctionalInterface(dest) &&
|
||||
!(source instanceof TargetFunNType && dest instanceof TargetFunNType)) {
|
||||
boxFunctionalInterface(state, source, dest);
|
||||
@@ -758,6 +762,16 @@ 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) {
|
||||
var mv = state.mv;
|
||||
|
||||
@@ -769,7 +783,8 @@ public class Codegen {
|
||||
|
||||
var parameters = new ArrayList<>(lambda.captures());
|
||||
parameters.addAll(signature.parameters());
|
||||
var implSignature = new TargetMethod.Signature(Set.of(), parameters, lambda.signature().returnType());
|
||||
parameters = parameters.stream().map(param -> param.withType(removeGenerics(param.pattern().type()))).collect(Collectors.toCollection(ArrayList::new));
|
||||
var implSignature = new TargetMethod.Signature(Set.of(), parameters, removeGenerics(lambda.signature().returnType()));
|
||||
|
||||
TargetMethod impl;
|
||||
if (lambdas.containsKey(lambda)) {
|
||||
@@ -777,21 +792,22 @@ public class Codegen {
|
||||
} else {
|
||||
var name = "lambda$" + lambdaCounter++;
|
||||
|
||||
impl = new TargetMethod(0, name, lambda.block(), implSignature, null);
|
||||
generateMethod(impl);
|
||||
impl = new TargetMethod(state.isStatic ? ACC_STATIC : 0, name, lambda.block(), implSignature, null);
|
||||
generateMethod(impl, state);
|
||||
lambdas.put(lambda, impl);
|
||||
}
|
||||
|
||||
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 handle = new Handle(H_INVOKEVIRTUAL, clazz.getName(), impl.name(), implSignature.getDescriptor(), false);
|
||||
var handle = new Handle(state.isStatic ? H_INVOKESTATIC : H_INVOKEVIRTUAL, clazz.getName(), impl.name(), implSignature.getDescriptor(), false);
|
||||
|
||||
var params = new ArrayList<TargetType>();
|
||||
params.add(new TargetRefType(clazz.qualifiedName().getClassName()));
|
||||
if(!state.isStatic) params.add(new TargetRefType(clazz.qualifiedName().getClassName()));
|
||||
params.addAll(lambda.captures().stream().map(mp -> mp.pattern().type()).toList());
|
||||
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
if (!state.isStatic)
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
for (var index = 0; index < lambda.captures().size(); index++) {
|
||||
var capture = lambda.captures().get(index);
|
||||
var pattern = (TargetTypePattern) capture.pattern();
|
||||
@@ -1159,48 +1175,11 @@ public class Codegen {
|
||||
mv.visitLabel(end);
|
||||
break;
|
||||
}
|
||||
case TargetPattern targetPattern:
|
||||
break;
|
||||
case TargetTryCatchFinally targetTryCatchFinally:
|
||||
generateTryCatchFinally(targetTryCatchFinally, state);
|
||||
default:
|
||||
throw new CodeGenException("Unexpected value: " + expr);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateTryCatchFinally(TargetTryCatchFinally tryCatchFinally, State state){
|
||||
MethodVisitor mv = state.mv;
|
||||
Label startTry = new Label();
|
||||
Label endTry = new Label();
|
||||
Label endOrFinally = new Label();
|
||||
|
||||
//Try
|
||||
mv.visitLabel(startTry);
|
||||
generate(state, tryCatchFinally.tryBlock());
|
||||
mv.visitLabel(endTry);
|
||||
mv.visitJumpInsn(GOTO, endOrFinally);
|
||||
|
||||
for (var catchClause : tryCatchFinally.catchClauses()){
|
||||
Label startCatch = new Label();
|
||||
Label endCatch = new Label();
|
||||
mv.visitTryCatchBlock(startTry, endOrFinally, startCatch, "java/lang/Exception"); //ignore all exception types except the first
|
||||
mv.visitLabel(startCatch);
|
||||
if (!catchClause.identifier().isEmpty()) {
|
||||
mv.visitFrame(F_SAME1, 0, null, 1, new Object[]{"java/lang/Exception"});
|
||||
LocalVar excep = state.createVariable(catchClause.identifier(), catchClause.exceptionNames().getFirst());
|
||||
mv.visitVarInsn(ASTORE, excep.index());
|
||||
}
|
||||
generate(state, catchClause.catchBlock());
|
||||
mv.visitLabel(endCatch);
|
||||
mv.visitJumpInsn(GOTO, endOrFinally);
|
||||
}
|
||||
|
||||
if (tryCatchFinally.finallyBlock().isPresent()){
|
||||
mv.visitLabel(endOrFinally);
|
||||
generate(state, tryCatchFinally.finallyBlock().get());
|
||||
}
|
||||
else mv.visitLabel(endOrFinally);
|
||||
|
||||
}
|
||||
|
||||
private void generateForEach(TargetForEach forEach, State state) {
|
||||
state.enterScope();
|
||||
TargetVarDecl vd = (TargetVarDecl) forEach.vardecl();
|
||||
@@ -1556,7 +1535,7 @@ public class Codegen {
|
||||
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "<clinit>", "()V", null, null);
|
||||
mv.visitCode();
|
||||
|
||||
var state = new State(null, mv, 0);
|
||||
var state = new State(null, mv, 0, true);
|
||||
generate(state, constructor.block());
|
||||
|
||||
mv.visitInsn(RETURN);
|
||||
@@ -1570,7 +1549,7 @@ public class Codegen {
|
||||
mv.visitAttribute(new JavaTXSignatureAttribute(constructor.getTXSignature()));
|
||||
|
||||
mv.visitCode();
|
||||
var state = new State(null, mv, 1);
|
||||
var state = new State(null, mv, 1, false);
|
||||
for (var param : constructor.parameters()) {
|
||||
var pattern = param.pattern();
|
||||
if (pattern instanceof TargetTypePattern tp)
|
||||
@@ -1616,9 +1595,31 @@ public class Codegen {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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, className, "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 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)
|
||||
access |= ACC_ABSTRACT;
|
||||
if (clazz instanceof TargetInterface)
|
||||
@@ -1632,7 +1633,10 @@ public class Codegen {
|
||||
|
||||
if (method.block() != null) {
|
||||
mv.visitCode();
|
||||
var state = new State(method.signature().returnType(), mv, method.isStatic() ? 0 : 1);
|
||||
var state = new State(method.signature().returnType(), mv, method.isStatic() ? 0 : 1, method.isStatic());
|
||||
if (parent != null) {
|
||||
state.scope.parent = parent.scope;
|
||||
}
|
||||
var offset = 1;
|
||||
for (var param : method.signature().parameters()) {
|
||||
state.createVariable(param.pattern().name(), param.pattern().type());
|
||||
@@ -1642,6 +1646,8 @@ public class Codegen {
|
||||
bindLocalVariables(state, cp, offset);
|
||||
offset++;
|
||||
}
|
||||
//if (parent != null) System.out.println("parent: " + parent.scope.locals.keySet());
|
||||
//System.out.println(state.scope.locals.keySet());
|
||||
generate(state, method.block());
|
||||
if (method.signature().returnType() == null)
|
||||
mv.visitInsn(RETURN);
|
||||
@@ -1748,7 +1754,7 @@ public class Codegen {
|
||||
|
||||
// Generate wrapper method
|
||||
var mv = cw2.visitMethod(ACC_PUBLIC, toMethod.name, toDescriptor, null, null);
|
||||
var state = new State(null, mv, 0);
|
||||
var state = new State(null, mv, 0, false);
|
||||
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitFieldInsn(GETFIELD, className, "wrapped", pair.from.toDescriptor());
|
||||
@@ -1772,7 +1778,7 @@ public class Codegen {
|
||||
|
||||
cw2.visitEnd();
|
||||
var bytes = cw2.toByteArray();
|
||||
converter.auxiliaries.put(className, bytes);
|
||||
compiler.auxiliaries.put(className, bytes);
|
||||
|
||||
// TODO These class loading shenanigans happen in a few places, the tests load the classes individually.
|
||||
// Instead we should just look at the folder.
|
||||
@@ -1780,7 +1786,7 @@ public class Codegen {
|
||||
converter.classLoader.findClass(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
try {
|
||||
converter.classLoader.loadClass(bytes);
|
||||
converter.classLoader.loadClass(className, bytes);
|
||||
} catch (LinkageError ignored) {}
|
||||
}
|
||||
}
|
||||
|
@@ -39,6 +39,10 @@ public class FunNGenerator {
|
||||
public final List<TargetType> inParams;
|
||||
public final List<TargetType> realParams;
|
||||
|
||||
public GenericParameters(TargetFunNType funNType) {
|
||||
this(funNType.funNParams(), funNType.returnArguments());
|
||||
}
|
||||
|
||||
public GenericParameters(List<TargetType> params, int numReturns) {
|
||||
this.realParams = params;
|
||||
this.inParams = flattenTypeParams(params);
|
||||
|
@@ -2,9 +2,11 @@
|
||||
package de.dhbwstuttgart.core;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.Codegen;
|
||||
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
||||
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
||||
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.languageServerInterface.model.LanguageServerTransferObject;
|
||||
import de.dhbwstuttgart.parser.JavaTXParser;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
||||
@@ -73,6 +75,11 @@ public class JavaTXCompiler {
|
||||
public final List<File> classPath;
|
||||
private final File outputPath;
|
||||
|
||||
public final Map<String, FunNGenerator.GenericParameters> usedFunN = new HashMap<>();
|
||||
public final Set<Integer> usedFunNSuperTypes = new HashSet<>();
|
||||
|
||||
public Map<String, byte[]> auxiliaries = new HashMap<>();
|
||||
|
||||
public DirectoryClassLoader getClassLoader() {
|
||||
return classLoader;
|
||||
}
|
||||
@@ -97,7 +104,7 @@ public class JavaTXCompiler {
|
||||
path.add(new File(System.getProperty("user.dir")));
|
||||
}
|
||||
if (outputPath != null) path.add(outputPath);
|
||||
classLoader = new DirectoryClassLoader(path, ClassLoader.getPlatformClassLoader());
|
||||
classLoader = new DirectoryClassLoader(path, ClassLoader.getSystemClassLoader());
|
||||
environment = new CompilationEnvironment(sources, classLoader);
|
||||
classPath = path;
|
||||
this.outputPath = outputPath;
|
||||
@@ -393,7 +400,12 @@ public class JavaTXCompiler {
|
||||
logFile.write(ASTTypePrinter.print(sf));
|
||||
System.out.println(ASTTypePrinter.print(sf));
|
||||
logFile.flush();
|
||||
System.out.println("Unify nach Oder-Constraints-Anpassung:" + unifyCons.toString());
|
||||
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);
|
||||
@@ -416,7 +428,14 @@ public class JavaTXCompiler {
|
||||
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
|
||||
urm.addUnifyResultListener(li);
|
||||
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm, usedTasks);
|
||||
System.out.println("RESULT Final: " + li.getResults());
|
||||
//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();
|
||||
@@ -457,6 +476,85 @@ public class JavaTXCompiler {
|
||||
return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* TEMPORARY - Only for Language Server Usage
|
||||
*/
|
||||
public LanguageServerTransferObject getResultSetAndAbstractSyntax(File file) throws IOException, ClassNotFoundException {
|
||||
var sf = sourceFiles.get(file);
|
||||
if(sf == null){
|
||||
sf = sourceFiles.values().stream().findFirst().get();
|
||||
}
|
||||
Set<ClassOrInterface> allClasses = new HashSet<>();
|
||||
allClasses.addAll(getAvailableClasses(sf));
|
||||
allClasses.addAll(sf.getClasses());
|
||||
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), file, this).stream().map(ASTFactory::createClass).collect(Collectors.toSet());
|
||||
for (var clazz : newClasses) {
|
||||
// Don't load classes that get recompiled
|
||||
if (sf.getClasses().stream().anyMatch(nf -> nf.getClassName().equals(clazz.getClassName())))
|
||||
continue;
|
||||
if (allClasses.stream().noneMatch(old -> old.getClassName().equals(clazz.getClassName())))
|
||||
allClasses.add(clazz);
|
||||
}
|
||||
|
||||
final ConstraintSet<Pair> cons = getConstraints(file);
|
||||
Set<Set<UnifyPair>> results = new HashSet<>();
|
||||
try {
|
||||
Writer logFile = new OutputStreamWriter(new NullOutputStream());
|
||||
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses.stream().toList(), logFile, classLoader, this);
|
||||
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons);
|
||||
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
|
||||
UnifyType lhs, rhs;
|
||||
if (((lhs = x.getLhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType) && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
|
||||
((PlaceholderType) lhs).setInnerType(true);
|
||||
((PlaceholderType) rhs).setInnerType(true);
|
||||
}
|
||||
return x;
|
||||
|
||||
};
|
||||
|
||||
|
||||
unifyCons = unifyCons.map(distributeInnerVars);
|
||||
TypeUnify unify = new TypeUnify();
|
||||
Set<PlaceholderType> varianceTPHold;
|
||||
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
||||
|
||||
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints();
|
||||
|
||||
if (resultmodel) {
|
||||
/* UnifyResultModel Anfang */
|
||||
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
|
||||
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
|
||||
urm.addUnifyResultListener(li);
|
||||
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm, usedTasks);
|
||||
generateBytecode(sf, li.getResults());
|
||||
return new LanguageServerTransferObject(li.getResults(), sf, ASTTypePrinter.print(sf), generatedGenerics);
|
||||
}
|
||||
/* UnifyResultModel End */
|
||||
else {
|
||||
Set<Set<UnifyPair>> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons, finiteClosure), usedTasks);
|
||||
results.addAll(result);
|
||||
|
||||
results = results.stream().map(x -> {
|
||||
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> {
|
||||
if (y.getPairOp() == PairOperator.SMALLERDOTWC)
|
||||
y.setPairOp(PairOperator.EQUALSDOT);
|
||||
return y; // alle Paare a <.? b erden durch a =. b ersetzt
|
||||
}).collect(Collectors.toCollection(HashSet::new)));
|
||||
if (res.isPresent()) {// wenn subst ein Erg liefert wurde was veraendert
|
||||
return new TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure);
|
||||
} else
|
||||
return x; // wenn nichts veraendert wurde wird x zurueckgegeben
|
||||
}).collect(Collectors.toCollection(HashSet::new));
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
}
|
||||
generateBytecode(sf, results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList()));
|
||||
return new LanguageServerTransferObject(results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList()), sf, ASTTypePrinter.print(sf), generatedGenerics);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine Variance !=0 hat auf alle Typvariablen in Theta.
|
||||
*
|
||||
@@ -631,12 +729,12 @@ public class JavaTXCompiler {
|
||||
var codegen = new Codegen(converter.convert(clazz), this, converter);
|
||||
var code = codegen.generate();
|
||||
generatedClasses.put(clazz.getClassName(), code);
|
||||
converter.auxiliaries.forEach((name, source) -> {
|
||||
generatedClasses.put(new JavaClassName(name), source);
|
||||
});
|
||||
}
|
||||
generatedGenerics.put(sf, converter.javaGenerics());
|
||||
converter.generateFunNTypes();
|
||||
auxiliaries.forEach((name, source) -> {
|
||||
generatedClasses.put(new JavaClassName(name), source);
|
||||
});
|
||||
return generatedClasses;
|
||||
}
|
||||
|
||||
|
@@ -1,13 +0,0 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* Imitiert die Environment beim Aufruf des JavaCompilers auf einer Menge von java-Dateien Die Environment enth<EFBFBD>lt automatisch die Java Standard Library
|
||||
* Imitiert die Environment beim Aufruf des JavaCompilers auf einer Menge von java-Dateien Die Environment enthält automatisch die Java Standard Library
|
||||
*
|
||||
* @param sourceFiles die zu kompilierenden Dateien
|
||||
*/
|
||||
|
@@ -16,7 +16,7 @@ public class DirectoryClassLoader extends URLClassLoader implements IByteArrayCl
|
||||
// }
|
||||
|
||||
public DirectoryClassLoader(List<File> directory, java.lang.ClassLoader parent) {
|
||||
super(directory.stream().map(DirectoryClassLoader::dirToURL).flatMap(List::stream).toArray(URL[]::new), parent);
|
||||
super(directory.stream().map(DirectoryClassLoader::dirToURL).flatMap(List::stream).collect(Collectors.toList()).toArray(new URL[0]), parent.getParent());
|
||||
}
|
||||
|
||||
private static URL[] generateURLArray(URL url) {
|
||||
|
@@ -6,18 +6,22 @@ import java.nio.file.Path;
|
||||
|
||||
public interface IByteArrayClassLoader {
|
||||
|
||||
Class loadClass(String path) throws ClassNotFoundException;
|
||||
Class<?> loadClass(String path) throws ClassNotFoundException;
|
||||
|
||||
default Class loadClass(byte[] code) {
|
||||
return this._defineClass(null, code, 0, code.length);
|
||||
default Class<?> loadClass(byte[] code) {
|
||||
return this.loadClass(null, code);
|
||||
}
|
||||
|
||||
default Class loadClass(Path path) throws IOException {
|
||||
default Class<?> loadClass(String name, byte[] code) {
|
||||
return this._defineClass(name, code, 0, code.length);
|
||||
}
|
||||
|
||||
default Class<?> loadClass(Path path) throws IOException {
|
||||
var code = Files.readAllBytes(path);
|
||||
return this._defineClass(null, code, 0, code.length);
|
||||
}
|
||||
|
||||
public Class<?> findClass(String name) throws ClassNotFoundException;
|
||||
|
||||
Class _defineClass(String name, byte[] code, int i, int length) throws ClassFormatError;
|
||||
Class<?> _defineClass(String name, byte[] code, int i, int length) throws ClassFormatError;
|
||||
}
|
||||
|
@@ -0,0 +1,249 @@
|
||||
package de.dhbwstuttgart.languageServerInterface;
|
||||
|
||||
|
||||
import de.dhbwstuttgart.bytecode.Codegen;
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
||||
import de.dhbwstuttgart.languageServerInterface.model.LanguageServerTransferObject;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||
import de.dhbwstuttgart.target.generate.GenericsResult;
|
||||
import de.dhbwstuttgart.target.tree.TargetStructure;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Implementation of an Interface for the Language-Server to get the Resultset and abstract Syntax.
|
||||
*/
|
||||
public class LanguageServerInterface {
|
||||
|
||||
|
||||
public LanguageServerTransferObject getResultSetAndAbastractSyntax(String path, String resetNamesTo) throws IOException, URISyntaxException, ClassNotFoundException {
|
||||
NameGenerator.resetTo(resetNamesTo);
|
||||
return getResultSetAndAbstractSyntax(path);
|
||||
|
||||
}
|
||||
|
||||
public SourceFile getAst(String path, String resetNamesTo) throws IOException, URISyntaxException, ClassNotFoundException {
|
||||
NameGenerator.resetTo(resetNamesTo);
|
||||
return getAST(path);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* returns the ResultSets, GenericResultSet and the AST
|
||||
* You have to give the input as well as the path because of potential locks when the File is currently opened in an IDE.
|
||||
* Example: file:///c:/test/main.jav -> file:///c:/test/out/main.class
|
||||
*
|
||||
* @param pathAsString the URI of the File. See Example.
|
||||
* @throws IOException
|
||||
* @throws ClassNotFoundException
|
||||
* @throws URISyntaxException
|
||||
*/
|
||||
public LanguageServerTransferObject getResultSetAndAbstractSyntax(String pathAsString) throws IOException, ClassNotFoundException, URISyntaxException {
|
||||
System.setOut(new PrintStream(OutputStream.nullOutputStream()));
|
||||
|
||||
var uri = new URI(pathAsString);
|
||||
var path = Path.of(uri);
|
||||
var file = path.toFile();
|
||||
Files.createDirectories(path.getParent().resolve("out"));
|
||||
var compiler = new JavaTXCompiler(List.of(file), List.of(path.getParent().toFile()), path.getParent().resolve("out").toFile());
|
||||
|
||||
var parsedSource = compiler.sourceFiles.get(file);
|
||||
var tiResults = compiler.typeInference(file);
|
||||
|
||||
Map<JavaClassName, byte[]> bytecode = compiler.generateBytecode(parsedSource, tiResults);
|
||||
Files.createDirectories(path.getParent().resolve("out"));
|
||||
compiler.writeClassFile(bytecode, path.getParent().resolve("out").toFile(), false);
|
||||
|
||||
return new LanguageServerTransferObject(tiResults, parsedSource, "", compiler.getGeneratedGenerics());
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the AST without calculating the result
|
||||
* You have to give the input as well as the path because of potential locks when the File is currently opened in an IDE.
|
||||
* Example: file:///c:/test/main.jav -> file:///c:/test/out/main.class
|
||||
*
|
||||
* @param path the URI of the File. See Example.
|
||||
* @throws IOException
|
||||
* @throws ClassNotFoundException
|
||||
* @throws URISyntaxException
|
||||
*/
|
||||
public SourceFile getAST(String path) throws IOException, ClassNotFoundException, URISyntaxException {
|
||||
|
||||
|
||||
System.setOut(new PrintStream(OutputStream.nullOutputStream()));
|
||||
|
||||
|
||||
URI uri = new URI(path);
|
||||
ArrayList<String> pathWithoutName = new ArrayList<>(List.of(uri.getPath().split("/")));
|
||||
pathWithoutName.remove(List.of(uri.getPath().split("/")).size() - 1);
|
||||
String stringPathWithoutName = "";
|
||||
|
||||
for (String i : pathWithoutName) {
|
||||
stringPathWithoutName += "/" + i;
|
||||
}
|
||||
|
||||
try {
|
||||
FileUtils.cleanDirectory(new File(stringPathWithoutName + "/out"));
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
try {
|
||||
(new File(stringPathWithoutName + "/out")).mkdirs();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
var test = getAST(uri.getPath().split("/")[uri.getPath().split("/").length - 1], new File(stringPathWithoutName).getPath());
|
||||
System.setOut(System.out);
|
||||
return test;
|
||||
}
|
||||
|
||||
private static void writeClassFile(String name, byte[] code, Path outputPath) throws IOException {
|
||||
Files.createDirectories(outputPath);
|
||||
Files.write(outputPath.resolve(name + ".class"), code);
|
||||
}
|
||||
|
||||
public static Map<String, ? extends Class<?>> generateClassFiles(IByteArrayClassLoader classLoader, Path path, Path outputPath, String... files) throws IOException, ClassNotFoundException {
|
||||
Files.createDirectories(outputPath);
|
||||
var filenames = Arrays.stream(files).map(filename -> Path.of(path.toString(), filename).toFile()).toList();
|
||||
var compiler = new JavaTXCompiler(filenames, List.of(path.toFile(), outputPath.toFile()), outputPath.toFile());
|
||||
|
||||
var result = new HashMap<String, Class<?>>();
|
||||
for (var file : filenames) {
|
||||
var resultSet = compiler.typeInference(file);
|
||||
|
||||
var sourceFile = compiler.sourceFiles.get(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, sourceFile, classLoader);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
result.putAll(classes.stream().map(cli -> {
|
||||
try {
|
||||
return generateClass(converter.convert(cli), classLoader, converter, outputPath);
|
||||
} catch (IOException exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}).collect(Collectors.toMap(Class::getName, Function.identity())));
|
||||
|
||||
converter.generateFunNTypes();
|
||||
|
||||
for (var entry : converter.auxiliaries.entrySet()) {
|
||||
writeClassFile(entry.getKey(), entry.getValue(), outputPath);
|
||||
}
|
||||
}
|
||||
|
||||
for (var entry : compiler.loadedClasses.entrySet()) {
|
||||
var name = entry.getKey().toString();
|
||||
result.put(name, classLoader.loadClass(Path.of(entry.getValue().classFile().toURI())));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Class<?> generateClass(TargetStructure clazz, IByteArrayClassLoader classLoader, ASTToTargetAST converter, Path outputPath) throws IOException {
|
||||
Codegen codegen = new Codegen(clazz, converter.compiler, converter);
|
||||
var code = codegen.generate();
|
||||
writeClassFile(clazz.qualifiedName().getClassName(), code, outputPath);
|
||||
return classLoader.loadClass(code);
|
||||
}
|
||||
|
||||
public static Map<String, ? extends Class<?>> generateClassFiles(String filename, IByteArrayClassLoader classLoader, String filePath) throws IOException, ClassNotFoundException {
|
||||
var file = Path.of(filePath, filename).toFile();
|
||||
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()), Path.of(filePath + "/out").toFile());
|
||||
var resultSet = compiler.typeInference(file);
|
||||
|
||||
var sourceFile = compiler.sourceFiles.get(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, sourceFile, classLoader);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var result = classes.stream().map(cli -> {
|
||||
try {
|
||||
return generateClass(converter.convert(cli), classLoader, converter, Path.of(filePath + "/out/"));
|
||||
} catch (IOException exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}).collect(Collectors.toMap(Class::getName, Function.identity()));
|
||||
|
||||
converter.generateFunNTypes();
|
||||
|
||||
for (var entry : converter.auxiliaries.entrySet()) {
|
||||
writeClassFile(entry.getKey(), entry.getValue(), Path.of(filePath + "/out/"));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static SourceFile getAST(String filename, String filePath) throws IOException, ClassNotFoundException {
|
||||
var file = Path.of(filePath, filename).toFile();
|
||||
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()), Path.of(filePath + "/out").toFile());
|
||||
return compiler.sourceFiles.get(file);
|
||||
}
|
||||
|
||||
public static LanguageServerTransferObject getLanguageServerTransferObject(String filename, IByteArrayClassLoader classLoader, String filePath) throws IOException, ClassNotFoundException {
|
||||
var file = Path.of(filePath, filename).toFile();
|
||||
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()), Path.of(filePath + "/out").toFile());
|
||||
var resultSet = compiler.typeInference(file);
|
||||
|
||||
var sourceFile = compiler.sourceFiles.get(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, sourceFile, classLoader);
|
||||
compiler.generateBytecode();
|
||||
converter.generateFunNTypes();
|
||||
|
||||
var ta = converter.javaGenerics();
|
||||
var tb = converter.txGenerics();
|
||||
Map<SourceFile, List<GenericsResult>> generics = new HashMap<>();
|
||||
|
||||
ArrayList<GenericsResult> genericsResults = new ArrayList<>();
|
||||
genericsResults.addAll(ta);
|
||||
genericsResults.addAll(tb);
|
||||
generics.put(converter.compiler.sourceFiles.values().stream().findFirst().get(), ta);
|
||||
var test = new LanguageServerTransferObject(resultSet, converter.compiler.sourceFiles.values().stream().findFirst().get(), "", compiler.getGeneratedGenerics());
|
||||
return test;
|
||||
}
|
||||
|
||||
/**
|
||||
* generates Bytecode for the given Path of the File.
|
||||
* The Generated Bytecode can be found in the same place as the path, except the File lies in an /out/ Directory
|
||||
* Example: file:///c:/test/main.jav -> file:///c:/test/out/main.class
|
||||
*
|
||||
* @param uri the URI of the File. See Example.
|
||||
* @throws IOException
|
||||
* @throws ClassNotFoundException
|
||||
* @throws URISyntaxException
|
||||
*/
|
||||
public void generateBytecode(URI uri) throws IOException, ClassNotFoundException, URISyntaxException {
|
||||
|
||||
// System.setOut(new PrintStream(OutputStream.nullOutputStream()));
|
||||
//
|
||||
//
|
||||
// File inputDir = new File(uri.getPath());
|
||||
// File outFile = new File(uri.getPath() + "/out");
|
||||
// FileUtils.cleanDirectory(outFile);
|
||||
// String[] allowedEndings = {".jav"};
|
||||
// ArrayList<File> files = new ArrayList<>();
|
||||
//
|
||||
// try (Stream<Path> stream = Files.walk(Paths.get(inputDir.toURI()))) {
|
||||
// stream.filter(Files::isRegularFile)
|
||||
// .forEach(el -> files.add(el.toFile()));
|
||||
// }
|
||||
//
|
||||
//
|
||||
// List<String> javFiles = files.stream().filter(el -> el.getName().split("\\.").length >= 2 && el.getName().split("\\.")[el.getName().split("\\.").length - 1].contains("jav")).map(el -> el.getPath().replace(inputDir.getPath(), "").substring(1)).toList();
|
||||
// //TODO: Link between Files
|
||||
// generateClassFiles(new ByteArrayClassLoader(), Path.of(inputDir.toURI()), Path.of(outFile.toURI()), javFiles.toArray(new String[0]));
|
||||
// System.setOut(System.out);
|
||||
}
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
package de.dhbwstuttgart.languageServerInterface;
|
||||
|
||||
|
||||
|
||||
import de.dhbwstuttgart.languageServerInterface.model.CustomParserErrorHandler;
|
||||
import de.dhbwstuttgart.languageServerInterface.model.ParserError;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Lexer;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17ParserBaseListener;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ParserInterface {
|
||||
|
||||
public List<ParserError> getParseErrors(String input){
|
||||
|
||||
CustomParserErrorHandler errorListener = new CustomParserErrorHandler();
|
||||
CharStream charStream = CharStreams.fromString(input);
|
||||
|
||||
Java17Lexer lexer = new Java17Lexer(charStream);
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||
|
||||
Java17Parser parser = new Java17Parser(tokens);
|
||||
parser.removeErrorListeners();
|
||||
parser.addErrorListener(errorListener);
|
||||
|
||||
|
||||
ParseTree tree = parser.sourceFile();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
Java17ParserBaseListener listener = new Java17ParserBaseListener();
|
||||
walker.walk(listener, tree);
|
||||
|
||||
return errorListener.getErrorMessages();
|
||||
}
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
package de.dhbwstuttgart.languageServerInterface.model;
|
||||
|
||||
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.atn.ATNConfigSet;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
|
||||
public class CustomParserErrorHandler implements ANTLRErrorListener {
|
||||
private final List<ParserError> errorMessages = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
|
||||
int endCharPosition = charPositionInLine;
|
||||
if (offendingSymbol instanceof Token) {
|
||||
Token offendingToken = (Token) offendingSymbol;
|
||||
endCharPosition = charPositionInLine + offendingToken.getText().length();
|
||||
}
|
||||
|
||||
ParserError parserError = new ParserError(line, charPositionInLine, endCharPosition, msg);
|
||||
errorMessages.add(parserError);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportAmbiguity(Parser parser, DFA dfa, int i, int i1, boolean b, BitSet bitSet, ATNConfigSet atnConfigSet) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportAttemptingFullContext(Parser parser, DFA dfa, int i, int i1, BitSet bitSet, ATNConfigSet atnConfigSet) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportContextSensitivity(Parser parser, DFA dfa, int i, int i1, int i2, ATNConfigSet atnConfigSet) {
|
||||
|
||||
}
|
||||
|
||||
public List<ParserError> getErrorMessages() {
|
||||
return errorMessages;
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
package de.dhbwstuttgart.languageServerInterface.model;
|
||||
|
||||
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||
import de.dhbwstuttgart.target.generate.GenericsResult;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class LanguageServerTransferObject {
|
||||
List<ResultSet> resultSets;
|
||||
SourceFile Ast;
|
||||
String printedAst;
|
||||
Map<SourceFile, List<GenericsResult>> generatedGenerics = new HashMap<>();
|
||||
|
||||
|
||||
public LanguageServerTransferObject(List<ResultSet> resultSets, SourceFile Ast, String printedAst, Map<SourceFile, List<GenericsResult>> generatedGenerics) {
|
||||
this.resultSets = resultSets;
|
||||
this.Ast = Ast;
|
||||
this.printedAst = printedAst;
|
||||
this.generatedGenerics = generatedGenerics;
|
||||
}
|
||||
|
||||
public List<ResultSet> getResultSets() {return resultSets;}
|
||||
public SourceFile getAst() {return Ast;}
|
||||
public String getPrintedAst() {return printedAst;}
|
||||
public Map<SourceFile, List<GenericsResult>> getGeneratedGenerics() {return generatedGenerics;}
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
package de.dhbwstuttgart.languageServerInterface.model;
|
||||
|
||||
public class ParserError {
|
||||
|
||||
private int line;
|
||||
private int charPositionInLine;
|
||||
private int endCharPosition;
|
||||
String msg;
|
||||
|
||||
public ParserError(int line, int charPositionInLine, int endCharPosition, String msg) {
|
||||
this.line = line;
|
||||
this.charPositionInLine = charPositionInLine;
|
||||
this. endCharPosition = endCharPosition;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public int getEndCharPosition() {
|
||||
return endCharPosition;
|
||||
}
|
||||
|
||||
public void setEndCharPosition(int endCharPosition) {
|
||||
this.endCharPosition = endCharPosition;
|
||||
}
|
||||
|
||||
public void setCharPositionInLine(int charPositionInLine) {
|
||||
this.charPositionInLine = charPositionInLine;
|
||||
}
|
||||
|
||||
public void setLine(int line) {
|
||||
this.line = line;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public int getCharPositionInLine() {
|
||||
return charPositionInLine;
|
||||
}
|
||||
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package de.dhbwstuttgart.languageServerInterface.model;
|
||||
|
||||
|
||||
import com.google.common.reflect.TypeResolver;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyResultEvent;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyResultListener;
|
||||
|
||||
public class ResultSetListener implements UnifyResultListener {
|
||||
|
||||
TypeResolver typeResolver;
|
||||
|
||||
public ResultSetListener(TypeResolver typeResolver){
|
||||
this.typeResolver = typeResolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewTypeResultFound(UnifyResultEvent evt) {
|
||||
|
||||
}
|
||||
}
|
@@ -1,7 +1,12 @@
|
||||
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -11,7 +16,6 @@ import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||
import de.dhbwstuttgart.target.tree.expression.TargetUnaryOp;
|
||||
import de.dhbwstuttgart.target.generate.StatementToTargetExpression;
|
||||
import org.antlr.v4.runtime.RuleContext;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
@@ -146,7 +150,7 @@ public class StatementGenerator {
|
||||
} else {
|
||||
type = methodparameters?
|
||||
TypePlaceholder.fresh(fp.getStart(), 1, false)
|
||||
: TypePlaceholder.fresh(fp.getStart());
|
||||
: TypePlaceholder.fresh(fp.getStart(), 1, false);
|
||||
}
|
||||
ret.add(new FormalParameter(paramName, type, fp.getStart()));
|
||||
localVars.put(paramName, type);
|
||||
@@ -634,16 +638,8 @@ public class StatementGenerator {
|
||||
}
|
||||
|
||||
private Statement convert(Java17Parser.TrycatchblockContext stmt) {
|
||||
Block tryBlock = convert(stmt.block(), false);
|
||||
List<CatchClause> catchClauses = stmt.catchClause().stream().
|
||||
map(x ->
|
||||
new CatchClause(x.catchType().typeType().stream().map(y -> TypeGenerator.convert(y, reg, generics)).toList(),
|
||||
x.identifier().getText(),
|
||||
convert(x.block(), false)
|
||||
)).toList();
|
||||
|
||||
Optional<Block> finallyBlock = stmt.finallyBlock() != null ? Optional.of(convert(stmt.finallyBlock().block(), false)) : Optional.empty();
|
||||
return new TryCatchFinally(tryBlock, catchClauses, finallyBlock, stmt.getStart());
|
||||
// TODO
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Statement convert(Java17Parser.TrycatchresourceContext stmt) {
|
||||
@@ -1069,7 +1065,7 @@ public class StatementGenerator {
|
||||
List<Pattern> parameterList = new ArrayList<>();
|
||||
for (IdentifierContext identifier : lambdaParams.identifier()) {
|
||||
Token offset = identifier.getStart();
|
||||
parameterList.add(new FormalParameter(identifier.getText(), TypePlaceholder.fresh(offset), offset));
|
||||
parameterList.add(new FormalParameter(identifier.getText(), TypePlaceholder.fresh(offset, 1, false), offset));
|
||||
}
|
||||
params = new ParameterList(parameterList, lambdaParams.getStart());
|
||||
} else if (lambdaParams.formalParameterList() != null) {
|
||||
@@ -1079,7 +1075,7 @@ public class StatementGenerator {
|
||||
List<Pattern> parameterList = new ArrayList<>();
|
||||
for (LambdaLVTIParameterContext param : lambdaParams.lambdaLVTIList().lambdaLVTIParameter()) {
|
||||
Token offset = param.getStart();
|
||||
parameterList.add(new FormalParameter(param.identifier().getText(), TypePlaceholder.fresh(offset), offset));
|
||||
parameterList.add(new FormalParameter(param.identifier().getText(), TypePlaceholder.fresh(offset, 1, false), offset));
|
||||
}
|
||||
params = new ParameterList(parameterList, lambdaParams.getStart());
|
||||
} else {
|
||||
@@ -1103,9 +1099,9 @@ public class StatementGenerator {
|
||||
block = lambdaGenerator.convert(expression.lambdaBody().block(), true);
|
||||
}
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>();
|
||||
funNParams.add(TypePlaceholder.fresh(expression.getStart()));// ret-Type
|
||||
funNParams.add(TypePlaceholder.fresh(expression.getStart(), -1, false));// ret-Type
|
||||
params.getFormalparalist().forEach(formalParameter -> // Für jeden Parameter einen TPH anfügen:
|
||||
funNParams.add(TypePlaceholder.fresh(expression.getStart())));
|
||||
funNParams.add(TypePlaceholder.fresh(expression.getStart(), 1, false)));
|
||||
RefTypeOrTPHOrWildcardOrGeneric lambdaType = TypePlaceholder.fresh(expression.getStart());
|
||||
// RefType lambdaType = new
|
||||
// RefType(reg.getName("Fun"+params.getFormalparalist().size()),
|
||||
|
@@ -39,11 +39,6 @@ public class SyntacticSugar {
|
||||
public void visit(LambdaExpression le) {
|
||||
//PL 2024-04-09 Do nothing, as in a LambdaExpression a return could be
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(TryCatchFinally tryCatchFinally) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasReturn(Block block) {
|
||||
|
@@ -41,7 +41,7 @@ public class JavaClassName {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt von einem Klassennamen nur den Namen der Klasse zur<EFBFBD>ck
|
||||
* Gibt von einem Klassennamen nur den Namen der Klasse zurück
|
||||
* Beispiel:
|
||||
* java.lang.Object wird zu: Object
|
||||
*/
|
||||
|
@@ -5,9 +5,9 @@ import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Speichert die Klassen f<EFBFBD>r einen bestimmten Projektscope
|
||||
* Speichert die Klassen für einen bestimmten Projektscope
|
||||
*/
|
||||
public class JavaClassRegistry {
|
||||
public class JavaClassRegistry{
|
||||
final Map<JavaClassName, Integer> existingClasses = new HashMap<>();
|
||||
|
||||
public JavaClassRegistry(Map<String, Integer> initialNames) {
|
||||
@@ -22,6 +22,10 @@ public class JavaClassRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
public Set<JavaClassName> getAllClassNames(){
|
||||
return existingClasses.keySet();
|
||||
}
|
||||
|
||||
public void addName(String className, int numberOfGenerics) {
|
||||
existingClasses.put(new JavaClassName(className), numberOfGenerics);
|
||||
}
|
||||
|
@@ -1,6 +1,5 @@
|
||||
package de.dhbwstuttgart.syntaxtree;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.statement.TryCatchFinally;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
|
||||
public interface ASTVisitor extends StatementVisitor{
|
||||
@@ -41,6 +40,4 @@ public interface ASTVisitor extends StatementVisitor{
|
||||
|
||||
void visit(GuardedPattern aGuardedPattern);
|
||||
|
||||
void visit(TryCatchFinally tryCatchFinally);
|
||||
|
||||
}
|
||||
|
@@ -1,19 +0,0 @@
|
||||
package de.dhbwstuttgart.syntaxtree;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Block;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CatchClause {
|
||||
public List<RefTypeOrTPHOrWildcardOrGeneric> exceptionTypes;
|
||||
public String identifier;
|
||||
public Block catchBlock;
|
||||
|
||||
public CatchClause(List<RefTypeOrTPHOrWildcardOrGeneric> exceptionTypes, String identifier, Block catchBlock){
|
||||
this.exceptionTypes = exceptionTypes;
|
||||
this.identifier = identifier;
|
||||
this.catchBlock = catchBlock;
|
||||
}
|
||||
}
|
||||
|
@@ -6,10 +6,12 @@ import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.target.tree.TargetGeneric;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces
|
||||
@@ -31,6 +33,7 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
||||
private List<RefType> implementedInterfaces;
|
||||
private List<RefType> permittedSubtypes;
|
||||
private List<Constructor> constructors;
|
||||
private Set<GenericTypeVar> userDefinedGenerics;
|
||||
|
||||
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, Optional<Method> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, Boolean isFunctionalInterface, List<RefType> implementedInterfaces, List<RefType> permittedSubtypes, Token offset, String fileName) {
|
||||
super(offset);
|
||||
@@ -199,4 +202,22 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
||||
public int hashCode() {
|
||||
return Objects.hash(name);
|
||||
}
|
||||
|
||||
public Set<GenericTypeVar> getUserDefinedGenerics() {
|
||||
if (this.userDefinedGenerics != null) return this.userDefinedGenerics;
|
||||
|
||||
var genericsIter = getGenerics().iterator();
|
||||
if (genericsIter.hasNext()) {
|
||||
// Add empty set of generics to cache so that it doesn't try to calculate it later
|
||||
this.userDefinedGenerics = new HashSet<>();
|
||||
while (genericsIter.hasNext()) {
|
||||
var next = genericsIter.next();
|
||||
userDefinedGenerics.add(next);
|
||||
}
|
||||
} else {
|
||||
this.userDefinedGenerics = new HashSet<>();
|
||||
}
|
||||
|
||||
return this.userDefinedGenerics;
|
||||
}
|
||||
}
|
||||
|
@@ -5,8 +5,10 @@ import java.util.*;
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
//import sun.security.x509.X509CertInfo;
|
||||
|
||||
public class SourceFile extends SyntaxTreeNode {
|
||||
@@ -18,6 +20,7 @@ public class SourceFile extends SyntaxTreeNode {
|
||||
private boolean isGenerated;
|
||||
|
||||
public List<ClassOrInterface> availableClasses = new ArrayList<>();
|
||||
public List<ASTToTargetAST.Generics> generics = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Die SourceFile repräsntiert eine zu einem Syntaxbaum eingelesene Java-Datei.
|
||||
@@ -40,6 +43,10 @@ public class SourceFile extends SyntaxTreeNode {
|
||||
this.imports = new HashSet<>(sf.imports);
|
||||
}
|
||||
|
||||
public void addResultSet(ResultSet rs) {
|
||||
|
||||
}
|
||||
|
||||
public void setPackageName(String packageName) {
|
||||
this.pkgName = packageName;
|
||||
}
|
||||
|
@@ -85,6 +85,4 @@ public interface StatementVisitor {
|
||||
void visit(Throw aThrow);
|
||||
|
||||
void visit(Ternary ternary);
|
||||
|
||||
void visit(TryCatchFinally tryCatchFinally);
|
||||
}
|
||||
|
@@ -13,6 +13,10 @@ public class NameGenerator {
|
||||
public static void reset() {
|
||||
strNextName = "A";
|
||||
}
|
||||
|
||||
public static void resetTo(String name) {
|
||||
strNextName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Berechnet einen neuen, eindeutigen Namen f�r eine neue
|
||||
|
@@ -1,30 +0,0 @@
|
||||
package de.dhbwstuttgart.syntaxtree.statement;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.CatchClause;
|
||||
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class TryCatchFinally extends Statement{
|
||||
|
||||
public Block tryBlock;
|
||||
public List<CatchClause> catchClauses;
|
||||
public Optional<Block> finallyBlock;
|
||||
|
||||
public TryCatchFinally(Block tryBlock, List<CatchClause> catchClauses, Optional<Block> finallyBlock, Token offset){
|
||||
super(new Void(offset), offset);
|
||||
this.tryBlock = tryBlock;
|
||||
this.catchClauses = catchClauses;
|
||||
this.finallyBlock = finallyBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(StatementVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
@@ -530,9 +530,4 @@ public class OutputGenerator implements ASTVisitor {
|
||||
out.append(" with ");
|
||||
aGuardedPattern.getCondition().accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(TryCatchFinally tryCatchFinally) {
|
||||
out.append("");
|
||||
}
|
||||
}
|
@@ -1,8 +1,8 @@
|
||||
|
||||
package de.dhbwstuttgart.target.generate;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
@@ -12,6 +12,8 @@ import de.dhbwstuttgart.syntaxtree.Record;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
|
||||
import de.dhbwstuttgart.syntaxtree.visual.OutputGenerator;
|
||||
import de.dhbwstuttgart.target.tree.*;
|
||||
import de.dhbwstuttgart.target.tree.expression.*;
|
||||
import de.dhbwstuttgart.target.tree.type.*;
|
||||
@@ -35,7 +37,6 @@ public class ASTToTargetAST {
|
||||
public Generics generics;
|
||||
public List<Generics> currentMethodOverloads;
|
||||
|
||||
final Map<ClassOrInterface, Set<GenericTypeVar>> userDefinedGenerics = new HashMap<>();
|
||||
final Map<Method, Set<SignaturePair>> tphsInMethods = new HashMap<>();
|
||||
private Method currentMethod;
|
||||
|
||||
@@ -60,17 +61,19 @@ public class ASTToTargetAST {
|
||||
}
|
||||
|
||||
public record Generics(JavaGenerics javaGenerics, TxGenerics txGenerics) {
|
||||
public Generics(JavaTXCompiler compiler, ResultSet set) {
|
||||
this(new JavaGenerics(compiler, set), new TxGenerics(compiler, set));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public IByteArrayClassLoader classLoader;
|
||||
protected SourceFile sourceFile;
|
||||
|
||||
public ASTToTargetAST(List<ResultSet> resultSets) {
|
||||
this(null, resultSets);
|
||||
public ASTToTargetAST(List<ResultSet> resultSets, IByteArrayClassLoader classLoader) {
|
||||
this(null, resultSets, classLoader);
|
||||
}
|
||||
public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets) {
|
||||
this(compiler, resultSets, null, new ByteArrayClassLoader());
|
||||
public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets, IByteArrayClassLoader classLoader) {
|
||||
this(compiler, resultSets, null, classLoader);
|
||||
}
|
||||
|
||||
public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets, SourceFile sourceFile, IByteArrayClassLoader classLoader) {
|
||||
@@ -80,9 +83,9 @@ public class ASTToTargetAST {
|
||||
|
||||
all = new ArrayList<>();
|
||||
for (var set : resultSets) {
|
||||
all.add(new Generics(new JavaGenerics(this, set), new TxGenerics(this, set)));
|
||||
all.add(new Generics(compiler, set));
|
||||
}
|
||||
this.generics = all.get(0);
|
||||
this.generics = all.getFirst();
|
||||
}
|
||||
|
||||
public void addSignaturePair(TypePlaceholder signature, RefTypeOrTPHOrWildcardOrGeneric parameter) {
|
||||
@@ -92,9 +95,13 @@ public class ASTToTargetAST {
|
||||
}
|
||||
|
||||
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();
|
||||
while (method.isEmpty()) {
|
||||
method = owner.getMethods().stream().filter(m -> m.name.equals(name) && parameterEquals(m.getParameterList(), argumentList)).findFirst();
|
||||
method = owner.getMethods().stream().filter(m -> m.name.equals(name) && parameterEquals(m.getParameterList(), argumentList, generics)).findFirst();
|
||||
if (owner.getClassName().toString().equals("java.lang.Object")) break;
|
||||
owner = compiler.getClass(owner.getSuperClass().getName());
|
||||
}
|
||||
@@ -102,16 +109,16 @@ public class ASTToTargetAST {
|
||||
}
|
||||
|
||||
Optional<Constructor> findConstructor(ClassOrInterface owner, List<TargetType> argumentList) {
|
||||
return owner.getConstructors().stream().filter(c -> parameterEquals(c.getParameterList(), argumentList)).findFirst();
|
||||
return owner.getConstructors().stream().filter(c -> parameterEquals(c.getParameterList(), argumentList, generics.javaGenerics)).findFirst();
|
||||
}
|
||||
|
||||
boolean parameterEquals(ParameterList parameterList, List<TargetType> arguments) {
|
||||
static boolean parameterEquals(ParameterList parameterList, List<TargetType> arguments, GenerateGenerics generics) {
|
||||
var pars = parameterList.getFormalparalist();
|
||||
if (pars.size() != arguments.size())
|
||||
return false;
|
||||
|
||||
for (var i = 0; i < pars.size(); i++) {
|
||||
var type1 = convert(pars.get(i).getType(), generics.javaGenerics);
|
||||
var type1 = generics.getTargetType(pars.get(i).getType());
|
||||
var type2 = arguments.get(i);
|
||||
if (type1 instanceof TargetGenericType)
|
||||
return true;
|
||||
@@ -349,19 +356,14 @@ public class ASTToTargetAST {
|
||||
Set<TargetGeneric> javaGenerics = new HashSet<>();
|
||||
Set<TargetGeneric> txGenerics = new HashSet<>();
|
||||
|
||||
var genericsIter = input.getGenerics().iterator();
|
||||
if (genericsIter.hasNext()) {
|
||||
var userDefinedGenerics = input.getUserDefinedGenerics();
|
||||
if (!userDefinedGenerics.isEmpty()) {
|
||||
// Add empty set of generics to cache so that it doesn't try to calculate it later
|
||||
var userDefinedGenerics = new HashSet<GenericTypeVar>();
|
||||
this.userDefinedGenerics.put(input, userDefinedGenerics);
|
||||
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))));
|
||||
for (var generic : userDefinedGenerics) {
|
||||
// TODO Support multiple bouds
|
||||
javaGenerics.add(new TargetGeneric(generic.getName(), convert(generic.getBounds().getFirst())));
|
||||
}
|
||||
} else {
|
||||
this.userDefinedGenerics.put(input, new HashSet<>());
|
||||
// Generate generics only if there are no user defined ones
|
||||
javaGenerics = convert(generics.javaGenerics.generics(input), generics.javaGenerics);
|
||||
txGenerics = convert(generics.txGenerics.generics(input), generics.txGenerics);
|
||||
@@ -423,7 +425,7 @@ public class ASTToTargetAST {
|
||||
}
|
||||
|
||||
private List<TargetConstructor> convert(ClassOrInterface currentClass, Constructor input, TargetBlock fieldInitializer) {
|
||||
generics = all.get(0);
|
||||
generics = all.getFirst();
|
||||
List<TargetConstructor> result = new ArrayList<>();
|
||||
Set<List<MethodParameter>> parameterSet = new HashSet<>();
|
||||
this.currentMethod = input;
|
||||
@@ -467,13 +469,6 @@ 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) {
|
||||
if (methods.isEmpty()) throw new DebugException("Couldn't find a candidate for switch overloading");
|
||||
if (methods.size() == 1) {
|
||||
@@ -744,11 +739,6 @@ public class ASTToTargetAST {
|
||||
return new TargetField(input.modifier, convert(input.getType(), generics.javaGenerics), input.getName());
|
||||
}
|
||||
|
||||
private final Map<String, FunNGenerator.GenericParameters> usedFunN = new HashMap<>();
|
||||
private final Set<Integer> usedFunNSuperTypes = new HashSet<>();
|
||||
|
||||
public Map<String, byte[]> auxiliaries = new HashMap<>();
|
||||
|
||||
public TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input) {
|
||||
return convert(input, generics.javaGenerics);
|
||||
}
|
||||
@@ -781,7 +771,15 @@ public class ASTToTargetAST {
|
||||
return TargetFunNType.fromParams(params, filteredParams, gep.getReturnType() != null ? 1 : 0);
|
||||
}
|
||||
|
||||
private FunNGenerator.GenericParameters convertToParameters(TargetFunNType input) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isSubtype(TargetType test, TargetType other) {
|
||||
if (other.equals(TargetType.Object)) return true;
|
||||
if (test instanceof TargetFunNType tfun && other instanceof TargetFunNType ofun)
|
||||
return isSubtype(new FunNGenerator.GenericParameters(tfun), new FunNGenerator.GenericParameters(ofun));
|
||||
|
||||
var testClass = compiler.getClass(new JavaClassName(test.name()));
|
||||
var otherClass = compiler.getClass(new JavaClassName(other.name()));
|
||||
if (testClass == null) return false;
|
||||
@@ -809,28 +807,24 @@ public class ASTToTargetAST {
|
||||
}
|
||||
|
||||
public void generateFunNTypes() {
|
||||
for (var entry : usedFunN.entrySet()) {
|
||||
for (var entry : compiler.usedFunN.entrySet()) {
|
||||
var gep = entry.getValue();
|
||||
var superInterfaces = usedFunN.values().stream()
|
||||
var superInterfaces = compiler.usedFunN.values().stream()
|
||||
.filter(g -> !g.equals(gep))
|
||||
.filter(genericParameters -> isSubtype(gep, genericParameters))
|
||||
.map(FunNGenerator::getSpecializedClassName)
|
||||
.toList();
|
||||
|
||||
var code = FunNGenerator.generateSpecializedBytecode(gep, superInterfaces);
|
||||
|
||||
try {
|
||||
classLoader.findClass(entry.getKey());
|
||||
} catch (ClassNotFoundException e) {
|
||||
try {
|
||||
classLoader.loadClass(code);
|
||||
} catch (LinkageError ignored) {}
|
||||
}
|
||||
auxiliaries.put(entry.getKey(), code);
|
||||
compiler.auxiliaries.put(entry.getKey(), code);
|
||||
}
|
||||
}
|
||||
|
||||
protected TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, GenerateGenerics generics) {
|
||||
public 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<>() {
|
||||
@Override
|
||||
public TargetType visit(RefType refType) {
|
||||
@@ -842,31 +836,31 @@ public class ASTToTargetAST {
|
||||
}
|
||||
|
||||
var params = refType.getParaList().stream().map(type -> {
|
||||
return convert(type, generics);
|
||||
return convert(type, generics, compiler);
|
||||
}).toList();
|
||||
|
||||
if (name.matches("Fun\\d+\\$\\$")) { // TODO This seems like a bad idea
|
||||
var returnType = FunNGenerator.getReturnType(params);
|
||||
var className = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), returnType);
|
||||
if (!usedFunNSuperTypes.contains(params.size())) {
|
||||
usedFunNSuperTypes.add(params.size());
|
||||
if (!compiler.usedFunNSuperTypes.contains(params.size())) {
|
||||
compiler.usedFunNSuperTypes.add(params.size());
|
||||
var code = FunNGenerator.generateSuperBytecode(params.size() - 1, returnType != null ? 1 : 0);
|
||||
var superClassName = FunNGenerator.getSuperClassName(params.size() - 1, returnType != null ? 1 : 0);
|
||||
try {
|
||||
classLoader.findClass(superClassName);
|
||||
compiler.classLoader.findClass(superClassName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
try {
|
||||
classLoader.loadClass(code);
|
||||
compiler.classLoader.loadClass(superClassName, code);
|
||||
} catch (LinkageError ignored) {}
|
||||
}
|
||||
auxiliaries.put(superClassName, code);
|
||||
compiler.auxiliaries.put(superClassName, code);
|
||||
}
|
||||
FunNGenerator.GenericParameters gep = null;
|
||||
if (!usedFunN.containsKey(className)) {
|
||||
if (!compiler.usedFunN.containsKey(className)) {
|
||||
gep = new FunNGenerator.GenericParameters(params, returnType != null ? 1 : 0);
|
||||
usedFunN.put(className, gep);
|
||||
compiler.usedFunN.put(className, gep);
|
||||
} else {
|
||||
gep = usedFunN.get(className);
|
||||
gep = compiler.usedFunN.get(className);
|
||||
}
|
||||
return flattenFunNType(params, gep);
|
||||
}
|
||||
@@ -875,7 +869,7 @@ public class ASTToTargetAST {
|
||||
|
||||
@Override
|
||||
public TargetType visit(SuperWildcardType superWildcardType) {
|
||||
return new TargetSuperWildcard(convert(superWildcardType.getInnerType(), generics));
|
||||
return new TargetSuperWildcard(convert(superWildcardType.getInnerType(), generics, compiler));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -885,7 +879,7 @@ public class ASTToTargetAST {
|
||||
|
||||
@Override
|
||||
public TargetType visit(ExtendsWildcardType extendsWildcardType) {
|
||||
return new TargetExtendsWildcard(convert(extendsWildcardType.getInnerType(), generics));
|
||||
return new TargetExtendsWildcard(convert(extendsWildcardType.getInnerType(), generics, compiler));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -1,5 +1,7 @@
|
||||
package de.dhbwstuttgart.target.generate;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.parser.JavaTXParser;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
@@ -18,7 +20,7 @@ import java.util.stream.Stream;
|
||||
|
||||
public abstract class GenerateGenerics {
|
||||
|
||||
private final ASTToTargetAST astToTargetAST;
|
||||
private final JavaTXCompiler compiler;
|
||||
|
||||
public class TPH {
|
||||
private final TypePlaceholder wrap;
|
||||
@@ -134,8 +136,8 @@ public abstract class GenerateGenerics {
|
||||
Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes = new HashMap<>();
|
||||
Map<TypePlaceholder, TypePlaceholder> equality = new HashMap<>();
|
||||
|
||||
GenerateGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) {
|
||||
this.astToTargetAST = astToTargetAST;
|
||||
GenerateGenerics(JavaTXCompiler compiler, ResultSet constraints) {
|
||||
this.compiler = compiler;
|
||||
for (var constraint : constraints.results) {
|
||||
if (constraint instanceof PairTPHsmallerTPH p) {
|
||||
System.out.println(p.left + " " + p.left.getVariance());
|
||||
@@ -281,7 +283,7 @@ public abstract class GenerateGenerics {
|
||||
Set<TPH> typeVariablesOfClass,
|
||||
Set<Pair> result
|
||||
) {
|
||||
var userDefinedGenericsOfClass = astToTargetAST.userDefinedGenerics.get(owner);
|
||||
var userDefinedGenericsOfClass = owner.getUserDefinedGenerics();
|
||||
|
||||
// Type variables with bounds that are also type variables of the method
|
||||
for (var typeVariable : new HashSet<>(typeVariables)) {
|
||||
@@ -329,7 +331,7 @@ public abstract class GenerateGenerics {
|
||||
|
||||
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver) {
|
||||
if (expressionReceiver.expr instanceof This) {
|
||||
var optMethod = astToTargetAST.findMethod(owner, methodCall.name, methodCall.signatureArguments().stream().map(astToTargetAST::convert).toList());
|
||||
var optMethod = ASTToTargetAST.findMethod(owner, methodCall.name, methodCall.signatureArguments().stream().map(x -> getTargetType(x)).toList(), GenerateGenerics.this, compiler);
|
||||
if (optMethod.isEmpty()) return;
|
||||
var method2 = optMethod.get();
|
||||
System.out.println("In: " + method.getName() + " Method: " + method2.getName());
|
||||
@@ -434,11 +436,6 @@ public abstract class GenerateGenerics {
|
||||
whileStmt.loopBlock.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(TryCatchFinally tryCatchFinally) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ArgumentList arglist) {
|
||||
for (int i = 0; i < arglist.getArguments().size(); i++) {
|
||||
@@ -541,11 +538,6 @@ public abstract class GenerateGenerics {
|
||||
super.visit(methodCall);
|
||||
typeVariables.addAll(findTypeVariables(methodCall.getType()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(TryCatchFinally tryCatchFinally) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1015,8 +1007,8 @@ public abstract class GenerateGenerics {
|
||||
}
|
||||
var type = concreteTypes.get(new TPH(tph));
|
||||
if (type == null) return new TargetGenericType(tph.getName());
|
||||
return astToTargetAST.convert(type, this);
|
||||
return ASTToTargetAST.convert(type, this, compiler);
|
||||
}
|
||||
return astToTargetAST.convert(in, this);
|
||||
return ASTToTargetAST.convert(in, this, compiler);
|
||||
}
|
||||
}
|
||||
|
@@ -69,8 +69,4 @@ public class GenericsResult {
|
||||
return this.generics.getType(tph);
|
||||
return type;
|
||||
}
|
||||
|
||||
public TargetType resolveTarget(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||
return this.generics.getTargetType(type);
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package de.dhbwstuttgart.target.generate;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
@@ -7,8 +8,8 @@ import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import java.util.Set;
|
||||
|
||||
final class JavaGenerics extends GenerateGenerics {
|
||||
JavaGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) {
|
||||
super(astToTargetAST, constraints);
|
||||
JavaGenerics(JavaTXCompiler compiler, ResultSet constraints) {
|
||||
super(compiler, constraints);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -14,6 +14,7 @@ import de.dhbwstuttgart.target.tree.expression.*;
|
||||
import de.dhbwstuttgart.target.tree.type.*;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.sql.Array;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
@@ -32,59 +33,71 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private class LambdaCaptureFinder extends TracingStatementVisitor {
|
||||
|
||||
// TODO The same mechanism is implemented in Codegen, maybe use it from there?
|
||||
final Stack<Set<String>> localVariables = new Stack<>();
|
||||
private final List<MethodParameter> parameters;
|
||||
private final List<MethodParameter> captures;
|
||||
|
||||
LambdaCaptureFinder(List<MethodParameter> parameters, List<MethodParameter> captures) {
|
||||
localVariables.push(new HashSet<>());
|
||||
this.parameters = parameters;
|
||||
this.captures = captures;
|
||||
}
|
||||
|
||||
boolean hasLocalVar(String name) {
|
||||
for (var localVariables : this.localVariables) {
|
||||
if (localVariables.contains(name))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Block block) {
|
||||
localVariables.push(new HashSet<>());
|
||||
super.visit(block);
|
||||
localVariables.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(LocalVar localVar) {
|
||||
super.visit(localVar);
|
||||
var capture = new MethodParameter(new TargetTypePattern(converter.convert(localVar.getType()), localVar.name));
|
||||
if (!hasLocalVar(localVar.name) && !parameters.contains(capture) && !captures.contains(capture))
|
||||
captures.add(capture);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(LocalVarDecl varDecl) {
|
||||
var localVariables = this.localVariables.peek();
|
||||
localVariables.add(varDecl.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(LambdaExpression lambda) {
|
||||
var newCaptures = new ArrayList<MethodParameter>();
|
||||
var captureFinder = new LambdaCaptureFinder(createParameters(lambda), newCaptures);
|
||||
lambda.methodBody.accept(captureFinder);
|
||||
newCaptures.removeAll(parameters);
|
||||
captures.addAll(newCaptures);
|
||||
}
|
||||
}
|
||||
|
||||
private List<MethodParameter> createParameters(LambdaExpression lambda) {
|
||||
return StreamSupport.stream(lambda.params.spliterator(), false)
|
||||
.map(p -> (FormalParameter) p)
|
||||
.map(p -> new MethodParameter(new TargetTypePattern(converter.convert(p.getType()), p.getName())))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(LambdaExpression lambdaExpression) {
|
||||
var parameters = StreamSupport.stream(lambdaExpression.params.spliterator(), false)
|
||||
.map(p -> (FormalParameter) p)
|
||||
.map(p -> new MethodParameter(new TargetTypePattern(converter.convert(p.getType()), p.getName())))
|
||||
.toList();
|
||||
|
||||
var parameters = createParameters(lambdaExpression);
|
||||
List<MethodParameter> captures = new ArrayList<>();
|
||||
lambdaExpression.methodBody.accept(new TracingStatementVisitor() {
|
||||
// TODO The same mechanism is implemented in Codegen, maybe use it from there?
|
||||
final Stack<Set<String>> localVariables = new Stack<>();
|
||||
{
|
||||
localVariables.push(new HashSet<>());
|
||||
}
|
||||
|
||||
boolean hasLocalVar(String name) {
|
||||
for (var localVariables : this.localVariables) {
|
||||
if (localVariables.contains(name))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Block block) {
|
||||
localVariables.push(new HashSet<>());
|
||||
super.visit(block);
|
||||
localVariables.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(LocalVar localVar) {
|
||||
super.visit(localVar);
|
||||
var capture = new MethodParameter(new TargetTypePattern(converter.convert(localVar.getType()), localVar.name));
|
||||
if (!hasLocalVar(localVar.name) && !parameters.contains(capture) && !captures.contains(capture))
|
||||
captures.add(capture);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(LocalVarDecl varDecl) {
|
||||
var localVariables = this.localVariables.peek();
|
||||
localVariables.add(varDecl.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(TryCatchFinally tryCatchFinally) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(LambdaExpression lambda) {
|
||||
} // Don't look at lambda expressions
|
||||
});
|
||||
var visitor = new LambdaCaptureFinder(parameters, captures);
|
||||
lambdaExpression.methodBody.accept(visitor);
|
||||
|
||||
TargetMethod.Signature signature = new TargetMethod.Signature(Set.of(), parameters, converter.convert(lambdaExpression.getReturnType()));;
|
||||
var tpe = converter.convert(lambdaExpression.getType());
|
||||
@@ -125,7 +138,10 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(BoolExpression bool) {
|
||||
System.out.println("BoolExpression");
|
||||
result = switch(bool.operation) {
|
||||
case OR -> new TargetBinaryOp.Or(converter.convert(bool.getType()), converter.convert(bool.lexpr), converter.convert(bool.rexpr));
|
||||
case AND -> new TargetBinaryOp.And(converter.convert(bool.getType()), converter.convert(bool.lexpr), converter.convert(bool.rexpr));
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -596,14 +612,4 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
public void visit(GuardedPattern aGuardedPattern) {
|
||||
result = new TargetGuard((TargetPattern) converter.convert(aGuardedPattern.getNestedPattern()), converter.convert(aGuardedPattern.getCondition()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(TryCatchFinally tryCatchFinally) {
|
||||
|
||||
result = new TargetTryCatchFinally(
|
||||
converter.convert(tryCatchFinally.tryBlock),
|
||||
tryCatchFinally.catchClauses.stream().map(x -> new TargetCatchClause(x.exceptionTypes.stream().map(converter::convert).toList(), x.identifier, converter.convert(x.catchBlock))).toList(),
|
||||
tryCatchFinally.finallyBlock.map(converter::convert)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package de.dhbwstuttgart.target.generate;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
@@ -7,8 +8,8 @@ import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import java.util.Set;
|
||||
|
||||
final class TxGenerics extends GenerateGenerics {
|
||||
TxGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) {
|
||||
super(astToTargetAST, constraints);
|
||||
TxGenerics(JavaTXCompiler compiler, ResultSet constraints) {
|
||||
super(compiler, constraints);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -1,8 +0,0 @@
|
||||
package de.dhbwstuttgart.target.tree.expression;
|
||||
|
||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record TargetCatchClause(List<TargetType> exceptionNames, String identifier, TargetBlock catchBlock) {
|
||||
}
|
@@ -3,7 +3,7 @@ package de.dhbwstuttgart.target.tree.expression;
|
||||
import de.dhbwstuttgart.target.tree.type.*;
|
||||
|
||||
public sealed interface TargetExpression
|
||||
permits TargetBinaryOp, TargetBlock, TargetBreak, TargetCast, TargetClassName, TargetContinue, TargetDo, TargetFieldVar, TargetFor, TargetForEach, TargetIf, TargetInstanceOf, TargetLambdaExpression, TargetLiteral, TargetLocalVar, TargetPattern, TargetReturn, TargetStatementExpression, TargetSuper, TargetSwitch, TargetTernary, TargetThis, TargetThrow, TargetTryCatchFinally, TargetUnaryOp, TargetVarDecl, TargetWhile, TargetYield {
|
||||
permits TargetBinaryOp, TargetBlock, TargetBreak, TargetCast, TargetClassName, TargetContinue, TargetDo, TargetFieldVar, TargetFor, TargetForEach, TargetIf, TargetInstanceOf, TargetLambdaExpression, TargetLiteral, TargetLocalVar, TargetPattern, TargetReturn, TargetStatementExpression, TargetSuper, TargetSwitch, TargetTernary, TargetThis, TargetThrow, TargetUnaryOp, TargetVarDecl, TargetWhile, TargetYield {
|
||||
|
||||
default TargetType type() {
|
||||
return null;
|
||||
|
@@ -1,7 +0,0 @@
|
||||
package de.dhbwstuttgart.target.tree.expression;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public record TargetTryCatchFinally(TargetBlock tryBlock, List<TargetCatchClause> catchClauses, Optional<TargetBlock> finallyBlock) implements TargetExpression{
|
||||
}
|
@@ -2,7 +2,6 @@ package de.dhbwstuttgart.typedeployment;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.TryCatchFinally;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.target.generate.GenericsResult;
|
||||
import de.dhbwstuttgart.target.generate.GenericsResultSet;
|
||||
@@ -33,11 +32,6 @@ public class TypeInsertPlacer extends AbstractASTWalker {
|
||||
TypeInsertPlacerClass cl = new TypeInsertPlacerClass(classOrInterface, withResults, genericsResult);
|
||||
this.inserts.addAll(cl.inserts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(TryCatchFinally tryCatchFinally) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class TypeInsertPlacerClass extends AbstractASTWalker{
|
||||
@@ -69,11 +63,6 @@ class TypeInsertPlacerClass extends AbstractASTWalker{
|
||||
super.visit(method);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(TryCatchFinally tryCatchFinally) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Field field) {
|
||||
if(field.getType() instanceof TypePlaceholder){
|
||||
|
@@ -6,7 +6,7 @@ import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class Constraint<A> extends HashSet<A> {
|
||||
public class Constraint<A> extends HashSet<A> implements Comparable<Constraint<A>> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Boolean isInherited = false;//wird beides nur für die Method-Constraints benoetigt
|
||||
private Boolean isImplemented = false;
|
||||
@@ -73,5 +73,9 @@ public class Constraint<A> extends HashSet<A> {
|
||||
public String toStringBase() {
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int compareTo(Constraint<A> o) {
|
||||
return this.toString().compareTo(o.toString());
|
||||
}
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
/**
|
||||
* Paare, welche das Unifikationsergebnis darstellen
|
||||
*/
|
||||
public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B extends RefTypeOrTPHOrWildcardOrGeneric> {
|
||||
public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric, B extends RefTypeOrTPHOrWildcardOrGeneric> implements Comparable<ResultPair<A,B>> {
|
||||
private final A left;
|
||||
private final B right;
|
||||
|
||||
@@ -58,5 +58,14 @@ public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B ext
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ResultPair<A, B> o) {
|
||||
if (o == null) {
|
||||
return 1; // this is greater than null
|
||||
}
|
||||
|
||||
return o.left.toString().compareTo(this.left.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,6 +1,8 @@
|
||||
package de.dhbwstuttgart.typeinference.result;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
@@ -12,7 +14,7 @@ import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class ResultSet {
|
||||
public class ResultSet implements Comparable<ResultSet>{
|
||||
|
||||
public final Set<ResultPair> results;
|
||||
public Set<ResultPair<TypePlaceholder, TypePlaceholder>> genIns;
|
||||
@@ -22,6 +24,10 @@ public class ResultSet {
|
||||
this.genIns = new HashSet<>();
|
||||
results.forEach(x -> { if (x instanceof PairTPHsmallerTPH) { this.genIns.add(x);}} );
|
||||
}
|
||||
|
||||
public List<ResultPair> getSortedResults() {
|
||||
return results.stream().sorted().toList();
|
||||
}
|
||||
|
||||
public boolean contains(ResultPair toCheck) {
|
||||
return this.results.contains(toCheck);
|
||||
@@ -63,6 +69,21 @@ public class ResultSet {
|
||||
public int hashCode() {
|
||||
return results.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ResultSet o) {
|
||||
List<ResultPair> thisSorted = this.getSortedResults();
|
||||
List<ResultPair> otherSorted = o.getSortedResults();
|
||||
int sizeCompare = Integer.compare(thisSorted.size(), otherSorted.size());
|
||||
if (sizeCompare != 0) return sizeCompare;
|
||||
|
||||
for (int i = 0; i < thisSorted.size(); i++) {
|
||||
int cmp = thisSorted.get(i).compareTo(otherSorted.get(i));
|
||||
if (cmp != 0) return cmp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
class Resolver implements ResultSetVisitor {
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package de.dhbwstuttgart.typeinference.typeAlgo;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.SourceLoc;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
@@ -9,15 +10,18 @@ import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.target.tree.type.TargetRefType;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||
import de.dhbwstuttgart.util.BiRelation;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
|
||||
public class TYPE {
|
||||
@@ -87,12 +91,25 @@ public class TYPE {
|
||||
TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m);
|
||||
TYPEStmt methodScope = new TYPEStmt(blockInfo);
|
||||
ConstraintSet constraintSet = new ConstraintSet();
|
||||
m.getParameterList().getFormalparalist().forEach(el -> {
|
||||
if(el instanceof RecordPattern){
|
||||
constraintSet.addAll(addRecursiveParameterConstraints((RecordPattern) el, blockInfo));
|
||||
|
||||
}
|
||||
});
|
||||
if (m.name.equals("main") && Modifier.isStatic(m.modifier) && m.getParameterList().getFormalparalist().size() == 1) {
|
||||
// Add constraint for main method
|
||||
var firstParam = m.getParameterList().getParameterAt(0);
|
||||
|
||||
constraintSet.addUndConstraint(new Pair(firstParam.getType(),
|
||||
new RefType(new JavaClassName("java.util.List"),
|
||||
List.of(new RefType(new JavaClassName("java.lang.String"), new NullToken())),
|
||||
new NullToken()),
|
||||
PairOperator.EQUALSDOT));
|
||||
} else {
|
||||
m.getParameterList().getFormalparalist().forEach(el -> {
|
||||
if (el instanceof RecordPattern rp){
|
||||
constraintSet.addAll(addRecursiveParameterConstraints(rp, blockInfo));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
m.block.accept(methodScope);
|
||||
constraintSet.addAll(methodScope.getConstraints());
|
||||
return constraintSet;
|
||||
|
@@ -73,7 +73,7 @@ public class TYPEStmt implements StatementVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(LambdaExpression lambdaExpression) {
|
||||
TypePlaceholder tphRetType = TypePlaceholder.fresh(new NullToken());
|
||||
TypePlaceholder tphRetType = TypePlaceholder.fresh(new NullToken(), -1, false);
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> lambdaParams = lambdaExpression.params.getFormalparalist().stream().map((formalParameter -> formalParameter.getType())).collect(Collectors.toList());
|
||||
lambdaParams.add(tphRetType);
|
||||
// lambdaParams.add(0,tphRetType);
|
||||
@@ -500,12 +500,6 @@ public class TYPEStmt implements StatementVisitor {
|
||||
constraintsSet.addUndConstraint(new Pair(ternary.iffalse.getType(), ternary.getType(), PairOperator.SMALLERDOT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(TryCatchFinally tryCatchFinally) {
|
||||
tryCatchFinally.tryBlock.accept(this);
|
||||
tryCatchFinally.catchClauses.forEach(c -> c.catchBlock.accept(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Return returnExpr) {
|
||||
returnExpr.retexpr.accept(this);
|
||||
@@ -641,6 +635,7 @@ public class TYPEStmt implements StatementVisitor {
|
||||
params.add(resolver.resolve(new GenericRefType(gtv.getName(), new NullToken())));
|
||||
}
|
||||
RefTypeOrTPHOrWildcardOrGeneric receiverType;
|
||||
|
||||
if (receiver instanceof FunNClass) {
|
||||
receiverType = new RefType(new JavaClassName(receiver.getClassName().toString() + "$$"), params, new NullToken()); // new FunN(params);
|
||||
} else {
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -53,7 +53,7 @@ class Node<T> {
|
||||
addDescendant(descendant);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a directed edge from the predecessor to this node (predecessor -> this)
|
||||
*/
|
||||
@@ -73,7 +73,7 @@ class Node<T> {
|
||||
addPredecessor(predecessor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The content of this node.
|
||||
*/
|
||||
|
@@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static targetast.TestCodegen.generateClassFiles;
|
||||
|
||||
import java.io.File;
|
||||
@@ -9,13 +9,12 @@ import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
|
||||
public class AllgemeinTest {
|
||||
|
||||
|
@@ -6,12 +6,12 @@ import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class GenericsParserTest {
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
@@ -24,7 +24,7 @@ public class TestPackages {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("This doesn't work")
|
||||
@Disabled("This doesn't work")
|
||||
public void testPackagesCircular() throws Exception {
|
||||
var cmp = new JavaTXCompiler(
|
||||
List.of(
|
||||
|
@@ -4,7 +4,7 @@ import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||
import de.dhbwstuttgart.typedeployment.TypeInsert;
|
||||
import de.dhbwstuttgart.typedeployment.TypeInsertFactory;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
|
@@ -4,7 +4,7 @@ package astfactory;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
@@ -12,7 +12,8 @@ import java.lang.reflect.TypeVariable;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
public class ASTFactoryTest<A> extends HashMap<String, A>{
|
||||
@Test
|
||||
|
@@ -3,7 +3,7 @@ package finiteClosure;
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.FCGenerator;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
@@ -0,0 +1,51 @@
|
||||
package languageServerInterfaceTest;
|
||||
|
||||
import de.dhbwstuttgart.core.ConsoleInterface;
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
||||
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import de.dhbwstuttgart.languageServerInterface.LanguageServerInterface;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class LangaugeServerInterfaceTest {
|
||||
@Test
|
||||
@Ignore
|
||||
public void consoleInterfaceTest() throws IOException, ClassNotFoundException, URISyntaxException {
|
||||
|
||||
|
||||
LanguageServerInterface languageServerInterface = new LanguageServerInterface();
|
||||
var resp = languageServerInterface.getResultSetAndAbstractSyntax("/home/ruben/code/JavaCompilerCore/src/test/java/languageServerInterfaceTest/test.jav");
|
||||
|
||||
System.out.println("\n-----------------------------------------\n");
|
||||
System.out.println(ASTPrinter.print(resp.getAst()));
|
||||
System.out.println("\n-----------------------------------------\n");
|
||||
|
||||
LanguageServerInterface languageServerInterface2 = new LanguageServerInterface();
|
||||
var ast = languageServerInterface2.getAst("/home/ruben/code/JavaCompilerCore/src/test/java/languageServerInterfaceTest/test.jav", "N");
|
||||
|
||||
System.out.println("\n-----------------------------------------\n");
|
||||
System.out.println(ASTPrinter.print(ast));
|
||||
System.out.println("\n-----------------------------------------\n");
|
||||
System.out.println("");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testBytecodeGen() throws IOException, ClassNotFoundException, URISyntaxException {
|
||||
|
||||
//TODO: Ordner und Datei löschen wenn sie bereits existieren
|
||||
LanguageServerInterface languageServerInterface = new LanguageServerInterface();
|
||||
languageServerInterface.generateBytecode(new URI("c%3A/Users/ruben/Neuer%20Ordner%20%282%29/LSP-Vortrag/images/"));
|
||||
}
|
||||
}
|
5
src/test/java/languageServerInterfaceTest/test.jav
Normal file
5
src/test/java/languageServerInterfaceTest/test.jav
Normal file
@@ -0,0 +1,5 @@
|
||||
public class t{
|
||||
public mofus(){
|
||||
return 1;
|
||||
}
|
||||
}
|
@@ -1,9 +1,5 @@
|
||||
package syntaxtreegenerator;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileInputStream;
|
||||
@@ -12,21 +8,23 @@ import java.io.ObjectOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Unit-Tests für den 'SyntaxTreeGenerator' aus dem Package 'parser' nach Vorbild der Klasse 'TestComplete' aus dem Test-Package 'targetast'
|
||||
*/
|
||||
public class TestComplete {
|
||||
private static HashMap<String, File[]> javFiles = new HashMap<>();
|
||||
|
||||
@BeforeClass
|
||||
@BeforeAll
|
||||
public static void setUp() {
|
||||
final String testFileDirectory = "resources/bytecode/javFiles/";
|
||||
final String expectedASTDirectory = "resources/syntaxtreegenerator/";
|
||||
@@ -353,7 +351,7 @@ public class TestComplete {
|
||||
assertEquals("Comparing expected and resulting AST for mathStrucInteger.jav", expectedAST, resultingAST);
|
||||
} catch (Exception exc) {
|
||||
exc.printStackTrace();
|
||||
assertTrue("An error occured while generating the AST for mathStrucInteger.jav", exc instanceof NotImplementedException);
|
||||
assertInstanceOf(NotImplementedException.class, exc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,15 +1,15 @@
|
||||
package syntaxtreegenerator;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileInputStream;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
|
||||
@@ -17,7 +17,7 @@ import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
|
||||
public class TestNewFeatures {
|
||||
private static HashMap<String, File[]> javFiles = new HashMap<>();
|
||||
|
||||
@BeforeClass
|
||||
@BeforeAll
|
||||
public static void setUp() {
|
||||
final String testFileDirectory = "resources/syntaxtreegenerator/javFiles/";
|
||||
final String expectedASTDirectory = "resources/syntaxtreegenerator/";
|
||||
|
@@ -2,7 +2,6 @@ package targetast;
|
||||
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
@@ -10,13 +9,13 @@ import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||
import de.dhbwstuttgart.target.tree.TargetStructure;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class ASTToTypedTargetAST {
|
||||
|
||||
@@ -24,7 +23,7 @@ public class ASTToTypedTargetAST {
|
||||
public void emptyClass() {
|
||||
ClassOrInterface emptyClass = new ClassOrInterface(0, new JavaClassName("EmptyClass"), new ArrayList<>(), Optional.empty(), Optional.empty(), new ArrayList<>(), new ArrayList<>(), new GenericDeclarationList(new ArrayList<>(), new NullToken()), new RefType(new JavaClassName("Object"), new NullToken()), false, false, new ArrayList<>(), new ArrayList<>(), new NullToken(), null);
|
||||
ResultSet emptyResultSet = new ResultSet(new HashSet<>());
|
||||
TargetStructure emptyTargetClass = new ASTToTargetAST(List.of(emptyResultSet)).convert(emptyClass);
|
||||
TargetStructure emptyTargetClass = new ASTToTargetAST(List.of(emptyResultSet), TestCodegen.createClassLoader()).convert(emptyClass);
|
||||
assert emptyTargetClass.getName().equals("EmptyClass");
|
||||
assert emptyTargetClass.methods().size() == 0;
|
||||
assert emptyTargetClass.fields().size() == 0;
|
||||
@@ -32,13 +31,14 @@ public class ASTToTypedTargetAST {
|
||||
|
||||
@Test
|
||||
public void overloading() throws Exception {
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
|
||||
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Overloading.jav").toFile();
|
||||
var compiler = new JavaTXCompiler(file);
|
||||
var resultSet = compiler.typeInference(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, classLoader);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var classLoader = new ByteArrayClassLoader();
|
||||
var overloading = TestCodegen.generateClass(converter.convert(classes.get(0)), classLoader);
|
||||
var overloading2 = TestCodegen.generateClass(converter.convert(classes.get(1)), classLoader);
|
||||
|
||||
@@ -54,46 +54,54 @@ public class ASTToTypedTargetAST {
|
||||
|
||||
@Test
|
||||
public void tphsAndGenerics() throws Exception {
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
|
||||
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Tph2.jav").toFile();
|
||||
var compiler = new JavaTXCompiler(file);
|
||||
var resultSet = compiler.typeInference(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, classLoader);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var tphAndGenerics = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
|
||||
var tphAndGenerics = TestCodegen.generateClass(converter.convert(classes.get(0)), classLoader);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cycles() throws Exception {
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
|
||||
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Cycle.jav").toFile();
|
||||
var compiler = new JavaTXCompiler(file);
|
||||
var resultSet = compiler.typeInference(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, classLoader);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var cycle = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
|
||||
var cycle = TestCodegen.generateClass(converter.convert(classes.get(0)), classLoader);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void infimum() throws Exception {
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
|
||||
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Infimum.jav").toFile();
|
||||
var compiler = new JavaTXCompiler(file);
|
||||
var resultSet = compiler.typeInference(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, classLoader);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var infimum = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
|
||||
var infimum = TestCodegen.generateClass(converter.convert(classes.get(0)), classLoader);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void gen() throws Exception {
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
|
||||
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Gen.jav").toFile();
|
||||
var compiler = new JavaTXCompiler(file);
|
||||
var resultSet = compiler.typeInference(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, classLoader);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var generics = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
|
||||
var generics = TestCodegen.generateClass(converter.convert(classes.get(0)), TestCodegen.createClassLoader());
|
||||
var m = generics.getDeclaredMethod("m", Vector.class);
|
||||
var mReturnType = m.getGenericReturnType();
|
||||
assertEquals(mReturnType, m.getParameters()[0].getParameterizedType());
|
||||
@@ -103,13 +111,15 @@ public class ASTToTypedTargetAST {
|
||||
|
||||
@Test
|
||||
public void definedGenerics() throws Exception {
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
|
||||
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Generics.jav").toFile();
|
||||
var compiler = new JavaTXCompiler(file);
|
||||
var resultSet = compiler.typeInference(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, classLoader);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var generics = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
|
||||
var generics = TestCodegen.generateClass(converter.convert(classes.get(0)), classLoader);
|
||||
var B = generics.getTypeParameters()[0];
|
||||
var mt1 = generics.getDeclaredMethod("mt1", Object.class);
|
||||
var constructor = generics.getDeclaredConstructor(Object.class);
|
||||
@@ -121,13 +131,15 @@ public class ASTToTypedTargetAST {
|
||||
|
||||
@Test
|
||||
public void definedGenerics2() throws Exception {
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
|
||||
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Generics2.jav").toFile();
|
||||
var compiler = new JavaTXCompiler(file);
|
||||
var resultSet = compiler.typeInference(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, classLoader);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var generics2 = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
|
||||
var generics2 = TestCodegen.generateClass(converter.convert(classes.get(0)), classLoader);
|
||||
assertEquals(generics2.getTypeParameters()[0].getBounds()[0], String.class);
|
||||
var m = generics2.getDeclaredMethod("m1", Object.class);
|
||||
assertEquals(m.getTypeParameters()[0].getBounds()[0], Integer.class);
|
||||
@@ -135,26 +147,30 @@ public class ASTToTypedTargetAST {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Not implemented")
|
||||
@Disabled("Not implemented")
|
||||
public void definedGenerics3() throws Exception {
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
|
||||
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Generics3.jav").toFile();
|
||||
var compiler = new JavaTXCompiler(file);
|
||||
var resultSet = compiler.typeInference(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, classLoader);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var generics3 = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
|
||||
var generics3 = TestCodegen.generateClass(converter.convert(classes.get(0)), classLoader);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void definedGenerics4() throws Exception {
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
|
||||
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Generics4.jav").toFile();
|
||||
var compiler = new JavaTXCompiler(file);
|
||||
var resultSet = compiler.typeInference(file);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, classLoader);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var generics4 = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
|
||||
var generics4 = TestCodegen.generateClass(converter.convert(classes.get(0)), classLoader);
|
||||
|
||||
// var instance = generics4.getDeclaredConstructor().newInstance();
|
||||
// var method = generics4.getDeclaredMethod("m2", Object.class);
|
||||
|
@@ -1,22 +1,21 @@
|
||||
package targetast;
|
||||
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class GreaterEqualTest {
|
||||
static Class<?> classToTest;
|
||||
static Object instance;
|
||||
|
||||
@BeforeClass
|
||||
@BeforeAll
|
||||
public static void beforeClass() throws Exception {
|
||||
var classFiles = TestCodegen.generateClassFiles(new ByteArrayClassLoader(), "GreaterEqual.jav");
|
||||
var classFiles = TestCodegen.generateClassFiles(TestCodegen.createClassLoader(), "GreaterEqual.jav");
|
||||
classToTest = classFiles.get("GreaterEqual");
|
||||
instance = classToTest.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
@@ -1,21 +1,20 @@
|
||||
package targetast;
|
||||
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class GreaterThanTest {
|
||||
static Class<?> classToTest;
|
||||
static Object instance;
|
||||
|
||||
@BeforeClass
|
||||
@BeforeAll
|
||||
public static void beforeClass() throws Exception {
|
||||
var classFiles = TestCodegen.generateClassFiles(new ByteArrayClassLoader(), "GreaterThan.jav");
|
||||
var classFiles = TestCodegen.generateClassFiles(TestCodegen.createClassLoader(), "GreaterThan.jav");
|
||||
classToTest = classFiles.get("GreaterThan");
|
||||
instance = classToTest.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
@@ -1,22 +1,20 @@
|
||||
package targetast;
|
||||
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Vector;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class InheritTest {
|
||||
private static Class<?> classToTest, classToTestAA, classToTestBB, classToTestCC, classToTestDD;
|
||||
private static Object instanceOfClass, instanceOfClassAA, instanceOfClassBB, instanceOfClassCC, instanceOfClassDD;
|
||||
|
||||
@BeforeClass
|
||||
@BeforeAll
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
var classLoader = new ByteArrayClassLoader();
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
|
||||
var classes = TestCodegen.generateClassFiles(classLoader, "Inherit.jav");
|
||||
classToTest = classes.get("Inherit");
|
||||
@@ -35,72 +33,72 @@ public class InheritTest {
|
||||
@Test
|
||||
public void testmainAA() throws Exception {
|
||||
Method m = classToTestAA.getDeclaredMethod("m", Integer.class);
|
||||
assertEquals(m.invoke(instanceOfClassAA, 5), "AA");
|
||||
assertEquals("AA", m.invoke(instanceOfClassAA, 5));
|
||||
Method main = classToTest.getDeclaredMethod("main", classToTestAA, Integer.class);
|
||||
assertEquals(main.invoke(instanceOfClass, instanceOfClassAA, 5), "AA");
|
||||
assertEquals("AA", main.invoke(instanceOfClass, instanceOfClassAA, 5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testmainBB() throws Exception {
|
||||
Method m = classToTestAA.getDeclaredMethod("m", Integer.class);
|
||||
assertEquals(m.invoke(instanceOfClassBB, 5), "AA");
|
||||
assertEquals("AA", m.invoke(instanceOfClassBB, 5));
|
||||
Method main = classToTest.getDeclaredMethod("main", classToTestAA, Integer.class);
|
||||
assertEquals(main.invoke(instanceOfClass, instanceOfClassBB, 5), "AA");
|
||||
assertEquals("AA", main.invoke(instanceOfClass, instanceOfClassBB, 5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testmainCC() throws Exception {
|
||||
Method m = classToTestCC.getDeclaredMethod("m", Integer.class);
|
||||
assertEquals(m.invoke(instanceOfClassCC, 5), "CC");
|
||||
assertEquals("CC", m.invoke(instanceOfClassCC, 5));
|
||||
Method main = classToTest.getDeclaredMethod("main", classToTestCC, Integer.class);
|
||||
assertEquals(main.invoke(instanceOfClass, instanceOfClassCC, 5), "CC");
|
||||
assertEquals("CC", main.invoke(instanceOfClass, instanceOfClassCC, 5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testmainDD() throws Exception {
|
||||
Method m = classToTestCC.getDeclaredMethod("m", Integer.class);
|
||||
assertEquals(m.invoke(instanceOfClassDD, 5), "CC");
|
||||
assertEquals("CC", m.invoke(instanceOfClassDD, 5));
|
||||
Method main = classToTest.getDeclaredMethod("main", classToTestCC, Integer.class);
|
||||
assertEquals(main.invoke(instanceOfClass, instanceOfClassDD, 5), "CC");
|
||||
assertEquals("CC", main.invoke(instanceOfClass, instanceOfClassDD, 5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testmainVectorAA() throws Exception {
|
||||
Method m = classToTestAA.getDeclaredMethod("m", Integer.class);
|
||||
assertEquals(m.invoke(instanceOfClassAA, 5), "AA");
|
||||
assertEquals("AA", m.invoke(instanceOfClassAA, 5));
|
||||
Vector v = new Vector<>();
|
||||
v.add(instanceOfClassAA);
|
||||
Method main = classToTest.getDeclaredMethod("main", Vector.class, Integer.class);
|
||||
assertEquals(main.invoke(instanceOfClass, v, 5), "AA");
|
||||
assertEquals("AA", main.invoke(instanceOfClass, v, 5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testmainVectorBB() throws Exception {
|
||||
Method m = classToTestAA.getDeclaredMethod("m", Integer.class);
|
||||
assertEquals(m.invoke(instanceOfClassBB, 5), "AA");
|
||||
assertEquals("AA", m.invoke(instanceOfClassBB, 5));
|
||||
Vector v = new Vector<>();
|
||||
v.add(instanceOfClassBB);
|
||||
Method main = classToTest.getDeclaredMethod("main", Vector.class, Integer.class);
|
||||
assertEquals(main.invoke(instanceOfClass, v, 5), "AA");
|
||||
assertEquals("AA", main.invoke(instanceOfClass, v, 5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testmainVectorCC() throws Exception {
|
||||
Method m = classToTestCC.getDeclaredMethod("m", Integer.class);
|
||||
assertEquals(m.invoke(instanceOfClassCC, 5), "CC");
|
||||
assertEquals("CC", m.invoke(instanceOfClassCC, 5));
|
||||
Vector v = new Vector<>();
|
||||
v.add(instanceOfClassCC);
|
||||
Method main = classToTest.getDeclaredMethod("main", Vector.class, Integer.class);
|
||||
assertEquals(main.invoke(instanceOfClass, v, 5), "CC");
|
||||
assertEquals("CC", main.invoke(instanceOfClass, v, 5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testmainVectorDD() throws Exception {
|
||||
Method m = classToTestCC.getDeclaredMethod("m", Integer.class);
|
||||
assertEquals(m.invoke(instanceOfClassDD, 5), "CC");
|
||||
assertEquals("CC", m.invoke(instanceOfClassDD, 5));
|
||||
Vector v = new Vector<>();
|
||||
v.add(instanceOfClassDD);
|
||||
Method main = classToTest.getDeclaredMethod("main", Vector.class, Integer.class);
|
||||
assertEquals(main.invoke(instanceOfClass, v, 5), "CC");
|
||||
assertEquals("CC", main.invoke(instanceOfClass, v, 5));
|
||||
}
|
||||
}
|
||||
|
@@ -1,23 +1,22 @@
|
||||
package targetast;
|
||||
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Vector;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@Ignore("FIXME")
|
||||
@Disabled("FIXME")
|
||||
public class InheritTest2 {
|
||||
private static Class<?> classToTest, classToTestAA, classToTestBB, classToTestCC, classToTestDD;
|
||||
private static Object instanceOfClass, instanceOfClassAA, instanceOfClassBB, instanceOfClassCC, instanceOfClassDD;
|
||||
|
||||
@BeforeClass
|
||||
@BeforeAll
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
var classLoader = new ByteArrayClassLoader();
|
||||
var classLoader = TestCodegen.createClassLoader();
|
||||
classToTest = TestCodegen.generateClassFiles(classLoader, "Inherit2.jav").get("Inherit2");
|
||||
classToTestAA = TestCodegen.generateClassFiles(classLoader, "AA.jav").get("AA");
|
||||
classToTestBB = TestCodegen.generateClassFiles(classLoader, "BB.jav").get("BB");
|
||||
|
@@ -1,21 +1,20 @@
|
||||
package targetast;
|
||||
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class LessEqualTest {
|
||||
static Class<?> classToTest;
|
||||
static Object instance;
|
||||
|
||||
@BeforeClass
|
||||
@BeforeAll
|
||||
public static void beforeClass() throws Exception {
|
||||
var classFiles = TestCodegen.generateClassFiles(new ByteArrayClassLoader(), "LessEqual.jav");
|
||||
var classFiles = TestCodegen.generateClassFiles(TestCodegen.createClassLoader(), "LessEqual.jav");
|
||||
classToTest = classFiles.get("LessEqual");
|
||||
instance = classToTest.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
@@ -1,21 +1,20 @@
|
||||
package targetast;
|
||||
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class LessThanTest {
|
||||
static Class<?> classToTest;
|
||||
static Object instance;
|
||||
|
||||
@BeforeClass
|
||||
@BeforeAll
|
||||
public static void beforeClass() throws Exception {
|
||||
var classFiles = TestCodegen.generateClassFiles(new ByteArrayClassLoader(), "LessThan.jav");
|
||||
var classFiles = TestCodegen.generateClassFiles(TestCodegen.createClassLoader(), "LessThan.jav");
|
||||
classToTest = classFiles.get("LessThan");
|
||||
instance = classToTest.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
@@ -1,12 +1,12 @@
|
||||
package targetast;
|
||||
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
|
||||
public class OLTest {
|
||||
private static Class<?> classToTest;
|
||||
@@ -14,9 +14,9 @@ public class OLTest {
|
||||
private static Object instanceOfClass;
|
||||
private static Object instanceOfClass1;
|
||||
|
||||
@BeforeClass
|
||||
@BeforeAll
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
var classFiles = TestCodegen.generateClassFiles(new ByteArrayClassLoader(), "OL.jav");
|
||||
var classFiles = TestCodegen.generateClassFiles(TestCodegen.createClassLoader(), "OL.jav");
|
||||
classToTest = classFiles.get("OL");
|
||||
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||
classToTest1 = classFiles.get("OLMain");
|
||||
|
@@ -1,20 +1,19 @@
|
||||
package targetast;
|
||||
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class PostIncTest {
|
||||
private static Class<?> classToTest;
|
||||
private static Object instanceOfClass;
|
||||
|
||||
@BeforeClass
|
||||
@BeforeAll
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
var classFiles = TestCodegen.generateClassFiles(new ByteArrayClassLoader(), "PostIncDec.jav");
|
||||
var classFiles = TestCodegen.generateClassFiles(TestCodegen.createClassLoader(), "PostIncDec.jav");
|
||||
classToTest = classFiles.get("PostIncDec");
|
||||
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
@@ -1,20 +1,19 @@
|
||||
package targetast;
|
||||
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class PreIncTest {
|
||||
private static Class<?> classToTest;
|
||||
private static Object instanceOfClass;
|
||||
|
||||
@BeforeClass
|
||||
@BeforeAll
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
var classFiles = TestCodegen.generateClassFiles(new ByteArrayClassLoader(), "PreInc.jav");
|
||||
var classFiles = TestCodegen.generateClassFiles(TestCodegen.createClassLoader(), "PreInc.jav");
|
||||
classToTest = classFiles.get("PreInc");
|
||||
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
@@ -1,22 +1,21 @@
|
||||
package targetast;
|
||||
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Stack;
|
||||
import java.util.Vector;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class PutTest {
|
||||
private static Class<?> classToTest;
|
||||
private static Object instanceOfClass;
|
||||
|
||||
@BeforeClass
|
||||
@BeforeAll
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
var classFiles = TestCodegen.generateClassFiles(new ByteArrayClassLoader(), "Put.jav");
|
||||
var classFiles = TestCodegen.generateClassFiles(TestCodegen.createClassLoader(), "Put.jav");
|
||||
classToTest = classFiles.get("Put");
|
||||
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@ package targetast;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.bytecode.Codegen;
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
||||
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||
@@ -14,10 +14,10 @@ import de.dhbwstuttgart.target.tree.expression.*;
|
||||
import de.dhbwstuttgart.target.tree.type.TargetFunNType;
|
||||
import de.dhbwstuttgart.target.tree.type.TargetRefType;
|
||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
@@ -37,6 +37,10 @@ public class TestCodegen {
|
||||
Files.write(outputPath.resolve(name + ".class"), code);
|
||||
}
|
||||
|
||||
public static IByteArrayClassLoader createClassLoader() {
|
||||
return new DirectoryClassLoader(List.of(outputPath.toFile()), ClassLoader.getSystemClassLoader());
|
||||
}
|
||||
|
||||
public static Path path = Path.of(System.getProperty("user.dir"), "resources/bytecode/javFiles/");
|
||||
|
||||
public static Map<String, ? extends Class<?>> generateClassFiles(IByteArrayClassLoader classLoader, String... files) throws IOException, ClassNotFoundException {
|
||||
@@ -62,7 +66,7 @@ public class TestCodegen {
|
||||
|
||||
converter.generateFunNTypes();
|
||||
|
||||
for (var entry : converter.auxiliaries.entrySet()) {
|
||||
for (var entry : compiler.auxiliaries.entrySet()) {
|
||||
writeClassFile(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
@@ -108,7 +112,7 @@ public class TestCodegen {
|
||||
|
||||
converter.generateFunNTypes();
|
||||
|
||||
for (var entry : converter.auxiliaries.entrySet()) {
|
||||
for (var entry : compiler.auxiliaries.entrySet()) {
|
||||
writeClassFile(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
@@ -119,7 +123,7 @@ public class TestCodegen {
|
||||
public void testEmptyClass() throws Exception {
|
||||
var clazz = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("Empty"));
|
||||
clazz.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "main", List.of(), null, new TargetBlock(List.of()));
|
||||
generateClass(clazz, new ByteArrayClassLoader()).getDeclaredMethod("main").invoke(null);
|
||||
generateClass(clazz, createClassLoader()).getDeclaredMethod("main").invoke(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -132,7 +136,7 @@ public class TestCodegen {
|
||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "mul", List.of(new MethodParameter(TargetType.Integer, "a"), new MethodParameter(TargetType.Integer, "b")), TargetType.Integer, new TargetBlock(List.of(new TargetReturn(new TargetBinaryOp.Mul(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "a"), new TargetLocalVar(TargetType.Integer, "b"))))));
|
||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "rem", List.of(new MethodParameter(TargetType.Integer, "a"), new MethodParameter(TargetType.Integer, "b")), TargetType.Integer, new TargetBlock(List.of(new TargetReturn(new TargetBinaryOp.Rem(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "a"), new TargetLocalVar(TargetType.Integer, "b"))))));
|
||||
|
||||
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||
var clazz = generateClass(targetClass, createClassLoader());
|
||||
assertEquals(clazz.getDeclaredMethod("add", Integer.class, Integer.class).invoke(null, 10, 10), 20);
|
||||
assertEquals(clazz.getDeclaredMethod("sub", Integer.class, Integer.class).invoke(null, 20, 10), 10);
|
||||
assertEquals(clazz.getDeclaredMethod("div", Integer.class, Integer.class).invoke(null, 20, 10), 2);
|
||||
@@ -148,7 +152,7 @@ public class TestCodegen {
|
||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "neg", List.of(new MethodParameter(TargetType.Integer, "a")), TargetType.Integer, new TargetBlock(List.of(new TargetReturn(new TargetUnaryOp.Negate(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "a"))))));
|
||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "add", List.of(new MethodParameter(TargetType.Integer, "a")), TargetType.Integer, new TargetBlock(List.of(new TargetReturn(new TargetUnaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "a"))))));
|
||||
|
||||
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||
var clazz = generateClass(targetClass, createClassLoader());
|
||||
assertEquals(clazz.getDeclaredMethod("not", Integer.class).invoke(null, 10), -11);
|
||||
assertEquals(clazz.getDeclaredMethod("neg", Integer.class).invoke(null, 10), -10);
|
||||
assertEquals(clazz.getDeclaredMethod("add", Integer.class).invoke(null, 10), 10);
|
||||
@@ -162,7 +166,7 @@ public class TestCodegen {
|
||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "and", List.of(new MethodParameter(TargetType.Boolean, "a"), new MethodParameter(TargetType.Boolean, "b")), TargetType.Boolean, new TargetBlock(List.of(new TargetReturn(new TargetBinaryOp.And(TargetType.Boolean, new TargetLocalVar(TargetType.Boolean, "a"), new TargetLocalVar(TargetType.Boolean, "b"))))));
|
||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "or", List.of(new MethodParameter(TargetType.Boolean, "a"), new MethodParameter(TargetType.Boolean, "b")), TargetType.Boolean, new TargetBlock(List.of(new TargetReturn(new TargetBinaryOp.Or(TargetType.Boolean, new TargetLocalVar(TargetType.Boolean, "a"), new TargetLocalVar(TargetType.Boolean, "b"))))));
|
||||
|
||||
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||
var clazz = generateClass(targetClass, createClassLoader());
|
||||
var and = clazz.getDeclaredMethod("and", Boolean.class, Boolean.class);
|
||||
var or = clazz.getDeclaredMethod("or", Boolean.class, Boolean.class);
|
||||
assertEquals(and.invoke(null, true, false), false);
|
||||
@@ -176,7 +180,7 @@ public class TestCodegen {
|
||||
public void testArithmeticConvert() throws Exception {
|
||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("ArithmeticConvert"));
|
||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "add", List.of(), TargetType.Long, new TargetBlock(List.of(new TargetReturn(new TargetBinaryOp.Add(TargetType.Long, new TargetLiteral.CharLiteral((char) 10), new TargetLiteral.LongLiteral((long) 20))))));
|
||||
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||
var clazz = generateClass(targetClass, createClassLoader());
|
||||
assertEquals(clazz.getDeclaredMethod("add").invoke(null), (long) 30);
|
||||
}
|
||||
|
||||
@@ -185,7 +189,7 @@ public class TestCodegen {
|
||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("HelloWorld"));
|
||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "helloWorld", List.of(), null, new TargetBlock(List.of(new TargetMethodCall(null, new TargetFieldVar(new TargetRefType("java.io.PrintStream"), new TargetRefType("java.lang.System"), true, new TargetClassName(new TargetRefType("java.lang.System")), "out"), List.of(new TargetLiteral.StringLiteral("Hello World!")), new TargetRefType("java.io.PrintStream"), "println", false, false, false))));
|
||||
|
||||
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||
var clazz = generateClass(targetClass, createClassLoader());
|
||||
clazz.getDeclaredMethod("helloWorld").invoke(null);
|
||||
}
|
||||
|
||||
@@ -193,7 +197,7 @@ public class TestCodegen {
|
||||
public void testIfStatement() throws Exception {
|
||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("IfStmt"));
|
||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "ifStmt", List.of(new MethodParameter(TargetType.Integer, "val")), TargetType.Integer, new TargetBlock(List.of(new TargetIf(new TargetBinaryOp.Equal(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "val"), new TargetLiteral.IntLiteral(10)), new TargetReturn(new TargetLiteral.IntLiteral(1)), new TargetIf(new TargetBinaryOp.Less(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "val"), new TargetLiteral.IntLiteral(5)), new TargetReturn(new TargetLiteral.IntLiteral(2)), new TargetReturn(new TargetLiteral.IntLiteral(3)))))));
|
||||
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||
var clazz = generateClass(targetClass, createClassLoader());
|
||||
var ifStmt = clazz.getDeclaredMethod("ifStmt", Integer.class);
|
||||
assertEquals(ifStmt.invoke(null, 10), 1);
|
||||
assertEquals(ifStmt.invoke(null, 3), 2);
|
||||
@@ -204,7 +208,7 @@ public class TestCodegen {
|
||||
public void testFor() throws Exception {
|
||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("For"));
|
||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "forLoop", List.of(), TargetType.Integer, new TargetBlock(List.of(new TargetVarDecl(TargetType.Integer, "sum", new TargetLiteral.IntLiteral(0)), new TargetFor(List.of(new TargetVarDecl(TargetType.Integer, "i", new TargetLiteral.IntLiteral(0))), new TargetBinaryOp.Less(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(10)), List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetBinaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(1)))), new TargetBlock(List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "sum"), new TargetBinaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "sum"), new TargetLocalVar(TargetType.Integer, "i")))))), new TargetReturn(new TargetLocalVar(TargetType.Integer, "sum")))));
|
||||
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||
var clazz = generateClass(targetClass, createClassLoader());
|
||||
assertEquals(clazz.getDeclaredMethod("forLoop").invoke(null), 45);
|
||||
}
|
||||
|
||||
@@ -212,7 +216,7 @@ public class TestCodegen {
|
||||
public void testWhile() throws Exception {
|
||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("While"));
|
||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "whileLoop", List.of(), TargetType.Integer, new TargetBlock(List.of(new TargetVarDecl(TargetType.Integer, "i", new TargetLiteral.IntLiteral(0)), new TargetWhile(new TargetBinaryOp.Less(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(10)), new TargetBlock(List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetBinaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(1)))))), new TargetReturn(new TargetLocalVar(TargetType.Integer, "i")))));
|
||||
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||
var clazz = generateClass(targetClass, createClassLoader());
|
||||
assertEquals(clazz.getDeclaredMethod("whileLoop").invoke(null), 10);
|
||||
}
|
||||
|
||||
@@ -235,7 +239,7 @@ public class TestCodegen {
|
||||
new TargetReturn(new TargetLocalVar(TargetType.Integer, "res"))
|
||||
)));
|
||||
|
||||
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||
var clazz = generateClass(targetClass, createClassLoader());
|
||||
var m = clazz.getDeclaredMethod("switchClassic", Integer.class);
|
||||
assertEquals(m.invoke(null, 10), 0);
|
||||
assertEquals(m.invoke(null, 15), 1);
|
||||
@@ -264,7 +268,7 @@ public class TestCodegen {
|
||||
List.of(new TargetLiteral.IntLiteral(2))
|
||||
), true), TargetType.Integer)
|
||||
))));
|
||||
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||
var clazz = generateClass(targetClass, createClassLoader());
|
||||
var m = clazz.getDeclaredMethod("switchType", Object.class);
|
||||
assertEquals(m.invoke(null, "String"), 0);
|
||||
assertEquals(m.invoke(null, 10), 1);
|
||||
@@ -273,9 +277,9 @@ public class TestCodegen {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("The lambda class is not generated because we don't call ASTToTargetAST")
|
||||
@Disabled("The lambda class is not generated because we don't call ASTToTargetAST")
|
||||
public void testLambda() throws Exception {
|
||||
var classLoader = new ByteArrayClassLoader();
|
||||
var classLoader = createClassLoader();
|
||||
// var fun = classLoader.loadClass(Path.of(System.getProperty("user.dir"), "src/test/java/targetast/Fun1$$.class"));
|
||||
var interfaceType = TargetFunNType.fromParams(List.of(TargetType.Integer), 1);
|
||||
|
||||
|
@@ -12,9 +12,9 @@ import de.dhbwstuttgart.target.generate.Bound;
|
||||
import static de.dhbwstuttgart.target.generate.Bound.*;
|
||||
import de.dhbwstuttgart.target.generate.BoundsList;
|
||||
import de.dhbwstuttgart.target.generate.GenericsResult;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -22,7 +22,7 @@ import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Ignore("TODO: Rewrite with the new algorithm")
|
||||
@Disabled("TODO: Rewrite with the new algorithm")
|
||||
public class TestGenerics {
|
||||
private static final String rootDirectory = System.getProperty("user.dir") + "/resources/insertGenerics/javFiles/";
|
||||
private static final String bytecodeDirectory = System.getProperty("user.dir") + "targetTest";
|
||||
|
@@ -1,21 +1,21 @@
|
||||
package targetast;
|
||||
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
|
||||
public class TphTest {
|
||||
|
||||
private static Class<?> classToTest;
|
||||
private static Object instanceOfClass;
|
||||
|
||||
@BeforeClass
|
||||
@BeforeAll
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
var classFiles = TestCodegen.generateClassFiles(new ByteArrayClassLoader(), "Tph.jav");
|
||||
var classFiles = TestCodegen.generateClassFiles(TestCodegen.createClassLoader(), "Tph.jav");
|
||||
classToTest = classFiles.get("Tph");
|
||||
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
@@ -1,20 +1,19 @@
|
||||
package targetast;
|
||||
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class WhileTest {
|
||||
private static Class<?> classToTest;
|
||||
private static Object instanceOfClass;
|
||||
|
||||
@BeforeClass
|
||||
@BeforeAll
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
var classFiles = TestCodegen.generateClassFiles(new ByteArrayClassLoader(), "While.jav");
|
||||
var classFiles = TestCodegen.generateClassFiles(TestCodegen.createClassLoader(), "While.jav");
|
||||
classToTest = classFiles.get("While");
|
||||
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
@@ -8,8 +8,8 @@ import de.dhbwstuttgart.typedeployment.TypeInsert;
|
||||
import de.dhbwstuttgart.typedeployment.TypeInsertFactory;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -22,7 +22,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Ignore("To be renewed")
|
||||
@Disabled("To be renewed")
|
||||
public class JavaTXCompilerTest {
|
||||
|
||||
public static final String rootDirectory = System.getProperty("user.dir") + "/src/test/resources/javFiles/";
|
||||
|
Reference in New Issue
Block a user