diff --git a/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java b/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java index 22c0bf0..a6369f5 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java @@ -42,10 +42,8 @@ public class ClassReference14Processor { ctor.setStringDescriptor("()V"); ctor.setFunctype(InvocationExprent.TYP_INIT); ctor.setDescriptor(MethodDescriptor.parseDescriptor("()V")); - NewExprent newExpr = new NewExprent(new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/NoClassDefFoundError"), new ArrayList<>(), null); newExpr.setConstructor(ctor); - InvocationExprent invCause = new InvocationExprent(); invCause.setName("initCause"); invCause.setClassname("java/lang/NoClassDefFoundError"); @@ -54,18 +52,18 @@ public class ClassReference14Processor { invCause.setInstance(newExpr); invCause.setLstParameters( Collections.singletonList(new VarExprent(2, new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/ClassNotFoundException"), null))); - HANDLER_EXPR = new ExitExprent(ExitExprent.EXIT_THROW, invCause, null, null); } public static void processClassReferences(ClassNode node) { // find the synthetic method Class class$(String) if present - HashMap mapClassMeths = new HashMap<>(); + Map mapClassMeths = new HashMap<>(); mapClassMethods(node, mapClassMeths); if (mapClassMeths.isEmpty()) { return; } - HashSet setFound = new HashSet<>(); + + Set setFound = new HashSet<>(); processClassRec(node, mapClassMeths, setFound); if (!setFound.isEmpty()) { @@ -76,15 +74,11 @@ public class ClassReference14Processor { } } - private static void processClassRec(ClassNode node, - final HashMap mapClassMeths, - final HashSet setFound) { - - final ClassWrapper wrapper = node.getWrapper(); + private static void processClassRec(ClassNode node, Map mapClassMeths, Set setFound) { + ClassWrapper wrapper = node.getWrapper(); // search code for (MethodWrapper meth : wrapper.getMethods()) { - RootStatement root = meth.root; if (root != null) { DirectGraph graph = meth.getOrBuildGraph(); @@ -166,13 +160,10 @@ public class ClassReference14Processor { } } - private static boolean replaceInvocations(Exprent exprent, ClassWrapper wrapper, MethodWrapper meth) { - boolean res = false; while (true) { - boolean found = false; for (Exprent expr : exprent.getAllExprents()) { @@ -195,9 +186,7 @@ public class ClassReference14Processor { return res; } - private static String isClass14Invocation(Exprent exprent, ClassWrapper wrapper, MethodWrapper meth) { - if (exprent.type == Exprent.EXPRENT_FUNCTION) { FunctionExprent fexpr = (FunctionExprent)exprent; if (fexpr.getFuncType() == FunctionExprent.FUNCTION_IIF) { diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java index a296a0d..5b6ae7e 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -647,11 +647,13 @@ public class ClassWriter { descriptor = GenericMain.parseMethodSignature(attr.getSignature()); if (descriptor != null) { long actualParams = md.params.length; - List sigFields = methodWrapper.signatureFields; - if (sigFields != null) { - actualParams = sigFields.stream().filter(Objects::isNull).count(); + List mask = methodWrapper.synthParameters; + if (mask != null) { + actualParams = mask.stream().filter(Objects::isNull).count(); + } + else if (isEnum && init) { + actualParams -= 2; } - else if (isEnum && init) actualParams -= 2; if (actualParams != descriptor.params.size()) { String message = "Inconsistent generic signature in method " + mt.getName() + " " + mt.getDescriptor() + " in " + cl.qualifiedName; DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); @@ -685,12 +687,11 @@ public class ClassWriter { buffer.append(toValidJavaIdentifier(name)); buffer.append('('); - // parameters - List signFields = methodWrapper.signatureFields; + List mask = methodWrapper.synthParameters; int lastVisibleParameterIndex = -1; for (int i = 0; i < md.params.length; i++) { - if (signFields == null || signFields.get(i) == null) { + if (mask == null || mask.get(i) == null) { lastVisibleParameterIndex = i; } } @@ -701,7 +702,7 @@ public class ClassWriter { int start = isEnum && init && !hasDescriptor ? 2 : 0; int params = hasDescriptor ? descriptor.params.size() : md.params.length; for (int i = start; i < params; i++) { - if (hasDescriptor || (signFields == null || signFields.get(i) == null)) { + if (hasDescriptor || mask == null || mask.get(i) == null) { if (!firstParameter) { buffer.append(", "); } diff --git a/src/org/jetbrains/java/decompiler/main/rels/MethodWrapper.java b/src/org/jetbrains/java/decompiler/main/rels/MethodWrapper.java index 4fabf23..51a768d 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/MethodWrapper.java +++ b/src/org/jetbrains/java/decompiler/main/rels/MethodWrapper.java @@ -11,16 +11,17 @@ import org.jetbrains.java.decompiler.struct.StructMethod; import java.util.HashSet; import java.util.List; +import java.util.Set; public class MethodWrapper { public final RootStatement root; public final VarProcessor varproc; public final StructMethod methodStruct; public final CounterContainer counter; - public final HashSet setOuterVarNames = new HashSet<>(); + public final Set setOuterVarNames = new HashSet<>(); public DirectGraph graph; - public List signatureFields; + public List synthParameters; public boolean decompiledWithErrors; public MethodWrapper(RootStatement root, VarProcessor varproc, StructMethod methodStruct, CounterContainer counter) { diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java index b213031..4a77471 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java @@ -28,7 +28,6 @@ import java.util.*; import java.util.Map.Entry; public class NestedClassProcessor { - public void processClass(ClassNode root, ClassNode node) { // hide synthetic lambda content methods if (node.type == ClassNode.CLASS_LAMBDA && !node.lambdaInformation.is_method_reference) { @@ -93,22 +92,18 @@ public class NestedClassProcessor { } MethodWrapper method = parent.getWrapper().getMethods().getWithKey(child.lambdaInformation.content_method_key); - final MethodWrapper enclosingMethod = parent.getWrapper().getMethods().getWithKey(child.enclosingMethod); + MethodWrapper enclosingMethod = parent.getWrapper().getMethods().getWithKey(child.enclosingMethod); MethodDescriptor md_lambda = MethodDescriptor.parseDescriptor(child.lambdaInformation.method_descriptor); - final MethodDescriptor md_content = MethodDescriptor.parseDescriptor(child.lambdaInformation.content_method_descriptor); - - final int vars_count = md_content.params.length - md_lambda.params.length; - // if(vars_count < 0) { // should not happen, but just in case... - // vars_count = 0; - // } + MethodDescriptor md_content = MethodDescriptor.parseDescriptor(child.lambdaInformation.content_method_descriptor); - final boolean is_static_lambda_content = child.lambdaInformation.is_content_method_static; + int vars_count = md_content.params.length - md_lambda.params.length; + boolean is_static_lambda_content = child.lambdaInformation.is_content_method_static; String parent_class_name = parent.getWrapper().getClassStruct().qualifiedName; String lambda_class_name = child.simpleName; - final VarType lambda_class_type = new VarType(lambda_class_name, true); + VarType lambda_class_type = new VarType(lambda_class_name, true); // this pointer if (!is_static_lambda_content && DecompilerContext.getOption(IFernflowerPreferences.LAMBDA_TO_ANONYMOUS_CLASS)) { @@ -116,7 +111,7 @@ public class NestedClassProcessor { method.varproc.setVarName(new VarVersionPair(0, 0), parent.simpleName + ".this"); } - final Map mapNewNames = new HashMap<>(); + Map mapNewNames = new HashMap<>(); enclosingMethod.getOrBuildGraph().iterateExprents(exprent -> { List lst = exprent.getAllExprents(true); @@ -172,7 +167,7 @@ public class NestedClassProcessor { List copy = new ArrayList<>(node.nested); for (ClassNode child : copy) { - if (child.classStruct.hasModifier(CodeConstants.ACC_SYNTHETIC)) { + if (child.classStruct.isSynthetic()) { continue; } @@ -234,19 +229,15 @@ public class NestedClassProcessor { return false; } - private static void computeLocalVarsAndDefinitions(final ClassNode node) { - // local var masks - // class name, constructor descriptor, field mask - final Map>> mapVarMasks = new HashMap<>(); + private static void computeLocalVarsAndDefinitions(ClassNode node) { + // class name -> constructor descriptor -> var to field link + Map>> mapVarMasks = new HashMap<>(); int clTypes = 0; for (ClassNode nd : node.nested) { - if (nd.classStruct.hasModifier(CodeConstants.ACC_SYNTHETIC)) { - continue; - } - if (nd.type != ClassNode.CLASS_LAMBDA && + !nd.classStruct.isSynthetic() && (nd.access & CodeConstants.ACC_STATIC) == 0 && (nd.access & CodeConstants.ACC_INTERFACE) == 0) { clTypes |= nd.type; @@ -263,11 +254,11 @@ public class NestedClassProcessor { } // local var masks - final Map>> mapVarFieldPairs = new HashMap<>(); + Map>> mapVarFieldPairs = new HashMap<>(); if (clTypes != ClassNode.CLASS_MEMBER) { // iterate enclosing class - for (final MethodWrapper method : node.getWrapper().getMethods()) { + for (MethodWrapper method : node.getWrapper().getMethods()) { if (method.root != null) { // neither abstract, nor native method.getOrBuildGraph().iterateExprents(exprent -> { List lst = exprent.getAllExprents(true); @@ -388,34 +379,33 @@ public class NestedClassProcessor { for (Entry> entry : enclosing.getValue().entrySet()) { mergeListSignatures(entry.getValue(), interPairMask, false); - MethodWrapper method = nestedNode.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, entry.getKey()); - method.signatureFields = new ArrayList<>(); - + List mask = new ArrayList<>(entry.getValue().size()); boolean firstSignField = nestedNode.type != ClassNode.CLASS_ANONYMOUS; for (VarFieldPair pair : entry.getValue()) { - method.signatureFields.add(pair == null || (!firstSignField && pair.fieldKey.isEmpty()) ? null : pair.varPair); + mask.add(pair == null || (!firstSignField && pair.fieldKey.isEmpty()) ? null : pair.varPair); firstSignField = false; } + nestedNode.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, entry.getKey()).synthParameters = mask; } } } - private static void insertLocalVars(ClassNode parent, final ClassNode child) { + private static void insertLocalVars(ClassNode parent, ClassNode child) { // enclosing method, is null iff member class MethodWrapper enclosingMethod = parent.getWrapper().getMethods().getWithKey(child.enclosingMethod); // iterate all child methods - for (final MethodWrapper method : child.getWrapper().getMethods()) { + for (MethodWrapper method : child.getWrapper().getMethods()) { if (method.root != null) { // neither abstract nor native Map mapNewNames = new HashMap<>(); // local var names Map mapNewTypes = new HashMap<>(); // local var types - final Map mapParamsToNewVars = new HashMap<>(); - if (method.signatureFields != null) { + Map mapParamsToNewVars = new HashMap<>(); + if (method.synthParameters != null) { int index = 0, varIndex = 1; MethodDescriptor md = MethodDescriptor.parseDescriptor(method.methodStruct.getDescriptor()); - for (VarVersionPair pair : method.signatureFields) { + for (VarVersionPair pair : method.synthParameters) { if (pair != null) { VarVersionPair newVar = new VarVersionPair(method.counter.getCounterAndIncrement(CounterContainer.VAR_COUNTER), 0); @@ -450,7 +440,7 @@ public class NestedClassProcessor { } } - final Map mapFieldsToNewVars = new HashMap<>(); + Map mapFieldsToNewVars = new HashMap<>(); for (ClassNode classNode = child; classNode != null; classNode = classNode.parent) { for (Entry entry : classNode.mapFieldsToVars.entrySet()) { VarVersionPair newVar = new VarVersionPair(method.counter.getCounterAndIncrement(CounterContainer.VAR_COUNTER), 0); @@ -632,10 +622,10 @@ public class NestedClassProcessor { assignExpr.getLeft().type == Exprent.EXPRENT_FIELD) { FieldExprent left = (FieldExprent)assignExpr.getLeft(); StructField fd = cl.getField(left.getName(), left.getDescriptor().descriptorString); - - if (fd != null && cl.qualifiedName.equals(left.getClassname()) && + if (fd != null && + cl.qualifiedName.equals(left.getClassname()) && fd.hasModifier(CodeConstants.ACC_FINAL) && - (fd.isSynthetic() || (noSynthFlag && fd.hasModifier(CodeConstants.ACC_PRIVATE)))) { + (fd.isSynthetic() || noSynthFlag && fd.hasModifier(CodeConstants.ACC_PRIVATE))) { // local (== not inherited) field field = InterpreterUtil.makeUniqueKey(left.getName(), left.getDescriptor().descriptorString); break; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/IfHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/IfHelper.java index 379fb52..b46cdae 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/IfHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/IfHelper.java @@ -9,39 +9,25 @@ import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement; import org.jetbrains.java.decompiler.modules.decompiler.stats.SequenceStatement; import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; - +import java.util.*; public class IfHelper { - - public static boolean mergeAllIfs(RootStatement root) { - boolean res = mergeAllIfsRec(root, new HashSet<>()); - if (res) { SequenceHelper.condenseSequences(root); } - return res; } - - private static boolean mergeAllIfsRec(Statement stat, HashSet setReorderedIfs) { - + private static boolean mergeAllIfsRec(Statement stat, Set setReorderedIfs) { boolean res = false; if (stat.getExprents() == null) { - while (true) { - boolean changed = false; for (Statement st : stat.getStats()) { - res |= mergeAllIfsRec(st, setReorderedIfs); // collapse composed if's @@ -61,7 +47,7 @@ public class IfHelper { return res; } - public static boolean mergeIfs(Statement statement, HashSet setReorderedIfs) { + public static boolean mergeIfs(Statement statement, Set setReorderedIfs) { if (statement.type != Statement.TYPE_IF && statement.type != Statement.TYPE_SEQUENCE) { return false; } @@ -193,11 +179,9 @@ public class IfHelper { } private static boolean collapseIfElse(IfNode rtnode) { - if (rtnode.edgetypes.get(0) == 0) { IfNode ifbranch = rtnode.succs.get(0); if (ifbranch.succs.size() == 2) { - // if-else branch if (ifbranch.succs.get(0).value == rtnode.succs.get(1).value) { @@ -245,9 +229,7 @@ public class IfHelper { return false; } - private static boolean collapseElse(IfNode rtnode) { - if (rtnode.edgetypes.get(1) == 0) { IfNode elsebranch = rtnode.succs.get(1); if (elsebranch.succs.size() == 2) { @@ -308,9 +290,7 @@ public class IfHelper { } } else if (elsebranch.succs.size() == 1) { - if (elsebranch.succs.get(0).value == rtnode.succs.get(0).value) { - IfStatement firstif = (IfStatement)rtnode.value; Statement second = elsebranch.value; @@ -349,9 +329,7 @@ public class IfHelper { return false; } - private static IfNode buildGraph(IfStatement stat, boolean stsingle) { - if (stat.iftype == IfStatement.IFTYPE_IFELSE) { return null; } @@ -664,9 +642,7 @@ public class IfHelper { return false; } - private static Statement getNextStatement(Statement stat) { - Statement parent = stat.getParent(); switch (parent.type) { case Statement.TYPE_ROOT: @@ -688,7 +664,6 @@ public class IfHelper { } private static boolean existsPath(Statement from, Statement to) { - for (StatEdge edge : to.getAllPredecessorEdges()) { if (from.containsStatementStrict(edge.getSource())) { return true; @@ -700,7 +675,6 @@ public class IfHelper { private static class IfNode { public final Statement value; - public final List succs = new ArrayList<>(); public final List edgetypes = new ArrayList<>(); @@ -713,4 +687,4 @@ public class IfHelper { edgetypes.add(type); } } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java index 3a4d088..0bade66 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java @@ -21,7 +21,29 @@ import java.util.*; import java.util.Map.Entry; public class SimplifyExprentsHelper { - static final MatchEngine class14Builder = new MatchEngine(); + @SuppressWarnings("SpellCheckingInspection") private static final MatchEngine class14Builder = new MatchEngine( + "statement type:if iftype:if exprsize:-1\n" + + " exprent position:head type:if\n" + + " exprent type:function functype:eq\n" + + " exprent type:field name:$fieldname$\n" + + " exprent type:constant consttype:null\n" + + " statement type:basicblock\n" + + " exprent position:-1 type:assignment ret:$assignfield$\n" + + " exprent type:var index:$var$\n" + + " exprent type:field name:$fieldname$\n" + + " statement type:sequence statsize:2\n" + + " statement type:trycatch\n" + + " statement type:basicblock exprsize:1\n" + + " exprent type:assignment\n" + + " exprent type:var index:$var$\n" + + " exprent type:invocation invclass:java/lang/Class signature:forName(Ljava/lang/String;)Ljava/lang/Class;\n" + + " exprent position:0 type:constant consttype:string constvalue:$classname$\n" + + " statement type:basicblock exprsize:1\n" + + " exprent type:exit exittype:throw\n" + + " statement type:basicblock exprsize:1\n" + + " exprent type:assignment\n" + + " exprent type:field name:$fieldname$ ret:$field$\n" + + " exprent type:var index:$var$"); private final boolean firstInvocation; @@ -29,10 +51,11 @@ public class SimplifyExprentsHelper { this.firstInvocation = firstInvocation; } - public boolean simplifyStackVarsStatement(Statement stat, HashSet setReorderedIfs, SSAConstructorSparseEx ssa, StructClass cl) { + public boolean simplifyStackVarsStatement(Statement stat, Set setReorderedIfs, SSAConstructorSparseEx ssa, StructClass cl) { boolean res = false; - if (stat.getExprents() == null) { + List expressions = stat.getExprents(); + if (expressions == null) { boolean processClass14 = DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_CLASS_1_4); while (true) { @@ -65,7 +88,7 @@ public class SimplifyExprentsHelper { } } else { - res = simplifyStackVarsExprents(stat.getExprents(), cl); + res = simplifyStackVarsExprents(expressions, cl); } return res; @@ -75,7 +98,6 @@ public class SimplifyExprentsHelper { boolean res = false; int index = 0; - while (index < list.size()) { Exprent current = list.get(index); @@ -131,9 +153,9 @@ public class SimplifyExprentsHelper { } // direct initialization of an array - int arrcount = isArrayInitializer(list, index); - if (arrcount > 0) { - for (int i = 0; i < arrcount; i++) { + int arrCount = isArrayInitializer(list, index); + if (arrCount > 0) { + for (int i = 0; i < arrCount; i++) { list.remove(index + 1); } res = true; @@ -163,13 +185,13 @@ public class SimplifyExprentsHelper { } // assignment on stack - if (isStackAssignement(current, next)) { + if (isStackAssignment(current, next)) { list.remove(index + 1); res = true; continue; } - if (!firstInvocation && isStackAssignement2(current, next)) { + if (!firstInvocation && isStackAssignment2(current, next)) { list.remove(index + 1); res = true; continue; @@ -186,38 +208,38 @@ public class SimplifyExprentsHelper { AssignmentExprent as = (AssignmentExprent)first; if (as.getRight().type == Exprent.EXPRENT_NEW && as.getLeft().type == Exprent.EXPRENT_VAR) { - NewExprent newex = (NewExprent)as.getRight(); + NewExprent newExpr = (NewExprent)as.getRight(); - if (!newex.getLstArrayElements().isEmpty()) { - VarExprent arrvar = (VarExprent)as.getLeft(); + if (!newExpr.getLstArrayElements().isEmpty()) { + VarExprent arrVar = (VarExprent)as.getLeft(); if (second.type == Exprent.EXPRENT_ASSIGNMENT) { AssignmentExprent aas = (AssignmentExprent)second; if (aas.getLeft().type == Exprent.EXPRENT_ARRAY) { - ArrayExprent arrex = (ArrayExprent)aas.getLeft(); - if (arrex.getArray().type == Exprent.EXPRENT_VAR && arrvar.equals(arrex.getArray()) - && arrex.getIndex().type == Exprent.EXPRENT_CONST) { - - int constvalue = ((ConstExprent)arrex.getIndex()).getIntValue(); - - if (constvalue < newex.getLstArrayElements().size()) { - Exprent init = newex.getLstArrayElements().get(constvalue); + ArrayExprent arrExpr = (ArrayExprent)aas.getLeft(); + if (arrExpr.getArray().type == Exprent.EXPRENT_VAR && + arrVar.equals(arrExpr.getArray()) && + arrExpr.getIndex().type == Exprent.EXPRENT_CONST) { + int constValue = ((ConstExprent)arrExpr.getIndex()).getIntValue(); + + if (constValue < newExpr.getLstArrayElements().size()) { + Exprent init = newExpr.getLstArrayElements().get(constValue); if (init.type == Exprent.EXPRENT_CONST) { ConstExprent cinit = (ConstExprent)init; - VarType arrtype = newex.getNewType().decreaseArrayDim(); - ConstExprent defaultval = ExprProcessor.getDefaultArrayValue(arrtype); + VarType arrType = newExpr.getNewType().decreaseArrayDim(); + ConstExprent defaultVal = ExprProcessor.getDefaultArrayValue(arrType); - if (cinit.equals(defaultval)) { - Exprent tempexpr = aas.getRight(); + if (cinit.equals(defaultVal)) { + Exprent tempExpr = aas.getRight(); - if (!tempexpr.containsExprent(arrvar)) { - newex.getLstArrayElements().set(constvalue, tempexpr); + if (!tempExpr.containsExprent(arrVar)) { + newExpr.getLstArrayElements().set(constValue, tempExpr); - if (tempexpr.type == Exprent.EXPRENT_NEW) { - NewExprent tempnewex = (NewExprent)tempexpr; - int dims = newex.getNewType().arrayDim; - if (dims > 1 && !tempnewex.getLstArrayElements().isEmpty()) { - tempnewex.setDirectArrayInit(true); + if (tempExpr.type == Exprent.EXPRENT_NEW) { + NewExprent tempNewExpr = (NewExprent)tempExpr; + int dims = newExpr.getNewType().arrayDim; + if (dims > 1 && !tempNewExpr.getLstArrayElements().isEmpty()) { + tempNewExpr.setDirectArrayInit(true); } } @@ -242,19 +264,18 @@ public class SimplifyExprentsHelper { AssignmentExprent as = (AssignmentExprent)current; if (as.getRight().type == Exprent.EXPRENT_NEW && as.getLeft().type == Exprent.EXPRENT_VAR) { - NewExprent newex = (NewExprent)as.getRight(); + NewExprent newExpr = (NewExprent)as.getRight(); - if (newex.getExprType().arrayDim > 0 && newex.getLstDims().size() == 1 && newex.getLstArrayElements().isEmpty() && - newex.getLstDims().get(0).type == Exprent.EXPRENT_CONST) { + if (newExpr.getExprType().arrayDim > 0 && newExpr.getLstDims().size() == 1 && newExpr.getLstArrayElements().isEmpty() && + newExpr.getLstDims().get(0).type == Exprent.EXPRENT_CONST) { - int size = (Integer)((ConstExprent)newex.getLstDims().get(0)).getValue(); + int size = (Integer)((ConstExprent)newExpr.getLstDims().get(0)).getValue(); if (size == 0) { return 0; } - VarExprent arrvar = (VarExprent)as.getLeft(); - - HashMap mapInit = new HashMap<>(); + VarExprent arrVar = (VarExprent)as.getLeft(); + Map mapInit = new HashMap<>(); int i = 1; while (index + i < list.size() && i <= size) { @@ -264,17 +285,14 @@ public class SimplifyExprentsHelper { if (expr.type == Exprent.EXPRENT_ASSIGNMENT) { AssignmentExprent aas = (AssignmentExprent)expr; if (aas.getLeft().type == Exprent.EXPRENT_ARRAY) { - ArrayExprent arrex = (ArrayExprent)aas.getLeft(); - if (arrex.getArray().type == Exprent.EXPRENT_VAR && arrvar.equals(arrex.getArray()) - && arrex.getIndex().type == Exprent.EXPRENT_CONST) { - - int constvalue = ((ConstExprent)arrex.getIndex()) - .getIntValue(); // TODO: check for a number type. Failure extremely improbable, but nevertheless... - - if (constvalue < size && !mapInit.containsKey(constvalue)) { - - if (!aas.getRight().containsExprent(arrvar)) { - mapInit.put(constvalue, aas.getRight()); + ArrayExprent arrExpr = (ArrayExprent)aas.getLeft(); + if (arrExpr.getArray().type == Exprent.EXPRENT_VAR && arrVar.equals(arrExpr.getArray()) && + arrExpr.getIndex().type == Exprent.EXPRENT_CONST) { + // TODO: check for a number type. Failure extremely improbable, but nevertheless... + int constValue = ((ConstExprent)arrExpr.getIndex()).getIntValue(); + if (constValue < size && !mapInit.containsKey(constValue)) { + if (!aas.getRight().containsExprent(arrVar)) { + mapInit.put(constValue, aas.getRight()); found = true; } } @@ -291,33 +309,29 @@ public class SimplifyExprentsHelper { double fraction = ((double)mapInit.size()) / size; - if ((arrvar.isStack() && fraction > 0) || (size <= 7 && fraction >= 0.3) || - (size > 7 && fraction >= 0.7)) { - + if ((arrVar.isStack() && fraction > 0) || (size <= 7 && fraction >= 0.3) || (size > 7 && fraction >= 0.7)) { List lstRet = new ArrayList<>(); - VarType arrtype = newex.getNewType().decreaseArrayDim(); - - ConstExprent defaultval = ExprProcessor.getDefaultArrayValue(arrtype); - + VarType arrayType = newExpr.getNewType().decreaseArrayDim(); + ConstExprent defaultVal = ExprProcessor.getDefaultArrayValue(arrayType); for (int j = 0; j < size; j++) { - lstRet.add(defaultval.copy()); + lstRet.add(defaultVal.copy()); } - int dims = newex.getNewType().arrayDim; + int dims = newExpr.getNewType().arrayDim; for (Entry ent : mapInit.entrySet()) { - Exprent tempexpr = ent.getValue(); - lstRet.set(ent.getKey(), tempexpr); + Exprent tempExpr = ent.getValue(); + lstRet.set(ent.getKey(), tempExpr); - if (tempexpr.type == Exprent.EXPRENT_NEW) { - NewExprent tempnewex = (NewExprent)tempexpr; - if (dims > 1 && !tempnewex.getLstArrayElements().isEmpty()) { - tempnewex.setDirectArrayInit(true); + if (tempExpr.type == Exprent.EXPRENT_NEW) { + NewExprent tempNewExpr = (NewExprent)tempExpr; + if (dims > 1 && !tempNewExpr.getLstArrayElements().isEmpty()) { + tempNewExpr.setDirectArrayInit(true); } } } - newex.setLstArrayElements(lstRet); + newExpr.setLstArrayElements(lstRet); return mapInit.size(); } @@ -333,17 +347,16 @@ public class SimplifyExprentsHelper { AssignmentExprent asf = (AssignmentExprent)first; if (asf.getLeft().type == Exprent.EXPRENT_VAR && asf.getRight().type == Exprent.EXPRENT_VAR) { - VarExprent varleft = (VarExprent)asf.getLeft(); - VarExprent varright = (VarExprent)asf.getRight(); - - return varleft.getIndex() == varright.getIndex() && varleft.isStack() && varright.isStack(); + VarExprent left = (VarExprent)asf.getLeft(); + VarExprent right = (VarExprent)asf.getRight(); + return left.getIndex() == right.getIndex() && left.isStack() && right.isStack(); } } return false; } - private static boolean isStackAssignement2(Exprent first, Exprent second) { // e.g. 1.4-style class invocation + private static boolean isStackAssignment2(Exprent first, Exprent second) { // e.g. 1.4-style class invocation if (first.type == Exprent.EXPRENT_ASSIGNMENT && second.type == Exprent.EXPRENT_ASSIGNMENT) { AssignmentExprent asf = (AssignmentExprent)first; AssignmentExprent ass = (AssignmentExprent)second; @@ -360,7 +373,7 @@ public class SimplifyExprentsHelper { return false; } - private static boolean isStackAssignement(Exprent first, Exprent second) { + private static boolean isStackAssignment(Exprent first, Exprent second) { if (first.type == Exprent.EXPRENT_ASSIGNMENT && second.type == Exprent.EXPRENT_ASSIGNMENT) { AssignmentExprent asf = (AssignmentExprent)first; AssignmentExprent ass = (AssignmentExprent)second; @@ -395,8 +408,7 @@ public class SimplifyExprentsHelper { if (as.getRight().type == Exprent.EXPRENT_FUNCTION) { FunctionExprent func = (FunctionExprent)as.getRight(); - if (func.getFuncType() == FunctionExprent.FUNCTION_ADD || - func.getFuncType() == FunctionExprent.FUNCTION_SUB) { + if (func.getFuncType() == FunctionExprent.FUNCTION_ADD || func.getFuncType() == FunctionExprent.FUNCTION_SUB) { Exprent econd = func.getLstOperands().get(0); Exprent econst = func.getLstOperands().get(1); @@ -410,9 +422,8 @@ public class SimplifyExprentsHelper { Exprent left = as.getLeft(); if (left.type != Exprent.EXPRENT_VAR && left.equals(econd)) { - FunctionExprent ret = new FunctionExprent( - func.getFuncType() == FunctionExprent.FUNCTION_ADD ? FunctionExprent.FUNCTION_PPI : FunctionExprent.FUNCTION_MMI, - econd, func.bytecode); + int type = func.getFuncType() == FunctionExprent.FUNCTION_ADD ? FunctionExprent.FUNCTION_PPI : FunctionExprent.FUNCTION_MMI; + FunctionExprent ret = new FunctionExprent(type, econd, func.bytecode); ret.setImplicitType(VarType.VARTYPE_INT); return ret; } @@ -449,10 +460,10 @@ public class SimplifyExprentsHelper { private static boolean isMonitorExit(Exprent first) { if (first.type == Exprent.EXPRENT_MONITOR) { - MonitorExprent monexpr = (MonitorExprent)first; - return monexpr.getMonType() == MonitorExprent.MONITOR_EXIT && - monexpr.getValue().type == Exprent.EXPRENT_VAR && - !((VarExprent)monexpr.getValue()).isStack(); + MonitorExprent expr = (MonitorExprent)first; + return expr.getMonType() == MonitorExprent.MONITOR_EXIT && + expr.getValue().type == Exprent.EXPRENT_VAR && + !((VarExprent)expr.getValue()).isStack(); } return false; @@ -460,21 +471,21 @@ public class SimplifyExprentsHelper { private static boolean isQualifiedNewGetClass(Exprent first, Exprent second) { if (first.type == Exprent.EXPRENT_INVOCATION) { - InvocationExprent invexpr = (InvocationExprent)first; + InvocationExprent invocation = (InvocationExprent)first; - if (!invexpr.isStatic() && invexpr.getInstance().type == Exprent.EXPRENT_VAR && invexpr.getName().equals("getClass") && - invexpr.getStringDescriptor().equals("()Ljava/lang/Class;")) { + if (!invocation.isStatic() && invocation.getInstance().type == Exprent.EXPRENT_VAR && invocation.getName().equals("getClass") && + invocation.getStringDescriptor().equals("()Ljava/lang/Class;")) { List lstExprents = second.getAllExprents(); lstExprents.add(second); for (Exprent expr : lstExprents) { if (expr.type == Exprent.EXPRENT_NEW) { - NewExprent nexpr = (NewExprent)expr; - if (nexpr.getConstructor() != null && !nexpr.getConstructor().getLstParameters().isEmpty() && - nexpr.getConstructor().getLstParameters().get(0).equals(invexpr.getInstance())) { + NewExprent newExpr = (NewExprent)expr; + if (newExpr.getConstructor() != null && !newExpr.getConstructor().getLstParameters().isEmpty() && + newExpr.getConstructor().getLstParameters().get(0).equals(invocation.getInstance())) { - String classname = nexpr.getNewType().value; + String classname = newExpr.getNewType().value; ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(classname); if (node != null && node.type != ClassNode.CLASS_ROOT) { return true; @@ -488,7 +499,7 @@ public class SimplifyExprentsHelper { return false; } - // propagate (var = new X) forward to the invokation + // propagate (var = new X) forward to the invocation private static boolean isConstructorInvocationRemote(List list, int index) { Exprent current = list.get(index); @@ -497,12 +508,11 @@ public class SimplifyExprentsHelper { if (as.getLeft().type == Exprent.EXPRENT_VAR && as.getRight().type == Exprent.EXPRENT_NEW) { - NewExprent newexpr = (NewExprent)as.getRight(); - VarType newtype = newexpr.getNewType(); - VarVersionPair leftPaar = new VarVersionPair((VarExprent)as.getLeft()); - - if (newtype.type == CodeConstants.TYPE_OBJECT && newtype.arrayDim == 0 && newexpr.getConstructor() == null) { + NewExprent newExpr = (NewExprent)as.getRight(); + VarType newType = newExpr.getNewType(); + VarVersionPair leftPair = new VarVersionPair((VarExprent)as.getLeft()); + if (newType.type == CodeConstants.TYPE_OBJECT && newType.arrayDim == 0 && newExpr.getConstructor() == null) { for (int i = index + 1; i < list.size(); i++) { Exprent remote = list.get(i); @@ -513,8 +523,7 @@ public class SimplifyExprentsHelper { if (in.getFunctype() == InvocationExprent.TYP_INIT && in.getInstance().type == Exprent.EXPRENT_VAR && as.getLeft().equals(in.getInstance())) { - - newexpr.setConstructor(in); + newExpr.setConstructor(in); in.setInstance(null); list.set(i, as.copy()); @@ -525,7 +534,7 @@ public class SimplifyExprentsHelper { // check for variable in use Set setVars = remote.getAllVariables(); - if (setVars.contains(leftPaar)) { // variable used somewhere in between -> exit, need a better reduced code + if (setVars.contains(leftPair)) { // variable used somewhere in between -> exit, need a better reduced code return false; } } @@ -553,13 +562,13 @@ public class SimplifyExprentsHelper { ClassNode lambda_class = DecompilerContext.getClassProcessor().getMapRootClasses().get(lambda_class_name); if (lambda_class != null) { // real lambda class found, replace invocation with an anonymous class - NewExprent newexp = new NewExprent(new VarType(lambda_class_name, true), null, 0, in.bytecode); - newexp.setConstructor(in); - // note: we don't set the instance to null with in.setInstance(null) like it is done for a common constructor invokation + NewExprent newExpr = new NewExprent(new VarType(lambda_class_name, true), null, 0, in.bytecode); + newExpr.setConstructor(in); + // note: we don't set the instance to null with in.setInstance(null) like it is done for a common constructor invocation // lambda can also be a reference to a virtual method (e.g. String x; ...(x::toString);) // in this case instance will hold the corresponding object - return newexp; + return newExpr; } } } @@ -579,10 +588,10 @@ public class SimplifyExprentsHelper { if (exprent.type == Exprent.EXPRENT_INVOCATION) { InvocationExprent in = (InvocationExprent)exprent; if (in.getFunctype() == InvocationExprent.TYP_INIT && in.getInstance().type == Exprent.EXPRENT_NEW) { - NewExprent newexp = (NewExprent)in.getInstance(); - newexp.setConstructor(in); + NewExprent newExpr = (NewExprent)in.getInstance(); + newExpr.setConstructor(in); in.setInstance(null); - return newexp; + return newExpr; } } @@ -591,37 +600,35 @@ public class SimplifyExprentsHelper { private static boolean buildIff(Statement stat, SSAConstructorSparseEx ssa) { if (stat.type == Statement.TYPE_IF && stat.getExprents() == null) { - IfStatement stif = (IfStatement)stat; - - Exprent ifheadexpr = stif.getHeadexprent(); - Set ifheadexpr_bytecode = (ifheadexpr == null ? null : ifheadexpr.bytecode); - - if (stif.iftype == IfStatement.IFTYPE_IFELSE) { - Statement ifstat = stif.getIfstat(); - Statement elsestat = stif.getElsestat(); - - if (ifstat.getExprents() != null && ifstat.getExprents().size() == 1 - && elsestat.getExprents() != null && elsestat.getExprents().size() == 1 - && ifstat.getAllSuccessorEdges().size() == 1 && elsestat.getAllSuccessorEdges().size() == 1 - && ifstat.getAllSuccessorEdges().get(0).getDestination() == elsestat.getAllSuccessorEdges().get(0).getDestination()) { - - Exprent ifexpr = ifstat.getExprents().get(0); - Exprent elseexpr = elsestat.getExprents().get(0); - - if (ifexpr.type == Exprent.EXPRENT_ASSIGNMENT && elseexpr.type == Exprent.EXPRENT_ASSIGNMENT) { - AssignmentExprent ifas = (AssignmentExprent)ifexpr; - AssignmentExprent elseas = (AssignmentExprent)elseexpr; - - if (ifas.getLeft().type == Exprent.EXPRENT_VAR && elseas.getLeft().type == Exprent.EXPRENT_VAR) { - VarExprent ifvar = (VarExprent)ifas.getLeft(); - VarExprent elsevar = (VarExprent)elseas.getLeft(); - - if (ifvar.getIndex() == elsevar.getIndex() && ifvar.isStack()) { // ifvar.getIndex() >= VarExprent.STACK_BASE) { + IfStatement statement = (IfStatement)stat; + Exprent ifHeadExpr = statement.getHeadexprent(); + Set ifHeadExprBytecode = (ifHeadExpr == null ? null : ifHeadExpr.bytecode); + + if (statement.iftype == IfStatement.IFTYPE_IFELSE) { + Statement ifStatement = statement.getIfstat(); + Statement elseStatement = statement.getElsestat(); + + if (ifStatement.getExprents() != null && ifStatement.getExprents().size() == 1 && + elseStatement.getExprents() != null && elseStatement.getExprents().size() == 1 && + ifStatement.getAllSuccessorEdges().size() == 1 && elseStatement.getAllSuccessorEdges().size() == 1 && + ifStatement.getAllSuccessorEdges().get(0).getDestination() == elseStatement.getAllSuccessorEdges().get(0).getDestination()) { + Exprent ifExpr = ifStatement.getExprents().get(0); + Exprent elseExpr = elseStatement.getExprents().get(0); + + if (ifExpr.type == Exprent.EXPRENT_ASSIGNMENT && elseExpr.type == Exprent.EXPRENT_ASSIGNMENT) { + AssignmentExprent ifAssign = (AssignmentExprent)ifExpr; + AssignmentExprent elseAssign = (AssignmentExprent)elseExpr; + + if (ifAssign.getLeft().type == Exprent.EXPRENT_VAR && elseAssign.getLeft().type == Exprent.EXPRENT_VAR) { + VarExprent ifVar = (VarExprent)ifAssign.getLeft(); + VarExprent elseVar = (VarExprent)elseAssign.getLeft(); + + if (ifVar.getIndex() == elseVar.getIndex() && ifVar.isStack()) { // ifVar.getIndex() >= VarExprent.STACK_BASE) { boolean found = false; for (Entry> ent : ssa.getPhi().entrySet()) { - if (ent.getKey().var == ifvar.getIndex()) { - if (ent.getValue().contains(ifvar.getVersion()) && ent.getValue().contains(elsevar.getVersion())) { + if (ent.getKey().var == ifVar.getIndex()) { + if (ent.getValue().contains(ifVar.getVersion()) && ent.getValue().contains(elseVar.getVersion())) { found = true; break; } @@ -629,65 +636,61 @@ public class SimplifyExprentsHelper { } if (found) { - List data = new ArrayList<>(stif.getFirst().getExprents()); - - data.add(new AssignmentExprent(ifvar, new FunctionExprent(FunctionExprent.FUNCTION_IIF, - Arrays.asList( - stif.getHeadexprent().getCondition(), - ifas.getRight(), - elseas.getRight()), ifheadexpr_bytecode), ifheadexpr_bytecode)); - stif.setExprents(data); - - if (stif.getAllSuccessorEdges().isEmpty()) { - StatEdge ifedge = ifstat.getAllSuccessorEdges().get(0); - StatEdge edge = new StatEdge(ifedge.getType(), stif, ifedge.getDestination()); - - stif.addSuccessor(edge); - if (ifedge.closure != null) { - ifedge.closure.addLabeledEdge(edge); + List data = new ArrayList<>(statement.getFirst().getExprents()); + + List operands = Arrays.asList(statement.getHeadexprent().getCondition(), ifAssign.getRight(), elseAssign.getRight()); + data.add(new AssignmentExprent(ifVar, new FunctionExprent(FunctionExprent.FUNCTION_IIF, operands, ifHeadExprBytecode), ifHeadExprBytecode)); + statement.setExprents(data); + + if (statement.getAllSuccessorEdges().isEmpty()) { + StatEdge ifEdge = ifStatement.getAllSuccessorEdges().get(0); + StatEdge edge = new StatEdge(ifEdge.getType(), statement, ifEdge.getDestination()); + + statement.addSuccessor(edge); + if (ifEdge.closure != null) { + ifEdge.closure.addLabeledEdge(edge); } } - SequenceHelper.destroyAndFlattenStatement(stif); + SequenceHelper.destroyAndFlattenStatement(statement); return true; } } } } - else if (ifexpr.type == Exprent.EXPRENT_EXIT && elseexpr.type == Exprent.EXPRENT_EXIT) { - ExitExprent ifex = (ExitExprent)ifexpr; - ExitExprent elseex = (ExitExprent)elseexpr; - - if (ifex.getExitType() == elseex.getExitType() && ifex.getValue() != null && elseex.getValue() != null && - ifex.getExitType() == ExitExprent.EXIT_RETURN) { + else if (ifExpr.type == Exprent.EXPRENT_EXIT && elseExpr.type == Exprent.EXPRENT_EXIT) { + ExitExprent ifExit = (ExitExprent)ifExpr; + ExitExprent elseExit = (ExitExprent)elseExpr; + if (ifExit.getExitType() == elseExit.getExitType() && ifExit.getValue() != null && elseExit.getValue() != null && + ifExit.getExitType() == ExitExprent.EXIT_RETURN) { // throw is dangerous, because of implicit casting to a common superclass // e.g. throws IOException and throw true?new RuntimeException():new IOException(); won't work - if (ifex.getExitType() == ExitExprent.EXIT_THROW && - !ifex.getValue().getExprType().equals(elseex.getValue().getExprType())) { // note: getExprType unreliable at this point! + if (ifExit.getExitType() == ExitExprent.EXIT_THROW && + !ifExit.getValue().getExprType().equals(elseExit.getValue().getExprType())) { // note: getExprType unreliable at this point! return false; } // avoid flattening to 'iff' if any of the branches is an 'iff' already - if (isIff(ifex.getValue()) || isIff(elseex.getValue())) { + if (isIff(ifExit.getValue()) || isIff(elseExit.getValue())) { return false; } - List data = new ArrayList<>(stif.getFirst().getExprents()); + List data = new ArrayList<>(statement.getFirst().getExprents()); - data.add(new ExitExprent(ifex.getExitType(), new FunctionExprent(FunctionExprent.FUNCTION_IIF, + data.add(new ExitExprent(ifExit.getExitType(), new FunctionExprent(FunctionExprent.FUNCTION_IIF, Arrays.asList( - stif.getHeadexprent().getCondition(), - ifex.getValue(), - elseex.getValue()), ifheadexpr_bytecode), ifex.getRetType(), ifheadexpr_bytecode)); - stif.setExprents(data); + statement.getHeadexprent().getCondition(), + ifExit.getValue(), + elseExit.getValue()), ifHeadExprBytecode), ifExit.getRetType(), ifHeadExprBytecode)); + statement.setExprents(data); - StatEdge retedge = ifstat.getAllSuccessorEdges().get(0); - stif.addSuccessor(new StatEdge(StatEdge.TYPE_BREAK, stif, retedge.getDestination(), - retedge.closure == stif ? stif.getParent() : retedge.closure)); + StatEdge retEdge = ifStatement.getAllSuccessorEdges().get(0); + Statement closure = retEdge.closure == statement ? statement.getParent() : retEdge.closure; + statement.addSuccessor(new StatEdge(StatEdge.TYPE_BREAK, statement, retEdge.getDestination(), closure)); - SequenceHelper.destroyAndFlattenStatement(stif); + SequenceHelper.destroyAndFlattenStatement(statement); return true; } @@ -703,41 +706,14 @@ public class SimplifyExprentsHelper { return exp.type == Exprent.EXPRENT_FUNCTION && ((FunctionExprent) exp).getFuncType() == FunctionExprent.FUNCTION_IIF; } - static { - class14Builder.parse( - "statement type:if iftype:if exprsize:-1\n" + - " exprent position:head type:if\n" + - " exprent type:function functype:eq\n" + - " exprent type:field name:$fieldname$\n" + - " exprent type:constant consttype:null\n" + - " statement type:basicblock\n" + - " exprent position:-1 type:assignment ret:$assignfield$\n" + - " exprent type:var index:$var$\n" + - " exprent type:field name:$fieldname$\n" + - " statement type:sequence statsize:2\n" + - " statement type:trycatch\n" + - " statement type:basicblock exprsize:1\n" + - " exprent type:assignment\n" + - " exprent type:var index:$var$\n" + - " exprent type:invocation invclass:java/lang/Class signature:forName(Ljava/lang/String;)Ljava/lang/Class;\n" + - " exprent position:0 type:constant consttype:string constvalue:$classname$\n" + - " statement type:basicblock exprsize:1\n" + - " exprent type:exit exittype:throw\n" + - " statement type:basicblock exprsize:1\n" + - " exprent type:assignment\n" + - " exprent type:field name:$fieldname$ ret:$field$\n" + - " exprent type:var index:$var$" - ); - } - private static boolean collapseInlinedClass14(Statement stat) { boolean ret = class14Builder.match(stat); if (ret) { String class_name = (String)class14Builder.getVariableValue("$classname$"); - AssignmentExprent assfirst = (AssignmentExprent)class14Builder.getVariableValue("$assignfield$"); - FieldExprent fieldexpr = (FieldExprent)class14Builder.getVariableValue("$field$"); + AssignmentExprent assignment = (AssignmentExprent)class14Builder.getVariableValue("$assignfield$"); + FieldExprent fieldExpr = (FieldExprent)class14Builder.getVariableValue("$field$"); - assfirst.replaceExprent(assfirst.getRight(), new ConstExprent(VarType.VARTYPE_CLASS, class_name, null)); + assignment.replaceExprent(assignment.getRight(), new ConstExprent(VarType.VARTYPE_CLASS, class_name, null)); List data = new ArrayList<>(stat.getFirst().getExprents()); @@ -747,7 +723,7 @@ public class SimplifyExprentsHelper { ClassWrapper wrapper = (ClassWrapper)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_WRAPPER); if (wrapper != null) { - wrapper.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(fieldexpr.getName(), fieldexpr.getDescriptor().descriptorString)); + wrapper.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(fieldExpr.getName(), fieldExpr.getDescriptor().descriptorString)); } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/StackVarsProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/StackVarsProcessor.java index a3b25de..c235387 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/StackVarsProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/StackVarsProcessor.java @@ -20,36 +20,22 @@ import org.jetbrains.java.decompiler.util.SFormsFastMapDirect; import java.util.*; import java.util.Map.Entry; - public class StackVarsProcessor { - public void simplifyStackVars(RootStatement root, StructMethod mt, StructClass cl) { - - HashSet setReorderedIfs = new HashSet<>(); - + Set setReorderedIfs = new HashSet<>(); SSAUConstructorSparseEx ssau = null; while (true) { - boolean found = false; - // System.out.println("--------------- \r\n"+root.toJava()); - SSAConstructorSparseEx ssa = new SSAConstructorSparseEx(); ssa.splitVariables(root, mt); - // System.out.println("--------------- \r\n"+root.toJava()); - - SimplifyExprentsHelper sehelper = new SimplifyExprentsHelper(ssau == null); while (sehelper.simplifyStackVarsStatement(root, setReorderedIfs, ssa, cl)) { - // System.out.println("--------------- \r\n"+root.toJava()); found = true; } - - // System.out.println("=============== \r\n"+root.toJava()); - setVersionsToNull(root); SequenceHelper.condenseSequences(root); @@ -57,21 +43,10 @@ public class StackVarsProcessor { ssau = new SSAUConstructorSparseEx(); ssau.splitVariables(root, mt); - // try { - // DotExporter.toDotFile(ssau.getSsuversions(), new File("c:\\Temp\\gr12_my.dot")); - // } catch(Exception ex) { - // ex.printStackTrace(); - // } - - // System.out.println("++++++++++++++++ \r\n"+root.toJava()); - - if (iterateStatements(root, ssau)) { found = true; } - // System.out.println("***************** \r\n"+root.toJava()); - setVersionsToNull(root); if (!found) { @@ -83,21 +58,12 @@ public class StackVarsProcessor { ssau = new SSAUConstructorSparseEx(); ssau.splitVariables(root, mt); - // try { - // DotExporter.toDotFile(ssau.getSsuversions(), new File("c:\\Temp\\gr12_my.dot")); - // } catch(Exception ex) { - // ex.printStackTrace(); - // } - iterateStatements(root, ssau); - // System.out.println("~~~~~~~~~~~~~~~~~~~~~~ \r\n"+root.toJava()); - setVersionsToNull(root); } private static void setVersionsToNull(Statement stat) { - if (stat.getExprents() == null) { for (Object obj : stat.getSequentialObjects()) { if (obj instanceof Statement) { @@ -116,7 +82,6 @@ public class StackVarsProcessor { } private static void setExprentVersionsToNull(Exprent exprent) { - List lst = exprent.getAllExprents(true); lst.add(exprent); @@ -127,25 +92,22 @@ public class StackVarsProcessor { } } - private boolean iterateStatements(RootStatement root, SSAUConstructorSparseEx ssa) { - FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); DirectGraph dgraph = flatthelper.buildDirectGraph(root); boolean res = false; - HashSet setVisited = new HashSet<>(); + Set setVisited = new HashSet<>(); LinkedList stack = new LinkedList<>(); - LinkedList> stackMaps = new LinkedList<>(); + LinkedList> stackMaps = new LinkedList<>(); stack.add(dgraph.first); stackMaps.add(new HashMap<>()); while (!stack.isEmpty()) { - DirectNode nd = stack.removeFirst(); - HashMap mapVarValues = stackMaps.removeFirst(); + Map mapVarValues = stackMaps.removeFirst(); if (setVisited.contains(nd)) { continue; @@ -182,9 +144,6 @@ public class StackVarsProcessor { } int[] ret = iterateExprent(lst, index, next, mapVarValues, ssa); - - //System.out.println("***************** \r\n"+root.toJava()); - if (ret[0] >= 0) { index = ret[0]; } @@ -221,26 +180,21 @@ public class StackVarsProcessor { return res; } - - private static Exprent isReplaceableVar(Exprent exprent, HashMap mapVarValues) { - + private static Exprent isReplaceableVar(Exprent exprent, Map mapVarValues) { Exprent dest = null; - if (exprent.type == Exprent.EXPRENT_VAR) { VarExprent var = (VarExprent)exprent; dest = mapVarValues.get(new VarVersionPair(var)); } - return dest; } private static void replaceSingleVar(Exprent parent, VarExprent var, Exprent dest, SSAUConstructorSparseEx ssau) { - parent.replaceExprent(var, dest); // live sets SFormsFastMapDirect livemap = ssau.getLiveVarVersionsMap(new VarVersionPair(var)); - HashSet setVars = getAllVersions(dest); + Set setVars = getAllVersions(dest); for (VarVersionPair varpaar : setVars) { VarVersionNode node = ssau.getSsuversions().nodes.getWithKey(varpaar); @@ -265,9 +219,11 @@ public class StackVarsProcessor { } } - private int[] iterateExprent(List lstExprents, int index, Exprent next, HashMap mapVarValues, SSAUConstructorSparseEx ssau) { - + private int[] iterateExprent(List lstExprents, + int index, + Exprent next, + Map mapVarValues, + SSAUConstructorSparseEx ssau) { Exprent exprent = lstExprents.get(index); int changed = 0; @@ -354,14 +310,14 @@ public class StackVarsProcessor { return new int[]{-1, changed}; } - HashMap> mapVars = getAllVarVersions(leftpaar, right, ssau); + Map> mapVars = getAllVarVersions(leftpaar, right, ssau); boolean isSelfReference = mapVars.containsKey(leftpaar.var); if (isSelfReference && notdom) { return new int[]{-1, changed}; } - HashSet setNextVars = next == null ? null : getAllVersions(next); + Set setNextVars = next == null ? null : getAllVersions(next); // FIXME: fix the entire method! if (right.type != Exprent.EXPRENT_CONST && @@ -380,8 +336,7 @@ public class StackVarsProcessor { boolean vernotreplaced = false; boolean verreplaced = false; - - HashSet setTempUsedVers = new HashSet<>(); + Set setTempUsedVers = new HashSet<>(); for (VarVersionNode usedvar : usedVers) { VarVersionPair usedver = new VarVersionPair(usedvar.var, usedvar.version); @@ -424,9 +379,8 @@ public class StackVarsProcessor { } } - private static HashSet getAllVersions(Exprent exprent) { - - HashSet res = new HashSet<>(); + private static Set getAllVersions(Exprent exprent) { + Set res = new HashSet<>(); List listTemp = new ArrayList<>(exprent.getAllExprents(true)); listTemp.add(exprent); @@ -444,9 +398,8 @@ public class StackVarsProcessor { private static Object[] iterateChildExprent(Exprent exprent, Exprent parent, Exprent next, - HashMap mapVarValues, + Map mapVarValues, SSAUConstructorSparseEx ssau) { - boolean changed = false; for (Exprent expr : exprent.getAllExprents()) { @@ -527,23 +480,21 @@ public class StackVarsProcessor { return new Object[]{null, changed, false}; } - HashMap> mapVars = getAllVarVersions(leftpaar, right, ssau); - + Map> mapVars = getAllVarVersions(leftpaar, right, ssau); if (mapVars.containsKey(leftpaar.var) && notdom) { return new Object[]{null, changed, false}; } - mapVars.remove(leftpaar.var); - HashSet setAllowedVars = getAllVersions(parent); + Set setAllowedVars = getAllVersions(parent); if (next != null) { setAllowedVars.addAll(getAllVersions(next)); } boolean vernotreplaced = false; - HashSet setTempUsedVers = new HashSet<>(); + Set setTempUsedVers = new HashSet<>(); for (VarVersionNode usedvar : usedVers) { VarVersionPair usedver = new VarVersionPair(usedvar.var, usedvar.version); @@ -558,7 +509,6 @@ public class StackVarsProcessor { } if (!notdom && !vernotreplaced) { - for (VarVersionPair usedver : setTempUsedVers) { Exprent copy = right.copy(); if (right.type == Exprent.EXPRENT_FIELD && ssau.getMapFieldVars().containsKey(right.id)) { @@ -576,19 +526,16 @@ public class StackVarsProcessor { } private static boolean getUsedVersions(SSAUConstructorSparseEx ssa, VarVersionPair var, List res) { - VarVersionsGraph ssuversions = ssa.getSsuversions(); VarVersionNode varnode = ssuversions.nodes.getWithKey(var); - HashSet setVisited = new HashSet<>(); - - HashSet setNotDoms = new HashSet<>(); + Set setVisited = new HashSet<>(); + Set setNotDoms = new HashSet<>(); LinkedList stack = new LinkedList<>(); stack.add(varnode); while (!stack.isEmpty()) { - VarVersionNode nd = stack.remove(0); setVisited.add(nd); @@ -625,10 +572,9 @@ public class StackVarsProcessor { } private static boolean isVersionToBeReplaced(VarVersionPair usedvar, - HashMap> mapVars, + Map> mapVars, SSAUConstructorSparseEx ssau, VarVersionPair leftpaar) { - VarVersionsGraph ssuversions = ssau.getSsuversions(); SFormsFastMapDirect mapLiveVars = ssau.getLiveVarVersionsMap(usedvar); @@ -643,13 +589,13 @@ public class StackVarsProcessor { return false; } - for (Entry> ent : mapVars.entrySet()) { + for (Entry> ent : mapVars.entrySet()) { FastSparseSet liveverset = mapLiveVars.get(ent.getKey()); if (liveverset == null) { return false; } - HashSet domset = new HashSet<>(); + Set domset = new HashSet<>(); for (VarVersionPair verpaar : ent.getValue()) { domset.add(ssuversions.nodes.getWithKey(verpaar)); } @@ -673,11 +619,10 @@ public class StackVarsProcessor { return true; } - private static HashMap> getAllVarVersions(VarVersionPair leftvar, - Exprent exprent, - SSAUConstructorSparseEx ssau) { - - HashMap> map = new HashMap<>(); + private static Map> getAllVarVersions(VarVersionPair leftvar, + Exprent exprent, + SSAUConstructorSparseEx ssau) { + Map> map = new HashMap<>(); SFormsFastMapDirect mapLiveVars = ssau.getLiveVarVersionsMap(leftvar); List lst = exprent.getAllExprents(true); @@ -688,7 +633,7 @@ public class StackVarsProcessor { int varindex = ((VarExprent)expr).getIndex(); if (leftvar.var != varindex) { if (mapLiveVars.containsKey(varindex)) { - HashSet verset = new HashSet<>(); + Set verset = new HashSet<>(); for (Integer vers : mapLiveVars.get(varindex)) { verset.add(new VarVersionPair(varindex, vers.intValue())); } @@ -706,7 +651,7 @@ public class StackVarsProcessor { if (ssau.getMapFieldVars().containsKey(expr.id)) { int varindex = ssau.getMapFieldVars().get(expr.id); if (mapLiveVars.containsKey(varindex)) { - HashSet verset = new HashSet<>(); + Set verset = new HashSet<>(); for (Integer vers : mapLiveVars.get(varindex)) { verset.add(new VarVersionPair(varindex, vers.intValue())); } @@ -718,4 +663,4 @@ public class StackVarsProcessor { return map; } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExprUtil.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExprUtil.java new file mode 100644 index 0000000..712845f --- /dev/null +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExprUtil.java @@ -0,0 +1,35 @@ +package org.jetbrains.java.decompiler.modules.decompiler.exps; + +import org.jetbrains.java.decompiler.code.CodeConstants; +import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; +import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.main.rels.ClassWrapper; +import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class ExprUtil { + public static List getSyntheticParametersMask(String className, String descriptor, int parameters) { + ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(className); + return node != null ? getSyntheticParametersMask(node, descriptor, parameters) : null; + } + + public static List getSyntheticParametersMask(ClassNode node, String descriptor, int parameters) { + List mask = null; + + ClassWrapper wrapper = node.getWrapper(); + if (wrapper != null) { + // own class + mask = wrapper.getMethodWrapper(CodeConstants.INIT_NAME, descriptor).synthParameters; + } + else if (parameters > 0 && node.type == ClassNode.CLASS_MEMBER && node.classStruct.hasModifier(CodeConstants.ACC_STATIC)) { + // non-static member class + mask = new ArrayList<>(Collections.nCopies(parameters, null)); + mask.set(0, new VarVersionPair(-1, 0)); + } + + return mask; + } +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java index e10b262..da19f41 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java @@ -217,9 +217,7 @@ public class FunctionExprent extends Exprent { public VarType getExprType() { VarType exprType = null; - if (funcType <= FUNCTION_NEG || funcType == FUNCTION_IPP || funcType == FUNCTION_PPI - || funcType == FUNCTION_IMM || funcType == FUNCTION_MMI) { - + if (funcType <= FUNCTION_NEG || funcType == FUNCTION_IPP || funcType == FUNCTION_PPI || funcType == FUNCTION_IMM || funcType == FUNCTION_MMI) { VarType type1 = lstOperands.get(0).getExprType(); VarType type2 = null; if (lstOperands.size() > 1) { @@ -268,7 +266,6 @@ public class FunctionExprent extends Exprent { Exprent param1 = lstOperands.get(1); Exprent param2 = lstOperands.get(2); VarType supertype = VarType.getCommonSupertype(param1.getExprType(), param2.getExprType()); - if (param1.type == Exprent.EXPRENT_CONST && param2.type == Exprent.EXPRENT_CONST && supertype.type != CodeConstants.TYPE_BOOLEAN && VarType.VARTYPE_INT.isSuperset(supertype)) { exprType = VarType.VARTYPE_INT; @@ -324,9 +321,6 @@ public class FunctionExprent extends Exprent { switch (funcType) { case FUNCTION_IIF: VarType supertype = getExprType(); - if (supertype == null) { - supertype = getExprType(); - } result.addMinTypeExprent(param1, VarType.VARTYPE_BOOLEAN); result.addMinTypeExprent(param2, VarType.getMinTypeInFamily(supertype.typeFamily)); result.addMinTypeExprent(lstOperands.get(2), VarType.getMinTypeInFamily(supertype.typeFamily)); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java index 6886540..ecbb55c 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java @@ -300,10 +300,11 @@ public class InvocationExprent extends Exprent { buf.append(""); } buf.append("("); - break; + case TYP_CLINIT: throw new RuntimeException("Explicit invocation of " + CodeConstants.CLINIT_NAME); + case TYP_INIT: if (super_qualifier != null) { buf.append("super("); @@ -311,31 +312,20 @@ public class InvocationExprent extends Exprent { else if (isInstanceThis) { buf.append("this("); } + else if (instance != null) { + buf.append(instance.toJava(indent, tracer)).append(".("); + } else { - if (instance != null) { - buf.append(instance.toJava(indent, tracer)).append(".("); - } - else { - throw new RuntimeException("Unrecognized invocation of " + CodeConstants.INIT_NAME); - } + throw new RuntimeException("Unrecognized invocation of " + CodeConstants.INIT_NAME); } } - List sigFields = null; + List mask = null; boolean isEnum = false; if (functype == TYP_INIT) { ClassNode newNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(classname); - - if (newNode != null) { // own class - if (newNode.getWrapper() != null) { - sigFields = newNode.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, stringDescriptor).signatureFields; - } - else { - if (newNode.type == ClassNode.CLASS_MEMBER && (newNode.access & CodeConstants.ACC_STATIC) == 0) { // non-static member class - sigFields = new ArrayList<>(Collections.nCopies(lstParameters.size(), (VarVersionPair)null)); - sigFields.set(0, new VarVersionPair(-1, 0)); - } - } + if (newNode != null) { + mask = ExprUtil.getSyntheticParametersMask(newNode, stringDescriptor, lstParameters.size()); isEnum = newNode.classStruct.hasModifier(CodeConstants.ACC_ENUM) && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM); } } @@ -353,7 +343,7 @@ public class InvocationExprent extends Exprent { boolean firstParameter = true; int start = isEnum ? 2 : 0; for (int i = start; i < lstParameters.size(); i++) { - if (sigFields == null || sigFields.get(i) == null) { + if (mask == null || mask.get(i) == null) { TextBuffer buff = new TextBuffer(); boolean ambiguous = setAmbiguousParameters.get(i); @@ -373,7 +363,7 @@ public class InvocationExprent extends Exprent { } } - buf.append(")"); + buf.append(')'); return buf; } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java index 5538546..95cf2f7 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java @@ -20,7 +20,6 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil; import org.jetbrains.java.decompiler.util.ListStack; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Set; @@ -90,10 +89,8 @@ public class NewExprent extends Exprent { } } } - else { - if (constructor != null) { - return constructor.checkExprTypeBounds(); - } + else if (constructor != null) { + return constructor.checkExprTypeBounds(); } return result; @@ -102,21 +99,18 @@ public class NewExprent extends Exprent { @Override public List getAllExprents() { List lst = new ArrayList<>(); - if (newType.arrayDim == 0) { - if (constructor != null) { - Exprent constructor_instance = constructor.getInstance(); - - if (constructor_instance != null) { // should be true only for a lambda expression with a virtual content method - lst.add(constructor_instance); - } - lst.addAll(constructor.getLstParameters()); - } - } - else { + if (newType.arrayDim != 0) { lst.addAll(lstDims); lst.addAll(lstArrayElements); } + else if (constructor != null) { + Exprent constructor = this.constructor.getInstance(); + if (constructor != null) { // should be true only for a lambda expression with a virtual content method + lst.add(constructor); + } + lst.addAll(this.constructor.getLstParameters()); + } return lst; } @@ -193,35 +187,22 @@ public class NewExprent extends Exprent { buf.append('('); if (!lambda && constructor != null) { - InvocationExprent invSuper = child.superInvocation; - - ClassNode newNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(invSuper.getClassname()); - - List sigFields = child.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, constructor.getStringDescriptor()).signatureFields; - if (sigFields == null && newNode != null) { // own class - if (newNode.getWrapper() != null) { - sigFields = newNode.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, invSuper.getStringDescriptor()).signatureFields; - } - else { - if (newNode.type == ClassNode.CLASS_MEMBER && (newNode.access & CodeConstants.ACC_STATIC) == 0 && - !constructor.getLstParameters().isEmpty()) { // member non-static class invoked with enclosing class instance - sigFields = new ArrayList<>(Collections.nCopies(constructor.getLstParameters().size(), (VarVersionPair)null)); - sigFields.set(0, new VarVersionPair(-1, 0)); - } - } + List parameters = constructor.getLstParameters(); + List mask = child.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, constructor.getStringDescriptor()).synthParameters; + if (mask == null) { + InvocationExprent superCall = child.superInvocation; + mask = ExprUtil.getSyntheticParametersMask(superCall.getClassname(), superCall.getStringDescriptor(), parameters.size()); } - List lstParameters = constructor.getLstParameters(); - int start = enumConst ? 2 : 0; boolean firstParam = true; - for (int i = start; i < lstParameters.size(); i++) { - if (sigFields == null || sigFields.get(i) == null) { + for (int i = start; i < parameters.size(); i++) { + if (mask == null || mask.get(i) == null) { if (!firstParam) { buf.append(", "); } - ExprProcessor.getCastedExprent(lstParameters.get(i), constructor.getDescriptor().params[i], buf, indent, true, tracer); + ExprProcessor.getCastedExprent(parameters.get(i), constructor.getDescriptor().params[i], buf, indent, true, tracer); firstParam = false; } @@ -289,33 +270,20 @@ public class NewExprent extends Exprent { } if (constructor != null) { - List lstParameters = constructor.getLstParameters(); - - ClassNode newNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(constructor.getClassname()); - - List sigFields = null; - if (newNode != null) { // own class - if (newNode.getWrapper() != null) { - sigFields = newNode.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, constructor.getStringDescriptor()).signatureFields; - } - else if (newNode.type == ClassNode.CLASS_MEMBER && (newNode.access & CodeConstants.ACC_STATIC) == 0 && !constructor.getLstParameters().isEmpty()) { - // member non-static class invoked with enclosing class instance - sigFields = new ArrayList<>(Collections.nCopies(lstParameters.size(), (VarVersionPair)null)); - sigFields.set(0, new VarVersionPair(-1, 0)); - } - } + List parameters = constructor.getLstParameters(); + List mask = ExprUtil.getSyntheticParametersMask(constructor.getClassname(), constructor.getStringDescriptor(), parameters.size()); int start = enumConst ? 2 : 0; - if (!enumConst || start < lstParameters.size()) { + if (!enumConst || start < parameters.size()) { buf.append('('); boolean firstParam = true; - for (int i = start; i < lstParameters.size(); i++) { - if (sigFields == null || sigFields.get(i) == null) { - Exprent expr = InvocationExprent.unboxIfNeeded(lstParameters.get(i)); + for (int i = start; i < parameters.size(); i++) { + if (mask == null || mask.get(i) == null) { + Exprent expr = InvocationExprent.unboxIfNeeded(parameters.get(i)); VarType leftType = constructor.getDescriptor().params[i]; - if (i == lstParameters.size() - 1 && expr.getExprType() == VarType.VARTYPE_NULL) { + if (i == parameters.size() - 1 && expr.getExprType() == VarType.VARTYPE_NULL) { ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(leftType.value); if (node != null && node.namelessConstructorStub) { break; // skip last parameter of synthetic constructor call diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java index b1d4e49..0402097 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java @@ -158,7 +158,7 @@ public class VarDefinitionHelper { boolean defset = false; - // search for the first assignement to var [index] + // search for the first assignment to var [index] int addindex = 0; for (Exprent expr : lst) { if (setDefinition(expr, index)) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsGraph.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsGraph.java index 18efb4c..ef0fc4b 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsGraph.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsGraph.java @@ -23,24 +23,21 @@ public class VarVersionsGraph { nodes.addAllWithKey(colnodes, colpaars); } - public boolean isDominatorSet(VarVersionNode node, HashSet domnodes) { - + public boolean isDominatorSet(VarVersionNode node, Set domnodes) { if (domnodes.size() == 1) { return engine.isDominator(node, domnodes.iterator().next()); } else { - - HashSet marked = new HashSet<>(); + Set marked = new HashSet<>(); if (domnodes.contains(node)) { return true; } - LinkedList lstNodes = new LinkedList<>(); + List lstNodes = new LinkedList<>(); lstNodes.add(node); while (!lstNodes.isEmpty()) { - VarVersionNode nd = lstNodes.remove(0); if (marked.contains(nd)) { continue; @@ -66,8 +63,7 @@ public class VarVersionsGraph { } public void initDominators() { - - final HashSet roots = new HashSet<>(); + Set roots = new HashSet<>(); for (VarVersionNode node : nodes) { if (node.preds.isEmpty()) { @@ -88,23 +84,20 @@ public class VarVersionsGraph { engine.initialize(); } - private static LinkedList getReversedPostOrder(Collection roots) { - - LinkedList lst = new LinkedList<>(); - HashSet setVisited = new HashSet<>(); + private static List getReversedPostOrder(Collection roots) { + List lst = new LinkedList<>(); + Set setVisited = new HashSet<>(); for (VarVersionNode root : roots) { - - LinkedList lstTemp = new LinkedList<>(); + List lstTemp = new LinkedList<>(); addToReversePostOrderListIterative(root, lstTemp, setVisited); - lst.addAll(lstTemp); } return lst; } - private static void addToReversePostOrderListIterative(VarVersionNode root, List lst, HashSet setVisited) { + private static void addToReversePostOrderListIterative(VarVersionNode root, List lst, Set setVisited) { Map> mapNodeSuccs = new HashMap<>(); LinkedList stackNode = new LinkedList<>(); LinkedList stackIndex = new LinkedList<>(); @@ -113,7 +106,6 @@ public class VarVersionsGraph { stackIndex.add(0); while (!stackNode.isEmpty()) { - VarVersionNode node = stackNode.getLast(); int index = stackIndex.removeLast(); diff --git a/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java b/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java index 41f3ae8..89c0cc8 100644 --- a/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java +++ b/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java @@ -8,7 +8,6 @@ import java.util.Arrays; import java.util.List; public class MethodDescriptor { - public final VarType[] params; public final VarType ret; @@ -127,4 +126,4 @@ public class MethodDescriptor { result = 31 * result + params.length; return result; } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/struct/match/IMatchable.java b/src/org/jetbrains/java/decompiler/struct/match/IMatchable.java index 6e038f8..7cc7cf9 100644 --- a/src/org/jetbrains/java/decompiler/struct/match/IMatchable.java +++ b/src/org/jetbrains/java/decompiler/struct/match/IMatchable.java @@ -1,9 +1,7 @@ // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package org.jetbrains.java.decompiler.struct.match; - public interface IMatchable { - enum MatchProperties { STATEMENT_TYPE, STATEMENT_RET, @@ -29,5 +27,4 @@ public interface IMatchable { IMatchable findObject(MatchNode matchNode, int index); boolean match(MatchNode matchNode, MatchEngine engine); - -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/struct/match/MatchEngine.java b/src/org/jetbrains/java/decompiler/struct/match/MatchEngine.java index 3c38e6b..0eebccf 100644 --- a/src/org/jetbrains/java/decompiler/struct/match/MatchEngine.java +++ b/src/org/jetbrains/java/decompiler/struct/match/MatchEngine.java @@ -12,13 +12,7 @@ import org.jetbrains.java.decompiler.struct.match.MatchNode.RuleValue; import java.util.*; - public class MatchEngine { - - private MatchNode rootNode = null; - - private final Map variables = new HashMap<>(); - private static final Map stat_properties = new HashMap<>(); private static final Map expr_properties = new HashMap<>(); private static final Map stat_type = new HashMap<>(); @@ -83,19 +77,19 @@ public class MatchEngine { expr_const_type.put("string", VarType.VARTYPE_STRING); } + private final MatchNode rootNode; + private final Map variables = new HashMap<>(); - public void parse(String description) { - + public MatchEngine(String description) { // each line is a separate statement/exprent String[] lines = description.split("\n"); int depth = 0; LinkedList stack = new LinkedList<>(); - for(String line : lines) { - + for (String line : lines) { List properties = new ArrayList<>(Arrays.asList(line.split("\\s+"))); // split on any number of whitespaces - if(properties.get(0).isEmpty()) { + if (properties.get(0).isEmpty()) { properties.remove(0); } @@ -103,11 +97,11 @@ public class MatchEngine { // create new node MatchNode matchNode = new MatchNode(node_type); - for(int i = 1; i < properties.size(); ++i) { + for (int i = 1; i < properties.size(); ++i) { String[] values = properties.get(i).split(":"); MatchProperties property = (node_type == MatchNode.MATCHNODE_STATEMENT ? stat_properties : expr_properties).get(values[0]); - if(property == null) { // unknown property defined + if (property == null) { // unknown property defined throw new RuntimeException("Unknown matching property"); } else { @@ -115,61 +109,61 @@ public class MatchEngine { int parameter = 0; String strValue = values[1]; - if(values.length == 3) { + if (values.length == 3) { parameter = Integer.parseInt(values[1]); strValue = values[2]; } - switch(property) { - case STATEMENT_TYPE: - value = stat_type.get(strValue); - break; - case STATEMENT_STATSIZE: - case STATEMENT_EXPRSIZE: - value = Integer.valueOf(strValue); - break; - case STATEMENT_POSITION: - case EXPRENT_POSITION: - case EXPRENT_INVOCATION_CLASS: - case EXPRENT_INVOCATION_SIGNATURE: - case EXPRENT_INVOCATION_PARAMETER: - case EXPRENT_VAR_INDEX: - case EXPRENT_FIELD_NAME: - case EXPRENT_CONSTVALUE: - case STATEMENT_RET: - case EXPRENT_RET: - value = strValue; - break; - case STATEMENT_IFTYPE: - value = stat_if_type.get(strValue); - break; - case EXPRENT_FUNCTYPE: - value = expr_func_type.get(strValue); - break; - case EXPRENT_EXITTYPE: - value = expr_exit_type.get(strValue); - break; - case EXPRENT_CONSTTYPE: - value = expr_const_type.get(strValue); - break; - case EXPRENT_TYPE: - value = expr_type.get(strValue); - break; - default: - throw new RuntimeException("Unhandled matching property"); + switch (property) { + case STATEMENT_TYPE: + value = stat_type.get(strValue); + break; + case STATEMENT_STATSIZE: + case STATEMENT_EXPRSIZE: + value = Integer.valueOf(strValue); + break; + case STATEMENT_POSITION: + case EXPRENT_POSITION: + case EXPRENT_INVOCATION_CLASS: + case EXPRENT_INVOCATION_SIGNATURE: + case EXPRENT_INVOCATION_PARAMETER: + case EXPRENT_VAR_INDEX: + case EXPRENT_FIELD_NAME: + case EXPRENT_CONSTVALUE: + case STATEMENT_RET: + case EXPRENT_RET: + value = strValue; + break; + case STATEMENT_IFTYPE: + value = stat_if_type.get(strValue); + break; + case EXPRENT_FUNCTYPE: + value = expr_func_type.get(strValue); + break; + case EXPRENT_EXITTYPE: + value = expr_exit_type.get(strValue); + break; + case EXPRENT_CONSTTYPE: + value = expr_const_type.get(strValue); + break; + case EXPRENT_TYPE: + value = expr_type.get(strValue); + break; + default: + throw new RuntimeException("Unhandled matching property"); } matchNode.addRule(property, new RuleValue(parameter, value)); } } - if(stack.isEmpty()) { // first line, root node + if (stack.isEmpty()) { // first line, root node stack.push(matchNode); - } else { - + } + else { // return to the correct parent on the stack int new_depth = line.lastIndexOf(' ', depth) + 1; - for(int i = new_depth; i <= depth; ++i) { + for (int i = new_depth; i <= depth; ++i) { stack.pop(); } @@ -190,25 +184,24 @@ public class MatchEngine { } private boolean match(MatchNode matchNode, IMatchable object) { - - if(!object.match(matchNode, this)) { + if (!object.match(matchNode, this)) { return false; } int expr_index = 0; int stat_index = 0; - - for(MatchNode childNode : matchNode.getChildren()) { + for (MatchNode childNode : matchNode.getChildren()) { boolean isStatement = childNode.getType() == MatchNode.MATCHNODE_STATEMENT; IMatchable childObject = object.findObject(childNode, isStatement ? stat_index : expr_index); - if(childObject == null || !match(childNode, childObject)) { + if (childObject == null || !match(childNode, childObject)) { return false; } - if(isStatement) { + if (isStatement) { stat_index++; - } else { + } + else { expr_index++; } } diff --git a/src/org/jetbrains/java/decompiler/struct/match/MatchNode.java b/src/org/jetbrains/java/decompiler/struct/match/MatchNode.java index 7320954..ff33e75 100644 --- a/src/org/jetbrains/java/decompiler/struct/match/MatchNode.java +++ b/src/org/jetbrains/java/decompiler/struct/match/MatchNode.java @@ -1,15 +1,14 @@ // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package org.jetbrains.java.decompiler.struct.match; +import org.jetbrains.java.decompiler.struct.match.IMatchable.MatchProperties; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.jetbrains.java.decompiler.struct.match.IMatchable.MatchProperties; - public class MatchNode { - public static class RuleValue { public final int parameter; public final Object value; @@ -33,12 +32,9 @@ public class MatchNode { public static final int MATCHNODE_EXPRENT = 1; private final int type; - private final Map rules = new HashMap<>(); - private final List children = new ArrayList<>(); - public MatchNode(int type) { this.type = type; } @@ -67,5 +63,4 @@ public class MatchNode { RuleValue rule = rules.get(property); return rule == null ? null : rule.value; } - -} +} \ No newline at end of file diff --git a/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java b/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java index 677bb2d..aebf570 100644 --- a/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java +++ b/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java @@ -14,7 +14,7 @@ import java.util.Objects; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertTrue; public class DecompilerTestFixture {