/** * Adds the necessary field and methods to support resource locating. * * @param declaringClass the class to which we add the support field and methods */ public static void apply(@Nonnull ClassNode declaringClass, @Nullable String beanName) { injectInterface(declaringClass, EVENT_PUBLISHER_CNODE); FieldNode epField = injectField( declaringClass, EVENT_ROUTER_FIELD_NAME, PRIVATE, EVENT_PUBLISHER_FIELD_CNODE, null); Parameter erParam = param(EVENT_ROUTER_CNODE, EVENT_ROUTER_PROPERTY); if (!isBlank(beanName)) { AnnotationNode namedAnnotation = new AnnotationNode(NAMED_TYPE); namedAnnotation.addMember("value", new ConstantExpression(beanName)); erParam.addAnnotation(namedAnnotation); } MethodNode setter = new MethodNode( METHOD_SET_EVENT_ROUTER, PRIVATE, VOID_TYPE, params(erParam), NO_EXCEPTIONS, stmnt(call(field(epField), METHOD_SET_EVENT_ROUTER, args(var(EVENT_ROUTER_PROPERTY))))); setter.addAnnotation(new AnnotationNode(INJECT_TYPE)); injectMethod(declaringClass, setter); addDelegateMethods(declaringClass, EVENT_PUBLISHER_CNODE, field(epField)); }
/** * Makes the given class visitor visit this field. * * @param cv a class visitor. */ public void accept(final ClassVisitor cv) { FieldVisitor fv = cv.visitField(access, name, desc, signature, value); if (fv == null) { return; } int i, n; n = visibleAnnotations == null ? 0 : visibleAnnotations.size(); for (i = 0; i < n; ++i) { AnnotationNode an = visibleAnnotations.get(i); an.accept(fv.visitAnnotation(an.desc, true)); } n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size(); for (i = 0; i < n; ++i) { AnnotationNode an = invisibleAnnotations.get(i); an.accept(fv.visitAnnotation(an.desc, false)); } n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size(); for (i = 0; i < n; ++i) { TypeAnnotationNode an = visibleTypeAnnotations.get(i); an.accept(fv.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(fv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, false)); } n = attrs == null ? 0 : attrs.size(); for (i = 0; i < n; ++i) { fv.visitAttribute(attrs.get(i)); } fv.visitEnd(); }
private void configureAnnotationFromDefinition(AnnotationNode definition, AnnotationNode root) { ClassNode type = definition.getClassNode(); if (!type.isResolved()) return; Class clazz = type.getTypeClass(); if (clazz == Retention.class) { Expression exp = definition.getMember("value"); if (!(exp instanceof PropertyExpression)) return; PropertyExpression pe = (PropertyExpression) exp; String name = pe.getPropertyAsString(); RetentionPolicy policy = RetentionPolicy.valueOf(name); setRetentionPolicy(policy, root); } else if (clazz == Target.class) { Expression exp = definition.getMember("value"); if (!(exp instanceof ListExpression)) return; ListExpression le = (ListExpression) exp; int bitmap = 0; for (Expression e : le.getExpressions()) { PropertyExpression element = (PropertyExpression) e; String name = element.getPropertyAsString(); ElementType value = ElementType.valueOf(name); bitmap |= getElementCode(value); } root.setAllowedTargets(bitmap); } }
/** * Convenience method to see if an annotated node is {@code @MybatisAware}. * * @param node the node to check * @return true if the node is an event publisher */ public static boolean hasMybatisAwareAnnotation(AnnotatedNode node) { for (AnnotationNode annotation : node.getAnnotations()) { if (MYBATIS_AWARE_CNODE.equals(annotation.getClassNode())) { return true; } } return false; }
/** * Convenience method to see if an annotated node is {@code @EventPublisher}. * * @param node the node to check * @return true if the node is an event publisher */ public static boolean hasEventPublisherAnnotation(AnnotatedNode node) { for (AnnotationNode annotation : node.getAnnotations()) { if (EVENT_PUBLISHER_ANODE.equals(annotation.getClassNode())) { return true; } } return false; }
/** * Convenience method to see if an annotated node is {@code @MessageSourceAware}. * * @param node the node to check * @return true if the node is an event publisher */ public static boolean hasMessageSourceAwareAnnotation(AnnotatedNode node) { for (AnnotationNode annotation : node.getAnnotations()) { if (MESSAGE_SOURCE_AWARE_TYPE.equals(annotation.getClassNode())) { return true; } } return false; }
private void printAnnotation(PrintWriter out, AnnotationNode annotation) { out.print("@" + annotation.getClassNode().getName() + "("); boolean first = true; Map<String, Expression> members = annotation.getMembers(); for (String key : members.keySet()) { if (first) first = false; else out.print(", "); out.print(key + "=" + getAnnotationValue(members.get(key))); } out.print(") "); }
/** * Makes the given class visitor visit this class. * * @param cv a class visitor. */ public void accept(final ClassVisitor cv) { // visits header String[] interfaces = new String[this.interfaces.size()]; this.interfaces.toArray(interfaces); cv.visit(version, access, name, signature, superName, interfaces); // visits source if (sourceFile != null || sourceDebug != null) { cv.visitSource(sourceFile, sourceDebug); } // visits outer class if (outerClass != null) { cv.visitOuterClass(outerClass, outerMethod, outerMethodDesc); } // visits attributes int i, n; n = visibleAnnotations == null ? 0 : visibleAnnotations.size(); for (i = 0; i < n; ++i) { AnnotationNode an = visibleAnnotations.get(i); an.accept(cv.visitAnnotation(an.desc, true)); } n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size(); for (i = 0; i < n; ++i) { AnnotationNode an = invisibleAnnotations.get(i); an.accept(cv.visitAnnotation(an.desc, false)); } n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size(); for (i = 0; i < n; ++i) { TypeAnnotationNode an = visibleTypeAnnotations.get(i); an.accept(cv.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(cv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, false)); } n = attrs == null ? 0 : attrs.size(); for (i = 0; i < n; ++i) { cv.visitAttribute(attrs.get(i)); } // visits inner classes for (i = 0; i < innerClasses.size(); ++i) { innerClasses.get(i).accept(cv); } // visits fields for (i = 0; i < fields.size(); ++i) { fields.get(i).accept(cv); } // visits methods for (i = 0; i < methods.size(); ++i) { methods.get(i).accept(cv); } // visits end cv.visitEnd(); }
public void visitAnnotations(AnnotatedNode node) { List<AnnotationNode> annotations = node.getAnnotations(); if (annotations.isEmpty()) return; for (AnnotationNode an : annotations) { // skip built-in properties if (an.isBuiltIn()) continue; for (Map.Entry<String, Expression> member : an.getMembers().entrySet()) { Expression annMemberValue = member.getValue(); annMemberValue.visit(this); } } }
// GRECLIPSE add protected void visitAnnotations(Iterable<AnnotationNode> nodes) { for (AnnotationNode node : nodes) { // skip built-in properties if (node.isBuiltIn()) continue; Set<AnnotationNode> originals = node.getNodeMetaData("AnnotationCollector"); if (originals != null && !originals.isEmpty()) { visitAnnotations(originals); } visitAnnotation(node); } }
public Expression transform(Expression exp) { if (exp == null) return null; if (exp.getClass() == VariableExpression.class) { return transformVariableExpression((VariableExpression) exp); } if (exp.getClass() == BinaryExpression.class) { return transformBinaryExpression((BinaryExpression) exp); } if (exp.getClass() == PropertyExpression.class) { return transformPropertyExpression((PropertyExpression) exp); } if (exp.getClass() == MethodCallExpression.class) { return transformMethodCallExpression((MethodCallExpression) exp); } if (exp.getClass() == ClosureExpression.class) { return transformClosureExpression((ClosureExpression) exp); } if (exp.getClass() == ConstructorCallExpression.class) { return transformConstructorCallExpression((ConstructorCallExpression) exp); } if (exp.getClass() == ArgumentListExpression.class) { Expression result = exp.transformExpression(this); if (inPropertyExpression) { foundArgs = result; } return result; } if (exp instanceof ConstantExpression) { Expression result = exp.transformExpression(this); if (inPropertyExpression) { foundConstant = result; } if (inAnnotation && exp instanceof AnnotationConstantExpression) { ConstantExpression ce = (ConstantExpression) result; if (ce.getValue() instanceof AnnotationNode) { // replicate a little bit of AnnotationVisitor here // because we can't wait until later to do this AnnotationNode an = (AnnotationNode) ce.getValue(); Map<String, Expression> attributes = an.getMembers(); for (Map.Entry<String, Expression> entry : attributes.entrySet()) { Expression attrExpr = transform(entry.getValue()); entry.setValue(attrExpr); } } } return result; } return exp.transformExpression(this); }
private void setRetentionPolicy(RetentionPolicy value, AnnotationNode node) { switch (value) { case RUNTIME: node.setRuntimeRetention(true); break; case SOURCE: node.setSourceRetention(true); break; case CLASS: node.setClassRetention(true); break; default: throw new GroovyBugError("unsupported Retention " + value); } }
private void visitDeprecation(AnnotatedNode node, AnnotationNode visited) { if (visited.getClassNode().isResolved() && visited.getClassNode().getName().equals("java.lang.Deprecated")) { if (node instanceof MethodNode) { MethodNode mn = (MethodNode) node; mn.setModifiers(mn.getModifiers() | Opcodes.ACC_DEPRECATED); } else if (node instanceof FieldNode) { FieldNode fn = (FieldNode) node; fn.setModifiers(fn.getModifiers() | Opcodes.ACC_DEPRECATED); } else if (node instanceof ClassNode) { ClassNode cn = (ClassNode) node; cn.setModifiers(cn.getModifiers() | Opcodes.ACC_DEPRECATED); } } }
public void configureAnnotation(AnnotationNode node) { ClassNode type = node.getClassNode(); List<AnnotationNode> annotations = type.getAnnotations(); for (AnnotationNode an : annotations) { configureAnnotationFromDefinition(an, node); } configureAnnotationFromDefinition(node, node); }
public static void addEventPublisherIfNeeded( SourceUnit source, AnnotationNode annotationNode, ClassNode classNode) { if (needsDelegate(classNode, source, METHODS, "EventPublisher", EVENT_PUBLISHER_TYPE)) { LOG.debug("Injecting {} into {}", EVENT_PUBLISHER_TYPE, classNode.getName()); ConstantExpression value = (ConstantExpression) annotationNode.getMember("value"); String beanName = value != null ? value.getText() : null; beanName = isBlank(beanName) ? null : beanName; apply(classNode, beanName); } }
private void validateFieldAnnotations() { for (FieldNode fieldNode : annotatedClass.getFields()) { if (shouldFieldBeIgnored(fieldNode)) continue; AnnotationNode annotation = getAnnotation(fieldNode, DSL_FIELD_ANNOTATION); if (annotation == null) continue; if (ASTHelper.isListOrMap(fieldNode.getType())) return; if (annotation.getMember("members") != null) { addCompileError( String.format( "@Field.members is only valid for List or Map fields, but field %s is of type %s", fieldNode.getName(), fieldNode.getType().getName()), annotation); } } }
private void validateFields(BlockStatement block) { Validation.Option mode = getEnumMemberValue( getAnnotation(annotatedClass, VALIDATION_ANNOTATION), "option", Validation.Option.class, Validation.Option.IGNORE_UNMARKED); for (FieldNode fieldNode : annotatedClass.getFields()) { if (shouldFieldBeIgnoredForValidation(fieldNode)) continue; ClosureExpression validationClosure = createGroovyTruthClosureExpression(block.getVariableScope()); String message = null; AnnotationNode validateAnnotation = getAnnotation(fieldNode, VALIDATE_ANNOTATION); if (validateAnnotation != null) { message = getMemberStringValue( validateAnnotation, "message", "'" + fieldNode.getName() + "' must be set!"); Expression member = validateAnnotation.getMember("value"); if (member instanceof ClassExpression) { ClassNode memberType = member.getType(); if (memberType.equals(ClassHelper.make(Validate.Ignore.class))) continue; else if (!memberType.equals(ClassHelper.make(Validate.GroovyTruth.class))) { addError( "value of Validate must be either Validate.GroovyTruth, Validate.Ignore or a closure.", fieldNode); } } else if (member instanceof ClosureExpression) { validationClosure = (ClosureExpression) member; } } if (validateAnnotation != null || mode == Validation.Option.VALIDATE_UNMARKED) { block.addStatement( new AssertStatement( new BooleanExpression( callX(validationClosure, "call", args(varX(fieldNode.getName())))), message == null ? ConstantExpression.NULL : new ConstantExpression(message))); } } }
public void visit(ASTNode[] nodes, SourceUnit source) { init(nodes, source); AnnotatedNode parent = (AnnotatedNode) nodes[1]; AnnotationNode node = (AnnotationNode) nodes[0]; // temporarily have weaker check which allows for old Deprecated Annotation // if (!MY_TYPE.equals(node.getClassNode())) return; if (!node.getClassNode().getName().endsWith(".Immutable")) return; List<PropertyNode> newProperties = new ArrayList<PropertyNode>(); if (parent instanceof ClassNode) { final List<String> knownImmutableClasses = getKnownImmutableClasses(node); final List<String> knownImmutables = getKnownImmutables(node); ClassNode cNode = (ClassNode) parent; String cName = cNode.getName(); checkNotInterface(cNode, MY_TYPE_NAME); makeClassFinal(cNode); final List<PropertyNode> pList = getInstanceProperties(cNode); for (PropertyNode pNode : pList) { adjustPropertyForImmutability(pNode, newProperties); } for (PropertyNode pNode : newProperties) { cNode.getProperties().remove(pNode); addProperty(cNode, pNode); } final List<FieldNode> fList = cNode.getFields(); for (FieldNode fNode : fList) { ensureNotPublic(cName, fNode); } createConstructors(cNode, knownImmutableClasses, knownImmutables); if (!hasAnnotation(cNode, EqualsAndHashCodeASTTransformation.MY_TYPE)) { createHashCode(cNode, true, false, false, null, null); createEquals(cNode, false, false, false, null, null); } if (!hasAnnotation(cNode, ToStringASTTransformation.MY_TYPE)) { createToString(cNode, false, false, null, null, false, true); } } }
protected void visitAnnotations(AnnotatedNode node, int target) { if (node.getAnnotations().isEmpty()) { return; } this.currentClass.setAnnotated(true); if (!isAnnotationCompatible()) { addError("Annotations are not supported in the current runtime. " + JVM_ERROR_MESSAGE, node); return; } for (AnnotationNode unvisited : node.getAnnotations()) { AnnotationNode visited = visitAnnotation(unvisited); boolean isTargetAnnotation = visited.getClassNode().isResolved() && visited.getClassNode().getName().equals("java.lang.annotation.Target"); // Check if the annotation target is correct, unless it's the target annotating an annotation // definition // defining on which target elements the annotation applies if (!isTargetAnnotation && !visited.isTargetAllowed(target)) { addError( "Annotation @" + visited.getClassNode().getName() + " is not allowed on element " + AnnotationNode.targetToName(target), visited); } visitDeprecation(node, visited); } }
public void visit(ASTNode[] nodes, SourceUnit source) { if (nodes.length != 2 || !(nodes[0] instanceof AnnotationNode) || !(nodes[1] instanceof AnnotatedNode)) { throw new RuntimeException( "Internal error: expecting [AnnotationNode, AnnotatedNode] but got: " + Arrays.asList(nodes)); } AnnotatedNode parent = (AnnotatedNode) nodes[1]; AnnotationNode node = (AnnotationNode) nodes[0]; boolean legacyMode = LEGACY_TYPE_NAME.equals(node.getClassNode().getName()); if (!MY_TYPE.equals(node.getClassNode()) && !legacyMode) return; Expression value = node.getMember("value"); if (parent instanceof ClassNode) { List<groovy.transform.PackageScopeTarget> targets; if (value == null) targets = Arrays.asList(legacyMode ? PackageScopeTarget.FIELDS : PackageScopeTarget.CLASS); else targets = determineTargets(value); visitClassNode((ClassNode) parent, targets); parent.getAnnotations(); } else { if (value != null) throw new RuntimeException( "Error during " + MY_TYPE_NAME + " processing: " + TARGET_CLASS_NAME + " only allowed at class level."); if (parent instanceof MethodNode) { visitMethodNode((MethodNode) parent); } else if (parent instanceof FieldNode) { visitFieldNode((FieldNode) parent); } } }
private void configureAnnotation(AnnotationNode node, Annotation annotation) { Class type = annotation.annotationType(); if (type == Retention.class) { Retention r = (Retention) annotation; RetentionPolicy value = r.value(); setRetentionPolicy(value, node); node.setMember( "value", new PropertyExpression( new ClassExpression(ClassHelper.makeWithoutCaching(RetentionPolicy.class, false)), value.toString())); } else if (type == Target.class) { Target t = (Target) annotation; ElementType[] elements = t.value(); ListExpression elementExprs = new ListExpression(); for (ElementType element : elements) { elementExprs.addExpression( new PropertyExpression( new ClassExpression(ClassHelper.ELEMENT_TYPE_TYPE), element.name())); } node.setMember("value", elementExprs); } else { Method[] declaredMethods = type.getDeclaredMethods(); for (int i = 0; i < declaredMethods.length; i++) { Method declaredMethod = declaredMethods[i]; try { Object value = declaredMethod.invoke(annotation); Expression valueExpression = annotationValueToExpression(value); if (valueExpression == null) continue; node.setMember(declaredMethod.getName(), valueExpression); } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } } } }
@SuppressWarnings("unchecked") public <T extends Enum> T getEnumMemberValue( AnnotationNode node, String name, Class<T> type, T defaultValue) { if (node == null) return defaultValue; final PropertyExpression member = (PropertyExpression) node.getMember(name); if (member == null) return defaultValue; if (!type.equals(member.getObjectExpression().getType().getTypeClass())) return defaultValue; try { String value = member.getPropertyAsString(); Method fromString = type.getMethod("valueOf", String.class); return (T) fromString.invoke(null, value); } catch (Exception e) { return defaultValue; } }
private List<String> getKnownImmutables(AnnotationNode node) { final ArrayList<String> immutables = new ArrayList<String>(); final Expression expression = node.getMember(MEMBER_KNOWN_IMMUTABLES); if (expression == null) return immutables; if (!(expression instanceof ListExpression)) { addError( "Use the Groovy list notation [el1, el2] to specify known immutable property names via \"" + MEMBER_KNOWN_IMMUTABLES + "\"", node); return immutables; } final ListExpression listExpression = (ListExpression) expression; for (Expression listItemExpression : listExpression.getExpressions()) { if (listItemExpression instanceof ConstantExpression) { immutables.add((String) ((ConstantExpression) listItemExpression).getValue()); } } return immutables; }
@Override public void visit(ASTNode[] astNodes, SourceUnit source) { if (!(astNodes[0] instanceof AnnotationNode) || !(astNodes[1] instanceof AnnotatedNode)) { throw new RuntimeException("Internal error: wrong types: $node.class / $parent.class"); } AnnotatedNode parent = (AnnotatedNode) astNodes[1]; AnnotationNode node = (AnnotationNode) astNodes[0]; if (!MY_TYPE.equals(node.getClassNode()) || !(parent instanceof ClassNode)) { return; } ClassNode classNode = (ClassNode) parent; if (classNode.isInterface() || Modifier.isAbstract(classNode.getModifiers())) { return; } boolean junit3Test = isJunit3Test(classNode); boolean spockTest = isSpockTest(classNode); boolean isJunit = classNode.getName().endsWith("Tests"); if (!junit3Test && !spockTest && !isJunit) return; Expression value = node.getMember("value"); ClassExpression ce; if (value instanceof ClassExpression) { ce = (ClassExpression) value; testFor(classNode, ce); } else { if (!junit3Test) { List<AnnotationNode> annotations = classNode.getAnnotations(MY_TYPE); if (annotations.size() > 0) return; // bail out, in this case it was already applied as a local transform // no explicit class specified try by convention String fileName = source.getName(); String className = GrailsResourceUtils.getClassName(new FileSystemResource(fileName)); if (className != null) { boolean isSpock = className.endsWith("Spec"); String targetClassName = null; if (isJunit) { targetClassName = className.substring(0, className.indexOf("Tests")); } else if (isSpock) { targetClassName = className.substring(0, className.indexOf("Spec")); } if (targetClassName != null) { Resource targetResource = getResourceLocator().findResourceForClassName(targetClassName); if (targetResource != null) { try { if (GrailsResourceUtils.isDomainClass(targetResource.getURL())) { testFor( classNode, new ClassExpression( new ClassNode(targetClassName, 0, ClassHelper.OBJECT_TYPE))); } else { for (String artefactType : artefactTypeToTestMap.keySet()) { if (targetClassName.endsWith(artefactType)) { testFor( classNode, new ClassExpression( new ClassNode(targetClassName, 0, ClassHelper.OBJECT_TYPE))); break; } } } } catch (IOException e) { // ignore } } } } } } }
/** * Makes the given method visitor visit this method. * * @param mv a method visitor. */ public void accept(final MethodVisitor mv) { // visits the method parameters 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); } // visits the method attributes 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)); } // visits the method's code if (instructions.size() > 0) { mv.visitCode(); // visits try catch blocks n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size(); for (i = 0; i < n; ++i) { tryCatchBlocks.get(i).updateIndex(i); tryCatchBlocks.get(i).accept(mv); } // visits instructions instructions.accept(mv); // visits local variables n = localVariables == null ? 0 : localVariables.size(); for (i = 0; i < n; ++i) { localVariables.get(i).accept(mv); } // visits local variable annotations 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); } // visits maxs mv.visitMaxs(maxStack, maxLocals); visited = true; } mv.visitEnd(); }
protected void visitAnnotation(AnnotationNode node) { for (Expression expr : node.getMembers().values()) { expr.visit(this); } }