Commit 81812810 authored by Eric Bruneton's avatar Eric Bruneton
Browse files

Merge branch 'fix-some-code-smells-and-duplications'

parents e5a48606 dbda8101
Pipeline #4535 passed with stage
in 11 minutes and 24 seconds
......@@ -600,36 +600,11 @@ public class Frame<V extends Value> {
case Opcodes.INVOKESPECIAL:
case Opcodes.INVOKESTATIC:
case Opcodes.INVOKEINTERFACE:
{
List<V> valueList = new ArrayList<>();
String methodDescriptor = ((MethodInsnNode) insn).desc;
for (int i = Type.getArgumentTypes(methodDescriptor).length; i > 0; --i) {
valueList.add(0, pop());
}
if (insn.getOpcode() != Opcodes.INVOKESTATIC) {
valueList.add(0, pop());
}
if (Type.getReturnType(methodDescriptor) == Type.VOID_TYPE) {
interpreter.naryOperation(insn, valueList);
} else {
push(interpreter.naryOperation(insn, valueList));
}
break;
}
executeInvokeInsn(insn, ((MethodInsnNode) insn).desc, interpreter);
break;
case Opcodes.INVOKEDYNAMIC:
{
List<V> valueList = new ArrayList<>();
String methodDesccriptor = ((InvokeDynamicInsnNode) insn).desc;
for (int i = Type.getArgumentTypes(methodDesccriptor).length; i > 0; --i) {
valueList.add(0, pop());
}
if (Type.getReturnType(methodDesccriptor) == Type.VOID_TYPE) {
interpreter.naryOperation(insn, valueList);
} else {
push(interpreter.naryOperation(insn, valueList));
}
break;
}
executeInvokeInsn(insn, ((InvokeDynamicInsnNode) insn).desc, interpreter);
break;
case Opcodes.NEW:
push(interpreter.newOperation(insn));
break;
......@@ -665,6 +640,23 @@ public class Frame<V extends Value> {
}
}
private void executeInvokeInsn(
final AbstractInsnNode insn, final String methodDescriptor, final Interpreter<V> interpreter)
throws AnalyzerException {
ArrayList<V> valueList = new ArrayList<>();
for (int i = Type.getArgumentTypes(methodDescriptor).length; i > 0; --i) {
valueList.add(0, pop());
}
if (insn.getOpcode() != Opcodes.INVOKESTATIC && insn.getOpcode() != Opcodes.INVOKEDYNAMIC) {
valueList.add(0, pop());
}
if (Type.getReturnType(methodDescriptor) == Type.VOID_TYPE) {
interpreter.naryOperation(insn, valueList);
} else {
push(interpreter.naryOperation(insn, valueList));
}
}
/**
* Merges the given frame into this frame.
*
......
......@@ -92,7 +92,13 @@ final class SmallSet<T> extends AbstractSet<T> {
@Override
public int size() {
return element1 == null ? 0 : (element2 == null ? 1 : 2);
if (element1 == null) {
return 0;
} else if (element2 == null) {
return 1;
} else {
return 2;
}
}
// -----------------------------------------------------------------------------------------------
......
......@@ -269,7 +269,7 @@ public class GeneratorAdapter extends LocalVariablesSorter {
method.getName(),
method.getDescriptor(),
signature,
getInternalNames(exceptions)));
exceptions == null ? null : getInternalNames(exceptions)));
}
/**
......@@ -279,9 +279,6 @@ public class GeneratorAdapter extends LocalVariablesSorter {
* @return the internal names of the given types.
*/
private static String[] getInternalNames(final Type[] types) {
if (types == null) {
return null;
}
String[] names = new String[types.length];
for (int i = 0; i < names.length; ++i) {
names[i] = types[i].getInternalName();
......
......@@ -36,7 +36,6 @@ import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
......@@ -445,18 +444,7 @@ public class SerialVersionUIDAdder extends ClassVisitor {
final boolean dotted)
throws IOException {
Item[] items = itemCollection.toArray(new Item[0]);
Arrays.sort(
items,
new Comparator<Item>() {
@Override
public int compare(final Item item1, final Item item2) {
int result = item1.name.compareTo(item2.name);
if (result == 0) {
result = item1.descriptor.compareTo(item2.descriptor);
}
return result;
}
});
Arrays.sort(items);
for (Item item : items) {
dataOutputStream.writeUTF(item.name);
dataOutputStream.writeInt(item.access);
......@@ -468,7 +456,7 @@ public class SerialVersionUIDAdder extends ClassVisitor {
// Inner classes
// -----------------------------------------------------------------------------------------------
private static final class Item {
private static final class Item implements Comparable<Item> {
final String name;
final int access;
......@@ -479,5 +467,27 @@ public class SerialVersionUIDAdder extends ClassVisitor {
this.access = access;
this.descriptor = descriptor;
}
@Override
public int compareTo(final Item item) {
int result = name.compareTo(item.name);
if (result == 0) {
result = descriptor.compareTo(item.descriptor);
}
return result;
}
@Override
public boolean equals(final Object other) {
if (other instanceof Item) {
return compareTo((Item) other) == 0;
}
return false;
}
@Override
public int hashCode() {
return name.hashCode() ^ descriptor.hashCode();
}
}
}
......@@ -65,9 +65,7 @@ public class MethodInsnNode extends AbstractInsnNode {
* org.objectweb.asm.Type#getInternalName()}).
* @param name the method's name.
* @param descriptor the method's descriptor (see {@link org.objectweb.asm.Type}).
* @deprecated use {@link #MethodInsnNode(int, String, String, String, boolean)} instead.
*/
@Deprecated
public MethodInsnNode(
final int opcode, final String owner, final String name, final String descriptor) {
this(opcode, owner, name, descriptor, opcode == Opcodes.INVOKEINTERFACE);
......
......@@ -29,8 +29,10 @@ package org.objectweb.asm.util;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ConstantDynamic;
......@@ -67,11 +69,23 @@ public class ASMifier extends Printer {
private static final String ANNOTATION_VISITOR = "annotationVisitor";
private static final String ANNOTATION_VISITOR0 = "annotationVisitor0 = ";
private static final String NEW_OBJECT_ARRAY = ", new Object[] {";
private static final String COMMA = "\", \"";
private static final String END_ARRAY = " });\n";
private static final String END_PARAMETERS = ");\n\n";
private static final String NEW_OBJECT_ARRAY = ", new Object[] {";
private static final String VISIT_END = ".visitEnd();\n";
private static final List<String> FRAME_TYPES =
Collections.unmodifiableList(
Arrays.asList(
"Opcodes.TOP",
"Opcodes.INTEGER",
"Opcodes.FLOAT",
"Opcodes.DOUBLE",
"Opcodes.LONG",
"Opcodes.NULL",
"Opcodes.UNINITIALIZED_THIS"));
private static final Map<Integer, String> CLASS_VERSIONS;
static {
......@@ -301,7 +315,7 @@ public class ASMifier extends Printer {
stringBuilder.setLength(0);
stringBuilder.append("classWriter.visitNestMember(");
appendConstant(nestMember);
stringBuilder.append(");\n\n");
stringBuilder.append(END_PARAMETERS);
text.add(stringBuilder.toString());
}
......@@ -429,27 +443,18 @@ public class ASMifier extends Printer {
@Override
public void visitExport(final String packaze, final int access, final String... modules) {
stringBuilder.setLength(0);
stringBuilder.append("moduleVisitor.visitExport(");
appendConstant(packaze);
stringBuilder.append(", ");
appendAccessFlags(access | ACCESS_MODULE);
if (modules != null && modules.length > 0) {
stringBuilder.append(", new String[] {");
for (int i = 0; i < modules.length; ++i) {
stringBuilder.append(i == 0 ? " " : ", ");
appendConstant(modules[i]);
}
stringBuilder.append(" }");
}
stringBuilder.append(");\n");
text.add(stringBuilder.toString());
visitExportOrOpen("moduleVisitor.visitExport(", packaze, access, modules);
}
@Override
public void visitOpen(final String packaze, final int access, final String... modules) {
visitExportOrOpen("moduleVisitor.visitOpen(", packaze, access, modules);
}
private void visitExportOrOpen(
final String visitMethod, final String packaze, final int access, final String... modules) {
stringBuilder.setLength(0);
stringBuilder.append("moduleVisitor.visitOpen(");
stringBuilder.append(visitMethod);
appendConstant(packaze);
stringBuilder.append(", ");
appendAccessFlags(access | ACCESS_MODULE);
......@@ -1372,14 +1377,14 @@ public class ASMifier extends Printer {
stringBuilder.append("new Handle(");
Handle handle = (Handle) value;
stringBuilder.append("Opcodes.").append(HANDLE_TAG[handle.getTag()]).append(", \"");
stringBuilder.append(handle.getOwner()).append("\", \"");
stringBuilder.append(handle.getName()).append("\", \"");
stringBuilder.append(handle.getOwner()).append(COMMA);
stringBuilder.append(handle.getName()).append(COMMA);
stringBuilder.append(handle.getDesc()).append("\", ");
stringBuilder.append(handle.isInterface()).append(")");
} else if (value instanceof ConstantDynamic) {
stringBuilder.append("new ConstantDynamic(\"");
ConstantDynamic constantDynamic = (ConstantDynamic) value;
stringBuilder.append(constantDynamic.getName()).append("\", \"");
stringBuilder.append(constantDynamic.getName()).append(COMMA);
stringBuilder.append(constantDynamic.getDescriptor()).append("\", ");
appendConstant(constantDynamic.getBootstrapMethod());
stringBuilder.append(NEW_OBJECT_ARRAY);
......@@ -1499,31 +1504,7 @@ public class ASMifier extends Printer {
if (frameTypes[i] instanceof String) {
appendConstant(frameTypes[i]);
} else if (frameTypes[i] instanceof Integer) {
switch (((Integer) frameTypes[i]).intValue()) {
case 0:
stringBuilder.append("Opcodes.TOP");
break;
case 1:
stringBuilder.append("Opcodes.INTEGER");
break;
case 2:
stringBuilder.append("Opcodes.FLOAT");
break;
case 3:
stringBuilder.append("Opcodes.DOUBLE");
break;
case 4:
stringBuilder.append("Opcodes.LONG");
break;
case 5:
stringBuilder.append("Opcodes.NULL");
break;
case 6:
stringBuilder.append("Opcodes.UNINITIALIZED_THIS");
break;
default:
throw new IllegalArgumentException();
}
stringBuilder.append(FRAME_TYPES.get(((Integer) frameTypes[i]).intValue()));
} else {
appendLabel((Label) frameTypes[i]);
}
......
......@@ -29,7 +29,10 @@ package org.objectweb.asm.util;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.Handle;
......@@ -98,6 +101,9 @@ public class Textifier extends Printer {
private static final String DEPRECATED = "// DEPRECATED\n";
private static final String INVISIBLE = " // invisible\n";
private static final List<String> FRAME_TYPES =
Collections.unmodifiableList(Arrays.asList("T", "I", "F", "D", "J", "N", "U"));
/** The indentation of class members at depth level 1 (e.g. fields, methods). */
protected String tab = " ";
......@@ -164,7 +170,7 @@ public class Textifier extends Printer {
* @param logger where to log errors.
* @throws IOException if the class cannot be found, or if an IOException occurs.
*/
public static void main(final String[] args, final PrintWriter output, final PrintWriter logger)
static void main(final String[] args, final PrintWriter output, final PrintWriter logger)
throws IOException {
main(args, USAGE, new Textifier(), output, logger);
}
......@@ -469,30 +475,20 @@ public class Textifier extends Printer {
}
@Override
public void visitExport(final String export, final int access, final String... modules) {
stringBuilder.setLength(0);
stringBuilder.append(tab).append("exports ");
stringBuilder.append(export);
if (modules != null && modules.length > 0) {
stringBuilder.append(" to");
} else {
stringBuilder.append(';');
}
appendRawAccess(access);
if (modules != null && modules.length > 0) {
for (int i = 0; i < modules.length; ++i) {
stringBuilder.append(tab2).append(modules[i]);
stringBuilder.append(i != modules.length - 1 ? ",\n" : ";\n");
}
}
text.add(stringBuilder.toString());
public void visitExport(final String packaze, final int access, final String... modules) {
visitExportOrOpen("exports ", packaze, access, modules);
}
@Override
public void visitOpen(final String export, final int access, final String... modules) {
public void visitOpen(final String packaze, final int access, final String... modules) {
visitExportOrOpen("opens ", packaze, access, modules);
}
private void visitExportOrOpen(
final String method, final String packaze, final int access, final String... modules) {
stringBuilder.setLength(0);
stringBuilder.append(tab).append("opens ");
stringBuilder.append(export);
stringBuilder.append(tab).append(method);
stringBuilder.append(packaze);
if (modules != null && modules.length > 0) {
stringBuilder.append(" to");
} else {
......@@ -1534,31 +1530,7 @@ public class Textifier extends Printer {
appendDescriptor(INTERNAL_NAME, descriptor);
}
} else if (frameTypes[i] instanceof Integer) {
switch (((Integer) frameTypes[i]).intValue()) {
case 0:
appendDescriptor(FIELD_DESCRIPTOR, "T");
break;
case 1:
appendDescriptor(FIELD_DESCRIPTOR, "I");
break;
case 2:
appendDescriptor(FIELD_DESCRIPTOR, "F");
break;
case 3:
appendDescriptor(FIELD_DESCRIPTOR, "D");
break;
case 4:
appendDescriptor(FIELD_DESCRIPTOR, "J");
break;
case 5:
appendDescriptor(FIELD_DESCRIPTOR, "N");
break;
case 6:
appendDescriptor(FIELD_DESCRIPTOR, "U");
break;
default:
throw new IllegalArgumentException();
}
stringBuilder.append(FRAME_TYPES.get(((Integer) frameTypes[i]).intValue()));
} else {
appendLabel((Label) frameTypes[i]);
}
......
......@@ -27,6 +27,9 @@
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.util;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.signature.SignatureVisitor;
......@@ -43,6 +46,22 @@ public final class TraceSignatureVisitor extends SignatureVisitor {
private static final String EXTENDS_SEPARATOR = " extends ";
private static final String IMPLEMENTS_SEPARATOR = " implements ";
private static final Map<Character, String> BASE_TYPES;
static {
HashMap<Character, String> baseTypes = new HashMap<>();
baseTypes.put('Z', "boolean");
baseTypes.put('B', "byte");
baseTypes.put('C', "char");
baseTypes.put('S', "short");
baseTypes.put('I', "int");
baseTypes.put('J', "long");
baseTypes.put('F', "float");
baseTypes.put('D', "double");
baseTypes.put('V', "void");
BASE_TYPES = Collections.unmodifiableMap(baseTypes);
}
/** Whether the visited signature is a class signature of a Java interface. */
private final boolean isInterface;
......@@ -181,37 +200,11 @@ public final class TraceSignatureVisitor extends SignatureVisitor {
@Override
public void visitBaseType(final char descriptor) {
switch (descriptor) {
case 'V':
declaration.append("void");
break;
case 'B':
declaration.append("byte");
break;
case 'J':
declaration.append("long");
break;
case 'Z':
declaration.append("boolean");
break;
case 'I':
declaration.append("int");
break;
case 'S':
declaration.append("short");
break;
case 'C':
declaration.append("char");
break;
case 'F':
declaration.append("float");
break;
case 'D':
declaration.append("double");
break;
default:
throw new IllegalArgumentException();
String baseType = BASE_TYPES.get(descriptor);
if (baseType == null) {
throw new IllegalArgumentException();
}
declaration.append(baseType);
endType();
}
......
......@@ -195,8 +195,8 @@ public class ClassReader {
int currentCpInfoIndex = 1;
int currentCpInfoOffset = classFileOffset + 10;
int currentMaxStringLength = 0;
boolean hasBootstrapMethods = false;
boolean hasConstantDynamic = false;
boolean hasConstantInvokeDynamic = false;
// The offset of the other entries depend on the total size of all the previous entries.
while (currentCpInfoIndex < constantPoolCount) {
cpInfoOffsets[currentCpInfoIndex++] = currentCpInfoOffset + 1;
......@@ -212,11 +212,12 @@ public class ClassReader {
break;
case Symbol.CONSTANT_DYNAMIC_TAG:
cpInfoSize = 5;
hasBootstrapMethods = true;
hasConstantDynamic = true;
break;
case Symbol.CONSTANT_INVOKE_DYNAMIC_TAG:
cpInfoSize = 5;
hasConstantInvokeDynamic = true;
hasBootstrapMethods = true;
break;
case Symbol.CONSTANT_LONG_TAG:
case Symbol.CONSTANT_DOUBLE_TAG:
......@@ -256,9 +257,7 @@ public class ClassReader {
// Read the BootstrapMethods attribute, if any (only get the offset of each method).
bootstrapMethodOffsets =
(hasConstantDynamic | hasConstantInvokeDynamic)
? readBootstrapMethodsAttribute(currentMaxStringLength)
: null;
hasBootstrapMethods ? readBootstrapMethodsAttribute(currentMaxStringLength) : null;
}
/**
......@@ -2096,17 +2095,15 @@ public class ClassReader {
break;
}
case Constants.ASM_GOTO_W:
{
// Replace ASM_GOTO_W with GOTO_W.
methodVisitor.visitJumpInsn(
Constants.GOTO_W, labels[currentBytecodeOffset + readInt(currentOffset + 1)]);
// The instruction just after is a jump target (because ASM_GOTO_W is used in patterns
// IFNOTxxx <L> ASM_GOTO_W <l> L:..., see MethodWriter), so we need to insert a frame
// here.
insertFrame = true;
currentOffset += 5;
break;
}
// Replace ASM_GOTO_W with GOTO_W.
methodVisitor.visitJumpInsn(
Constants.GOTO_W, labels[currentBytecodeOffset + readInt(currentOffset + 1)]);
// The instruction just after is a jump target (because ASM_GOTO_W is used in patterns
// IFNOTxxx <L> ASM_GOTO_W <l> L:..., see MethodWriter), so we need to insert a frame
// here.
insertFrame = true;
currentOffset += 5;
break;
case Constants.WIDE:
opcode = classFileBuffer[currentOffset + 1] & 0xFF;
if (opcode == Opcodes.IINC) {
......@@ -3227,7 +3224,7 @@ public class ClassReader {
*
* @param maxStringLength a conservative estimate of the maximum length of the strings contained
* in the constant pool of the class.
* @return the offsets of the bootstrap methods or null.
* @return the offsets of the bootstrap methods.
*/
private int[] readBootstrapMethodsAttribute(final int maxStringLength) {
char[] charBuffer = new char[maxStringLength];
......@@ -3254,7 +3251,7 @@ public class ClassReader {
}
currentAttributeOffset += attributeLength;
}
return null;
throw new IllegalArgumentException();
}
/**
......
......@@ -142,6 +142,11 @@ public final class ConstantDynamic {
return (firstCharOfDescriptor == 'J' || firstCharOfDescriptor == 'D') ? 2 : 1;
}
void accept(final MethodVisitor methodVisitor) {
methodVisitor.visitInvokeDynamicInsn(
name, descriptor, bootstrapMethod, bootstrapMethodArguments);
}
@Override
public boolean equals(final Object object) {
if (object == this) {
......
......@@ -1183,8 +1183,10 @@ final class SymbolTable {
* corresponding to the common super class of the given types.
*/
int addMergedType(final int typeTableIndex1, final int typeTableIndex2) {