forked from JavaTX/JavaCompilerCore
Compare commits
117 Commits
targetByte
...
aspGen
Author | SHA1 | Date | |
---|---|---|---|
9c2c6a3ea9 | |||
a7ad4fa984 | |||
fcda301b1e | |||
2aa3997f17 | |||
7e37497740 | |||
3d2b935c60 | |||
db01b0c8dd | |||
662756ac18 | |||
b0bf41968e | |||
2221b559ca | |||
021b7ec9fe | |||
154d4823e4 | |||
71dfe5d9e1 | |||
58110c474a | |||
df2ec4b1ba | |||
2c66a1d6e6 | |||
c76ee355d8 | |||
a5c314c5c5 | |||
cba35a4bec | |||
b774281cbb | |||
9358130468 | |||
708aa64283 | |||
c21e5202d6 | |||
b3bd5cde10 | |||
df78937ef3 | |||
7fb4824f8d | |||
e0d71a6003 | |||
49803385cf | |||
39d02f792c | |||
4fc78f494c | |||
b752219d8c | |||
ec890356e4 | |||
d405b0c3a2 | |||
6c8657b7a8 | |||
bcce4cee19 | |||
e6cd4038e2 | |||
e50f941b79 | |||
cb7d0e22cc | |||
0d5be89310 | |||
0b7f07108f | |||
6b0816c1c4 | |||
f66b9099f3 | |||
da74898f9d | |||
46a7f61234 | |||
e59accf7ee | |||
4b110244f2 | |||
e37040f367 | |||
6850a8fa21 | |||
877e5ed38a | |||
82b4450857 | |||
b70e435120 | |||
3b14cd609f | |||
8fdfbf875b | |||
bc61fc2e1d | |||
62f2e05f35 | |||
606ce8b82d | |||
c84befae51 | |||
7f3c1686ec | |||
43da2ffbdc | |||
9472b5c86f | |||
7cb0e9dbb7 | |||
e07521d9b6 | |||
c2ee12397f | |||
e6321ff8bc | |||
786e0a7a23 | |||
1c63321b30 | |||
1f74345324 | |||
518f58e08f | |||
0acfe6c0d4 | |||
c07d4d36e9 | |||
01e374eadd | |||
a1b5c0541b | |||
66c8c307b0 | |||
ebd6a00a39 | |||
f57d89c966 | |||
f9188e65ca | |||
e354838491 | |||
e17f08263e | |||
2cb84f9e2b | |||
83ae05ea4a | |||
26452eb5de | |||
38827544c9 | |||
ff905390e8 | |||
2d9094ec4e | |||
e27eb3a3fe | |||
73ca790711 | |||
452064398a | |||
20d6cb8eb9 | |||
b7f1db5d80 | |||
b327518921 | |||
945b47c762 | |||
65a71ebe0c | |||
deeb67c4f7 | |||
c92edeaf2a | |||
01e3d31f1a | |||
a90e9df1e8 | |||
1c1f5ae29f | |||
8ab5bbd831 | |||
1877d7f170 | |||
388614b220 | |||
f2e43f180c | |||
59585296b0 | |||
f11d4b0716 | |||
584690596e | |||
9c6372c3ba | |||
688358aa33 | |||
a60282414c | |||
75b9020cf9 | |||
e88d4428c5 | |||
dcfafe5995 | |||
a035589647 | |||
9da763b361 | |||
700ea125fc | |||
f18903834e | |||
b80cc726c8 | |||
6cc40162da | |||
71899ac673 |
.gitea/workflows
README.mdpom.xmlresources
AllgemeinTest
bytecode
javFiles
AA.javAccess.javAnnotation.javBB.javBinaryInMeth.javBug112.javBug122.javBug123.javBug125.javBug285.javBug290A.javBug290B.javBug293.javBug295.javBug296.javBug297.javBug298.javBug300.javBug301.javBug302.javBug306.javBug307.javBug309.javBug310.javBug311.javBug312.javBug314.javBug325.javBug326.javBug328.javBug328B.classBug328B.javaBug98.javBugXXX.javCC.javChain.javCycle.javDD.javExceptions.javFieldTph2.javFieldTphConsMeth.javFieldTphMMeth.javFor.javForEach.javFunctionalInterface.javGenerics2.javHelloWorld.javInherit.javInherit2.javInstanceOf.javLamRunnable.javLambda.javLessEqual.javLessThan.javLiteral.javMatrix.javMatrixOP.javMerge.javOL.javOLConstructor.javOp1.javOp2.javOverloadPattern.javOverloading.javOverrideEquals.javOverrideRoot.classOverrideRoot.javaPair.javPlus.javPostIncDec.javPreInc.javPut.javRecordTest.javRelOps.javScalar.javStatic.javSuperCall.javSwitch.javSwitchString.javTXGenerics.javTernary.javTph.javTypeCast.javWhile.javWildcards.javY.javapplyLambda.jav
packageTest
pkg
src
main
java
de
dhbwstuttgart
bytecode
core
environment
parser
SourceLoc.java
SyntaxTreeGenerator
FCGenerator.javaStatementGenerator.javaSyntacticSugar.javaSyntaxTreeGenerator.javaTypeGenerator.java
scope
syntaxtree
AbstractASTWalker.javaClassOrInterface.javaConstructor.javaMethod.javaRecord.javaSourceFile.javaStatementVisitor.java
factory
statement
BinaryExpr.javaForEachStmt.javaMethodCall.javaNewClass.javaStaticClassName.javaSuper.javaSuperCall.javaTernary.javaThis.javaThisCall.javaThrow.java
visual
target
generate
ASTToTargetAST.javaGenerateGenerics.javaStatementToTargetExpression.javaTracingStatementVisitor.java
tree
typeinference
assumptions
constraints
typeAlgo
unify
test
25
.gitea/workflows/build_and_test.yml
Normal file
25
.gitea/workflows/build_and_test.yml
Normal file
@ -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
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
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>
|
||||
|
10
resources/AllgemeinTest/Box.jav
Normal file
10
resources/AllgemeinTest/Box.jav
Normal file
@ -0,0 +1,10 @@
|
||||
class Box<A> {
|
||||
|
||||
A a;
|
||||
|
||||
Box(A a) {
|
||||
this.a = a;
|
||||
}
|
||||
}
|
||||
|
||||
|
46
resources/AllgemeinTest/List.jav
Normal file
46
resources/AllgemeinTest/List.jav
Normal file
@ -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"; }
|
||||
}
|
14
resources/bytecode/javFiles/Access.jav
Normal file
14
resources/bytecode/javFiles/Access.jav
Normal file
@ -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 {
|
||||
}
|
8
resources/bytecode/javFiles/Annotation.jav
Normal file
8
resources/bytecode/javFiles/Annotation.jav
Normal file
@ -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);
|
||||
}
|
||||
}
|
7
resources/bytecode/javFiles/Bug112.jav
Normal file
7
resources/bytecode/javFiles/Bug112.jav
Normal file
@ -0,0 +1,7 @@
|
||||
public class Bug112 {
|
||||
public m(x) {
|
||||
var y;
|
||||
x = y;
|
||||
return y;
|
||||
}
|
||||
}
|
12
resources/bytecode/javFiles/Bug122.jav
Normal file
12
resources/bytecode/javFiles/Bug122.jav
Normal file
@ -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++) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
13
resources/bytecode/javFiles/Bug123.jav
Normal file
13
resources/bytecode/javFiles/Bug123.jav
Normal file
@ -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;
|
||||
}
|
||||
}
|
16
resources/bytecode/javFiles/Bug125.jav
Normal file
16
resources/bytecode/javFiles/Bug125.jav
Normal file
@ -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();
|
||||
}
|
||||
}
|
15
resources/bytecode/javFiles/Bug285.jav
Normal file
15
resources/bytecode/javFiles/Bug285.jav
Normal file
@ -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();
|
||||
}
|
||||
}
|
7
resources/bytecode/javFiles/Bug290A.jav
Normal file
7
resources/bytecode/javFiles/Bug290A.jav
Normal file
@ -0,0 +1,7 @@
|
||||
import Bug290B;
|
||||
|
||||
public class Bug290A {
|
||||
public void m() {
|
||||
new Bug290B();
|
||||
}
|
||||
}
|
11
resources/bytecode/javFiles/Bug290B.jav
Normal file
11
resources/bytecode/javFiles/Bug290B.jav
Normal file
@ -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() + "$$";
|
||||
}
|
||||
}
|
13
resources/bytecode/javFiles/Bug293.jav
Normal file
13
resources/bytecode/javFiles/Bug293.jav
Normal file
@ -0,0 +1,13 @@
|
||||
import java.lang.Integer;
|
||||
import java.lang.Float;
|
||||
|
||||
public class Bug293 {
|
||||
bar(a) {
|
||||
return 2 * a;
|
||||
}
|
||||
}
|
||||
|
||||
interface IFoo {
|
||||
void ga();
|
||||
}
|
||||
|
18
resources/bytecode/javFiles/Bug295.jav
Normal file
18
resources/bytecode/javFiles/Bug295.jav
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
|
11
resources/bytecode/javFiles/Bug296.jav
Normal file
11
resources/bytecode/javFiles/Bug296.jav
Normal file
@ -0,0 +1,11 @@
|
||||
import java.lang.Integer;
|
||||
|
||||
public class Bug296 {
|
||||
public static m1() {
|
||||
return m2();
|
||||
}
|
||||
|
||||
static m2() {
|
||||
return 10;
|
||||
}
|
||||
}
|
11
resources/bytecode/javFiles/Bug297.jav
Normal file
11
resources/bytecode/javFiles/Bug297.jav
Normal file
@ -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);
|
||||
}
|
||||
}
|
17
resources/bytecode/javFiles/Bug298.jav
Normal file
17
resources/bytecode/javFiles/Bug298.jav
Normal file
@ -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;
|
||||
}
|
||||
}
|
17
resources/bytecode/javFiles/Bug300.jav
Normal file
17
resources/bytecode/javFiles/Bug300.jav
Normal file
@ -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";
|
||||
}
|
||||
}
|
4
resources/bytecode/javFiles/Bug301.jav
Normal file
4
resources/bytecode/javFiles/Bug301.jav
Normal file
@ -0,0 +1,4 @@
|
||||
import java.util.HashSet;
|
||||
|
||||
public class Bug301<A> extends HashSet<A> {
|
||||
}
|
11
resources/bytecode/javFiles/Bug302.jav
Normal file
11
resources/bytecode/javFiles/Bug302.jav
Normal file
@ -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>());
|
||||
}
|
||||
}
|
13
resources/bytecode/javFiles/Bug306.jav
Normal file
13
resources/bytecode/javFiles/Bug306.jav
Normal file
@ -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);
|
||||
}
|
||||
}
|
46
resources/bytecode/javFiles/Bug307.jav
Normal file
46
resources/bytecode/javFiles/Bug307.jav
Normal file
@ -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);
|
||||
}
|
||||
}
|
16
resources/bytecode/javFiles/Bug309.jav
Normal file
16
resources/bytecode/javFiles/Bug309.jav
Normal file
@ -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;
|
||||
}
|
||||
}
|
9
resources/bytecode/javFiles/Bug310.jav
Normal file
9
resources/bytecode/javFiles/Bug310.jav
Normal file
@ -0,0 +1,9 @@
|
||||
import java.lang.Integer;
|
||||
import java.lang.String;
|
||||
|
||||
public class Bug310 {
|
||||
Integer i = 3;
|
||||
public toString() {
|
||||
return i.toString();
|
||||
}
|
||||
}
|
10
resources/bytecode/javFiles/Bug311.jav
Normal file
10
resources/bytecode/javFiles/Bug311.jav
Normal file
@ -0,0 +1,10 @@
|
||||
import java.lang.String;
|
||||
|
||||
public class Bug311 {
|
||||
Bug311A i = new Bug311A();
|
||||
public toString() {
|
||||
return i.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class Bug311A {}
|
8
resources/bytecode/javFiles/Bug312.jav
Normal file
8
resources/bytecode/javFiles/Bug312.jav
Normal file
@ -0,0 +1,8 @@
|
||||
public class Bug312 {
|
||||
Bug312A i = new Bug312A();
|
||||
public main() {
|
||||
if (i == null) {}
|
||||
}
|
||||
}
|
||||
|
||||
class Bug312A {}
|
13
resources/bytecode/javFiles/Bug314.jav
Normal file
13
resources/bytecode/javFiles/Bug314.jav
Normal file
@ -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());
|
||||
}
|
||||
}
|
13
resources/bytecode/javFiles/Bug325.jav
Normal file
13
resources/bytecode/javFiles/Bug325.jav
Normal file
@ -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();
|
||||
}
|
||||
}
|
8
resources/bytecode/javFiles/Bug326.jav
Normal file
8
resources/bytecode/javFiles/Bug326.jav
Normal file
@ -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);
|
||||
}
|
||||
}
|
8
resources/bytecode/javFiles/Bug328.jav
Normal file
8
resources/bytecode/javFiles/Bug328.jav
Normal file
@ -0,0 +1,8 @@
|
||||
import java.lang.Integer;
|
||||
import Bug328B;
|
||||
|
||||
public class Bug328 extends Bug328B {
|
||||
public Bug328() {
|
||||
super(1);
|
||||
}
|
||||
}
|
BIN
resources/bytecode/javFiles/Bug328B.class
Normal file
BIN
resources/bytecode/javFiles/Bug328B.class
Normal file
Binary file not shown.
3
resources/bytecode/javFiles/Bug328B.java
Normal file
3
resources/bytecode/javFiles/Bug328B.java
Normal file
@ -0,0 +1,3 @@
|
||||
public class Bug328B {
|
||||
public Bug328B(int a) {}
|
||||
}
|
16
resources/bytecode/javFiles/Bug98.jav
Normal file
16
resources/bytecode/javFiles/Bug98.jav
Normal file
@ -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);
|
||||
}
|
||||
}
|
16
resources/bytecode/javFiles/BugXXX.jav
Normal file
16
resources/bytecode/javFiles/BugXXX.jav
Normal file
@ -0,0 +1,16 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.lang.String;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.lang.Integer;
|
||||
|
||||
class BugXXX {
|
||||
public main() {
|
||||
List<Integer> i = new ArrayList<>(List.of(1,2,3,4,5,6,7,8,9,10));
|
||||
Optional<Integer> tmp = i.stream().filter(x -> x == 5).map(x -> x*2).findFirst();
|
||||
return tmp;
|
||||
}
|
||||
}
|
@ -1,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;
|
||||
|
23
resources/bytecode/javFiles/ForEach.jav
Normal file
23
resources/bytecode/javFiles/ForEach.jav
Normal file
@ -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;
|
||||
}
|
||||
|
8
resources/bytecode/javFiles/Literal.jav
Normal file
8
resources/bytecode/javFiles/Literal.jav
Normal file
@ -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);
|
||||
|
17
resources/bytecode/javFiles/OLConstructor.jav
Normal file
17
resources/bytecode/javFiles/OLConstructor.jav
Normal file
@ -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";
|
||||
}
|
||||
}
|
12
resources/bytecode/javFiles/OverrideEquals.jav
Normal file
12
resources/bytecode/javFiles/OverrideEquals.jav
Normal file
@ -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;
|
||||
}
|
||||
}
|
BIN
resources/bytecode/javFiles/OverrideRoot.class
Normal file
BIN
resources/bytecode/javFiles/OverrideRoot.class
Normal file
Binary file not shown.
3
resources/bytecode/javFiles/OverrideRoot.java
Normal file
3
resources/bytecode/javFiles/OverrideRoot.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
|
11
resources/bytecode/javFiles/SuperCall.jav
Normal file
11
resources/bytecode/javFiles/SuperCall.jav
Normal file
@ -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);
|
||||
}
|
||||
|
9
resources/bytecode/javFiles/Ternary.jav
Normal file
9
resources/bytecode/javFiles/Ternary.jav
Normal file
@ -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;
|
||||
}
|
||||
}
|
11
resources/bytecode/javFiles/TypeCast.jav
Normal file
11
resources/bytecode/javFiles/TypeCast.jav
Normal file
@ -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;
|
||||
}
|
||||
|
8
resources/bytecode/javFiles/Wildcards.jav
Normal file
8
resources/bytecode/javFiles/Wildcards.jav
Normal file
@ -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;
|
||||
};
|
||||
|
3
resources/packageTest/pkg/sub/Interface.jav
Normal file
3
resources/packageTest/pkg/sub/Interface.jav
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
4
src/main/java/de/dhbwstuttgart/parser/SourceLoc.java
Normal file
4
src/main/java/de/dhbwstuttgart/parser/SourceLoc.java
Normal file
@ -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
Reference in New Issue
Block a user