[java-decompiler] cleanup (arrays to data classes; formatting; typos; dead code)
This commit is contained in:
@@ -46,7 +46,6 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil;
|
||||
import java.util.*;
|
||||
|
||||
public class ClassWriter {
|
||||
|
||||
private final ClassReference14Processor ref14processor;
|
||||
private final PoolInterceptor interceptor;
|
||||
|
||||
@@ -154,15 +153,6 @@ public class ClassWriter {
|
||||
DecompilerContext.getLogger().endWriteClass();
|
||||
}
|
||||
|
||||
private static void addTracer(StructClass cls, StructMethod method, BytecodeMappingTracer tracer) {
|
||||
StructLineNumberTableAttribute lineNumberTable =
|
||||
(StructLineNumberTableAttribute)method.getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_LINE_NUMBER_TABLE);
|
||||
tracer.setLineNumberTable(lineNumberTable);
|
||||
DecompilerContext.getBytecodeSourceMapper().addTracer(cls.qualifiedName,
|
||||
InterpreterUtil.makeUniqueKey(method.getName(), method.getDescriptor()),
|
||||
tracer);
|
||||
}
|
||||
|
||||
public void classToJava(ClassNode node, TextBuffer buffer, int indent, BytecodeMappingTracer tracer) {
|
||||
ClassNode outerNode = (ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE);
|
||||
DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS_NODE, node);
|
||||
@@ -183,12 +173,7 @@ public class ClassWriter {
|
||||
int start_class_def = buffer.length();
|
||||
writeClassDefinition(node, buffer, indent);
|
||||
|
||||
// // count lines in class definition the easiest way
|
||||
// startLine = buffer.substring(start_class_def).toString().split(lineSeparator, -1).length - 1;
|
||||
|
||||
boolean hasContent = false;
|
||||
|
||||
// fields
|
||||
boolean enumFields = false;
|
||||
|
||||
dummy_tracer.incrementCurrentSourceLine(buffer.countLines(start_class_def));
|
||||
@@ -287,6 +272,13 @@ public class ClassWriter {
|
||||
DecompilerContext.getLogger().endWriteClass();
|
||||
}
|
||||
|
||||
private static void addTracer(StructClass cls, StructMethod method, BytecodeMappingTracer tracer) {
|
||||
StructLineNumberTableAttribute table = (StructLineNumberTableAttribute)method.getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_LINE_NUMBER_TABLE);
|
||||
tracer.setLineNumberTable(table);
|
||||
String key = InterpreterUtil.makeUniqueKey(method.getName(), method.getDescriptor());
|
||||
DecompilerContext.getBytecodeSourceMapper().addTracer(cls.qualifiedName, key, tracer);
|
||||
}
|
||||
|
||||
private void writeClassDefinition(ClassNode node, TextBuffer buffer, int indent) {
|
||||
if (node.type == ClassNode.CLASS_ANONYMOUS) {
|
||||
buffer.append(" {").appendLineSeparator();
|
||||
@@ -567,7 +559,7 @@ public class ClassWriter {
|
||||
}
|
||||
}
|
||||
|
||||
public static String toValidJavaIdentifier(String name) {
|
||||
private static String toValidJavaIdentifier(String name) {
|
||||
if (name == null || name.isEmpty()) return name;
|
||||
|
||||
boolean changed = false;
|
||||
@@ -833,8 +825,6 @@ public class ClassWriter {
|
||||
}
|
||||
|
||||
// We do not have line information for method start, lets have it here for now
|
||||
StructLineNumberTableAttribute lineNumberTable =
|
||||
(StructLineNumberTableAttribute)mt.getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_LINE_NUMBER_TABLE);
|
||||
buffer.append('{').appendLineSeparator();
|
||||
tracer.incrementCurrentSourceLine();
|
||||
|
||||
@@ -842,8 +832,6 @@ public class ClassWriter {
|
||||
|
||||
if (root != null && !methodWrapper.decompiledWithErrors) { // check for existence
|
||||
try {
|
||||
int startLine = tracer.getCurrentSourceLine();
|
||||
|
||||
TextBuffer code = root.toJava(indent + 1, tracer);
|
||||
|
||||
hideMethod = (clinit || dinit || hideConstructor(wrapper, init, throwsExceptions, paramCount)) && code.length() == 0;
|
||||
@@ -960,7 +948,6 @@ public class ClassWriter {
|
||||
StructGeneralAttribute.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS, StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS};
|
||||
|
||||
private static void appendAnnotations(TextBuffer buffer, StructMember mb, int indent) {
|
||||
|
||||
BytecodeMappingTracer tracer_dummy = new BytecodeMappingTracer(); // FIXME: replace with a real one
|
||||
|
||||
for (String name : ANNOTATION_ATTRIBUTES) {
|
||||
|
||||
@@ -40,14 +40,22 @@ import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class ClassesProcessor {
|
||||
|
||||
public static final int AVERAGE_CLASS_SIZE = 16 * 1024;
|
||||
|
||||
private final Map<String, ClassNode> mapRootClasses = new HashMap<String, ClassNode>();
|
||||
|
||||
public ClassesProcessor(StructContext context) {
|
||||
private static class Inner {
|
||||
private String simpleName;
|
||||
private int type;
|
||||
private int accessFlags;
|
||||
|
||||
Map<String, Object[]> mapInnerClasses = new HashMap<String, Object[]>();
|
||||
private static boolean equal(Inner o1, Inner o2) {
|
||||
return o1.type == o2.type && o1.accessFlags == o2.accessFlags && InterpreterUtil.equalObjects(o1.simpleName, o2.simpleName);
|
||||
}
|
||||
}
|
||||
|
||||
public ClassesProcessor(StructContext context) {
|
||||
Map<String, Inner> mapInnerClasses = new HashMap<String, Inner>();
|
||||
Map<String, Set<String>> mapNestedClassReferences = new HashMap<String, Set<String>>();
|
||||
Map<String, Set<String>> mapEnclosingClassReferences = new HashMap<String, Set<String>>();
|
||||
Map<String, String> mapNewSimpleNames = new HashMap<String, String>();
|
||||
@@ -57,25 +65,16 @@ public class ClassesProcessor {
|
||||
// create class nodes
|
||||
for (StructClass cl : context.getClasses().values()) {
|
||||
if (cl.isOwn() && !mapRootClasses.containsKey(cl.qualifiedName)) {
|
||||
|
||||
if (bDecompileInner) {
|
||||
StructInnerClassesAttribute inner = (StructInnerClassesAttribute)cl.getAttributes().getWithKey("InnerClasses");
|
||||
|
||||
if (inner != null) {
|
||||
|
||||
for (int i = 0; i < inner.getClassEntries().size(); i++) {
|
||||
|
||||
int[] entry = inner.getClassEntries().get(i);
|
||||
String[] strEntry = inner.getStringEntries().get(i);
|
||||
Object[] arr = new Object[4]; // arr[0] not used
|
||||
String innerName = strEntry[0];
|
||||
|
||||
// nested class type
|
||||
arr[2] = entry[1] == 0 ? (entry[2] == 0 ? ClassNode.CLASS_ANONYMOUS : ClassNode.CLASS_LOCAL) : ClassNode.CLASS_MEMBER;
|
||||
for (StructInnerClassesAttribute.Entry entry : inner.getEntries()) {
|
||||
String innerName = entry.innerName;
|
||||
|
||||
// original simple name
|
||||
String simpleName = strEntry[2];
|
||||
String simpleName = entry.simpleName;
|
||||
String savedName = mapNewSimpleNames.get(innerName);
|
||||
|
||||
if (savedName != null) {
|
||||
simpleName = savedName;
|
||||
}
|
||||
@@ -87,15 +86,15 @@ public class ClassesProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
arr[1] = simpleName;
|
||||
|
||||
// original access flags
|
||||
arr[3] = entry[3];
|
||||
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.accessFlags = entry.accessFlags;
|
||||
|
||||
// enclosing class
|
||||
String enclClassName;
|
||||
if (entry[1] != 0) {
|
||||
enclClassName = strEntry[1];
|
||||
if (entry.outerNameIdx != 0) {
|
||||
enclClassName = entry.enclosingName;
|
||||
}
|
||||
else {
|
||||
enclClassName = cl.qualifiedName;
|
||||
@@ -105,11 +104,11 @@ public class ClassesProcessor {
|
||||
StructClass enclosing_class = context.getClasses().get(enclClassName);
|
||||
if (enclosing_class != null && enclosing_class.isOwn()) { // own classes only
|
||||
|
||||
Object[] arrOld = mapInnerClasses.get(innerName);
|
||||
if (arrOld == null) {
|
||||
mapInnerClasses.put(innerName, arr);
|
||||
Inner existingRec = mapInnerClasses.get(innerName);
|
||||
if (existingRec == null) {
|
||||
mapInnerClasses.put(innerName, rec);
|
||||
}
|
||||
else if (!InterpreterUtil.equalObjectArrays(arrOld, arr)) {
|
||||
else if (!Inner.equal(existingRec, rec)) {
|
||||
String message = "Inconsistent inner class entries for " + innerName + "!";
|
||||
DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN);
|
||||
}
|
||||
@@ -140,12 +139,10 @@ public class ClassesProcessor {
|
||||
}
|
||||
|
||||
if (bDecompileInner) {
|
||||
|
||||
// connect nested classes
|
||||
for (Entry<String, ClassNode> ent : mapRootClasses.entrySet()) {
|
||||
// root class?
|
||||
if (!mapInnerClasses.containsKey(ent.getKey())) {
|
||||
|
||||
Set<String> setVisited = new HashSet<String>();
|
||||
LinkedList<String> stack = new LinkedList<String>();
|
||||
|
||||
@@ -153,7 +150,6 @@ public class ClassesProcessor {
|
||||
setVisited.add(ent.getKey());
|
||||
|
||||
while (!stack.isEmpty()) {
|
||||
|
||||
String superClass = stack.removeFirst();
|
||||
ClassNode superNode = mapRootClasses.get(superClass);
|
||||
|
||||
@@ -163,13 +159,13 @@ public class ClassesProcessor {
|
||||
StructClass scl = superNode.classStruct;
|
||||
StructInnerClassesAttribute inner = (StructInnerClassesAttribute)scl.getAttributes().getWithKey("InnerClasses");
|
||||
|
||||
if (inner == null || inner.getStringEntries().isEmpty()) {
|
||||
if (inner == null || inner.getEntries().isEmpty()) {
|
||||
DecompilerContext.getLogger().writeMessage(superClass + " does not contain inner classes!", IFernflowerLogger.Severity.WARN);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < inner.getStringEntries().size(); i++) {
|
||||
String nestedClass = inner.getStringEntries().get(i)[0];
|
||||
for (StructInnerClassesAttribute.Entry entry : inner.getEntries()) {
|
||||
String nestedClass = entry.innerName;
|
||||
if (!setNestedClasses.contains(nestedClass)) {
|
||||
continue;
|
||||
}
|
||||
@@ -184,21 +180,20 @@ public class ClassesProcessor {
|
||||
continue;
|
||||
}
|
||||
|
||||
Object[] arr = mapInnerClasses.get(nestedClass);
|
||||
Inner rec = mapInnerClasses.get(nestedClass);
|
||||
|
||||
//if ((Integer)arr[2] == ClassNode.CLASS_MEMBER) {
|
||||
// FIXME: check for consistent naming
|
||||
//}
|
||||
|
||||
nestedNode.type = (Integer)arr[2];
|
||||
nestedNode.simpleName = (String)arr[1];
|
||||
nestedNode.access = (Integer)arr[3];
|
||||
nestedNode.simpleName = rec.simpleName;
|
||||
nestedNode.type = rec.type;
|
||||
nestedNode.access = rec.accessFlags;
|
||||
|
||||
if (nestedNode.type == ClassNode.CLASS_ANONYMOUS) {
|
||||
StructClass cl = nestedNode.classStruct;
|
||||
|
||||
// remove static if anonymous class
|
||||
// a common compiler bug
|
||||
// remove static if anonymous class (a common compiler bug)
|
||||
nestedNode.access &= ~CodeConstants.ACC_STATIC;
|
||||
|
||||
int[] interfaces = cl.getInterfaces();
|
||||
@@ -215,8 +210,7 @@ public class ClassesProcessor {
|
||||
}
|
||||
}
|
||||
else if (nestedNode.type == ClassNode.CLASS_LOCAL) {
|
||||
// only abstract and final are permitted
|
||||
// a common compiler bug
|
||||
// only abstract and final are permitted (a common compiler bug)
|
||||
nestedNode.access &= (CodeConstants.ACC_ABSTRACT | CodeConstants.ACC_FINAL);
|
||||
}
|
||||
|
||||
@@ -301,7 +295,6 @@ public class ClassesProcessor {
|
||||
}
|
||||
|
||||
private static void initWrappers(ClassNode node) throws IOException {
|
||||
|
||||
if (node.type == ClassNode.CLASS_LAMBDA) {
|
||||
return;
|
||||
}
|
||||
@@ -317,7 +310,6 @@ public class ClassesProcessor {
|
||||
}
|
||||
|
||||
private static void addClassnameToImport(ClassNode node, ImportCollector imp) {
|
||||
|
||||
if (node.simpleName != null && node.simpleName.length() > 0) {
|
||||
imp.getShortName(node.type == ClassNode.CLASS_ROOT ? node.classStruct.qualifiedName : node.simpleName, false);
|
||||
}
|
||||
@@ -328,7 +320,6 @@ public class ClassesProcessor {
|
||||
}
|
||||
|
||||
private static void destroyWrappers(ClassNode node) {
|
||||
|
||||
node.wrapper = null;
|
||||
node.classStruct.releaseResources();
|
||||
|
||||
@@ -343,7 +334,6 @@ public class ClassesProcessor {
|
||||
|
||||
|
||||
public static class ClassNode {
|
||||
|
||||
public static final int CLASS_ROOT = 0;
|
||||
public static final int CLASS_MEMBER = 1;
|
||||
public static final int CLASS_ANONYMOUS = 2;
|
||||
|
||||
@@ -21,13 +21,9 @@ import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class BytecodeMappingTracer {
|
||||
|
||||
private int currentSourceLine;
|
||||
|
||||
private StructLineNumberTableAttribute lineNumberTable = null;
|
||||
|
||||
// bytecode offset, source line
|
||||
private final Map<Integer, Integer> mapping = new HashMap<Integer, Integer>();
|
||||
private final Map<Integer, Integer> mapping = new HashMap<Integer, Integer>(); // bytecode offset, source line
|
||||
|
||||
public BytecodeMappingTracer() { }
|
||||
|
||||
@@ -43,12 +39,6 @@ public class BytecodeMappingTracer {
|
||||
currentSourceLine += number_lines;
|
||||
}
|
||||
|
||||
public void shiftSourceLines(int shift) {
|
||||
for (Entry<Integer, Integer> entry : mapping.entrySet()) {
|
||||
entry.setValue(entry.getValue() + shift);
|
||||
}
|
||||
}
|
||||
|
||||
public void addMapping(int bytecode_offset) {
|
||||
if (!mapping.containsKey(bytecode_offset)) {
|
||||
mapping.put(bytecode_offset, currentSourceLine);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -36,7 +36,6 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class NewExprent extends Exprent {
|
||||
|
||||
private InvocationExprent constructor;
|
||||
private final VarType newType;
|
||||
private List<Exprent> lstDims = new ArrayList<Exprent>();
|
||||
@@ -80,12 +79,7 @@ public class NewExprent extends Exprent {
|
||||
|
||||
@Override
|
||||
public VarType getExprType() {
|
||||
if (anonymous) {
|
||||
return DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.value).anonymousClassType;
|
||||
}
|
||||
else {
|
||||
return newType;
|
||||
}
|
||||
return anonymous ? DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.value).anonymousClassType : newType;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -163,24 +157,22 @@ public class NewExprent extends Exprent {
|
||||
TextBuffer buf = new TextBuffer();
|
||||
|
||||
if (anonymous) {
|
||||
|
||||
ClassNode child = DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.value);
|
||||
|
||||
buf.append("(");
|
||||
|
||||
if (!lambda && constructor != null) {
|
||||
InvocationExprent invSuper = child.superInvocation;
|
||||
|
||||
InvocationExprent invsuper = child.superInvocation;
|
||||
|
||||
ClassNode newnode = DecompilerContext.getClassProcessor().getMapRootClasses().get(invsuper.getClassname());
|
||||
ClassNode newNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(invSuper.getClassname());
|
||||
|
||||
List<VarVersionPair> sigFields = null;
|
||||
if (newnode != null) { // own class
|
||||
if (newnode.getWrapper() != null) {
|
||||
sigFields = newnode.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, invsuper.getStringDescriptor()).signatureFields;
|
||||
if (newNode != null) { // own class
|
||||
if (newNode.getWrapper() != null) {
|
||||
sigFields = newNode.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, invSuper.getStringDescriptor()).signatureFields;
|
||||
}
|
||||
else {
|
||||
if (newnode.type == ClassNode.CLASS_MEMBER && (newnode.access & CodeConstants.ACC_STATIC) == 0 &&
|
||||
if (newNode.type == ClassNode.CLASS_MEMBER && (newNode.access & CodeConstants.ACC_STATIC) == 0 &&
|
||||
!constructor.getLstParameters().isEmpty()) { // member non-static class invoked with enclosing class instance
|
||||
sigFields = new ArrayList<VarVersionPair>(Collections.nCopies(constructor.getLstParameters().size(), (VarVersionPair)null));
|
||||
sigFields.set(0, new VarVersionPair(-1, 0));
|
||||
@@ -188,31 +180,29 @@ public class NewExprent extends Exprent {
|
||||
}
|
||||
}
|
||||
|
||||
boolean firstpar = true;
|
||||
int start = 0, end = invsuper.getLstParameters().size();
|
||||
boolean firstParam = true;
|
||||
int start = 0, end = invSuper.getLstParameters().size();
|
||||
if (enumConst) {
|
||||
start += 2;
|
||||
end -= 1;
|
||||
}
|
||||
for (int i = start; i < end; i++) {
|
||||
if (sigFields == null || sigFields.get(i) == null) {
|
||||
if (!firstpar) {
|
||||
if (!firstParam) {
|
||||
buf.append(", ");
|
||||
}
|
||||
|
||||
Exprent param = invsuper.getLstParameters().get(i);
|
||||
Exprent param = invSuper.getLstParameters().get(i);
|
||||
if (param.type == Exprent.EXPRENT_VAR) {
|
||||
int varindex = ((VarExprent)param).getIndex();
|
||||
if (varindex > 0 && varindex <= constructor.getLstParameters().size()) {
|
||||
param = constructor.getLstParameters().get(varindex - 1);
|
||||
int varIndex = ((VarExprent)param).getIndex();
|
||||
if (varIndex > 0 && varIndex <= constructor.getLstParameters().size()) {
|
||||
param = constructor.getLstParameters().get(varIndex - 1);
|
||||
}
|
||||
}
|
||||
|
||||
TextBuffer buff = new TextBuffer();
|
||||
ExprProcessor.getCastedExprent(param, invsuper.getDescriptor().params[i], buff, indent, true, tracer);
|
||||
ExprProcessor.getCastedExprent(param, invSuper.getDescriptor().params[i], buf, indent, true, tracer);
|
||||
|
||||
buf.append(buff);
|
||||
firstpar = false;
|
||||
firstParam = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -226,14 +216,15 @@ public class NewExprent extends Exprent {
|
||||
String typename = ExprProcessor.getCastTypeName(child.anonymousClassType);
|
||||
|
||||
if (enclosing != null) {
|
||||
ClassNode anonimousNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(child.anonymousClassType.value);
|
||||
if (anonimousNode != null) {
|
||||
typename = anonimousNode.simpleName;
|
||||
ClassNode anonymousNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(child.anonymousClassType.value);
|
||||
if (anonymousNode != null) {
|
||||
typename = anonymousNode.simpleName;
|
||||
}
|
||||
else {
|
||||
typename = typename.substring(typename.lastIndexOf('.') + 1);
|
||||
}
|
||||
}
|
||||
|
||||
buf.prepend("new " + typename);
|
||||
|
||||
if (enclosing != null) {
|
||||
@@ -275,28 +266,23 @@ public class NewExprent extends Exprent {
|
||||
}
|
||||
buf.append("}");
|
||||
}
|
||||
else {
|
||||
if (newType.arrayDim == 0) {
|
||||
|
||||
else if (newType.arrayDim == 0) {
|
||||
if (constructor != null) {
|
||||
|
||||
List<Exprent> lstParameters = constructor.getLstParameters();
|
||||
|
||||
ClassNode newnode = DecompilerContext.getClassProcessor().getMapRootClasses().get(constructor.getClassname());
|
||||
ClassNode newNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(constructor.getClassname());
|
||||
|
||||
List<VarVersionPair> sigFields = null;
|
||||
if (newnode != null) { // own class
|
||||
if (newnode.getWrapper() != null) {
|
||||
sigFields = newnode.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, constructor.getStringDescriptor()).signatureFields;
|
||||
if (newNode != null) { // own class
|
||||
if (newNode.getWrapper() != null) {
|
||||
sigFields = newNode.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, constructor.getStringDescriptor()).signatureFields;
|
||||
}
|
||||
else {
|
||||
if (newnode.type == ClassNode.CLASS_MEMBER && (newnode.access & CodeConstants.ACC_STATIC) == 0 &&
|
||||
!constructor.getLstParameters().isEmpty()) { // member non-static class invoked with enclosing class instance
|
||||
else if (newNode.type == ClassNode.CLASS_MEMBER && (newNode.access & CodeConstants.ACC_STATIC) == 0 && !constructor.getLstParameters().isEmpty()) {
|
||||
// member non-static class invoked with enclosing class instance
|
||||
sigFields = new ArrayList<VarVersionPair>(Collections.nCopies(lstParameters.size(), (VarVersionPair)null));
|
||||
sigFields.set(0, new VarVersionPair(-1, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int start = enumConst ? 2 : 0;
|
||||
if (!enumConst || start < lstParameters.size()) {
|
||||
@@ -319,9 +305,7 @@ public class NewExprent extends Exprent {
|
||||
buf.append(", ");
|
||||
}
|
||||
|
||||
TextBuffer buff = new TextBuffer();
|
||||
ExprProcessor.getCastedExprent(expr, leftType, buff, indent, true, tracer);
|
||||
buf.append(buff);
|
||||
ExprProcessor.getCastedExprent(expr, leftType, buf, indent, true, tracer);
|
||||
|
||||
firstParam = false;
|
||||
}
|
||||
@@ -378,15 +362,12 @@ public class NewExprent extends Exprent {
|
||||
if (i > 0) {
|
||||
buf.append(", ");
|
||||
}
|
||||
TextBuffer buff = new TextBuffer();
|
||||
ExprProcessor.getCastedExprent(lstArrayElements.get(i), leftType, buff, indent, false, tracer);
|
||||
|
||||
buf.append(buff);
|
||||
ExprProcessor.getCastedExprent(lstArrayElements.get(i), leftType, buf, indent, false, tracer);
|
||||
}
|
||||
buf.append("}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,9 +24,27 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class StructInnerClassesAttribute extends StructGeneralAttribute {
|
||||
public static class Entry {
|
||||
public final int innerNameIdx;
|
||||
public final int outerNameIdx;
|
||||
public final int simpleNameIdx;
|
||||
public final int accessFlags;
|
||||
public final String innerName;
|
||||
public final String enclosingName;
|
||||
public final String simpleName;
|
||||
|
||||
private List<int[]> classEntries;
|
||||
private List<String[]> stringEntries;
|
||||
private Entry(int innerNameIdx, int outerNameIdx, int simpleNameIdx, int accessFlags, String innerName, String enclosingName, String simpleName) {
|
||||
this.innerNameIdx = innerNameIdx;
|
||||
this.outerNameIdx = outerNameIdx;
|
||||
this.simpleNameIdx = simpleNameIdx;
|
||||
this.accessFlags = accessFlags;
|
||||
this.innerName = innerName;
|
||||
this.enclosingName = enclosingName;
|
||||
this.simpleName = simpleName;
|
||||
}
|
||||
}
|
||||
|
||||
private List<Entry> entries;
|
||||
|
||||
@Override
|
||||
public void initContent(ConstantPool pool) throws IOException {
|
||||
@@ -34,39 +52,27 @@ public class StructInnerClassesAttribute extends StructGeneralAttribute {
|
||||
|
||||
int len = data.readUnsignedShort();
|
||||
if (len > 0) {
|
||||
classEntries = new ArrayList<int[]>(len);
|
||||
stringEntries = new ArrayList<String[]>(len);
|
||||
entries = new ArrayList<Entry>(len);
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
int[] classEntry = new int[4];
|
||||
for (int j = 0; j < 4; j++) {
|
||||
classEntry[j] = data.readUnsignedShort();
|
||||
}
|
||||
classEntries.add(classEntry);
|
||||
int innerNameIdx = data.readUnsignedShort();
|
||||
int outerNameIdx = data.readUnsignedShort();
|
||||
int simpleNameIdx = data.readUnsignedShort();
|
||||
int accessFlags = data.readUnsignedShort();
|
||||
|
||||
// inner name, enclosing class, original simple name
|
||||
String[] stringEntry = new String[3];
|
||||
stringEntry[0] = pool.getPrimitiveConstant(classEntry[0]).getString();
|
||||
if (classEntry[1] != 0) {
|
||||
stringEntry[1] = pool.getPrimitiveConstant(classEntry[1]).getString();
|
||||
}
|
||||
if (classEntry[2] != 0) {
|
||||
stringEntry[2] = pool.getPrimitiveConstant(classEntry[2]).getString();
|
||||
}
|
||||
stringEntries.add(stringEntry);
|
||||
String innerName = pool.getPrimitiveConstant(innerNameIdx).getString();
|
||||
String outerName = outerNameIdx != 0 ? pool.getPrimitiveConstant(outerNameIdx).getString() : null;
|
||||
String simpleName = simpleNameIdx != 0 ? pool.getPrimitiveConstant(simpleNameIdx).getString() : null;
|
||||
|
||||
entries.add(new Entry(innerNameIdx, outerNameIdx, simpleNameIdx, accessFlags, innerName, outerName, simpleName));
|
||||
}
|
||||
}
|
||||
else {
|
||||
classEntries = Collections.emptyList();
|
||||
stringEntries = Collections.emptyList();
|
||||
entries = Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
public List<int[]> getClassEntries() {
|
||||
return classEntries;
|
||||
}
|
||||
|
||||
public List<String[]> getStringEntries() {
|
||||
return stringEntries;
|
||||
public List<Entry> getEntries() {
|
||||
return entries;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,25 +120,6 @@ public class InterpreterUtil {
|
||||
return first == null ? second == null : first.equals(second);
|
||||
}
|
||||
|
||||
public static boolean equalObjectArrays(Object[] first, Object[] second) {
|
||||
if (first == null || second == null) {
|
||||
return equalObjects(first, second);
|
||||
}
|
||||
else {
|
||||
if (first.length != second.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < first.length; i++) {
|
||||
if (!equalObjects(first[i], second[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean equalLists(List<?> first, List<?> second) {
|
||||
if (first == null) {
|
||||
return second == null;
|
||||
@@ -172,6 +153,10 @@ public class InterpreterUtil {
|
||||
}
|
||||
|
||||
public static String makeUniqueKey(String name, String descriptor) {
|
||||
return name + " " + descriptor;
|
||||
return name + ' ' + descriptor;
|
||||
}
|
||||
|
||||
public static String makeUniqueKey(String name, String descriptor1, String descriptor2) {
|
||||
return name + ' ' + descriptor1 + ' ' + descriptor2;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user