forked from JavaTX/JavaCompilerCore
Add user defined generics to methods
This commit is contained in:
parent
229c6c523d
commit
7aa7f94110
@ -1,3 +1,6 @@
|
||||
import java.lang.String;
|
||||
import java.lang.Integer;
|
||||
|
||||
class Generics2<B extends String>{
|
||||
<B extends Integer> B m1(B b){
|
||||
return b;
|
||||
|
@ -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<TargetGeneric> convert(GenericTypeVar typeVar) {
|
||||
var ret = new ArrayList<TargetGeneric>();
|
||||
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<TargetGeneric> 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<TargetGeneric> collectMethodGenerics(Set<ResultPair<?, ?>> 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<TargetConstructor> convert(Constructor input, TargetBlock fieldInitializer) {
|
||||
sigma = all.get(0);
|
||||
List<TargetConstructor> result = new ArrayList<>();
|
||||
@ -640,7 +679,8 @@ public class ASTToTargetAST {
|
||||
var generics = sigma.generics(currentClass, input);
|
||||
List<MethodParameter> 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<MethodParameter> 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)
|
||||
));
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -226,7 +226,6 @@ public class TestGenerics {
|
||||
@Ignore("This doesn't work properly")
|
||||
public void testThreeArgs() throws Exception {
|
||||
var result = computeGenerics("TestThreeArgs.jav");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
Reference in New Issue
Block a user