Compare commits
16 Commits
newConstra
...
targetByte
Author | SHA1 | Date | |
---|---|---|---|
9801f8a5ae | |||
f0b9bea23e | |||
ce4347dd96 | |||
7785c2d0aa | |||
a654f55deb | |||
|
7037bdf9ef | ||
|
d9860497df | ||
|
fdffc11580 | ||
|
c10de35ca2 | ||
|
56b73332c0 | ||
|
bdcd5ea3cf | ||
|
4dba867f9e | ||
|
06caf0ff66 | ||
|
5d03995f10 | ||
|
1bc58573c7 | ||
|
3d2b935c60 |
4
pom.xml
4
pom.xml
@ -54,8 +54,8 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
|||||||
<version>3.11.0</version>
|
<version>3.11.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<compilerArgs>--enable-preview</compilerArgs>
|
<compilerArgs>--enable-preview</compilerArgs>
|
||||||
<source>22</source>
|
<source>21</source>
|
||||||
<target>22</target>
|
<target>21</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
10
resources/AllgemeinTest/Bar.java
Normal file
10
resources/AllgemeinTest/Bar.java
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
public class Bar{
|
||||||
|
|
||||||
|
void visit(Object o){
|
||||||
|
System.out.println("Object");
|
||||||
|
}
|
||||||
|
|
||||||
|
void visit(Bla f){
|
||||||
|
System.out.println("Foo");
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,9 @@
|
|||||||
class Box<A> {
|
public class Box<A> {
|
||||||
|
|
||||||
A a;
|
A a;
|
||||||
|
|
||||||
|
public Box() { }
|
||||||
public Box(A a) {
|
public Box(A a) {
|
||||||
this.a = a;
|
//this.a = a;
|
||||||
}
|
}
|
||||||
}
|
}
|
6
resources/AllgemeinTest/Foo.jav
Normal file
6
resources/AllgemeinTest/Foo.jav
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
public class Foo{
|
||||||
|
|
||||||
|
public accept(Bar b){
|
||||||
|
b.visit(this);
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +0,0 @@
|
|||||||
class Box<A> {
|
|
||||||
void m(A a) { }
|
|
||||||
}
|
|
2
resources/bytecode/javFiles/Bug343.jav
Normal file
2
resources/bytecode/javFiles/Bug343.jav
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
public record Bug343() {
|
||||||
|
}
|
@ -2,41 +2,21 @@ import java.lang.Integer;
|
|||||||
|
|
||||||
public class Y {
|
public class Y {
|
||||||
y;
|
y;
|
||||||
//factorial;
|
|
||||||
|
|
||||||
public Y() {
|
public Y() {
|
||||||
y = f -> t -> f.apply(y.apply(f)).apply(t);
|
y = f -> t -> f.apply(y.apply(f)).apply(t);
|
||||||
//factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
getY() {
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
class fac1 {
|
|
||||||
factorial;
|
|
||||||
|
|
||||||
fac1() {
|
|
||||||
var y;
|
|
||||||
y = new Y<Integer,Integer,Integer,Integer,Integer>().getY();
|
|
||||||
factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ergibt Parse-Error
|
public class Fac1 {
|
||||||
class fac1 {
|
public factorial;
|
||||||
factorial;
|
public Fac1() {
|
||||||
|
|
||||||
fac1() {
|
|
||||||
var y;
|
var y;
|
||||||
y = new Y<>().y;
|
var tmp = new Y<>(); // TODO Having new Y<>().y on one line doesn't work, see FIXME in StatementGenerator
|
||||||
|
y = tmp.y;
|
||||||
factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
|
factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
|
||||||
}
|
}
|
||||||
public static void main(String args[]) {
|
|
||||||
System.out.println(new fac1().factorial.apply(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public fac(v) {
|
||||||
|
return factorial.apply(v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
@ -1,11 +1,13 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
package de.dhbwstuttgart.bytecode;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.Break;
|
||||||
import de.dhbwstuttgart.target.tree.TargetGeneric;
|
import de.dhbwstuttgart.target.tree.TargetGeneric;
|
||||||
import de.dhbwstuttgart.target.tree.type.*;
|
import de.dhbwstuttgart.target.tree.type.*;
|
||||||
import org.objectweb.asm.ClassWriter;
|
import org.objectweb.asm.ClassWriter;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import java.sql.Array;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@ -35,19 +37,33 @@ public class FunNGenerator {
|
|||||||
public List<TargetType> parameters = new ArrayList<>();
|
public List<TargetType> parameters = new ArrayList<>();
|
||||||
final String descriptor;
|
final String descriptor;
|
||||||
public final List<TargetType> inParams;
|
public final List<TargetType> inParams;
|
||||||
|
public final List<TargetType> realParams;
|
||||||
|
|
||||||
public GenericParameters(List<TargetType> params, int numReturns) {
|
public GenericParameters(List<TargetType> params, int numReturns) {
|
||||||
this.inParams = params;
|
this.realParams = params;
|
||||||
|
this.inParams = flattenTypeParams(params);
|
||||||
var type = new TargetRefType(FunNGenerator.getSuperClassName(params.size() - 1, numReturns), params);
|
var type = new TargetRefType(FunNGenerator.getSuperClassName(params.size() - 1, numReturns), params);
|
||||||
descriptor = applyDescriptor(type, this);
|
descriptor = applyDescriptor(type, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<TargetType> flattenTypeParams(List<TargetType> params) {
|
||||||
|
var res = new ArrayList<TargetType>();
|
||||||
|
for (var param : params) {
|
||||||
|
if (param instanceof TargetSpecializedType tspec) {
|
||||||
|
res.addAll(flattenTypeParams(tspec.params()));
|
||||||
|
} else {
|
||||||
|
res.add(param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
public TargetType getReturnType() {
|
public TargetType getReturnType() {
|
||||||
return FunNGenerator.getReturnType(inParams);
|
return FunNGenerator.getReturnType(realParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TargetType> getArguments() {
|
public List<TargetType> getArguments() {
|
||||||
return FunNGenerator.getArguments(inParams);
|
return FunNGenerator.getArguments(realParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +178,7 @@ public class FunNGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String getSpecializedClassName(GenericParameters gep) {
|
public static String getSpecializedClassName(GenericParameters gep) {
|
||||||
return getSpecializedClassName(getArguments(gep.inParams), getReturnType(gep.inParams));
|
return getSpecializedClassName(gep.getArguments(), gep.getReturnType());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getSpecializedClassName(List<TargetType> argumentTypes, TargetType returnType) {
|
public static String getSpecializedClassName(List<TargetType> argumentTypes, TargetType returnType) {
|
||||||
|
@ -66,7 +66,7 @@ public class JavaTXCompiler {
|
|||||||
Boolean resultmodel = true;
|
Boolean resultmodel = true;
|
||||||
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
||||||
|
|
||||||
Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll?
|
Boolean log = false; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll?
|
||||||
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
||||||
public final DirectoryClassLoader classLoader;
|
public final DirectoryClassLoader classLoader;
|
||||||
|
|
||||||
|
@ -158,7 +158,8 @@ public class FCGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus.
|
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus auf der direkten Argumentebene.
|
||||||
|
* Hier sind keine Wildcards zulässig
|
||||||
*/
|
*/
|
||||||
private static class TypeExchanger implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric>{
|
private static class TypeExchanger implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric>{
|
||||||
|
|
||||||
@ -172,7 +173,7 @@ public class FCGenerator {
|
|||||||
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
|
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
|
||||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||||
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){
|
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){
|
||||||
params.add(param.acceptTV(this));
|
params.add(param.acceptTV(new TypeExchangerInner(gtvs)));
|
||||||
}
|
}
|
||||||
RefTypeOrTPHOrWildcardOrGeneric ret = new RefType(refType.getName(), params, new NullToken());
|
RefTypeOrTPHOrWildcardOrGeneric ret = new RefType(refType.getName(), params, new NullToken());
|
||||||
return ret;
|
return ret;
|
||||||
@ -201,4 +202,51 @@ public class FCGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus auf den Argumenten der Argumente.
|
||||||
|
* Hier sind Wildcards zulässig
|
||||||
|
*/
|
||||||
|
private static class TypeExchangerInner implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric>{
|
||||||
|
|
||||||
|
private final HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs;
|
||||||
|
|
||||||
|
TypeExchangerInner(HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs){
|
||||||
|
this.gtvs = gtvs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
|
||||||
|
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||||
|
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){
|
||||||
|
params.add(param.acceptTV(this));
|
||||||
|
}
|
||||||
|
RefTypeOrTPHOrWildcardOrGeneric ret = new RefType(refType.getName(), params, new NullToken());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RefTypeOrTPHOrWildcardOrGeneric visit(SuperWildcardType superWildcardType) {
|
||||||
|
return superWildcardType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RefTypeOrTPHOrWildcardOrGeneric visit(TypePlaceholder typePlaceholder) {
|
||||||
|
throw new DebugException("Dieser Fall darf nicht auftreten");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RefTypeOrTPHOrWildcardOrGeneric visit(ExtendsWildcardType extendsWildcardType) {
|
||||||
|
return extendsWildcardType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) {
|
||||||
|
if(! gtvs.containsKey(genericRefType.getParsedName()))
|
||||||
|
throw new DebugException("Dieser Fall darf nicht auftreten");
|
||||||
|
return gtvs.get(genericRefType.getParsedName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -697,6 +697,7 @@ public class StatementGenerator {
|
|||||||
if (!Objects.isNull(expr.methodCall())) {
|
if (!Objects.isNull(expr.methodCall())) {
|
||||||
return convert(expr.methodCall(), expr.expression(), offset);
|
return convert(expr.methodCall(), expr.expression(), offset);
|
||||||
} else if (!Objects.isNull(expr.identifier())) {
|
} else if (!Objects.isNull(expr.identifier())) {
|
||||||
|
// FIXME This is not the right way of handling any of this
|
||||||
return generateLocalOrFieldVarOrClassName(expr.getText(), offset);
|
return generateLocalOrFieldVarOrClassName(expr.getText(), offset);
|
||||||
} else {
|
} else {
|
||||||
// Für alle anderen Optionen, wie Feldzugriff, Aufrufe von super oder explizite
|
// Für alle anderen Optionen, wie Feldzugriff, Aufrufe von super oder explizite
|
||||||
@ -779,6 +780,7 @@ public class StatementGenerator {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private Expression generateLocalOrFieldVarOrClassName(String expression, Token offset) {
|
private Expression generateLocalOrFieldVarOrClassName(String expression, Token offset) {
|
||||||
|
// FIXME Why does this take a String argument???
|
||||||
String[] parts = expression.split("\\.");
|
String[] parts = expression.split("\\.");
|
||||||
if (parts.length < 2) {
|
if (parts.length < 2) {
|
||||||
// Check for localVar:
|
// Check for localVar:
|
||||||
|
@ -254,7 +254,10 @@ public class SyntaxTreeGenerator {
|
|||||||
List<RefType> implementedInterfaces = new ArrayList<>();
|
List<RefType> implementedInterfaces = new ArrayList<>();
|
||||||
List<Pattern> constructorParameters = new ArrayList<>();
|
List<Pattern> constructorParameters = new ArrayList<>();
|
||||||
List<Statement> constructorStatements = new ArrayList<>();
|
List<Statement> constructorStatements = new ArrayList<>();
|
||||||
for (RecordComponentContext component : recordDeclaration.recordHeader().recordComponentList().recordComponent()) {
|
|
||||||
|
List<Java17Parser.RecordComponentContext> components = recordDeclaration.recordHeader().recordComponentList() != null ?
|
||||||
|
recordDeclaration.recordHeader().recordComponentList().recordComponent(): List.of();
|
||||||
|
for (RecordComponentContext component : components) {
|
||||||
int fieldmodifiers = allmodifiers.get("private") + allmodifiers.get("final");
|
int fieldmodifiers = allmodifiers.get("private") + allmodifiers.get("final");
|
||||||
String fieldname = component.identifier().getText();
|
String fieldname = component.identifier().getText();
|
||||||
Token fieldoffset = component.getStart();
|
Token fieldoffset = component.getStart();
|
||||||
|
@ -188,9 +188,8 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
|||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (!(o instanceof ClassOrInterface other)) return false;
|
||||||
ClassOrInterface that = (ClassOrInterface) o;
|
return Objects.equals(name, other.name);
|
||||||
return Objects.equals(name, that.name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -34,6 +34,7 @@ public class ASTFactory {
|
|||||||
private static final HashMap<java.lang.Class, ClassOrInterface> cache = new HashMap<>();
|
private static final HashMap<java.lang.Class, ClassOrInterface> cache = new HashMap<>();
|
||||||
|
|
||||||
public static ClassOrInterface createClass(java.lang.Class jreClass) {
|
public static ClassOrInterface createClass(java.lang.Class jreClass) {
|
||||||
|
System.out.println(jreClass);
|
||||||
if (cache.containsKey(jreClass))
|
if (cache.containsKey(jreClass))
|
||||||
return cache.get(jreClass);
|
return cache.get(jreClass);
|
||||||
|
|
||||||
@ -173,6 +174,7 @@ public class ASTFactory {
|
|||||||
superClass = (RefType) createType(java.lang.Object.class);
|
superClass = (RefType) createType(java.lang.Object.class);
|
||||||
}
|
}
|
||||||
List<RefType> implementedInterfaces = new ArrayList<>();
|
List<RefType> implementedInterfaces = new ArrayList<>();
|
||||||
|
System.out.println(jreClass);
|
||||||
for (Type jreInterface : jreClass.getGenericInterfaces()) {
|
for (Type jreInterface : jreClass.getGenericInterfaces()) {
|
||||||
implementedInterfaces.add((RefType) createType(jreInterface));
|
implementedInterfaces.add((RefType) createType(jreInterface));
|
||||||
}
|
}
|
||||||
|
@ -652,14 +652,12 @@ public abstract class GenerateGenerics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void normalize(Set<Pair> result, Set<Pair> classGenerics, Set<TPH> usedTphs) {
|
void normalize(Set<Pair> result, Set<Pair> classGenerics, Set<TPH> usedTphs) {
|
||||||
outer:
|
for (var p1 : new HashSet<>(result)) {
|
||||||
for (var tph : usedTphs) {
|
if (p1 instanceof PairLT ptph && ptph.left.resolve().equals(ptph.right.resolve()))
|
||||||
for (var p1 : new HashSet<>(result)) {
|
result.remove(p1); // TODO This is a bit strange
|
||||||
if (p1 instanceof PairLT ptph && ptph.left.equals(ptph.right))
|
}
|
||||||
result.remove(p1); // TODO This is a bit strange
|
|
||||||
if (p1.left.equals(tph)) continue outer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
for (var tph : usedTphs) {
|
||||||
if (classGenerics == null || classGenerics.stream().noneMatch((pair) -> pair.left.equals(tph)))
|
if (classGenerics == null || classGenerics.stream().noneMatch((pair) -> pair.left.equals(tph)))
|
||||||
addToPairs(result, new PairEQ(tph, ASTToTargetAST.OBJECT));
|
addToPairs(result, new PairEQ(tph, ASTToTargetAST.OBJECT));
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,9 @@ public class AllgemeinTest {
|
|||||||
//String className = "WildcardList";
|
//String className = "WildcardList";
|
||||||
//String className = "List";
|
//String className = "List";
|
||||||
//String className = "Box";
|
//String className = "Box";
|
||||||
String className = "GenBox";
|
//String className = "GenBox";
|
||||||
|
//String className = "InnerInf";
|
||||||
|
String className = "Foo";
|
||||||
//PL 2019-10-24: genutzt fuer unterschiedliche Tests
|
//PL 2019-10-24: genutzt fuer unterschiedliche Tests
|
||||||
path = System.getProperty("user.dir")+"/resources/AllgemeinTest/" + className + ".jav";
|
path = System.getProperty("user.dir")+"/resources/AllgemeinTest/" + className + ".jav";
|
||||||
//path = System.getProperty("user.dir")+"/src/test/resources/AllgemeinTest/Overloading_Generics.jav";
|
//path = System.getProperty("user.dir")+"/src/test/resources/AllgemeinTest/Overloading_Generics.jav";
|
||||||
|
@ -602,7 +602,11 @@ public class TestComplete {
|
|||||||
@Test
|
@Test
|
||||||
public void yTest() throws Exception {
|
public void yTest() throws Exception {
|
||||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Y.jav");
|
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Y.jav");
|
||||||
var instance = classFiles.get("Y").getDeclaredConstructor().newInstance();
|
|
||||||
|
var fac1 = classFiles.get("Fac1");
|
||||||
|
var instance = fac1.getDeclaredConstructor().newInstance();
|
||||||
|
var fac = fac1.getDeclaredMethod("fac", Integer.class);
|
||||||
|
assertEquals(fac.invoke(instance, 10), 3628800);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -1147,4 +1151,11 @@ public class TestComplete {
|
|||||||
var clazz = classFiles.get("Bug338");
|
var clazz = classFiles.get("Bug338");
|
||||||
var instance = clazz.getDeclaredConstructor().newInstance();
|
var instance = clazz.getDeclaredConstructor().newInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBug343() throws Exception {
|
||||||
|
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug343.jav");
|
||||||
|
var clazz = classFiles.get("Bug343");
|
||||||
|
var instance = clazz.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user