[java decompiler] excludes false inner classes

master
Roman Shevchenko 7 years ago
parent 93429bc8a5
commit acf6646941
  1. 45
      src/org/jetbrains/java/decompiler/main/ClassesProcessor.java
  2. 2
      test/org/jetbrains/java/decompiler/SingleClassesTest.java
  3. BIN
      testData/classes/pkg/TestGroovyTrait$Trait$FieldHelper.class
  4. BIN
      testData/classes/pkg/TestGroovyTrait$Trait$Helper.class
  5. BIN
      testData/classes/pkg/TestGroovyTrait.class
  6. 17
      testData/results/TestGroovyTrait.dec
  7. 8
      testData/src/pkg/TestGroovyTrait.groovy

@ -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<String> setNestedClasses = mapNestedClassReferences.get(superClass);
if (setNestedClasses != null) {
StructClass scl = superNode.classStruct;
StructInnerClassesAttribute inner = (StructInnerClassesAttribute)scl.getAttribute("InnerClasses");

@ -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();

@ -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);
}

@ -0,0 +1,8 @@
package pkg
trait TestGroovyTrait {
def myField = 42
def myMethod() {
42
}
}
Loading…
Cancel
Save