diff --git a/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java b/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java index 097440b..5d9b881 100644 --- a/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java +++ b/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -27,20 +27,21 @@ import org.jetbrains.java.decompiler.util.DataInputFullStream; import java.io.DataInputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.BitSet; import java.util.List; +@SuppressWarnings("AssignmentToForLoopParameter") public class ConstantPool implements NewClassNameBuilder { - public static final int FIELD = 1; public static final int METHOD = 2; - private final List pool = new ArrayList(); + private final List pool; private final PoolInterceptor interceptor; - public ConstantPool(DataInputStream in) throws IOException { int size = in.readUnsignedShort(); - int[] pass = new int[size]; + pool = new ArrayList(size); + BitSet[] nextPass = {new BitSet(size), new BitSet(size), new BitSet(size)}; // first dummy constant pool.add(null); @@ -53,54 +54,59 @@ public class ConstantPool implements NewClassNameBuilder { case CodeConstants.CONSTANT_Utf8: pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Utf8, in.readUTF())); break; + case CodeConstants.CONSTANT_Integer: pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Integer, new Integer(in.readInt()))); break; + case CodeConstants.CONSTANT_Float: pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Float, new Float(in.readFloat()))); break; + case CodeConstants.CONSTANT_Long: pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Long, new Long(in.readLong()))); pool.add(null); i++; break; + case CodeConstants.CONSTANT_Double: pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Double, new Double(in.readDouble()))); pool.add(null); i++; break; + case CodeConstants.CONSTANT_Class: case CodeConstants.CONSTANT_String: case CodeConstants.CONSTANT_MethodType: pool.add(new PrimitiveConstant(tag, in.readUnsignedShort())); - pass[i] = 1; + nextPass[0].set(i); break; + + case CodeConstants.CONSTANT_NameAndType: + pool.add(new LinkConstant(tag, in.readUnsignedShort(), in.readUnsignedShort())); + nextPass[0].set(i); + break; + case CodeConstants.CONSTANT_Fieldref: case CodeConstants.CONSTANT_Methodref: case CodeConstants.CONSTANT_InterfaceMethodref: - case CodeConstants.CONSTANT_NameAndType: case CodeConstants.CONSTANT_InvokeDynamic: pool.add(new LinkConstant(tag, in.readUnsignedShort(), in.readUnsignedShort())); - if (tag == CodeConstants.CONSTANT_NameAndType) { - pass[i] = 1; - } - else { - pass[i] = 2; - } + nextPass[1].set(i); break; + case CodeConstants.CONSTANT_MethodHandle: pool.add(new LinkConstant(tag, in.readUnsignedByte(), in.readUnsignedShort())); - pass[i] = 3; + nextPass[2].set(i); break; } } // resolving complex pool elements - for (int passIndex = 1; passIndex <= 3; passIndex++) { - for (int i = 1; i < size; i++) { - if (pass[i] == passIndex) { - pool.get(i).resolveConstant(this); - } + for (BitSet pass : nextPass) { + int idx = 0; + while ((idx = pass.nextSetBit(idx + 1)) > 0) { + pool.get(idx).resolveConstant(this); } } @@ -116,6 +122,7 @@ public class ConstantPool implements NewClassNameBuilder { case CodeConstants.CONSTANT_Utf8: in.readUTF(); break; + case CodeConstants.CONSTANT_Integer: case CodeConstants.CONSTANT_Float: case CodeConstants.CONSTANT_Fieldref: @@ -125,16 +132,19 @@ public class ConstantPool implements NewClassNameBuilder { case CodeConstants.CONSTANT_InvokeDynamic: in.discard(4); break; + case CodeConstants.CONSTANT_Long: case CodeConstants.CONSTANT_Double: in.discard(8); i++; break; + case CodeConstants.CONSTANT_Class: case CodeConstants.CONSTANT_String: case CodeConstants.CONSTANT_MethodType: in.discard(2); break; + case CodeConstants.CONSTANT_MethodHandle: in.discard(3); } @@ -155,7 +165,7 @@ public class ConstantPool implements NewClassNameBuilder { className = oldClassName; } - String newElement = interceptor.getName(className + " " + elementName + " " + descriptor); + String newElement = interceptor.getName(className + ' ' + elementName + ' ' + descriptor); if (newElement != null) { elementName = newElement.split(" ")[1]; } @@ -196,7 +206,7 @@ public class ConstantPool implements NewClassNameBuilder { ln.type == CodeConstants.CONSTANT_Methodref || ln.type == CodeConstants.CONSTANT_InterfaceMethodref)) { String newClassName = buildNewClassname(ln.classname); - String newElement = interceptor.getName(ln.classname + " " + ln.elementname + " " + ln.descriptor); + String newElement = interceptor.getName(ln.classname + ' ' + ln.elementname + ' ' + ln.descriptor); String newDescriptor = buildNewDescriptor(ln.type == CodeConstants.CONSTANT_Fieldref, ln.descriptor); if (newClassName != null || newElement != null || newDescriptor != null) { @@ -220,10 +230,10 @@ public class ConstantPool implements NewClassNameBuilder { if (vt.arrayDim > 0) { for (int i = 0; i < vt.arrayDim; i++) { - buffer.append("["); + buffer.append('['); } - buffer.append("L").append(newName).append(";"); + buffer.append('L').append(newName).append(';'); } else { buffer.append(newName); @@ -243,4 +253,4 @@ public class ConstantPool implements NewClassNameBuilder { return MethodDescriptor.parseDescriptor(descriptor).buildNewDescriptor(this); } } -} +} \ No newline at end of file