2
0

Compare commits

...

117 Commits

Author SHA1 Message Date
9c2c6a3ea9 Alter OL Test 2024-07-01 12:36:22 +02:00
a7ad4fa984 Add OrCOnsTest 2024-06-28 11:32:32 +02:00
fcda301b1e Hack in ASP-Constraint generation for WLP2024 paper Prototype Test 2024-06-10 09:02:26 +02:00
2aa3997f17 Readme 2024-06-07 14:54:27 +02:00
7e37497740 Start ASP Gen after Constraint Generateion 2024-06-07 14:53:47 +02:00
3d2b935c60 Merge branch 'targetBytecode' of https://gitea.hb.dhbw-stuttgart.de/JavaTX/JavaCompilerCore into targetBytecode 2024-05-14 22:53:08 +02:00
db01b0c8dd new file: resources/AllgemeinTest/Box.jav 2024-05-14 22:50:20 +02:00
662756ac18 Merge branch 'targetBytecode' of https://gitea.hb.dhbw-stuttgart.de/JavaTX/JavaCompilerCore into targetBytecode 2024-05-10 16:51:10 +02:00
b0bf41968e Bug325 2024-05-10 16:50:06 +02:00
2221b559ca Implementierungen von Interfaces eingefuegt und Overriding ersetzt durch implementierung
modified:   ../src/main/java/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java

Overriding ersetzt durch implementierung (Umbennennung)
	modified:   ../resources/bytecode/javFiles/Matrix.jav
	modified:   ../src/main/java/de/dhbwstuttgart/syntaxtree/Method.java
	modified:   ../src/main/java/de/dhbwstuttgart/typeinference/constraints/Constraint.java
	modified:   ../src/main/java/de/dhbwstuttgart/typeinference/constraints/ConstraintSet.java
	modified:   ../src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java
	modified:   ../src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java
	modified:   ../src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
2024-05-10 14:16:23 +02:00
021b7ec9fe Fehler vom vorigen korriert Commit
modified:   ../resources/bytecode/javFiles/Matrix.jav
	modified:   ../src/main/java/de/dhbwstuttgart/typeinference/constraints/Constraint.java
	modified:   ../src/main/java/de/dhbwstuttgart/typeinference/constraints/ConstraintSet.java
	modified:   ../src/test/java/TestComplete.java
2024-05-08 09:07:22 +02:00
154d4823e4 isOverridden eingefuegt.
Problem beim Konvertioeren
	modified:   ../src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
	modified:   ../src/main/java/de/dhbwstuttgart/syntaxtree/Method.java
	modified:   ../src/main/java/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java
	modified:   ../src/main/java/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java
	modified:   ../src/main/java/de/dhbwstuttgart/typeinference/constraints/Constraint.java
	modified:   ../src/main/java/de/dhbwstuttgart/typeinference/constraints/ConstraintSet.java
	modified:   ../src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java
	modified:   ../src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java
	modified:   ../src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
	modified:   ../src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java
2024-05-08 00:14:21 +02:00
71dfe5d9e1 Bei diesem und vorigen Commit wurde der Bug

geloest.

1. src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
in der Methode copute wurden die methodSignatureConstraints der bereits zu Beginn
aufegloesten einer Oder Constraints in die Methodconstraints der Unifikation geschrieben
2. Elementtyp der linken Seiten der methodSignatureConstraints wurden von RefTypeOrTPHOrWildcardOrGeneric auf TypePlaceholder geaendert, weil dort nur TypePlaceholder geaendert.
3. src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java
in der Methode prepareBlock wurde der Typ des Rückgabewerts des supercalls von Void auf eine
Freshtpevar gesetzt.
4. src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
in der unify2-Methode wurde am Ende der Aufruf der Substitution nach Hinzufuegen der
Methodconstraints auskommentiert -> hat zu nicht geloesten Constraints gefuehrt.

	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
	modified:   src/test/java/TestComplete.java
2024-05-02 16:33:37 +02:00
58110c474a mathStrucInteger.jav funktioniert gerade nicht
modified:   resources/bytecode/javFiles/Matrix.jav
	modified:   src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java
	modified:   src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java
	modified:   src/main/java/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java
	modified:   src/main/java/de/dhbwstuttgart/syntaxtree/statement/NewClass.java
	modified:   src/main/java/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java
	modified:   src/main/java/de/dhbwstuttgart/syntaxtree/statement/ThisCall.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/constraints/Constraint.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/model/ReferenceType.java
2024-05-02 00:13:45 +02:00
df2ec4b1ba Fix , convert captures to correct types 2024-04-30 16:55:40 +02:00
2c66a1d6e6 add class file 2024-04-29 10:27:23 +02:00
c76ee355d8 Add bug for 2024-04-29 10:25:01 +02:00
a5c314c5c5 Fix 2024-04-28 19:25:20 +02:00
cba35a4bec Don't load source files twice 2024-04-27 23:08:15 +02:00
b774281cbb Add Ternary, fix 2024-04-22 12:17:53 +02:00
9358130468 Fix package weirdness? See 2024-04-18 11:51:08 +02:00
708aa64283 Fix current directory not being added to path 2024-04-18 10:31:12 +02:00
c21e5202d6 Fix 2024-04-18 10:20:35 +02:00
b3bd5cde10 Fix tests 2024-04-15 16:44:34 +02:00
df78937ef3 Fix test case a bit 2024-04-15 16:18:25 +02:00
7fb4824f8d Add modulo, fix 2024-04-12 15:40:22 +02:00
e0d71a6003 fix console 2024-04-12 14:17:15 +02:00
49803385cf Fix optional parameters 2024-04-12 13:58:11 +02:00
39d02f792c Deal with multiple source files properly, don't throw all the constraints together 2024-04-12 10:48:13 +02:00
4fc78f494c More poking around 2024-04-10 10:22:34 +02:00
b752219d8c Throw exception if class doesn't exist 2024-04-10 10:03:59 +02:00
ec890356e4 Don't trim stack trace because some tests randomly fail and we need to know why 2024-04-10 09:58:01 +02:00
d405b0c3a2 Merge branch 'targetBytecode' of ssh://gitea.hb.dhbw-stuttgart.de:2222/JavaTX/JavaCompilerCore into targetBytecode 2024-04-10 09:42:47 +02:00
6c8657b7a8 Work on 2024-04-10 09:42:31 +02:00
bcce4cee19 modified: src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntacticSugar.java
Im Visitor ReturnFinder wuder nicht beruecksichtigt, dass auch in einem Lambda-Ausdruck ein Reurn stehen kann, welchen die umgebenden Block nicht beendet.
2024-04-09 18:25:26 +02:00
e6cd4038e2 Fix bytecode error when calling interface functions 2024-04-09 15:52:44 +02:00
e50f941b79 Merge branch 'targetBytecode' of ssh://gitea.hb.dhbw-stuttgart.de:2222/JavaTX/JavaCompilerCore into targetBytecode 2024-04-09 14:59:16 +02:00
cb7d0e22cc Fix 2024-04-09 14:58:43 +02:00
0d5be89310 modified: ../src/main/java/de/dhbwstuttgart/typeinference/unify/Match.java
modified:   ../src/test/java/TestComplete.java
2024-04-09 01:50:42 +02:00
0b7f07108f Fix 2024-04-08 14:25:41 +02:00
6b0816c1c4 Add test for 2024-04-08 14:02:57 +02:00
f66b9099f3 Fix 2024-04-08 13:51:49 +02:00
da74898f9d Fix 2024-04-08 13:18:27 +02:00
46a7f61234 Fix 2024-04-08 11:52:52 +02:00
e59accf7ee Fix 2024-04-08 11:40:46 +02:00
4b110244f2 new file: ../../AllgemeinTest/List.jav 2024-04-07 17:31:05 +02:00
e37040f367 Bug 307 gefixt
Changes to be committed:
	modified:   src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
	modified:   src/test/java/TestComplete.java
