forked from JavaTX/JavaCompilerCore
First implementation for overloaded functions and test case
This commit is contained in:
parent
0a1a596bb9
commit
29112e7bd7
@ -809,7 +809,7 @@ public class Codegen {
|
||||
|
||||
public byte[] generate() {
|
||||
cw.visit(V1_8, clazz.modifiers(), clazz.qualifiedName(),
|
||||
null, clazz.superType().getName(),
|
||||
null, clazz.superType() != null ? clazz.superType().getName(): "java/lang/Object",
|
||||
clazz.implementingInterfaces().stream().map(TargetType::toSignature).toArray(String[]::new)
|
||||
);
|
||||
clazz.fields().forEach(this::generateField);
|
||||
|
@ -1,58 +1,113 @@
|
||||
package de.dhbwstuttgart.target.generate;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.Field;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Block;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
import de.dhbwstuttgart.target.tree.*;
|
||||
import de.dhbwstuttgart.target.tree.expression.TargetBlock;
|
||||
import de.dhbwstuttgart.target.tree.expression.TargetExpression;
|
||||
import de.dhbwstuttgart.target.tree.type.*;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import de.dhbwstuttgart.typeinference.result.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ASTToTargetAST {
|
||||
|
||||
protected List<HashMap<TypePlaceholder, TargetType>> all;
|
||||
protected HashMap<TypePlaceholder, TargetType> sigma;
|
||||
|
||||
public ASTToTargetAST(ResultSet resultSet) {
|
||||
private class ResultPairV implements ResultPairVisitor {
|
||||
@Override
|
||||
public void visit(PairTPHsmallerTPH p) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(PairTPHequalRefTypeOrWildcardType p) {
|
||||
sigma.put(p.left, convert(p.right));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(PairTPHEqualTPH p) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public ASTToTargetAST(List<ResultSet> resultSets) {
|
||||
all = new ArrayList<>();
|
||||
|
||||
for (var set : resultSets) {
|
||||
this.sigma = new HashMap<>();
|
||||
for (var pair : set.results) {
|
||||
var visitor = new ResultPairV();
|
||||
pair.accept(visitor);
|
||||
}
|
||||
all.add(this.sigma);
|
||||
}
|
||||
|
||||
this.sigma = all.get(0);
|
||||
}
|
||||
|
||||
public TargetClass convert(ClassOrInterface input) {
|
||||
List<TargetConstructor> targetConstructors = new ArrayList<>();
|
||||
//TODO constructor conversion -> also reduce syntactic sugar
|
||||
return new TargetClass(input.getModifiers(),input.getClassName().toString(), sigma.get(input.getSuperClass()),
|
||||
input.getSuperInterfaces().stream().map(it -> sigma.get(it)).collect(Collectors.toList()),
|
||||
targetConstructors,
|
||||
input.getFieldDecl().stream().map(it -> convert(input, it)).collect(Collectors.toList()),
|
||||
input.getMethods().stream().map(it -> convert(input, it)).collect(Collectors.toList()));
|
||||
return new TargetClass(input.getModifiers(),input.getClassName().toString(), convert(input.getSuperClass()),
|
||||
input.getSuperInterfaces().stream().map(it -> sigma.get(it)).toList(),
|
||||
input.getConstructors().stream().map(it -> convert(input, it)).flatMap(List::stream).toList(),
|
||||
input.getFieldDecl().stream().map(it -> convert(input, it)).toList(),
|
||||
input.getMethods().stream().map(it -> convert(input, it)).flatMap(List::stream).toList()
|
||||
);
|
||||
}
|
||||
|
||||
private TargetMethod convert(ClassOrInterface owner, Method input) {
|
||||
List<MethodParameter> params = input.getParameterList().getFormalparalist().stream()
|
||||
.map(param -> new MethodParameter(convert(param.getType()), param.getName())).collect(Collectors.toList());
|
||||
return new TargetMethod(
|
||||
private List<MethodParameter> convert(ParameterList input) {
|
||||
return input.getFormalparalist().stream()
|
||||
.map(param -> new MethodParameter(convert(param.getType()), param.getName())).toList();
|
||||
}
|
||||
|
||||
private List<TargetConstructor> convert(ClassOrInterface owner, Constructor input) {
|
||||
sigma = all.get(0);
|
||||
List<TargetConstructor> result = new ArrayList<>();
|
||||
Set<List<MethodParameter>> parameterSet = new HashSet<>();
|
||||
|
||||
for (var s : all) {
|
||||
sigma = s;
|
||||
List<MethodParameter> params = convert(input.getParameterList());
|
||||
if (!parameterSet.stream().filter(p -> p.equals(params)).findFirst().isPresent()) {
|
||||
result.add(new TargetConstructor(input.modifier, new TargetRefType(owner.getClassName().getClassName()), params, convert(input.block)));
|
||||
parameterSet.add(params);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<TargetMethod> convert(ClassOrInterface owner, Method input) {
|
||||
sigma = all.get(0);
|
||||
List<TargetMethod> result = new ArrayList<>();
|
||||
Set<List<MethodParameter>> parameterSet = new HashSet<>();
|
||||
|
||||
for (var s : all) {
|
||||
sigma = s;
|
||||
List<MethodParameter> params = convert(input.getParameterList());
|
||||
if (!parameterSet.stream().filter(p -> p.equals(params)).findFirst().isPresent()) {
|
||||
result.add(new TargetMethod(
|
||||
input.modifier,
|
||||
new TargetRefType(owner.getClassName().getClassName()),
|
||||
input.name, params,
|
||||
convert(input.getReturnType()),
|
||||
convert(input.block)
|
||||
);
|
||||
));
|
||||
parameterSet.add(params);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected TargetBlock convert(Block block) {
|
||||
return new TargetBlock(block.statements.stream().map(this::convert).collect(Collectors.toList()));
|
||||
return new TargetBlock(block.statements.stream().map(this::convert).toList());
|
||||
}
|
||||
|
||||
protected TargetExpression convert(Expression expr) {
|
||||
@ -74,8 +129,10 @@ public class ASTToTargetAST {
|
||||
return input.acceptTV(new TypeVisitor<>() {
|
||||
@Override
|
||||
public TargetType visit(RefType refType) {
|
||||
return new TargetRefType(refType.getName().toString(),
|
||||
refType.getParaList().stream().map(ASTToTargetAST.this::convert).collect(Collectors.toList()));
|
||||
var name = refType.getName().toString();
|
||||
if (name.equals("void")) return null;
|
||||
return new TargetRefType(name,
|
||||
refType.getParaList().stream().map(ASTToTargetAST.this::convert).toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -7,7 +7,9 @@ import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
import de.dhbwstuttgart.target.tree.MethodParameter;
|
||||
import de.dhbwstuttgart.target.tree.expression.*;
|
||||
import de.dhbwstuttgart.target.tree.type.TargetFunNType;
|
||||
import de.dhbwstuttgart.target.tree.type.TargetRefType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
public class StatementToTargetExpression implements StatementVisitor {
|
||||
@ -128,7 +130,7 @@ public class StatementToTargetExpression implements StatementVisitor {
|
||||
var receiver = methodCall.receiver;
|
||||
result = new TargetMethodCall(
|
||||
converter.convert(methodCall.getType()),
|
||||
methodCall.argTypes.stream().map(converter::convert).toList(),
|
||||
methodCall.argTypes == null ? List.of() : methodCall.argTypes.stream().map(converter::convert).toList(),
|
||||
converter.convert(receiver),
|
||||
methodCall.getArgumentList().getArguments().stream().map(converter::convert).toList(),
|
||||
converter.convert(receiver.getType()),
|
||||
@ -177,7 +179,7 @@ public class StatementToTargetExpression implements StatementVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(WhileStmt whileStmt) {
|
||||
|
||||
result = new TargetWhile(converter.convert(whileStmt.expr), converter.convert(whileStmt.loopBlock));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -198,13 +200,19 @@ public class StatementToTargetExpression implements StatementVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(SuperCall superCall) {
|
||||
this.visit((MethodCall) superCall);
|
||||
result = new TargetMethodCall(
|
||||
converter.convert(superCall.getType()),
|
||||
superCall.argTypes == null ? List.of() : superCall.argTypes.stream().map(converter::convert).toList(),
|
||||
new TargetSuper(null),
|
||||
superCall.getArgumentList().getArguments().stream().map(converter::convert).toList(),
|
||||
null,
|
||||
superCall.name, false, false
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ExpressionReceiver expressionReceiver) {
|
||||
// TODO What is this?
|
||||
throw new NotImplementedException();
|
||||
result = converter.convert(expressionReceiver.expr);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +0,0 @@
|
||||
package targetast;
|
||||
|
||||
public class ASTToTargetTest {
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package targetast;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
@ -7,14 +8,14 @@ import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||
import de.dhbwstuttgart.target.tree.TargetClass;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class ASTToTypedTargetAST {
|
||||
|
||||
@ -23,10 +24,30 @@ public class ASTToTypedTargetAST {
|
||||
ClassOrInterface emptyClass = new ClassOrInterface(0, new JavaClassName("EmptyClass"), new ArrayList<>(), java.util.Optional.empty(), new ArrayList<>(), new ArrayList<>(), new GenericDeclarationList(new ArrayList<>(), new NullToken()),
|
||||
new RefType(new JavaClassName("Object"), new NullToken()), false, new ArrayList<>(), new NullToken());
|
||||
ResultSet emptyResultSet = new ResultSet(new HashSet<>());
|
||||
TargetClass emptyTargetClass = new ASTToTargetAST(emptyResultSet).convert(emptyClass);
|
||||
TargetClass emptyTargetClass = new ASTToTargetAST(List.of(emptyResultSet)).convert(emptyClass);
|
||||
assert emptyTargetClass.getName().equals("EmptyClass");
|
||||
assert emptyTargetClass.methods().size() == 0;
|
||||
assert emptyTargetClass.fields().size() == 0;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void overloading() throws Exception {
|
||||
var file = Path.of(System.getProperty("user.dir"), "/src/test/resources/bytecode/javFiles/Overloading.jav").toFile();
|
||||
var compiler = new JavaTXCompiler(file);
|
||||
var resultSet = compiler.typeInference();
|
||||
var converter = new ASTToTargetAST(resultSet);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
Class overloading = TestCodegen.generateClass(converter.convert(classes.get(0)));
|
||||
Class overloading2 = TestCodegen.generateClass(converter.convert(classes.get(1)));
|
||||
|
||||
var test1 = overloading.getDeclaredMethod("test", overloading);
|
||||
test1.setAccessible(true);
|
||||
var test2 = overloading.getDeclaredMethod("test", overloading2);
|
||||
test2.setAccessible(true);
|
||||
Object overloadingInstance = overloading.getDeclaredConstructor().newInstance();
|
||||
Object overloading2Instance = overloading2.getDeclaredConstructor().newInstance();
|
||||
assertEquals(test1.invoke(overloadingInstance, overloadingInstance), "Overloading");
|
||||
assertEquals(test2.invoke(overloadingInstance, overloading2Instance), "Overloading2");
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ public class TestCodegen {
|
||||
|
||||
private static ByteArrayClassLoader loader = new ByteArrayClassLoader();
|
||||
|
||||
private static Class generateClass(TargetClass clazz) throws IOException {
|
||||
public static Class generateClass(TargetClass clazz) throws IOException {
|
||||
var codegen = new Codegen(clazz);
|
||||
var bytes = codegen.generate();
|
||||
var path = Path.of(System.getProperty("user.dir"), "src/test/resources/target/");
|
||||
|
Loading…
Reference in New Issue
Block a user