forked from JavaTX/JavaCompilerCore
Fixed Bugs 159, 162 and 163
This commit is contained in:
parent
857d63322e
commit
3c36c61077
@ -248,6 +248,10 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
} else {
|
||||
assign.rightSide.accept(this);
|
||||
}
|
||||
|
||||
statement = new AssignStmt(assign.rightSide);
|
||||
isBinaryExp = statement.isExprBinary();
|
||||
|
||||
if (isBinaryExp) {
|
||||
BinaryExpr binary = (BinaryExpr) assign.rightSide;
|
||||
String binaryType = getResolvedType(binary.getType());
|
||||
@ -290,6 +294,11 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
needDUP = true;
|
||||
|
||||
binary.lexpr.accept(this);
|
||||
|
||||
if(lexpType.equals(Type.getInternalName(String.class))) {
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class), "append",
|
||||
"(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
|
||||
}
|
||||
|
||||
if (!lexpType.equals(rexpType) && !lexpType.equals(largerType))
|
||||
doCast(lexpType, largerType);
|
||||
@ -298,7 +307,10 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
needDUP = true;
|
||||
|
||||
binary.rexpr.accept(this);
|
||||
|
||||
if(rexpType.equals(Type.getInternalName(String.class))) {
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class), "append",
|
||||
"(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
|
||||
}
|
||||
isParentBinary = false;
|
||||
|
||||
if (!lexpType.equals(rexpType) && !rexpType.equals(largerType))
|
||||
@ -383,7 +395,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
mv.visitInsn(Opcodes.I2F);
|
||||
}
|
||||
break;
|
||||
// braucht man eigentlic nicht, muss getestet werden
|
||||
// braucht man eigentlich nicht, muss getestet werden
|
||||
case "java/lang/String":
|
||||
if (sourceType.equals(Type.getInternalName(Double.class))) {
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "valueOf",
|
||||
@ -566,6 +578,10 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
case "java/lang/Float":
|
||||
mv.visitInsn(Opcodes.FADD);
|
||||
break;
|
||||
case "java/lang/String":
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;",
|
||||
false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -905,14 +921,15 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
mDesc, isInterface);
|
||||
}
|
||||
|
||||
// TODO: if called method is apply (from FI) then generate BC-instruction "CHECKCAST"
|
||||
|
||||
if(methodRefl != null && !methodRefl.getReturnType().isPrimitive()) {
|
||||
if(methodRefl.getReturnType().equals(Object.class)) {
|
||||
helper.createCheckCast(methodCall,mv);
|
||||
}
|
||||
if(isBinaryExp)
|
||||
if(isBinaryExp) {
|
||||
doUnboxing(getResolvedType(methodCall.getType()));
|
||||
|
||||
}
|
||||
} else if(receiverName.contains("$$") && !methCallType.equals(Type.getInternalName(Object.class))) {
|
||||
helper.createCheckCast(methodCall,mv);
|
||||
}
|
||||
@ -1229,11 +1246,11 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
// Unboxing: RefType -> prim
|
||||
public void doUnboxing(String type) {
|
||||
switch (type) {
|
||||
case "java/lang/String":
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class), "append",
|
||||
"(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
|
||||
|
||||
break;
|
||||
// case "java/lang/String":
|
||||
// mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class), "append",
|
||||
// "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
|
||||
//
|
||||
// break;
|
||||
case "java/lang/Boolean":
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
|
||||
break;
|
||||
@ -1330,10 +1347,10 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
// Boxing: prim -> RefType
|
||||
public void doBoxing(String type) {
|
||||
switch (type) {
|
||||
case "java/lang/String":
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;",
|
||||
false);
|
||||
break;
|
||||
// case "java/lang/String":
|
||||
// mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;",
|
||||
// false);
|
||||
// break;
|
||||
case "java/lang/Boolean":
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
|
||||
break;
|
||||
|
@ -32,6 +32,7 @@ import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.ParameterList;
|
||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
||||
@ -98,23 +99,62 @@ public class MethodCallHelper {
|
||||
public String getDesc(String className) throws NotInCurrentPackageException, NotFoundException {
|
||||
String name = methCall.name;
|
||||
ClassOrInterface clazz = getClassFromCurrPkg(className);
|
||||
|
||||
String retType = getResolvedType(methCall.getType());
|
||||
ArrayList<String> params = getTypes(methCall.arglist.getArguments());
|
||||
|
||||
Map<String, String> genAndBoundsClass = getGenericsAndBounds(clazz.getGenerics());
|
||||
modifyGenAndBounds(genAndBoundsClass);
|
||||
for (Method m : clazz.getMethods()) {
|
||||
if (name.equals(m.getName())) {
|
||||
Map<String, String> genAndBoundsMethod = getGenericsAndBoundsMethod(m.getGenerics());
|
||||
modifyGenAndBounds(genAndBoundsMethod);
|
||||
boolean hasGen = hasGen(m, genAndBoundsClass);
|
||||
NormalMethod nm = new NormalMethod(m, (HashMap<String, String>) genAndBoundsClass,
|
||||
(HashMap<String, String>) genAndBoundsMethod, hasGen);
|
||||
return nm.accept(new DescriptorToString(resultSet));
|
||||
if (name.equals(m.getName()) && retType.equals(getResolvedType(m.getReturnType()))) {
|
||||
ArrayList<String> paramsOfM = getTypes(m.getParameterList());
|
||||
if(areEquals(params,paramsOfM)) {
|
||||
Map<String, String> genAndBoundsMethod = getGenericsAndBoundsMethod(m.getGenerics());
|
||||
modifyGenAndBounds(genAndBoundsMethod);
|
||||
boolean hasGen = hasGen(m, genAndBoundsClass);
|
||||
NormalMethod nm = new NormalMethod(m, (HashMap<String, String>) genAndBoundsClass,
|
||||
(HashMap<String, String>) genAndBoundsMethod, hasGen);
|
||||
return nm.accept(new DescriptorToString(resultSet));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotFoundException("Method " + name + " is not found");
|
||||
}
|
||||
|
||||
private boolean areEquals(ArrayList<String> params, ArrayList<String> paramsOfM) {
|
||||
if(params.size() != paramsOfM.size())
|
||||
return false;
|
||||
|
||||
for(String t : params) {
|
||||
for(String t2 : paramsOfM) {
|
||||
if(!t.equals(t2))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private ArrayList<String> getTypes(ParameterList parameterList) {
|
||||
Iterator<FormalParameter> itr = parameterList.iterator();
|
||||
ArrayList<String> typeList = new ArrayList<>();
|
||||
while (itr.hasNext()) {
|
||||
FormalParameter fp = itr.next();
|
||||
String t = getResolvedType(fp.getType());
|
||||
typeList.add(t);
|
||||
}
|
||||
|
||||
return typeList;
|
||||
}
|
||||
|
||||
private ArrayList<String> getTypes(List<Expression> arguments) {
|
||||
ArrayList<String> types = new ArrayList<>();
|
||||
for(int i = 0; i<arguments.size(); ++i) {
|
||||
String t = getResolvedType(arguments.get(i).getType());
|
||||
types.add(t);
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
private boolean hasGen(Method m, Map<String, String> genericsAndBounds) {
|
||||
String retType = resultSet.resolveType(m.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
|
||||
/*Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist*/
|
||||
|
@ -1,7 +1,11 @@
|
||||
public class Id {
|
||||
|
||||
id(b){
|
||||
return b;
|
||||
}
|
||||
// id(b){
|
||||
// return b;
|
||||
// }
|
||||
id2 = x -> x;
|
||||
|
||||
id3 (x) {
|
||||
return id2.apply(x)
|
||||
}
|
||||
|
||||
|
@ -1,23 +1,24 @@
|
||||
import java.lang.String;
|
||||
import java.lang.Integer;
|
||||
import java.lang.Double;
|
||||
import java.lang.Boolean;
|
||||
import java.lang.Boolean;
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
public class OL {
|
||||
|
||||
m(x) { return x + x; }
|
||||
/*
|
||||
|
||||
m(Boolean x) { return x; }
|
||||
|
||||
|
||||
m(x) {
|
||||
x.add(1);
|
||||
// if the class contains just this method, then correct BC will be generated.
|
||||
// But if another methods are contained then the generated BC is not correct
|
||||
/* m(x) {
|
||||
//x.add(1);
|
||||
x.addAll(x);
|
||||
return x;
|
||||
}
|
||||
*/
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
public class OLMain {
|
||||
|
Loading…
Reference in New Issue
Block a user