Search in sources :

Example 86 with ClassNode

use of org.codehaus.groovy.ast.ClassNode in project groovy-core by groovy.

the class BindableASTTransformation method visit.

/**
     * Handles the bulk of the processing, mostly delegating to other methods.
     *
     * @param nodes   the ast nodes
     * @param source  the source unit for the nodes
     */
public void visit(ASTNode[] nodes, SourceUnit source) {
    if (!(nodes[0] instanceof AnnotationNode) || !(nodes[1] instanceof AnnotatedNode)) {
        throw new RuntimeException("Internal error: wrong types: $node.class / $parent.class");
    }
    AnnotationNode node = (AnnotationNode) nodes[0];
    AnnotatedNode parent = (AnnotatedNode) nodes[1];
    if (VetoableASTTransformation.hasVetoableAnnotation(parent)) {
        // VetoableASTTransformation will handle both @Bindable and @Vetoable
        return;
    }
    ClassNode declaringClass = parent.getDeclaringClass();
    if (parent instanceof FieldNode) {
        if ((((FieldNode) parent).getModifiers() & Opcodes.ACC_FINAL) != 0) {
            source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage(new SyntaxException("@groovy.beans.Bindable cannot annotate a final property.", node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()), source));
        }
        if (VetoableASTTransformation.hasVetoableAnnotation(parent.getDeclaringClass())) {
            // VetoableASTTransformation will handle both @Bindable and @Vetoable
            return;
        }
        addListenerToProperty(source, node, declaringClass, (FieldNode) parent);
    } else if (parent instanceof ClassNode) {
        addListenerToClass(source, (ClassNode) parent);
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) SyntaxErrorMessage(org.codehaus.groovy.control.messages.SyntaxErrorMessage) SyntaxException(org.codehaus.groovy.syntax.SyntaxException) AnnotatedNode(org.codehaus.groovy.ast.AnnotatedNode)

Example 87 with ClassNode

use of org.codehaus.groovy.ast.ClassNode in project groovy-core by groovy.

the class VetoableASTTransformation method needsVetoableChangeSupport.

/**
     * Snoops through the declaring class and all parents looking for a field
     * of type VetoableChangeSupport.  Remembers the field and returns false
     * if found otherwise returns true to indicate that such support should
     * be added.
     *
     * @param declaringClass the class to search
     * @return true if vetoable change support should be added
     */
protected boolean needsVetoableChangeSupport(ClassNode declaringClass, SourceUnit sourceUnit) {
    boolean foundAdd = false, foundRemove = false, foundFire = false;
    ClassNode consideredClass = declaringClass;
    while (consideredClass != null) {
        for (MethodNode method : consideredClass.getMethods()) {
            // just check length, MOP will match it up
            foundAdd = foundAdd || method.getName().equals("addVetoableChangeListener") && method.getParameters().length == 1;
            foundRemove = foundRemove || method.getName().equals("removeVetoableChangeListener") && method.getParameters().length == 1;
            foundFire = foundFire || method.getName().equals("fireVetoableChange") && method.getParameters().length == 3;
            if (foundAdd && foundRemove && foundFire) {
                return false;
            }
        }
        consideredClass = consideredClass.getSuperClass();
    }
    // check if a super class has @Vetoable annotations
    consideredClass = declaringClass.getSuperClass();
    while (consideredClass != null) {
        if (hasVetoableAnnotation(consideredClass))
            return false;
        for (FieldNode field : consideredClass.getFields()) {
            if (hasVetoableAnnotation(field))
                return false;
        }
        consideredClass = consideredClass.getSuperClass();
    }
    if (foundAdd || foundRemove || foundFire) {
        sourceUnit.getErrorCollector().addErrorAndContinue(new SimpleMessage("@Vetoable cannot be processed on " + declaringClass.getName() + " because some but not all of addVetoableChangeListener, removeVetoableChange, and fireVetoableChange were declared in the current or super classes.", sourceUnit));
        return false;
    }
    return true;
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) MethodNode(org.codehaus.groovy.ast.MethodNode) FieldNode(org.codehaus.groovy.ast.FieldNode) SimpleMessage(org.codehaus.groovy.control.messages.SimpleMessage)

