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
stable
jochen 25 years ago
parent 288a4b2980
commit 4da464b464
  1. 167
      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) {

Loading…
Cancel
Save