java-decompiler: fixes and cleanups
- unified attribute loading code - common methods for checking member flags - verifying skip() - correct resource closing - typos
This commit is contained in:
@@ -69,7 +69,7 @@ public class AssertProcessor {
|
||||
|
||||
ClassWrapper wrapper = node.wrapper;
|
||||
|
||||
boolean nosynthflag = DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET);
|
||||
boolean noSynthFlag = DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET);
|
||||
|
||||
for (StructField fd : wrapper.getClassStruct().getFields()) {
|
||||
|
||||
@@ -78,12 +78,8 @@ public class AssertProcessor {
|
||||
// initializer exists
|
||||
if (wrapper.getStaticFieldInitializers().containsKey(keyField)) {
|
||||
|
||||
int flags = fd.access_flags;
|
||||
boolean isSynthetic = (flags & CodeConstants.ACC_SYNTHETIC) != 0 || fd.getAttributes().containsKey("Synthetic");
|
||||
|
||||
// access flags set
|
||||
if ((flags & CodeConstants.ACC_STATIC) != 0 && (flags & CodeConstants.ACC_FINAL) != 0 &&
|
||||
(isSynthetic || nosynthflag)) {
|
||||
if (fd.hasModifier(CodeConstants.ACC_STATIC) && fd.hasModifier(CodeConstants.ACC_FINAL) && (noSynthFlag || fd.isSynthetic())) {
|
||||
|
||||
// field type boolean
|
||||
FieldDescriptor fdescr = FieldDescriptor.parseDescriptor(fd.getDescriptor());
|
||||
@@ -100,8 +96,7 @@ public class AssertProcessor {
|
||||
|
||||
if (invexpr.getInstance() != null &&
|
||||
invexpr.getInstance().type == Exprent.EXPRENT_CONST &&
|
||||
"desiredAssertionStatus".equals(invexpr.getName())
|
||||
&&
|
||||
"desiredAssertionStatus".equals(invexpr.getName()) &&
|
||||
"java/lang/Class".equals(invexpr.getClassname()) &&
|
||||
invexpr.getLstParameters().isEmpty()) {
|
||||
|
||||
|
||||
@@ -33,10 +33,7 @@ import org.jetbrains.java.decompiler.struct.gen.VarType;
|
||||
import org.jetbrains.java.decompiler.util.InterpreterUtil;
|
||||
import org.jetbrains.java.decompiler.util.VBStyleCollection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class ClassReference14Processor {
|
||||
@@ -105,7 +102,7 @@ public class ClassReference14Processor {
|
||||
|
||||
// find the synthetic method Class class$(String) if present
|
||||
HashMap<ClassWrapper, MethodWrapper> mapClassMeths = new HashMap<ClassWrapper, MethodWrapper>();
|
||||
findClassMethod(node, mapClassMeths);
|
||||
mapClassMethods(node, mapClassMeths);
|
||||
|
||||
if (mapClassMeths.isEmpty()) {
|
||||
return;
|
||||
@@ -176,37 +173,33 @@ public class ClassReference14Processor {
|
||||
}
|
||||
}
|
||||
|
||||
private void findClassMethod(ClassNode node, HashMap<ClassWrapper, MethodWrapper> mapClassMeths) {
|
||||
|
||||
boolean nosynthflag = DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET);
|
||||
private void mapClassMethods(ClassNode node, Map<ClassWrapper, MethodWrapper> map) {
|
||||
boolean noSynthFlag = DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET);
|
||||
|
||||
ClassWrapper wrapper = node.wrapper;
|
||||
|
||||
for (MethodWrapper meth : wrapper.getMethods()) {
|
||||
StructMethod mt = meth.methodStruct;
|
||||
for (MethodWrapper method : wrapper.getMethods()) {
|
||||
StructMethod mt = method.methodStruct;
|
||||
|
||||
if (((mt.getAccessFlags() & CodeConstants.ACC_SYNTHETIC) != 0 || mt.getAttributes().containsKey("Synthetic")
|
||||
|| nosynthflag) &&
|
||||
if ((noSynthFlag || mt.isSynthetic()) &&
|
||||
mt.getDescriptor().equals("(Ljava/lang/String;)Ljava/lang/Class;") &&
|
||||
(mt.getAccessFlags() & CodeConstants.ACC_STATIC) != 0) {
|
||||
mt.hasModifier(CodeConstants.ACC_STATIC)) {
|
||||
|
||||
RootStatement root = meth.root;
|
||||
if (root != null) {
|
||||
if (root.getFirst().type == Statement.TYPE_TRYCATCH) {
|
||||
CatchStatement cst = (CatchStatement)root.getFirst();
|
||||
if (cst.getStats().size() == 2 && cst.getFirst().type == Statement.TYPE_BASICBLOCK &&
|
||||
cst.getStats().get(1).type == Statement.TYPE_BASICBLOCK &&
|
||||
cst.getVars().get(0).getVartype().equals(new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/ClassNotFoundException"))) {
|
||||
RootStatement root = method.root;
|
||||
if (root != null && root.getFirst().type == Statement.TYPE_TRYCATCH) {
|
||||
CatchStatement cst = (CatchStatement)root.getFirst();
|
||||
if (cst.getStats().size() == 2 && cst.getFirst().type == Statement.TYPE_BASICBLOCK &&
|
||||
cst.getStats().get(1).type == Statement.TYPE_BASICBLOCK &&
|
||||
cst.getVars().get(0).getVartype().equals(new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/ClassNotFoundException"))) {
|
||||
|
||||
BasicBlockStatement body = (BasicBlockStatement)cst.getFirst();
|
||||
BasicBlockStatement handler = (BasicBlockStatement)cst.getStats().get(1);
|
||||
BasicBlockStatement body = (BasicBlockStatement)cst.getFirst();
|
||||
BasicBlockStatement handler = (BasicBlockStatement)cst.getStats().get(1);
|
||||
|
||||
if (body.getExprents().size() == 1 && handler.getExprents().size() == 1) {
|
||||
if (bodyexprent.equals(body.getExprents().get(0)) &&
|
||||
handlerexprent.equals(handler.getExprents().get(0))) {
|
||||
mapClassMeths.put(wrapper, meth);
|
||||
break;
|
||||
}
|
||||
if (body.getExprents().size() == 1 && handler.getExprents().size() == 1) {
|
||||
if (bodyexprent.equals(body.getExprents().get(0)) &&
|
||||
handlerexprent.equals(handler.getExprents().get(0))) {
|
||||
map.put(wrapper, method);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -216,7 +209,7 @@ public class ClassReference14Processor {
|
||||
|
||||
// iterate nested classes
|
||||
for (ClassNode nd : node.nested) {
|
||||
findClassMethod(nd, mapClassMeths);
|
||||
mapClassMethods(nd, map);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,9 +262,8 @@ public class ClassReference14Processor {
|
||||
StructField fd =
|
||||
wrapper.getClassStruct().getField(field.getName(), field.getDescriptor().descriptorString); // FIXME: can be null! why??
|
||||
|
||||
if (fd != null && (fd.access_flags & CodeConstants.ACC_STATIC) != 0 &&
|
||||
((fd.access_flags & CodeConstants.ACC_SYNTHETIC) != 0 || fd.getAttributes().containsKey("Synthetic")
|
||||
|| DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET))) {
|
||||
if (fd != null && fd.hasModifier(CodeConstants.ACC_STATIC) &&
|
||||
(fd.isSynthetic() || DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET))) {
|
||||
|
||||
if (fexpr.getLstOperands().get(1).type == Exprent.EXPRENT_ASSIGNMENT && fexpr.getLstOperands().get(2).equals(field)) {
|
||||
AssignmentExprent asexpr = (AssignmentExprent)fexpr.getLstOperands().get(1);
|
||||
|
||||
@@ -99,7 +99,7 @@ public class ClassWriter {
|
||||
ref14processor.processClassReferences(node);
|
||||
}
|
||||
|
||||
if (DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM) && (cl.access_flags & CodeConstants.ACC_ENUM) != 0) {
|
||||
if (cl.hasModifier(CodeConstants.ACC_ENUM) && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM)) {
|
||||
EnumProcessor.clearEnum(wrapper);
|
||||
}
|
||||
|
||||
@@ -234,11 +234,8 @@ public class ClassWriter {
|
||||
boolean mthidden = false;
|
||||
|
||||
for (StructMethod mt : cl.getMethods()) {
|
||||
|
||||
int flags = mt.getAccessFlags();
|
||||
|
||||
boolean isSynthetic = (flags & CodeConstants.ACC_SYNTHETIC) != 0 || mt.getAttributes().containsKey("Synthetic");
|
||||
boolean isBridge = (flags & CodeConstants.ACC_BRIDGE) != 0;
|
||||
boolean isSynthetic = mt.isSynthetic();
|
||||
boolean isBridge = mt.hasModifier(CodeConstants.ACC_BRIDGE);
|
||||
|
||||
if ((!isSynthetic || !DecompilerContext.getOption(IFernflowerPreferences.REMOVE_SYNTHETIC)) &&
|
||||
(!isBridge || !DecompilerContext.getOption(IFernflowerPreferences.REMOVE_BRIDGE)) &&
|
||||
@@ -262,12 +259,10 @@ public class ClassWriter {
|
||||
|
||||
// fields
|
||||
for (StructField fd : cl.getFields()) {
|
||||
int flags = fd.access_flags;
|
||||
boolean isSynthetic = (flags & CodeConstants.ACC_SYNTHETIC) != 0 || fd.getAttributes().containsKey("Synthetic");
|
||||
if ((!isSynthetic || !DecompilerContext.getOption(IFernflowerPreferences.REMOVE_SYNTHETIC))
|
||||
&& !wrapper.getHideMembers().contains(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()))) {
|
||||
|
||||
boolean isEnum = DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM) && (flags & CodeConstants.ACC_ENUM) != 0;
|
||||
boolean hide = fd.isSynthetic() && DecompilerContext.getOption(IFernflowerPreferences.REMOVE_SYNTHETIC) ||
|
||||
wrapper.getHideMembers().contains(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()));
|
||||
if (!hide) {
|
||||
boolean isEnum = fd.hasModifier(CodeConstants.ACC_ENUM) && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM);
|
||||
if (isEnum) {
|
||||
if (enumfields) {
|
||||
bufstrwriter1.write(",");
|
||||
@@ -310,12 +305,11 @@ public class ClassWriter {
|
||||
// member classes
|
||||
for (ClassNode inner : node.nested) {
|
||||
if (inner.type == ClassNode.CLASS_MEMBER) {
|
||||
StructClass innercl = inner.classStruct;
|
||||
|
||||
boolean isSynthetic =
|
||||
((inner.access | innercl.access_flags) & CodeConstants.ACC_SYNTHETIC) != 0 || innercl.getAttributes().containsKey("Synthetic");
|
||||
if ((!isSynthetic || !DecompilerContext.getOption(IFernflowerPreferences.REMOVE_SYNTHETIC))
|
||||
&& !wrapper.getHideMembers().contains(innercl.qualifiedName)) {
|
||||
StructClass innerCl = inner.classStruct;
|
||||
boolean isSynthetic = (inner.access & CodeConstants.ACC_SYNTHETIC) != 0 || innerCl.isSynthetic();
|
||||
boolean hide = isSynthetic && DecompilerContext.getOption(IFernflowerPreferences.REMOVE_SYNTHETIC) ||
|
||||
wrapper.getHideMembers().contains(innerCl.qualifiedName);
|
||||
if (!hide) {
|
||||
writer.write(DecompilerContext.getNewLineSeparator());
|
||||
classToJava(inner, writer, indent + 1);
|
||||
}
|
||||
@@ -347,7 +341,7 @@ public class ClassWriter {
|
||||
ClassWrapper wrapper = node.wrapper;
|
||||
StructClass cl = wrapper.getClassStruct();
|
||||
|
||||
int flags = node.type == ClassNode.CLASS_ROOT ? cl.access_flags : node.access;
|
||||
int flags = node.type == ClassNode.CLASS_ROOT ? cl.getAccessFlags() : node.access;
|
||||
boolean isInterface = (flags & CodeConstants.ACC_INTERFACE) != 0;
|
||||
boolean isAnnotation = (flags & CodeConstants.ACC_ANNOTATION) != 0;
|
||||
boolean isEnum = DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM) && (flags & CodeConstants.ACC_ENUM) != 0;
|
||||
@@ -486,8 +480,7 @@ public class ClassWriter {
|
||||
|
||||
String indstr = InterpreterUtil.getIndentString(indent);
|
||||
|
||||
boolean isInterface = (cl.access_flags & CodeConstants.ACC_INTERFACE) != 0;
|
||||
int flags = fd.access_flags;
|
||||
boolean isInterface = cl.hasModifier(CodeConstants.ACC_INTERFACE);
|
||||
|
||||
if (interceptor != null) {
|
||||
String oldname = interceptor.getOldName(cl.qualifiedName + " " + fd.getName() + " " + fd.getDescriptor());
|
||||
@@ -515,8 +508,8 @@ public class ClassWriter {
|
||||
writer.write(DecompilerContext.getNewLineSeparator());
|
||||
}
|
||||
|
||||
boolean isSynthetic = (flags & CodeConstants.ACC_SYNTHETIC) != 0 || fd.getAttributes().containsKey("Synthetic");
|
||||
boolean isEnum = DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM) && (flags & CodeConstants.ACC_ENUM) != 0;
|
||||
boolean isSynthetic = fd.isSynthetic();
|
||||
boolean isEnum = fd.hasModifier(CodeConstants.ACC_ENUM) && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM);
|
||||
|
||||
if (isSynthetic) {
|
||||
writer.write(indstr);
|
||||
@@ -529,7 +522,7 @@ public class ClassWriter {
|
||||
if (!isEnum) {
|
||||
for (int i = 0; i < modval_field.length; i++) {
|
||||
if (!isInterface || !mod_notinterface_fields.contains(modval_field[i])) {
|
||||
if ((flags & modval_field[i]) != 0) {
|
||||
if (fd.hasModifier(modval_field[i])) {
|
||||
writer.write(modstr_field[i]);
|
||||
}
|
||||
}
|
||||
@@ -559,7 +552,7 @@ public class ClassWriter {
|
||||
writer.write(fd.getName());
|
||||
|
||||
Exprent initializer;
|
||||
if ((flags & CodeConstants.ACC_STATIC) != 0) {
|
||||
if (fd.hasModifier(CodeConstants.ACC_STATIC)) {
|
||||
initializer = wrapper.getStaticFieldInitializers().getWithKey(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()));
|
||||
}
|
||||
else {
|
||||
@@ -577,7 +570,7 @@ public class ClassWriter {
|
||||
writer.write(initializer.toJava(indent));
|
||||
}
|
||||
}
|
||||
else if ((flags & CodeConstants.ACC_FINAL) != 0 && (flags & CodeConstants.ACC_STATIC) != 0) {
|
||||
else if (fd.hasModifier(CodeConstants.ACC_FINAL) && fd.hasModifier(CodeConstants.ACC_STATIC)) {
|
||||
StructConstantValueAttribute attr =
|
||||
(StructConstantValueAttribute)fd.getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_CONSTANT_VALUE);
|
||||
if (attr != null) {
|
||||
@@ -704,9 +697,9 @@ public class ClassWriter {
|
||||
MethodWrapper methold = (MethodWrapper)DecompilerContext.getProperty(DecompilerContext.CURRENT_METHOD_WRAPPER);
|
||||
DecompilerContext.setProperty(DecompilerContext.CURRENT_METHOD_WRAPPER, meth);
|
||||
|
||||
boolean isInterface = (cl.access_flags & CodeConstants.ACC_INTERFACE) != 0;
|
||||
boolean isAnnotation = (cl.access_flags & CodeConstants.ACC_ANNOTATION) != 0;
|
||||
boolean isEnum = (cl.access_flags & CodeConstants.ACC_ENUM) != 0 && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM);
|
||||
boolean isInterface = cl.hasModifier(CodeConstants.ACC_INTERFACE);
|
||||
boolean isAnnotation = cl.hasModifier(CodeConstants.ACC_ANNOTATION);
|
||||
boolean isEnum = cl.hasModifier(CodeConstants.ACC_ENUM) && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM);
|
||||
boolean isDeprecated = mt.getAttributes().containsKey("Deprecated");
|
||||
|
||||
String indstr = InterpreterUtil.getIndentString(indent);
|
||||
@@ -721,9 +714,8 @@ public class ClassWriter {
|
||||
if ((flags & CodeConstants.ACC_NATIVE) != 0) {
|
||||
flags &= ~CodeConstants.ACC_STRICT; // compiler bug: a strictfp class sets all methods to strictfp
|
||||
}
|
||||
|
||||
if ("<clinit>".equals(mt.getName())) {
|
||||
flags &= CodeConstants.ACC_STATIC; // ingnore all modifiers except 'static' in a static initializer
|
||||
flags &= CodeConstants.ACC_STATIC; // ignore all modifiers except 'static' in a static initializer
|
||||
}
|
||||
|
||||
if (interceptor != null) {
|
||||
@@ -816,7 +808,7 @@ public class ClassWriter {
|
||||
|
||||
if (!clinit && !dinit) {
|
||||
|
||||
boolean thisvar = (mt.getAccessFlags() & CodeConstants.ACC_STATIC) == 0;
|
||||
boolean thisvar = !mt.hasModifier(CodeConstants.ACC_STATIC);
|
||||
|
||||
// formal type parameters
|
||||
if (descriptor != null && !descriptor.fparameters.isEmpty()) {
|
||||
@@ -900,8 +892,7 @@ public class ClassWriter {
|
||||
if (descriptor != null) {
|
||||
GenericType partype = descriptor.params.get(i);
|
||||
|
||||
boolean isVarArgs = (i == lastparam_index && (mt.getAccessFlags() & CodeConstants.ACC_VARARGS) != 0
|
||||
&& partype.arraydim > 0);
|
||||
boolean isVarArgs = (i == lastparam_index && mt.hasModifier(CodeConstants.ACC_VARARGS) && partype.arraydim > 0);
|
||||
|
||||
if (isVarArgs) {
|
||||
partype.arraydim--;
|
||||
@@ -922,8 +913,7 @@ public class ClassWriter {
|
||||
else {
|
||||
VarType partype = md.params[i].copy();
|
||||
|
||||
boolean isVarArgs = (i == lastparam_index && (mt.getAccessFlags() & CodeConstants.ACC_VARARGS) != 0
|
||||
&& partype.arraydim > 0);
|
||||
boolean isVarArgs = (i == lastparam_index && mt.hasModifier(CodeConstants.ACC_VARARGS) && partype.arraydim > 0);
|
||||
|
||||
if (isVarArgs) {
|
||||
partype.decArrayDim();
|
||||
|
||||
@@ -139,7 +139,7 @@ public class ClassesProcessor {
|
||||
}
|
||||
|
||||
ClassNode node = new ClassNode(ClassNode.CLASS_ROOT, cl);
|
||||
node.access = cl.access_flags;
|
||||
node.access = cl.getAccessFlags();
|
||||
mapRootClasses.put(cl.qualifiedName, node);
|
||||
}
|
||||
}
|
||||
@@ -394,12 +394,9 @@ public class ClassesProcessor {
|
||||
anonimousClassType = new VarType(lambda_class_name, true);
|
||||
|
||||
boolean is_method_reference = (content_class_name != classStruct.qualifiedName);
|
||||
StructMethod mt = null;
|
||||
|
||||
if (!is_method_reference) { // content method in the same class, check synthetic flag
|
||||
mt = classStruct.getMethod(content_method_name, content_method_descriptor);
|
||||
is_method_reference = !((mt.getAccessFlags() & CodeConstants.ACC_SYNTHETIC) != 0 ||
|
||||
mt.getAttributes().containsKey("Synthetic")); // if not synthetic -> method reference
|
||||
StructMethod mt = classStruct.getMethod(content_method_name, content_method_descriptor);
|
||||
is_method_reference = !mt.isSynthetic(); // if not synthetic -> method reference
|
||||
}
|
||||
|
||||
lambda_information.is_method_reference = is_method_reference;
|
||||
|
||||
@@ -82,7 +82,7 @@ public class EnumProcessor {
|
||||
|
||||
// hide dummy synthetic fields of enum constants
|
||||
for (StructField fd : cl.getFields()) {
|
||||
if ((fd.access_flags & CodeConstants.ACC_ENUM) != 0) {
|
||||
if (fd.hasModifier(CodeConstants.ACC_ENUM)) {
|
||||
Exprent initializer =
|
||||
wrapper.getStaticFieldInitializers().getWithKey(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()));
|
||||
if (initializer != null && initializer.type == Exprent.EXPRENT_NEW) {
|
||||
@@ -97,10 +97,9 @@ public class EnumProcessor {
|
||||
}
|
||||
|
||||
private static void hideDummyFieldInConstant(ClassWrapper wrapper) {
|
||||
|
||||
StructClass cl = wrapper.getClassStruct();
|
||||
for (StructField fd : cl.getFields()) {
|
||||
if ((fd.access_flags & CodeConstants.ACC_SYNTHETIC) != 0) {
|
||||
if (fd.isSynthetic()) {
|
||||
FieldDescriptor descr = FieldDescriptor.parseDescriptor(fd.getDescriptor());
|
||||
VarType ret = descr.type;
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ public class InitializerProcessor {
|
||||
FieldExprent fexpr = (FieldExprent)asexpr.getLeft();
|
||||
if (fexpr.getClassname().equals(wrapper.getClassStruct().qualifiedName)) {
|
||||
StructField structField = wrapper.getClassStruct().getField(fexpr.getName(), fexpr.getDescriptor().descriptorString);
|
||||
if (structField != null && (structField.access_flags & CodeConstants.ACC_FINAL) != 0) {
|
||||
if (structField != null && structField.hasModifier(CodeConstants.ACC_FINAL)) {
|
||||
action = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ public class ClassWrapper {
|
||||
}
|
||||
}
|
||||
else {
|
||||
boolean thisvar = (mt.getAccessFlags() & CodeConstants.ACC_STATIC) == 0;
|
||||
boolean thisvar = !mt.hasModifier(CodeConstants.ACC_STATIC);
|
||||
MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor());
|
||||
|
||||
int paramcount = 0;
|
||||
|
||||
@@ -71,7 +71,7 @@ public class NestedClassProcessor {
|
||||
// ensure not-empty class name
|
||||
if ((child.type == ClassNode.CLASS_LOCAL || child.type == ClassNode.CLASS_MEMBER) && child.simpleName == null) {
|
||||
StructClass cl = child.classStruct;
|
||||
if (((child.access | cl.access_flags) & CodeConstants.ACC_SYNTHETIC) != 0 || cl.getAttributes().containsKey("Synthetic")) {
|
||||
if ((child.access & CodeConstants.ACC_SYNTHETIC) != 0 || cl.isSynthetic()) {
|
||||
child.simpleName = "SyntheticClass_" + (++synthetics);
|
||||
}
|
||||
else {
|
||||
@@ -675,7 +675,7 @@ public class NestedClassProcessor {
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean notsynth = DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET);
|
||||
boolean noSynthFlag = DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET);
|
||||
|
||||
// no loop at the begin
|
||||
DirectNode firstnode = graph.first;
|
||||
@@ -692,10 +692,8 @@ public class NestedClassProcessor {
|
||||
|
||||
if (fd != null) { // local (== not inherited) field
|
||||
if (cl.qualifiedName.equals(left.getClassname()) &&
|
||||
(fd.access_flags & CodeConstants.ACC_FINAL) != 0 &&
|
||||
((fd.access_flags & CodeConstants.ACC_SYNTHETIC) != 0 ||
|
||||
fd.getAttributes().containsKey("Synthetic") ||
|
||||
(notsynth && (fd.access_flags & CodeConstants.ACC_PRIVATE) != 0))) {
|
||||
fd.hasModifier(CodeConstants.ACC_FINAL) &&
|
||||
(fd.isSynthetic() || (noSynthFlag && fd.hasModifier(CodeConstants.ACC_PRIVATE)))) {
|
||||
field = InterpreterUtil.makeUniqueKey(left.getName(), left.getDescriptor().descriptorString);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -32,26 +32,25 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
|
||||
public class NestedMemberAccess {
|
||||
|
||||
private static final int METHOD_ACCESS_NORMAL = 1;
|
||||
private static final int METHOD_ACCESS_FIELDGET = 2;
|
||||
private static final int METHOD_ACCESS_FIELDSET = 3;
|
||||
private static final int METHOD_ACCESS_FIELD_GET = 2;
|
||||
private static final int METHOD_ACCESS_FIELD_SET = 3;
|
||||
private static final int METHOD_ACCESS_METHOD = 4;
|
||||
|
||||
private boolean notSetSync;
|
||||
|
||||
private HashMap<MethodWrapper, Integer> mapMethodType = new HashMap<MethodWrapper, Integer>();
|
||||
private boolean noSynthFlag;
|
||||
private Map<MethodWrapper, Integer> mapMethodType = new HashMap<MethodWrapper, Integer>();
|
||||
|
||||
|
||||
public void propagateMemberAccess(ClassNode root) {
|
||||
|
||||
if (root.nested.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
notSetSync = DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET);
|
||||
noSynthFlag = DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET);
|
||||
|
||||
computeMethodTypes(root);
|
||||
|
||||
@@ -60,7 +59,6 @@ public class NestedMemberAccess {
|
||||
|
||||
|
||||
private void computeMethodTypes(ClassNode node) {
|
||||
|
||||
if (node.type == ClassNode.CLASS_LAMBDA) {
|
||||
return;
|
||||
}
|
||||
@@ -69,27 +67,24 @@ public class NestedMemberAccess {
|
||||
computeMethodTypes(nd);
|
||||
}
|
||||
|
||||
for (MethodWrapper meth : node.wrapper.getMethods()) {
|
||||
computeMethodType(node, meth);
|
||||
for (MethodWrapper method : node.wrapper.getMethods()) {
|
||||
computeMethodType(node, method);
|
||||
}
|
||||
}
|
||||
|
||||
private void computeMethodType(ClassNode node, MethodWrapper meth) {
|
||||
|
||||
private void computeMethodType(ClassNode node, MethodWrapper method) {
|
||||
int type = METHOD_ACCESS_NORMAL;
|
||||
|
||||
if (meth.root != null) {
|
||||
if (method.root != null) {
|
||||
DirectGraph graph = method.getOrBuildGraph();
|
||||
|
||||
DirectGraph graph = meth.getOrBuildGraph();
|
||||
|
||||
int flags = meth.methodStruct.getAccessFlags();
|
||||
if (((flags & CodeConstants.ACC_SYNTHETIC) != 0 || meth.methodStruct.getAttributes().containsKey("Synthetic") || notSetSync) &&
|
||||
(flags & CodeConstants.ACC_STATIC) != 0) {
|
||||
StructMethod mt = method.methodStruct;
|
||||
if ((noSynthFlag || mt.isSynthetic()) && mt.hasModifier(CodeConstants.ACC_STATIC)) {
|
||||
if (graph.nodes.size() == 2) { // incl. dummy exit node
|
||||
if (graph.first.exprents.size() == 1) {
|
||||
Exprent exprent = graph.first.exprents.get(0);
|
||||
|
||||
MethodDescriptor mtdesc = MethodDescriptor.parseDescriptor(meth.methodStruct.getDescriptor());
|
||||
MethodDescriptor mtdesc = MethodDescriptor.parseDescriptor(mt.getDescriptor());
|
||||
int parcount = mtdesc.params.length;
|
||||
|
||||
Exprent exprCore = exprent;
|
||||
@@ -109,7 +104,7 @@ public class NestedMemberAccess {
|
||||
if (fexpr.getClassname().equals(node.classStruct.qualifiedName)) { // FIXME: check for private flag of the field
|
||||
if (fexpr.isStatic() ||
|
||||
(fexpr.getInstance().type == Exprent.EXPRENT_VAR && ((VarExprent)fexpr.getInstance()).getIndex() == 0)) {
|
||||
type = METHOD_ACCESS_FIELDGET;
|
||||
type = METHOD_ACCESS_FIELD_GET;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,7 +113,7 @@ public class NestedMemberAccess {
|
||||
if (parcount == 1) {
|
||||
// this or final variable
|
||||
if (((VarExprent)exprCore).getIndex() != 0) {
|
||||
type = METHOD_ACCESS_FIELDGET;
|
||||
type = METHOD_ACCESS_FIELD_GET;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +131,7 @@ public class NestedMemberAccess {
|
||||
if (fexpras.isStatic() ||
|
||||
(fexpras.getInstance().type == Exprent.EXPRENT_VAR && ((VarExprent)fexpras.getInstance()).getIndex() == 0)) {
|
||||
if (((VarExprent)asexpr.getRight()).getIndex() == parcount - 1) {
|
||||
type = METHOD_ACCESS_FIELDSET;
|
||||
type = METHOD_ACCESS_FIELD_SET;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -179,7 +174,7 @@ public class NestedMemberAccess {
|
||||
if (exprentFirst.type == Exprent.EXPRENT_ASSIGNMENT &&
|
||||
exprentSecond.type == Exprent.EXPRENT_EXIT) {
|
||||
|
||||
MethodDescriptor mtdesc = MethodDescriptor.parseDescriptor(meth.methodStruct.getDescriptor());
|
||||
MethodDescriptor mtdesc = MethodDescriptor.parseDescriptor(mt.getDescriptor());
|
||||
int parcount = mtdesc.params.length;
|
||||
|
||||
AssignmentExprent asexpr = (AssignmentExprent)exprentFirst;
|
||||
@@ -196,7 +191,7 @@ public class NestedMemberAccess {
|
||||
if (exexpr.getExittype() == ExitExprent.EXIT_RETURN && exexpr.getValue() != null) {
|
||||
if (exexpr.getValue().type == Exprent.EXPRENT_VAR &&
|
||||
((VarExprent)asexpr.getRight()).getIndex() == parcount - 1) {
|
||||
type = METHOD_ACCESS_FIELDSET;
|
||||
type = METHOD_ACCESS_FIELD_SET;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,10 +206,10 @@ public class NestedMemberAccess {
|
||||
}
|
||||
|
||||
if (type != METHOD_ACCESS_NORMAL) {
|
||||
mapMethodType.put(meth, type);
|
||||
mapMethodType.put(method, type);
|
||||
}
|
||||
else {
|
||||
mapMethodType.remove(meth);
|
||||
mapMethodType.remove(method);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,7 +360,7 @@ public class NestedMemberAccess {
|
||||
Exprent retexprent = null;
|
||||
|
||||
switch (type) {
|
||||
case METHOD_ACCESS_FIELDGET:
|
||||
case METHOD_ACCESS_FIELD_GET:
|
||||
ExitExprent exsource = (ExitExprent)source;
|
||||
if (exsource.getValue().type == Exprent.EXPRENT_VAR) { // qualified this
|
||||
VarExprent var = (VarExprent)exsource.getValue();
|
||||
@@ -393,7 +388,7 @@ public class NestedMemberAccess {
|
||||
retexprent = ret;
|
||||
}
|
||||
break;
|
||||
case METHOD_ACCESS_FIELDSET:
|
||||
case METHOD_ACCESS_FIELD_SET:
|
||||
AssignmentExprent ret;
|
||||
if (source.type == Exprent.EXPRENT_EXIT) {
|
||||
ExitExprent extex = (ExitExprent)source;
|
||||
@@ -440,7 +435,7 @@ public class NestedMemberAccess {
|
||||
|
||||
if (node.type == ClassNode.CLASS_ROOT || (node.access & CodeConstants.ACC_STATIC) != 0) {
|
||||
StructMethod mt = methsource.methodStruct;
|
||||
if ((mt.getAccessFlags() & CodeConstants.ACC_SYNTHETIC) == 0 && !mt.getAttributes().containsKey("Synthetic")) {
|
||||
if (!mt.isSynthetic()) {
|
||||
hide = false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user