Example 88 with ClassNode

use of org.codehaus.groovy.ast.ClassNode in project groovy-core by groovy.

the class VetoableASTTransformation method addListenerToProperty.

private void addListenerToProperty(SourceUnit source, AnnotationNode node, AnnotatedNode parent) {
    ClassNode declaringClass = parent.getDeclaringClass();
    FieldNode field = ((FieldNode) parent);
    String fieldName = field.getName();
    for (PropertyNode propertyNode : declaringClass.getProperties()) {
        boolean bindable = BindableASTTransformation.hasBindableAnnotation(parent) || BindableASTTransformation.hasBindableAnnotation(parent.getDeclaringClass());
        if (propertyNode.getName().equals(fieldName)) {
            if (field.isStatic()) {
                //noinspection ThrowableInstanceNeverThrown
                source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage(new SyntaxException("@groovy.beans.Vetoable cannot annotate a static property.", node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()), source));
            } else {
                createListenerSetter(source, bindable, declaringClass, propertyNode);
            }
            return;
        }
    }
    //noinspection ThrowableInstanceNeverThrown
    source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage(new SyntaxException("@groovy.beans.Vetoable must be on a property, not a field.  Try removing the private, protected, or public modifier.", node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()), source));
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) SyntaxErrorMessage(org.codehaus.groovy.control.messages.SyntaxErrorMessage) PropertyNode(org.codehaus.groovy.ast.PropertyNode) SyntaxException(org.codehaus.groovy.syntax.SyntaxException)

Example 89 with ClassNode

use of org.codehaus.groovy.ast.ClassNode in project grails-core by grails.

the class TestMixinTransformation method weaveMixinIntoClass.

protected void weaveMixinIntoClass(final ClassNode classNode, final ClassNode mixinClassNode, final Junit3TestFixtureMethodHandler junit3MethodHandler, ClassNode applicationClassNode) {
    if (mixinClassNode.getName().equals(IntegrationTestMixin.class.getName())) {
        new IntegrationTestMixinTransformation().weaveIntegrationTestMixin(classNode, applicationClassNode);
        return;
    }
    final String fieldName = '$' + GrailsNameUtils.getPropertyName(mixinClassNode.getName());
    boolean implementsTestRuntimeAwareMixin = GrailsASTUtils.findInterface(mixinClassNode, ClassHelper.make(TestRuntimeAwareMixin.class)) != null;
    FieldNode mixinFieldNode;
    if (!implementsTestRuntimeAwareMixin) {
        mixinFieldNode = addLegacyMixinFieldIfNonExistent(classNode, mixinClassNode, fieldName);
    } else {
        mixinFieldNode = addTestRuntimeAwareMixinFieldIfNonExistent(classNode, mixinClassNode, fieldName);
    }
    // already woven
    if (mixinFieldNode == null)
        return;
    FieldExpression fieldReference = new FieldExpression(mixinFieldNode);
    ClassNode currentMixinClassNode = mixinClassNode;
    while (!currentMixinClassNode.getName().equals(GrailsASTUtils.OBJECT_CLASS)) {
        final List<MethodNode> mixinMethods = currentMixinClassNode.getMethods();
        for (MethodNode mixinMethod : mixinMethods) {
            if (!isCandidateMethod(mixinMethod) || hasDeclaredMethod(classNode, mixinMethod)) {
                continue;
            }
            MethodNode methodNode;
            if (mixinMethod.isStatic()) {
                methodNode = GrailsASTUtils.addDelegateStaticMethod(classNode, mixinMethod);
            } else {
                methodNode = GrailsASTUtils.addDelegateInstanceMethod(classNode, fieldReference, mixinMethod, false);
            }
            if (methodNode != null) {
                methodNode.addAnnotation(MIXIN_METHOD_ANNOTATION);
                GrailsASTUtils.addCompileStaticAnnotation(methodNode);
            }
            if (junit3MethodHandler != null) {
                junit3MethodHandler.handle(mixinMethod, methodNode);
            }
        }
        currentMixinClassNode = currentMixinClassNode.getSuperClass();
        if (junit3MethodHandler != null) {
            junit3MethodHandler.mixinSuperClassChanged();
        }
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) MethodNode(org.codehaus.groovy.ast.MethodNode) IntegrationTestMixin(grails.test.mixin.integration.IntegrationTestMixin) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression)

