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 0000000..ebf6bf5 Binary files /dev/null and b/testData/classes/pkg/TestGroovyTrait$Trait$FieldHelper.class differ diff --git a/testData/classes/pkg/TestGroovyTrait$Trait$Helper.class b/testData/classes/pkg/TestGroovyTrait$Trait$Helper.class new file mode 100644 index 0000000..e97d360 Binary files /dev/null and b/testData/classes/pkg/TestGroovyTrait$Trait$Helper.class differ diff --git a/testData/classes/pkg/TestGroovyTrait.class b/testData/classes/pkg/TestGroovyTrait.class new file mode 100644 index 0000000..561230c Binary files /dev/null and b/testData/classes/pkg/TestGroovyTrait.class differ 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