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