|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
package jdk.internal.org.objectweb.asm.tree; |
|
|
|
import java.util.ArrayList; |
|
import java.util.List; |
|
import jdk.internal.org.objectweb.asm.AnnotationVisitor; |
|
import jdk.internal.org.objectweb.asm.Attribute; |
|
import jdk.internal.org.objectweb.asm.ClassVisitor; |
|
import jdk.internal.org.objectweb.asm.ConstantDynamic; |
|
import jdk.internal.org.objectweb.asm.Handle; |
|
import jdk.internal.org.objectweb.asm.Label; |
|
import jdk.internal.org.objectweb.asm.MethodVisitor; |
|
import jdk.internal.org.objectweb.asm.Opcodes; |
|
import jdk.internal.org.objectweb.asm.Type; |
|
import jdk.internal.org.objectweb.asm.TypePath; |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public class MethodNode extends MethodVisitor { |
|
|
|
|
|
|
|
|
|
*/ |
|
public int access; |
|
|
|
|
|
public String name; |
|
|
|
|
|
public String desc; |
|
|
|
|
|
public String signature; |
|
|
|
|
|
public List<String> exceptions; |
|
|
|
|
|
public List<ParameterNode> parameters; |
|
|
|
|
|
public List<AnnotationNode> visibleAnnotations; |
|
|
|
|
|
public List<AnnotationNode> invisibleAnnotations; |
|
|
|
|
|
public List<TypeAnnotationNode> visibleTypeAnnotations; |
|
|
|
|
|
public List<TypeAnnotationNode> invisibleTypeAnnotations; |
|
|
|
|
|
public List<Attribute> attrs; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public Object annotationDefault; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public int visibleAnnotableParameterCount; |
|
|
|
|
|
|
|
|
|
*/ |
|
public List<AnnotationNode>[] visibleParameterAnnotations; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public int invisibleAnnotableParameterCount; |
|
|
|
|
|
|
|
|
|
*/ |
|
public List<AnnotationNode>[] invisibleParameterAnnotations; |
|
|
|
|
|
public InsnList instructions; |
|
|
|
|
|
public List<TryCatchBlockNode> tryCatchBlocks; |
|
|
|
|
|
public int maxStack; |
|
|
|
|
|
public int maxLocals; |
|
|
|
|
|
public List<LocalVariableNode> localVariables; |
|
|
|
|
|
public List<LocalVariableAnnotationNode> visibleLocalVariableAnnotations; |
|
|
|
|
|
public List<LocalVariableAnnotationNode> invisibleLocalVariableAnnotations; |
|
|
|
|
|
private boolean visited; |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public MethodNode() { |
|
this( Opcodes.ASM8); |
|
if (getClass() != MethodNode.class) { |
|
throw new IllegalStateException(); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public MethodNode(final int api) { |
|
super(api); |
|
this.instructions = new InsnList(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public MethodNode( |
|
final int access, |
|
final String name, |
|
final String descriptor, |
|
final String signature, |
|
final String[] exceptions) { |
|
this( Opcodes.ASM8, access, name, descriptor, signature, exceptions); |
|
if (getClass() != MethodNode.class) { |
|
throw new IllegalStateException(); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public MethodNode( |
|
final int api, |
|
final int access, |
|
final String name, |
|
final String descriptor, |
|
final String signature, |
|
final String[] exceptions) { |
|
super(api); |
|
this.access = access; |
|
this.name = name; |
|
this.desc = descriptor; |
|
this.signature = signature; |
|
this.exceptions = Util.asArrayList(exceptions); |
|
if ((access & Opcodes.ACC_ABSTRACT) == 0) { |
|
this.localVariables = new ArrayList<>(5); |
|
} |
|
this.tryCatchBlocks = new ArrayList<>(); |
|
this.instructions = new InsnList(); |
|
} |
|
|
|
// ----------------------------------------------------------------------------------------------- |
|
// Implementation of the MethodVisitor abstract class |
|
// ----------------------------------------------------------------------------------------------- |
|
|
|
@Override |
|
public void visitParameter(final String name, final int access) { |
|
if (parameters == null) { |
|
parameters = new ArrayList<>(5); |
|
} |
|
parameters.add(new ParameterNode(name, access)); |
|
} |
|
|
|
@Override |
|
@SuppressWarnings("serial") |
|
public AnnotationVisitor visitAnnotationDefault() { |
|
return new AnnotationNode( |
|
new ArrayList<Object>(0) { |
|
@Override |
|
public boolean add(final Object o) { |
|
annotationDefault = o; |
|
return super.add(o); |
|
} |
|
}); |
|
} |
|
|
|
@Override |
|
public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { |
|
AnnotationNode annotation = new AnnotationNode(descriptor); |
|
if (visible) { |
|
visibleAnnotations = Util.add(visibleAnnotations, annotation); |
|
} else { |
|
invisibleAnnotations = Util.add(invisibleAnnotations, annotation); |
|
} |
|
return annotation; |
|
} |
|
|
|
@Override |
|
public AnnotationVisitor visitTypeAnnotation( |
|
final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { |
|
TypeAnnotationNode typeAnnotation = new TypeAnnotationNode(typeRef, typePath, descriptor); |
|
if (visible) { |
|
visibleTypeAnnotations = Util.add(visibleTypeAnnotations, typeAnnotation); |
|
} else { |
|
invisibleTypeAnnotations = Util.add(invisibleTypeAnnotations, typeAnnotation); |
|
} |
|
return typeAnnotation; |
|
} |
|
|
|
@Override |
|
public void visitAnnotableParameterCount(final int parameterCount, final boolean visible) { |
|
if (visible) { |
|
visibleAnnotableParameterCount = parameterCount; |
|
} else { |
|
invisibleAnnotableParameterCount = parameterCount; |
|
} |
|
} |
|
|
|
@Override |
|
@SuppressWarnings("unchecked") |
|
public AnnotationVisitor visitParameterAnnotation( |
|
final int parameter, final String descriptor, final boolean visible) { |
|
AnnotationNode annotation = new AnnotationNode(descriptor); |
|
if (visible) { |
|
if (visibleParameterAnnotations == null) { |
|
int params = Type.getArgumentTypes(desc).length; |
|
visibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params]; |
|
} |
|
visibleParameterAnnotations[parameter] = |
|
Util.add(visibleParameterAnnotations[parameter], annotation); |
|
} else { |
|
if (invisibleParameterAnnotations == null) { |
|
int params = Type.getArgumentTypes(desc).length; |
|
invisibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params]; |
|
} |
|
invisibleParameterAnnotations[parameter] = |
|
Util.add(invisibleParameterAnnotations[parameter], annotation); |
|
} |
|
return annotation; |
|
} |
|
|
|
@Override |
|
public void visitAttribute(final Attribute attribute) { |
|
attrs = Util.add(attrs, attribute); |
|
} |
|
|
|
@Override |
|
public void visitCode() { |
|
// Nothing to do. |
|
} |
|
|
|
@Override |
|
public void visitFrame( |
|
final int type, |
|
final int numLocal, |
|
final Object[] local, |
|
final int numStack, |
|
final Object[] stack) { |
|
instructions.add( |
|
new FrameNode( |
|
type, |
|
numLocal, |
|
local == null ? null : getLabelNodes(local), |
|
numStack, |
|
stack == null ? null : getLabelNodes(stack))); |
|
} |
|
|
|
@Override |
|
public void visitInsn(final int opcode) { |
|
instructions.add(new InsnNode(opcode)); |
|
} |
|
|
|
@Override |
|
public void visitIntInsn(final int opcode, final int operand) { |
|
instructions.add(new IntInsnNode(opcode, operand)); |
|
} |
|
|
|
@Override |
|
public void visitVarInsn(final int opcode, final int var) { |
|
instructions.add(new VarInsnNode(opcode, var)); |
|
} |
|
|
|
@Override |
|
public void visitTypeInsn(final int opcode, final String type) { |
|
instructions.add(new TypeInsnNode(opcode, type)); |
|
} |
|
|
|
@Override |
|
public void visitFieldInsn( |
|
final int opcode, final String owner, final String name, final String descriptor) { |
|
instructions.add(new FieldInsnNode(opcode, owner, name, descriptor)); |
|
} |
|
|
|
@Override |
|
public void visitMethodInsn( |
|
final int opcodeAndSource, |
|
final String owner, |
|
final String name, |
|
final String descriptor, |
|
final boolean isInterface) { |
|
if (api < Opcodes.ASM5 && (opcodeAndSource & Opcodes.SOURCE_DEPRECATED) == 0) { |
|
|
|
super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface); |
|
return; |
|
} |
|
int opcode = opcodeAndSource & ~Opcodes.SOURCE_MASK; |
|
|
|
instructions.add(new MethodInsnNode(opcode, owner, name, descriptor, isInterface)); |
|
} |
|
|
|
@Override |
|
public void visitInvokeDynamicInsn( |
|
final String name, |
|
final String descriptor, |
|
final Handle bootstrapMethodHandle, |
|
final Object... bootstrapMethodArguments) { |
|
instructions.add( |
|
new InvokeDynamicInsnNode( |
|
name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments)); |
|
} |
|
|
|
@Override |
|
public void visitJumpInsn(final int opcode, final Label label) { |
|
instructions.add(new JumpInsnNode(opcode, getLabelNode(label))); |
|
} |
|
|
|
@Override |
|
public void visitLabel(final Label label) { |
|
instructions.add(getLabelNode(label)); |
|
} |
|
|
|
@Override |
|
public void visitLdcInsn(final Object value) { |
|
instructions.add(new LdcInsnNode(value)); |
|
} |
|
|
|
@Override |
|
public void visitIincInsn(final int var, final int increment) { |
|
instructions.add(new IincInsnNode(var, increment)); |
|
} |
|
|
|
@Override |
|
public void visitTableSwitchInsn( |
|
final int min, final int max, final Label dflt, final Label... labels) { |
|
instructions.add(new TableSwitchInsnNode(min, max, getLabelNode(dflt), getLabelNodes(labels))); |
|
} |
|
|
|
@Override |
|
public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { |
|
instructions.add(new LookupSwitchInsnNode(getLabelNode(dflt), keys, getLabelNodes(labels))); |
|
} |
|
|
|
@Override |
|
public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) { |
|
instructions.add(new MultiANewArrayInsnNode(descriptor, numDimensions)); |
|
} |
|
|
|
@Override |
|
public AnnotationVisitor visitInsnAnnotation( |
|
final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { |
|
|
|
AbstractInsnNode currentInsn = instructions.getLast(); |
|
while (currentInsn.getOpcode() == -1) { |
|
currentInsn = currentInsn.getPrevious(); |
|
} |
|
|
|
TypeAnnotationNode typeAnnotation = new TypeAnnotationNode(typeRef, typePath, descriptor); |
|
if (visible) { |
|
currentInsn.visibleTypeAnnotations = |
|
Util.add(currentInsn.visibleTypeAnnotations, typeAnnotation); |
|
} else { |
|
currentInsn.invisibleTypeAnnotations = |
|
Util.add(currentInsn.invisibleTypeAnnotations, typeAnnotation); |
|
} |
|
return typeAnnotation; |
|
} |
|
|
|
@Override |
|
public void visitTryCatchBlock( |
|
final Label start, final Label end, final Label handler, final String type) { |
|
TryCatchBlockNode tryCatchBlock = |
|
new TryCatchBlockNode(getLabelNode(start), getLabelNode(end), getLabelNode(handler), type); |
|
tryCatchBlocks = Util.add(tryCatchBlocks, tryCatchBlock); |
|
} |
|
|
|
@Override |
|
public AnnotationVisitor visitTryCatchAnnotation( |
|
final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { |
|
TryCatchBlockNode tryCatchBlock = tryCatchBlocks.get((typeRef & 0x00FFFF00) >> 8); |
|
TypeAnnotationNode typeAnnotation = new TypeAnnotationNode(typeRef, typePath, descriptor); |
|
if (visible) { |
|
tryCatchBlock.visibleTypeAnnotations = |
|
Util.add(tryCatchBlock.visibleTypeAnnotations, typeAnnotation); |
|
} else { |
|
tryCatchBlock.invisibleTypeAnnotations = |
|
Util.add(tryCatchBlock.invisibleTypeAnnotations, typeAnnotation); |
|
} |
|
return typeAnnotation; |
|
} |
|
|
|
@Override |
|
public void visitLocalVariable( |
|
final String name, |
|
final String descriptor, |
|
final String signature, |
|
final Label start, |
|
final Label end, |
|
final int index) { |
|
LocalVariableNode localVariable = |
|
new LocalVariableNode( |
|
name, descriptor, signature, getLabelNode(start), getLabelNode(end), index); |
|
localVariables = Util.add(localVariables, localVariable); |
|
} |
|
|
|
@Override |
|
public AnnotationVisitor visitLocalVariableAnnotation( |
|
final int typeRef, |
|
final TypePath typePath, |
|
final Label[] start, |
|
final Label[] end, |
|
final int[] index, |
|
final String descriptor, |
|
final boolean visible) { |
|
LocalVariableAnnotationNode localVariableAnnotation = |
|
new LocalVariableAnnotationNode( |
|
typeRef, typePath, getLabelNodes(start), getLabelNodes(end), index, descriptor); |
|
if (visible) { |
|
visibleLocalVariableAnnotations = |
|
Util.add(visibleLocalVariableAnnotations, localVariableAnnotation); |
|
} else { |
|
invisibleLocalVariableAnnotations = |
|
Util.add(invisibleLocalVariableAnnotations, localVariableAnnotation); |
|
} |
|
return localVariableAnnotation; |
|
} |
|
|
|
@Override |
|
public void visitLineNumber(final int line, final Label start) { |
|
instructions.add(new LineNumberNode(line, getLabelNode(start))); |
|
} |
|
|
|
@Override |
|
public void visitMaxs(final int maxStack, final int maxLocals) { |
|
this.maxStack = maxStack; |
|
this.maxLocals = maxLocals; |
|
} |
|
|
|
@Override |
|
public void visitEnd() { |
|
// Nothing to do. |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected LabelNode getLabelNode(final Label label) { |
|
if (!(label.info instanceof LabelNode)) { |
|
label.info = new LabelNode(); |
|
} |
|
return (LabelNode) label.info; |
|
} |
|
|
|
private LabelNode[] getLabelNodes(final Label[] labels) { |
|
LabelNode[] labelNodes = new LabelNode[labels.length]; |
|
for (int i = 0, n = labels.length; i < n; ++i) { |
|
labelNodes[i] = getLabelNode(labels[i]); |
|
} |
|
return labelNodes; |
|
} |
|
|
|
private Object[] getLabelNodes(final Object[] objects) { |
|
Object[] labelNodes = new Object[objects.length]; |
|
for (int i = 0, n = objects.length; i < n; ++i) { |
|
Object o = objects[i]; |
|
if (o instanceof Label) { |
|
o = getLabelNode((Label) o); |
|
} |
|
labelNodes[i] = o; |
|
} |
|
return labelNodes; |
|
} |
|
|
|
// ----------------------------------------------------------------------------------------------- |
|
// Accept method |
|
// ----------------------------------------------------------------------------------------------- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void check(final int api) { |
|
if (api == Opcodes.ASM4) { |
|
if (parameters != null && !parameters.isEmpty()) { |
|
throw new UnsupportedClassVersionException(); |
|
} |
|
if (visibleTypeAnnotations != null && !visibleTypeAnnotations.isEmpty()) { |
|
throw new UnsupportedClassVersionException(); |
|
} |
|
if (invisibleTypeAnnotations != null && !invisibleTypeAnnotations.isEmpty()) { |
|
throw new UnsupportedClassVersionException(); |
|
} |
|
if (tryCatchBlocks != null) { |
|
for (int i = tryCatchBlocks.size() - 1; i >= 0; --i) { |
|
TryCatchBlockNode tryCatchBlock = tryCatchBlocks.get(i); |
|
if (tryCatchBlock.visibleTypeAnnotations != null |
|
&& !tryCatchBlock.visibleTypeAnnotations.isEmpty()) { |
|
throw new UnsupportedClassVersionException(); |
|
} |
|
if (tryCatchBlock.invisibleTypeAnnotations != null |
|
&& !tryCatchBlock.invisibleTypeAnnotations.isEmpty()) { |
|
throw new UnsupportedClassVersionException(); |
|
} |
|
} |
|
} |
|
for (int i = instructions.size() - 1; i >= 0; --i) { |
|
AbstractInsnNode insn = instructions.get(i); |
|
if (insn.visibleTypeAnnotations != null && !insn.visibleTypeAnnotations.isEmpty()) { |
|
throw new UnsupportedClassVersionException(); |
|
} |
|
if (insn.invisibleTypeAnnotations != null && !insn.invisibleTypeAnnotations.isEmpty()) { |
|
throw new UnsupportedClassVersionException(); |
|
} |
|
if (insn instanceof MethodInsnNode) { |
|
boolean isInterface = ((MethodInsnNode) insn).itf; |
|
if (isInterface != (insn.opcode == Opcodes.INVOKEINTERFACE)) { |
|
throw new UnsupportedClassVersionException(); |
|
} |
|
} else if (insn instanceof LdcInsnNode) { |
|
Object value = ((LdcInsnNode) insn).cst; |
|
if (value instanceof Handle |
|
|| (value instanceof Type && ((Type) value).getSort() == Type.METHOD)) { |
|
throw new UnsupportedClassVersionException(); |
|
} |
|
} |
|
} |
|
if (visibleLocalVariableAnnotations != null && !visibleLocalVariableAnnotations.isEmpty()) { |
|
throw new UnsupportedClassVersionException(); |
|
} |
|
if (invisibleLocalVariableAnnotations != null |
|
&& !invisibleLocalVariableAnnotations.isEmpty()) { |
|
throw new UnsupportedClassVersionException(); |
|
} |
|
} |
|
if (api < Opcodes.ASM7) { |
|
for (int i = instructions.size() - 1; i >= 0; --i) { |
|
AbstractInsnNode insn = instructions.get(i); |
|
if (insn instanceof LdcInsnNode) { |
|
Object value = ((LdcInsnNode) insn).cst; |
|
if (value instanceof ConstantDynamic) { |
|
throw new UnsupportedClassVersionException(); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void accept(final ClassVisitor classVisitor) { |
|
String[] exceptionsArray = exceptions == null ? null : exceptions.toArray(new String[0]); |
|
MethodVisitor methodVisitor = |
|
classVisitor.visitMethod(access, name, desc, signature, exceptionsArray); |
|
if (methodVisitor != null) { |
|
accept(methodVisitor); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void accept(final MethodVisitor methodVisitor) { |
|
|
|
if (parameters != null) { |
|
for (int i = 0, n = parameters.size(); i < n; i++) { |
|
parameters.get(i).accept(methodVisitor); |
|
} |
|
} |
|
|
|
if (annotationDefault != null) { |
|
AnnotationVisitor annotationVisitor = methodVisitor.visitAnnotationDefault(); |
|
AnnotationNode.accept(annotationVisitor, null, annotationDefault); |
|
if (annotationVisitor != null) { |
|
annotationVisitor.visitEnd(); |
|
} |
|
} |
|
if (visibleAnnotations != null) { |
|
for (int i = 0, n = visibleAnnotations.size(); i < n; ++i) { |
|
AnnotationNode annotation = visibleAnnotations.get(i); |
|
annotation.accept(methodVisitor.visitAnnotation(annotation.desc, true)); |
|
} |
|
} |
|
if (invisibleAnnotations != null) { |
|
for (int i = 0, n = invisibleAnnotations.size(); i < n; ++i) { |
|
AnnotationNode annotation = invisibleAnnotations.get(i); |
|
annotation.accept(methodVisitor.visitAnnotation(annotation.desc, false)); |
|
} |
|
} |
|
if (visibleTypeAnnotations != null) { |
|
for (int i = 0, n = visibleTypeAnnotations.size(); i < n; ++i) { |
|
TypeAnnotationNode typeAnnotation = visibleTypeAnnotations.get(i); |
|
typeAnnotation.accept( |
|
methodVisitor.visitTypeAnnotation( |
|
typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, true)); |
|
} |
|
} |
|
if (invisibleTypeAnnotations != null) { |
|
for (int i = 0, n = invisibleTypeAnnotations.size(); i < n; ++i) { |
|
TypeAnnotationNode typeAnnotation = invisibleTypeAnnotations.get(i); |
|
typeAnnotation.accept( |
|
methodVisitor.visitTypeAnnotation( |
|
typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, false)); |
|
} |
|
} |
|
if (visibleAnnotableParameterCount > 0) { |
|
methodVisitor.visitAnnotableParameterCount(visibleAnnotableParameterCount, true); |
|
} |
|
if (visibleParameterAnnotations != null) { |
|
for (int i = 0, n = visibleParameterAnnotations.length; i < n; ++i) { |
|
List<AnnotationNode> parameterAnnotations = visibleParameterAnnotations[i]; |
|
if (parameterAnnotations == null) { |
|
continue; |
|
} |
|
for (int j = 0, m = parameterAnnotations.size(); j < m; ++j) { |
|
AnnotationNode annotation = parameterAnnotations.get(j); |
|
annotation.accept(methodVisitor.visitParameterAnnotation(i, annotation.desc, true)); |
|
} |
|
} |
|
} |
|
if (invisibleAnnotableParameterCount > 0) { |
|
methodVisitor.visitAnnotableParameterCount(invisibleAnnotableParameterCount, false); |
|
} |
|
if (invisibleParameterAnnotations != null) { |
|
for (int i = 0, n = invisibleParameterAnnotations.length; i < n; ++i) { |
|
List<AnnotationNode> parameterAnnotations = invisibleParameterAnnotations[i]; |
|
if (parameterAnnotations == null) { |
|
continue; |
|
} |
|
for (int j = 0, m = parameterAnnotations.size(); j < m; ++j) { |
|
AnnotationNode annotation = parameterAnnotations.get(j); |
|
annotation.accept(methodVisitor.visitParameterAnnotation(i, annotation.desc, false)); |
|
} |
|
} |
|
} |
|
|
|
if (visited) { |
|
instructions.resetLabels(); |
|
} |
|
if (attrs != null) { |
|
for (int i = 0, n = attrs.size(); i < n; ++i) { |
|
methodVisitor.visitAttribute(attrs.get(i)); |
|
} |
|
} |
|
|
|
if (instructions.size() > 0) { |
|
methodVisitor.visitCode(); |
|
|
|
if (tryCatchBlocks != null) { |
|
for (int i = 0, n = tryCatchBlocks.size(); i < n; ++i) { |
|
tryCatchBlocks.get(i).updateIndex(i); |
|
tryCatchBlocks.get(i).accept(methodVisitor); |
|
} |
|
} |
|
|
|
instructions.accept(methodVisitor); |
|
|
|
if (localVariables != null) { |
|
for (int i = 0, n = localVariables.size(); i < n; ++i) { |
|
localVariables.get(i).accept(methodVisitor); |
|
} |
|
} |
|
|
|
if (visibleLocalVariableAnnotations != null) { |
|
for (int i = 0, n = visibleLocalVariableAnnotations.size(); i < n; ++i) { |
|
visibleLocalVariableAnnotations.get(i).accept(methodVisitor, true); |
|
} |
|
} |
|
if (invisibleLocalVariableAnnotations != null) { |
|
for (int i = 0, n = invisibleLocalVariableAnnotations.size(); i < n; ++i) { |
|
invisibleLocalVariableAnnotations.get(i).accept(methodVisitor, false); |
|
} |
|
} |
|
methodVisitor.visitMaxs(maxStack, maxLocals); |
|
visited = true; |
|
} |
|
methodVisitor.visitEnd(); |
|
} |
|
} |