From 686b5abef9c269a726897c6992d0ea2abea79b04 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 4 Sep 2014 18:16:16 +0400 Subject: [PATCH] java-decompiler: optimization (empty lists allocation avoided) --- .../decompiler/main/ClassesProcessor.java | 10 +- .../main/rels/NestedClassProcessor.java | 2 +- .../modules/decompiler/vars/VarProcessor.java | 3 +- .../attr/StructAnnDefaultAttribute.java | 13 +- .../attr/StructAnnotationAttribute.java | 252 +++++++++--------- .../StructAnnotationParameterAttribute.java | 29 +- .../attr/StructAnnotationTypeAttribute.java | 119 ++++----- .../attr/StructBootstrapMethodsAttribute.java | 47 ++-- .../attr/StructConstantValueAttribute.java | 9 +- .../attr/StructEnclosingMethodAttribute.java | 35 ++- .../attr/StructExceptionsAttribute.java | 29 +- .../struct/attr/StructGeneralAttribute.java | 15 +- .../attr/StructGenericSignatureAttribute.java | 10 +- .../attr/StructInnerClassesAttribute.java | 70 ++--- .../StructLocalVariableTableAttribute.java | 45 +++- 15 files changed, 345 insertions(+), 343 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java index 0fc74fd..74c86d0 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java @@ -61,10 +61,10 @@ public class ClassesProcessor { StructInnerClassesAttribute inner = (StructInnerClassesAttribute)cl.getAttributes().getWithKey("InnerClasses"); if (inner != null) { - for (int i = 0; i < inner.getClassentries().size(); i++) { + for (int i = 0; i < inner.getClassEntries().size(); i++) { - int[] entry = inner.getClassentries().get(i); - String[] strentry = inner.getStringentries().get(i); + int[] entry = inner.getClassEntries().get(i); + String[] strentry = inner.getStringEntries().get(i); Object[] arr = new Object[4]; // arr[0] not used @@ -165,8 +165,8 @@ public class ClassesProcessor { StructClass scl = supernode.classStruct; StructInnerClassesAttribute inner = (StructInnerClassesAttribute)scl.getAttributes().getWithKey("InnerClasses"); - for (int i = 0; i < inner.getStringentries().size(); i++) { - String nestedClass = inner.getStringentries().get(i)[0]; + for (int i = 0; i < inner.getStringEntries().size(); i++) { + String nestedClass = inner.getStringEntries().get(i)[0]; if (!setNestedClasses.contains(nestedClass)) { continue; } diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java index 3757d7e..684864d 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java @@ -201,7 +201,7 @@ public class NestedClassProcessor { StructEnclosingMethodAttribute attr = (StructEnclosingMethodAttribute)child.classStruct.getAttributes().getWithKey("EnclosingMethod"); if (attr != null && attr.getMethodName() != null) { - if (node.classStruct.qualifiedName.equals(attr.getClassname()) && + if (node.classStruct.qualifiedName.equals(attr.getClassName()) && node.classStruct.getMethod(attr.getMethodName(), attr.getMethodDescriptor()) != null) { child.enclosingMethod = InterpreterUtil.makeUniqueKey(attr.getMethodName(), attr.getMethodDescriptor()); continue; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java index 5783ea7..266ba94 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java @@ -51,8 +51,7 @@ public class VarProcessor { defproc.setVarDefinitions(); } - public void setDebugVarNames(HashMap mapDebugVarNames) { - + public void setDebugVarNames(Map mapDebugVarNames) { if (varvers == null) { return; } diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnDefaultAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnDefaultAttribute.java index f36df6d..fbad47e 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnDefaultAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnDefaultAttribute.java @@ -18,20 +18,15 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; - +import java.io.IOException; public class StructAnnDefaultAttribute extends StructGeneralAttribute { private Exprent defaultValue; - public void initContent(ConstantPool pool) { - - name = ATTRIBUTE_ANNOTATION_DEFAULT; - - DataInputStream data = new DataInputStream(new ByteArrayInputStream(info)); - defaultValue = StructAnnotationAttribute.parseAnnotationElement(data, pool); + @Override + public void initContent(ConstantPool pool) throws IOException { + defaultValue = StructAnnotationAttribute.parseAnnotationElement(stream(), pool); } public Exprent getDefaultValue() { diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java index 2a2c74c..d04cb04 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java @@ -22,160 +22,162 @@ import org.jetbrains.java.decompiler.struct.consts.PrimitiveConstant; import org.jetbrains.java.decompiler.struct.gen.FieldDescriptor; import org.jetbrains.java.decompiler.struct.gen.VarType; -import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class StructAnnotationAttribute extends StructGeneralAttribute { private List annotations; - public void initContent(ConstantPool pool) { - - super.initContent(pool); - - annotations = new ArrayList(); - DataInputStream data = new DataInputStream(new ByteArrayInputStream(info, 2, info.length)); - - int len = (((info[0] & 0xFF) << 8) | (info[1] & 0xFF)); - for (int i = 0; i < len; i++) { - annotations.add(parseAnnotation(data, pool)); - } + @Override + public void initContent(ConstantPool pool) throws IOException { + annotations = parseAnnotations(pool, stream()); } - public static AnnotationExprent parseAnnotation(DataInputStream data, ConstantPool pool) { - - try { - - String classname = pool.getPrimitiveConstant(data.readUnsignedShort()).getString(); - VarType cltype = new VarType(classname); - - int len = data.readUnsignedShort(); - - List parnames = new ArrayList(); - List parvalues = new ArrayList(); - + public static List parseAnnotations(ConstantPool pool, DataInputStream data) throws IOException { + int len = data.readUnsignedShort(); + if (len > 0) { + List annotations = new ArrayList(len); for (int i = 0; i < len; i++) { - parnames.add(pool.getPrimitiveConstant(data.readUnsignedShort()).getString()); - parvalues.add(parseAnnotationElement(data, pool)); + annotations.add(parseAnnotation(data, pool)); } - - return new AnnotationExprent(cltype.value, parnames, parvalues); + return annotations; } - catch (IOException ex) { - throw new RuntimeException(ex); + else { + return Collections.emptyList(); } } - public static Exprent parseAnnotationElement(DataInputStream data, ConstantPool pool) { + public static AnnotationExprent parseAnnotation(DataInputStream data, ConstantPool pool) throws IOException { + String className = pool.getPrimitiveConstant(data.readUnsignedShort()).getString(); - try { - int tag = data.readUnsignedByte(); + List names; + List values; + int len = data.readUnsignedShort(); + if (len > 0) { + names = new ArrayList(len); + values = new ArrayList(len); + for (int i = 0; i < len; i++) { + names.add(pool.getPrimitiveConstant(data.readUnsignedShort()).getString()); + values.add(parseAnnotationElement(data, pool)); + } + } + else { + names = Collections.emptyList(); + values = Collections.emptyList(); + } - switch (tag) { - case 'e': // enum constant - String classname = pool.getPrimitiveConstant(data.readUnsignedShort()).getString(); - String constname = pool.getPrimitiveConstant(data.readUnsignedShort()).getString(); + return new AnnotationExprent(new VarType(className).value, names, values); + } - FieldDescriptor descr = FieldDescriptor.parseDescriptor(classname); - return new FieldExprent(constname, descr.type.value, true, null, descr); - case 'c': // class - String descriptor = pool.getPrimitiveConstant(data.readUnsignedShort()).getString(); - VarType type = FieldDescriptor.parseDescriptor(descriptor).type; + public static Exprent parseAnnotationElement(DataInputStream data, ConstantPool pool) throws IOException { + int tag = data.readUnsignedByte(); - String value; - switch (type.type) { - case CodeConstants.TYPE_OBJECT: - value = type.value; - break; - case CodeConstants.TYPE_BYTE: - value = byte.class.getName(); - break; - case CodeConstants.TYPE_CHAR: - value = char.class.getName(); - break; - case CodeConstants.TYPE_DOUBLE: - value = double.class.getName(); - break; - case CodeConstants.TYPE_FLOAT: - value = float.class.getName(); - break; - case CodeConstants.TYPE_INT: - value = int.class.getName(); - break; - case CodeConstants.TYPE_LONG: - value = long.class.getName(); - break; - case CodeConstants.TYPE_SHORT: - value = short.class.getName(); - break; - case CodeConstants.TYPE_BOOLEAN: - value = boolean.class.getName(); - break; - case CodeConstants.TYPE_VOID: - value = void.class.getName(); - break; - default: - throw new RuntimeException("invalid class type: " + type.type); - } - return new ConstExprent(VarType.VARTYPE_CLASS, value); - case '[': // array - int len = data.readUnsignedShort(); - List lst = new ArrayList(); + switch (tag) { + case 'e': // enum constant + String className = pool.getPrimitiveConstant(data.readUnsignedShort()).getString(); + String constName = pool.getPrimitiveConstant(data.readUnsignedShort()).getString(); + FieldDescriptor descr = FieldDescriptor.parseDescriptor(className); + return new FieldExprent(constName, descr.type.value, true, null, descr); + case 'c': // class + String descriptor = pool.getPrimitiveConstant(data.readUnsignedShort()).getString(); + VarType type = FieldDescriptor.parseDescriptor(descriptor).type; + + String value; + switch (type.type) { + case CodeConstants.TYPE_OBJECT: + value = type.value; + break; + case CodeConstants.TYPE_BYTE: + value = byte.class.getName(); + break; + case CodeConstants.TYPE_CHAR: + value = char.class.getName(); + break; + case CodeConstants.TYPE_DOUBLE: + value = double.class.getName(); + break; + case CodeConstants.TYPE_FLOAT: + value = float.class.getName(); + break; + case CodeConstants.TYPE_INT: + value = int.class.getName(); + break; + case CodeConstants.TYPE_LONG: + value = long.class.getName(); + break; + case CodeConstants.TYPE_SHORT: + value = short.class.getName(); + break; + case CodeConstants.TYPE_BOOLEAN: + value = boolean.class.getName(); + break; + case CodeConstants.TYPE_VOID: + value = void.class.getName(); + break; + default: + throw new RuntimeException("invalid class type: " + type.type); + } + return new ConstExprent(VarType.VARTYPE_CLASS, value); + + case '[': // array + List elements = Collections.emptyList(); + int len = data.readUnsignedShort(); + if (len > 0) { + elements = new ArrayList(len); for (int i = 0; i < len; i++) { - lst.add(parseAnnotationElement(data, pool)); + elements.add(parseAnnotationElement(data, pool)); } + } - VarType newtype; - if (lst.isEmpty()) { - newtype = new VarType(CodeConstants.TYPE_OBJECT, 1, "java/lang/Object"); - } - else { - VarType eltype = lst.get(0).getExprType(); - newtype = new VarType(eltype.type, 1, eltype.value); - } + VarType newType; + if (elements.isEmpty()) { + newType = new VarType(CodeConstants.TYPE_OBJECT, 1, "java/lang/Object"); + } + else { + VarType elementType = elements.get(0).getExprType(); + newType = new VarType(elementType.type, 1, elementType.value); + } - NewExprent newexpr = new NewExprent(newtype, new ArrayList()); - newexpr.setDirectArrayInit(true); - newexpr.setLstArrayElements(lst); - return newexpr; - case '@': // annotation - return parseAnnotation(data, pool); - default: - PrimitiveConstant cn = pool.getPrimitiveConstant(data.readUnsignedShort()); - switch (tag) { - case 'B': - return new ConstExprent(VarType.VARTYPE_BYTE, cn.value); - case 'C': - return new ConstExprent(VarType.VARTYPE_CHAR, cn.value); - case 'D': - return new ConstExprent(VarType.VARTYPE_DOUBLE, cn.value); - case 'F': - return new ConstExprent(VarType.VARTYPE_FLOAT, cn.value); - case 'I': - return new ConstExprent(VarType.VARTYPE_INT, cn.value); - case 'J': - return new ConstExprent(VarType.VARTYPE_LONG, cn.value); - case 'S': - return new ConstExprent(VarType.VARTYPE_SHORT, cn.value); - case 'Z': - return new ConstExprent(VarType.VARTYPE_BOOLEAN, cn.value); - case 's': - return new ConstExprent(VarType.VARTYPE_STRING, cn.value); - default: - throw new RuntimeException("invalid element type!"); - } - } - } - catch (IOException ex) { - throw new RuntimeException(ex); + NewExprent newExpr = new NewExprent(newType, Collections.emptyList()); + newExpr.setDirectArrayInit(true); + newExpr.setLstArrayElements(elements); + return newExpr; + + case '@': // annotation + return parseAnnotation(data, pool); + + default: + PrimitiveConstant cn = pool.getPrimitiveConstant(data.readUnsignedShort()); + switch (tag) { + case 'B': + return new ConstExprent(VarType.VARTYPE_BYTE, cn.value); + case 'C': + return new ConstExprent(VarType.VARTYPE_CHAR, cn.value); + case 'D': + return new ConstExprent(VarType.VARTYPE_DOUBLE, cn.value); + case 'F': + return new ConstExprent(VarType.VARTYPE_FLOAT, cn.value); + case 'I': + return new ConstExprent(VarType.VARTYPE_INT, cn.value); + case 'J': + return new ConstExprent(VarType.VARTYPE_LONG, cn.value); + case 'S': + return new ConstExprent(VarType.VARTYPE_SHORT, cn.value); + case 'Z': + return new ConstExprent(VarType.VARTYPE_BOOLEAN, cn.value); + case 's': + return new ConstExprent(VarType.VARTYPE_STRING, cn.value); + default: + throw new RuntimeException("invalid element type!"); + } } } - public List getAnnotations() { return annotations; } diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationParameterAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationParameterAttribute.java index 432d3b6..a33c7bb 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationParameterAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationParameterAttribute.java @@ -18,37 +18,30 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.modules.decompiler.exps.AnnotationExprent; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; -import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class StructAnnotationParameterAttribute extends StructGeneralAttribute { private List> paramAnnotations; - public void initContent(ConstantPool pool) { + @Override + public void initContent(ConstantPool pool) throws IOException { + DataInputStream data = stream(); - super.initContent(pool); - - paramAnnotations = new ArrayList>(); - DataInputStream data = new DataInputStream(new ByteArrayInputStream(info)); - - try { - int len = data.readUnsignedByte(); + int len = data.readUnsignedByte(); + if (len > 0) { + paramAnnotations = new ArrayList>(len); for (int i = 0; i < len; i++) { - List lst = new ArrayList(); - int annsize = data.readUnsignedShort(); - - for (int j = 0; j < annsize; j++) { - lst.add(StructAnnotationAttribute.parseAnnotation(data, pool)); - } - paramAnnotations.add(lst); + List annotations = StructAnnotationAttribute.parseAnnotations(pool, data); + paramAnnotations.add(annotations); } } - catch (IOException ex) { - throw new RuntimeException(ex); + else { + paramAnnotations = Collections.emptyList(); } } diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationTypeAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationTypeAttribute.java index f228ed5..59324e3 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationTypeAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationTypeAttribute.java @@ -18,81 +18,77 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.modules.decompiler.exps.AnnotationExprent; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; -import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class StructAnnotationTypeAttribute extends StructGeneralAttribute { - public static final int ANNOTATION_TARGET_TYPE_GENERIC_CLASS = 0x00; - public static final int ANNOTATION_TARGET_TYPE_GENERIC_METHOD = 0x01; - public static final int ANNOTATION_TARGET_TYPE_EXTENDS_IMPLEMENTS = 0x10; - public static final int ANNOTATION_TARGET_TYPE_GENERIC_CLASS_BOUND = 0x11; - public static final int ANNOTATION_TARGET_TYPE_GENERIC_METHOD_BOUND = 0x12; - public static final int ANNOTATION_TARGET_TYPE_FIELD = 0x13; - public static final int ANNOTATION_TARGET_TYPE_RETURN = 0x14; - public static final int ANNOTATION_TARGET_TYPE_RECEIVER = 0x15; - public static final int ANNOTATION_TARGET_TYPE_FORMAL = 0x16; - public static final int ANNOTATION_TARGET_TYPE_THROWS = 0x17; - public static final int ANNOTATION_TARGET_TYPE_LOCAL_VARIABLE = 0x40; - public static final int ANNOTATION_TARGET_TYPE_RESOURCE_VARIABLE = 0x41; - public static final int ANNOTATION_TARGET_TYPE_EXCEPTION = 0x42; - public static final int ANNOTATION_TARGET_TYPE_INSTANCEOF = 0x43; - public static final int ANNOTATION_TARGET_TYPE_NEW = 0x44; - public static final int ANNOTATION_TARGET_TYPE_DOUBLECOLON_NEW = 0x45; - public static final int ANNOTATION_TARGET_TYPE_DOUBLECOLON_ID = 0x46; - public static final int ANNOTATION_TARGET_TYPE_CAST = 0x47; - public static final int ANNOTATION_TARGET_TYPE_INVOKATION_CONSTRUCTOR = 0x48; - public static final int ANNOTATION_TARGET_TYPE_INVOKATION_METHOD = 0x49; - public static final int ANNOTATION_TARGET_TYPE_GENERIC_DOUBLECOLON_NEW = 0x4A; - public static final int ANNOTATION_TARGET_TYPE_GENERIC_DOUBLECOLON_ID = 0x4B; + private static final int ANNOTATION_TARGET_TYPE_GENERIC_CLASS = 0x00; + private static final int ANNOTATION_TARGET_TYPE_GENERIC_METHOD = 0x01; + private static final int ANNOTATION_TARGET_TYPE_EXTENDS_IMPLEMENTS = 0x10; + private static final int ANNOTATION_TARGET_TYPE_GENERIC_CLASS_BOUND = 0x11; + private static final int ANNOTATION_TARGET_TYPE_GENERIC_METHOD_BOUND = 0x12; + private static final int ANNOTATION_TARGET_TYPE_FIELD = 0x13; + private static final int ANNOTATION_TARGET_TYPE_RETURN = 0x14; + private static final int ANNOTATION_TARGET_TYPE_RECEIVER = 0x15; + private static final int ANNOTATION_TARGET_TYPE_FORMAL = 0x16; + private static final int ANNOTATION_TARGET_TYPE_THROWS = 0x17; + private static final int ANNOTATION_TARGET_TYPE_LOCAL_VARIABLE = 0x40; + private static final int ANNOTATION_TARGET_TYPE_RESOURCE_VARIABLE = 0x41; + private static final int ANNOTATION_TARGET_TYPE_EXCEPTION = 0x42; + private static final int ANNOTATION_TARGET_TYPE_INSTANCEOF = 0x43; + private static final int ANNOTATION_TARGET_TYPE_NEW = 0x44; + private static final int ANNOTATION_TARGET_TYPE_DOUBLE_COLON_NEW = 0x45; + private static final int ANNOTATION_TARGET_TYPE_DOUBLE_COLON_ID = 0x46; + private static final int ANNOTATION_TARGET_TYPE_CAST = 0x47; + private static final int ANNOTATION_TARGET_TYPE_INVOCATION_CONSTRUCTOR = 0x48; + private static final int ANNOTATION_TARGET_TYPE_INVOCATION_METHOD = 0x49; + private static final int ANNOTATION_TARGET_TYPE_GENERIC_DOUBLE_COLON_NEW = 0x4A; + private static final int ANNOTATION_TARGET_TYPE_GENERIC_DOUBLE_COLON_ID = 0x4B; - public static final int ANNOTATION_TARGET_UNION_TYPE_PARAMETER = 1; - public static final int ANNOTATION_TARGET_UNION_SUPERTYPE = 2; - public static final int ANNOTATION_TARGET_UNION_TYPE_PARAMETER_BOUND = 3; - public static final int ANNOTATION_TARGET_UNION_EMPTY = 4; - public static final int ANNOTATION_TARGET_UNION_FORMAL_PARAMETER = 5; - public static final int ANNOTATION_TARGET_UNION_THROWS = 6; - public static final int ANNOTATION_TARGET_UNION_LOCALVAR = 7; - public static final int ANNOTATION_TARGET_UNION_CATCH = 8; - public static final int ANNOTATION_TARGET_UNION_OFFSET = 9; - public static final int ANNOTATION_TARGET_UNION_TYPE_ARGUMENT = 10; + private static final int ANNOTATION_TARGET_UNION_TYPE_PARAMETER = 1; + private static final int ANNOTATION_TARGET_UNION_SUPERTYPE = 2; + private static final int ANNOTATION_TARGET_UNION_TYPE_PARAMETER_BOUND = 3; + private static final int ANNOTATION_TARGET_UNION_EMPTY = 4; + private static final int ANNOTATION_TARGET_UNION_FORMAL_PARAMETER = 5; + private static final int ANNOTATION_TARGET_UNION_THROWS = 6; + private static final int ANNOTATION_TARGET_UNION_LOCAL_VAR = 7; + private static final int ANNOTATION_TARGET_UNION_CATCH = 8; + private static final int ANNOTATION_TARGET_UNION_OFFSET = 9; + private static final int ANNOTATION_TARGET_UNION_TYPE_ARGUMENT = 10; + @SuppressWarnings("FieldCanBeLocal") private List locations; + @SuppressWarnings("FieldCanBeLocal") private List annotations; - List locations = new ArrayList(); - List annotations = new ArrayList(); + @Override + public void initContent(ConstantPool pool) throws IOException { + DataInputStream data = stream(); - public void initContent(ConstantPool pool) { - - super.initContent(pool); - - DataInputStream data = new DataInputStream(new ByteArrayInputStream(info)); - - try { - - int ann_number = data.readUnsignedByte(); - for (int i = 0; i < ann_number; i++) { + int len = data.readUnsignedByte(); + if (len > 0) { + locations = new ArrayList(len); + annotations = new ArrayList(len); + for (int i = 0; i < len; i++) { locations.add(parseAnnotationLocation(data)); annotations.add(StructAnnotationAttribute.parseAnnotation(data, pool)); } } - catch (IOException ex) { - throw new RuntimeException(ex); + else { + locations = Collections.emptyList(); + annotations = Collections.emptyList(); } } - public AnnotationLocation parseAnnotationLocation(DataInputStream data) throws IOException { - + private static AnnotationLocation parseAnnotationLocation(DataInputStream data) throws IOException { AnnotationLocation ann_location = new AnnotationLocation(); // target type - ann_location.target_type = data.readUnsignedByte(); // target union - switch (ann_location.target_type) { case ANNOTATION_TARGET_TYPE_GENERIC_CLASS: case ANNOTATION_TARGET_TYPE_GENERIC_METHOD: @@ -118,22 +114,22 @@ public class StructAnnotationTypeAttribute extends StructGeneralAttribute { break; case ANNOTATION_TARGET_TYPE_LOCAL_VARIABLE: case ANNOTATION_TARGET_TYPE_RESOURCE_VARIABLE: - ann_location.target_union = ANNOTATION_TARGET_UNION_LOCALVAR; + ann_location.target_union = ANNOTATION_TARGET_UNION_LOCAL_VAR; break; case ANNOTATION_TARGET_TYPE_EXCEPTION: ann_location.target_union = ANNOTATION_TARGET_UNION_CATCH; break; case ANNOTATION_TARGET_TYPE_INSTANCEOF: case ANNOTATION_TARGET_TYPE_NEW: - case ANNOTATION_TARGET_TYPE_DOUBLECOLON_NEW: - case ANNOTATION_TARGET_TYPE_DOUBLECOLON_ID: + case ANNOTATION_TARGET_TYPE_DOUBLE_COLON_NEW: + case ANNOTATION_TARGET_TYPE_DOUBLE_COLON_ID: ann_location.target_union = ANNOTATION_TARGET_UNION_OFFSET; break; case ANNOTATION_TARGET_TYPE_CAST: - case ANNOTATION_TARGET_TYPE_INVOKATION_CONSTRUCTOR: - case ANNOTATION_TARGET_TYPE_INVOKATION_METHOD: - case ANNOTATION_TARGET_TYPE_GENERIC_DOUBLECOLON_NEW: - case ANNOTATION_TARGET_TYPE_GENERIC_DOUBLECOLON_ID: + case ANNOTATION_TARGET_TYPE_INVOCATION_CONSTRUCTOR: + case ANNOTATION_TARGET_TYPE_INVOCATION_METHOD: + case ANNOTATION_TARGET_TYPE_GENERIC_DOUBLE_COLON_NEW: + case ANNOTATION_TARGET_TYPE_GENERIC_DOUBLE_COLON_ID: ann_location.target_union = ANNOTATION_TARGET_UNION_TYPE_ARGUMENT; break; default: @@ -158,7 +154,7 @@ public class StructAnnotationTypeAttribute extends StructGeneralAttribute { break; case ANNOTATION_TARGET_UNION_EMPTY: break; - case ANNOTATION_TARGET_UNION_LOCALVAR: + case ANNOTATION_TARGET_UNION_LOCAL_VAR: int table_length = data.readUnsignedShort(); ann_location.data = new int[table_length * 3 + 1]; @@ -175,7 +171,6 @@ public class StructAnnotationTypeAttribute extends StructGeneralAttribute { } // target path - int path_length = data.readUnsignedByte(); ann_location.target_path_kind = new int[path_length]; @@ -190,14 +185,10 @@ public class StructAnnotationTypeAttribute extends StructGeneralAttribute { } private static class AnnotationLocation { - public int target_type; public int target_union; - public int[] data; - public int[] target_path_kind; public int[] target_argument_index; } } - diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructBootstrapMethodsAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructBootstrapMethodsAttribute.java index 717bad9..840acc7 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructBootstrapMethodsAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructBootstrapMethodsAttribute.java @@ -19,7 +19,6 @@ import org.jetbrains.java.decompiler.struct.consts.ConstantPool; import org.jetbrains.java.decompiler.struct.consts.LinkConstant; import org.jetbrains.java.decompiler.struct.consts.PooledConstant; -import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import java.util.ArrayList; @@ -27,49 +26,41 @@ import java.util.List; public class StructBootstrapMethodsAttribute extends StructGeneralAttribute { - private List method_refs = new ArrayList(); - private List> method_arguments = new ArrayList>(); + private List methodRefs = new ArrayList(); + private List> methodArguments = new ArrayList>(); - public void initContent(ConstantPool pool) { + @Override + public void initContent(ConstantPool pool) throws IOException { + DataInputStream data = stream(); - name = ATTRIBUTE_BOOTSTRAP_METHODS; + int method_number = data.readUnsignedShort(); - try { + for (int i = 0; i < method_number; ++i) { + int bootstrap_method_ref = data.readUnsignedShort(); + int num_bootstrap_arguments = data.readUnsignedShort(); - DataInputStream data = new DataInputStream(new ByteArrayInputStream(info, 0, info.length)); + List list_arguments = new ArrayList(); - int method_number = data.readUnsignedShort(); + for (int j = 0; j < num_bootstrap_arguments; ++j) { + int bootstrap_argument_ref = data.readUnsignedShort(); - for (int i = 0; i < method_number; ++i) { - int bootstrap_method_ref = data.readUnsignedShort(); - int num_bootstrap_arguments = data.readUnsignedShort(); - - List list_arguments = new ArrayList(); - - for (int j = 0; j < num_bootstrap_arguments; ++j) { - int bootstrap_argument_ref = data.readUnsignedShort(); - - list_arguments.add(pool.getConstant(bootstrap_argument_ref)); - } - - method_refs.add(pool.getLinkConstant(bootstrap_method_ref)); - method_arguments.add(list_arguments); + list_arguments.add(pool.getConstant(bootstrap_argument_ref)); } - } - catch (IOException ex) { - throw new RuntimeException(ex); + + methodRefs.add(pool.getLinkConstant(bootstrap_method_ref)); + methodArguments.add(list_arguments); } } public int getMethodsNumber() { - return method_refs.size(); + return methodRefs.size(); } public LinkConstant getMethodReference(int index) { - return method_refs.get(index); + return methodRefs.get(index); } public List getMethodArguments(int index) { - return method_arguments.get(index); + return methodArguments.get(index); } } diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructConstantValueAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructConstantValueAttribute.java index ae3bd1d..07a5073 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructConstantValueAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructConstantValueAttribute.java @@ -17,14 +17,15 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; +import java.io.IOException; + public class StructConstantValueAttribute extends StructGeneralAttribute { private int index; - public void initContent(ConstantPool pool) { - - name = ATTRIBUTE_CONSTANT_VALUE; - index = ((info[0] & 0xFF) << 8) | (info[1] & 0xFF); + @Override + public void initContent(ConstantPool pool) throws IOException { + index = stream().readUnsignedShort(); } public int getIndex() { diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructEnclosingMethodAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructEnclosingMethodAttribute.java index ebf9407..c9b9ebb 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructEnclosingMethodAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructEnclosingMethodAttribute.java @@ -18,32 +18,31 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; import org.jetbrains.java.decompiler.struct.consts.LinkConstant; +import java.io.DataInputStream; +import java.io.IOException; + public class StructEnclosingMethodAttribute extends StructGeneralAttribute { - private String classname; - - private String mtname; - + private String className; + private String methodName; private String methodDescriptor; - public void initContent(ConstantPool pool) { + @Override + public void initContent(ConstantPool pool) throws IOException { + DataInputStream data = stream(); + int classIndex = data.readUnsignedShort(); + int methodIndex = data.readUnsignedShort(); - name = ATTRIBUTE_ENCLOSING_METHOD; - - int clindex = (((info[0] & 0xFF) << 8) | (info[1] & 0xFF)); - int mtindex = (((info[2] & 0xFF) << 8) | (info[3] & 0xFF)); - - classname = pool.getPrimitiveConstant(clindex).getString(); - if (mtindex != 0) { - LinkConstant lk = pool.getLinkConstant(mtindex); - - mtname = lk.elementname; + className = pool.getPrimitiveConstant(classIndex).getString(); + if (methodIndex != 0) { + LinkConstant lk = pool.getLinkConstant(methodIndex); + methodName = lk.elementname; methodDescriptor = lk.descriptor; } } - public String getClassname() { - return classname; + public String getClassName() { + return className; } public String getMethodDescriptor() { @@ -51,6 +50,6 @@ public class StructEnclosingMethodAttribute extends StructGeneralAttribute { } public String getMethodName() { - return mtname; + return methodName; } } diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructExceptionsAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructExceptionsAttribute.java index 53c02ec..5eda047 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructExceptionsAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructExceptionsAttribute.java @@ -17,21 +17,28 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; +import java.io.DataInputStream; +import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class StructExceptionsAttribute extends StructGeneralAttribute { - private List throwsExceptions = new ArrayList(); + private List throwsExceptions; - public void initContent(ConstantPool pool) { - - name = ATTRIBUTE_EXCEPTIONS; - - int length = 2 + (((info[0] & 0xFF) << 8) | (info[1] & 0xFF)) * 2; - for (int i = 2; i < length; i += 2) { - int index = ((info[i] & 0xFF) << 8) | (info[i + 1] & 0xFF); - throwsExceptions.add(index); + @Override + public void initContent(ConstantPool pool) throws IOException { + DataInputStream data = stream(); + int len = data.readUnsignedShort(); + if (len > 0) { + throwsExceptions = new ArrayList(len); + for (int i = 0; i < len; i++) { + throwsExceptions.add(data.readUnsignedShort()); + } + } + else { + throwsExceptions = Collections.emptyList(); } } @@ -42,8 +49,4 @@ public class StructExceptionsAttribute extends StructGeneralAttribute { public List getThrowsExceptions() { return throwsExceptions; } - - public void setThrowsExceptions(List throwsExceptions) { - this.throwsExceptions = throwsExceptions; - } } diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java index 632575f..5d43100 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java @@ -16,6 +16,10 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; +import org.jetbrains.java.decompiler.util.DataInputFullStream; + +import java.io.ByteArrayInputStream; +import java.io.IOException; /* attribute_info { @@ -44,9 +48,8 @@ public class StructGeneralAttribute { public static final String ATTRIBUTE_SYNTHETIC = "Synthetic"; public static final String ATTRIBUTE_DEPRECATED = "Deprecated"; - protected String name; - protected byte[] info; - + private String name; + private byte[] info; public static StructGeneralAttribute createAttribute(String name) { StructGeneralAttribute attr; @@ -100,7 +103,11 @@ public class StructGeneralAttribute { return attr; } - public void initContent(ConstantPool pool) { } + protected DataInputFullStream stream() { + return new DataInputFullStream(new ByteArrayInputStream(info)); + } + + public void initContent(ConstantPool pool) throws IOException { } public void setInfo(byte[] info) { this.info = info; diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructGenericSignatureAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructGenericSignatureAttribute.java index 6f2224c..62c892f 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructGenericSignatureAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructGenericSignatureAttribute.java @@ -17,14 +17,16 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; +import java.io.IOException; + public class StructGenericSignatureAttribute extends StructGeneralAttribute { private String signature; - public void initContent(ConstantPool pool) { - - name = ATTRIBUTE_SIGNATURE; - signature = pool.getPrimitiveConstant(((info[0] & 0xFF) << 8) | (info[1] & 0xFF)).getString(); + @Override + public void initContent(ConstantPool pool) throws IOException { + int index = stream().readUnsignedShort(); + signature = pool.getPrimitiveConstant(index).getString(); } public String getSignature() { diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java index 14ecd36..5969487 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java @@ -17,56 +17,56 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; +import java.io.DataInputStream; +import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class StructInnerClassesAttribute extends StructGeneralAttribute { - private List classentries = new ArrayList(); + private List classEntries; + private List stringEntries; - private List stringentries = new ArrayList(); + @Override + public void initContent(ConstantPool pool) throws IOException { + DataInputStream data = stream(); - public void initContent(ConstantPool pool) { + int len = data.readUnsignedShort(); + if (len > 0) { + classEntries = new ArrayList(len); + stringEntries = new ArrayList(len); - name = ATTRIBUTE_INNER_CLASSES; + 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 length = 2 + (((info[0] & 0xFF) << 8) | (info[1] & 0xFF)) * 8; - int i = 2; - - while (i < length) { - - int[] arr = new int[4]; - for (int j = 0; j < 4; j++) { - arr[j] = ((info[i] & 0xFF) << 8) | (info[i + 1] & 0xFF); - i += 2; + // 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); } - - classentries.add(arr); } - - for (int[] entry : classentries) { - - String[] arr = new String[3]; - // inner name - arr[0] = pool.getPrimitiveConstant(entry[0]).getString(); - //enclosing class - if (entry[1] != 0) { - arr[1] = pool.getPrimitiveConstant(entry[1]).getString(); - } - // original simple name - if (entry[2] != 0) { - arr[2] = pool.getPrimitiveConstant(entry[2]).getString(); - } - - stringentries.add(arr); + else { + classEntries = Collections.emptyList(); + stringEntries = Collections.emptyList(); } } - public List getClassentries() { - return classentries; + public List getClassEntries() { + return classEntries; } - public List getStringentries() { - return stringentries; + public List getStringEntries() { + return stringEntries; } } diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java index 0cf2a89..60e40c0 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java @@ -16,25 +16,44 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; +import org.jetbrains.java.decompiler.util.DataInputFullStream; +import java.io.IOException; +import java.util.Collections; import java.util.HashMap; +import java.util.Map; +/* + u2 local_variable_table_length; + local_variable { + u2 start_pc; + u2 length; + u2 name_index; + u2 descriptor_index; + u2 index; + } +*/ public class StructLocalVariableTableAttribute extends StructGeneralAttribute { - private HashMap mapVarNames = new HashMap(); + private Map mapVarNames = new HashMap(); - public void initContent(ConstantPool pool) { + @Override + public void initContent(ConstantPool pool) throws IOException { + DataInputFullStream data = stream(); - name = ATTRIBUTE_LOCAL_VARIABLE_TABLE; - - int len = ((info[0] & 0xFF) << 8) | (info[1] & 0xFF); - - int ind = 6; - for (int i = 0; i < len; i++, ind += 10) { - int nindex = ((info[ind] & 0xFF) << 8) | (info[ind + 1] & 0xFF); - int vindex = ((info[ind + 4] & 0xFF) << 8) | (info[ind + 5] & 0xFF); - - mapVarNames.put(vindex, pool.getPrimitiveConstant(nindex).getString()); + int len = data.readUnsignedShort(); + if (len > 0) { + mapVarNames = new HashMap(len); + for (int i = 0; i < len; i++) { + data.discard(4); + int nameIndex = data.readUnsignedShort(); + data.discard(2); + int varIndex = data.readUnsignedShort(); + mapVarNames.put(varIndex, pool.getPrimitiveConstant(nameIndex).getString()); + } + } + else { + mapVarNames = Collections.emptyMap(); } } @@ -42,7 +61,7 @@ public class StructLocalVariableTableAttribute extends StructGeneralAttribute { mapVarNames.putAll(attr.getMapVarNames()); } - public HashMap getMapVarNames() { + public Map getMapVarNames() { return mapVarNames; } }