Compare commits
22 Commits
master
...
effc31782f
Author | SHA1 | Date | |
---|---|---|---|
|
effc31782f | ||
|
2a24eab9d3 | ||
|
a314013f40 | ||
|
37c58be1f3 | ||
|
24920330c6 | ||
|
bc43ea749d | ||
|
c479b044b3 | ||
|
9046fb09e5 | ||
|
42e31a3471 | ||
|
d3b3f92193 | ||
|
8208abcaea | ||
|
e4a3939ce9 | ||
|
d903ec0ebb | ||
|
61de81cf92 | ||
|
59888006e0 | ||
|
94034912b4 | ||
|
f303163118 | ||
|
7d99fba044 | ||
|
3740d34954 | ||
|
d8b861ea95 | ||
|
cf45ea68bd | ||
|
be72e4d7fb |
9
pom.xml
9
pom.xml
@@ -44,11 +44,6 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
|||||||
<artifactId>asm</artifactId>
|
<artifactId>asm</artifactId>
|
||||||
<version>9.8</version>
|
<version>9.8</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.ow2.asm</groupId>
|
|
||||||
<artifactId>asm-util</artifactId>
|
|
||||||
<version>9.8</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@@ -78,8 +73,8 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
|||||||
<version>3.14.0</version>
|
<version>3.14.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<compilerArgs>--enable-preview</compilerArgs>
|
<compilerArgs>--enable-preview</compilerArgs>
|
||||||
<source>24</source>
|
<source>23</source>
|
||||||
<target>24</target>
|
<target>23</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
@@ -1,3 +0,0 @@
|
|||||||
class Bug378Id {
|
|
||||||
id2 = x -> x;
|
|
||||||
}
|
|
@@ -1,8 +0,0 @@
|
|||||||
import Bug378Id;
|
|
||||||
import java.lang.Integer;
|
|
||||||
|
|
||||||
class Bug378Main {
|
|
||||||
static main(args) {
|
|
||||||
var hallo = (new Bug378Id<Integer>().id2).apply(1);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,24 +0,0 @@
|
|||||||
import java.lang.Integer;
|
|
||||||
import java.lang.Double;
|
|
||||||
import java.lang.System;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
|
|
||||||
public class Bug379 {
|
|
||||||
public Fun1$$<Double, Double> fact = (x) -> {
|
|
||||||
if (x == 1) {
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return x * (fact.apply(x-1));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public getFact(x) {
|
|
||||||
return fact.apply(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(x) {
|
|
||||||
var f = new Bug379();
|
|
||||||
var intRes = f.getFact(3);
|
|
||||||
System.out.println(intRes);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -4,7 +4,7 @@ import java.lang.Integer;
|
|||||||
import java.lang.Boolean;
|
import java.lang.Boolean;
|
||||||
|
|
||||||
public class MatrixOP extends Vector<Vector<Integer>> {
|
public class MatrixOP extends Vector<Vector<Integer>> {
|
||||||
|
|
||||||
MatrixOP () {
|
MatrixOP () {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,8 +36,8 @@ public class MatrixOP extends Vector<Vector<Integer>> {
|
|||||||
v2.addElement(erg);
|
v2.addElement(erg);
|
||||||
j++; }
|
j++; }
|
||||||
ret.addElement(v2);
|
ret.addElement(v2);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -9,9 +9,7 @@ import de.dhbwstuttgart.target.tree.*;
|
|||||||
import de.dhbwstuttgart.target.tree.expression.*;
|
import de.dhbwstuttgart.target.tree.expression.*;
|
||||||
import de.dhbwstuttgart.target.tree.type.*;
|
import de.dhbwstuttgart.target.tree.type.*;
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
import org.objectweb.asm.util.CheckClassAdapter;
|
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.lang.invoke.*;
|
import java.lang.invoke.*;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -127,36 +125,34 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void popValue(State state, TargetType type) {
|
private void popValue(State state, TargetType type) {
|
||||||
if (type.equals(TargetType.double_) || type.equals(TargetType.long_))
|
if (type.equals(TargetType.Double) || type.equals(TargetType.Long))
|
||||||
state.mv.visitInsn(POP2);
|
state.mv.visitInsn(POP2);
|
||||||
else
|
else
|
||||||
state.mv.visitInsn(POP);
|
state.mv.visitInsn(POP);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void boxPrimitive(State state, TargetType type) {
|
private void boxPrimitive(State state, TargetType type) {
|
||||||
if (type instanceof TargetExtendsWildcard ew) type = ew.innerType();
|
|
||||||
var mv = state.mv;
|
var mv = state.mv;
|
||||||
if (type.equals(TargetType.boolean_)) {
|
if (type.equals(TargetType.Boolean) || type.equals(TargetType.boolean_)) {
|
||||||
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
|
||||||
} else if (type.equals(TargetType.byte_)) {
|
} else if (type.equals(TargetType.Byte) || type.equals(TargetType.byte_)) {
|
||||||
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
|
||||||
} else if (type.equals(TargetType.double_)) {
|
} else if (type.equals(TargetType.Double) || type.equals(TargetType.double_)) {
|
||||||
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
|
||||||
} else if (type.equals(TargetType.long_)) {
|
} else if (type.equals(TargetType.Long) || type.equals(TargetType.long_)) {
|
||||||
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
|
||||||
} else if (type.equals(TargetType.int_)) {
|
} else if (type.equals(TargetType.Integer) || type.equals(TargetType.int_)) {
|
||||||
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
|
||||||
} else if (type.equals(TargetType.float_)) {
|
} else if (type.equals(TargetType.Float) || type.equals(TargetType.float_)) {
|
||||||
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
|
||||||
} else if (type.equals(TargetType.short_)) {
|
} else if (type.equals(TargetType.Short) || type.equals(TargetType.short_)) {
|
||||||
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
|
||||||
} else if (type.equals(TargetType.char_)) {
|
} else if (type.equals(TargetType.Char) || type.equals(TargetType.char_)) {
|
||||||
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false);
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unboxPrimitive(State state, TargetType type) {
|
private void unboxPrimitive(State state, TargetType type) {
|
||||||
if (type instanceof TargetExtendsWildcard ew) type = ew.innerType();
|
|
||||||
var mv = state.mv;
|
var mv = state.mv;
|
||||||
if (type.equals(TargetType.Boolean)) {
|
if (type.equals(TargetType.Boolean)) {
|
||||||
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
|
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
|
||||||
@@ -187,11 +183,9 @@ public class Codegen {
|
|||||||
convertTo(state, op.right().type(), type);
|
convertTo(state, op.right().type(), type);
|
||||||
mv.visitJumpInsn(code, if_true);
|
mv.visitJumpInsn(code, if_true);
|
||||||
mv.visitInsn(ICONST_0);
|
mv.visitInsn(ICONST_0);
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
|
||||||
mv.visitJumpInsn(GOTO, end);
|
mv.visitJumpInsn(GOTO, end);
|
||||||
mv.visitLabel(if_true);
|
mv.visitLabel(if_true);
|
||||||
mv.visitInsn(ICONST_1);
|
mv.visitInsn(ICONST_1);
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
|
||||||
mv.visitLabel(end);
|
mv.visitLabel(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,11 +200,9 @@ public class Codegen {
|
|||||||
mv.visitInsn(cmp);
|
mv.visitInsn(cmp);
|
||||||
mv.visitJumpInsn(code, if_true);
|
mv.visitJumpInsn(code, if_true);
|
||||||
mv.visitInsn(ICONST_0);
|
mv.visitInsn(ICONST_0);
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
|
||||||
mv.visitJumpInsn(GOTO, end);
|
mv.visitJumpInsn(GOTO, end);
|
||||||
mv.visitLabel(if_true);
|
mv.visitLabel(if_true);
|
||||||
mv.visitInsn(ICONST_1);
|
mv.visitInsn(ICONST_1);
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
|
||||||
mv.visitLabel(end);
|
mv.visitLabel(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,85 +228,64 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void convertTo(State state, TargetType source, TargetType dest) {
|
private void convertTo(State state, TargetType source, TargetType dest) {
|
||||||
if (source instanceof TargetExtendsWildcard ew) source = ew.innerType();
|
var mv = state.mv;
|
||||||
if (dest instanceof TargetExtendsWildcard ew) dest = ew.innerType();
|
|
||||||
|
|
||||||
if (source.equals(dest))
|
if (source.equals(dest))
|
||||||
return;
|
return;
|
||||||
|
if (source.equals(TargetType.Long)) {
|
||||||
var mv = state.mv;
|
if (dest.equals(TargetType.Integer))
|
||||||
if ((source instanceof TargetRefType || source instanceof TargetGenericType) &&
|
|
||||||
(dest instanceof TargetRefType || dest instanceof TargetGenericType)) {
|
|
||||||
if (dest instanceof TargetGenericType) return;
|
|
||||||
mv.visitTypeInsn(CHECKCAST, dest.getInternalName());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(source instanceof TargetPrimitiveType)) {
|
|
||||||
unboxPrimitive(state, source);
|
|
||||||
source = TargetType.toPrimitive(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
var origDest = dest;
|
|
||||||
dest = TargetType.toPrimitive(dest);
|
|
||||||
if (source.equals(TargetType.long_)) {
|
|
||||||
if (dest.equals(TargetType.int_))
|
|
||||||
mv.visitInsn(L2I);
|
mv.visitInsn(L2I);
|
||||||
else if (dest.equals(TargetType.float_))
|
else if (dest.equals(TargetType.Float))
|
||||||
mv.visitInsn(L2F);
|
mv.visitInsn(L2F);
|
||||||
else if (dest.equals(TargetType.double_))
|
else if (dest.equals(TargetType.Double))
|
||||||
mv.visitInsn(L2D);
|
mv.visitInsn(L2D);
|
||||||
else if (dest.equals(TargetType.byte_) || dest.equals(TargetType.char_) || dest.equals(TargetType.short_)) {
|
else if (dest.equals(TargetType.Byte) || dest.equals(TargetType.Char) || dest.equals(TargetType.Short)) {
|
||||||
mv.visitInsn(L2I);
|
mv.visitInsn(L2I);
|
||||||
convertTo(state, TargetType.int_, dest);
|
convertTo(state, TargetType.Integer, dest);
|
||||||
}
|
}
|
||||||
} else if (source.equals(TargetType.float_)) {
|
} else if (source.equals(TargetType.Float)) {
|
||||||
if (dest.equals(TargetType.int_))
|
if (dest.equals(TargetType.Integer))
|
||||||
mv.visitInsn(F2I);
|
mv.visitInsn(F2I);
|
||||||
else if (dest.equals(TargetType.double_))
|
else if (dest.equals(TargetType.Double))
|
||||||
mv.visitInsn(F2D);
|
mv.visitInsn(F2D);
|
||||||
else if (dest.equals(TargetType.long_))
|
else if (dest.equals(TargetType.Long))
|
||||||
mv.visitInsn(F2L);
|
mv.visitInsn(F2L);
|
||||||
else if (dest.equals(TargetType.byte_) || dest.equals(TargetType.char_) || dest.equals(TargetType.short_)) {
|
else if (dest.equals(TargetType.Byte) || dest.equals(TargetType.Char) || dest.equals(TargetType.Short)) {
|
||||||
mv.visitInsn(F2I);
|
mv.visitInsn(F2I);
|
||||||
convertTo(state, TargetType.int_, dest);
|
convertTo(state, TargetType.Integer, dest);
|
||||||
}
|
}
|
||||||
} else if (source.equals(TargetType.double_)) {
|
} else if (source.equals(TargetType.Double)) {
|
||||||
if (dest.equals(TargetType.int_))
|
if (dest.equals(TargetType.Integer))
|
||||||
mv.visitInsn(D2I);
|
mv.visitInsn(D2I);
|
||||||
else if (dest.equals(TargetType.float_))
|
else if (dest.equals(TargetType.Float))
|
||||||
mv.visitInsn(D2F);
|
mv.visitInsn(D2F);
|
||||||
else if (dest.equals(TargetType.long_))
|
else if (dest.equals(TargetType.Long))
|
||||||
mv.visitInsn(D2L);
|
mv.visitInsn(D2L);
|
||||||
else if (dest.equals(TargetType.byte_) || dest.equals(TargetType.char_) || dest.equals(TargetType.short_)) {
|
else if (dest.equals(TargetType.Byte) || dest.equals(TargetType.Char) || dest.equals(TargetType.Short)) {
|
||||||
mv.visitInsn(D2I);
|
mv.visitInsn(D2I);
|
||||||
convertTo(state, TargetType.int_, dest);
|
convertTo(state, TargetType.Integer, dest);
|
||||||
}
|
}
|
||||||
} else if (source.equals(TargetType.byte_) || source.equals(TargetType.char_) || source.equals(TargetType.short_) || source.equals(TargetType.int_)) {
|
} else if (source.equals(TargetType.Byte) || source.equals(TargetType.Char) || source.equals(TargetType.Short) || source.equals(TargetType.Integer)) {
|
||||||
if (dest.equals(TargetType.byte_))
|
if (dest.equals(TargetType.Byte))
|
||||||
mv.visitInsn(I2B);
|
mv.visitInsn(I2B);
|
||||||
else if (dest.equals(TargetType.char_))
|
else if (dest.equals(TargetType.Char))
|
||||||
mv.visitInsn(I2C);
|
mv.visitInsn(I2C);
|
||||||
else if (dest.equals(TargetType.short_))
|
else if (dest.equals(TargetType.Short))
|
||||||
mv.visitInsn(I2S);
|
mv.visitInsn(I2S);
|
||||||
else if (dest.equals(TargetType.long_))
|
else if (dest.equals(TargetType.Long))
|
||||||
mv.visitInsn(I2L);
|
mv.visitInsn(I2L);
|
||||||
else if (dest.equals(TargetType.float_))
|
else if (dest.equals(TargetType.Float))
|
||||||
mv.visitInsn(I2F);
|
mv.visitInsn(I2F);
|
||||||
else if (dest.equals(TargetType.double_))
|
else if (dest.equals(TargetType.Double))
|
||||||
mv.visitInsn(I2D);
|
mv.visitInsn(I2D);
|
||||||
} else if (source.equals(TargetType.boolean_)) {
|
} else if (source.equals(TargetType.Boolean)) {
|
||||||
unboxPrimitive(state, dest);
|
unboxPrimitive(state, dest);
|
||||||
} else if (isFunctionalInterface(source) && isFunctionalInterface(dest) &&
|
} else if (isFunctionalInterface(source) && isFunctionalInterface(dest) &&
|
||||||
!(source instanceof TargetFunNType && dest instanceof TargetFunNType)) {
|
!(source instanceof TargetFunNType && dest instanceof TargetFunNType)) {
|
||||||
boxFunctionalInterface(state, source, dest);
|
boxFunctionalInterface(state, source, dest);
|
||||||
return;
|
} else if (!(dest instanceof TargetGenericType)) {
|
||||||
}
|
//boxPrimitive(state, source);
|
||||||
|
mv.visitTypeInsn(CHECKCAST, dest.getInternalName());
|
||||||
if (!(origDest instanceof TargetPrimitiveType)) {
|
unboxPrimitive(state, dest);
|
||||||
if (dest instanceof TargetPrimitiveType)
|
|
||||||
boxPrimitive(state, dest);
|
|
||||||
else boxPrimitive(state, source);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,9 +345,9 @@ public class Codegen {
|
|||||||
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false);
|
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false);
|
||||||
} else {
|
} else {
|
||||||
generate(state, add.left());
|
generate(state, add.left());
|
||||||
convertTo(state, add.left().type(), TargetType.toPrimitive(add.type()));
|
convertTo(state, add.left().type(), add.type());
|
||||||
generate(state, add.right());
|
generate(state, add.right());
|
||||||
convertTo(state, add.right().type(), TargetType.toPrimitive(add.type()));
|
convertTo(state, add.right().type(), add.type());
|
||||||
var type = add.type();
|
var type = add.type();
|
||||||
if (type.equals(TargetType.Byte) || type.equals(TargetType.Char) || type.equals(TargetType.Integer) || type.equals(TargetType.Short)) {
|
if (type.equals(TargetType.Byte) || type.equals(TargetType.Char) || type.equals(TargetType.Integer) || type.equals(TargetType.Short)) {
|
||||||
mv.visitInsn(IADD);
|
mv.visitInsn(IADD);
|
||||||
@@ -389,7 +360,6 @@ public class Codegen {
|
|||||||
} else {
|
} else {
|
||||||
throw new CodeGenException("Invalid argument to Add expression, type: " + add.type());
|
throw new CodeGenException("Invalid argument to Add expression, type: " + add.type());
|
||||||
}
|
}
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
|
||||||
}
|
}
|
||||||
if (add.type().equals(TargetType.String)) {
|
if (add.type().equals(TargetType.String)) {
|
||||||
generate(state, add.right());
|
generate(state, add.right());
|
||||||
@@ -401,9 +371,9 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
case Sub sub: {
|
case Sub sub: {
|
||||||
generate(state, sub.left());
|
generate(state, sub.left());
|
||||||
convertTo(state, sub.left().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, sub.left().type(), op.type());
|
||||||
generate(state, sub.right());
|
generate(state, sub.right());
|
||||||
convertTo(state, sub.right().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, sub.right().type(), op.type());
|
||||||
var type = sub.type();
|
var type = sub.type();
|
||||||
if (type.equals(TargetType.Byte) || type.equals(TargetType.Char) || type.equals(TargetType.Integer) || type.equals(TargetType.Short)) {
|
if (type.equals(TargetType.Byte) || type.equals(TargetType.Char) || type.equals(TargetType.Integer) || type.equals(TargetType.Short)) {
|
||||||
mv.visitInsn(ISUB);
|
mv.visitInsn(ISUB);
|
||||||
@@ -416,14 +386,13 @@ public class Codegen {
|
|||||||
} else {
|
} else {
|
||||||
throw new CodeGenException("Invalid argument to Sub expression");
|
throw new CodeGenException("Invalid argument to Sub expression");
|
||||||
}
|
}
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Div div: {
|
case Div div: {
|
||||||
generate(state, div.left());
|
generate(state, div.left());
|
||||||
convertTo(state, div.left().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, div.left().type(), op.type());
|
||||||
generate(state, div.right());
|
generate(state, div.right());
|
||||||
convertTo(state, div.right().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, div.right().type(), op.type());
|
||||||
var type = div.type();
|
var type = div.type();
|
||||||
if (type.equals(TargetType.Byte) || type.equals(TargetType.Char) || type.equals(TargetType.Integer) || type.equals(TargetType.Short)) {
|
if (type.equals(TargetType.Byte) || type.equals(TargetType.Char) || type.equals(TargetType.Integer) || type.equals(TargetType.Short)) {
|
||||||
mv.visitInsn(IDIV);
|
mv.visitInsn(IDIV);
|
||||||
@@ -436,14 +405,13 @@ public class Codegen {
|
|||||||
} else {
|
} else {
|
||||||
throw new CodeGenException("Invalid argument to Div expression");
|
throw new CodeGenException("Invalid argument to Div expression");
|
||||||
}
|
}
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Mul mul: {
|
case Mul mul: {
|
||||||
generate(state, mul.left());
|
generate(state, mul.left());
|
||||||
convertTo(state, mul.left().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, mul.left().type(), op.type());
|
||||||
generate(state, mul.right());
|
generate(state, mul.right());
|
||||||
convertTo(state, mul.right().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, mul.right().type(), op.type());
|
||||||
var type = mul.type();
|
var type = mul.type();
|
||||||
if (type.equals(TargetType.Byte) || type.equals(TargetType.Char) || type.equals(TargetType.Integer) || type.equals(TargetType.Short)) {
|
if (type.equals(TargetType.Byte) || type.equals(TargetType.Char) || type.equals(TargetType.Integer) || type.equals(TargetType.Short)) {
|
||||||
mv.visitInsn(IMUL);
|
mv.visitInsn(IMUL);
|
||||||
@@ -456,14 +424,13 @@ public class Codegen {
|
|||||||
} else {
|
} else {
|
||||||
throw new CodeGenException("Invalid argument to Mul expression");
|
throw new CodeGenException("Invalid argument to Mul expression");
|
||||||
}
|
}
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Rem rem: {
|
case Rem rem: {
|
||||||
generate(state, rem.left());
|
generate(state, rem.left());
|
||||||
convertTo(state, rem.left().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, rem.left().type(), op.type());
|
||||||
generate(state, rem.right());
|
generate(state, rem.right());
|
||||||
convertTo(state, rem.right().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, rem.right().type(), op.type());
|
||||||
var type = rem.type();
|
var type = rem.type();
|
||||||
if (type.equals(TargetType.Byte) || type.equals(TargetType.Char) || type.equals(TargetType.Integer) || type.equals(TargetType.Short)) {
|
if (type.equals(TargetType.Byte) || type.equals(TargetType.Char) || type.equals(TargetType.Integer) || type.equals(TargetType.Short)) {
|
||||||
mv.visitInsn(IREM);
|
mv.visitInsn(IREM);
|
||||||
@@ -476,7 +443,6 @@ public class Codegen {
|
|||||||
} else {
|
} else {
|
||||||
throw new CodeGenException("Invalid argument to Rem expression");
|
throw new CodeGenException("Invalid argument to Rem expression");
|
||||||
}
|
}
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Or or: {
|
case Or or: {
|
||||||
@@ -484,18 +450,14 @@ public class Codegen {
|
|||||||
Label or_true = new Label();
|
Label or_true = new Label();
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
generate(state, or.left());
|
generate(state, or.left());
|
||||||
convertTo(state, or.left().type(), TargetType.toPrimitive(op.type()));
|
|
||||||
mv.visitJumpInsn(IFNE, or_true);
|
mv.visitJumpInsn(IFNE, or_true);
|
||||||
generate(state, or.right());
|
generate(state, or.right());
|
||||||
convertTo(state, or.right().type(), TargetType.toPrimitive(op.type()));
|
|
||||||
mv.visitJumpInsn(IFEQ, or_false);
|
mv.visitJumpInsn(IFEQ, or_false);
|
||||||
mv.visitLabel(or_true);
|
mv.visitLabel(or_true);
|
||||||
mv.visitInsn(ICONST_1);
|
mv.visitInsn(ICONST_1);
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
|
||||||
mv.visitJumpInsn(GOTO, end);
|
mv.visitJumpInsn(GOTO, end);
|
||||||
mv.visitLabel(or_false);
|
mv.visitLabel(or_false);
|
||||||
mv.visitInsn(ICONST_0);
|
mv.visitInsn(ICONST_0);
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
|
||||||
mv.visitLabel(end);
|
mv.visitLabel(end);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -503,54 +465,47 @@ public class Codegen {
|
|||||||
Label and_false = new Label();
|
Label and_false = new Label();
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
generate(state, and.left());
|
generate(state, and.left());
|
||||||
convertTo(state, and.left().type(), TargetType.toPrimitive(op.type()));
|
|
||||||
mv.visitJumpInsn(IFEQ, and_false);
|
mv.visitJumpInsn(IFEQ, and_false);
|
||||||
generate(state, and.right());
|
generate(state, and.right());
|
||||||
convertTo(state, and.right().type(), TargetType.toPrimitive(op.type()));
|
|
||||||
mv.visitJumpInsn(IFEQ, and_false);
|
mv.visitJumpInsn(IFEQ, and_false);
|
||||||
mv.visitInsn(ICONST_1);
|
mv.visitInsn(ICONST_1);
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
|
||||||
mv.visitJumpInsn(GOTO, end);
|
mv.visitJumpInsn(GOTO, end);
|
||||||
mv.visitLabel(and_false);
|
mv.visitLabel(and_false);
|
||||||
mv.visitInsn(ICONST_0);
|
mv.visitInsn(ICONST_0);
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
|
||||||
mv.visitLabel(end);
|
mv.visitLabel(end);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BAnd band: {
|
case BAnd band: {
|
||||||
generate(state, band.left());
|
generate(state, band.left());
|
||||||
convertTo(state, band.left().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, band.left().type(), op.type());
|
||||||
generate(state, band.right());
|
generate(state, band.right());
|
||||||
convertTo(state, band.right().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, band.right().type(), op.type());
|
||||||
if (band.type().equals(TargetType.Long))
|
if (band.type().equals(TargetType.Long))
|
||||||
mv.visitInsn(LAND);
|
mv.visitInsn(LAND);
|
||||||
else
|
else
|
||||||
mv.visitInsn(IAND);
|
mv.visitInsn(IAND);
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BOr bor: {
|
case BOr bor: {
|
||||||
generate(state, bor.left());
|
generate(state, bor.left());
|
||||||
convertTo(state, bor.left().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, bor.left().type(), op.type());
|
||||||
generate(state, bor.right());
|
generate(state, bor.right());
|
||||||
convertTo(state, bor.right().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, bor.right().type(), op.type());
|
||||||
if (bor.type().equals(TargetType.Long))
|
if (bor.type().equals(TargetType.Long))
|
||||||
mv.visitInsn(LOR);
|
mv.visitInsn(LOR);
|
||||||
else
|
else
|
||||||
mv.visitInsn(IOR);
|
mv.visitInsn(IOR);
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case XOr xor: {
|
case XOr xor: {
|
||||||
generate(state, xor.left());
|
generate(state, xor.left());
|
||||||
convertTo(state, xor.left().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, xor.left().type(), op.type());
|
||||||
generate(state, xor.right());
|
generate(state, xor.right());
|
||||||
convertTo(state, xor.right().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, xor.right().type(), op.type());
|
||||||
if (xor.type().equals(TargetType.Long))
|
if (xor.type().equals(TargetType.Long))
|
||||||
mv.visitInsn(LXOR);
|
mv.visitInsn(LXOR);
|
||||||
else
|
else
|
||||||
mv.visitInsn(IXOR);
|
mv.visitInsn(IXOR);
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Instof instof: {
|
case Instof instof: {
|
||||||
@@ -559,47 +514,44 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
case Shl shl: {
|
case Shl shl: {
|
||||||
generate(state, shl.left());
|
generate(state, shl.left());
|
||||||
convertTo(state, shl.left().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, shl.left().type(), op.type());
|
||||||
generate(state, shl.right());
|
generate(state, shl.right());
|
||||||
convertTo(state, shl.right().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, shl.right().type(), op.type());
|
||||||
if (shl.type().equals(TargetType.Long))
|
if (shl.type().equals(TargetType.Long))
|
||||||
mv.visitInsn(LSHL);
|
mv.visitInsn(LSHL);
|
||||||
else
|
else
|
||||||
mv.visitInsn(ISHL);
|
mv.visitInsn(ISHL);
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Shr shr: {
|
case Shr shr: {
|
||||||
generate(state, shr.left());
|
generate(state, shr.left());
|
||||||
convertTo(state, shr.left().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, shr.left().type(), op.type());
|
||||||
generate(state, shr.right());
|
generate(state, shr.right());
|
||||||
convertTo(state, shr.right().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, shr.right().type(), op.type());
|
||||||
if (shr.type().equals(TargetType.Long))
|
if (shr.type().equals(TargetType.Long))
|
||||||
mv.visitInsn(LSHR);
|
mv.visitInsn(LSHR);
|
||||||
else
|
else
|
||||||
mv.visitInsn(ISHR);
|
mv.visitInsn(ISHR);
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UShr ushr: {
|
case UShr ushr: {
|
||||||
generate(state, ushr.left());
|
generate(state, ushr.left());
|
||||||
convertTo(state, ushr.left().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, ushr.left().type(), op.type());
|
||||||
generate(state, ushr.right());
|
generate(state, ushr.right());
|
||||||
convertTo(state, ushr.right().type(), TargetType.toPrimitive(op.type()));
|
convertTo(state, ushr.right().type(), op.type());
|
||||||
if (ushr.type().equals(TargetType.Long))
|
if (ushr.type().equals(TargetType.Long))
|
||||||
mv.visitInsn(LUSHR);
|
mv.visitInsn(LUSHR);
|
||||||
else
|
else
|
||||||
mv.visitInsn(IUSHR);
|
mv.visitInsn(IUSHR);
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Greater greater: {
|
case Greater greater: {
|
||||||
var type = TargetType.toPrimitive(largerType(greater.left().type(), greater.right().type()));
|
var type = largerType(greater.left().type(), greater.right().type());
|
||||||
if (type.equals(TargetType.long_)) {
|
if (type.equals(TargetType.Long)) {
|
||||||
generateRelationalOperator(state, greater, type, LCMP, IFGT);
|
generateRelationalOperator(state, greater, type, LCMP, IFGT);
|
||||||
} else if (type.equals(TargetType.float_)) {
|
} else if (type.equals(TargetType.Float)) {
|
||||||
generateRelationalOperator(state, greater, type, FCMPL, IFGT);
|
generateRelationalOperator(state, greater, type, FCMPL, IFGT);
|
||||||
} else if (type.equals(TargetType.double_)) {
|
} else if (type.equals(TargetType.Double)) {
|
||||||
generateRelationalOperator(state, greater, type, DCMPL, IFGT);
|
generateRelationalOperator(state, greater, type, DCMPL, IFGT);
|
||||||
} else {
|
} else {
|
||||||
generateRelationalOperator(state, greater, type, IF_ICMPGT);
|
generateRelationalOperator(state, greater, type, IF_ICMPGT);
|
||||||
@@ -607,12 +559,12 @@ public class Codegen {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Less less: {
|
case Less less: {
|
||||||
var type = TargetType.toPrimitive(largerType(less.left().type(), less.right().type()));
|
var type = largerType(less.left().type(), less.right().type());
|
||||||
if (type.equals(TargetType.long_)) {
|
if (type.equals(TargetType.Long)) {
|
||||||
generateRelationalOperator(state, less, type, LCMP, IFLT);
|
generateRelationalOperator(state, less, type, LCMP, IFLT);
|
||||||
} else if (type.equals(TargetType.float_)) {
|
} else if (type.equals(TargetType.Float)) {
|
||||||
generateRelationalOperator(state, less, type, FCMPL, IFLT);
|
generateRelationalOperator(state, less, type, FCMPL, IFLT);
|
||||||
} else if (type.equals(TargetType.double_)) {
|
} else if (type.equals(TargetType.Double)) {
|
||||||
generateRelationalOperator(state, less, type, DCMPL, IFLT);
|
generateRelationalOperator(state, less, type, DCMPL, IFLT);
|
||||||
} else {
|
} else {
|
||||||
generateRelationalOperator(state, less, type, IF_ICMPLT);
|
generateRelationalOperator(state, less, type, IF_ICMPLT);
|
||||||
@@ -620,12 +572,12 @@ public class Codegen {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GreaterOrEqual greaterOrEqual: {
|
case GreaterOrEqual greaterOrEqual: {
|
||||||
var type = TargetType.toPrimitive(largerType(greaterOrEqual.left().type(), greaterOrEqual.right().type()));
|
var type = largerType(greaterOrEqual.left().type(), greaterOrEqual.right().type());
|
||||||
if (type.equals(TargetType.long_)) {
|
if (type.equals(TargetType.Long)) {
|
||||||
generateRelationalOperator(state, greaterOrEqual, type, LCMP, IFGE);
|
generateRelationalOperator(state, greaterOrEqual, type, LCMP, IFGE);
|
||||||
} else if (type.equals(TargetType.float_)) {
|
} else if (type.equals(TargetType.Float)) {
|
||||||
generateRelationalOperator(state, greaterOrEqual, type, FCMPL, IFGE);
|
generateRelationalOperator(state, greaterOrEqual, type, FCMPL, IFGE);
|
||||||
} else if (type.equals(TargetType.double_)) {
|
} else if (type.equals(TargetType.Double)) {
|
||||||
generateRelationalOperator(state, greaterOrEqual, type, DCMPL, IFGE);
|
generateRelationalOperator(state, greaterOrEqual, type, DCMPL, IFGE);
|
||||||
} else {
|
} else {
|
||||||
generateRelationalOperator(state, greaterOrEqual, type, IF_ICMPGE);
|
generateRelationalOperator(state, greaterOrEqual, type, IF_ICMPGE);
|
||||||
@@ -633,12 +585,12 @@ public class Codegen {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LessOrEqual lessOrEqual: {
|
case LessOrEqual lessOrEqual: {
|
||||||
var type = TargetType.toPrimitive(largerType(lessOrEqual.left().type(), lessOrEqual.right().type()));
|
var type = largerType(lessOrEqual.left().type(), lessOrEqual.right().type());
|
||||||
if (type.equals(TargetType.long_)) {
|
if (type.equals(TargetType.Long)) {
|
||||||
generateRelationalOperator(state, lessOrEqual, type, LCMP, IFLE);
|
generateRelationalOperator(state, lessOrEqual, type, LCMP, IFLE);
|
||||||
} else if (type.equals(TargetType.float_)) {
|
} else if (type.equals(TargetType.Float)) {
|
||||||
generateRelationalOperator(state, lessOrEqual, type, FCMPL, IFLE);
|
generateRelationalOperator(state, lessOrEqual, type, FCMPL, IFLE);
|
||||||
} else if (type.equals(TargetType.double_)) {
|
} else if (type.equals(TargetType.Double)) {
|
||||||
generateRelationalOperator(state, lessOrEqual, type, DCMPL, IFLE);
|
generateRelationalOperator(state, lessOrEqual, type, DCMPL, IFLE);
|
||||||
} else {
|
} else {
|
||||||
generateRelationalOperator(state, lessOrEqual, type, IF_ICMPLE);
|
generateRelationalOperator(state, lessOrEqual, type, IF_ICMPLE);
|
||||||
@@ -646,30 +598,30 @@ public class Codegen {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Equal equal: {
|
case Equal equal: {
|
||||||
var type = TargetType.toPrimitive(largerType(equal.left().type(), equal.right().type()));
|
var type = largerType(equal.left().type(), equal.right().type());
|
||||||
if (type.equals(TargetType.long_)) {
|
if (type.equals(TargetType.Long)) {
|
||||||
generateRelationalOperator(state, equal, TargetType.long_, LCMP, IFEQ);
|
generateRelationalOperator(state, equal, type, LCMP, IFEQ);
|
||||||
} else if (type.equals(TargetType.float_)) {
|
} else if (type.equals(TargetType.Float)) {
|
||||||
generateRelationalOperator(state, equal, TargetType.float_, FCMPL, IFEQ);
|
generateRelationalOperator(state, equal, type, FCMPL, IFEQ);
|
||||||
} else if (type.equals(TargetType.double_)) {
|
} else if (type.equals(TargetType.Double)) {
|
||||||
generateRelationalOperator(state, equal, TargetType.double_, DCMPL, IFEQ);
|
generateRelationalOperator(state, equal, type, DCMPL, IFEQ);
|
||||||
} else if (type.equals(TargetType.char_) || type.equals(TargetType.short_) || type.equals(TargetType.byte_) || type.equals(TargetType.int_) || type.equals(TargetType.boolean_)) {
|
} else if (type.equals(TargetType.Char) || type.equals(TargetType.Short) || type.equals(TargetType.Byte) || type.equals(TargetType.Integer) || type.equals(TargetType.Boolean)) {
|
||||||
generateRelationalOperator(state, equal, TargetType.int_, IF_ICMPEQ);
|
generateRelationalOperator(state, equal, type, IF_ICMPEQ);
|
||||||
} else {
|
} else {
|
||||||
generateRelationalOperator(state, equal, type, IF_ACMPEQ);
|
generateRelationalOperator(state, equal, type, IF_ACMPEQ);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NotEqual notEqual: {
|
case NotEqual notEqual: {
|
||||||
var type = TargetType.toPrimitive(largerType(notEqual.left().type(), notEqual.right().type()));
|
var type = largerType(notEqual.left().type(), notEqual.right().type());
|
||||||
if (type.equals(TargetType.long_)) {
|
if (type.equals(TargetType.Long)) {
|
||||||
generateRelationalOperator(state, notEqual, TargetType.long_, LCMP, IFNE);
|
generateRelationalOperator(state, notEqual, type, LCMP, IFNE);
|
||||||
} else if (type.equals(TargetType.float_)) {
|
} else if (type.equals(TargetType.Float)) {
|
||||||
generateRelationalOperator(state, notEqual, TargetType.float_, FCMPL, IFNE);
|
generateRelationalOperator(state, notEqual, type, FCMPL, IFNE);
|
||||||
} else if (type.equals(TargetType.double_)) {
|
} else if (type.equals(TargetType.Double)) {
|
||||||
generateRelationalOperator(state, notEqual, TargetType.double_, DCMPL, IFNE);
|
generateRelationalOperator(state, notEqual, type, DCMPL, IFNE);
|
||||||
} else if (type.equals(TargetType.char_) || type.equals(TargetType.short_) || type.equals(TargetType.byte_) || type.equals(TargetType.int_) || type.equals(TargetType.boolean_)) {
|
} else if (type.equals(TargetType.Char) || type.equals(TargetType.Short) || type.equals(TargetType.Byte) || type.equals(TargetType.Integer)) {
|
||||||
generateRelationalOperator(state, notEqual, TargetType.int_, IF_ICMPNE);
|
generateRelationalOperator(state, notEqual, type, IF_ICMPNE);
|
||||||
} else {
|
} else {
|
||||||
generateRelationalOperator(state, notEqual, type, IF_ACMPNE);
|
generateRelationalOperator(state, notEqual, type, IF_ACMPNE);
|
||||||
}
|
}
|
||||||
@@ -688,7 +640,7 @@ public class Codegen {
|
|||||||
} else if (op.expr() instanceof TargetFieldVar fieldVar) {
|
} else if (op.expr() instanceof TargetFieldVar fieldVar) {
|
||||||
generate(state, fieldVar.left());
|
generate(state, fieldVar.left());
|
||||||
mv.visitInsn(SWAP);
|
mv.visitInsn(SWAP);
|
||||||
mv.visitFieldInsn(PUTFIELD, fieldVar.owner().getInternalName(), fieldVar.right(), fieldVar.type().toDescriptor());
|
mv.visitFieldInsn(PUTFIELD, fieldVar.owner().getInternalName(), fieldVar.right(), fieldVar.type().toSignature());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -700,7 +652,6 @@ public class Codegen {
|
|||||||
generate(state, add.expr());
|
generate(state, add.expr());
|
||||||
case TargetUnaryOp.Negate negate -> {
|
case TargetUnaryOp.Negate negate -> {
|
||||||
generate(state, negate.expr());
|
generate(state, negate.expr());
|
||||||
convertTo(state, negate.expr().type(), TargetType.boolean_);
|
|
||||||
if (negate.type().equals(TargetType.Double))
|
if (negate.type().equals(TargetType.Double))
|
||||||
mv.visitInsn(DNEG);
|
mv.visitInsn(DNEG);
|
||||||
else if (negate.type().equals(TargetType.Float))
|
else if (negate.type().equals(TargetType.Float))
|
||||||
@@ -709,11 +660,9 @@ public class Codegen {
|
|||||||
mv.visitInsn(LNEG);
|
mv.visitInsn(LNEG);
|
||||||
else
|
else
|
||||||
mv.visitInsn(INEG);
|
mv.visitInsn(INEG);
|
||||||
boxPrimitive(state, TargetType.boolean_);
|
|
||||||
}
|
}
|
||||||
case TargetUnaryOp.Not not -> {
|
case TargetUnaryOp.Not not -> {
|
||||||
generate(state, not.expr());
|
generate(state, not.expr());
|
||||||
convertTo(state, not.expr().type(), TargetType.boolean_);
|
|
||||||
if (not.type().equals(TargetType.Long)) {
|
if (not.type().equals(TargetType.Long)) {
|
||||||
mv.visitLdcInsn(-1L);
|
mv.visitLdcInsn(-1L);
|
||||||
mv.visitInsn(LXOR);
|
mv.visitInsn(LXOR);
|
||||||
@@ -721,86 +670,93 @@ public class Codegen {
|
|||||||
mv.visitInsn(ICONST_M1);
|
mv.visitInsn(ICONST_M1);
|
||||||
mv.visitInsn(IXOR);
|
mv.visitInsn(IXOR);
|
||||||
}
|
}
|
||||||
boxPrimitive(state, TargetType.boolean_);
|
|
||||||
}
|
}
|
||||||
case TargetUnaryOp.PreIncrement preIncrement -> {
|
case TargetUnaryOp.PreIncrement preIncrement -> {
|
||||||
generate(state, preIncrement.expr());
|
generate(state, preIncrement.expr());
|
||||||
convertTo(state, preIncrement.expr().type(), TargetType.toPrimitive(op.type()));
|
|
||||||
if (preIncrement.type().equals(TargetType.Float)) {
|
if (preIncrement.type().equals(TargetType.Float)) {
|
||||||
mv.visitLdcInsn(1F);
|
mv.visitLdcInsn(1F);
|
||||||
mv.visitInsn(FADD);
|
mv.visitInsn(FADD);
|
||||||
|
mv.visitInsn(DUP);
|
||||||
} else if (preIncrement.type().equals(TargetType.Double)) {
|
} else if (preIncrement.type().equals(TargetType.Double)) {
|
||||||
mv.visitLdcInsn(1D);
|
mv.visitLdcInsn(1D);
|
||||||
mv.visitInsn(DADD);
|
mv.visitInsn(DADD);
|
||||||
|
mv.visitInsn(DUP2);
|
||||||
} else if (preIncrement.type().equals(TargetType.Long)) {
|
} else if (preIncrement.type().equals(TargetType.Long)) {
|
||||||
mv.visitLdcInsn(1L);
|
mv.visitLdcInsn(1L);
|
||||||
mv.visitInsn(LADD);
|
mv.visitInsn(LADD);
|
||||||
|
mv.visitInsn(DUP2);
|
||||||
} else {
|
} else {
|
||||||
mv.visitLdcInsn(1);
|
mv.visitLdcInsn(1);
|
||||||
mv.visitInsn(IADD);
|
mv.visitInsn(IADD);
|
||||||
|
mv.visitInsn(DUP);
|
||||||
}
|
}
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
boxPrimitive(state, preIncrement.type());
|
||||||
mv.visitInsn(DUP);
|
|
||||||
afterIncDec(state, preIncrement);
|
afterIncDec(state, preIncrement);
|
||||||
}
|
}
|
||||||
case TargetUnaryOp.PreDecrement preDecrement -> {
|
case TargetUnaryOp.PreDecrement preDecrement -> {
|
||||||
generate(state, preDecrement.expr());
|
generate(state, preDecrement.expr());
|
||||||
convertTo(state, preDecrement.expr().type(), TargetType.toPrimitive(op.type()));
|
|
||||||
if (preDecrement.type().equals(TargetType.Float)) {
|
if (preDecrement.type().equals(TargetType.Float)) {
|
||||||
mv.visitLdcInsn(1F);
|
mv.visitLdcInsn(1F);
|
||||||
mv.visitInsn(FSUB);
|
mv.visitInsn(FSUB);
|
||||||
|
mv.visitInsn(DUP);
|
||||||
} else if (preDecrement.type().equals(TargetType.Double)) {
|
} else if (preDecrement.type().equals(TargetType.Double)) {
|
||||||
mv.visitLdcInsn(1D);
|
mv.visitLdcInsn(1D);
|
||||||
mv.visitInsn(DSUB);
|
mv.visitInsn(DSUB);
|
||||||
|
mv.visitInsn(DUP2);
|
||||||
} else if (preDecrement.type().equals(TargetType.Long)) {
|
} else if (preDecrement.type().equals(TargetType.Long)) {
|
||||||
mv.visitLdcInsn(1L);
|
mv.visitLdcInsn(1L);
|
||||||
mv.visitInsn(LSUB);
|
mv.visitInsn(LSUB);
|
||||||
|
mv.visitInsn(DUP2);
|
||||||
} else {
|
} else {
|
||||||
mv.visitLdcInsn(1);
|
mv.visitLdcInsn(1);
|
||||||
mv.visitInsn(ISUB);
|
mv.visitInsn(ISUB);
|
||||||
|
mv.visitInsn(DUP);
|
||||||
}
|
}
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
boxPrimitive(state, preDecrement.type());
|
||||||
mv.visitInsn(DUP);
|
|
||||||
afterIncDec(state, preDecrement);
|
afterIncDec(state, preDecrement);
|
||||||
}
|
}
|
||||||
case TargetUnaryOp.PostIncrement postIncrement -> {
|
case TargetUnaryOp.PostIncrement postIncrement -> {
|
||||||
generate(state, postIncrement.expr());
|
generate(state, postIncrement.expr());
|
||||||
mv.visitInsn(DUP);
|
|
||||||
convertTo(state, postIncrement.expr().type(), TargetType.toPrimitive(op.type()));
|
|
||||||
if (postIncrement.type().equals(TargetType.Float)) {
|
if (postIncrement.type().equals(TargetType.Float)) {
|
||||||
|
mv.visitInsn(DUP);
|
||||||
mv.visitLdcInsn(1F);
|
mv.visitLdcInsn(1F);
|
||||||
mv.visitInsn(FADD);
|
mv.visitInsn(FADD);
|
||||||
} else if (postIncrement.type().equals(TargetType.Double)) {
|
} else if (postIncrement.type().equals(TargetType.Double)) {
|
||||||
|
mv.visitInsn(DUP2);
|
||||||
mv.visitLdcInsn(1D);
|
mv.visitLdcInsn(1D);
|
||||||
mv.visitInsn(DADD);
|
mv.visitInsn(DADD);
|
||||||
} else if (postIncrement.type().equals(TargetType.Long)) {
|
} else if (postIncrement.type().equals(TargetType.Long)) {
|
||||||
|
mv.visitInsn(DUP2);
|
||||||
mv.visitLdcInsn(1L);
|
mv.visitLdcInsn(1L);
|
||||||
mv.visitInsn(LADD);
|
mv.visitInsn(LADD);
|
||||||
} else {
|
} else {
|
||||||
|
mv.visitInsn(DUP);
|
||||||
mv.visitLdcInsn(1);
|
mv.visitLdcInsn(1);
|
||||||
mv.visitInsn(IADD);
|
mv.visitInsn(IADD);
|
||||||
}
|
}
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
boxPrimitive(state, postIncrement.type());
|
||||||
afterIncDec(state, postIncrement);
|
afterIncDec(state, postIncrement);
|
||||||
}
|
}
|
||||||
case TargetUnaryOp.PostDecrement postDecrement -> {
|
case TargetUnaryOp.PostDecrement postDecrement -> {
|
||||||
generate(state, postDecrement.expr());
|
generate(state, postDecrement.expr());
|
||||||
mv.visitInsn(DUP);
|
|
||||||
convertTo(state, postDecrement.expr().type(), TargetType.toPrimitive(op.type()));
|
|
||||||
if (postDecrement.type().equals(TargetType.Float)) {
|
if (postDecrement.type().equals(TargetType.Float)) {
|
||||||
|
mv.visitInsn(DUP);
|
||||||
mv.visitLdcInsn(1F);
|
mv.visitLdcInsn(1F);
|
||||||
mv.visitInsn(FSUB);
|
mv.visitInsn(FSUB);
|
||||||
} else if (postDecrement.type().equals(TargetType.Double)) {
|
} else if (postDecrement.type().equals(TargetType.Double)) {
|
||||||
|
mv.visitInsn(DUP2);
|
||||||
mv.visitLdcInsn(1D);
|
mv.visitLdcInsn(1D);
|
||||||
mv.visitInsn(DSUB);
|
mv.visitInsn(DSUB);
|
||||||
} else if (postDecrement.type().equals(TargetType.Long)) {
|
} else if (postDecrement.type().equals(TargetType.Long)) {
|
||||||
|
mv.visitInsn(DUP2);
|
||||||
mv.visitLdcInsn(1L);
|
mv.visitLdcInsn(1L);
|
||||||
mv.visitInsn(LSUB);
|
mv.visitInsn(LSUB);
|
||||||
} else {
|
} else {
|
||||||
|
mv.visitInsn(DUP);
|
||||||
mv.visitLdcInsn(1);
|
mv.visitLdcInsn(1);
|
||||||
mv.visitInsn(ISUB);
|
mv.visitInsn(ISUB);
|
||||||
}
|
}
|
||||||
boxPrimitive(state, TargetType.toPrimitive(op.type()));
|
boxPrimitive(state, postDecrement.type());
|
||||||
afterIncDec(state, postDecrement);
|
afterIncDec(state, postDecrement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -847,7 +803,7 @@ public class Codegen {
|
|||||||
var handle = new Handle(state.isStatic ? H_INVOKESTATIC : H_INVOKEVIRTUAL, clazz.getName(), impl.name(), implSignature.getDescriptor(), false);
|
var handle = new Handle(state.isStatic ? H_INVOKESTATIC : H_INVOKEVIRTUAL, clazz.getName(), impl.name(), implSignature.getDescriptor(), false);
|
||||||
|
|
||||||
var params = new ArrayList<TargetType>();
|
var params = new ArrayList<TargetType>();
|
||||||
if(!state.isStatic) params.add(new TargetRefType(clazz.qualifiedName().toString()));
|
if(!state.isStatic) params.add(new TargetRefType(clazz.qualifiedName().getClassName()));
|
||||||
params.addAll(lambda.captures().stream().map(mp -> mp.pattern().type()).toList());
|
params.addAll(lambda.captures().stream().map(mp -> mp.pattern().type()).toList());
|
||||||
|
|
||||||
if (!state.isStatic)
|
if (!state.isStatic)
|
||||||
@@ -986,7 +942,7 @@ public class Codegen {
|
|||||||
mv.visitInsn(DUP);
|
mv.visitInsn(DUP);
|
||||||
else
|
else
|
||||||
mv.visitInsn(DUP_X1);
|
mv.visitInsn(DUP_X1);
|
||||||
mv.visitFieldInsn(dot.isStatic() ? PUTSTATIC : PUTFIELD, dot.owner().getInternalName(), dot.right(), fieldType.toDescriptor());
|
mv.visitFieldInsn(dot.isStatic() ? PUTSTATIC : PUTFIELD, dot.owner().getInternalName(), dot.right(), fieldType.toSignature());
|
||||||
}
|
}
|
||||||
default -> throw new CodeGenException("Invalid assignment");
|
default -> throw new CodeGenException("Invalid assignment");
|
||||||
}
|
}
|
||||||
@@ -997,14 +953,14 @@ public class Codegen {
|
|||||||
mv.visitVarInsn(ALOAD, local.index());
|
mv.visitVarInsn(ALOAD, local.index());
|
||||||
// This is a bit weird but sometimes the types don't match (see lambda expressions)
|
// This is a bit weird but sometimes the types don't match (see lambda expressions)
|
||||||
convertTo(state, local.type(), localVar.type());
|
convertTo(state, local.type(), localVar.type());
|
||||||
//unboxPrimitive(state, local.type());
|
unboxPrimitive(state, local.type());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TargetFieldVar dot: {
|
case TargetFieldVar dot: {
|
||||||
if (!dot.isStatic())
|
if (!dot.isStatic())
|
||||||
generate(state, dot.left());
|
generate(state, dot.left());
|
||||||
mv.visitFieldInsn(dot.isStatic() ? GETSTATIC : GETFIELD, dot.left().type().getInternalName(), dot.right(), dot.type().toDescriptor());
|
mv.visitFieldInsn(dot.isStatic() ? GETSTATIC : GETFIELD, dot.left().type().getInternalName(), dot.right(), dot.type().toSignature());
|
||||||
//unboxPrimitive(state, dot.type());
|
unboxPrimitive(state, dot.type());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TargetFor _for: {
|
case TargetFor _for: {
|
||||||
@@ -1020,14 +976,11 @@ public class Codegen {
|
|||||||
Label start = new Label();
|
Label start = new Label();
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
mv.visitLabel(start);
|
mv.visitLabel(start);
|
||||||
if (_for.termination() != null) {
|
if (_for.termination() != null)
|
||||||
generate(state, _for.termination());
|
generate(state, _for.termination());
|
||||||
convertTo(state, _for.termination().type(), TargetType.boolean_);
|
else
|
||||||
mv.visitJumpInsn(IFEQ, end);
|
|
||||||
} else {
|
|
||||||
mv.visitInsn(ICONST_1);
|
mv.visitInsn(ICONST_1);
|
||||||
mv.visitJumpInsn(IFEQ, end);
|
mv.visitJumpInsn(IFEQ, end);
|
||||||
}
|
|
||||||
|
|
||||||
var env = new BreakEnv();
|
var env = new BreakEnv();
|
||||||
env.startLabel = start;
|
env.startLabel = start;
|
||||||
@@ -1059,7 +1012,6 @@ public class Codegen {
|
|||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
mv.visitLabel(start);
|
mv.visitLabel(start);
|
||||||
generate(state, _while.cond());
|
generate(state, _while.cond());
|
||||||
convertTo(state, _while.cond().type(), TargetType.boolean_);
|
|
||||||
mv.visitJumpInsn(IFEQ, end);
|
mv.visitJumpInsn(IFEQ, end);
|
||||||
|
|
||||||
var env = new BreakEnv();
|
var env = new BreakEnv();
|
||||||
@@ -1090,7 +1042,6 @@ public class Codegen {
|
|||||||
|
|
||||||
mv.visitLabel(check);
|
mv.visitLabel(check);
|
||||||
generate(state, _do.cond());
|
generate(state, _do.cond());
|
||||||
convertTo(state, _do.cond().type(), TargetType.boolean_);
|
|
||||||
mv.visitJumpInsn(IFEQ, end);
|
mv.visitJumpInsn(IFEQ, end);
|
||||||
mv.visitJumpInsn(GOTO, start);
|
mv.visitJumpInsn(GOTO, start);
|
||||||
mv.visitLabel(end);
|
mv.visitLabel(end);
|
||||||
@@ -1098,7 +1049,6 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
case TargetIf _if: {
|
case TargetIf _if: {
|
||||||
generate(state, _if.cond());
|
generate(state, _if.cond());
|
||||||
convertTo(state, _if.cond().type(), TargetType.boolean_);
|
|
||||||
Label _else = new Label();
|
Label _else = new Label();
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
mv.visitJumpInsn(IFEQ, _else);
|
mv.visitJumpInsn(IFEQ, _else);
|
||||||
@@ -1116,10 +1066,11 @@ public class Codegen {
|
|||||||
if (state.returnType instanceof TargetPrimitiveType) {
|
if (state.returnType instanceof TargetPrimitiveType) {
|
||||||
generate(state, ret.expression());
|
generate(state, ret.expression());
|
||||||
|
|
||||||
convertTo(state, ret.expression().type(), state.returnType);
|
unboxPrimitive(state, state.returnType);
|
||||||
mv.visitInsn(findReturnCode(state.returnType));
|
mv.visitInsn(findReturnCode(state.returnType));
|
||||||
} else {
|
} else {
|
||||||
generate(state, ret.expression());
|
generate(state, ret.expression());
|
||||||
|
boxPrimitive(state, ret.expression().type());
|
||||||
convertTo(state, ret.expression().type(), state.returnType);
|
convertTo(state, ret.expression().type(), state.returnType);
|
||||||
mv.visitInsn(ARETURN);
|
mv.visitInsn(ARETURN);
|
||||||
}
|
}
|
||||||
@@ -1171,6 +1122,8 @@ public class Codegen {
|
|||||||
var arg = call.parameterTypes().get(i);
|
var arg = call.parameterTypes().get(i);
|
||||||
generate(state, e);
|
generate(state, e);
|
||||||
convertTo(state, e.type(), arg);
|
convertTo(state, e.type(), arg);
|
||||||
|
if (!(arg instanceof TargetPrimitiveType))
|
||||||
|
boxPrimitive(state, e.type());
|
||||||
}
|
}
|
||||||
var descriptor = call.getDescriptor();
|
var descriptor = call.getDescriptor();
|
||||||
if (call.owner() instanceof TargetFunNType) // Decay FunN
|
if (call.owner() instanceof TargetFunNType) // Decay FunN
|
||||||
@@ -1183,13 +1136,11 @@ public class Codegen {
|
|||||||
|
|
||||||
mv.visitMethodInsn(insn, call.owner().getInternalName(), call.name(), descriptor, call.isInterface());
|
mv.visitMethodInsn(insn, call.owner().getInternalName(), call.name(), descriptor, call.isInterface());
|
||||||
|
|
||||||
/*if (call.type() != null && call.returnType() != null && !(call.returnType() instanceof TargetPrimitiveType)) {
|
if (call.type() != null && call.returnType() != null && !(call.returnType() instanceof TargetPrimitiveType)) {
|
||||||
if (!call.returnType().equals(call.type()) && !(call.type() instanceof TargetGenericType))
|
if (!call.returnType().equals(call.type()) && !(call.type() instanceof TargetGenericType))
|
||||||
mv.visitTypeInsn(CHECKCAST, call.type().getInternalName());
|
mv.visitTypeInsn(CHECKCAST, call.type().getInternalName());
|
||||||
unboxPrimitive(state, call.type());
|
unboxPrimitive(state, call.type());
|
||||||
}*/
|
}
|
||||||
if (call.type() != null)
|
|
||||||
convertTo(state, call.returnType(), call.type());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TargetLambdaExpression lambda:
|
case TargetLambdaExpression lambda:
|
||||||
@@ -1212,7 +1163,6 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
case TargetTernary ternary: {
|
case TargetTernary ternary: {
|
||||||
generate(state, ternary.cond());
|
generate(state, ternary.cond());
|
||||||
convertTo(state, ternary.cond().type(), TargetType.boolean_);
|
|
||||||
var iffalse = new Label();
|
var iffalse = new Label();
|
||||||
var end = new Label();
|
var end = new Label();
|
||||||
mv.visitJumpInsn(IFEQ, iffalse);
|
mv.visitJumpInsn(IFEQ, iffalse);
|
||||||
@@ -1266,7 +1216,6 @@ public class Codegen {
|
|||||||
if (instanceOf.right() instanceof TargetTypePattern right && right.name() == null) {
|
if (instanceOf.right() instanceof TargetTypePattern right && right.name() == null) {
|
||||||
generate(state, instanceOf.left());
|
generate(state, instanceOf.left());
|
||||||
mv.visitTypeInsn(INSTANCEOF, right.type().getInternalName());
|
mv.visitTypeInsn(INSTANCEOF, right.type().getInternalName());
|
||||||
boxPrimitive(state, TargetType.boolean_);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1461,7 +1410,7 @@ public class Codegen {
|
|||||||
if (aSwitch.isExpression()) {
|
if (aSwitch.isExpression()) {
|
||||||
if (aSwitch.type() != null) {
|
if (aSwitch.type() != null) {
|
||||||
mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
|
mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
|
||||||
//unboxPrimitive(state, aSwitch.type());
|
unboxPrimitive(state, aSwitch.type());
|
||||||
}
|
}
|
||||||
state.popSwitch();
|
state.popSwitch();
|
||||||
}
|
}
|
||||||
@@ -1474,12 +1423,12 @@ public class Codegen {
|
|||||||
throw new CodeGenException("Couldn't find suitable field accessor for '" + type.name() + "'");
|
throw new CodeGenException("Couldn't find suitable field accessor for '" + type.name() + "'");
|
||||||
var field = clazz.getFieldDecl().get(i);
|
var field = clazz.getFieldDecl().get(i);
|
||||||
var fieldType = converter.convert(field.getType());
|
var fieldType = converter.convert(field.getType());
|
||||||
state.mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), field.getName(), "()" + fieldType.toDescriptor(), false);
|
state.mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), field.getName(), "()" + fieldType.toSignature(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindPattern(State state, TargetType type, TargetPattern pat, Label start, int index, int depth) {
|
private void bindPattern(State state, TargetType type, TargetPattern pat, Label start, int index, int depth) {
|
||||||
//if (pat.type() instanceof TargetPrimitiveType)
|
if (pat.type() instanceof TargetPrimitiveType)
|
||||||
// boxPrimitive(state, pat.type());
|
boxPrimitive(state, pat.type());
|
||||||
|
|
||||||
if (pat.type() instanceof TargetRefType) {
|
if (pat.type() instanceof TargetRefType) {
|
||||||
state.mv.visitInsn(DUP);
|
state.mv.visitInsn(DUP);
|
||||||
@@ -1500,14 +1449,13 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pat instanceof TargetExpressionPattern ep) {
|
if (pat instanceof TargetExpressionPattern ep) {
|
||||||
var cur = state.createVariable(TargetType.toWrapper(pat.type()));
|
var cur = state.createVariable(pat.type());
|
||||||
state.mv.visitVarInsn(ASTORE, cur.index);
|
state.mv.visitVarInsn(ASTORE, cur.index);
|
||||||
|
|
||||||
var expr = new Equal(pat.type(), new TargetLocalVar(cur.type, cur.name), ep.expression());
|
var expr = new Equal(pat.type(), new TargetLocalVar(cur.type, cur.name), ep.expression());
|
||||||
generate(state, expr);
|
generate(state, expr);
|
||||||
|
|
||||||
var cont = new Label();
|
var cont = new Label();
|
||||||
unboxPrimitive(state, TargetType.Boolean);
|
|
||||||
state.mv.visitJumpInsn(IFNE, cont);
|
state.mv.visitJumpInsn(IFNE, cont);
|
||||||
for (var i = 0; i < depth - 1; i++) {
|
for (var i = 0; i < depth - 1; i++) {
|
||||||
state.mv.visitInsn(POP);
|
state.mv.visitInsn(POP);
|
||||||
@@ -1580,7 +1528,7 @@ public class Codegen {
|
|||||||
//if ((access & ACC_PRIVATE) == 0 && (access & ACC_PROTECTED) == 0) // TODO Implement access modifiers properly
|
//if ((access & ACC_PRIVATE) == 0 && (access & ACC_PROTECTED) == 0) // TODO Implement access modifiers properly
|
||||||
// access |= ACC_PUBLIC;
|
// access |= ACC_PUBLIC;
|
||||||
|
|
||||||
cw.visitField(access, field.name(), field.type().toDescriptor(), field.type().toSignature(), null);
|
cw.visitField(access, field.name(), field.type().toSignature(), field.type().toDescriptor(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateStaticConstructor(TargetMethod constructor) {
|
private void generateStaticConstructor(TargetMethod constructor) {
|
||||||
@@ -1656,7 +1604,7 @@ public class Codegen {
|
|||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
mv.visitVarInsn(ALOAD, 0);
|
mv.visitVarInsn(ALOAD, 0);
|
||||||
mv.visitMethodInsn(INVOKESTATIC, "java/util/List", "of", "([Ljava/lang/Object;)Ljava/util/List;", true);
|
mv.visitMethodInsn(INVOKESTATIC, "java/util/List", "of", "([Ljava/lang/Object;)Ljava/util/List;", true);
|
||||||
mv.visitMethodInsn(INVOKESTATIC, new TargetRefType(clazz.qualifiedName().toString()).getInternalName(), "main", "(Ljava/util/List;)V", false);
|
mv.visitMethodInsn(INVOKESTATIC, className, "main", "(Ljava/util/List;)V", false);
|
||||||
mv.visitInsn(RETURN);
|
mv.visitInsn(RETURN);
|
||||||
mv.visitMaxs(0, 0);
|
mv.visitMaxs(0, 0);
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
@@ -1703,7 +1651,7 @@ public class Codegen {
|
|||||||
generate(state, method.block());
|
generate(state, method.block());
|
||||||
if (method.signature().returnType() == null)
|
if (method.signature().returnType() == null)
|
||||||
mv.visitInsn(RETURN);
|
mv.visitInsn(RETURN);
|
||||||
mv.visitMaxs(0, 0);
|
mv.visitMaxs(0, 0);
|
||||||
}
|
}
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
@@ -1713,14 +1661,12 @@ public class Codegen {
|
|||||||
if (!generics.isEmpty()) {
|
if (!generics.isEmpty()) {
|
||||||
ret += "<";
|
ret += "<";
|
||||||
for (var generic : generics) {
|
for (var generic : generics) {
|
||||||
ret += generic.name() + ":" + generic.bound().toSignature();
|
ret += generic.name() + ":" + generic.bound().toDescriptor();
|
||||||
}
|
}
|
||||||
ret += ">";
|
ret += ">";
|
||||||
}
|
}
|
||||||
if (clazz.superType() != null)
|
if (clazz.superType() != null)
|
||||||
ret += clazz.superType().toSignature();
|
ret += clazz.superType().toDescriptor();
|
||||||
else ret += "Ljava/lang/Object;";
|
|
||||||
|
|
||||||
for (var intf : clazz.implementingInterfaces()) {
|
for (var intf : clazz.implementingInterfaces()) {
|
||||||
ret += intf.toSignature();
|
ret += intf.toSignature();
|
||||||
}
|
}
|
||||||
@@ -1823,12 +1769,8 @@ public class Codegen {
|
|||||||
} else convertTo(state, fromReturn, toReturn);
|
} else convertTo(state, fromReturn, toReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toReturn != null) {
|
if (toReturn != null)
|
||||||
if ((fromReturn instanceof TargetRefType || fromReturn instanceof TargetGenericType)
|
|
||||||
&& (toReturn instanceof TargetPrimitiveType))
|
|
||||||
unboxPrimitive(state, TargetType.toWrapper(toReturn));
|
|
||||||
mv.visitInsn(findReturnCode(toReturn));
|
mv.visitInsn(findReturnCode(toReturn));
|
||||||
}
|
|
||||||
|
|
||||||
else mv.visitInsn(RETURN);
|
else mv.visitInsn(RETURN);
|
||||||
mv.visitMaxs(0, 0);
|
mv.visitMaxs(0, 0);
|
||||||
@@ -1850,9 +1792,6 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cw.visitEnd();
|
cw.visitEnd();
|
||||||
ClassReader cr = new ClassReader(cw.toByteArray());
|
|
||||||
System.out.println("Checking class " + className);
|
|
||||||
CheckClassAdapter.verify(cr, false, new PrintWriter(System.err));
|
|
||||||
return cw.toByteArray();
|
return cw.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1882,7 +1821,7 @@ public class Codegen {
|
|||||||
bootstrapArgs[1] = String.join(";", clazz.fields().stream().map(TargetField::name).toArray(String[]::new));
|
bootstrapArgs[1] = String.join(";", clazz.fields().stream().map(TargetField::name).toArray(String[]::new));
|
||||||
for (var i = 0; i < clazz.fields().size(); i++) {
|
for (var i = 0; i < clazz.fields().size(); i++) {
|
||||||
var field = clazz.fields().get(i);
|
var field = clazz.fields().get(i);
|
||||||
var fieldRef = new Handle(H_GETFIELD, clazz.getName(), field.name(), field.type().toDescriptor(), false);
|
var fieldRef = new Handle(H_GETFIELD, clazz.getName(), field.name(), field.type().toSignature(), false);
|
||||||
bootstrapArgs[i + 2] = fieldRef;
|
bootstrapArgs[i + 2] = fieldRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -98,7 +98,7 @@ public class FunNGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static String applySignature(TargetType a) { return a.toSignature(); }
|
private static String applySignature(TargetType a) { return a.toSignature(); }
|
||||||
private static String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("%s", a.toDescriptor()); }
|
private static String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("%s", applySignature(a)); }
|
||||||
|
|
||||||
public static String encodeType(TargetType type) {
|
public static String encodeType(TargetType type) {
|
||||||
if (type == null) return VOID;
|
if (type == null) return VOID;
|
||||||
|
@@ -6,6 +6,7 @@ import de.dhbwstuttgart.bytecode.FunNGenerator;
|
|||||||
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
||||||
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
||||||
import de.dhbwstuttgart.exceptions.DebugException;
|
import de.dhbwstuttgart.exceptions.DebugException;
|
||||||
|
import de.dhbwstuttgart.languageServerInterface.model.LanguageServerTransferObject;
|
||||||
import de.dhbwstuttgart.parser.JavaTXParser;
|
import de.dhbwstuttgart.parser.JavaTXParser;
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
||||||
@@ -475,6 +476,85 @@ public class JavaTXCompiler {
|
|||||||
return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList());
|
return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TEMPORARY - Only for Language Server Usage
|
||||||
|
*/
|
||||||
|
public LanguageServerTransferObject getResultSetAndAbstractSyntax(File file) throws IOException, ClassNotFoundException {
|
||||||
|
var sf = sourceFiles.get(file);
|
||||||
|
if(sf == null){
|
||||||
|
sf = sourceFiles.values().stream().findFirst().get();
|
||||||
|
}
|
||||||
|
Set<ClassOrInterface> allClasses = new HashSet<>();
|
||||||
|
allClasses.addAll(getAvailableClasses(sf));
|
||||||
|
allClasses.addAll(sf.getClasses());
|
||||||
|
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), file, this).stream().map(ASTFactory::createClass).collect(Collectors.toSet());
|
||||||
|
for (var clazz : newClasses) {
|
||||||
|
// Don't load classes that get recompiled
|
||||||
|
if (sf.getClasses().stream().anyMatch(nf -> nf.getClassName().equals(clazz.getClassName())))
|
||||||
|
continue;
|
||||||
|
if (allClasses.stream().noneMatch(old -> old.getClassName().equals(clazz.getClassName())))
|
||||||
|
allClasses.add(clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
final ConstraintSet<Pair> cons = getConstraints(file);
|
||||||
|
Set<Set<UnifyPair>> results = new HashSet<>();
|
||||||
|
try {
|
||||||
|
Writer logFile = new OutputStreamWriter(new NullOutputStream());
|
||||||
|
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses.stream().toList(), logFile, classLoader, this);
|
||||||
|
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons);
|
||||||
|
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
|
||||||
|
UnifyType lhs, rhs;
|
||||||
|
if (((lhs = x.getLhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType) && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
|
||||||
|
((PlaceholderType) lhs).setInnerType(true);
|
||||||
|
((PlaceholderType) rhs).setInnerType(true);
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
unifyCons = unifyCons.map(distributeInnerVars);
|
||||||
|
TypeUnify unify = new TypeUnify();
|
||||||
|
Set<PlaceholderType> varianceTPHold;
|
||||||
|
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||||
|
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
||||||
|
|
||||||
|
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints();
|
||||||
|
|
||||||
|
if (resultmodel) {
|
||||||
|
/* UnifyResultModel Anfang */
|
||||||
|
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
|
||||||
|
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
|
||||||
|
urm.addUnifyResultListener(li);
|
||||||
|
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm, usedTasks);
|
||||||
|
generateBytecode(sf, li.getResults());
|
||||||
|
return new LanguageServerTransferObject(li.getResults(), sf, ASTTypePrinter.print(sf), generatedGenerics);
|
||||||
|
}
|
||||||
|
/* UnifyResultModel End */
|
||||||
|
else {
|
||||||
|
Set<Set<UnifyPair>> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons, finiteClosure), usedTasks);
|
||||||
|
results.addAll(result);
|
||||||
|
|
||||||
|
results = results.stream().map(x -> {
|
||||||
|
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> {
|
||||||
|
if (y.getPairOp() == PairOperator.SMALLERDOTWC)
|
||||||
|
y.setPairOp(PairOperator.EQUALSDOT);
|
||||||
|
return y; // alle Paare a <.? b erden durch a =. b ersetzt
|
||||||
|
}).collect(Collectors.toCollection(HashSet::new)));
|
||||||
|
if (res.isPresent()) {// wenn subst ein Erg liefert wurde was veraendert
|
||||||
|
return new TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure);
|
||||||
|
} else
|
||||||
|
return x; // wenn nichts veraendert wurde wird x zurueckgegeben
|
||||||
|
}).collect(Collectors.toCollection(HashSet::new));
|
||||||
|
}
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
}
|
||||||
|
generateBytecode(sf, results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList()));
|
||||||
|
return new LanguageServerTransferObject(results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList()), sf, ASTTypePrinter.print(sf), generatedGenerics);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine Variance !=0 hat auf alle Typvariablen in Theta.
|
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine Variance !=0 hat auf alle Typvariablen in Theta.
|
||||||
*
|
*
|
||||||
|
@@ -0,0 +1,249 @@
|
|||||||
|
package de.dhbwstuttgart.languageServerInterface;
|
||||||
|
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.Codegen;
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
||||||
|
import de.dhbwstuttgart.languageServerInterface.model.LanguageServerTransferObject;
|
||||||
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
||||||
|
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||||
|
import de.dhbwstuttgart.target.generate.GenericsResult;
|
||||||
|
import de.dhbwstuttgart.target.tree.TargetStructure;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.file.DirectoryStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of an Interface for the Language-Server to get the Resultset and abstract Syntax.
|
||||||
|
*/
|
||||||
|
public class LanguageServerInterface {
|
||||||
|
|
||||||
|
|
||||||
|
public LanguageServerTransferObject getResultSetAndAbastractSyntax(String path, String resetNamesTo) throws IOException, URISyntaxException, ClassNotFoundException {
|
||||||
|
NameGenerator.resetTo(resetNamesTo);
|
||||||
|
return getResultSetAndAbstractSyntax(path);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public SourceFile getAst(String path, String resetNamesTo) throws IOException, URISyntaxException, ClassNotFoundException {
|
||||||
|
NameGenerator.resetTo(resetNamesTo);
|
||||||
|
return getAST(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the ResultSets, GenericResultSet and the AST
|
||||||
|
* You have to give the input as well as the path because of potential locks when the File is currently opened in an IDE.
|
||||||
|
* Example: file:///c:/test/main.jav -> file:///c:/test/out/main.class
|
||||||
|
*
|
||||||
|
* @param pathAsString the URI of the File. See Example.
|
||||||
|
* @throws IOException
|
||||||
|
* @throws ClassNotFoundException
|
||||||
|
* @throws URISyntaxException
|
||||||
|
*/
|
||||||
|
public LanguageServerTransferObject getResultSetAndAbstractSyntax(String pathAsString) throws IOException, ClassNotFoundException, URISyntaxException {
|
||||||
|
System.setOut(new PrintStream(OutputStream.nullOutputStream()));
|
||||||
|
|
||||||
|
var uri = new URI(pathAsString);
|
||||||
|
var path = Path.of(uri);
|
||||||
|
var file = path.toFile();
|
||||||
|
Files.createDirectories(path.getParent().resolve("out"));
|
||||||
|
var compiler = new JavaTXCompiler(List.of(file), List.of(path.getParent().toFile()), path.getParent().resolve("out").toFile());
|
||||||
|
|
||||||
|
var parsedSource = compiler.sourceFiles.get(file);
|
||||||
|
var tiResults = compiler.typeInference(file);
|
||||||
|
|
||||||
|
Map<JavaClassName, byte[]> bytecode = compiler.generateBytecode(parsedSource, tiResults);
|
||||||
|
Files.createDirectories(path.getParent().resolve("out"));
|
||||||
|
compiler.writeClassFile(bytecode, path.getParent().resolve("out").toFile(), false);
|
||||||
|
|
||||||
|
return new LanguageServerTransferObject(tiResults, parsedSource, "", compiler.getGeneratedGenerics());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the AST without calculating the result
|
||||||
|
* You have to give the input as well as the path because of potential locks when the File is currently opened in an IDE.
|
||||||
|
* Example: file:///c:/test/main.jav -> file:///c:/test/out/main.class
|
||||||
|
*
|
||||||
|
* @param path the URI of the File. See Example.
|
||||||
|
* @throws IOException
|
||||||
|
* @throws ClassNotFoundException
|
||||||
|
* @throws URISyntaxException
|
||||||
|
*/
|
||||||
|
public SourceFile getAST(String path) throws IOException, ClassNotFoundException, URISyntaxException {
|
||||||
|
|
||||||
|
|
||||||
|
System.setOut(new PrintStream(OutputStream.nullOutputStream()));
|
||||||
|
|
||||||
|
|
||||||
|
URI uri = new URI(path);
|
||||||
|
ArrayList<String> pathWithoutName = new ArrayList<>(List.of(uri.getPath().split("/")));
|
||||||
|
pathWithoutName.remove(List.of(uri.getPath().split("/")).size() - 1);
|
||||||
|
String stringPathWithoutName = "";
|
||||||
|
|
||||||
|
for (String i : pathWithoutName) {
|
||||||
|
stringPathWithoutName += "/" + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
FileUtils.cleanDirectory(new File(stringPathWithoutName + "/out"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
(new File(stringPathWithoutName + "/out")).mkdirs();
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
var test = getAST(uri.getPath().split("/")[uri.getPath().split("/").length - 1], new File(stringPathWithoutName).getPath());
|
||||||
|
System.setOut(System.out);
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void writeClassFile(String name, byte[] code, Path outputPath) throws IOException {
|
||||||
|
Files.createDirectories(outputPath);
|
||||||
|
Files.write(outputPath.resolve(name + ".class"), code);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, ? extends Class<?>> generateClassFiles(IByteArrayClassLoader classLoader, Path path, Path outputPath, String... files) throws IOException, ClassNotFoundException {
|
||||||
|
Files.createDirectories(outputPath);
|
||||||
|
var filenames = Arrays.stream(files).map(filename -> Path.of(path.toString(), filename).toFile()).toList();
|
||||||
|
var compiler = new JavaTXCompiler(filenames, List.of(path.toFile(), outputPath.toFile()), outputPath.toFile());
|
||||||
|
|
||||||
|
var result = new HashMap<String, Class<?>>();
|
||||||
|
for (var file : filenames) {
|
||||||
|
var resultSet = compiler.typeInference(file);
|
||||||
|
|
||||||
|
var sourceFile = compiler.sourceFiles.get(file);
|
||||||
|
var converter = new ASTToTargetAST(compiler, resultSet, sourceFile, classLoader);
|
||||||
|
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||||
|
|
||||||
|
result.putAll(classes.stream().map(cli -> {
|
||||||
|
try {
|
||||||
|
return generateClass(converter.convert(cli), classLoader, converter, outputPath);
|
||||||
|
} catch (IOException exception) {
|
||||||
|
throw new RuntimeException(exception);
|
||||||
|
}
|
||||||
|
}).collect(Collectors.toMap(Class::getName, Function.identity())));
|
||||||
|
|
||||||
|
converter.generateFunNTypes();
|
||||||
|
|
||||||
|
for (var entry : converter.auxiliaries.entrySet()) {
|
||||||
|
writeClassFile(entry.getKey(), entry.getValue(), outputPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entry : compiler.loadedClasses.entrySet()) {
|
||||||
|
var name = entry.getKey().toString();
|
||||||
|
result.put(name, classLoader.loadClass(Path.of(entry.getValue().classFile().toURI())));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Class<?> generateClass(TargetStructure clazz, IByteArrayClassLoader classLoader, ASTToTargetAST converter, Path outputPath) throws IOException {
|
||||||
|
Codegen codegen = new Codegen(clazz, converter.compiler, converter);
|
||||||
|
var code = codegen.generate();
|
||||||
|
writeClassFile(clazz.qualifiedName().getClassName(), code, outputPath);
|
||||||
|
return classLoader.loadClass(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, ? extends Class<?>> generateClassFiles(String filename, IByteArrayClassLoader classLoader, String filePath) throws IOException, ClassNotFoundException {
|
||||||
|
var file = Path.of(filePath, filename).toFile();
|
||||||
|
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()), Path.of(filePath + "/out").toFile());
|
||||||
|
var resultSet = compiler.typeInference(file);
|
||||||
|
|
||||||
|
var sourceFile = compiler.sourceFiles.get(file);
|
||||||
|
var converter = new ASTToTargetAST(compiler, resultSet, sourceFile, classLoader);
|
||||||
|
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||||
|
|
||||||
|
var result = classes.stream().map(cli -> {
|
||||||
|
try {
|
||||||
|
return generateClass(converter.convert(cli), classLoader, converter, Path.of(filePath + "/out/"));
|
||||||
|
} catch (IOException exception) {
|
||||||
|
throw new RuntimeException(exception);
|
||||||
|
}
|
||||||
|
}).collect(Collectors.toMap(Class::getName, Function.identity()));
|
||||||
|
|
||||||
|
converter.generateFunNTypes();
|
||||||
|
|
||||||
|
for (var entry : converter.auxiliaries.entrySet()) {
|
||||||
|
writeClassFile(entry.getKey(), entry.getValue(), Path.of(filePath + "/out/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SourceFile getAST(String filename, String filePath) throws IOException, ClassNotFoundException {
|
||||||
|
var file = Path.of(filePath, filename).toFile();
|
||||||
|
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()), Path.of(filePath + "/out").toFile());
|
||||||
|
return compiler.sourceFiles.get(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LanguageServerTransferObject getLanguageServerTransferObject(String filename, IByteArrayClassLoader classLoader, String filePath) throws IOException, ClassNotFoundException {
|
||||||
|
var file = Path.of(filePath, filename).toFile();
|
||||||
|
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()), Path.of(filePath + "/out").toFile());
|
||||||
|
var resultSet = compiler.typeInference(file);
|
||||||
|
|
||||||
|
var sourceFile = compiler.sourceFiles.get(file);
|
||||||
|
var converter = new ASTToTargetAST(compiler, resultSet, sourceFile, classLoader);
|
||||||
|
compiler.generateBytecode();
|
||||||
|
converter.generateFunNTypes();
|
||||||
|
|
||||||
|
var ta = converter.javaGenerics();
|
||||||
|
var tb = converter.txGenerics();
|
||||||
|
Map<SourceFile, List<GenericsResult>> generics = new HashMap<>();
|
||||||
|
|
||||||
|
ArrayList<GenericsResult> genericsResults = new ArrayList<>();
|
||||||
|
genericsResults.addAll(ta);
|
||||||
|
genericsResults.addAll(tb);
|
||||||
|
generics.put(converter.compiler.sourceFiles.values().stream().findFirst().get(), ta);
|
||||||
|
var test = new LanguageServerTransferObject(resultSet, converter.compiler.sourceFiles.values().stream().findFirst().get(), "", compiler.getGeneratedGenerics());
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generates Bytecode for the given Path of the File.
|
||||||
|
* The Generated Bytecode can be found in the same place as the path, except the File lies in an /out/ Directory
|
||||||
|
* Example: file:///c:/test/main.jav -> file:///c:/test/out/main.class
|
||||||
|
*
|
||||||
|
* @param uri the URI of the File. See Example.
|
||||||
|
* @throws IOException
|
||||||
|
* @throws ClassNotFoundException
|
||||||
|
* @throws URISyntaxException
|
||||||
|
*/
|
||||||
|
public void generateBytecode(URI uri) throws IOException, ClassNotFoundException, URISyntaxException {
|
||||||
|
|
||||||
|
// System.setOut(new PrintStream(OutputStream.nullOutputStream()));
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// File inputDir = new File(uri.getPath());
|
||||||
|
// File outFile = new File(uri.getPath() + "/out");
|
||||||
|
// FileUtils.cleanDirectory(outFile);
|
||||||
|
// String[] allowedEndings = {".jav"};
|
||||||
|
// ArrayList<File> files = new ArrayList<>();
|
||||||
|
//
|
||||||
|
// try (Stream<Path> stream = Files.walk(Paths.get(inputDir.toURI()))) {
|
||||||
|
// stream.filter(Files::isRegularFile)
|
||||||
|
// .forEach(el -> files.add(el.toFile()));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// List<String> javFiles = files.stream().filter(el -> el.getName().split("\\.").length >= 2 && el.getName().split("\\.")[el.getName().split("\\.").length - 1].contains("jav")).map(el -> el.getPath().replace(inputDir.getPath(), "").substring(1)).toList();
|
||||||
|
// //TODO: Link between Files
|
||||||
|
// generateClassFiles(new ByteArrayClassLoader(), Path.of(inputDir.toURI()), Path.of(outFile.toURI()), javFiles.toArray(new String[0]));
|
||||||
|
// System.setOut(System.out);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,40 @@
|
|||||||
|
package de.dhbwstuttgart.languageServerInterface;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.languageServerInterface.model.CustomParserErrorHandler;
|
||||||
|
import de.dhbwstuttgart.languageServerInterface.model.ParserError;
|
||||||
|
import de.dhbwstuttgart.parser.antlr.Java17Lexer;
|
||||||
|
import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
||||||
|
import de.dhbwstuttgart.parser.antlr.Java17ParserBaseListener;
|
||||||
|
import org.antlr.v4.runtime.CharStream;
|
||||||
|
import org.antlr.v4.runtime.CharStreams;
|
||||||
|
import org.antlr.v4.runtime.CommonTokenStream;
|
||||||
|
import org.antlr.v4.runtime.tree.ParseTree;
|
||||||
|
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ParserInterface {
|
||||||
|
|
||||||
|
public List<ParserError> getParseErrors(String input){
|
||||||
|
|
||||||
|
CustomParserErrorHandler errorListener = new CustomParserErrorHandler();
|
||||||
|
CharStream charStream = CharStreams.fromString(input);
|
||||||
|
|
||||||
|
Java17Lexer lexer = new Java17Lexer(charStream);
|
||||||
|
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||||
|
|
||||||
|
Java17Parser parser = new Java17Parser(tokens);
|
||||||
|
parser.removeErrorListeners();
|
||||||
|
parser.addErrorListener(errorListener);
|
||||||
|
|
||||||
|
|
||||||
|
ParseTree tree = parser.sourceFile();
|
||||||
|
ParseTreeWalker walker = new ParseTreeWalker();
|
||||||
|
Java17ParserBaseListener listener = new Java17ParserBaseListener();
|
||||||
|
walker.walk(listener, tree);
|
||||||
|
|
||||||
|
return errorListener.getErrorMessages();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,47 @@
|
|||||||
|
package de.dhbwstuttgart.languageServerInterface.model;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import org.antlr.v4.runtime.*;
|
||||||
|
import org.antlr.v4.runtime.atn.ATNConfigSet;
|
||||||
|
import org.antlr.v4.runtime.dfa.DFA;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.BitSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CustomParserErrorHandler implements ANTLRErrorListener {
|
||||||
|
private final List<ParserError> errorMessages = new ArrayList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
|
||||||
|
int endCharPosition = charPositionInLine;
|
||||||
|
if (offendingSymbol instanceof Token) {
|
||||||
|
Token offendingToken = (Token) offendingSymbol;
|
||||||
|
endCharPosition = charPositionInLine + offendingToken.getText().length();
|
||||||
|
}
|
||||||
|
|
||||||
|
ParserError parserError = new ParserError(line, charPositionInLine, endCharPosition, msg);
|
||||||
|
errorMessages.add(parserError);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportAmbiguity(Parser parser, DFA dfa, int i, int i1, boolean b, BitSet bitSet, ATNConfigSet atnConfigSet) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportAttemptingFullContext(Parser parser, DFA dfa, int i, int i1, BitSet bitSet, ATNConfigSet atnConfigSet) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportContextSensitivity(Parser parser, DFA dfa, int i, int i1, int i2, ATNConfigSet atnConfigSet) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ParserError> getErrorMessages() {
|
||||||
|
return errorMessages;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,31 @@
|
|||||||
|
package de.dhbwstuttgart.languageServerInterface.model;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||||
|
import de.dhbwstuttgart.target.generate.GenericsResult;
|
||||||
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class LanguageServerTransferObject {
|
||||||
|
List<ResultSet> resultSets;
|
||||||
|
SourceFile Ast;
|
||||||
|
String printedAst;
|
||||||
|
Map<SourceFile, List<GenericsResult>> generatedGenerics = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
public LanguageServerTransferObject(List<ResultSet> resultSets, SourceFile Ast, String printedAst, Map<SourceFile, List<GenericsResult>> generatedGenerics) {
|
||||||
|
this.resultSets = resultSets;
|
||||||
|
this.Ast = Ast;
|
||||||
|
this.printedAst = printedAst;
|
||||||
|
this.generatedGenerics = generatedGenerics;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ResultSet> getResultSets() {return resultSets;}
|
||||||
|
public SourceFile getAst() {return Ast;}
|
||||||
|
public String getPrintedAst() {return printedAst;}
|
||||||
|
public Map<SourceFile, List<GenericsResult>> getGeneratedGenerics() {return generatedGenerics;}
|
||||||
|
}
|
@@ -0,0 +1,48 @@
|
|||||||
|
package de.dhbwstuttgart.languageServerInterface.model;
|
||||||
|
|
||||||
|
public class ParserError {
|
||||||
|
|
||||||
|
private int line;
|
||||||
|
private int charPositionInLine;
|
||||||
|
private int endCharPosition;
|
||||||
|
String msg;
|
||||||
|
|
||||||
|
public ParserError(int line, int charPositionInLine, int endCharPosition, String msg) {
|
||||||
|
this.line = line;
|
||||||
|
this.charPositionInLine = charPositionInLine;
|
||||||
|
this. endCharPosition = endCharPosition;
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEndCharPosition() {
|
||||||
|
return endCharPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEndCharPosition(int endCharPosition) {
|
||||||
|
this.endCharPosition = endCharPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCharPositionInLine(int charPositionInLine) {
|
||||||
|
this.charPositionInLine = charPositionInLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLine(int line) {
|
||||||
|
this.line = line;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMsg(String msg) {
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCharPositionInLine() {
|
||||||
|
return charPositionInLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLine() {
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMsg() {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,20 @@
|
|||||||
|
package de.dhbwstuttgart.languageServerInterface.model;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.common.reflect.TypeResolver;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyResultEvent;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyResultListener;
|
||||||
|
|
||||||
|
public class ResultSetListener implements UnifyResultListener {
|
||||||
|
|
||||||
|
TypeResolver typeResolver;
|
||||||
|
|
||||||
|
public ResultSetListener(TypeResolver typeResolver){
|
||||||
|
this.typeResolver = typeResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNewTypeResultFound(UnifyResultEvent evt) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -111,7 +111,7 @@ public class SyntaxTreeGenerator {
|
|||||||
this.allmodifiers.put(Modifier.toString(Modifier.INTERFACE), Modifier.INTERFACE);
|
this.allmodifiers.put(Modifier.toString(Modifier.INTERFACE), Modifier.INTERFACE);
|
||||||
this.allmodifiers.put("sealed", 4096);
|
this.allmodifiers.put("sealed", 4096);
|
||||||
this.allmodifiers.put("non-sealed", 8192);
|
this.allmodifiers.put("non-sealed", 8192);
|
||||||
this.allmodifiers.put("default", 0); // Doesn't exist
|
this.allmodifiers.put("default", 16384);
|
||||||
this.allmodifiers.put("strictfp", 32768);
|
this.allmodifiers.put("strictfp", 32768);
|
||||||
|
|
||||||
this.compiler = compiler;
|
this.compiler = compiler;
|
||||||
|
@@ -13,6 +13,10 @@ public class NameGenerator {
|
|||||||
public static void reset() {
|
public static void reset() {
|
||||||
strNextName = "A";
|
strNextName = "A";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void resetTo(String name) {
|
||||||
|
strNextName = name;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Berechnet einen neuen, eindeutigen Namen f�r eine neue
|
* Berechnet einen neuen, eindeutigen Namen f�r eine neue
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
package de.dhbwstuttgart.target.generate;
|
package de.dhbwstuttgart.target.generate;
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
||||||
|
@@ -161,6 +161,7 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(FieldVar fieldVar) {
|
public void visit(FieldVar fieldVar) {
|
||||||
|
var isStatic = false;
|
||||||
var type = converter.convert(fieldVar.receiver.getType());
|
var type = converter.convert(fieldVar.receiver.getType());
|
||||||
var clazz = converter.compiler.getClass(new JavaClassName(type.name()));
|
var clazz = converter.compiler.getClass(new JavaClassName(type.name()));
|
||||||
var field = clazz.getField(fieldVar.fieldVarName).orElseThrow();
|
var field = clazz.getField(fieldVar.fieldVarName).orElseThrow();
|
||||||
|
@@ -36,30 +36,30 @@ public record TargetMethod(int access, String name, TargetBlock block, Signature
|
|||||||
public static String getDescriptor(TargetType returnType, TargetType... parameters) {
|
public static String getDescriptor(TargetType returnType, TargetType... parameters) {
|
||||||
String ret = "(";
|
String ret = "(";
|
||||||
for (var parameterType : parameters) {
|
for (var parameterType : parameters) {
|
||||||
ret += parameterType.toDescriptor();
|
ret += parameterType.toSignature();
|
||||||
}
|
}
|
||||||
ret += ")";
|
ret += ")";
|
||||||
if (returnType == null) ret += "V";
|
if (returnType == null) ret += "V";
|
||||||
else ret += returnType.toDescriptor();
|
else ret += returnType.toSignature();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getSignature(Set<TargetGeneric> generics, List<MethodParameter> parameters, TargetType returnType) {
|
public static String getSignature(Set<TargetGeneric> generics, List<MethodParameter> parameters, TargetType returnType) {
|
||||||
String ret = "";
|
String ret = "";
|
||||||
if (!generics.isEmpty()) {
|
if (generics.size() > 0) {
|
||||||
ret += "<";
|
ret += "<";
|
||||||
for (var generic : generics) {
|
for (var generic : generics) {
|
||||||
ret += generic.name() + ":" + generic.bound().toSignature();
|
ret += generic.name() + ":" + generic.bound().toDescriptor();
|
||||||
}
|
}
|
||||||
ret += ">";
|
ret += ">";
|
||||||
}
|
}
|
||||||
ret += "(";
|
ret += "(";
|
||||||
for (var param : parameters) {
|
for (var param : parameters) {
|
||||||
ret += param.pattern().type().toSignature();
|
ret += param.pattern().type().toDescriptor();
|
||||||
}
|
}
|
||||||
ret += ")";
|
ret += ")";
|
||||||
if (returnType == null) ret += "V";
|
if (returnType == null) ret += "V";
|
||||||
else ret += returnType.toSignature();
|
else ret += returnType.toDescriptor();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,42 +8,42 @@ public sealed interface TargetLiteral extends TargetExpression {
|
|||||||
record BooleanLiteral(Boolean value) implements TargetLiteral {
|
record BooleanLiteral(Boolean value) implements TargetLiteral {
|
||||||
@Override
|
@Override
|
||||||
public TargetType type() {
|
public TargetType type() {
|
||||||
return TargetType.boolean_;
|
return TargetType.Boolean;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
record CharLiteral(Character value) implements TargetLiteral {
|
record CharLiteral(Character value) implements TargetLiteral {
|
||||||
@Override
|
@Override
|
||||||
public TargetType type() {
|
public TargetType type() {
|
||||||
return TargetType.char_;
|
return TargetType.Char;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
record IntLiteral(Integer value) implements TargetLiteral {
|
record IntLiteral(Integer value) implements TargetLiteral {
|
||||||
@Override
|
@Override
|
||||||
public TargetType type() {
|
public TargetType type() {
|
||||||
return TargetType.int_;
|
return TargetType.Integer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
record LongLiteral(Long value) implements TargetLiteral {
|
record LongLiteral(Long value) implements TargetLiteral {
|
||||||
@Override
|
@Override
|
||||||
public TargetType type() {
|
public TargetType type() {
|
||||||
return TargetType.long_;
|
return TargetType.Long;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
record FloatLiteral(Float value) implements TargetLiteral {
|
record FloatLiteral(Float value) implements TargetLiteral {
|
||||||
@Override
|
@Override
|
||||||
public TargetType type() {
|
public TargetType type() {
|
||||||
return TargetType.float_;
|
return TargetType.Float;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
record DoubleLiteral(Double value) implements TargetLiteral {
|
record DoubleLiteral(Double value) implements TargetLiteral {
|
||||||
@Override
|
@Override
|
||||||
public TargetType type() {
|
public TargetType type() {
|
||||||
return TargetType.double_;
|
return TargetType.Double;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,12 +3,12 @@ package de.dhbwstuttgart.target.tree.type;
|
|||||||
public record TargetExtendsWildcard(TargetType innerType) implements TargetType {
|
public record TargetExtendsWildcard(TargetType innerType) implements TargetType {
|
||||||
@Override
|
@Override
|
||||||
public String toSignature() {
|
public String toSignature() {
|
||||||
return "+" + innerType.toSignature();
|
return innerType.toSignature();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toDescriptor() {
|
public String toDescriptor() {
|
||||||
return innerType.toDescriptor();
|
return "+" + innerType.toDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -36,7 +36,6 @@ public record TargetFunNType(String name, List<TargetType> funNParams, List<Targ
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toSignature() {
|
public String toSignature() {
|
||||||
var args = FunNGenerator.getArguments(params);
|
return "L" + getInternalName() + ";";
|
||||||
return "LFun" + args.size() + "$$" + TargetSpecializedType.signatureParameters(params) + ";";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,12 +2,12 @@ package de.dhbwstuttgart.target.tree.type;
|
|||||||
|
|
||||||
public record TargetGenericType(String name) implements TargetType {
|
public record TargetGenericType(String name) implements TargetType {
|
||||||
@Override
|
@Override
|
||||||
public String toDescriptor() {
|
public String toSignature() {
|
||||||
return "Ljava/lang/Object;"; // TODO Use bounds for this?
|
return "Ljava/lang/Object;"; // TODO Use bounds for this?
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toSignature() {
|
public String toDescriptor() {
|
||||||
return "T" + getInternalName() + ";";
|
return "T" + getInternalName() + ";";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -12,6 +12,11 @@ public record TargetRefType(String name, List<TargetType> params) implements Tar
|
|||||||
return this.name.replaceAll("\\.", "/");
|
return this.name.replaceAll("\\.", "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toSignature() {
|
||||||
|
return "L" + getInternalName() + ";";
|
||||||
|
}
|
||||||
|
|
||||||
// Type erasure means we need to override hashCode and equals to only consider the name
|
// Type erasure means we need to override hashCode and equals to only consider the name
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
|
@@ -6,27 +6,16 @@ public sealed interface TargetSpecializedType extends TargetType permits TargetF
|
|||||||
List<TargetType> params();
|
List<TargetType> params();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default String toSignature() {
|
default String toDescriptor() {
|
||||||
String ret = "L" + getInternalName();
|
String ret = "L" + getInternalName();
|
||||||
ret += signatureParameters(params());
|
if (params().size() > 0) {
|
||||||
ret += ";";
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static String signatureParameters(List<TargetType> params) {
|
|
||||||
var ret = "";
|
|
||||||
if (!params.isEmpty()) {
|
|
||||||
ret += "<";
|
ret += "<";
|
||||||
for (var param : params) {
|
for (var param : params()) {
|
||||||
ret += param.toSignature();
|
ret += param.toDescriptor();
|
||||||
}
|
}
|
||||||
ret += ">";
|
ret += ">";
|
||||||
}
|
}
|
||||||
|
ret += ";";
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
default String toDescriptor() {
|
|
||||||
return "L" + getInternalName() + ";";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -3,12 +3,12 @@ package de.dhbwstuttgart.target.tree.type;
|
|||||||
public record TargetSuperWildcard(TargetType innerType) implements TargetType {
|
public record TargetSuperWildcard(TargetType innerType) implements TargetType {
|
||||||
@Override
|
@Override
|
||||||
public String toSignature() {
|
public String toSignature() {
|
||||||
return "-" + innerType.toSignature();
|
return innerType.toSignature();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toDescriptor() {
|
public String toDescriptor() {
|
||||||
return innerType.toDescriptor();
|
return "-" + innerType.toDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -1476,21 +1476,4 @@ public class TestComplete {
|
|||||||
var m = clazz.getDeclaredMethod("main");
|
var m = clazz.getDeclaredMethod("main");
|
||||||
m.invoke(null);
|
m.invoke(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Disabled("Doesn't work yet")
|
|
||||||
@Test
|
|
||||||
public void testBug378() throws Exception {
|
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "Bug378Main.jav");
|
|
||||||
var clazz = classFiles.get("Bug378Main");
|
|
||||||
var main = clazz.getDeclaredMethod("main", List.class);
|
|
||||||
main.setAccessible(true);
|
|
||||||
main.invoke(null, List.of());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBug379() throws Exception {
|
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "Bug379.jav");
|
|
||||||
var clazz = classFiles.get("Bug379");
|
|
||||||
clazz.getDeclaredConstructor().newInstance();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,51 @@
|
|||||||
|
package languageServerInterfaceTest;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.ConsoleInterface;
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import de.dhbwstuttgart.languageServerInterface.LanguageServerInterface;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
public class LangaugeServerInterfaceTest {
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void consoleInterfaceTest() throws IOException, ClassNotFoundException, URISyntaxException {
|
||||||
|
|
||||||
|
|
||||||
|
LanguageServerInterface languageServerInterface = new LanguageServerInterface();
|
||||||
|
var resp = languageServerInterface.getResultSetAndAbstractSyntax("/home/ruben/code/JavaCompilerCore/src/test/java/languageServerInterfaceTest/test.jav");
|
||||||
|
|
||||||
|
System.out.println("\n-----------------------------------------\n");
|
||||||
|
System.out.println(ASTPrinter.print(resp.getAst()));
|
||||||
|
System.out.println("\n-----------------------------------------\n");
|
||||||
|
|
||||||
|
LanguageServerInterface languageServerInterface2 = new LanguageServerInterface();
|
||||||
|
var ast = languageServerInterface2.getAst("/home/ruben/code/JavaCompilerCore/src/test/java/languageServerInterfaceTest/test.jav", "N");
|
||||||
|
|
||||||
|
System.out.println("\n-----------------------------------------\n");
|
||||||
|
System.out.println(ASTPrinter.print(ast));
|
||||||
|
System.out.println("\n-----------------------------------------\n");
|
||||||
|
System.out.println("");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testBytecodeGen() throws IOException, ClassNotFoundException, URISyntaxException {
|
||||||
|
|
||||||
|
//TODO: Ordner und Datei löschen wenn sie bereits existieren
|
||||||
|
LanguageServerInterface languageServerInterface = new LanguageServerInterface();
|
||||||
|
languageServerInterface.generateBytecode(new URI("c%3A/Users/ruben/Neuer%20Ordner%20%282%29/LSP-Vortrag/images/"));
|
||||||
|
}
|
||||||
|
}
|
5
src/test/java/languageServerInterfaceTest/test.jav
Normal file
5
src/test/java/languageServerInterfaceTest/test.jav
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
public class t{
|
||||||
|
public mofus(){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user