private void extractGrab(Expression init, ConstantExpression ce) { if (ce.getValue() instanceof AnnotationNode) { AnnotationNode annotation = (AnnotationNode) ce.getValue(); if ((init != null) && (annotation.getMember("initClass") != null)) { annotation.setMember("initClass", init); } String name = annotation.getClassNode().getName(); if ((GRAB_CLASS_NAME.equals(name)) || (allowShortGrab && GRAB_SHORT_NAME.equals(name)) || (grabAliases.contains(name))) { grabAnnotations.add(annotation); } if ((GRABEXCLUDE_CLASS_NAME.equals(name)) || (allowShortGrabExcludes && GRABEXCLUDE_SHORT_NAME.equals(name)) || (grabExcludeAliases.contains(name))) { grabExcludeAnnotations.add(annotation); } if ((GRABCONFIG_CLASS_NAME.equals(name)) || (allowShortGrabConfig && GRABCONFIG_SHORT_NAME.equals(name)) || (grabConfigAliases.contains(name))) { grabConfigAnnotations.add(annotation); } if ((GRABRESOLVER_CLASS_NAME.equals(name)) || (allowShortGrabResolver && GRABRESOLVER_SHORT_NAME.equals(name)) || (grabResolverAliases.contains(name))) { grabResolverAnnotations.add(annotation); } } }
/** * 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)); }
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); } }
/** * Adds the annotation to the internal target list if a match is found. * * @param node the AST node we are processing */ public void visitAnnotations(AnnotatedNode node) { super.visitAnnotations(node); for (AnnotationNode an : node.getAnnotations()) { String name = an.getClassNode().getName(); if ((GRAB_CLASS_NAME.equals(name)) || (allowShortGrab && GRAB_SHORT_NAME.equals(name)) || (grabAliases.contains(name))) { grabAnnotations.add(an); } if ((GRABEXCLUDE_CLASS_NAME.equals(name)) || (allowShortGrabExcludes && GRABEXCLUDE_SHORT_NAME.equals(name)) || (grabExcludeAliases.contains(name))) { grabExcludeAnnotations.add(an); } if ((GRABCONFIG_CLASS_NAME.equals(name)) || (allowShortGrabConfig && GRABCONFIG_SHORT_NAME.equals(name)) || (grabConfigAliases.contains(name))) { grabConfigAnnotations.add(an); } if ((GRAPES_CLASS_NAME.equals(name)) || (allowShortGrapes && GRAPES_SHORT_NAME.equals(name)) || (grapesAliases.contains(name))) { grapesAnnotations.add(an); } if ((GRABRESOLVER_CLASS_NAME.equals(name)) || (allowShortGrabResolver && GRABRESOLVER_SHORT_NAME.equals(name)) || (grabResolverAliases.contains(name))) { grabResolverAnnotations.add(an); } } }
public static void configureAnnotationFromDefinition( AnnotationNode definition, AnnotationNode root) { ClassNode type = definition.getClassNode(); if ("java.lang.annotation.Retention".equals(type.getName())) { 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 ("java.lang.annotation.Target".equals(type.getName())) { Expression exp = definition.getMember("value"); if (!(exp instanceof ListExpression)) return; ListExpression le = (ListExpression) exp; int bitmap = 0; for (Expression e : le.getExpressions()) { if (!(e instanceof PropertyExpression)) return; PropertyExpression element = (PropertyExpression) e; String name = element.getPropertyAsString(); ElementType value = ElementType.valueOf(name); bitmap |= getElementCode(value); } root.setAllowedTargets(bitmap); } }
private void callGrabAsStaticInitIfNeeded( ClassNode classNode, ClassNode grapeClassNode, AnnotationNode node, List<Map<String, Object>> grabExcludeMaps) { if ((node.getMember("initClass") == null) || (node.getMember("initClass") == ConstantExpression.TRUE)) { List<Statement> grabInitializers = new ArrayList<Statement>(); // add Grape.grab(excludeArgs, [group:group, module:module, version:version, // classifier:classifier]) // or Grape.grab([group:group, module:module, version:version, classifier:classifier]) MapExpression me = new MapExpression(); for (String s : GRAB_REQUIRED) { me.addMapEntryExpression(new ConstantExpression(s), node.getMember(s)); } for (String s : GRAB_OPTIONAL) { if (node.getMember(s) != null) me.addMapEntryExpression(new ConstantExpression(s), node.getMember(s)); } if (autoDownload != null) { me.addMapEntryExpression( new ConstantExpression(AUTO_DOWNLOAD_SETTING), new ConstantExpression(autoDownload)); } if (disableChecksums != null) { me.addMapEntryExpression( new ConstantExpression(DISABLE_CHECKSUMS_SETTING), new ConstantExpression(disableChecksums)); } ArgumentListExpression grabArgs; if (grabExcludeMaps.isEmpty()) { grabArgs = new ArgumentListExpression(me); } else { MapExpression args = new MapExpression(); ListExpression list = new ListExpression(); for (Map<String, Object> map : grabExcludeMaps) { Set<Map.Entry<String, Object>> entries = map.entrySet(); MapExpression inner = new MapExpression(); for (Map.Entry<String, Object> entry : entries) { inner.addMapEntryExpression( new ConstantExpression(entry.getKey()), new ConstantExpression(entry.getValue())); } list.addExpression(inner); } args.addMapEntryExpression(new ConstantExpression("excludes"), list); grabArgs = new ArgumentListExpression(args, me); } grabInitializers.add( new ExpressionStatement( new StaticMethodCallExpression(grapeClassNode, "grab", grabArgs))); // insert at beginning so we have the classloader set up before the class is called classNode.addStaticInitializerStatements(grabInitializers, true); } }
/** * 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 @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; }
public void visit(GroovyCodeVisitor visitor) { AnnotationNode node = (AnnotationNode) getValue(); Map<String, Expression> attrs = node.getMembers(); for (Expression expr : attrs.values()) { expr.visit(visitor); } super.visit(visitor); }
/** * 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_CNODE.equals(annotation.getClassNode())) { return true; } } return false; }
private Class[] getTransformClasses(ClassNode classNode) { if (!classNode.hasClass()) { List<AnnotationNode> annotations = classNode.getAnnotations(); AnnotationNode transformAnnotation = null; for (AnnotationNode anno : annotations) { if (anno.getClassNode().getName().equals(GroovyASTTransformationClass.class.getName())) { transformAnnotation = anno; break; } } if (transformAnnotation != null) { Expression expr = (Expression) transformAnnotation.getMember("classes"); if (expr == null) { return NO_CLASSES; } Class<?>[] values = NO_CLASSES; // Will need to extract the classnames if (expr instanceof ListExpression) { List<Class<?>> loadedClasses = new ArrayList<Class<?>>(); ListExpression expression = (ListExpression) expr; List<Expression> expressions = expression.getExpressions(); for (Expression oneExpr : expressions) { String classname = ((ClassExpression) oneExpr).getType().getName(); try { Class<?> clazz = Class.forName(classname, false, transformLoader); loadedClasses.add(clazz); } catch (ClassNotFoundException cnfe) { source .getErrorCollector() .addError( new SimpleMessage( "Ast transform processing, cannot find " + classname, source)); } } if (loadedClasses.size() != 0) { values = loadedClasses.toArray(new Class<?>[loadedClasses.size()]); } return values; } else { } throw new RuntimeException( "nyi implemented in eclipse: need to support: " + expr + " (class=" + expr.getClass() + ")"); } return null; } else { Annotation transformClassAnnotation = getTransformClassAnnotation(classNode); if (transformClassAnnotation == null) { return null; } return getTransformClasses(transformClassAnnotation); } }
public static AnnotationNode findAnnotation( ClassNode annotationClassNode, List<AnnotationNode> annotations) { for (AnnotationNode annotation : annotations) { if (annotation.getClassNode().equals(annotationClassNode)) { return annotation; } } return null; }
AnnotationNode findAnnotation(ClassNode clazz) { if (clazz != null) { for (AnnotationNode node : clazz.getAnnotations()) { if (node.getClassNode().getName().equals(LineNumber.class.getName())) { // LOG.debug "Transforming in ${clazz.name}" return node; } } } return null; }
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(") "); }
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); } } }
public void visit(ASTNode[] nodes, SourceUnit source) { init(nodes, source); AnnotatedNode parent = (AnnotatedNode) nodes[1]; AnnotationNode node = (AnnotationNode) nodes[0]; if (!MY_TYPE.equals(node.getClassNode())) return; if (parent instanceof DeclarationExpression) { changeBaseScriptTypeFromDeclaration((DeclarationExpression) parent, node); } else if (parent instanceof ImportNode || parent instanceof PackageNode) { changeBaseScriptTypeFromPackageOrImport(source, parent, node); } else if (parent instanceof ClassNode) { changeBaseScriptTypeFromClass((ClassNode) parent, 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); }
/** * For the supplied classnode, this method will check if there is an annotation on it of kind * 'GroovyASTTransformationClass'. If there is then the 'value' member of that annotation will be * retrieved and the value considered to be the class name of a transformation. * * @return null if no annotation found, otherwise a String[] of classnames - this will be size 0 * if no value was specified */ private String[] getTransformClassNames(ClassNode cn) { if (!cn.hasClass()) { List<AnnotationNode> annotations = cn.getAnnotations(); AnnotationNode transformAnnotation = null; for (AnnotationNode anno : annotations) { if (anno.getClassNode().getName().equals(GroovyASTTransformationClass.class.getName())) { transformAnnotation = anno; break; } } if (transformAnnotation != null) { // will work so long as signature for the member 'value' is String[] Expression expr2 = transformAnnotation.getMember("value"); String[] values = null; if (expr2 == null) { return NONE; } if (expr2 instanceof ListExpression) { ListExpression expression = (ListExpression) expr2; List<Expression> expressions = expression.getExpressions(); values = new String[expressions.size()]; int e = 0; for (Expression expr : expressions) { values[e++] = ((ConstantExpression) expr).getText(); } } else if (expr2 instanceof ConstantExpression) { values = new String[1]; values[0] = ((ConstantExpression) expr2).getText(); } else { throw new IllegalStateException( "NYI: eclipse doesn't understand this kind of expression in an Ast transform definition: " + expr2 + " (class=" + expr2.getClass().getName() + ")"); } return values; } return null; } else { // FIXASC check haven't broken transforms for 'vanilla' (outside of eclipse) execution of // groovyc Annotation transformClassAnnotation = getTransformClassAnnotation(cn); if (transformClassAnnotation == null) { return null; } return getTransformClassNames(transformClassAnnotation); } }
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); } } }
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 checkForInitContextClassLoader(AnnotationNode node) { Object val = node.getMember("initContextClassLoader"); if (val == null || !(val instanceof ConstantExpression)) return; Object initContextClassLoaderObject = ((ConstantExpression) val).getValue(); if (!(initContextClassLoaderObject instanceof Boolean)) return; initContextClassLoader = (Boolean) initContextClassLoaderObject; }
@SuppressWarnings("unused") private List<String> getTransformClassNames( AnnotationNode annotation, Annotation transformClassAnnotation) { List<String> result = new ArrayList<String>(); try { Method valueMethod = transformClassAnnotation.getClass().getMethod("value"); String[] names = (String[]) valueMethod.invoke(transformClassAnnotation); result.addAll(Arrays.asList(names)); Method classesMethod = transformClassAnnotation.getClass().getMethod("classes"); Class[] classes = (Class[]) classesMethod.invoke(transformClassAnnotation); for (Class klass : classes) { result.add(klass.getName()); } if (names.length > 0 && classes.length > 0) { source .getErrorCollector() .addError( new SimpleMessage( "@GroovyASTTransformationClass in " + annotation.getClassNode().getName() + " should specify transforms only by class names or by classes and not by both", source)); } } catch (Exception e) { source.addException(e); } return result; }
// GRECLIPSE: start: slight refactoring to provide a new method that can work with a real // annotation @SuppressWarnings("unused") private void addTransformsToClassNode( AnnotationNode annotation, Annotation transformClassAnnotation) { String[] transformClassNames = getTransformClassNames(annotation.getClassNode()); Class[] transformClasses = getTransformClasses(transformClassAnnotation); addTransformsToClassNode(annotation, transformClassNames, transformClasses); }
public void visit(ASTNode[] nodes, SourceUnit source) { init(nodes, source); AnnotatedNode parent = (AnnotatedNode) nodes[1]; AnnotationNode node = (AnnotationNode) nodes[0]; if (!MY_TYPE.equals(node.getClassNode())) return; if (parent instanceof DeclarationExpression) { setScriptURIOnDeclaration((DeclarationExpression) parent, node); } else if (parent instanceof FieldNode) { setScriptURIOnField((FieldNode) parent, node); } else { addError( "Expected to find the annotation " + MY_TYPE_NAME + " on an declaration statement.", parent); } }
private void verifyCompilePhase(AnnotationNode annotation, Class<?> klass) { GroovyASTTransformation transformationClass = klass.getAnnotation(GroovyASTTransformation.class); if (transformationClass != null) { CompilePhase specifiedCompilePhase = transformationClass.phase(); if (specifiedCompilePhase.getPhaseNumber() < CompilePhase.SEMANTIC_ANALYSIS.getPhaseNumber()) { source .getErrorCollector() .addError( new SimpleMessage( annotation.getClassNode().getName() + " is defined to be run in compile phase " + specifiedCompilePhase + ". Local AST transformations must run in " + CompilePhase.SEMANTIC_ANALYSIS + " or later!", source)); } } else { source .getErrorCollector() .addError( new SimpleMessage( "AST transformation implementation classes must be annotated with " + GroovyASTTransformation.class.getName() + ". " + klass.getName() + " lacks this annotation.", source)); } }
private void checkForAutoDownload(AnnotationNode node) { Object val = node.getMember(AUTO_DOWNLOAD_SETTING); if (val == null || !(val instanceof ConstantExpression)) return; Object autoDownloadValue = ((ConstantExpression) val).getValue(); if (!(autoDownloadValue instanceof Boolean)) return; autoDownload = (Boolean) autoDownloadValue; }
private static String lookupCategoryName(AnnotationNode logAnnotation) { Expression member = logAnnotation.getMember("category"); if (member != null && member.getText() != null) { return member.getText(); } return DEFAULT_CATEGORY_NAME; }
private void changeBaseScriptTypeFromDeclaration( final DeclarationExpression de, final AnnotationNode node) { if (de.isMultipleAssignmentDeclaration()) { addError( "Annotation " + MY_TYPE_NAME + " not supported with multiple assignment notation.", de); return; } if (!(de.getRightExpression() instanceof EmptyExpression)) { addError("Annotation " + MY_TYPE_NAME + " not supported with variable assignment.", de); return; } Expression value = node.getMember("value"); if (value != null) { addError( "Annotation " + MY_TYPE_NAME + " cannot have member 'value' if used on a declaration.", value); return; } ClassNode cNode = de.getDeclaringClass(); ClassNode baseScriptType = de.getVariableExpression().getType().getPlainNodeReference(); de.setRightExpression(new VariableExpression("this")); changeBaseScriptType(de, cNode, baseScriptType); }
private void checkForDisableChecksums(AnnotationNode node) { Object val = node.getMember(DISABLE_CHECKSUMS_SETTING); if (val == null || !(val instanceof ConstantExpression)) return; Object disableChecksumsValue = ((ConstantExpression) val).getValue(); if (!(disableChecksumsValue instanceof Boolean)) return; disableChecksums = (Boolean) disableChecksumsValue; }
private static String lookupLogFieldName(AnnotationNode logAnnotation) { Expression member = logAnnotation.getMember("value"); if (member != null && member.getText() != null) { return member.getText(); } else { return "log"; } }