diff --git a/pom.xml b/pom.xml
index 78e5bf45..3236c59c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,10 +17,11 @@ http://maven.apache.org/maven-v4_0_0.xsd">
4.11
test
+
org.antlr
antlr4
- 4.8-1
+ 4.11.1
commons-io
@@ -53,12 +54,14 @@ http://maven.apache.org/maven-v4_0_0.xsd">
3.8.0
--enable-preview
-
+
+ 19
+
org.antlr
antlr4-maven-plugin
- 4.8-1
+ 4.11.1
antlr
diff --git a/resources/bytecode/javFiles/Generics2.jav b/resources/bytecode/javFiles/Generics2.jav
index 52d5caa2..762890bd 100644
--- a/resources/bytecode/javFiles/Generics2.jav
+++ b/resources/bytecode/javFiles/Generics2.jav
@@ -1,3 +1,6 @@
+import java.lang.String;
+import java.lang.Integer;
+
class Generics2{
B m1(B b){
return b;
diff --git a/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java b/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java
index b2e9048f..a1359be4 100644
--- a/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java
+++ b/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java
@@ -17,7 +17,11 @@ import de.dhbwstuttgart.typeinference.result.*;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+/**
+ * @author dholle
+ */
public class ASTToTargetAST {
public static RefType OBJECT = ASTFactory.createObjectType(); // TODO It would be better if I could call this directly but the hashcode seems to change
@@ -608,16 +612,37 @@ public class ASTToTargetAST {
}).collect(Collectors.toSet());
}
+ public List convert(GenericTypeVar typeVar) {
+ var ret = new ArrayList();
+ for (var bound : typeVar.getBounds()) {
+ ret.add(new TargetGeneric(typeVar.getName(), convert(bound)));
+ }
+ return ret;
+ }
+
public TargetClass convert(ClassOrInterface input) {
currentClass = input;
- var generics = sigma.generics(input);
+ Set generics = new HashSet<>();
+ var genericsIter = input.getGenerics().iterator();
+ if (genericsIter.hasNext()) {
+ // Add empty set of generics to cache so that it doesn't try to calculate it later
+ sigma.computedGenericsOfClasses.put(input, new HashSet<>());
+ while (genericsIter.hasNext()) {
+ var next = genericsIter.next();
+ generics.addAll(convert(next));
+ }
+ } else {
+ // Generate generics only if there are no user defined ones
+ generics = convert(sigma.generics(input));
+ }
+
TargetBlock fieldInitializer = null;
if (input.getfieldInitializations().isPresent())
fieldInitializer = convert(input.getfieldInitializations().get().block);
TargetBlock finalFieldInitializer = fieldInitializer;
return new TargetClass(input.getModifiers(), input.getClassName().toString(), convert(input.getSuperClass()),
- convert(generics),
+ generics,
input.getSuperInterfaces().stream().map(this::convert).toList(),
input.getConstructors().stream().map(constructor -> this.convert(constructor, finalFieldInitializer)).flatMap(List::stream).toList(),
input.getFieldDecl().stream().map(this::convert).toList(),
@@ -630,6 +655,20 @@ public class ASTToTargetAST {
.map(param -> new MethodParameter(convert(param.getType()), param.getName())).toList();
}
+ private Set collectMethodGenerics(Set> generics, Method input) {
+ var convertedGenerics = new HashSet<>(convert(generics));
+ outer:
+ for (GenericTypeVar typeVar : input.getGenerics()) {
+ for (var classGeneric : currentClass.getGenerics()) {
+ if (classGeneric.equals(typeVar)) {
+ continue outer;
+ }
+ }
+ convertedGenerics.addAll(convert(typeVar));
+ }
+ return convertedGenerics;
+ }
+
private List convert(Constructor input, TargetBlock fieldInitializer) {
sigma = all.get(0);
List result = new ArrayList<>();
@@ -640,7 +679,8 @@ public class ASTToTargetAST {
var generics = sigma.generics(currentClass, input);
List params = convert(input.getParameterList());
if (parameterSet.stream().noneMatch(p -> p.equals(params))) {
- result.add(new TargetConstructor(input.modifier, convert(generics), params, convert(input.block), fieldInitializer));
+ var convertedGenerics = collectMethodGenerics(generics, input);
+ result.add(new TargetConstructor(input.modifier, convertedGenerics, params, convert(input.block), fieldInitializer));
parameterSet.add(params);
}
}
@@ -658,9 +698,10 @@ public class ASTToTargetAST {
var generics = sigma.generics(currentClass, input);
List params = convert(input.getParameterList());
if (parameterSet.stream().noneMatch(p -> p.equals(params))) {
+ var convertedGenerics = collectMethodGenerics(generics, input);
result.add(new TargetMethod(
input.modifier,
- input.name, convert(generics), params,
+ input.name, convertedGenerics, params,
convert(input.getReturnType()),
convert(input.block)
));
diff --git a/src/test/java/targetast/ASTToTypedTargetAST.java b/src/test/java/targetast/ASTToTypedTargetAST.java
index a8994318..fd75bd11 100644
--- a/src/test/java/targetast/ASTToTypedTargetAST.java
+++ b/src/test/java/targetast/ASTToTypedTargetAST.java
@@ -33,7 +33,7 @@ public class ASTToTypedTargetAST {
@Test
public void overloading() throws Exception {
- var file = Path.of(System.getProperty("user.dir"), "/src/test/resources/bytecode/javFiles/Overloading.jav").toFile();
+ var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Overloading.jav").toFile();
var compiler = new JavaTXCompiler(file);
var resultSet = compiler.typeInference();
var converter = new ASTToTargetAST(resultSet);
@@ -55,7 +55,7 @@ public class ASTToTypedTargetAST {
@Test
public void tphsAndGenerics() throws Exception {
- var file = Path.of(System.getProperty("user.dir"), "/src/test/resources/bytecode/javFiles/Tph2.jav").toFile();
+ var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Tph2.jav").toFile();
var compiler = new JavaTXCompiler(file);
var resultSet = compiler.typeInference();
var converter = new ASTToTargetAST(resultSet);
@@ -66,7 +66,7 @@ public class ASTToTypedTargetAST {
@Test
public void cycles() throws Exception {
- var file = Path.of(System.getProperty("user.dir"), "/src/test/resources/bytecode/javFiles/Cycle.jav").toFile();
+ var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Cycle.jav").toFile();
var compiler = new JavaTXCompiler(file);
var resultSet = compiler.typeInference();
var converter = new ASTToTargetAST(resultSet);
@@ -77,7 +77,7 @@ public class ASTToTypedTargetAST {
@Test
public void infimum() throws Exception {
- var file = Path.of(System.getProperty("user.dir"), "/src/test/resources/bytecode/javFiles/Infimum.jav").toFile();
+ var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Infimum.jav").toFile();
var compiler = new JavaTXCompiler(file);
var resultSet = compiler.typeInference();
var converter = new ASTToTargetAST(resultSet);
@@ -85,4 +85,26 @@ public class ASTToTypedTargetAST {
var infimum = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
}
+
+ @Test
+ public void definedGenerics() throws Exception {
+ var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Generics.jav").toFile();
+ var compiler = new JavaTXCompiler(file);
+ var resultSet = compiler.typeInference();
+ var converter = new ASTToTargetAST(resultSet);
+ var classes = compiler.sourceFiles.get(file).getClasses();
+
+ var generics = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
+ }
+
+ @Test
+ public void definedGenerics2() throws Exception {
+ var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Generics2.jav").toFile();
+ var compiler = new JavaTXCompiler(file);
+ var resultSet = compiler.typeInference();
+ var converter = new ASTToTargetAST(resultSet);
+ var classes = compiler.sourceFiles.get(file).getClasses();
+
+ var generics2 = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
+ }
}
diff --git a/src/test/java/targetast/TestCodegen.java b/src/test/java/targetast/TestCodegen.java
index 8bc767b8..104ff7d0 100644
--- a/src/test/java/targetast/TestCodegen.java
+++ b/src/test/java/targetast/TestCodegen.java
@@ -42,7 +42,7 @@ public class TestCodegen {
}
public static Map> generateClassFiles(String filename, IByteArrayClassLoader classLoader) throws IOException, ClassNotFoundException {
- var file = Path.of(System.getProperty("user.dir"), "/src/test/resources/bytecode/javFiles/", filename).toFile();
+ var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/", filename).toFile();
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()));
var resultSet = compiler.typeInference();
var sourceFile = compiler.sourceFiles.get(file);
diff --git a/src/test/java/targetast/TestGenerics.java b/src/test/java/targetast/TestGenerics.java
index 4e80d3f2..d3b45ca3 100644
--- a/src/test/java/targetast/TestGenerics.java
+++ b/src/test/java/targetast/TestGenerics.java
@@ -22,7 +22,7 @@ import java.util.List;
public class TestGenerics {
- private static final String rootDirectory = System.getProperty("user.dir") + "/src/test/resources/insertGenericsJav/";
+ private static final String rootDirectory = System.getProperty("user.dir") + "/resources/insertGenericsJav/";
private static final String bytecodeDirectory = System.getProperty("user.dir") + "/src/test/resources/testBytecode/generatedBC/";
private record Result(List genericsResults, ClassOrInterface clazz) {
@@ -226,7 +226,6 @@ public class TestGenerics {
@Ignore("This doesn't work properly")
public void testThreeArgs() throws Exception {
var result = computeGenerics("TestThreeArgs.jav");
-
}
@Test