Example 90 with ClassNode

use of org.codehaus.groovy.ast.ClassNode in project grails-core by grails.

the class DefaultASTValidateableHelper method getPropertiesToEnsureConstraintsFor.

/**
     * Retrieves a Map describing all of the properties which need to be constrained for the class
     * represented by classNode.  The keys in the Map will be property names and the values are the
     * type of the corresponding property.
     * 
     * @param classNode the class to inspect
     * @return a Map describing all of the properties which need to be constrained
     */
protected Map<String, ClassNode> getPropertiesToEnsureConstraintsFor(final ClassNode classNode) {
    final Map<String, ClassNode> fieldsToConstrain = new HashMap<String, ClassNode>();
    final List<FieldNode> allFields = classNode.getFields();
    for (final FieldNode field : allFields) {
        if (!field.isStatic()) {
            final PropertyNode property = classNode.getProperty(field.getName());
            if (property != null) {
                fieldsToConstrain.put(field.getName(), field.getType());
            }
        }
    }
    final Map<String, MethodNode> declaredMethodsMap = classNode.getDeclaredMethodsMap();
    for (Entry<String, MethodNode> methodEntry : declaredMethodsMap.entrySet()) {
        final MethodNode value = methodEntry.getValue();
        if (!value.isStatic() && value.isPublic() && classNode.equals(value.getDeclaringClass()) && value.getLineNumber() > 0) {
            Parameter[] parameters = value.getParameters();
            if (parameters == null || parameters.length == 0) {
                final String methodName = value.getName();
                if (methodName.startsWith("get")) {
                    final ClassNode returnType = value.getReturnType();
                    final String restOfMethodName = methodName.substring(3);
                    final String propertyName = GrailsNameUtils.getPropertyName(restOfMethodName);
                    fieldsToConstrain.put(propertyName, returnType);
                }
            }
        }
    }
    final ClassNode superClass = classNode.getSuperClass();
    if (!superClass.equals(new ClassNode(Object.class))) {
        fieldsToConstrain.putAll(getPropertiesToEnsureConstraintsFor(superClass));
    }
    return fieldsToConstrain;
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) MethodNode(org.codehaus.groovy.ast.MethodNode) HashMap(java.util.HashMap) PropertyNode(org.codehaus.groovy.ast.PropertyNode) Parameter(org.codehaus.groovy.ast.Parameter)

Aggregations

ClassNode (org.codehaus.groovy.ast.ClassNode)869 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)348 MethodNode (org.codehaus.groovy.ast.MethodNode)193 GenericsType (org.codehaus.groovy.ast.GenericsType)154 LowestUpperBoundClassNode (org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode)148 Expression (org.codehaus.groovy.ast.expr.Expression)146 Parameter (org.codehaus.groovy.ast.Parameter)135 FieldNode (org.codehaus.groovy.ast.FieldNode)126 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)118 AnnotationNode (org.codehaus.groovy.ast.AnnotationNode)117 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)113 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)103 ArrayList (java.util.ArrayList)95 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)92 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)75 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)74 LinkedList (java.util.LinkedList)71 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)71 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)62 ListExpression (org.codehaus.groovy.ast.expr.ListExpression)61