From 646f1c3f216395814e9e81576e3099e38df10c41 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 3 Sep 2014 12:52:55 +0400 Subject: [PATCH] java-decompiler: hide synthetic field assignment --- .../java/decompiler/main/EnumProcessor.java | 85 +++++-------------- .../decompiler/exps/AssignmentExprent.java | 22 +++-- .../java/decompiler/SingleClassesTest.java | 2 +- 3 files changed, 38 insertions(+), 71 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/EnumProcessor.java b/src/org/jetbrains/java/decompiler/main/EnumProcessor.java index fcdeaf1..d6ae2b9 100644 --- a/src/org/jetbrains/java/decompiler/main/EnumProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/EnumProcessor.java @@ -15,97 +15,58 @@ */ package org.jetbrains.java.decompiler.main; -import org.jetbrains.java.decompiler.code.CodeConstants; -import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.rels.ClassWrapper; import org.jetbrains.java.decompiler.main.rels.MethodWrapper; import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; import org.jetbrains.java.decompiler.modules.decompiler.exps.InvocationExprent; -import org.jetbrains.java.decompiler.modules.decompiler.exps.NewExprent; import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent; import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPaar; import org.jetbrains.java.decompiler.struct.StructClass; import org.jetbrains.java.decompiler.struct.StructField; import org.jetbrains.java.decompiler.struct.StructMethod; -import org.jetbrains.java.decompiler.struct.gen.FieldDescriptor; -import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.util.InterpreterUtil; public class EnumProcessor { public static void clearEnum(ClassWrapper wrapper) { - StructClass cl = wrapper.getClassStruct(); - // hide values() and valueOf() - for (StructMethod meth : cl.getMethods()) { - - String name = meth.getName(); - int flag = 0; + // hide values/valueOf methods and super() invocations + for (MethodWrapper method : wrapper.getMethods()) { + StructMethod mt = method.methodStruct; + String name = mt.getName(); + String descriptor = mt.getDescriptor(); if ("values".equals(name)) { - flag = 1; - } - else if ("valueOf".equals(name)) { - flag = 2; - } - - if (flag > 0) { - String[] arr = meth.getDescriptor().split("[()]"); - String par = arr[1]; - - if ((flag == 1 && par.length() == 0) || - flag == 2 && "Ljava/lang/String;".equals(par)) { - wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(name, meth.getDescriptor())); + if (descriptor.equals("()[L" + cl.qualifiedName + ";")) { + wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(name, descriptor)); } } - } - - // hide all super invocations - for (MethodWrapper meth : wrapper.getMethods()) { - if ("".equals(meth.methodStruct.getName())) { - Statement firstdata = findFirstData(meth.root); - if (firstdata == null || firstdata.getExprents().isEmpty()) { - return; - } - - Exprent exprent = firstdata.getExprents().get(0); - if (exprent.type == Exprent.EXPRENT_INVOCATION) { - InvocationExprent invexpr = (InvocationExprent)exprent; - if (isInvocationSuperConstructor(invexpr, meth, wrapper)) { - firstdata.getExprents().remove(0); - } + else if ("valueOf".equals(name)) { + if (descriptor.equals("(Ljava/lang/String;)L" + cl.qualifiedName + ";")) { + wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(name, descriptor)); } } - } - - // hide dummy synthetic fields of enum constants - for (StructField fd : cl.getFields()) { - 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) { - NewExprent nexpr = (NewExprent)initializer; - if (nexpr.isAnonymous()) { - ClassNode child = DecompilerContext.getClassProcessor().getMapRootClasses().get(nexpr.getNewtype().value); - hideDummyFieldInConstant(child.wrapper); + else if ("".equals(name)) { + Statement firstData = findFirstData(method.root); + if (firstData != null && !firstData.getExprents().isEmpty()) { + Exprent exprent = firstData.getExprents().get(0); + if (exprent.type == Exprent.EXPRENT_INVOCATION) { + InvocationExprent invexpr = (InvocationExprent)exprent; + if (isInvocationSuperConstructor(invexpr, method, wrapper)) { + firstData.getExprents().remove(0); + } } } } } - } - private static void hideDummyFieldInConstant(ClassWrapper wrapper) { - StructClass cl = wrapper.getClassStruct(); + // hide synthetic fields of enum and it's constants for (StructField fd : cl.getFields()) { - if (fd.isSynthetic()) { - FieldDescriptor descr = FieldDescriptor.parseDescriptor(fd.getDescriptor()); - VarType ret = descr.type; - - if (ret.type == CodeConstants.TYPE_OBJECT && ret.arraydim == 1 && cl.qualifiedName.equals(ret.value)) { - wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor())); - } + String descriptor = fd.getDescriptor(); + if (fd.isSynthetic() && descriptor.equals("[L" + cl.qualifiedName + ";")) { + wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(fd.getName(), descriptor)); } } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java index 6c6b1f3..8790624 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java @@ -20,7 +20,6 @@ import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.CheckTypesResult; -import org.jetbrains.java.decompiler.struct.StructClass; import org.jetbrains.java.decompiler.struct.StructField; import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.util.InterpreterUtil; @@ -105,26 +104,33 @@ public class AssignmentExprent extends Exprent { } public String toJava(int indent) { - VarType leftType = left.getExprType(); VarType rightType = right.getExprType(); - boolean fieldInStatInit = false; + boolean fieldInClassInit = false, hiddenField = false; if (left.type == Exprent.EXPRENT_FIELD) { // first assignment to a final field. Field name without "this" in front of it FieldExprent field = (FieldExprent)left; ClassNode node = ((ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE)); if (node != null) { - StructClass cl = node.classStruct; - StructField fd = cl.getField(field.getName(), field.getDescriptor().descriptorString); - if (fd != null && field.isStatic() && fd.hasModifier(CodeConstants.ACC_FINAL)) { - fieldInStatInit = true; + StructField fd = node.classStruct.getField(field.getName(), field.getDescriptor().descriptorString); + if (fd != null) { + if (field.isStatic() && fd.hasModifier(CodeConstants.ACC_FINAL)) { + fieldInClassInit = true; + } + if (node.wrapper.getHideMembers().contains(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()))) { + hiddenField = true; + } } } } + if (hiddenField) { + return ""; + } + StringBuilder buffer = new StringBuilder(); - if (fieldInStatInit) { + if (fieldInClassInit) { buffer.append(((FieldExprent)left).getName()); } else { diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 02fb612..f6146c9 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -65,7 +65,7 @@ public class SingleClassesTest { @Test public void testMethodParameters() { doTest("TestMethodParameters"); } @Test public void testCodeConstructs() { doTest("TestCodeConstructs"); } @Test public void testConstants() { doTest("TestConstants"); } - //@Test public void testEnum() { doTest("TestEnum"); } + @Test public void testEnum() { doTest("TestEnum"); } private void doTest(final String testName) { try {