2024-04-03 00:11:01 +02:00
6850a8fa21 Decouple unify from the rest of the code 2024-03-28 10:35:34 +01:00
877e5ed38a Reversing alone would disturb the parameters () 2024-03-27 14:52:15 +01:00
82b4450857 Fix 298 for real this time? 2024-03-27 14:39:43 +01:00
b70e435120 Work on issue 2024-03-27 12:21:57 +01:00
3b14cd609f Revert "Get rid of mutable state, hopefully fix "
This reverts commit bc61fc2e1d.
2024-03-27 09:57:21 +01:00
8fdfbf875b Fix maybe? 2024-03-26 17:31:48 +01:00
bc61fc2e1d Get rid of mutable state, hopefully fix 2024-03-26 16:54:24 +01:00
62f2e05f35 Add test case for 2024-03-26 11:04:03 +01:00
606ce8b82d Implement AND/OR/XOR, fix 2024-03-26 10:54:32 +01:00
c84befae51 Add Negation operator (fixes ) 2024-03-25 17:05:20 +01:00
7f3c1686ec Fix 2024-03-25 15:10:47 +01:00
43da2ffbdc Fix 2024-03-25 14:49:18 +01:00
9472b5c86f Types are weird in this one 2024-03-25 13:51:56 +01:00
7cb0e9dbb7 Taking the super methods parameters should only happen for the types, fix 2024-03-25 13:43:30 +01:00
e07521d9b6 Fix 2024-03-25 12:14:03 +01:00
c2ee12397f Work on issue 2024-03-22 14:54:23 +01:00
e6321ff8bc Fix gtvs being strange, 2024-03-21 17:40:42 +01:00
786e0a7a23 Fix and also call private methods correctly 2024-03-21 11:49:16 +01:00
1c63321b30 Fix 2024-03-20 14:37:15 +01:00
1f74345324 Upload test for 2024-03-19 15:19:57 +01:00
518f58e08f Maybe null here was in fact right? 2024-03-18 13:40:37 +01:00
0acfe6c0d4 Implement ThisCall (fix ) 2024-03-18 13:29:53 +01:00
c07d4d36e9 Fix wrong type conversion, see 2024-03-18 12:14:03 +01:00
01e374eadd Fix 2024-03-18 10:14:40 +01:00
a1b5c0541b Fix NPE in generics, probably because interface method don't have code 2024-03-15 17:14:27 +01:00
66c8c307b0 Fix recursive packages 2024-03-14 15:23:31 +01:00
ebd6a00a39 Fix the rest of the test cases 2024-03-14 14:38:02 +01:00
f57d89c966 Manage imports per source file instead of globally, should fix 2024-03-14 13:51:20 +01:00
f9188e65ca Public all the things 2024-03-14 13:50:56 +01:00
e354838491 Use wildcard constraint in foreach, fixes and hopefully doesn't break anything 2024-03-14 10:23:19 +01:00
e17f08263e Fix <?> Wildcard not working in STG, fixes 2024-03-13 11:42:32 +01:00
2cb84f9e2b Ignore annotations in STG, fix 2024-03-13 11:29:17 +01:00
83ae05ea4a Fix 2024-03-13 11:21:00 +01:00
26452eb5de Fix 2024-03-11 16:16:10 +01:00
38827544c9 Split up test and compile to improve readability 2024-03-08 17:33:49 +01:00
ff905390e8 Limit stack traces 2024-03-08 17:30:01 +01:00
2d9094ec4e Redirect test output to file in order for the test output to be visible on gitea 2024-03-08 17:20:54 +01:00
e27eb3a3fe Fix 2024-03-08 16:58:00 +01:00
73ca790711 Create folder 2024-03-08 15:26:40 +01:00
452064398a Update actions 2024-03-08 15:08:45 +01:00
20d6cb8eb9 Remove sudo? 2024-03-08 15:05:02 +01:00
b7f1db5d80 Update workflow 2024-03-08 15:00:17 +01:00
b327518921 Update workflow 2024-03-08 14:54:58 +01:00
945b47c762 Fix 2024-03-08 14:42:49 +01:00
65a71ebe0c Add test for and partially fix it 2024-03-08 14:00:52 +01:00
deeb67c4f7 Add test workflow 2024-03-07 14:41:50 +01:00
c92edeaf2a Merge branch 'targetBytecode' of ssh://gohorb.ba-horb.de:/bahome/projekt/git/JavaCompilerCore into targetBytecode 2024-03-07 10:44:37 +01:00
01e3d31f1a Add Object methods to every interface, fixes 2024-03-06 14:10:57 +01:00
a90e9df1e8 Fix regression 2024-03-05 10:26:30 +01:00
1c1f5ae29f Merge branch 'targetBytecode' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into targetBytecode 2024-03-04 19:37:40 +01:00
8ab5bbd831 modified: src/test/java/AllgemeinTest.java 2024-03-04 19:37:10 +01:00
1877d7f170 Add test for 2024-03-04 12:19:56 +01:00
388614b220 Add testcase for LamRunnable 2024-03-04 12:00:29 +01:00
f2e43f180c Add test for issue 2024-03-04 11:51:28 +01:00
59585296b0 Fix single expressions not converting to blocks. Fixes 2024-03-04 11:30:36 +01:00
f11d4b0716 Fix for loop overflowing the stack. Fixes 2024-03-04 10:58:26 +01:00
584690596e Add filename to debug output, closes 2024-03-01 17:34:40 +01:00
9c6372c3ba Thats probably important 2024-02-28 13:22:13 +01:00
688358aa33 Add more debug help 2024-02-28 13:16:32 +01:00
a60282414c Add location information to constraints 2024-02-27 16:25:47 +01:00
75b9020cf9 Fix up Character 2024-02-26 15:02:15 +01:00
e88d4428c5 Fix constructor overloads getting picked with the wrong arity 2024-02-05 15:24:06 +01:00
dcfafe5995 Fix null literal 2024-02-05 14:46:00 +01:00
a035589647 Implement throw 2024-02-01 11:58:08 +01:00
9da763b361 Add instanceof 2024-01-31 17:27:18 +01:00
700ea125fc Throw different exception 2024-01-30 15:46:02 +01:00
f18903834e Fix super calls 2024-01-23 14:00:42 +01:00
b80cc726c8 Add ForEach loop 2024-01-19 16:29:59 +01:00
6cc40162da Merge branch 'targetBytecode' of gohorb.ba-horb.de:/bahome/projekt/git/JavaCompilerCore into targetBytecode 2023-12-15 13:49:35 +01:00
71899ac673 Please enter the commit message for your changes. Lines starting
with '#' will be ignored, and an empty message aborts the commit.
2023-12-15 13:47:25 +01:00
169 changed files with 2819 additions and 810 deletions
.gitea/workflows
README.mdpom.xml
resources
src
main
test

@ -0,0 +1,25 @@
name: Build and Test with Maven
on: [push]
jobs:
Build-and-test-with-Maven:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v3
- name: Install maven
run: |
apt update
apt install -y maven
- name: Install java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
cache: 'maven'
- name: Compile project
run: |
mvn compile
- name: Run tests
run: |
mvn test

9
README.md Normal file

@ -0,0 +1,9 @@
Prototype
run with:
mvn test -Dtest="TestComplete#matrixTest"
mvn test -Dtest="typeinference.JavaTXCompilerTest#importTest"
then the output is in: /tmp/output

10
pom.xml

@ -53,9 +53,8 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<compilerArgs>--enable-preview</compilerArgs>
<source>21</source>
<target>21</target>
<source>22</source>
<target>22</target>
</configuration>
</plugin>
<plugin>
@ -63,9 +62,14 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
<reportsDirectory>${project.build.directory}/test-reports</reportsDirectory>
<argLine>--enable-preview</argLine>
<trimStackTrace>false</trimStackTrace>
<excludes>
<exclude>**/JavaTXCompilerTest.java</exclude>
<exclude>**/AllgemeinTest.java</exclude>
<exclude>**/syntaxtreegenerator/*.java</exclude>
</excludes>
</configuration>
</plugin>

@ -0,0 +1,10 @@
class Box<A> {
A a;
Box(A a) {
this.a = a;
}
}

@ -0,0 +1,46 @@
import java.lang.Boolean;
import java.lang.Object;
class List {
elem;
next;
List() {
super();
}
List(elem, next) {
this.elem = elem;
this.next = next;
}
addElement(newElem) {
return new List(newElem, this);
}
append(l) {
if (next == null) {
return l;
}
else {
return new List(elem, next.append(l));
}
}
/*
addAll(l) {
var nextLoc = next;
while (//nextLoc != null
true) {
nextLoc = nextLoc.next;
}
nextLoc = l;
}
void m() {
List<? extends Object> l; // = new List<Integer>(1, null);
List<? extends Object> l2; // = new List<String>("SSS", null);
l.addAll(l2);
}
*/
}

@ -2,7 +2,7 @@ import java.lang.Integer;
import java.lang.String;
public class AA {
m(Integer i) { return "AA"; }
public m(Integer i) { return "AA"; }
m2(AA x) { return "AA"; }
public m2(AA x) { return "AA"; }
}

@ -0,0 +1,14 @@
public class Access {
public int fPublic;
int fDefault;
private int fPrivate;
protected int fProtected;
public void mPublic() {}
void mDefault() {}
private void mPrivate() {}
protected void mProtected() {}
}
class AccessDefault {
}

@ -0,0 +1,8 @@
class Base {
public void foo() {}
}
public class Annotation extends Base {
@Override
public void foo() {}
}

@ -1,3 +1,4 @@
import java.lang.Integer;
import AA;
public class BB extends AA { }

