From acf6646941222f48e7e77f7f51592bed64ec3528 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 5 Dec 2017 12:57:55 +0100 Subject: [PATCH] [java decompiler] excludes false inner classes --- .../decompiler/main/ClassesProcessor.java | 45 ++++++++---------- .../java/decompiler/SingleClassesTest.java | 2 + .../TestGroovyTrait$Trait$FieldHelper.class | Bin 0 -> 467 bytes .../pkg/TestGroovyTrait$Trait$Helper.class | Bin 0 -> 5192 bytes testData/classes/pkg/TestGroovyTrait.class | Bin 0 -> 530 bytes testData/results/TestGroovyTrait.dec | 17 +++++++ testData/src/pkg/TestGroovyTrait.groovy | 8 ++++ 7 files changed, 47 insertions(+), 25 deletions(-) create mode 100644 testData/classes/pkg/TestGroovyTrait$Trait$FieldHelper.class create mode 100644 testData/classes/pkg/TestGroovyTrait$Trait$Helper.class create mode 100644 testData/classes/pkg/TestGroovyTrait.class create mode 100644 testData/results/TestGroovyTrait.dec create mode 100644 testData/src/pkg/TestGroovyTrait.groovy diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java index 9995121..26817be 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java @@ -77,37 +77,33 @@ public class ClassesProcessor { Inner rec = new Inner(); rec.simpleName = simpleName; - rec.type = entry.outerNameIdx != 0 ? ClassNode.CLASS_MEMBER : entry.simpleNameIdx != 0 ? ClassNode.CLASS_LOCAL : ClassNode.CLASS_ANONYMOUS; + rec.type = entry.simpleNameIdx == 0 ? ClassNode.CLASS_ANONYMOUS : entry.outerNameIdx == 0 ? ClassNode.CLASS_LOCAL : ClassNode.CLASS_MEMBER; rec.accessFlags = entry.accessFlags; // enclosing class - String enclClassName; - if (entry.outerNameIdx != 0) { - enclClassName = entry.enclosingName; + String enclClassName = entry.outerNameIdx != 0 ? entry.enclosingName : cl.qualifiedName; + if (enclClassName == null || innerName.equals(enclClassName)) { + continue; // invalid name or self reference } - else { - enclClassName = cl.qualifiedName; + if (rec.type == ClassNode.CLASS_MEMBER && !innerName.equals(enclClassName + '$' + entry.simpleName)) { + continue; // not a real inner class } - if (!innerName.equals(enclClassName)) { // self reference - StructClass enclosing_class = context.getClasses().get(enclClassName); - if (enclosing_class != null && enclosing_class.isOwn()) { // own classes only - - Inner existingRec = mapInnerClasses.get(innerName); - if (existingRec == null) { - mapInnerClasses.put(innerName, rec); - } - else if (!Inner.equal(existingRec, rec)) { - String message = "Inconsistent inner class entries for " + innerName + "!"; - DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); - } - - // reference to the nested class - mapNestedClassReferences.computeIfAbsent(enclClassName, k1 -> new HashSet<>()).add(innerName); - - // reference to the enclosing class - mapEnclosingClassReferences.computeIfAbsent(innerName, k -> new HashSet<>()).add(enclClassName); + StructClass enclosingClass = context.getClasses().get(enclClassName); + if (enclosingClass != null && enclosingClass.isOwn()) { // own classes only + Inner existingRec = mapInnerClasses.get(innerName); + if (existingRec == null) { + mapInnerClasses.put(innerName, rec); } + else if (!Inner.equal(existingRec, rec)) { + String message = "Inconsistent inner class entries for " + innerName + "!"; + DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); + } + + // reference to the nested class + mapNestedClassReferences.computeIfAbsent(enclClassName, k -> new HashSet<>()).add(innerName); + // reference to the enclosing class + mapEnclosingClassReferences.computeIfAbsent(innerName, k -> new HashSet<>()).add(enclClassName); } } } @@ -136,7 +132,6 @@ public class ClassesProcessor { Set setNestedClasses = mapNestedClassReferences.get(superClass); if (setNestedClasses != null) { - StructClass scl = superNode.classStruct; StructInnerClassesAttribute inner = (StructInnerClassesAttribute)scl.getAttribute("InnerClasses"); diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 11d393e..0c24ed8 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -111,6 +111,8 @@ public class SingleClassesTest { //@Test public void testInUse() { doTest("pkg/TestInUse"); } //@Test public void testInterfaceSuper() { doTest("pkg/TestInterfaceSuper"); } + @Test public void testGroovyTrait() { doTest("pkg/TestGroovyTrait"); } + private void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); diff --git a/testData/classes/pkg/TestGroovyTrait$Trait$FieldHelper.class b/testData/classes/pkg/TestGroovyTrait$Trait$FieldHelper.class new file mode 100644 index 0000000000000000000000000000000000000000..ebf6bf55a6dbab1100279607a64b59767fd5d046 GIT binary patch literal 467 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 literal 0 HcmV?d00001 diff --git a/testData/results/TestGroovyTrait.dec b/testData/results/TestGroovyTrait.dec new file mode 100644 index 0000000..f36832a --- /dev/null +++ b/testData/results/TestGroovyTrait.dec @@ -0,0 +1,17 @@ +package pkg; + +import groovy.transform.Trait; +import org.codehaus.groovy.transform.trait.Traits.Implemented; + +@Trait +public interface TestGroovyTrait { + @Implemented + Object myMethod(); + + @Implemented + Object getMyField(); + + @Implemented + void setMyField(Object var1); +} + diff --git a/testData/src/pkg/TestGroovyTrait.groovy b/testData/src/pkg/TestGroovyTrait.groovy new file mode 100644 index 0000000..5bbc203 --- /dev/null +++ b/testData/src/pkg/TestGroovyTrait.groovy @@ -0,0 +1,8 @@ +package pkg + +trait TestGroovyTrait { + def myField = 42 + def myMethod() { + 42 + } +} \ No newline at end of file