[java decompiler] cleanup (duplicates; dead code; typos; formatting)

This commit is contained in:
Roman Shevchenko
2017-12-05 14:29:45 +01:00
parent acf6646941
commit b3171e60c9
18 changed files with 387 additions and 548 deletions

View File

@@ -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<ClassWrapper, MethodWrapper> mapClassMeths = new HashMap<>();
Map<ClassWrapper, MethodWrapper> mapClassMeths = new HashMap<>();
mapClassMethods(node, mapClassMeths);
if (mapClassMeths.isEmpty()) {
return;
}
HashSet<ClassWrapper> setFound = new HashSet<>();
Set<ClassWrapper> 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<ClassWrapper, MethodWrapper> mapClassMeths,
final HashSet<ClassWrapper> setFound) {
final ClassWrapper wrapper = node.getWrapper();
private static void processClassRec(ClassNode node, Map<ClassWrapper, MethodWrapper> mapClassMeths, Set<ClassWrapper> 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) {

View File

@@ -647,11 +647,13 @@ public class ClassWriter {
descriptor = GenericMain.parseMethodSignature(attr.getSignature());
if (descriptor != null) {
long actualParams = md.params.length;
List<VarVersionPair> sigFields = methodWrapper.signatureFields;
if (sigFields != null) {
actualParams = sigFields.stream().filter(Objects::isNull).count();
List<VarVersionPair> 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<VarVersionPair> signFields = methodWrapper.signatureFields;
List<VarVersionPair> 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(", ");
}

View File

@@ -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<String> setOuterVarNames = new HashSet<>();
public final Set<String> setOuterVarNames = new HashSet<>();
public DirectGraph graph;
public List<VarVersionPair> signatureFields;
public List<VarVersionPair> synthParameters;
public boolean decompiledWithErrors;
public MethodWrapper(RootStatement root, VarProcessor varproc, StructMethod methodStruct, CounterContainer counter) {

View File

@@ -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);
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;
// }
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<VarVersionPair, String> mapNewNames = new HashMap<>();
Map<VarVersionPair, String> mapNewNames = new HashMap<>();
enclosingMethod.getOrBuildGraph().iterateExprents(exprent -> {
List<Exprent> lst = exprent.getAllExprents(true);
@@ -172,7 +167,7 @@ public class NestedClassProcessor {
List<ClassNode> 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<String, Map<String, List<VarFieldPair>>> mapVarMasks = new HashMap<>();
private static void computeLocalVarsAndDefinitions(ClassNode node) {
// class name -> constructor descriptor -> var to field link
Map<String, Map<String, List<VarFieldPair>>> 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<String, Map<String, List<VarFieldPair>>> mapVarFieldPairs = new HashMap<>();
Map<String, Map<String, List<VarFieldPair>>> 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<Exprent> lst = exprent.getAllExprents(true);
@@ -388,34 +379,33 @@ public class NestedClassProcessor {
for (Entry<String, List<VarFieldPair>> entry : enclosing.getValue().entrySet()) {
mergeListSignatures(entry.getValue(), interPairMask, false);
MethodWrapper method = nestedNode.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, entry.getKey());
method.signatureFields = new ArrayList<>();
List<VarVersionPair> 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<VarVersionPair, String> mapNewNames = new HashMap<>(); // local var names
Map<VarVersionPair, VarType> mapNewTypes = new HashMap<>(); // local var types
final Map<Integer, VarVersionPair> mapParamsToNewVars = new HashMap<>();
if (method.signatureFields != null) {
Map<Integer, VarVersionPair> 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<String, VarVersionPair> mapFieldsToNewVars = new HashMap<>();
Map<String, VarVersionPair> mapFieldsToNewVars = new HashMap<>();
for (ClassNode classNode = child; classNode != null; classNode = classNode.parent) {
for (Entry<String, VarVersionPair> 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;