diff --git a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/javasyntax/declaration/ClassFileFormalParameter.java b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/javasyntax/declaration/ClassFileFormalParameter.java new file mode 100644 index 00000000..ccab6a00 --- /dev/null +++ b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/javasyntax/declaration/ClassFileFormalParameter.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2008-2019 Emmanuel Dupuy. + * This project is distributed under the GPLv3 license. + * This is a Copyleft license that gives the user the right to use, + * copy and modify the code freely for non-commercial purposes. + */ + +package org.jd.core.v1.service.converter.classfiletojavasyntax.model.javasyntax.declaration; + +import org.jd.core.v1.model.javasyntax.declaration.FormalParameter; +import org.jd.core.v1.model.javasyntax.reference.BaseAnnotationReference; +import org.jd.core.v1.model.javasyntax.type.Type; +import org.jd.core.v1.service.converter.classfiletojavasyntax.model.localvariable.AbstractLocalVariable; +import org.jd.core.v1.service.converter.classfiletojavasyntax.model.localvariable.LocalVariableReference; + + +public class ClassFileFormalParameter extends FormalParameter implements LocalVariableReference { + protected AbstractLocalVariable localVariable; + + public ClassFileFormalParameter(AbstractLocalVariable localVariable) { + super(null, null); + this.localVariable = localVariable; + } + + public ClassFileFormalParameter(AbstractLocalVariable localVariable, boolean varargs) { + super(null, varargs, null); + this.localVariable = localVariable; + } + + public ClassFileFormalParameter(BaseAnnotationReference annotationReferences, AbstractLocalVariable localVariable, boolean varargs) { + super(annotationReferences, null, varargs, null); + this.localVariable = localVariable; + } + + public Type getType() { + return localVariable.getType(); + } + + public String getName() { + return localVariable.getName(); + } + + public void setName(String name) { + localVariable.setName(name); + } + + @Override + public AbstractLocalVariable getLocalVariable() { + return localVariable; + } + + @Override + public void setLocalVariable(AbstractLocalVariable localVariable) { + this.localVariable = localVariable; + } + + @Override + public String toString() { + String s = "ClassFileFormalParameter{"; + + if (annotationReferences != null) + s += annotationReferences + " "; + + Type type = localVariable.getType(); + + if (varargs) + s += type.createType(type.getDimension()-1) + "... "; + else + s += type + " "; + + return s + localVariable.getName() + "}"; + } +} diff --git a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/javasyntax/expression/ClassFileLocalVariableReferenceExpression.java b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/javasyntax/expression/ClassFileLocalVariableReferenceExpression.java index bf0da27b..1a05ce35 100644 --- a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/javasyntax/expression/ClassFileLocalVariableReferenceExpression.java +++ b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/javasyntax/expression/ClassFileLocalVariableReferenceExpression.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2019 Emmanuel Dupuy. + * Copyright (c) 2008, 2019 Emmanuel Dupuy. * This project is distributed under the GPLv3 license. * This is a Copyleft license that gives the user the right to use, * copy and modify the code freely for non-commercial purposes. @@ -10,8 +10,9 @@ import org.jd.core.v1.model.javasyntax.expression.LocalVariableReferenceExpression; import org.jd.core.v1.model.javasyntax.type.Type; import org.jd.core.v1.service.converter.classfiletojavasyntax.model.localvariable.AbstractLocalVariable; +import org.jd.core.v1.service.converter.classfiletojavasyntax.model.localvariable.LocalVariableReference; -public class ClassFileLocalVariableReferenceExpression extends LocalVariableReferenceExpression { +public class ClassFileLocalVariableReferenceExpression extends LocalVariableReferenceExpression implements LocalVariableReference { protected AbstractLocalVariable localVariable; public ClassFileLocalVariableReferenceExpression(int lineNumber, AbstractLocalVariable localVariable) { @@ -30,10 +31,12 @@ public String getName() { return localVariable.getName(); } + @Override public AbstractLocalVariable getLocalVariable() { return localVariable; } + @Override public void setLocalVariable(AbstractLocalVariable localVariable) { this.localVariable = localVariable; } diff --git a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/AbstractLocalVariable.java b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/AbstractLocalVariable.java index b7a84e3b..ec4424d5 100644 --- a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/AbstractLocalVariable.java +++ b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/AbstractLocalVariable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2019 Emmanuel Dupuy. + * Copyright (c) 2008, 2019 Emmanuel Dupuy. * This project is distributed under the GPLv3 license. * This is a Copyleft license that gives the user the right to use, * copy and modify the code freely for non-commercial purposes. @@ -20,7 +20,7 @@ public abstract class AbstractLocalVariable implements LocalVariable { protected int toOffset; protected String name; protected int dimension; - protected DefaultList<ClassFileLocalVariableReferenceExpression> references = new DefaultList<>(); + protected DefaultList<LocalVariableReference> references = new DefaultList<>(); public AbstractLocalVariable(int index, int offset, int dimension) { this.declared = (offset == 0); @@ -106,9 +106,13 @@ public void setToOffset(int offset) { @Override public String getName() { return name; } + public void setName(String name) { + this.name = name; + } + public int getDimension() { return dimension; } - public DefaultList<ClassFileLocalVariableReferenceExpression> getReferences() { + public DefaultList<LocalVariableReference> getReferences() { return references; } @@ -121,8 +125,7 @@ public DefaultList<ClassFileLocalVariableReferenceExpression> getReferences() { public abstract void rightReduce(Type otherType); public abstract void rightReduce(AbstractLocalVariable other); - @Override - public void addReference(ClassFileLocalVariableReferenceExpression reference) { + public void addReference(LocalVariableReference reference) { references.add(reference); } } diff --git a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/Frame.java b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/Frame.java index a86eefe4..0c310215 100644 --- a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/Frame.java +++ b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/Frame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2019 Emmanuel Dupuy. + * Copyright (c) 2008, 2019 Emmanuel Dupuy. * This project is distributed under the GPLv3 license. * This is a Copyleft license that gives the user the right to use, * copy and modify the code freely for non-commercial purposes. @@ -98,12 +98,34 @@ public void mergeLocalVariable(AbstractLocalVariable lv) { } } } else if (lv != alvToMerge) { - for (ClassFileLocalVariableReferenceExpression reference : alvToMerge.getReferences()) { + for (LocalVariableReference reference : alvToMerge.getReferences()) { reference.setLocalVariable(lv); } lv.getReferences().addAll(alvToMerge.getReferences()); lv.setFromOffset(alvToMerge.getFromOffset()); + + if (!lv.isAssignable(alvToMerge)) { + Type type = lv.getType(); + Type alvToMergeType = alvToMerge.getType(); + + assert (type.isPrimitive() == alvToMergeType.isPrimitive()) && (type.isObject() == alvToMergeType.isObject()) && (type.isGeneric() == alvToMergeType.isGeneric()); + + if (type.isPrimitive()) { + if (alvToMerge.isAssignable(lv)) { + ((PrimitiveLocalVariable)lv).setPrimitiveType((PrimitiveType)type); + } else { + ((PrimitiveLocalVariable)lv).setPrimitiveType(PrimitiveType.TYPE_INT); + } + } else if (type.isObject()) { + if (alvToMerge.isAssignable(lv)) { + ((ObjectLocalVariable)lv).setObjectType((ObjectType)type); + } else { + ((ObjectLocalVariable)lv).setObjectType(ObjectType.TYPE_OBJECT); + } + } + } + localVariableArray[index] = alvToMerge.getNext(); } } @@ -474,8 +496,7 @@ protected void updateForStatement( } @SuppressWarnings("unchecked") - protected void updateForStatement( - HashSet<AbstractLocalVariable> variablesToDeclare, HashSet<AbstractLocalVariable> foundVariables, ClassFileForStatement forStatement, Expressions init) { + protected void updateForStatement(HashSet<AbstractLocalVariable> variablesToDeclare, HashSet<AbstractLocalVariable> foundVariables, ClassFileForStatement forStatement, Expressions init) { DefaultList<BinaryOperatorExpression> boes = new DefaultList<>(); DefaultList<AbstractLocalVariable> localVariables = new DefaultList<>(); diff --git a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/LocalVariable.java b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/LocalVariable.java index 51531c82..eecb5361 100644 --- a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/LocalVariable.java +++ b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/LocalVariable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2019 Emmanuel Dupuy. + * Copyright (c) 2008, 2019 Emmanuel Dupuy. * This project is distributed under the GPLv3 license. * This is a Copyleft license that gives the user the right to use, * copy and modify the code freely for non-commercial purposes. @@ -8,7 +8,6 @@ package org.jd.core.v1.service.converter.classfiletojavasyntax.model.localvariable; import org.jd.core.v1.model.javasyntax.type.Type; -import org.jd.core.v1.service.converter.classfiletojavasyntax.model.javasyntax.expression.ClassFileLocalVariableReferenceExpression; public interface LocalVariable { @@ -16,7 +15,5 @@ public interface LocalVariable { String getName(); - void addReference(ClassFileLocalVariableReferenceExpression reference); - void accept(LocalVariableVisitor visitor); } diff --git a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/LocalVariableReference.java b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/LocalVariableReference.java new file mode 100644 index 00000000..cc141b7f --- /dev/null +++ b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/LocalVariableReference.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2008, 2019 Emmanuel Dupuy. + * This project is distributed under the GPLv3 license. + * This is a Copyleft license that gives the user the right to use, + * copy and modify the code freely for non-commercial purposes. + */ + +package org.jd.core.v1.service.converter.classfiletojavasyntax.model.localvariable; + + +public interface LocalVariableReference { + AbstractLocalVariable getLocalVariable(); + + void setLocalVariable(AbstractLocalVariable localVariable); +} diff --git a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/LocalVariableSet.java b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/LocalVariableSet.java index 344aeffc..93d00f2c 100644 --- a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/LocalVariableSet.java +++ b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/LocalVariableSet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2019 Emmanuel Dupuy. + * Copyright (c) 2008, 2019 Emmanuel Dupuy. * This project is distributed under the GPLv3 license. * This is a Copyleft license that gives the user the right to use, * copy and modify the code freely for non-commercial purposes. @@ -95,6 +95,23 @@ public AbstractLocalVariable remove(int index, int offset) { return null; } + public AbstractLocalVariable get(int index, int offset) { + if (index < array.length) { + AbstractLocalVariable lv = array[index]; + + while (lv != null) { + if (lv.fromOffset <= offset) { + return lv; + } + + assert lv != lv.getNext(); + lv = lv.getNext(); + } + } + + return null; + } + public boolean isEmpty() { return size == 0; } diff --git a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/ObjectLocalVariable.java b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/ObjectLocalVariable.java index a762dd81..188a571a 100644 --- a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/ObjectLocalVariable.java +++ b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/ObjectLocalVariable.java @@ -76,6 +76,16 @@ public Type getType() { return (dimension == 0) ? toType : arrayType; } + public void setObjectType(ObjectType type) { + dimension = type.getDimension(); + + if (dimension == 0) { + this.fromType = this.toType = (ObjectType)type; + } else { + this.arrayType = type; + } + } + @Override public boolean isAssignable(AbstractLocalVariable other) { if (other.getClass() == ObjectLocalVariable.class) { diff --git a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/PrimitiveLocalVariable.java b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/PrimitiveLocalVariable.java index 525308f9..ec682a67 100644 --- a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/PrimitiveLocalVariable.java +++ b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/model/localvariable/PrimitiveLocalVariable.java @@ -57,6 +57,11 @@ public Type getType() { return PrimitiveTypeUtil.getPrimitiveType(flags, dimension); } + public void setPrimitiveType(PrimitiveType type) { + assert type.getDimension() == 0; + this.flags = type.getFlags(); + } + @Override public boolean isAssignable(AbstractLocalVariable other) { if ((other.getDimension() == 0) && (other.getClass() == PrimitiveLocalVariable.class)) { diff --git a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/util/ByteCodeParser.java b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/util/ByteCodeParser.java index ee798435..ce821203 100644 --- a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/util/ByteCodeParser.java +++ b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/util/ByteCodeParser.java @@ -658,25 +658,25 @@ public void parse(BasicBlock basicBlock, Statements<Statement> statements, Defau case 161: // IF_ICMPLT expression2 = stack.pop(); expression1 = stack.pop(); - stack.push(newComparisonOperatorExpression(lineNumber, expression1, basicBlock.mustInverseCondition() ? ">=" : "<", expression2, 8)); + stack.push(newNumericComparisonOperatorExpression(lineNumber, expression1, basicBlock.mustInverseCondition() ? ">=" : "<", expression2, 8)); offset += 2; // Skip branch offset break; case 162: // IF_ICMPGE expression2 = stack.pop(); expression1 = stack.pop(); - stack.push(newComparisonOperatorExpression(lineNumber, expression1, basicBlock.mustInverseCondition() ? "<" : ">=", expression2, 8)); + stack.push(newNumericComparisonOperatorExpression(lineNumber, expression1, basicBlock.mustInverseCondition() ? "<" : ">=", expression2, 8)); offset += 2; // Skip branch offset break; case 163: // IF_ICMPGT expression2 = stack.pop(); expression1 = stack.pop(); - stack.push(newComparisonOperatorExpression(lineNumber, expression1, basicBlock.mustInverseCondition() ? "<=" : ">", expression2, 8)); + stack.push(newNumericComparisonOperatorExpression(lineNumber, expression1, basicBlock.mustInverseCondition() ? "<=" : ">", expression2, 8)); offset += 2; // Skip branch offset break; case 164: // IF_ICMPLE expression2 = stack.pop(); expression1 = stack.pop(); - stack.push(newComparisonOperatorExpression(lineNumber, expression1, basicBlock.mustInverseCondition() ? ">" : "<=", expression2, 8)); + stack.push(newNumericComparisonOperatorExpression(lineNumber, expression1, basicBlock.mustInverseCondition() ? ">" : "<=", expression2, 8)); offset += 2; // Skip branch offset break; case 168: // JSR @@ -736,19 +736,19 @@ public void parse(BasicBlock basicBlock, Statements<Statement> statements, Defau BaseExpression parameters = getParameters(statements, stack, descriptor); Type returnedType = signatureParser.parseReturnedType(descriptor); - if (!statements.isEmpty() && (opcode == 184)) { // INVOKESTATIC - Statement last = statements.getLast(); - - if (last.getClass() == ExpressionStatement.class) { - Expression expression = ((ExpressionStatement)last).getExpression(); - - if ((expression.getLineNumber() == lineNumber) && (expression.getType().equals(ot))) { - statements.removeLast(); - stack.push(expression); - opcode = 0; - } - } - } +// if (!statements.isEmpty() && (opcode == 184)) { // INVOKESTATIC +// Statement last = statements.getLast(); +// +// if (last.getClass() == ExpressionStatement.class) { +// Expression expression = ((ExpressionStatement)last).getExpression(); +// +// if ((expression.getLineNumber() == lineNumber) && (expression.getType().equals(ot))) { +// statements.removeLast(); +// stack.push(expression); +// opcode = 0; +// } +// } +// } if (opcode == 184) { // INVOKESTATIC expression1 = new MethodInvocationExpression(lineNumber, returnedType, new ObjectTypeReferenceExpression(lineNumber, ot), typeName, name, descriptor, parameters); @@ -1797,6 +1797,42 @@ private static Expression newComparisonOperatorExpression(int lineNumber, Expres return new BinaryOperatorExpression(lineNumber, TYPE_BOOLEAN, leftExpression, operator, rightExpression, priority); } + private static Expression newNumericComparisonOperatorExpression(int lineNumber, Expression leftExpression, String operator, Expression rightExpression, int priority) { + Type leftType = leftExpression.getType(); + Type rightType = rightExpression.getType(); + Type type; + + if (leftType == rightType) { + type = leftType; + } else { + type = PrimitiveTypeUtil.getCommonPrimitiveType((PrimitiveType)leftType, (PrimitiveType)rightType); + if (type == null) { + type = leftType; + } + } + + if ((((PrimitiveType)type).getFlags() & (FLAG_CHAR|FLAG_BYTE|FLAG_SHORT|FLAG_INT)) != 0) { + if (leftExpression.getClass() == ClassFileLocalVariableReferenceExpression.class) { + ClassFileLocalVariableReferenceExpression lvre = (ClassFileLocalVariableReferenceExpression) leftExpression; + + if (lvre.getLocalVariable().getClass() == PrimitiveLocalVariable.class) { + PrimitiveLocalVariable plv = (PrimitiveLocalVariable) lvre.getLocalVariable(); + plv.leftReduce(type); + } + } + if (rightExpression.getClass() == ClassFileLocalVariableReferenceExpression.class) { + ClassFileLocalVariableReferenceExpression lvre = (ClassFileLocalVariableReferenceExpression) rightExpression; + + if (lvre.getLocalVariable().getClass() == PrimitiveLocalVariable.class) { + PrimitiveLocalVariable plv = (PrimitiveLocalVariable) lvre.getLocalVariable(); + plv.leftReduce(type); + } + } + } + + return new BinaryOperatorExpression(lineNumber, TYPE_BOOLEAN, leftExpression, operator, rightExpression, priority); + } + private static Expression newPreArithmeticOperatorExpression(int lineNumber, String operator, Expression expression) { reduceIntegerLocalVariableType(expression); return new PreOperatorExpression(lineNumber, operator, expression); diff --git a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/util/LocalVariableMaker.java b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/util/LocalVariableMaker.java index 641d0fd9..c4c9c2f2 100644 --- a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/util/LocalVariableMaker.java +++ b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/util/LocalVariableMaker.java @@ -22,6 +22,7 @@ import org.jd.core.v1.model.javasyntax.type.PrimitiveType; import org.jd.core.v1.model.javasyntax.type.Type; import org.jd.core.v1.service.converter.classfiletojavasyntax.model.javasyntax.declaration.ClassFileConstructorOrMethodDeclaration; +import org.jd.core.v1.service.converter.classfiletojavasyntax.model.javasyntax.declaration.ClassFileFormalParameter; import org.jd.core.v1.service.converter.classfiletojavasyntax.model.javasyntax.expression.ClassFileLocalVariableReferenceExpression; import org.jd.core.v1.service.converter.classfiletojavasyntax.model.localvariable.*; import org.jd.core.v1.service.converter.classfiletojavasyntax.visitor.*; @@ -143,7 +144,7 @@ public LocalVariableMaker(ObjectTypeMaker objectTypeMaker, SignatureParser signa for (int parameterIndex=0, variableIndex=firstVariableIndex; parameterIndex<=lastParameterIndex; parameterIndex++, variableIndex++) { AbstractLocalVariable lv = localVariableSet.root(variableIndex); - formalParameters.add(new FormalParameter(lv.getType(), varargs && (parameterIndex==lastParameterIndex), lv.getName())); + formalParameters.add(new ClassFileFormalParameter(lv, varargs && (parameterIndex==lastParameterIndex))); if (PrimitiveType.TYPE_LONG.equals(lv.getType()) || PrimitiveType.TYPE_DOUBLE.equals(lv.getType())) { variableIndex++; @@ -161,7 +162,7 @@ public LocalVariableMaker(ObjectTypeMaker objectTypeMaker, SignatureParser signa Annotations invisibles = ((invisiblesArray == null) || (invisiblesArray.length <= parameterIndex)) ? null : invisiblesArray[parameterIndex]; BaseAnnotationReference annotationReferences = annotationConverter.convert(visibles, invisibles); - formalParameters.add(new FormalParameter(annotationReferences, lv.getType(), varargs && (parameterIndex==lastParameterIndex), lv.getName())); + formalParameters.add(new ClassFileFormalParameter(annotationReferences, lv, varargs && (parameterIndex==lastParameterIndex))); if (PrimitiveType.TYPE_LONG.equals(lv.getType()) || PrimitiveType.TYPE_DOUBLE.equals(lv.getType())) { variableIndex++; @@ -327,10 +328,18 @@ public AbstractLocalVariable getLocalVariable(int index, int offset) { } public AbstractLocalVariable getPrimitiveLocalVariableInAssignment(int index, int offset, Expression value) { - AbstractLocalVariable lv = localVariableSet.remove(index, offset); + AbstractLocalVariable lv = localVariableSet.get(index, offset); if (lv == null) { lv = currentFrame.getLocalVariable(index); + } else { + AbstractLocalVariable lv2 = currentFrame.getLocalVariable(index); + + if ((lv2 != null) && (lv.getFromOffset() < lv2.getFromOffset())) { + lv = lv2; + } else { + localVariableSet.remove(index, offset); + } } if (lv == null) { @@ -379,11 +388,19 @@ public AbstractLocalVariable getPrimitiveLocalVariableInAssignment(int index, in } public AbstractLocalVariable getObjectLocalVariableInAssignment(int index, int offset, Expression value) { - AbstractLocalVariable lv = localVariableSet.remove(index, offset); + AbstractLocalVariable lv = localVariableSet.get(index, offset); Class valueClass = value.getClass(); if (lv == null) { lv = currentFrame.getLocalVariable(index); + } else { + AbstractLocalVariable lv2 = currentFrame.getLocalVariable(index); + + if ((lv2 != null) && (lv.getFromOffset() < lv2.getFromOffset())) { + lv = lv2; + } else { + localVariableSet.remove(index, offset); + } } if (lv == null) { @@ -453,21 +470,15 @@ public AbstractLocalVariable getExceptionLocalVariable(int index, int offset, Ob if (index == -1) { currentFrame.setExceptionLocalVariable(lv = new ObjectLocalVariable(objectTypeMaker, index, offset, type, null, true)); } else { - lv = currentFrame.getLocalVariable(index); + lv = localVariableSet.remove(index, offset); if (lv == null) { - lv = localVariableSet.remove(index, offset); - - if (lv == null) { - lv = new ObjectLocalVariable(objectTypeMaker, index, offset, type, null, true); - } else { - lv.setDeclared(true); - } - - currentFrame.addLocalVariable(lv); + lv = new ObjectLocalVariable(objectTypeMaker, index, offset, type, null, true); } else { lv.setDeclared(true); } + + currentFrame.addLocalVariable(lv); } return lv; diff --git a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/visitor/InitInnerClassVisitor.java b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/visitor/InitInnerClassVisitor.java index 0277dd60..7d2b3bdb 100644 --- a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/visitor/InitInnerClassVisitor.java +++ b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/visitor/InitInnerClassVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2019 Emmanuel Dupuy. + * Copyright (c) 2008, 2019 Emmanuel Dupuy. * This project is distributed under the GPLv3 license. * This is a Copyleft license that gives the user the right to use, * copy and modify the code freely for non-commercial purposes. @@ -134,7 +134,7 @@ public void visit(ConstructorDeclaration declaration) { int size = list.size(); list.subList(size - count, size).clear(); } - } else { + } else if (outerType != null) { cfcd.setFormalParameters(null); } } @@ -510,10 +510,8 @@ public void visit(LocalVariableDeclaration declaration) { @Override public void visit(LocalVariableDeclarator declarator) { if (finalLocalVariableNameMap.containsKey(declarator.getName())) { - LocalVariableDeclarator cflvd = (LocalVariableDeclarator)declarator; - fina1 = true; - cflvd.setName(finalLocalVariableNameMap.get(declarator.getName())); + declarator.setName(finalLocalVariableNameMap.get(declarator.getName())); } } } diff --git a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/visitor/RemoveBinaryOpReturnStatementsVisitor.java b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/visitor/RemoveBinaryOpReturnStatementsVisitor.java index 23700f96..d4a6c898 100644 --- a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/visitor/RemoveBinaryOpReturnStatementsVisitor.java +++ b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/visitor/RemoveBinaryOpReturnStatementsVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2019 Emmanuel Dupuy. + * Copyright (c) 2008, 2019 Emmanuel Dupuy. * This project is distributed under the GPLv3 license. * This is a Copyleft license that gives the user the right to use, * copy and modify the code freely for non-commercial purposes. @@ -50,7 +50,7 @@ public void visit(Statements statements) { if (leftExpression.getClass() == ClassFileLocalVariableReferenceExpression.class) { ClassFileLocalVariableReferenceExpression lvr2 = (ClassFileLocalVariableReferenceExpression)leftExpression; - if (lvr1.getLocalVariable() == lvr2.getLocalVariable()) { + if ((lvr1.getLocalVariable() == lvr2.getLocalVariable()) && (lvr1.getLocalVariable().getReferences().size() == 2)) { // Remove synthetic assignment statement statements.remove(statements.size()-2); // Replace synthetic local variable with expression diff --git a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/visitor/UpdateIntegerConstantTypeVisitor.java b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/visitor/UpdateIntegerConstantTypeVisitor.java index 075f115a..767590ca 100644 --- a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/visitor/UpdateIntegerConstantTypeVisitor.java +++ b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/visitor/UpdateIntegerConstantTypeVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2019 Emmanuel Dupuy. + * Copyright (c) 2008, 2019 Emmanuel Dupuy. * This project is distributed under the GPLv3 license. * This is a Copyleft license that gives the user the right to use, * copy and modify the code freely for non-commercial purposes. @@ -333,6 +333,7 @@ protected BaseExpression updateExpressions(List<Type> types, BaseExpression expr case FLAG_BYTE: case FLAG_SHORT: expressions = new CastExpression(type, updatedParameter); + break; } } }