@ -3,15 +3,15 @@ import java.lang.Double;
public class BinaryInMeth {
m(a){
public m(a){
return ++a;
}
m2(a,b){
public m2(a,b){
return m(a+b);
}
m3(a) {
public m3(a) {
return m(++a);
}
}

@ -0,0 +1,7 @@
public class Bug112 {
public m(x) {
var y;
x = y;
return y;
}
}

@ -0,0 +1,12 @@
import java.lang.Integer;
import java.lang.Boolean;
public class Bug122 {
public void main() {
if (true) {
for (Integer i = 0; i < 10; i++) {
}
}
}
}

@ -0,0 +1,13 @@
import java.lang.Boolean;
import java.lang.Integer;
public class Bug123 {
public Boolean works(){
if(true) return true;
else return false;
}
public void fails(){
Boolean a = true;
if(true) a = false;
}
}

@ -0,0 +1,16 @@
import java.lang.Boolean;
import java.lang.Integer;
import java.lang.String;
import java.util.List;
import java.util.LinkedList;
import java.util.ArrayList;
public class Bug125 {
static ArrayList<String> works = new ArrayList<>();
static List<String> fails = new ArrayList<>();
public void main() {
works.toString();
fails.toString();
}
}

@ -0,0 +1,15 @@
import java.util.Optional;
import java.lang.Integer;
public class StaticClass {
public static StaticClass barbar() {
return new StaticClass();
}
}
public class Bug285 {
public void foo() {
Optional<Integer> opt = Optional.empty();
StaticClass b = StaticClass.barbar();
}
}

@ -0,0 +1,7 @@
import Bug290B;
public class Bug290A {
public void m() {
new Bug290B();
}
}

@ -0,0 +1,11 @@
import java.lang.String;
import java.lang.Integer;
public class Bug290B {
String name;
public Bug290B() {
Integer i = 0;
name = i.toString() + "$$";
}
}

@ -0,0 +1,13 @@
import java.lang.Integer;
import java.lang.Float;
public class Bug293 {
bar(a) {
return 2 * a;
}
}
interface IFoo {
void ga();
}

@ -0,0 +1,18 @@
import java.lang.Integer;
public class Bug295 {
public Integer a;
public Integer b;
public Integer c;
public Bug295(a, b, c) {
this(a);
this.b = b;
this.c = c;
}
public Bug295(a) {
this.a = a;
}
}

@ -0,0 +1,11 @@
import java.lang.Integer;
public class Bug296 {
public static m1() {
return m2();
}
static m2() {
return 10;
}
}

@ -0,0 +1,11 @@
import java.lang.Integer;
public class Bug297 {
public static operation(func, a, b) {
return func.apply(a, b);
}
public exec() {
return Foo.operation((x, y) -> x + y, 10, 10);
}
}

@ -0,0 +1,17 @@
import java.util.List;
import java.util.ArrayList;
import java.lang.Integer;
import java.lang.System;
import java.lang.Boolean;
import java.io.PrintStream;
import java.util.stream.Stream;
import java.util.function.Function;
public class Bug298 {
public void m() {
List<Integer> list = new ArrayList<>();
list.stream().map(x -> 2 * x);
Function<Integer, Boolean> filter = x -> true;
}
}

@ -0,0 +1,17 @@
import java.lang.String;
class Base {
toString() {
return "Base";
}
}
public class Bug300 extends Base {
public m() {
return super.toString();
}
toString() {
return "Derived";
}
}

@ -0,0 +1,4 @@
import java.util.HashSet;
public class Bug301<A> extends HashSet<A> {
}

@ -0,0 +1,11 @@
import java.util.ArrayList;
import java.util.List;
import java.lang.Integer;
public class Bug302 {
public Bug302(List<Integer> a){}
public static m() {
new Bug302(new ArrayList<Integer>());
}
}

@ -0,0 +1,13 @@
import java.lang.Integer;
import java.util.List;
class Base {
m(List<Integer> a) {}
}
public class Bug306 extends Base {
@Override
m(List<Integer> b) {
b.add(1);
}
}

@ -0,0 +1,46 @@
public class Bug307 {
public void main() {
IVisitor v = new Visitor();
Impl2 f = new Impl2();
Impl1 g = new Impl1();
f.accept(v);
g.accept(v);
}
}
interface IVisitor {
void visit(Impl1 f);
void visit(Impl2 fb);
}
interface IAcceptor {
void accept(IVisitor v);
}
class Visitor implements IVisitor {
@Override
public void visit(Impl1 f) {
}
@Override
public void visit(Impl2 fb) {
}
}
class Impl1 implements IAcceptor {
@Override
public void accept(IVisitor v) {
v.visit(this);
}
}
class Impl2 implements IAcceptor {
@Override
public void accept(IVisitor v) {
v.visit(this);
}
}

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

@ -0,0 +1,9 @@
import java.lang.Integer;
import java.lang.String;
public class Bug310 {
Integer i = 3;
public toString() {
return i.toString();
}
}

@ -0,0 +1,10 @@
import java.lang.String;
public class Bug311 {
Bug311A i = new Bug311A();
public toString() {
return i.toString();
}
}
class Bug311A {}

@ -0,0 +1,8 @@
public class Bug312 {
Bug312A i = new Bug312A();
public main() {
if (i == null) {}
}
}
class Bug312A {}

@ -0,0 +1,13 @@
import java.lang.Integer;
import java.util.List;
import java.util.ArrayList;
import java.util.stream.Stream;
import java.util.function.Predicate;
import java.util.function.Function;
import java.util.stream.Collectors;
public class Bug314 {
public List<Integer> convert(List<Integer> in) {
return in.stream().filter(x -> x > 5).collect(Collectors.toList());
}
}

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

@ -0,0 +1,8 @@
import java.lang.Integer;
public class Bug326 {
public Bug326() {
var func = x -> y -> x * y;
return func.apply(3).apply(4);
}
}

@ -0,0 +1,8 @@
import java.lang.Integer;
import Bug328B;
public class Bug328 extends Bug328B {
public Bug328() {
super(1);
}
}

Binary file not shown.

@ -0,0 +1,3 @@
public class Bug328B {
public Bug328B(int a) {}
}

@ -0,0 +1,16 @@
import java.util.Vector;
import java.lang.Integer;
import java.lang.String;
public class Bug98 {
public m(x, y ,z) {
x = new Vector<Integer>();
y = new Vector<String>();
x.add(1);
y.add("2");
//Integer i = x.elementAt(0);
//String s = y.elementAt(0);
return z.vectorAddAll(x, y);
}
}

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

@ -1,11 +1,11 @@
import java.lang.Integer;
import java.lang.String;
import BB;
public class CC extends BB {
m(Integer i) {
public m(Integer i) {
return "CC";
}
m2(CC x) { return "CC"; }
public m2(CC x) { return "CC"; }
}

@ -7,7 +7,7 @@ public class Chain {
return this;
}
m() {
public m() {
return this.chain().chain().chain().x;
}
}

@ -1,5 +1,5 @@
class Cycle {
m(x, y) {
public class Cycle {
public m(x, y) {
y = x;
x = y;
}

@ -1,4 +1,5 @@
import java.lang.Integer;
import CC;
public class DD extends CC { }

@ -1,3 +1,8 @@
import java.lang.String;
import java.lang.RuntimeException;
public class Exceptions {
// m(Integer i) throws
public m() {
throw new RuntimeException("Some Exception");
}
}

@ -1,14 +1,14 @@
import java.lang.String;
public class FieldTph2 {
a;
public a;
m(b){
public m(b){
b = a;
return b;
}
m2(c){
public m2(c){
a = c;
}
}

@ -1,20 +1,20 @@
public class FieldTphConsMeth {
a;
public a;
public FieldTphConsMeth(c) {
a = id(c);
}
id(b) {
public id(b) {
return b;
}
setA(x) {
public setA(x) {
a = x;
return a;
}
m(x,y) {
public m(x,y) {
x = id(y);
}

@ -1,13 +1,13 @@
import java.lang.Boolean;
public class FieldTphMMeth {
a;
public a;
public FieldTphMMeth(c,d,e) {
a = m(c,d,e);
}
m(b,d,e) {
public m(b,d,e) {
if(e) {
return m3(b);
} else{
@ -16,11 +16,11 @@ public class FieldTphMMeth {
}
m2(b) {
public m2(b) {
a = m3(b);
}
m3(b){
public m3(b){
return b;
}

@ -1,8 +1,8 @@
import java.lang.Integer;
import java.lang.Boolean;
class For{
Integer m(Integer x){
public class For{
public Integer m(Integer x){
var c = x + 2;
Boolean b = true;
c = 5;

@ -0,0 +1,23 @@
import java.util.ArrayList;
import java.lang.Integer;
import java.lang.Number;
public class ForEach {
public m() {
var list = new ArrayList<>();
list.add(1); list.add(2); list.add(3);
var sum = 0;
for (var i : list) {
sum = sum + i;
}
return sum;
}
public m2() {
var list = new ArrayList<? extends Number>();
for (Number n : list) {
}
}
}

@ -6,7 +6,7 @@ public class FunctionalInterface {
return f.apply(20);
}
Integer m() {
public Integer m() {
var v = accept(i -> {
return i * 10;
});

@ -1,8 +1,8 @@
import java.lang.String;
import java.lang.Integer;
class Generics2<B extends String>{
<B extends Integer> B m1(B b){
public class Generics2<B extends String>{
public <X extends Integer> X m1(X b){
return b;
}

@ -3,7 +3,7 @@ import java.lang.String;
import java.io.PrintStream;
public class HelloWorld {
static hello() {
public static hello() {
System.out.println("Hello World!");
}
}

@ -2,15 +2,18 @@ import java.util.Vector;
import java.lang.Integer;
import java.lang.String;
import AA;
import BB;
import CC;
import DD;
public class Inherit {
main(d, i) {
public main(d, i) {
return d.m(i);
}
main(v, i) {
public main(v, i) {
var aa = v.elementAt(0);
return aa.m(i);
}

@ -2,15 +2,18 @@ import java.util.Vector;
import java.lang.Integer;
import java.lang.String;
import AA;
import BB;
import CC;
import DD;
public class Inherit2 {
main(d) {
public main(d) {
return d.m2(d);
}
main(v) {
public main(v) {
var aa = v.elementAt(0);
return aa.m2(aa);
}

@ -1,18 +1,18 @@
import java.lang.Number;
import java.lang.Object;
import java.lang.Integer;
import java.lang.Double;
import java.lang.String;
import java.lang.Boolean;
interface Interface {}
class Test implements Interface {
}
class Test2 {
}
public class InstanceOf {
main(n) {
if (n instanceof Integer i) {
takes(i);
return "Integer";
} else if (n instanceof Double d) {
takes(d);
return "Double";
}
}
a = new Test();
takes(i) {} // Should be overloaded
public test1() { return this.a instanceof Test; }
public test2() { return this.a instanceof Interface; }
public test3() { return this.a instanceof Integer; }
}

@ -1,8 +1,15 @@
public class LamRunnable{
import java.lang.Runnable;
import java.lang.System;
import java.lang.String;
import java.io.PrintStream;
public class LamRunnable {
public LamRunnable() {
Runnable lam = () -> {
System.out.println("lambda");
};
public LamRunnable(){
Runnable lam = () -> {System.out.println("lambda");};
lam.run();
}
}

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

@ -4,52 +4,52 @@ import java.lang.Float;
import java.lang.Double;
public class LessEqual {
lessEqual(Integer a, Integer b){
public lessEqual(Integer a, Integer b){
var c = a<=b;
return c;
}
lessEqual(Long a, Long b){
public lessEqual(Long a, Long b){
var c = a<=b;
return c;
}
lessEqual(Float a, Float b){
public lessEqual(Float a, Float b){
var c = a<=b;
return c;
}
lessEqual(Double a, Double b){
public lessEqual(Double a, Double b){
var c = a<=b;
return c;
}
lessEqual(Long a, Integer b){
public lessEqual(Long a, Integer b){
var c = a<=b;
return c;
}
lessEqual(Float a, Integer b){
public lessEqual(Float a, Integer b){
var c = a<=b;
return c;
}
lessEqual(Double a, Integer b){
public lessEqual(Double a, Integer b){
var c = a<=b;
return c;
}
lessEqual(Float a, Long b){
public lessEqual(Float a, Long b){
var c = a<=b;
return c;
}
lessEqual(Double a, Long b){
public lessEqual(Double a, Long b){
var c = a<=b;
return c;
}
lessEqual(Double a, Float b){
public lessEqual(Double a, Float b){
var c = a<=b;
return c;
}

@ -5,52 +5,52 @@ import java.lang.Double;
public class LessThan {
lessThan(Integer a, Integer b){
public lessThan(Integer a, Integer b){
var c = a<b;
return c;
}
lessThan(Long a, Long b){
public lessThan(Long a, Long b){
var c = a<b;
return c;
}
lessThan(Float a, Float b){
public lessThan(Float a, Float b){
var c = a<b;
return c;
}
lessThan(Double a, Double b){
public lessThan(Double a, Double b){
var c = a<b;
return c;
}
lessThan(Long a, Integer b){
public lessThan(Long a, Integer b){
var c = a<b;
return c;
}
lessThan(Float a, Integer b){
public lessThan(Float a, Integer b){
var c = a<b;
return c;
}
lessThan(Double a, Integer b){
public lessThan(Double a, Integer b){
var c = a<b;
return c;
}
lessThan(Float a, Long b){
public lessThan(Float a, Long b){
var c = a<b;
return c;
}
lessThan(Double a, Long b){
public lessThan(Double a, Long b){
var c = a<b;
return c;
}
lessThan(Double a, Float b){
public lessThan(Double a, Float b){
var c = a<b;
return c;
}

@ -0,0 +1,8 @@
import java.lang.Character;
public class Literal {
public m() { return null; }
public m2() { return 'C'; }
public m3() { return 10L; }
public m4() { return 10.5F; }
}

@ -1,3 +1,5 @@
import java.util.List;
import java.util.AbstractList;
import java.util.Vector;
import java.lang.Integer;
//import java.lang.Float;
@ -9,7 +11,7 @@ public class Matrix extends Vector<Vector<Integer>> {
Matrix () {
}
Matrix(vv) {
public Matrix(vv) {
Integer i;
i = 0;
while(i < vv.size()) {
@ -19,7 +21,7 @@ public class Matrix extends Vector<Vector<Integer>> {
}
}
mul(m) {
public mul(m) {
var ret = new Matrix();
var i = 0;
while(i < size()) {
@ -30,8 +32,8 @@ public class Matrix extends Vector<Vector<Integer>> {
var erg = 0;
var k = 0;
while(k < v1.size()) {
erg = erg + v1.elementAt(k)
* m.elementAt(k).elementAt(j);
erg = erg + v1.get(k)
* m.get(k).get(j);
k++; }
// v2.addElement(new Integer(erg));
v2.addElement(erg);

@ -8,7 +8,7 @@ public class MatrixOP extends Vector<Vector<Integer>> {
MatrixOP () {
}
MatrixOP(vv) {
public MatrixOP(vv) {
Integer i;
i = 0;
while(i < vv.size()) {

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

@ -1,13 +1,14 @@
import java.lang.Double;
import java.lang.String;
import java.lang.Long;
import java.lang.Integer;
class OL {
m (x) { return x + x; }
public class OL {
public m (x) { return x + x; }
}
class OLMain {
main(x) {
public class OLMain {
public main(x) {
var ol;
ol = new OL();
return ol.m(x);

@ -0,0 +1,17 @@
import java.lang.Integer;
public class Parent {
public Integer x;
public Parent(Integer a) {
this.x = a;
}
public Parent() {}
}
public class Child extends Parent {
public Child() {
super(3);
}
}

@ -1,11 +1,34 @@
public class Op1{
public Op1() {
Runnable lam = () -> {
String test = "";
String b = "b";
test = b;
System.out.println(test);};
//lam.run();
import java.lang.Boolean;
import java.lang.Integer;
public class Op1 {
public not() {
var b = false;
var c = !b;
return c;
}
public or() {
var a = 10;
var b = 20;
return a | b;
}
public and() {
var a = 10;
var b = 20;
return a & b;
}
public xor() {
var a = 10;
var b = 20;
return a ^ b;
}
public mod() {
var a = 10;
var b = 2;
return a % b;
}
}

@ -1,11 +1,17 @@
import java.lang.Integer;
import java.lang.Double;
import java.lang.String;
public class Op2 {
m(){
public m(){
var x = "";
var a = 5+x;
Integer x = 10;
Double y = 10.5;
var a = x - y;
return a;
}
}

@ -5,15 +5,15 @@ import java.lang.Float;
record Point(Number x, Number y) {}
public class OverloadPattern {
m(Point(Integer x, Integer y)) {
public m(Point(Integer x, Integer y)) {
return x + y;
}
m(Point(Float x, Float y)) {
public m(Point(Float x, Float y)) {
return x * y;
}
m(Integer x) {
public m(Integer x) {
return x;
}
}

@ -2,17 +2,17 @@ import java.lang.String;
public class Overloading{
test(x){
public test(x){
return x.methode();
}
methode(){
public methode(){
return "Overloading";
}
}
public class Overloading2{
methode(){
public methode(){
return "Overloading2";
}
}

@ -0,0 +1,12 @@
import java.lang.Object;
import java.lang.Boolean;
public class OverrideEquals extends OverrideRoot {
public boolean equals(Object o) {
return true;
}
public int method(int var1, float var2) {
return 0;
}
}

Binary file not shown.

@ -0,0 +1,3 @@
public abstract class OverrideRoot {
public abstract int method(int a, float b);
}

@ -2,31 +2,16 @@ import java.util.Vector;
import java.lang.Boolean;
import java.lang.Object;
class Pair<U, T> {
U a;
T b;
make(x) {
var ret = new Pair<>();
ret.a = x.elementAt(0);
ret.b = x.elementAt(1);
return ret;
}
/*
eq(a, b) {
b = a;
return a == b;
}
public class Pair<T, U> {
T x;
U y;
compare( p) {
return eq(p.a, p.b);
//return p.a == p.b;
}
public fst() {
return x;
}
void m(Pair<?, ?> p, List<? extends Eq> b)
{
//this.compare(p); //1, type incorrect
this.compare(this.make(b)); //2, OK
public snd() {
return y;
}
*/
}

@ -3,7 +3,7 @@ import java.lang.String;
public class Plus {
m(a,b) {
public m(a,b) {
return a+b;
}
}

@ -1,25 +1,25 @@
import java.lang.Integer;
public class PostIncDec {
m() {
public m() {
var i = 0;
i++;
return i;
}
m2() {
public m2() {
var i = 0;
var j = i++;
return j;
}
d() {
public d() {
var i = 0;
i--;
return i;
}
d2() {
public d2() {
var i = 0;
var j = i--;
return j;

@ -1,25 +1,25 @@
import java.lang.Integer;
public class PreInc {
m() {
public m() {
var i = 0;
++i;
return i;
}
m2() {
public m2() {
var i = 0;
var j = ++i;
return j;
}
d() {
public d() {
var i = 0;
--i;
return i;
}
d2() {
public d2() {
var i = 0;
var j = --i;
return j;

@ -3,16 +3,16 @@ import java.util.Stack;
public class Put {
putElement(ele, v) {
public putElement(ele, v) {
v.addElement(ele);
}
putElement(ele, s) {
public putElement(ele, s) {
s.push(ele);
}
main(ele, x) {
public main(ele, x) {
putElement(ele, x);
}

@ -11,12 +11,12 @@ record Rec(Integer a, Integer b) {}
}*/
public class RecordTest {
a = new Rec(10, 20);
b = new Rec(10, 20);
c = new Rec(20, 40);
Rec a = new Rec(10, 20);
Rec b = new Rec(10, 20);
Rec c = new Rec(20, 40);
doesEqual() { return a.equals(b); }
doesNotEqual() { return b.equals(c); }
hashCode() { return a.hashCode(); }
toString() { return a.toString(); }
public doesEqual() { return a.equals(b); }
public doesNotEqual() { return b.equals(c); }
public hashCode() { return a.hashCode(); }
public toString() { return a.toString(); }
}

@ -2,7 +2,7 @@ import java.lang.Integer;
import java.lang.Boolean;
public class RelOps {
m(a,b){
public m(a,b){
return a<b;
}
}

@ -6,7 +6,7 @@ import java.lang.Float;
public class Scalar extends Vector<Integer> {
Scalar(v) {
public Scalar(v) {
Integer i;
i = 0;
while(i < v.size()) {
@ -15,7 +15,7 @@ public class Scalar extends Vector<Integer> {
}
}
mul(v) {
public mul(v) {
var ret = 0;
var i = 0;
while(i < size()) {

@ -12,7 +12,7 @@ public class Static {
i = x;
}
static m() {
public static m() {
return i + Other.field;
}
}

@ -0,0 +1,11 @@
import java.lang.Integer;
class Parent {
public Parent(Integer x) {}
}
public class SuperCall extends Parent {
public SuperCall() {
super(20);
}
}

@ -2,10 +2,10 @@ import java.lang.Integer;
import java.lang.Object;
import java.lang.Float;
record Rec(Integer a, Object b) {}
public record Rec(Integer a, Object b) {}
public class Switch {
main(o) {
public main(o) {
return switch (o) {
case Rec(Integer a, Integer b) -> a + b;
case Rec(Integer a, Float b) -> a + 10;

@ -3,7 +3,7 @@ import java.lang.String;
import java.lang.Object;
public class SwitchString {
main(o) {
public main(o) {
return switch (o) {
case "AaAaAa" -> 1; // These two have the same hash code!
case "AaAaBB" -> 2;

@ -1,10 +1,10 @@
import java.lang.String;
class TXGenerics {
public class TXGenerics {
a;
b;
test() {
public test() {
var c = new Cycle();
c.m(a, b);
}

@ -0,0 +1,9 @@
import java.lang.Boolean;
import java.lang.String;
import java.lang.Integer;
public class Ternary {
public main(x) {
return x > 10 ? "big" : "small";
}
}

@ -1,11 +1,11 @@
public class Tph {
m(a,b){
public m(a,b){
var c = m2(b);
return a;
}
m2(b){
public m2(b){
return b;
}
}

@ -0,0 +1,11 @@
import java.lang.Object;
import java.lang.Integer;
import java.util.List;
import java.util.ArrayList;
public class TypeCast {
public void main() {
Object a = new ArrayList<Integer>();
ArrayList b = (ArrayList) a;
}
}

@ -3,7 +3,7 @@ import java.lang.Long;
import java.lang.Double;
public class While {
m(x) {
public m(x) {
while(x < 2) {
x = x+1;
}

@ -0,0 +1,8 @@
import java.util.List;
import java.lang.Number;
public class Wildcards {
public void m1(List<?> a) {}
public void m2(List<? extends Number> a) {}
public void m3(List<? super Number> a) {}
}

@ -1,10 +1,10 @@
import java.lang.Integer;
class Y {
public class Y {
y;
//factorial;
Y() {
public Y() {
y = f -> t -> f.apply(y.apply(f)).apply(t);
//factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
}

@ -3,7 +3,7 @@ class Apply { }
public class applyLambda {
m () {
public m () {
var lam1 = (x) -> {
return x;
};

@ -0,0 +1,3 @@
package pkg.sub;
public interface Interface {}

@ -2,9 +2,12 @@ package de.dhbwstuttgart.bytecode;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
import de.dhbwstuttgart.target.generate.StatementToTargetExpression;
import de.dhbwstuttgart.target.tree.*;
import de.dhbwstuttgart.target.tree.expression.*;
import de.dhbwstuttgart.target.tree.type.*;
@ -13,6 +16,7 @@ import org.objectweb.asm.*;
import java.lang.invoke.*;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.stream.IntStream;
import static org.objectweb.asm.Opcodes.*;
import static de.dhbwstuttgart.target.tree.expression.TargetBinaryOp.*;
@ -25,8 +29,9 @@ public class Codegen {
private int lambdaCounter = 0;
private final HashMap<TargetLambdaExpression, TargetMethod> lambdas = new HashMap<>();
private final JavaTXCompiler compiler;
private final ASTToTargetAST converter;
public Codegen(TargetStructure clazz, JavaTXCompiler compiler) {
public Codegen(TargetStructure clazz, JavaTXCompiler compiler, ASTToTargetAST converter) {
this.clazz = clazz;
this.className = clazz.qualifiedName().getClassName();
this.cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) {
@ -36,6 +41,7 @@ public class Codegen {
}
};
this.compiler = compiler;
this.converter = converter;
}
private record LocalVar(int index, String name, TargetType type) {
@ -135,7 +141,7 @@ public class Codegen {
} else if (type.equals(TargetType.Short) || type.equals(TargetType.short_)) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
} else if (type.equals(TargetType.Char) || type.equals(TargetType.char_)) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Char", "valueOf", "(C)Ljava/lang/Char;", false);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false);
}
}
@ -156,7 +162,7 @@ public class Codegen {
} else if (type.equals(TargetType.Short)) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false);
} else if (type.equals(TargetType.Char)) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Char", "charValue", "()C", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false);
}
}
@ -280,9 +286,12 @@ public class Codegen {
return TargetType.Float;
} else if (left.equals(TargetType.Long) || right.equals(TargetType.Long)) {
return TargetType.Long;
} else {
} else if (left.equals(TargetType.Integer) || right.equals(TargetType.Integer)) {
return TargetType.Integer;
} else if (left.equals(TargetType.Short) || right.equals(TargetType.Short)) {
return TargetType.Short;
}
return left;
}
private void generateBinaryOp(State state, TargetBinaryOp op) {
@ -717,15 +726,49 @@ public class Codegen {
private void generateLambdaExpression(State state, TargetLambdaExpression lambda) {
var mv = state.mv;
String methodName = "apply";
TargetMethod.Signature signature = null;
if (!(state.contextType instanceof TargetFunNType ctx)) {
var intf = compiler.getClass(new JavaClassName(state.contextType.name()));
if (intf != null) {
var method = intf.getMethods().stream().filter(m -> Modifier.isAbstract(m.modifier)).findFirst().orElseThrow();
methodName = method.getName();
var methodParams = new ArrayList<MethodParameter>();
for (var i = 0; i < lambda.signature().parameters().size(); i++) {
var param = lambda.signature().parameters().get(i);
var tpe = converter.convert(method.getParameterList().getParameterAt(i).getType());
methodParams.add(param.withType(tpe));
}
var retType = converter.convert(method.getReturnType());
signature = new TargetMethod.Signature(Set.of(), methodParams, retType);
}
}
if (signature == null) {
signature = new TargetMethod.Signature(Set.of(), lambda.signature().parameters().stream().map(par -> par.withType(TargetType.Object)).toList(), TargetType.Object);
}
signature = new TargetMethod.Signature(
signature.generics(),
signature.parameters().stream().map(par ->
par.withType(par.pattern().type() instanceof TargetGenericType ? TargetType.Object : par.pattern().type())
).toList(),
signature.returnType() instanceof TargetGenericType ? TargetType.Object : signature.returnType()
);
var parameters = new ArrayList<>(lambda.captures());
parameters.addAll(signature.parameters());
var implSignature = new TargetMethod.Signature(Set.of(), parameters, lambda.signature().returnType());
// Normalize
TargetMethod impl;
if (lambdas.containsKey(lambda)) {
impl = lambdas.get(lambda);
} else {
var name = "lambda$" + lambdaCounter++;
var parameters = new ArrayList<>(lambda.captures());
parameters.addAll(lambda.params().stream().map(param -> param.pattern().type() instanceof TargetGenericType ? param.withType(TargetType.Object) : param).toList());
impl = new TargetMethod(0, name, lambda.block(), new TargetMethod.Signature(Set.of(), parameters, lambda.returnType() instanceof TargetGenericType ? TargetType.Object : lambda.returnType()), null);
impl = new TargetMethod(0, name, lambda.block(), implSignature, null);
generateMethod(impl);
lambdas.put(lambda, impl);
}
@ -733,17 +776,7 @@ public class Codegen {
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(), impl.getDescriptor(), false);
// TODO maybe make this a function?
var desugared = "(";
for (var param : lambda.params())
desugared += "Ljava/lang/Object;";
desugared += ")";
if (lambda.returnType() != null)
desugared += "Ljava/lang/Object;";
else
desugared += "V";
var handle = new Handle(H_INVOKEVIRTUAL, clazz.getName(), impl.name(), implSignature.getDescriptor(), false);
var params = new ArrayList<TargetType>();
params.add(new TargetRefType(clazz.qualifiedName().getClassName()));
@ -751,17 +784,15 @@ public class Codegen {
var descriptor = TargetMethod.getDescriptor(state.contextType, params.toArray(TargetType[]::new));
mv.visitVarInsn(ALOAD, 0);
for (var capture : lambda.captures()) {
for (var index = 0; index < lambda.captures().size(); index++) {
var capture = lambda.captures().get(index);
var pattern = (TargetTypePattern) capture.pattern();
mv.visitVarInsn(ALOAD, state.scope.get(pattern.name()).index);
var variable = state.scope.get(pattern.name());
mv.visitVarInsn(ALOAD, variable.index);
mv.visitTypeInsn(CHECKCAST, capture.pattern().type().getInternalName());
}
String methodName;
var intf = compiler.getClass(new JavaClassName(state.contextType.name()));
if (intf == null) methodName = "apply"; // TODO Weird fallback logic here
else methodName = intf.getMethods().stream().filter(m -> Modifier.isAbstract(m.modifier)).findFirst().orElseThrow().getName();
mv.visitInvokeDynamicInsn(methodName, descriptor, bootstrap, Type.getType(desugared), handle, Type.getType(TargetMethod.getDescriptor(impl.signature().returnType(), lambda.params().stream().map(mp -> mp.pattern().type()).toArray(TargetType[]::new))));
mv.visitInvokeDynamicInsn(methodName, descriptor, bootstrap, Type.getType(signature.getSignature()), handle, Type.getType(signature.getDescriptor()));
}
private void generate(State state, TargetExpression expr) {
@ -805,6 +836,7 @@ public class Codegen {
case StringLiteral stringLiteral -> mv.visitLdcInsn(stringLiteral.value());
case CharLiteral charLiteral -> mv.visitIntInsn(BIPUSH, charLiteral.value());
case DoubleLiteral doubleLiteral -> mv.visitLdcInsn(doubleLiteral.value());
case Null ignored -> mv.visitInsn(ACONST_NULL);
case BooleanLiteral booleanLiteral -> {
if (booleanLiteral.value()) {
mv.visitInsn(ICONST_1);
@ -871,6 +903,8 @@ public class Codegen {
case TargetLocalVar localVar: {
LocalVar local = state.scope.get(localVar.name());
mv.visitVarInsn(ALOAD, local.index());
// This is a bit weird but sometimes the types don't match (see lambda expressions)
convertTo(state, local.type(), localVar.type());
unboxPrimitive(state, local.type());
break;
}
@ -884,8 +918,12 @@ public class Codegen {
case TargetFor _for: {
state.enterScope();
var localCounter = state.localCounter;
if (_for.init() != null)
_for.init().forEach(e -> generate(state, e));
if (_for.init() != null) {
for (var e : _for.init()) {
generate(state, e);
if (e instanceof TargetAssign) mv.visitInsn(POP);
}
}
Label start = new Label();
Label end = new Label();
@ -918,6 +956,9 @@ public class Codegen {
state.localCounter = localCounter;
break;
}
case TargetForEach forEach:
generateForEach(forEach, state);
break;
case TargetWhile _while: {
Label start = new Label();
Label end = new Label();
@ -953,13 +994,34 @@ public class Codegen {
}
case TargetReturn ret: {
if (ret.expression() != null && state.returnType != null) {
var ctype = state.contextType;
state.contextType = state.returnType;
generate(state, ret.expression());
state.contextType = ctype;
convertTo(state, ret.expression().type(), state.returnType);
boxPrimitive(state, state.returnType);
mv.visitInsn(ARETURN);
if (state.returnType instanceof TargetPrimitiveType) {
var ctype = state.contextType;
state.contextType = state.returnType;
generate(state, ret.expression());
state.contextType = ctype;
unboxPrimitive(state, state.returnType);
if (state.returnType.equals(TargetType.boolean_)
|| state.returnType.equals(TargetType.char_)
|| state.returnType.equals(TargetType.int_)
|| state.returnType.equals(TargetType.short_)
|| state.returnType.equals(TargetType.byte_))
mv.visitInsn(IRETURN);
else if (state.returnType.equals(TargetType.long_))
mv.visitInsn(LRETURN);
else if (state.returnType.equals(TargetType.float_))
mv.visitInsn(FRETURN);
else if (state.returnType.equals(TargetType.double_))
mv.visitInsn(DRETURN);
} else {
var ctype = state.contextType;
state.contextType = state.returnType;
generate(state, ret.expression());
state.contextType = ctype;
boxPrimitive(state, ret.expression().type());
convertTo(state, ret.expression().type(), state.returnType);
mv.visitInsn(ARETURN);
}
} else
mv.visitInsn(RETURN);
break;
@ -999,7 +1061,10 @@ public class Codegen {
break;
}
case TargetMethodCall call: {
generate(state, call.expr());
if (!call.isStatic()) {
generate(state, call.expr());
boxPrimitive(state, call.expr().type());
}
for (var i = 0; i < call.args().size(); i++) {
var e = call.args().get(i);
var arg = call.parameterTypes().get(i);
@ -1014,7 +1079,12 @@ public class Codegen {
if (call.owner() instanceof TargetFunNType) // Decay FunN
descriptor = TargetMethod.getDescriptor(call.returnType() == null ? null : TargetType.Object, call.parameterTypes().stream().map(x -> TargetType.Object).toArray(TargetType[]::new));
mv.visitMethodInsn(call.isInterface() ? INVOKEINTERFACE : call.isStatic() ? INVOKESTATIC : call.name().equals("<init>") ? INVOKESPECIAL : INVOKEVIRTUAL, call.owner().getInternalName(), call.name(), descriptor, call.isInterface());
int insn = INVOKEVIRTUAL;
if (call.isStatic()) insn = INVOKESTATIC;
else if (call.isInterface()) insn = INVOKEINTERFACE;
else if (call.name().equals("<init>") || call.expr() instanceof TargetSuper || call.isPrivate()) insn = INVOKESPECIAL;
mv.visitMethodInsn(insn, call.owner().getInternalName(), call.name(), descriptor, call.isInterface());
if (call.type() != null && call.returnType() != null && !(call.returnType() instanceof TargetPrimitiveType)) {
if (!call.returnType().equals(call.type()) && !(call.type() instanceof TargetGenericType))
@ -1036,15 +1106,65 @@ public class Codegen {
mv.visitMethodInsn(INVOKESPECIAL, _new.type().getInternalName(), "<init>", _new.getDescriptor(), false);
break;
}
case TargetThrow _throw: {
generate(state, _throw.expr());
mv.visitInsn(ATHROW);
break;
}
case TargetTernary ternary: {
generate(state, ternary.cond());
var iffalse = new Label();
var end = new Label();
mv.visitJumpInsn(IFEQ, iffalse);
generate(state, ternary.iftrue());
convertTo(state, ternary.iftrue().type(), ternary.type());
mv.visitJumpInsn(GOTO, end);
mv.visitLabel(iffalse);
generate(state, ternary.iffalse());
convertTo(state, ternary.iffalse().type(), ternary.type());
mv.visitLabel(end);
break;
}
default:
throw new CodeGenException("Unexpected value: " + expr);
}
}
private void generateForEach(TargetForEach forEach, State state) {
state.enterScope();
TargetVarDecl vd = (TargetVarDecl) forEach.vardecl();
var localVar = state.createVariable(vd.name(), vd.varType());
var expr = forEach.expression();
// TODO Check for arrays
var mv = state.mv;
generate(state, expr);
mv.visitMethodInsn(INVOKEINTERFACE, "java/lang/Iterable", "iterator", "()Ljava/util/Iterator;", true);
var start = new Label();
var end = new Label();
mv.visitLabel(start);
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z", true);
mv.visitJumpInsn(IFEQ, end);
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true);
mv.visitTypeInsn(CHECKCAST, localVar.type().getInternalName());
mv.visitVarInsn(ASTORE, localVar.index);
generate(state, forEach.body());
mv.visitJumpInsn(GOTO, start);
mv.visitLabel(end);
mv.visitInsn(POP);
state.exitScope();
}
private void generateInstanceOf(State state, TargetInstanceOf instanceOf) {
var mv = state.mv;
if (instanceOf.right() instanceof TargetTypePattern right && right.name() == null) {
generate(state, instanceOf.left());
mv.visitTypeInsn(INSTANCEOF, right.type().getInternalName());
return;
}
@ -1313,8 +1433,8 @@ public class Codegen {
private void generateField(TargetField field) {
var access = field.access();
if ((access & ACC_PRIVATE) == 0 && (access & ACC_PROTECTED) == 0) // TODO Implement access modifiers properly
access |= ACC_PUBLIC;
//if ((access & ACC_PRIVATE) == 0 && (access & ACC_PROTECTED) == 0) // TODO Implement access modifiers properly
// access |= ACC_PUBLIC;
cw.visitField(access, field.name(), field.type().toSignature(), field.type().toDescriptor(), null);
}
@ -1332,10 +1452,10 @@ public class Codegen {
}
private void generateConstructor(TargetConstructor constructor) {
MethodVisitor mv = cw.visitMethod(constructor.access() | ACC_PUBLIC, "<init>", constructor.getDescriptor(), constructor.getSignature(), null);
MethodVisitor mv = cw.visitMethod(constructor.access(), "<init>", constructor.getDescriptor(), constructor.getSignature(), null);
if (constructor.txGenerics() != null)
mv.visitAttribute(new JavaTXSignatureAttribute(constructor.getTXSignature()));
mv.visitCode();
var state = new State(null, mv, 1);
for (var param : constructor.parameters()) {
@ -1349,8 +1469,8 @@ public class Codegen {
generate(state, stmts.get(0));
if (constructor.fieldInitializer() != null) {
var stmts2 = constructor.fieldInitializer().statements();
for (var i = 1; i < stmts2.size(); i++) {
generate(state, stmts2.get(i));
for (TargetExpression expression : stmts2) {
generate(state, expression);
}
}
for (var i = 1; i < stmts.size(); i++)
@ -1387,9 +1507,11 @@ public class Codegen {
}
private void generateMethod(TargetMethod method) {
var access = method.access() | ACC_PUBLIC;
var access = method.access();
if (method.block() == null)
access |= ACC_ABSTRACT;
if (clazz instanceof TargetInterface)
access |= ACC_PUBLIC;
// TODO The older codegen has set ACC_PUBLIC for all methods, good for testing but bad for everything else
MethodVisitor mv = cw.visitMethod(access, method.name(), method.getDescriptor(), method.getSignature(), null);
@ -1431,8 +1553,8 @@ public class Codegen {
public byte[] generate() {
var access = clazz.modifiers();
if ((access & ACC_PRIVATE) == 0 && (access & ACC_PROTECTED) == 0) // TODO Implement access modifiers properly
access |= ACC_PUBLIC;
//if ((access & ACC_PRIVATE) == 0 && (access & ACC_PROTECTED) == 0) // TODO Implement access modifiers properly
// access |= ACC_PUBLIC;
if (!(clazz instanceof TargetInterface))
access |= ACC_SUPER;

@ -2,6 +2,8 @@ package de.dhbwstuttgart.core;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.*;
public class ConsoleInterface {
private static final String directory = System.getProperty("user.dir");
@ -35,9 +37,9 @@ public class ConsoleInterface {
input.add(new File(arg));
}
}
JavaTXCompiler compiler = new JavaTXCompiler(input, classpath);
JavaTXCompiler compiler = new JavaTXCompiler(input, classpath, outputPath != null ? new File(outputPath) : null);
//compiler.typeInference();
compiler.generateBytecode(outputPath);
compiler.generateBytecode();
}

@ -1,7 +1,6 @@
//PL 2018-12-19: typeInferenceOld nach typeInference uebertragen
package de.dhbwstuttgart.core;
import com.google.common.collect.Lists;
import de.dhbwstuttgart.bytecode.Codegen;
import de.dhbwstuttgart.environment.CompilationEnvironment;
import de.dhbwstuttgart.environment.DirectoryClassLoader;
@ -31,7 +30,6 @@ import de.dhbwstuttgart.syntaxtree.type.TypeVisitor;
import de.dhbwstuttgart.syntaxtree.visual.ASTTypePrinter;
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
import de.dhbwstuttgart.target.generate.GenericsResult;
import de.dhbwstuttgart.target.tree.expression.TargetBinaryOp;
import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair;
@ -51,12 +49,9 @@ import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl;
import de.dhbwstuttgart.typeinference.unify.UnifyResultModel;
import de.dhbwstuttgart.typeinference.unify.UnifyTaskModel;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.io.*;
import java.lang.reflect.Modifier;
import java.nio.file.Path;
import java.util.*;
import java.util.Map.Entry;
import java.util.function.Function;
@ -71,18 +66,19 @@ public class JavaTXCompiler {
Boolean resultmodel = true;
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
Boolean log = false; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll?
Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll?
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
private final DirectoryClassLoader classLoader;
public final DirectoryClassLoader classLoader;
private final List<File> classPath;
public final List<File> classPath;
private final File outputPath;
public DirectoryClassLoader getClassLoader() {
return classLoader;
}
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
this(Arrays.asList(sourceFile), null);
this(Arrays.asList(sourceFile), List.of(), new File("."));
}
public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
@ -91,17 +87,20 @@ public class JavaTXCompiler {
}
public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException {
this(sourceFiles, null);
this(sourceFiles, List.of(), new File("."));
}
public JavaTXCompiler(List<File> sources, List<File> contextPath) throws IOException, ClassNotFoundException {
if (contextPath == null || contextPath.isEmpty()) {
public JavaTXCompiler(List<File> sources, List<File> contextPath, File outputPath) throws IOException, ClassNotFoundException {
var path = new ArrayList<>(contextPath);
if (contextPath.isEmpty()) {
// When no contextPaths are given, the working directory is the sources root
contextPath = Lists.newArrayList(new File(System.getProperty("user.dir")));
path.add(new File(System.getProperty("user.dir")));
}
classLoader = new DirectoryClassLoader(contextPath, ClassLoader.getSystemClassLoader());
if (outputPath != null) path.add(outputPath);
classLoader = new DirectoryClassLoader(path, ClassLoader.getSystemClassLoader());
environment = new CompilationEnvironment(sources);
classPath = contextPath;
classPath = path;
this.outputPath = outputPath;
for (File s : sources) {
parse(s);
@ -114,6 +113,7 @@ public class JavaTXCompiler {
}
public ClassOrInterface getClass(JavaClassName name) {
if (loadedClasses.containsKey(name)) return loadedClasses.get(name).cif();
for (var sf : sourceFiles.values()) {
for (var clazz : sf.KlassenVektor) {
if (clazz.getClassName().equals(name)) return clazz;
@ -127,33 +127,48 @@ public class JavaTXCompiler {
return null;
}
public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException, IOException {
List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses();
List<ClassOrInterface> importedClasses = new ArrayList<>();
ClassOrInterface objectClass = ASTFactory.createClass(classLoader.loadClass(new JavaClassName("java.lang.Object").toString()));
// Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
for (Entry<File, SourceFile> source : sourceFiles.entrySet()) {
for (JavaClassName name : source.getValue().getImports()) {
importedClasses.addAll(getAvailableClasses(name));
}
for (Class c : CompilationEnvironment.loadDefaultPackageClasses(source.getValue().getPkgName(), source.getKey(), this)) {
ClassOrInterface importedClass = ASTFactory.createClass(c);
importedClasses.add(importedClass);
public ConstraintSet<Pair> getConstraints(File sourceFile) throws ClassNotFoundException, IOException {
Set<ClassOrInterface> allClasses = new HashSet<>();// environment.getAllAvailableClasses();
ClassOrInterface objectClass = ASTFactory.createClass(Object.class);
var recordClass = ASTFactory.createClass(Record.class);
allClasses.add(objectClass);
allClasses.add(recordClass);
var sf = sourceFiles.get(sourceFile);
var importedClasses = new ArrayList<ClassOrInterface>();
for (JavaClassName name : sf.getImports()) {
importedClasses.addAll(getAvailableClasses(name));
}
for (Class c : CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), sourceFile, this)) {
ClassOrInterface importedClass = ASTFactory.createClass(c);
importedClasses.add(importedClass);
}
sf.availableClasses.addAll(importedClasses);
SourceFile sf_new = new SourceFile(sf.getPkgName(), sf.KlassenVektor.stream().map(cl -> new ClassOrInterface(cl)).collect(Collectors.toCollection(ArrayList::new)), sf.imports);
// sf enthaelt neues Source-File, neue Klassen-Objekte und neue
// ArrayListen-Objekte fuer Fields, Construktoren und Methoden
// Alle anderen Objekte werden nur kopiert.
var isCached = false;
for (var clazz : sf.availableClasses) {
if (loadedClasses.containsKey(clazz.getClassName())) {
allClasses.removeIf(cl -> cl.getClassName().equals(clazz.getClassName()));
var cif = loadedClasses.get(clazz.getClassName()).cif();
allClasses.add(cif);
isCached = true;
}
}
for (File f : this.sourceFiles.keySet()) {
SourceFile sf = sourceFiles.get(f);
sf = new SourceFile(sf.getPkgName(), sf.KlassenVektor.stream().map(cl -> new ClassOrInterface(cl)).collect(Collectors.toCollection(ArrayList::new)), sf.imports);
// sf enthaelt neues Source-File, neue Klassen-Objekte und neue
// ArrayListen-Objekte fuer Fields, Construktoren und Methoden
// Alle anderen Objekte werden nur kopiert.
SourceFile sf_new = sf;
sf.KlassenVektor.forEach(cl -> addMethods(sf_new, cl, importedClasses, objectClass));
allClasses.addAll(sf.getClasses());
if (!isCached) {
sf_new.KlassenVektor.forEach(cl -> addMethods(sf_new, cl, sf.availableClasses, objectClass));
allClasses.addAll(sf_new.getClasses());
}
allClasses.addAll(importedClasses);
TYPE ty = new TYPE(sourceFiles.values(), allClasses);
return ty.getConstraints();
allClasses.addAll(sf.KlassenVektor);
TYPE ty = new TYPE(sf, allClasses);
var constraints = ty.getConstraints();
return constraints;
}
void addMethods(SourceFile sf, ClassOrInterface cl, List<ClassOrInterface> importedClasses, ClassOrInterface objectClass) {
@ -183,36 +198,35 @@ public class JavaTXCompiler {
while (paraIt.hasNext()) {
gtvs.put(tvarVarIt.next().getName(), paraIt.next());
}
Iterator<Method> methodIt = superclass.getMethods().iterator();
// TODO: PL 2020-05-06: Hier müssen ueberschriebene Methoden noch rausgefiltert
// werden
while (methodIt.hasNext()) {
Method m = methodIt.next();
ParameterList newParaList = new ParameterList(m.getParameterList().getFormalparalist().stream().map(fp -> fp.withType(fp.getType().acceptTV(new TypeExchanger(gtvs)))).collect(Collectors.toCollection(ArrayList::new)), m.getParameterList().getOffset());
cl.getMethods().add(new Method(m.modifier, m.name, m.getReturnType().acceptTV(new TypeExchanger(gtvs)), newParaList, m.block,
// new GenericDeclarationList(newGenericsList,
// ((GenericDeclarationList)m.getGenerics()).getOffset()),
(GenericDeclarationList) m.getGenerics(), m.getOffset(), true));
}
for (Method m : superclass.getMethods()) {
if (m.isInherited || Modifier.isStatic(m.modifier)) continue;
// TODO: Add gtvs from method itself
ParameterList newParaList = new ParameterList(m.getParameterList().getFormalparalist().stream().map(fp -> fp.withType(fp.getType().acceptTV(new TypeExchanger(gtvs)))).collect(Collectors.toCollection(ArrayList::new)), m.getParameterList().getOffset());
cl.getMethods().add(new Method(m.modifier, m.name, m.getReturnType().acceptTV(new TypeExchanger(gtvs)), newParaList, m.block,
// new GenericDeclarationList(newGenericsList,
// ((GenericDeclarationList)m.getGenerics()).getOffset()),
(GenericDeclarationList) m.getGenerics(), m.getOffset(), true, false));
}
}
cl.setMethodsAdded();
}
private List<ClassOrInterface> getAvailableClasses(JavaClassName name) throws ClassNotFoundException {
private Set<ClassOrInterface> getAvailableClasses(JavaClassName name) throws ClassNotFoundException {
Set<ClassOrInterface> allClasses = new HashSet<>();
if (loadJavaTXClass(name)) {
var file = findFileForClass(name);
var sf = sourceFiles.get(file);
if (sf != null) allClasses.addAll(sf.KlassenVektor);
} else {
var clazz = loadJavaTXClass(name);
if (clazz == null) {
ClassOrInterface importedClass = ASTFactory.createClass(classLoader.loadClass(name.toString()));
allClasses.add(importedClass);
} else {
allClasses.add(clazz);
}
return new ArrayList<>(allClasses);
return allClasses;
}
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
public Set<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
// PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal
// hinzugefuegt werden
// List<ClassOrInterface> allClasses = new
@ -222,7 +236,7 @@ public class JavaTXCompiler {
for (JavaClassName name : forSourceFile.getImports()) {
allClasses.addAll(getAvailableClasses(name));
}
return new ArrayList<>(allClasses);
return allClasses;
}
/*
@ -278,17 +292,21 @@ public class JavaTXCompiler {
allClasses.addAll(CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), source.getKey(), this).stream().map(ASTFactory::createClass).collect(Collectors.toList()));
}
final ConstraintSet<Pair> cons = getConstraints();
final ConstraintSet<Pair> cons = new ConstraintSet<>();
for (var f : this.sourceFiles.keySet()) {
cons.addAll(getConstraints(f));
}
Set<Set<UnifyPair>> results = new HashSet<>();
UnifyResultModel urm = null;
// urm.addUnifyResultListener(resultListener);
try {
logFile = logFile == null ? new FileWriter(new File("log_" + sourceFiles.keySet().iterator().next().getName())) : logFile;
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, getClassLoader());
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, getClassLoader(), this);
System.out.println(finiteClosure);
urm = new UnifyResultModel(cons, finiteClosure);
urm.addUnifyResultListener(resultListener);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons);
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
UnifyType lhs, rhs;
@ -305,8 +323,8 @@ public class JavaTXCompiler {
TypeUnify unify = new TypeUnify();
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
logFile.write("FC:\\" + finiteClosure.toString() + "\n");
for (SourceFile sf : this.sourceFiles.values()) {
logFile.write(ASTTypePrinter.print(sf));
for (SourceFile f : this.sourceFiles.values()) {
logFile.write(ASTTypePrinter.print(f));
}
logFile.flush();
@ -399,32 +417,29 @@ public class JavaTXCompiler {
return urm;
}
public List<ResultSet> typeInference() throws ClassNotFoundException, IOException {
List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses();
// Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
for (Entry<File, SourceFile> source : this.sourceFiles.entrySet()) {
SourceFile sf = source.getValue();
allClasses.addAll(getAvailableClasses(sf));
allClasses.addAll(sf.getClasses());
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), source.getKey(), this).stream().map(ASTFactory::createClass).collect(Collectors.toList());
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);
}
public List<ResultSet> typeInference(File file) throws ClassNotFoundException, IOException {
var sf = sourceFiles.get(file);
Set<ClassOrInterface> allClasses = new HashSet<>();// environment.getAllAvailableClasses();
allClasses.addAll(getAvailableClasses(sf));
allClasses.addAll(sf.getClasses());
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), file, this).stream().map(ASTFactory::createClass).collect(Collectors.toSet());
for (var clazz : newClasses) {
// Don't load classes that get recompiled
if (sf.getClasses().stream().anyMatch(nf -> nf.getClassName().equals(clazz.getClassName())))
continue;
if (allClasses.stream().noneMatch(old -> old.getClassName().equals(clazz.getClassName())))
allClasses.add(clazz);
}
final ConstraintSet<Pair> cons = getConstraints();
final ConstraintSet<Pair> cons = getConstraints(file);
Set<Set<UnifyPair>> results = new HashSet<>();
try {
var logFolder = new File(System.getProperty("user.dir") + "/logFiles/");
if (log) logFolder.mkdirs();
Writer logFile = log ? new FileWriter(new File(logFolder, "log_" + sourceFiles.keySet().iterator().next().getName())) : new OutputStreamWriter(new NullOutputStream());
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, classLoader);
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses.stream().toList(), logFile, classLoader, this);
System.out.println(finiteClosure);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons);
System.out.println("xxx1");
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
UnifyType lhs, rhs;
@ -443,10 +458,8 @@ public class JavaTXCompiler {
TypeUnify unify = new TypeUnify();
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
logFile.write("FC:\\" + finiteClosure.toString() + "\n");
for (SourceFile sf : this.sourceFiles.values()) {
logFile.write(ASTTypePrinter.print(sf));
System.out.println(ASTTypePrinter.print(sf));
}
logFile.write(ASTTypePrinter.print(sf));
System.out.println(ASTTypePrinter.print(sf));
logFile.flush();
Set<String> methodParaTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist().stream().filter(z -> z.getType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce(new HashSet<String>(), (a, b) -> {
@ -648,14 +661,20 @@ public class JavaTXCompiler {
public final JavaClassRegistry classRegistry = new JavaClassRegistry();
public record ClassEntry(File classFile, ClassOrInterface cif) {}
public final Map<JavaClassName, ClassEntry> loadedClasses = new HashMap<>();
private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException {
if (sourceFiles.containsKey(sourceFile)) return sourceFiles.get(sourceFile);
SourceFileContext tree = JavaTXParser.parse(sourceFile);
environment.addClassesToRegistry(classRegistry, tree, sourceFile, this);
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null));
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null), sourceFile.getName());
var classes = new ArrayList<ClassOrInterface>();
var sf = new SourceFile(generator.pkgName, classes, generator.imports);
var sf = new SourceFile("", classes, generator.imports);
addSourceFile(sourceFile, sf);
generator.convert(classes, tree, environment.packageCrawler);
sf.setPackageName(generator.pkgName);
sf.imports.addAll(generator.imports);
return sf;
}
@ -665,24 +684,33 @@ public class JavaTXCompiler {
* if it doesn't exist it's going to compile it and add it to the source files list
* @param name
*/
public boolean loadJavaTXClass(JavaClassName name) {
public ClassOrInterface loadJavaTXClass(JavaClassName name) {
var file = findFileForClass(name);
if (file != null) {
if (loadedClasses.containsKey(name)) return loadedClasses.get(name).cif();
try {
var tree = JavaTXParser.parse(file);
classRegistry.addName(name.toString(), 0); // TODO This gets overwritten later, is it bad if we don't know this right away?
environment.addClassesToRegistry(classRegistry, tree, file, this);
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null));
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null), file.getName());
var classes = new ArrayList<ClassOrInterface>();
var sf = new SourceFile(generator.pkgName, classes, generator.imports);
var sf = new SourceFile("", classes, generator.imports);
addSourceFile(file, sf);
generator.convert(classes, tree, environment.packageCrawler);
return true;
sf.setPackageName(generator.pkgName);
var classFiles = generateBytecode(file);
sf.setGenerated();
writeClassFile(classFiles, outputPath != null ? outputPath : new File("."), false);
var clazz = classLoader.loadClass(name.toString());
var classOrInterface = ASTFactory.createClass(clazz);
loadedClasses.put(name, new ClassEntry(new File(outputPath, clazz.getName() + ".class"), classOrInterface));
return classOrInterface;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return false;
return null;
}
public File findFileForClass(JavaClassName name) {
@ -696,25 +724,26 @@ public class JavaTXCompiler {
}
public void generateBytecode() throws ClassNotFoundException, IOException {
generateBytecode((File) null);
}
/**
* @param path - can be null, then class file output is in the same directory as the parsed source files
*/
public void generateBytecode(String path) throws ClassNotFoundException, IOException {
if (path != null)
generateBytecode(new File(path));
else
generateBytecode();
for (var file : sourceFiles.keySet()) {
var sf = sourceFiles.get(file);
if (sf.isGenerated()) continue;
var classes = generateBytecode(file);
sf.setGenerated();
writeClassFile(classes, outputPath == null ? file.getParentFile() : outputPath, outputPath == null);
}
}
/**
* @param path - output-Directory can be null, then class file output is in the same directory as the parsed source files
* @return
*/
public void generateBytecode(File path) throws ClassNotFoundException, IOException {
List<ResultSet> typeinferenceResult = this.typeInference();
generateBytecode(path, typeinferenceResult);
public Map<JavaClassName, byte[]> generateBytecode(File sourceFile) throws ClassNotFoundException, IOException {
var sf = sourceFiles.get(sourceFile);
if (sf.isGenerated()) return null;
List<ResultSet> typeinferenceResult = this.typeInference(sourceFile);
var classes = generateBytecode(sf, typeinferenceResult);
sf.setGenerated();
return classes;
}
private Map<SourceFile, List<GenericsResult>> generatedGenerics = new HashMap<>();
@ -732,15 +761,13 @@ public class JavaTXCompiler {
for (File f : sourceFiles.keySet()) {
HashMap<JavaClassName, byte[]> classFiles = new HashMap<>();
SourceFile sf = sourceFiles.get(f);
File path;
File path = outputPath;
if (outputPath == null) {
path = f.getParentFile(); // Set path to path of the parsed .jav file
} else {
path = new File(outputPath, sf.getPkgName().replace(".", "/")); // add package path to root path
}
var generatedClasses = generateBytecode(sf, typeinferenceResult);
writeClassFile(generatedClasses, path);
writeClassFile(generatedClasses, path, outputPath == null);
}
}
@ -748,7 +775,7 @@ public class JavaTXCompiler {
var converter = new ASTToTargetAST(this, typeInferenceResult, sf, classLoader);
var generatedClasses = new HashMap<JavaClassName, byte[]>();
for (var clazz : sf.getClasses()) {
var codegen = new Codegen(converter.convert(clazz), this);
var codegen = new Codegen(converter.convert(clazz), this, converter);
var code = codegen.generate();
generatedClasses.put(clazz.getClassName(), code);
converter.auxiliaries.forEach((name, source) -> {
@ -759,15 +786,15 @@ public class JavaTXCompiler {
return generatedClasses;
}
public synchronized void writeClassFile(Map<JavaClassName, byte[]> classFiles, File path) throws IOException {
public synchronized void writeClassFile(Map<JavaClassName, byte[]> classFiles, File path, boolean preserveHierarchy) throws IOException {
FileOutputStream output;
for (JavaClassName name : classFiles.keySet()) {
byte[] bytecode = classFiles.get(name);
System.out.println("generating " + name + ".class file ...");
// output = new FileOutputStream(new File(System.getProperty("user.dir") +
// "/testBytecode/generatedBC/" +name+".class"));
File outputFile = new File(path, name.getClassName() + ".class");
var subPath = preserveHierarchy ? path : Path.of(path.toString(), name.getPackageName().split("\\.")).toFile();
File outputFile = new File(subPath, name.getClassName() + ".class");
outputFile.getAbsoluteFile().getParentFile().mkdirs();
System.out.println(outputFile);
output = new FileOutputStream(outputFile);
output.write(bytecode);
output.close();

@ -77,7 +77,7 @@ public class CompilationEnvironment {
// Set classLoader to include default package for this specific source file
File dir = sourceFile.getAbsoluteFile().getParentFile();
String dirPath = dir.toString() + "/";
if (packageName.length() > 0)
if (!packageName.isEmpty())
dirPath = dirPath.substring(0, dirPath.length() - packageName.length() - 1);
String path = dirPath;
ArrayList<File> defaultPath = Lists.newArrayList(new File(path));
@ -89,7 +89,10 @@ public class CompilationEnvironment {
String className = classFile.getName().substring(0, classFile.getName().length() - 6);
if (className.matches("Fun\\d+\\$\\$.*"))
continue;
ret.add(classLoader.loadClass(packageName + className));
var name = packageName;
if (!packageName.isEmpty()) name += ".";
name += className;
ret.add(classLoader.loadClass(name));
}
return ret;
}

@ -41,4 +41,8 @@ public class DirectoryClassLoader extends URLClassLoader implements IByteArrayCl
public Class<?> findClass(String name) throws ClassNotFoundException {
return super.findClass(name);
}
public Class<?> _findLoadedClass(String name) throws ClassNotFoundException {
return super.findLoadedClass(name);
}
}

@ -0,0 +1,4 @@
package de.dhbwstuttgart.parser;
public record SourceLoc(String file, int line) {
}

@ -1,5 +1,6 @@
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.JavaClassName;
@ -25,8 +26,8 @@ public class FCGenerator {
*
* @param availableClasses - Alle geparsten Klassen
*/
public static Set<UnifyPair> toUnifyFC(Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException {
return toFC(availableClasses, classLoader).stream().map(t -> UnifyTypeFactory.convert(t)).collect(Collectors.toSet());
public static Set<UnifyPair> toUnifyFC(JavaTXCompiler compiler, Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException {
return toFC(availableClasses, classLoader).stream().map(t -> UnifyTypeFactory.convert(compiler, t)).collect(Collectors.toSet());
}
public static Set<Pair> toFC(Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException {
@ -60,7 +61,7 @@ public class FCGenerator {
.collect(Collectors.toList()));
tl.add(m.getReturnType().acceptTV(new TypeExchanger(gtvs)));
return new Pair(new RefType(new JavaClassName("Fun" + (tl.size()-1) + "$$"), tl, new NullToken()),
fIType);
fIType, PairOperator.SMALLER);
}
return null; //kann nicht passieren, da die Methode nur aufgerufen wird wenn cl Functional Interface ist
}

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