Merge branch 'targetBytecode' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into targetBytecode
This commit is contained in:
commit
fba7f0ee81
@ -1,14 +1,17 @@
|
||||
import java.lang.Runnable;
|
||||
import java.lang.String;
|
||||
import java.lang.System;
|
||||
import java.io.PrintStream;
|
||||
|
||||
public class LamRunnable{
|
||||
public class LambdaRunnable {
|
||||
|
||||
public LamRunnable(){
|
||||
public LambdaRunnable(){
|
||||
|
||||
Runnable lam;
|
||||
lam = () -> {var a;};
|
||||
//lam.run();
|
||||
|
||||
Runnable lam = () -> {
|
||||
System.out.println("Runnable is running");
|
||||
};
|
||||
lam.run();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,6 +76,8 @@ public class Codegen {
|
||||
int localCounter;
|
||||
MethodVisitor mv;
|
||||
TargetType returnType;
|
||||
// This is used to remember the type from lambda expressions
|
||||
TargetType contextType;
|
||||
|
||||
Stack<BreakEnv> breakStack = new Stack<>();
|
||||
Stack<Integer> switchResultValue = new Stack<>();
|
||||
@ -747,14 +749,19 @@ public class Codegen {
|
||||
params.add(new TargetRefType(clazz.qualifiedName().getClassName()));
|
||||
params.addAll(lambda.captures().stream().map(mp -> mp.pattern().type()).toList());
|
||||
|
||||
var descriptor = TargetMethod.getDescriptor(lambda.type(), params.toArray(TargetType[]::new));
|
||||
var descriptor = TargetMethod.getDescriptor(state.contextType, params.toArray(TargetType[]::new));
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
for (var capture : lambda.captures()) {
|
||||
var pattern = (TargetTypePattern) capture.pattern();
|
||||
mv.visitVarInsn(ALOAD, state.scope.get(pattern.name()).index);
|
||||
}
|
||||
|
||||
mv.visitInvokeDynamicInsn("apply", descriptor, bootstrap, Type.getType(desugared), handle, Type.getType(TargetMethod.getDescriptor(impl.signature().returnType(), lambda.params().stream().map(mp -> mp.pattern().type()).toArray(TargetType[]::new))));
|
||||
String methodName;
|
||||
var intf = compiler.getClass(new JavaClassName(state.contextType.name()));
|
||||
if (intf == null) methodName = "apply"; // TODO Weird fallback logic here
|
||||
else methodName = intf.getMethods().stream().filter(m -> Modifier.isAbstract(m.modifier)).findFirst().orElseThrow().getName();
|
||||
|
||||
mv.visitInvokeDynamicInsn(methodName, descriptor, bootstrap, Type.getType(desugared), handle, Type.getType(TargetMethod.getDescriptor(impl.signature().returnType(), lambda.params().stream().map(mp -> mp.pattern().type()).toArray(TargetType[]::new))));
|
||||
}
|
||||
|
||||
private void generate(State state, TargetExpression expr) {
|
||||
@ -781,7 +788,10 @@ public class Codegen {
|
||||
break;
|
||||
}
|
||||
case TargetCast cast:
|
||||
var ctx = state.contextType;
|
||||
state.contextType = cast.type();
|
||||
generate(state, cast.expr());
|
||||
state.contextType = ctx;
|
||||
convertTo(state, cast.expr().type(), cast.type());
|
||||
break;
|
||||
case TargetInstanceOf instanceOf:
|
||||
@ -825,7 +835,11 @@ public class Codegen {
|
||||
case TargetAssign assign: {
|
||||
switch (assign.left()) {
|
||||
case TargetLocalVar localVar -> {
|
||||
var ctype = state.contextType;
|
||||
state.contextType = localVar.type();
|
||||
generate(state, assign.right());
|
||||
state.contextType = ctype;
|
||||
|
||||
convertTo(state, assign.right().type(), localVar.type());
|
||||
boxPrimitive(state, localVar.type());
|
||||
var local = state.scope.get(localVar.name());
|
||||
@ -836,7 +850,12 @@ public class Codegen {
|
||||
var fieldType = dot.type();
|
||||
if (!(dot.left() instanceof TargetThis && dot.isStatic()))
|
||||
generate(state, dot.left());
|
||||
|
||||
var ctype = state.contextType;
|
||||
state.contextType = fieldType;
|
||||
generate(state, assign.right());
|
||||
state.contextType = ctype;
|
||||
|
||||
convertTo(state, assign.right().type(), fieldType);
|
||||
boxPrimitive(state, fieldType);
|
||||
if (dot.isStatic())
|
||||
@ -934,7 +953,10 @@ public class Codegen {
|
||||
}
|
||||
case TargetReturn ret: {
|
||||
if (ret.expression() != null && state.returnType != null) {
|
||||
var ctype = state.contextType;
|
||||
state.contextType = state.returnType;
|
||||
generate(state, ret.expression());
|
||||
state.contextType = ctype;
|
||||
convertTo(state, ret.expression().type(), state.returnType);
|
||||
boxPrimitive(state, state.returnType);
|
||||
mv.visitInsn(ARETURN);
|
||||
@ -981,9 +1003,12 @@ public class Codegen {
|
||||
for (var i = 0; i < call.args().size(); i++) {
|
||||
var e = call.args().get(i);
|
||||
var arg = call.parameterTypes().get(i);
|
||||
var ctype = state.contextType;
|
||||
state.contextType = arg;
|
||||
generate(state, e);
|
||||
if (!(arg instanceof TargetPrimitiveType))
|
||||
boxPrimitive(state, e.type());
|
||||
state.contextType = ctype;
|
||||
}
|
||||
var descriptor = call.getDescriptor();
|
||||
if (call.owner() instanceof TargetFunNType) // Decay FunN
|
||||
|
@ -28,12 +28,15 @@ public class FunNGenerator {
|
||||
private static final String objectSuperType = Type.getInternalName(Object.class).replace('.','/');
|
||||
private static final String objectSignature = applySignature(TargetType.Object);
|
||||
|
||||
private static final String VOID = "Ljava/lang/Void;";
|
||||
|
||||
public static class GenericParameters {
|
||||
int start;
|
||||
public List<TargetType> parameters = new ArrayList<>();
|
||||
}
|
||||
|
||||
private static String applyDescriptor(TargetType type, GenericParameters gep) {
|
||||
if (type == null) return VOID;
|
||||
var res = "L" + type.getInternalName();
|
||||
if (type instanceof TargetSpecializedType a) {
|
||||
if (a.params().size() > 0) {
|
||||
@ -62,6 +65,7 @@ public class FunNGenerator {
|
||||
private static String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("%s", applySignature(a)); }
|
||||
|
||||
public static String encodeType(TargetType type) {
|
||||
if (type == null) return VOID;
|
||||
return applyNameDescriptor(type).replace("/", "$").replace(";", "$_$");
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,8 @@ public class JavaTXCompiler {
|
||||
}
|
||||
try {
|
||||
var clazz = classLoader.loadClass(name.toString());
|
||||
return ASTFactory.createClass(clazz);
|
||||
if (clazz != null)
|
||||
return ASTFactory.createClass(clazz);
|
||||
} catch (ClassNotFoundException ignored) {}
|
||||
return null;
|
||||
}
|
||||
@ -418,7 +419,9 @@ public class JavaTXCompiler {
|
||||
final ConstraintSet<Pair> cons = getConstraints();
|
||||
Set<Set<UnifyPair>> results = new HashSet<>();
|
||||
try {
|
||||
Writer logFile = log ? new FileWriter(new File(System.getProperty("user.dir") + "/logFiles/" + "log_" + sourceFiles.keySet().iterator().next().getName())) : new OutputStreamWriter(new NullOutputStream());
|
||||
var logFolder = new File(System.getProperty("user.dir") + "/logFiles/");
|
||||
if (log) logFolder.mkdirs();
|
||||
Writer logFile = log ? new FileWriter(new File(logFolder, "log_" + sourceFiles.keySet().iterator().next().getName())) : new OutputStreamWriter(new NullOutputStream());
|
||||
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, classLoader);
|
||||
System.out.println(finiteClosure);
|
||||
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons);
|
||||
@ -742,7 +745,7 @@ public class JavaTXCompiler {
|
||||
}
|
||||
|
||||
public synchronized Map<JavaClassName, byte[]> generateBytecode(SourceFile sf, List<ResultSet> typeInferenceResult) {
|
||||
var converter = new ASTToTargetAST(typeInferenceResult, sf, classLoader);
|
||||
var converter = new ASTToTargetAST(this, typeInferenceResult, sf, classLoader);
|
||||
var generatedClasses = new HashMap<JavaClassName, byte[]>();
|
||||
for (var clazz : sf.getClasses()) {
|
||||
var codegen = new Codegen(converter.convert(clazz), this);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package de.dhbwstuttgart.syntaxtree.factory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.*;
|
||||
@ -45,7 +46,7 @@ public class ASTFactory {
|
||||
try {
|
||||
var path = jreClass.getName().replace('.', '/') + ".class";
|
||||
var classLoader = jreClass.getClassLoader();
|
||||
if (classLoader != null) {
|
||||
if (classLoader != null && new File(path).exists()) {
|
||||
var bytes = IOUtils.toByteArray(Objects.requireNonNull(classLoader.getResourceAsStream(path)));
|
||||
var classReader = new ClassReader(bytes);
|
||||
var classVisitor = new ClassVisitor(Opcodes.ASM7) {
|
||||
@ -354,19 +355,19 @@ public class ASTFactory {
|
||||
if (type == null || type.getTypeName().equals("void")) {
|
||||
return new Void(new NullToken());
|
||||
} else if (type.getTypeName().equals("int")) {
|
||||
return new RefType(new JavaClassName("java.lang.Integer"), new ArrayList<>(), new NullToken());
|
||||
return new RefType(new JavaClassName("java.lang.Integer"), new ArrayList<>(), new NullToken(), true);
|
||||
} else if (type.getTypeName().equals("byte")) {
|
||||
return new RefType(new JavaClassName("java.lang.Byte"), new ArrayList<>(), new NullToken());
|
||||
return new RefType(new JavaClassName("java.lang.Byte"), new ArrayList<>(), new NullToken(), true);
|
||||
} else if (type.getTypeName().equals("boolean")) {
|
||||
return new RefType(new JavaClassName("java.lang.Boolean"), new ArrayList<>(), new NullToken());
|
||||
return new RefType(new JavaClassName("java.lang.Boolean"), new ArrayList<>(), new NullToken(), true);
|
||||
} else if (type.getTypeName().equals("char")) {
|
||||
return new RefType(new JavaClassName("java.lang.Char"), new ArrayList<>(), new NullToken());
|
||||
return new RefType(new JavaClassName("java.lang.Char"), new ArrayList<>(), new NullToken(), true);
|
||||
} else if (type.getTypeName().equals("short")) {
|
||||
return new RefType(new JavaClassName("java.lang.Short"), new ArrayList<>(), new NullToken());
|
||||
return new RefType(new JavaClassName("java.lang.Short"), new ArrayList<>(), new NullToken(), true);
|
||||
} else if (type.getTypeName().equals("double")) {
|
||||
return new RefType(new JavaClassName("java.lang.Double"), new ArrayList<>(), new NullToken());
|
||||
return new RefType(new JavaClassName("java.lang.Double"), new ArrayList<>(), new NullToken(), true);
|
||||
} else if (type.getTypeName().equals("long")) {
|
||||
return new RefType(new JavaClassName("java.lang.Long"), new ArrayList<>(), new NullToken());
|
||||
return new RefType(new JavaClassName("java.lang.Long"), new ArrayList<>(), new NullToken(), true);
|
||||
} else {
|
||||
if (type instanceof TypeVariable) {
|
||||
// GTVDeclarationContext via "(TypeVariable) type).getGenericDeclaration()"
|
||||
|
@ -38,7 +38,11 @@ public class MethodCall extends Statement
|
||||
this.receiverType = receiverType;
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
|
||||
public List<RefTypeOrTPHOrWildcardOrGeneric> signatureArguments() {
|
||||
return signature.subList(0, signature.size() - 1);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void accept(StatementVisitor visitor) {
|
||||
|
@ -8,6 +8,7 @@ public class ThisCall extends MethodCall
|
||||
{
|
||||
public ThisCall(Receiver receiver, ArgumentList arglist, int offset)
|
||||
{
|
||||
// TODO What is this?
|
||||
super(null, null, null, null, null, null, null);
|
||||
|
||||
}
|
||||
|
@ -20,13 +20,17 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
|
||||
*
|
||||
* Bsp: java.lang.Integer mit Flag wird dann zu [int]
|
||||
*/
|
||||
private boolean primitiveFlag=false;
|
||||
boolean primitiveFlag = false; // TODO Should be final
|
||||
|
||||
public RefType(JavaClassName fullyQualifiedName, Token offset)
|
||||
{
|
||||
this(fullyQualifiedName, new ArrayList<>(), offset);
|
||||
}
|
||||
|
||||
public boolean isPrimitive() {
|
||||
return primitiveFlag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
String params = "";
|
||||
@ -51,11 +55,15 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
|
||||
return hash;
|
||||
}
|
||||
|
||||
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset)
|
||||
{
|
||||
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset) {
|
||||
this(fullyQualifiedName, parameter, offset, false);
|
||||
}
|
||||
|
||||
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset, boolean primitiveFlag) {
|
||||
super(offset);
|
||||
this.name = (fullyQualifiedName);
|
||||
this.parameter = parameter;
|
||||
this.primitiveFlag = primitiveFlag;
|
||||
}
|
||||
|
||||
public JavaClassName getName()
|
||||
|
@ -1,6 +1,7 @@
|
||||
package de.dhbwstuttgart.target.generate;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
@ -15,6 +16,7 @@ import de.dhbwstuttgart.target.tree.expression.*;
|
||||
import de.dhbwstuttgart.target.tree.type.*;
|
||||
import de.dhbwstuttgart.typeinference.result.*;
|
||||
|
||||
import javax.sql.rowset.RowSetWarning;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
@ -31,6 +33,8 @@ public class ASTToTargetAST {
|
||||
protected Generics generics;
|
||||
final Map<ClassOrInterface, Set<GenericTypeVar>> userDefinedGenerics = new HashMap<>();
|
||||
|
||||
public final JavaTXCompiler compiler;
|
||||
|
||||
protected ClassOrInterface currentClass; // TODO This is only needed because of SuperCall, maybe there's
|
||||
|
||||
public List<GenericsResult> txGenerics() {
|
||||
@ -55,10 +59,14 @@ public class ASTToTargetAST {
|
||||
protected SourceFile sourceFile;
|
||||
|
||||
public ASTToTargetAST(List<ResultSet> resultSets) {
|
||||
this(resultSets, null, new ByteArrayClassLoader());
|
||||
this(null, resultSets);
|
||||
}
|
||||
public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets) {
|
||||
this(compiler, resultSets, null, new ByteArrayClassLoader());
|
||||
}
|
||||
|
||||
public ASTToTargetAST(List<ResultSet> resultSets, SourceFile sourceFile, IByteArrayClassLoader classLoader) {
|
||||
public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets, SourceFile sourceFile, IByteArrayClassLoader classLoader) {
|
||||
this.compiler = compiler;
|
||||
this.classLoader = classLoader;
|
||||
this.sourceFile = sourceFile;
|
||||
|
||||
@ -69,20 +77,26 @@ public class ASTToTargetAST {
|
||||
this.generics = all.get(0);
|
||||
}
|
||||
|
||||
Optional<Method> findMethod(ClassOrInterface owner, String name, ArgumentList argumentList) {
|
||||
return owner.getMethods().stream().filter(m -> m.name.equals(name) && parameterEquals(m.getParameterList(), argumentList)).findFirst();
|
||||
Optional<Method> findMethod(ClassOrInterface owner, String name, List<TargetType> argumentList) {
|
||||
Optional<Method> method = Optional.empty();
|
||||
while (method.isEmpty() && !owner.getClassName().toString().equals("java.lang.Object")) {
|
||||
method = owner.getMethods().stream().filter(m -> m.name.equals(name) && parameterEquals(m.getParameterList(), argumentList)).findFirst();
|
||||
owner = compiler.getClass(owner.getSuperClass().getName());
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
boolean parameterEquals(ParameterList parameterList, ArgumentList argumentList) {
|
||||
boolean parameterEquals(ParameterList parameterList, List<TargetType> arguments) {
|
||||
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(), generics.javaGenerics);
|
||||
var type2 = convert(arguments.get(i).getType(), generics.javaGenerics);
|
||||
if (type2 instanceof TargetGenericType && type1 instanceof TargetGenericType)
|
||||
var type2 = arguments.get(i);
|
||||
if (type1 instanceof TargetGenericType)
|
||||
return true;
|
||||
if (TargetType.toPrimitive(type2).equals(type1))
|
||||
return true;
|
||||
if (!type1.equals(type2))
|
||||
return false;
|
||||
@ -398,8 +412,7 @@ public class ASTToTargetAST {
|
||||
|
||||
static TargetType flattenFunNType(List<TargetType> params, FunNGenerator.GenericParameters gep) {
|
||||
var newParams = new ArrayList<TargetType>();
|
||||
for (var i = 0; i < params.size(); i++) {
|
||||
var param = params.get(i);
|
||||
for (TargetType param : params) {
|
||||
if (param instanceof TargetSpecializedType fn) {
|
||||
collectArguments(fn, newParams);
|
||||
} else {
|
||||
@ -421,8 +434,16 @@ public class ASTToTargetAST {
|
||||
var name = refType.getName().toString();
|
||||
if (name.equals("void"))
|
||||
return null;
|
||||
if (refType.isPrimitive()) {
|
||||
return TargetType.toPrimitive(refType);
|
||||
}
|
||||
|
||||
var params = refType.getParaList().stream().map(type -> {
|
||||
var res = convert(type, generics);
|
||||
if (res == null) res = new TargetRefType("java.lang.Void");
|
||||
return res;
|
||||
}).toList();
|
||||
|
||||
var params = refType.getParaList().stream().map(type -> convert(type, generics)).toList();
|
||||
if (name.matches("Fun\\d+\\$\\$")) { // TODO This seems like a bad idea
|
||||
var className = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params));
|
||||
if (!usedFunNSuperTypes.contains(params.size())) {
|
||||
|
@ -297,7 +297,7 @@ public abstract class GenerateGenerics {
|
||||
|
||||
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver) {
|
||||
if (expressionReceiver.expr instanceof This) {
|
||||
var optMethod = astToTargetAST.findMethod(owner, methodCall.name, methodCall.getArgumentList());
|
||||
var optMethod = astToTargetAST.findMethod(owner, methodCall.name, methodCall.signatureArguments().stream().map(astToTargetAST::convert).toList());
|
||||
if (optMethod.isEmpty()) return;
|
||||
var method2 = optMethod.get();
|
||||
System.out.println("In: " + method.getName() + " Method: " + method2.getName());
|
||||
|
@ -4,13 +4,15 @@ import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.PrimitiveMethodsGenerator;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
import de.dhbwstuttgart.target.tree.MethodParameter;
|
||||
import de.dhbwstuttgart.target.tree.expression.*;
|
||||
import de.dhbwstuttgart.target.tree.type.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import javax.swing.text.html.Option;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
@ -169,67 +171,42 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
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;
|
||||
Optional<Method> findMethod(JavaClassName className, String name, List<TargetType> args) {
|
||||
return converter.findMethod(converter.compiler.getClass(className), name, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MethodCall methodCall) {
|
||||
var receiverType = converter.convert(methodCall.receiver.getType());
|
||||
var isFunNType = receiverType instanceof TargetFunNType;
|
||||
|
||||
var returnType = isFunNType ? TargetType.Object : converter.convert(methodCall.signature.get(methodCall.signature.size() - 1));
|
||||
var receiverName = new JavaClassName(converter.convert(methodCall.receiver.getType()).name());
|
||||
var argList = methodCall.signature.stream().map(converter::convert).toList();
|
||||
argList = argList.subList(0, argList.size() - 1);
|
||||
|
||||
Method foundMethod = null;
|
||||
var isStatic = false;
|
||||
var isInterface = true;
|
||||
var signature = methodCall.signatureArguments().stream().map(converter::convert).toList();
|
||||
|
||||
var receiverClass = converter.currentClass;
|
||||
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver && expressionReceiver.expr instanceof This) {
|
||||
var thisMethod = converter.findMethod(converter.currentClass, methodCall.name, methodCall.arglist);
|
||||
if (thisMethod.isEmpty()) {
|
||||
foundMethod = findMethod(converter.currentClass.getSuperClass().getName(), methodCall.name, argList);
|
||||
}
|
||||
} else {
|
||||
foundMethod = findMethod(receiverName, methodCall.name, argList);
|
||||
var thisMethod = converter.findMethod(converter.currentClass, methodCall.name, signature);
|
||||
foundMethod = thisMethod.orElseGet(() -> findMethod(converter.currentClass.getSuperClass().getName(), methodCall.name, signature).orElseThrow());
|
||||
} else if (!isFunNType) {
|
||||
receiverClass = converter.compiler.getClass(receiverName);
|
||||
foundMethod = findMethod(receiverName, methodCall.name, signature).orElseThrow();
|
||||
}
|
||||
|
||||
if (foundMethod != null) {
|
||||
returnType = TargetType.toTargetType(foundMethod.getReturnType());
|
||||
argList = Stream.of(foundMethod.getParameterTypes()).map(TargetType::toTargetType).toList();
|
||||
if (!isFunNType) {
|
||||
returnType = converter.convert(foundMethod.getReturnType());
|
||||
argList = foundMethod.getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType())).toList();
|
||||
isStatic = Modifier.isStatic(foundMethod.modifier);
|
||||
isInterface = receiverClass.isInterface();
|
||||
}
|
||||
|
||||
result = new TargetMethodCall(converter.convert(methodCall.getType()), returnType, argList, converter.convert(methodCall.receiver), methodCall.getArgumentList().getArguments().stream().map(converter::convert).toList(), receiverType, methodCall.name, false, isFunNType);
|
||||
result = new TargetMethodCall(converter.convert(methodCall.getType()), returnType, argList, converter.convert(methodCall.receiver), methodCall.getArgumentList().getArguments().stream().map(converter::convert).toList(), receiverType, methodCall.name, isStatic, isInterface);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,7 @@
|
||||
package de.dhbwstuttgart.target.tree.type;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
|
||||
public sealed interface TargetType
|
||||
permits TargetExtendsWildcard, TargetGenericType, TargetSpecializedType, TargetSuperWildcard, TargetPrimitiveType {
|
||||
|
||||
@ -37,6 +39,20 @@ public sealed interface TargetType
|
||||
return type;
|
||||
}
|
||||
|
||||
static TargetType toPrimitive(RefType type) {
|
||||
return switch(type.getName().toString()) {
|
||||
case "java.lang.Boolean" -> boolean_;
|
||||
case "java.lang.Character" -> char_;
|
||||
case "java.lang.Byte" -> byte_;
|
||||
case "java.lang.Short" -> short_;
|
||||
case "java.lang.Integer" -> int_;
|
||||
case "java.lang.Long" -> long_;
|
||||
case "java.lang.Float" -> float_;
|
||||
case "java.lang.Double" -> double_;
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
static TargetType toTargetType(Class<?> clazz) {
|
||||
if (clazz.isPrimitive()) {
|
||||
if (clazz.equals(boolean.class)) return boolean_;
|
||||
|
@ -47,7 +47,7 @@ public class TestCodegen {
|
||||
var result = new HashMap<String, Class<?>>();
|
||||
for (var file : filenames) {
|
||||
var sourceFile = compiler.sourceFiles.get(file);
|
||||
var converter = new ASTToTargetAST(resultSet, sourceFile, classLoader);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, sourceFile, classLoader);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
result.putAll(classes.stream().map(cli -> {
|
||||
@ -86,7 +86,7 @@ public class TestCodegen {
|
||||
var resultSet = compiler.typeInference();
|
||||
|
||||
var sourceFile = compiler.sourceFiles.get(file);
|
||||
var converter = new ASTToTargetAST(resultSet, sourceFile, classLoader);
|
||||
var converter = new ASTToTargetAST(compiler, resultSet, sourceFile, classLoader);
|
||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||
|
||||
var result = classes.stream().map(cli -> {
|
||||
|
Loading…
Reference in New Issue
Block a user