From 4da464b4648cdd00e64e2ae2155a03a8a4319072 Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 17 Jun 1999 11:09:08 +0000 Subject: [PATCH] handle anonymous / method scope classes don't print nasty empty lines git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@860 379699f6-c40d-0410-875b-85095c16579e --- jode/jode/decompiler/ClassAnalyzer.java | 167 ++++++++++++++---------- 1 file changed, 101 insertions(+), 66 deletions(-) diff --git a/jode/jode/decompiler/ClassAnalyzer.java b/jode/jode/decompiler/ClassAnalyzer.java index 2637a43..8604e35 100644 --- a/jode/jode/decompiler/ClassAnalyzer.java +++ b/jode/jode/decompiler/ClassAnalyzer.java @@ -26,12 +26,13 @@ import jode.bytecode.MethodInfo; import jode.bytecode.InnerClassInfo; import jode.bytecode.ConstantPool; import jode.expr.Expression; +import jode.expr.ThisOperator; import jode.expr.ConstructorOperator; import jode.flow.TransformConstructors; import java.util.NoSuchElementException; import java.lang.reflect.Modifier; -public class ClassAnalyzer implements Analyzer, Scope { +public class ClassAnalyzer implements Analyzer, Scope, Declarable { ImportHandler imports; ClassInfo clazz; Object parent; @@ -45,20 +46,23 @@ public class ClassAnalyzer implements Analyzer, Scope { MethodAnalyzer staticConstructor; MethodAnalyzer[] constructors; + Expression[] outerValues; public ClassAnalyzer(Object parent, - ClassInfo clazz, ImportHandler imports) + ClassInfo clazz, ImportHandler imports, + Expression[] outerValues) { clazz.loadInfo(clazz.FULLINFO); this.parent = parent; this.clazz = clazz; this.imports = imports; + this.outerValues = outerValues; modifiers = clazz.getModifiers(); name = clazz.getName(); if (parent != null) { InnerClassInfo[] outerInfos = clazz.getOuterClasses(); - if (outerInfos[0].outer == null) { + if (outerInfos[0].outer == null || outerInfos[0].name == null) { if (parent instanceof ClassAnalyzer) throw new jode.AssertError ("ClassInfo Attributes are inconsistent: " @@ -82,6 +86,12 @@ public class ClassAnalyzer implements Analyzer, Scope { } } + public ClassAnalyzer(Object parent, + ClassInfo clazz, ImportHandler imports) + { + this(parent, clazz, imports, null); + } + public ClassAnalyzer(ClassInfo clazz, ImportHandler imports) { this(null, clazz, imports); @@ -118,6 +128,10 @@ public class ClassAnalyzer implements Analyzer, Scope { return clazz; } + public Expression[] getOuterValues() { + return outerValues; + } + public void analyze() { FieldInfo[] finfos = clazz.getFields(); MethodInfo[] minfos = clazz.getMethods(); @@ -132,11 +146,18 @@ public class ClassAnalyzer implements Analyzer, Scope { if ((Decompiler.options & Decompiler.OPTION_INNER) != 0 && innerInfos != null) { + Expression[] outerThis = new Expression[] { + new ThisOperator(clazz) + }; + int innerCount = innerInfos.length; inners = new ClassAnalyzer[innerCount]; for (int i=0; i < innerCount; i++) { + ClassInfo ci = ClassInfo.forName(innerInfos[i].inner); inners[i] = new ClassAnalyzer - (this, ClassInfo.forName(innerInfos[i].inner), imports); + (this, ci, imports, + Modifier.isStatic(innerInfos[i].modifiers) + ? null : outerThis); } } else inners = new ClassAnalyzer[0]; @@ -164,30 +185,33 @@ public class ClassAnalyzer implements Analyzer, Scope { // now analyze constructors: constructors = new MethodAnalyzer[constrVector.size()]; - if (constructors.length > 0) { + if (constructors.length > 0) { constrVector.copyInto(constructors); for (int j=0; j< constructors.length; j++) constructors[j].analyze(); - TransformConstructors.transform - (this, false, parent instanceof ClassAnalyzer, - parent instanceof ConstructorOperator, constructors); + + TransformConstructors.transform(this, false, constructors); } if (staticConstructor != null) { staticConstructor.analyze(); - TransformConstructors.transform(this, true, false, false, - new MethodAnalyzer[] - { staticConstructor }); + TransformConstructors.transform + (this, true, new MethodAnalyzer[] { staticConstructor }); } // Now analyze remaining methods. for (int j=0; j < methods.length; j++) { - if (!methods[j].isConstructor()) + if (!methods[j].isConstructor() + && !methods[j].isJikesConstructor) methods[j].analyze(); } // Now analyze the inner classes. for (int j=0; j < inners.length; j++) inners[j].analyze(); + // Now analyze the method scoped classes. + for (int j=0; j < methods.length; j++) + methods[j].analyzeAnonymousClasses(); + imports.useClass(clazz); if (clazz.getSuperclass() != null) imports.useClass(clazz.getSuperclass()); @@ -204,6 +228,36 @@ public class ClassAnalyzer implements Analyzer, Scope { this.name = name; } + public void dumpDeclaration(TabbedPrintWriter writer) + throws java.io.IOException + { + dumpSource(writer); + } + + public void dumpBlock(TabbedPrintWriter writer) throws java.io.IOException + { + boolean needNewLine = false; + for (int i=0; i< fields.length; i++) { + if (fields[i].skipWriting()) + continue; + fields[i].dumpSource(writer); + needNewLine = true; + } + for (int i=0; i< inners.length; i++) { + if (needNewLine) + writer.println(""); + inners[i].dumpSource(writer); + } + for (int i=0; i< methods.length; i++) { + if (methods[i].skipWriting()) + continue; + if (needNewLine) + writer.println(""); + methods[i].dumpSource(writer); + needNewLine = true; + } + } + public void dumpSource(TabbedPrintWriter writer) throws java.io.IOException { if (fields == null) { @@ -213,74 +267,50 @@ public class ClassAnalyzer implements Analyzer, Scope { return; } writer.pushScope(this); + int modifiedModifiers = modifiers & ~Modifier.SYNCHRONIZED; if (clazz.isInterface()) modifiedModifiers &= ~Modifier.ABSTRACT; + if (parent instanceof CodeAnalyzer) { + /* method scope classes are implicitly private */ + modifiedModifiers &= ~Modifier.PRIVATE; + /* anonymous classes are implicitly final */ + if (name == null) + modifiedModifiers &= ~Modifier.FINAL; + } String modif = Modifier.toString(modifiedModifiers); if (modif.length() > 0) writer.print(modif + " "); /*interface is in modif*/ if (!clazz.isInterface()) writer.print("class "); - if (parent != null && name == null) { - /* This is an anonymous class */ - ClassInfo superClazz = clazz.getSuperclass(); - ClassInfo[] interfaces = clazz.getInterfaces(); - if (interfaces.length == 1 - && (superClazz == null - || superClazz == ClassInfo.javaLangObject)) { - writer.print(writer.getClassString(interfaces[0], - Scope.CLASSNAME)); - } else { - if (interfaces.length > 0) { - writer.print("/*too many supers*/ "); - for (int i=0; i< interfaces.length; i++) - writer.print(writer.getClassString - (interfaces[i], Scope.CLASSNAME) + ","); - } - if (superClazz == null) - writer.print(writer.getClassString - (ClassInfo.javaLangObject, Scope.CLASSNAME)); - else - writer.print(writer.getClassString - (superClazz, Scope.CLASSNAME)); - } - } else { - writer.println(name); - writer.tab(); - ClassInfo superClazz = clazz.getSuperclass(); - if (superClazz != null && - superClazz != ClassInfo.javaLangObject) { - writer.println("extends " + (writer.getClassString - (superClazz, Scope.CLASSNAME))); - } - ClassInfo[] interfaces = clazz.getInterfaces(); - if (interfaces.length > 0) { - writer.print(clazz.isInterface() ? "extends " : "implements "); - for (int i=0; i < interfaces.length; i++) { - if (i > 0) - writer.print(", "); - writer.print(writer.getClassString - (interfaces[i], Scope.CLASSNAME)); - } - writer.println(""); + writer.println(name); + writer.tab(); + ClassInfo superClazz = clazz.getSuperclass(); + if (superClazz != null && + superClazz != ClassInfo.javaLangObject) { + writer.println("extends " + (writer.getClassString + (superClazz, Scope.CLASSNAME))); + } + ClassInfo[] interfaces = clazz.getInterfaces(); + if (interfaces.length > 0) { + writer.print(clazz.isInterface() ? "extends " : "implements "); + for (int i=0; i < interfaces.length; i++) { + if (i > 0) + writer.print(", "); + writer.print(writer.getClassString + (interfaces[i], Scope.CLASSNAME)); } - writer.untab(); + writer.println(""); } + writer.untab(); + writer.openBrace(); writer.tab(); - - for (int i=0; i< fields.length; i++) - fields[i].dumpSource(writer); - for (int i=0; i< inners.length; i++) { - writer.println(""); - inners[i].dumpSource(writer); - } - for (int i=0; i< methods.length; i++) - methods[i].dumpSource(writer); + dumpBlock(writer); writer.untab(); - if (parent != null && name == null) { - /* This is an anonymous class */ + if (parent instanceof CodeAnalyzer) { + /* This is a method scope class */ writer.closeBraceNoSpace(); } else writer.closeBrace(); @@ -303,6 +333,11 @@ public class ClassAnalyzer implements Analyzer, Scope { return false; } + static int serialnr = 0; + public void makeNameUnique() { + name = name + "_" + serialnr++ + "_"; + } + public boolean conflicts(String name, int usageType) { ClassInfo info = clazz; while (info != null) {