Merge branch 'targetBytecode' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into targetBytecode

This commit is contained in:
pl@gohorb.ba-horb.de 2022-08-08 11:50:07 +02:00
commit 975f2cefe3
14 changed files with 162 additions and 103 deletions

View File

@ -122,8 +122,8 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<configuration> <configuration>
<source>18</source> <source>17</source>
<target>18</target> <target>17</target>
<compilerArgs>--enable-preview</compilerArgs> <compilerArgs>--enable-preview</compilerArgs>
</configuration> </configuration>
</plugin> </plugin>

View File

@ -2,10 +2,7 @@ package de.dhbwstuttgart.target.bytecode;
import de.dhbwstuttgart.target.tree.*; import de.dhbwstuttgart.target.tree.*;
import de.dhbwstuttgart.target.tree.expression.*; import de.dhbwstuttgart.target.tree.expression.*;
import de.dhbwstuttgart.target.tree.type.TargetFunNType; import de.dhbwstuttgart.target.tree.type.*;
import de.dhbwstuttgart.target.tree.type.TargetPrimitiveType;
import de.dhbwstuttgart.target.tree.type.TargetRefType;
import de.dhbwstuttgart.target.tree.type.TargetType;
import org.objectweb.asm.*; import org.objectweb.asm.*;
import java.lang.invoke.CallSite; import java.lang.invoke.CallSite;
@ -13,10 +10,9 @@ import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType; import java.lang.invoke.MethodType;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.IntStream;
import static org.objectweb.asm.Opcodes.*; import static org.objectweb.asm.Opcodes.*;
import static de.dhbwstuttgart.target.tree.expression.TargetBinaryOp.*; import static de.dhbwstuttgart.target.tree.expression.TargetBinaryOp.*;
@ -26,6 +22,8 @@ public class Codegen {
private final TargetClass clazz; private final TargetClass clazz;
private final ClassWriter cw; private final ClassWriter cw;
public final String className; public final String className;
private int lambdaCounter = 0;
private final HashMap<TargetLambdaExpression, TargetMethod> lambdas = new HashMap<>();
public Codegen(TargetClass clazz) { public Codegen(TargetClass clazz) {
this.clazz = clazz; this.clazz = clazz;
@ -62,7 +60,6 @@ public class Codegen {
private static class State { private static class State {
Scope scope = new Scope(null); Scope scope = new Scope(null);
int localCounter; int localCounter;
int lambdaCounter;
MethodVisitor mv; MethodVisitor mv;
State(MethodVisitor mv, int localCounter) { State(MethodVisitor mv, int localCounter) {
@ -243,7 +240,7 @@ public class Codegen {
mv.visitInsn(I2D); mv.visitInsn(I2D);
} else { } else {
boxPrimitive(state, source); boxPrimitive(state, source);
mv.visitTypeInsn(CHECKCAST, dest.getName()); mv.visitTypeInsn(CHECKCAST, dest.getInternalName());
unboxPrimitive(state, dest); unboxPrimitive(state, dest);
} }
} }
@ -578,7 +575,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().getName(), fieldVar.right(), fieldVar.type().toSignature()); mv.visitFieldInsn(PUTFIELD, fieldVar.owner().getInternalName(), fieldVar.right(), fieldVar.type().toSignature());
} }
} }
@ -702,12 +699,19 @@ public class Codegen {
private void generateLambdaExpression(State state, TargetLambdaExpression lambda) { private void generateLambdaExpression(State state, TargetLambdaExpression lambda) {
var mv = state.mv; var mv = state.mv;
var name = "lambda$" + state.lambdaCounter;
var impl = new TargetMethod( TargetMethod impl;
0, name, Set.of(), if (lambdas.containsKey(lambda)) {
lambda.params(), lambda.returnType(), lambda.block() impl = lambdas.get(lambda);
); } else {
generateMethod(impl); var name = "lambda$" + lambdaCounter++;
impl = new TargetMethod(
0, name, Set.of(),
lambda.params(), lambda.returnType(), lambda.block()
);
generateMethod(impl);
lambdas.put(lambda, impl);
}
var mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, var mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
MethodType.class, MethodType.class, MethodHandle.class, MethodType.class); MethodType.class, MethodType.class, MethodHandle.class, MethodType.class);
@ -715,7 +719,7 @@ public class Codegen {
var bootstrap = new Handle(H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory", var bootstrap = new Handle(H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory",
mt.toMethodDescriptorString(), false); mt.toMethodDescriptorString(), false);
var handle = new Handle( var handle = new Handle(
H_INVOKEVIRTUAL, clazz.getName(), name, H_INVOKEVIRTUAL, clazz.getName(), impl.name(),
impl.getDescriptor(), false impl.getDescriptor(), false
); );
@ -731,8 +735,6 @@ public class Codegen {
mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 0);
mv.visitInvokeDynamicInsn("apply", TargetMethod.getDescriptor(lambda.type(), new TargetRefType(clazz.qualifiedName())), mv.visitInvokeDynamicInsn("apply", TargetMethod.getDescriptor(lambda.type(), new TargetRefType(clazz.qualifiedName())),
bootstrap, Type.getType(desugared), handle, Type.getType(impl.getDescriptor())); bootstrap, Type.getType(desugared), handle, Type.getType(impl.getDescriptor()));
state.lambdaCounter++;
} }
private void generate(State state, TargetExpression expr) { private void generate(State state, TargetExpression expr) {
@ -760,7 +762,7 @@ public class Codegen {
convertTo(state, cast.expr().type(), cast.type()); convertTo(state, cast.expr().type(), cast.type());
break; break;
case TargetInstanceOf instanceOf: case TargetInstanceOf instanceOf:
mv.visitTypeInsn(INSTANCEOF, instanceOf.right().getName()); mv.visitTypeInsn(INSTANCEOF, instanceOf.right().getInternalName());
break; break;
case TargetLiteral literal: case TargetLiteral literal:
switch (literal) { switch (literal) {
@ -823,7 +825,7 @@ public class Codegen {
if (dot.isStatic()) if (dot.isStatic())
mv.visitInsn(DUP); mv.visitInsn(DUP);
else mv.visitInsn(DUP_X1); else mv.visitInsn(DUP_X1);
mv.visitFieldInsn(dot.isStatic() ? PUTSTATIC : PUTFIELD, dot.owner().getName(), dot.right(), dot.type().toSignature()); mv.visitFieldInsn(dot.isStatic() ? PUTSTATIC : PUTFIELD, dot.owner().getInternalName(), dot.right(), dot.type().toSignature());
break; break;
} }
default: default:
@ -840,7 +842,7 @@ public class Codegen {
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().getName(), dot.right(), dot.type().toSignature()); 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;
} }
@ -926,11 +928,11 @@ public class Codegen {
); );
mv.visitMethodInsn(call.isInterface() ? INVOKEINTERFACE : call.isStatic() ? INVOKESTATIC: call.name().equals("<init>") ? INVOKESPECIAL : INVOKEVIRTUAL, mv.visitMethodInsn(call.isInterface() ? INVOKEINTERFACE : call.isStatic() ? INVOKESTATIC: call.name().equals("<init>") ? INVOKESPECIAL : INVOKEVIRTUAL,
call.owner().getName(), call.name(), descriptor, call.isInterface()); call.owner().getInternalName(), call.name(), descriptor, call.isInterface());
if (call.returnType() != null && !(call.returnType() instanceof TargetPrimitiveType)) { if (call.returnType() != null && !(call.returnType() instanceof TargetPrimitiveType)) {
if (!call.returnType().equals(call.type())) if (!call.returnType().equals(call.type()) && !(call.type() instanceof TargetGenericType))
mv.visitTypeInsn(CHECKCAST, call.type().getName()); mv.visitTypeInsn(CHECKCAST, call.type().getInternalName());
else unboxPrimitive(state, call.type()); else unboxPrimitive(state, call.type());
} }
break; break;
@ -939,13 +941,13 @@ public class Codegen {
generateLambdaExpression(state, lambda); generateLambdaExpression(state, lambda);
break; break;
case TargetNew _new: { case TargetNew _new: {
mv.visitTypeInsn(NEW, _new.type().getName()); mv.visitTypeInsn(NEW, _new.type().getInternalName());
mv.visitInsn(DUP); mv.visitInsn(DUP);
for (TargetExpression e : _new.params()) { for (TargetExpression e : _new.params()) {
generate(state, e); generate(state, e);
boxPrimitive(state, e.type()); boxPrimitive(state, e.type());
} }
mv.visitMethodInsn(INVOKESPECIAL, _new.type().getName(), "<init>", _new.getDescriptor(), false); mv.visitMethodInsn(INVOKESPECIAL, _new.type().getInternalName(), "<init>", _new.getDescriptor(), false);
break; break;
} }
default: default:
@ -963,7 +965,18 @@ public class Codegen {
var state = new State(mv, 1); var state = new State(mv, 1);
for (var param: constructor.parameters()) for (var param: constructor.parameters())
state.createVariable(param.name(), param.type()); state.createVariable(param.name(), param.type());
generate(state, constructor.block());
var stmts = constructor.block().statements();
generate(state, stmts.get(0));
if (constructor.fieldInitializer() != null) {
var stmts2 = constructor.fieldInitializer().statements();
for (var i = 1; i < stmts2.size(); i++) {
generate(state, stmts2.get(i));
}
}
for (var i = 1; i < stmts.size(); i++)
generate(state, stmts.get(i));
mv.visitInsn(RETURN); mv.visitInsn(RETURN);
mv.visitMaxs(0, 0); mv.visitMaxs(0, 0);
mv.visitEnd(); mv.visitEnd();
@ -996,7 +1009,7 @@ public class Codegen {
public byte[] generate() { public byte[] generate() {
cw.visit(V1_8, clazz.modifiers() | ACC_PUBLIC, clazz.qualifiedName(), cw.visit(V1_8, clazz.modifiers() | ACC_PUBLIC, clazz.qualifiedName(),
generateSignature(clazz), clazz.superType() != null ? clazz.superType().getName(): "java/lang/Object", generateSignature(clazz), clazz.superType() != null ? clazz.superType().getInternalName(): "java/lang/Object",
clazz.implementingInterfaces().stream().map(TargetType::toSignature).toArray(String[]::new) clazz.implementingInterfaces().stream().map(TargetType::toSignature).toArray(String[]::new)
); );
clazz.fields().forEach(this::generateField); clazz.fields().forEach(this::generateField);

View File

@ -1,6 +1,7 @@
package de.dhbwstuttgart.target.generate; package de.dhbwstuttgart.target.generate;
import de.dhbwstuttgart.bytecode.funN.FunNGenerator; import de.dhbwstuttgart.bytecode.funN.FunNGenerator;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
@ -174,9 +175,7 @@ public class ASTToTargetAST {
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver) { if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver) {
if (expressionReceiver.expr instanceof This) { if (expressionReceiver.expr instanceof This) {
var optMethod = owner.getMethods().stream().filter( var optMethod = findMethod(owner, methodCall.name, methodCall.getArgumentList());
m -> m.name.equals(methodCall.name) && parameterEquals(methodCall.getArgumentList(), methodCall.getArgumentList().getArguments())
).findFirst();
if (optMethod.isEmpty()) return; if (optMethod.isEmpty()) return;
var method = optMethod.get(); var method = optMethod.get();
if (visitedMethods.contains(method)) return; if (visitedMethods.contains(method)) return;
@ -451,19 +450,6 @@ public class ASTToTargetAST {
} }
} }
private boolean parameterEquals(ArgumentList argumentList, List<Expression> arguments) {
if (argumentList.getArguments().size() != arguments.size())
return false;
for (var i = 0; i < argumentList.getArguments().size(); i++) {
var type1 = convert(argumentList.getArguments().get(i).getType());
var type2 = convert(arguments.get(i).getType());
if (!type1.equals(type2)) return false;
}
return true;
}
protected ByteArrayClassLoader classLoader; protected ByteArrayClassLoader classLoader;
protected SourceFile sourceFile; protected SourceFile sourceFile;
@ -571,6 +557,27 @@ public class ASTToTargetAST {
return cycles; return cycles;
} }
Optional<Method> findMethod(ClassOrInterface owner, String name, ArgumentList argumentList) {
return owner.getMethods().stream().filter(
m -> m.name.equals(name) && parameterEquals(m.getParameterList(), argumentList)
).findFirst();
}
boolean parameterEquals(ParameterList parameterList, ArgumentList argumentList) {
var pars = parameterList.getFormalparalist();
var arguments = argumentList.getArguments();
if (pars.size() != arguments.size())
return false;
for (var i = 0; i < pars.size(); i++) {
var type1 = convert(pars.get(i).getType());
var type2 = convert(arguments.get(i).getType());
if (!type1.equals(type2)) return false;
}
return true;
}
Set<TargetGeneric> convert(Set<ResultPair<?, ?>> result) { Set<TargetGeneric> convert(Set<ResultPair<?, ?>> result) {
return result.stream().map(p -> { return result.stream().map(p -> {
if (p instanceof PairTPHsmallerTPH pair) { if (p instanceof PairTPHsmallerTPH pair) {
@ -584,12 +591,18 @@ public class ASTToTargetAST {
} }
public TargetClass convert(ClassOrInterface input) { public TargetClass convert(ClassOrInterface input) {
currentClass = 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()), return new TargetClass(input.getModifiers(), input.getClassName().toString(), convert(input.getSuperClass()),
convert(sigma.generics(input)), convert(sigma.generics(input)),
input.getSuperInterfaces().stream().map(this::convert).toList(), input.getSuperInterfaces().stream().map(this::convert).toList(),
input.getConstructors().stream().map(constructor -> this.convert(input, constructor)).flatMap(List::stream).toList(), input.getConstructors().stream().map(constructor -> this.convert(constructor, finalFieldInitializer)).flatMap(List::stream).toList(),
input.getFieldDecl().stream().map(this::convert).toList(), input.getFieldDecl().stream().map(this::convert).toList(),
input.getMethods().stream().map(method -> this.convert(input, method)).flatMap(List::stream).toList() input.getMethods().stream().map(this::convert).flatMap(List::stream).toList()
); );
} }
@ -598,18 +611,17 @@ public class ASTToTargetAST {
.map(param -> new MethodParameter(convert(param.getType()), param.getName())).toList(); .map(param -> new MethodParameter(convert(param.getType()), param.getName())).toList();
} }
private List<TargetConstructor> convert(ClassOrInterface owner, Constructor input) { private List<TargetConstructor> convert(Constructor input, TargetBlock fieldInitializer) {
currentClass = owner;
sigma = all.get(0); sigma = all.get(0);
List<TargetConstructor> result = new ArrayList<>(); List<TargetConstructor> result = new ArrayList<>();
Set<List<MethodParameter>> parameterSet = new HashSet<>(); Set<List<MethodParameter>> parameterSet = new HashSet<>();
for (var s : all) { for (var s : all) {
sigma = s; sigma = s;
var generics = sigma.generics(owner, input); var generics = sigma.generics(currentClass, input);
List<MethodParameter> params = convert(input.getParameterList()); List<MethodParameter> params = convert(input.getParameterList());
if (parameterSet.stream().noneMatch(p -> p.equals(params))) { if (parameterSet.stream().noneMatch(p -> p.equals(params))) {
result.add(new TargetConstructor(input.modifier, convert(generics), params, convert(input.block))); result.add(new TargetConstructor(input.modifier, convert(generics), params, convert(input.block), fieldInitializer));
parameterSet.add(params); parameterSet.add(params);
} }
} }
@ -617,15 +629,14 @@ public class ASTToTargetAST {
return result; return result;
} }
private List<TargetMethod> convert(ClassOrInterface owner, Method input) { private List<TargetMethod> convert(Method input) {
currentClass = owner;
sigma = all.get(0); sigma = all.get(0);
List<TargetMethod> result = new ArrayList<>(); List<TargetMethod> result = new ArrayList<>();
Set<List<MethodParameter>> parameterSet = new HashSet<>(); Set<List<MethodParameter>> parameterSet = new HashSet<>();
for (var s : all) { for (var s : all) {
sigma = s; sigma = s;
var generics = sigma.generics(owner, input); var generics = sigma.generics(currentClass, input);
List<MethodParameter> params = convert(input.getParameterList()); List<MethodParameter> params = convert(input.getParameterList());
if (parameterSet.stream().noneMatch(p -> p.equals(params))) { if (parameterSet.stream().noneMatch(p -> p.equals(params))) {
result.add(new TargetMethod( result.add(new TargetMethod(

View File

@ -3,7 +3,7 @@ package de.dhbwstuttgart.target.generate;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.StatementVisitor; import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
@ -14,7 +14,10 @@ import de.dhbwstuttgart.target.tree.type.TargetRefType;
import de.dhbwstuttgart.target.tree.type.TargetSpecializedType; import de.dhbwstuttgart.target.tree.type.TargetSpecializedType;
import de.dhbwstuttgart.target.tree.type.TargetType; import de.dhbwstuttgart.target.tree.type.TargetType;
import java.lang.reflect.Method;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream; import java.util.stream.Stream;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
@ -131,36 +134,60 @@ public class StatementToTargetExpression implements StatementVisitor {
result = new TargetVarDecl(converter.convert(localVarDecl.getType()), localVarDecl.getName(), null); result = new TargetVarDecl(converter.convert(localVarDecl.getType()), localVarDecl.getName(), null);
} }
static boolean convertsTo(TargetType from, TargetType to) {
if (to.equals(TargetType.Object)) return true; // TODO Consider type coercion and suptyping
return to.equals(from);
}
Method findMethod(JavaClassName className, String name, List<TargetType> args) {
if (converter.sourceFile != null && converter.sourceFile.imports.contains(className)) {
try {
var clazz = converter.classLoader.loadClass(className.toString());
outer: for (var method : clazz.getMethods()) {
if (method.getParameterTypes().length != args.size()) continue;
if (!method.getName().equals(name)) continue;
for (var i = 0; i < method.getParameterTypes().length; i++) {
var param = method.getParameterTypes()[i];
var arg = args.get(i);
if (param.isPrimitive()) {
arg = TargetType.toPrimitive(arg);
}
if (!convertsTo(arg, Objects.requireNonNull(TargetType.toTargetType(param)))) continue outer;
}
return method;
}
} catch (ClassNotFoundException ignored) {}
}
if (converter.sourceFile != null) { // TODO Multiple source files
var thisClass = converter.sourceFile.KlassenVektor.stream()
.filter(classOrInterface -> classOrInterface.getClassName().equals(className)).findFirst();
if (thisClass.isPresent()) {
var superClass = thisClass.get().getSuperClass().getName();
return findMethod(superClass, name, args);
}
}
return null;
}
@Override @Override
public void visit(MethodCall methodCall) { public void visit(MethodCall methodCall) {
var receiverType = converter.convert(methodCall.receiver.getType()); var receiverType = converter.convert(methodCall.receiver.getType());
var isFunNType = receiverType instanceof TargetFunNType; var isFunNType = receiverType instanceof TargetFunNType;
var returnType = converter.convert(methodCall.getType()); var returnType = isFunNType ? TargetType.Object : converter.convert(methodCall.getType());
var receiverName = new JavaClassName(((TargetSpecializedType) converter.convert(methodCall.receiver.getType())).name()); var receiverName = new JavaClassName(converter.convert(methodCall.receiver.getType()).name());
var argList = methodCall.arglist.getArguments().stream().map(expr -> converter.convert(expr.getType())).toList(); var argList = methodCall.arglist.getArguments().stream().map(expr -> converter.convert(expr.getType())).toList();
java.lang.reflect.Method foundMethod = null; Method foundMethod = null;
if (converter.sourceFile != null && converter.sourceFile.imports.contains(receiverName)) { if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver && expressionReceiver.expr instanceof This) {
try { var thisMethod = converter.findMethod(converter.currentClass, methodCall.name, methodCall.arglist);
var clazz = converter.classLoader.loadClass(receiverName.toString()); if (thisMethod.isEmpty()) {
foundMethod = findMethod(converter.currentClass.getSuperClass().getName(), methodCall.name, argList);
outer: for (var method : clazz.getMethods()) { }
if (method.getParameterTypes().length != argList.size()) continue; } else {
if (!method.getName().equals(methodCall.name)) continue; foundMethod = findMethod(receiverName, methodCall.name, argList);
for (var i = 0; i < method.getParameterTypes().length; i++) {
var param = method.getParameterTypes()[i];
var arg = argList.get(i);
if (param.isPrimitive()) {
arg = TargetType.toPrimitive(arg);
}
if (!TargetType.toTargetType(param).equals(arg)) continue outer;
}
foundMethod = method;
break;
}
} catch (ClassNotFoundException ignored) {}
} }
if (foundMethod != null) { if (foundMethod != null) {

View File

@ -33,7 +33,7 @@ public record TargetClass(int modifiers, String qualifiedName, TargetType superT
} }
public void addConstructor(int access, Set<TargetGeneric> generics, List<MethodParameter> paramterTypes, TargetBlock block) { public void addConstructor(int access, Set<TargetGeneric> generics, List<MethodParameter> paramterTypes, TargetBlock block) {
this.constructors.add(new TargetConstructor(access, generics, paramterTypes, block)); this.constructors.add(new TargetConstructor(access, generics, paramterTypes, block, null));
} }
public void addConstructor(int access, List<MethodParameter> paramterTypes, TargetBlock block) { public void addConstructor(int access, List<MethodParameter> paramterTypes, TargetBlock block) {

View File

@ -6,7 +6,7 @@ import de.dhbwstuttgart.target.tree.type.TargetType;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
public record TargetConstructor(int access, Set<TargetGeneric> generics, List<MethodParameter> parameters, TargetBlock block) { public record TargetConstructor(int access, Set<TargetGeneric> generics, List<MethodParameter> parameters, TargetBlock block, TargetBlock fieldInitializer) {
public String getDescriptor() { public String getDescriptor() {
return TargetMethod.getDescriptor(null, parameters.stream().map(MethodParameter::type).toArray(TargetType[]::new)); return TargetMethod.getDescriptor(null, parameters.stream().map(MethodParameter::type).toArray(TargetType[]::new));

View File

@ -12,8 +12,13 @@ public record TargetExtendsWildcard(TargetType innerType) implements TargetType
} }
@Override @Override
public String getName() { public String getInternalName() {
return innerType.getName(); return innerType.getInternalName();
}
@Override
public String name() {
return innerType.name();
} }
} }

View File

@ -4,17 +4,17 @@ import java.util.List;
public record TargetFunNType(int N, List<TargetType> params) implements TargetSpecializedType { public record TargetFunNType(int N, List<TargetType> params) implements TargetSpecializedType {
@Override @Override
public String getName() { public String getInternalName() {
return "Fun" + N + "$$"; return "Fun" + N + "$$";
} }
@Override @Override
public String name() { public String name() {
return getName(); return getInternalName();
} }
@Override @Override
public String toSignature() { public String toSignature() {
return "L" + getName() + ";"; return "L" + getInternalName() + ";";
} }
} }

View File

@ -8,11 +8,11 @@ public record TargetGenericType(String name) implements TargetType {
@Override @Override
public String toGenericSignature() { public String toGenericSignature() {
return "T" + getName() + ";"; return "T" + getInternalName() + ";";
} }
@Override @Override
public String getName() { public String getInternalName() {
return name; return name;
} }
} }

View File

@ -4,7 +4,7 @@ public record TargetPrimitiveType(String name) implements TargetType {
@Override @Override
public String toSignature() { public String toSignature() {
return getName(); return getInternalName();
} }
@Override @Override
@ -13,7 +13,7 @@ public record TargetPrimitiveType(String name) implements TargetType {
} }
@Override @Override
public String getName() { public String getInternalName() {
return name; return name;
} }
} }

View File

@ -1,7 +1,5 @@
package de.dhbwstuttgart.target.tree.type; package de.dhbwstuttgart.target.tree.type;
import de.dhbwstuttgart.target.tree.type.TargetType;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -10,13 +8,13 @@ public record TargetRefType(String name, List<TargetType> params) implements Tar
this(name, List.of()); this(name, List.of());
} }
public String getName() { public String getInternalName() {
return this.name.replaceAll("\\.", "/"); return this.name.replaceAll("\\.", "/");
} }
@Override @Override
public String toSignature() { public String toSignature() {
return "L" + getName() + ";"; 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

View File

@ -7,7 +7,7 @@ public sealed interface TargetSpecializedType extends TargetType permits TargetF
@Override @Override
default String toGenericSignature() { default String toGenericSignature() {
String ret = "L" + getName(); String ret = "L" + getInternalName();
if (params().size() > 0) { if (params().size() > 0) {
ret += "<"; ret += "<";
for (var param : params()) { for (var param : params()) {
@ -18,6 +18,4 @@ public sealed interface TargetSpecializedType extends TargetType permits TargetF
ret += ";"; ret += ";";
return ret; return ret;
} }
String name();
} }

View File

@ -12,7 +12,14 @@ public record TargetSuperWildcard(TargetType innerType) implements TargetType {
} }
@Override @Override
public String getName() { public String getInternalName() {
return innerType.getName(); return innerType.getInternalName();
}
@Override
public String name() {
return innerType.name();
} }
} }

View File

@ -1,7 +1,5 @@
package de.dhbwstuttgart.target.tree.type; package de.dhbwstuttgart.target.tree.type;
import java.util.List;
public sealed interface TargetType public sealed interface TargetType
permits TargetExtendsWildcard, TargetGenericType, TargetSpecializedType, TargetSuperWildcard, TargetPrimitiveType { permits TargetExtendsWildcard, TargetGenericType, TargetSpecializedType, TargetSuperWildcard, TargetPrimitiveType {
@ -50,10 +48,12 @@ public sealed interface TargetType
if (clazz.equals(float.class)) return float_; if (clazz.equals(float.class)) return float_;
if (clazz.equals(double.class)) return double_; if (clazz.equals(double.class)) return double_;
} }
if (clazz.equals(void.class)) return null;
return new TargetRefType(clazz.getName()); return new TargetRefType(clazz.getName());
} }
String toSignature(); String toSignature();
String toGenericSignature(); String toGenericSignature();
String getName(); String getInternalName();
String name();
} }