|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
package jdk.internal.org.objectweb.asm.tree; |
|
|
|
import java.util.ArrayList; |
|
import java.util.Arrays; |
|
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.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 List<AnnotationNode>[] visibleParameterAnnotations; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
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.ASM6); |
|
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 desc, |
|
final String signature, final String[] exceptions) { |
|
this(Opcodes.ASM6, access, name, desc, signature, exceptions); |
|
if (getClass() != MethodNode.class) { |
|
throw new IllegalStateException(); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public MethodNode(final int api, final int access, final String name, |
|
final String desc, final String signature, final String[] exceptions) { |
|
super(api); |
|
this.access = access; |
|
this.name = name; |
|
this.desc = desc; |
|
this.signature = signature; |
|
this.exceptions = new ArrayList<String>(exceptions == null ? 0 |
|
: exceptions.length); |
|
boolean isAbstract = (access & Opcodes.ACC_ABSTRACT) != 0; |
|
if (!isAbstract) { |
|
this.localVariables = new ArrayList<LocalVariableNode>(5); |
|
} |
|
this.tryCatchBlocks = new ArrayList<TryCatchBlockNode>(); |
|
if (exceptions != null) { |
|
this.exceptions.addAll(Arrays.asList(exceptions)); |
|
} |
|
this.instructions = new InsnList(); |
|
} |
|
|
|
// ------------------------------------------------------------------------ |
|
// Implementation of the MethodVisitor abstract class |
|
// ------------------------------------------------------------------------ |
|
|
|
@Override |
|
public void visitParameter(String name, int access) { |
|
if (parameters == null) { |
|
parameters = new ArrayList<ParameterNode>(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 desc, |
|
final boolean visible) { |
|
AnnotationNode an = new AnnotationNode(desc); |
|
if (visible) { |
|
if (visibleAnnotations == null) { |
|
visibleAnnotations = new ArrayList<AnnotationNode>(1); |
|
} |
|
visibleAnnotations.add(an); |
|
} else { |
|
if (invisibleAnnotations == null) { |
|
invisibleAnnotations = new ArrayList<AnnotationNode>(1); |
|
} |
|
invisibleAnnotations.add(an); |
|
} |
|
return an; |
|
} |
|
|
|
@Override |
|
public AnnotationVisitor visitTypeAnnotation(int typeRef, |
|
TypePath typePath, String desc, boolean visible) { |
|
TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc); |
|
if (visible) { |
|
if (visibleTypeAnnotations == null) { |
|
visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1); |
|
} |
|
visibleTypeAnnotations.add(an); |
|
} else { |
|
if (invisibleTypeAnnotations == null) { |
|
invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1); |
|
} |
|
invisibleTypeAnnotations.add(an); |
|
} |
|
return an; |
|
} |
|
|
|
@Override |
|
@SuppressWarnings("unchecked") |
|
public AnnotationVisitor visitParameterAnnotation(final int parameter, |
|
final String desc, final boolean visible) { |
|
AnnotationNode an = new AnnotationNode(desc); |
|
if (visible) { |
|
if (visibleParameterAnnotations == null) { |
|
int params = Type.getArgumentTypes(this.desc).length; |
|
visibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params]; |
|
} |
|
if (visibleParameterAnnotations[parameter] == null) { |
|
visibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>( |
|
1); |
|
} |
|
visibleParameterAnnotations[parameter].add(an); |
|
} else { |
|
if (invisibleParameterAnnotations == null) { |
|
int params = Type.getArgumentTypes(this.desc).length; |
|
invisibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params]; |
|
} |
|
if (invisibleParameterAnnotations[parameter] == null) { |
|
invisibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>( |
|
1); |
|
} |
|
invisibleParameterAnnotations[parameter].add(an); |
|
} |
|
return an; |
|
} |
|
|
|
@Override |
|
public void visitAttribute(final Attribute attr) { |
|
if (attrs == null) { |
|
attrs = new ArrayList<Attribute>(1); |
|
} |
|
attrs.add(attr); |
|
} |
|
|
|
@Override |
|
public void visitCode() { |
|
} |
|
|
|
@Override |
|
public void visitFrame(final int type, final int nLocal, |
|
final Object[] local, final int nStack, final Object[] stack) { |
|
instructions.add(new FrameNode(type, nLocal, local == null ? null |
|
: getLabelNodes(local), nStack, 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 desc) { |
|
instructions.add(new FieldInsnNode(opcode, owner, name, desc)); |
|
} |
|
|
|
@Deprecated |
|
@Override |
|
public void visitMethodInsn(int opcode, String owner, String name, |
|
String desc) { |
|
if (api >= Opcodes.ASM5) { |
|
super.visitMethodInsn(opcode, owner, name, desc); |
|
return; |
|
} |
|
instructions.add(new MethodInsnNode(opcode, owner, name, desc)); |
|
} |
|
|
|
@Override |
|
public void visitMethodInsn(int opcode, String owner, String name, |
|
String desc, boolean itf) { |
|
if (api < Opcodes.ASM5) { |
|
super.visitMethodInsn(opcode, owner, name, desc, itf); |
|
return; |
|
} |
|
instructions.add(new MethodInsnNode(opcode, owner, name, desc, itf)); |
|
} |
|
|
|
@Override |
|
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, |
|
Object... bsmArgs) { |
|
instructions.add(new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs)); |
|
} |
|
|
|
@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 cst) { |
|
instructions.add(new LdcInsnNode(cst)); |
|
} |
|
|
|
@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 desc, final int dims) { |
|
instructions.add(new MultiANewArrayInsnNode(desc, dims)); |
|
} |
|
|
|
@Override |
|
public AnnotationVisitor visitInsnAnnotation(int typeRef, |
|
TypePath typePath, String desc, boolean visible) { |
|
// Finds the last real instruction, i.e. the instruction targeted by |
|
|
|
AbstractInsnNode insn = instructions.getLast(); |
|
while (insn.getOpcode() == -1) { |
|
insn = insn.getPrevious(); |
|
} |
|
|
|
TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc); |
|
if (visible) { |
|
if (insn.visibleTypeAnnotations == null) { |
|
insn.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>( |
|
1); |
|
} |
|
insn.visibleTypeAnnotations.add(an); |
|
} else { |
|
if (insn.invisibleTypeAnnotations == null) { |
|
insn.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>( |
|
1); |
|
} |
|
insn.invisibleTypeAnnotations.add(an); |
|
} |
|
return an; |
|
} |
|
|
|
@Override |
|
public void visitTryCatchBlock(final Label start, final Label end, |
|
final Label handler, final String type) { |
|
tryCatchBlocks.add(new TryCatchBlockNode(getLabelNode(start), |
|
getLabelNode(end), getLabelNode(handler), type)); |
|
} |
|
|
|
@Override |
|
public AnnotationVisitor visitTryCatchAnnotation(int typeRef, |
|
TypePath typePath, String desc, boolean visible) { |
|
TryCatchBlockNode tcb = tryCatchBlocks.get((typeRef & 0x00FFFF00) >> 8); |
|
TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc); |
|
if (visible) { |
|
if (tcb.visibleTypeAnnotations == null) { |
|
tcb.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>( |
|
1); |
|
} |
|
tcb.visibleTypeAnnotations.add(an); |
|
} else { |
|
if (tcb.invisibleTypeAnnotations == null) { |
|
tcb.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>( |
|
1); |
|
} |
|
tcb.invisibleTypeAnnotations.add(an); |
|
} |
|
return an; |
|
} |
|
|
|
@Override |
|
public void visitLocalVariable(final String name, final String desc, |
|
final String signature, final Label start, final Label end, |
|
final int index) { |
|
localVariables.add(new LocalVariableNode(name, desc, signature, |
|
getLabelNode(start), getLabelNode(end), index)); |
|
} |
|
|
|
@Override |
|
public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, |
|
TypePath typePath, Label[] start, Label[] end, int[] index, |
|
String desc, boolean visible) { |
|
LocalVariableAnnotationNode an = new LocalVariableAnnotationNode( |
|
typeRef, typePath, getLabelNodes(start), getLabelNodes(end), |
|
index, desc); |
|
if (visible) { |
|
if (visibleLocalVariableAnnotations == null) { |
|
visibleLocalVariableAnnotations = new ArrayList<LocalVariableAnnotationNode>( |
|
1); |
|
} |
|
visibleLocalVariableAnnotations.add(an); |
|
} else { |
|
if (invisibleLocalVariableAnnotations == null) { |
|
invisibleLocalVariableAnnotations = new ArrayList<LocalVariableAnnotationNode>( |
|
1); |
|
} |
|
invisibleLocalVariableAnnotations.add(an); |
|
} |
|
return an; |
|
} |
|
|
|
@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() { |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected LabelNode getLabelNode(final Label l) { |
|
if (!(l.info instanceof LabelNode)) { |
|
l.info = new LabelNode(); |
|
} |
|
return (LabelNode) l.info; |
|
} |
|
|
|
private LabelNode[] getLabelNodes(final Label[] l) { |
|
LabelNode[] nodes = new LabelNode[l.length]; |
|
for (int i = 0; i < l.length; ++i) { |
|
nodes[i] = getLabelNode(l[i]); |
|
} |
|
return nodes; |
|
} |
|
|
|
private Object[] getLabelNodes(final Object[] objs) { |
|
Object[] nodes = new Object[objs.length]; |
|
for (int i = 0; i < objs.length; ++i) { |
|
Object o = objs[i]; |
|
if (o instanceof Label) { |
|
o = getLabelNode((Label) o); |
|
} |
|
nodes[i] = o; |
|
} |
|
return nodes; |
|
} |
|
|
|
// ------------------------------------------------------------------------ |
|
// Accept method |
|
// ------------------------------------------------------------------------ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void check(final int api) { |
|
if (api == Opcodes.ASM4) { |
|
if (visibleTypeAnnotations != null |
|
&& visibleTypeAnnotations.size() > 0) { |
|
throw new RuntimeException(); |
|
} |
|
if (invisibleTypeAnnotations != null |
|
&& invisibleTypeAnnotations.size() > 0) { |
|
throw new RuntimeException(); |
|
} |
|
int n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size(); |
|
for (int i = 0; i < n; ++i) { |
|
TryCatchBlockNode tcb = tryCatchBlocks.get(i); |
|
if (tcb.visibleTypeAnnotations != null |
|
&& tcb.visibleTypeAnnotations.size() > 0) { |
|
throw new RuntimeException(); |
|
} |
|
if (tcb.invisibleTypeAnnotations != null |
|
&& tcb.invisibleTypeAnnotations.size() > 0) { |
|
throw new RuntimeException(); |
|
} |
|
} |
|
for (int i = 0; i < instructions.size(); ++i) { |
|
AbstractInsnNode insn = instructions.get(i); |
|
if (insn.visibleTypeAnnotations != null |
|
&& insn.visibleTypeAnnotations.size() > 0) { |
|
throw new RuntimeException(); |
|
} |
|
if (insn.invisibleTypeAnnotations != null |
|
&& insn.invisibleTypeAnnotations.size() > 0) { |
|
throw new RuntimeException(); |
|
} |
|
if (insn instanceof MethodInsnNode) { |
|
boolean itf = ((MethodInsnNode) insn).itf; |
|
if (itf != (insn.opcode == Opcodes.INVOKEINTERFACE)) { |
|
throw new RuntimeException(); |
|
} |
|
} |
|
} |
|
if (visibleLocalVariableAnnotations != null |
|
&& visibleLocalVariableAnnotations.size() > 0) { |
|
throw new RuntimeException(); |
|
} |
|
if (invisibleLocalVariableAnnotations != null |
|
&& invisibleLocalVariableAnnotations.size() > 0) { |
|
throw new RuntimeException(); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void accept(final ClassVisitor cv) { |
|
String[] exceptions = new String[this.exceptions.size()]; |
|
this.exceptions.toArray(exceptions); |
|
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, |
|
exceptions); |
|
if (mv != null) { |
|
accept(mv); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void accept(final MethodVisitor mv) { |
|
|
|
int i, j, n; |
|
n = parameters == null ? 0 : parameters.size(); |
|
for (i = 0; i < n; i++) { |
|
ParameterNode parameter = parameters.get(i); |
|
mv.visitParameter(parameter.name, parameter.access); |
|
} |
|
|
|
if (annotationDefault != null) { |
|
AnnotationVisitor av = mv.visitAnnotationDefault(); |
|
AnnotationNode.accept(av, null, annotationDefault); |
|
if (av != null) { |
|
av.visitEnd(); |
|
} |
|
} |
|
n = visibleAnnotations == null ? 0 : visibleAnnotations.size(); |
|
for (i = 0; i < n; ++i) { |
|
AnnotationNode an = visibleAnnotations.get(i); |
|
an.accept(mv.visitAnnotation(an.desc, true)); |
|
} |
|
n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size(); |
|
for (i = 0; i < n; ++i) { |
|
AnnotationNode an = invisibleAnnotations.get(i); |
|
an.accept(mv.visitAnnotation(an.desc, false)); |
|
} |
|
n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size(); |
|
for (i = 0; i < n; ++i) { |
|
TypeAnnotationNode an = visibleTypeAnnotations.get(i); |
|
an.accept(mv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, |
|
true)); |
|
} |
|
n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations |
|
.size(); |
|
for (i = 0; i < n; ++i) { |
|
TypeAnnotationNode an = invisibleTypeAnnotations.get(i); |
|
an.accept(mv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, |
|
false)); |
|
} |
|
n = visibleParameterAnnotations == null ? 0 |
|
: visibleParameterAnnotations.length; |
|
for (i = 0; i < n; ++i) { |
|
List<?> l = visibleParameterAnnotations[i]; |
|
if (l == null) { |
|
continue; |
|
} |
|
for (j = 0; j < l.size(); ++j) { |
|
AnnotationNode an = (AnnotationNode) l.get(j); |
|
an.accept(mv.visitParameterAnnotation(i, an.desc, true)); |
|
} |
|
} |
|
n = invisibleParameterAnnotations == null ? 0 |
|
: invisibleParameterAnnotations.length; |
|
for (i = 0; i < n; ++i) { |
|
List<?> l = invisibleParameterAnnotations[i]; |
|
if (l == null) { |
|
continue; |
|
} |
|
for (j = 0; j < l.size(); ++j) { |
|
AnnotationNode an = (AnnotationNode) l.get(j); |
|
an.accept(mv.visitParameterAnnotation(i, an.desc, false)); |
|
} |
|
} |
|
if (visited) { |
|
instructions.resetLabels(); |
|
} |
|
n = attrs == null ? 0 : attrs.size(); |
|
for (i = 0; i < n; ++i) { |
|
mv.visitAttribute(attrs.get(i)); |
|
} |
|
|
|
if (instructions.size() > 0) { |
|
mv.visitCode(); |
|
|
|
n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size(); |
|
for (i = 0; i < n; ++i) { |
|
tryCatchBlocks.get(i).updateIndex(i); |
|
tryCatchBlocks.get(i).accept(mv); |
|
} |
|
|
|
instructions.accept(mv); |
|
|
|
n = localVariables == null ? 0 : localVariables.size(); |
|
for (i = 0; i < n; ++i) { |
|
localVariables.get(i).accept(mv); |
|
} |
|
|
|
n = visibleLocalVariableAnnotations == null ? 0 |
|
: visibleLocalVariableAnnotations.size(); |
|
for (i = 0; i < n; ++i) { |
|
visibleLocalVariableAnnotations.get(i).accept(mv, true); |
|
} |
|
n = invisibleLocalVariableAnnotations == null ? 0 |
|
: invisibleLocalVariableAnnotations.size(); |
|
for (i = 0; i < n; ++i) { |
|
invisibleLocalVariableAnnotations.get(i).accept(mv, false); |
|
} |
|
|
|
mv.visitMaxs(maxStack, maxLocals); |
|
visited = true; |
|
} |
|
mv.visitEnd(); |
|
} |
|
} |