Search in sources :

Example 41 with FieldNode

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

the class ExternalizeVerifierASTTransformation method visit.

public void visit(ASTNode[] nodes, SourceUnit source) {
    init(nodes, source);
    AnnotatedNode parent = (AnnotatedNode) nodes[1];
    AnnotationNode anno = (AnnotationNode) nodes[0];
    if (!MY_TYPE.equals(anno.getClassNode()))
        return;
    if (parent instanceof ClassNode) {
        ClassNode cNode = (ClassNode) parent;
        if (!hasNoargConstructor(cNode)) {
            addError(MY_TYPE_NAME + ": An Externalizable class requires a no-arg constructor but none found", cNode);
        }
        if (!implementsExternalizable(cNode)) {
            addError(MY_TYPE_NAME + ": An Externalizable class must implement the Externalizable interface", cNode);
        }
        boolean includeFields = memberHasValue(anno, "includeFields", true);
        boolean checkPropertyTypes = memberHasValue(anno, "checkPropertyTypes", true);
        List<String> excludes = getMemberList(anno, "excludes");
        List<FieldNode> list = getInstancePropertyFields(cNode);
        if (includeFields) {
            list.addAll(getInstanceNonPropertyFields(cNode));
        }
        checkProps(list, excludes, checkPropertyTypes);
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) AnnotatedNode(org.codehaus.groovy.ast.AnnotatedNode)

Example 42 with FieldNode

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

the class FieldASTTransformation method visit.

public void visit(ASTNode[] nodes, SourceUnit source) {
    sourceUnit = source;
    if (nodes.length != 2 || !(nodes[0] instanceof AnnotationNode) || !(nodes[1] instanceof AnnotatedNode)) {
        throw new GroovyBugError("Internal error: expecting [AnnotationNode, AnnotatedNode] but got: " + Arrays.asList(nodes));
    }
    AnnotatedNode parent = (AnnotatedNode) nodes[1];
    AnnotationNode node = (AnnotationNode) nodes[0];
    if (!MY_TYPE.equals(node.getClassNode()))
        return;
    if (parent instanceof DeclarationExpression) {
        DeclarationExpression de = (DeclarationExpression) parent;
        ClassNode cNode = de.getDeclaringClass();
        if (!cNode.isScript()) {
            addError("Annotation " + MY_TYPE_NAME + " can only be used within a Script.", parent);
            return;
        }
        candidate = de;
        // GROOVY-4548: temp fix to stop CCE until proper support is added
        if (de.isMultipleAssignmentDeclaration()) {
            addError("Annotation " + MY_TYPE_NAME + " not supported with multiple assignment notation.", parent);
            return;
        }
        VariableExpression ve = de.getVariableExpression();
        variableName = ve.getName();
        // set owner null here, it will be updated by addField
        fieldNode = new FieldNode(variableName, ve.getModifiers(), ve.getType(), null, de.getRightExpression());
        fieldNode.setSourcePosition(de);
        cNode.addField(fieldNode);
        // GROOVY-4833 : annotations that are not Groovy transforms should be transferred to the generated field
        // GROOVY-6112 : also copy acceptable Groovy transforms
        final List<AnnotationNode> annotations = de.getAnnotations();
        for (AnnotationNode annotation : annotations) {
            // GROOVY-6337 HACK: in case newly created field is @Lazy
            if (annotation.getClassNode().equals(LAZY_TYPE)) {
                LazyASTTransformation.visitField(annotation, fieldNode);
            }
            final ClassNode annotationClassNode = annotation.getClassNode();
            if (notTransform(annotationClassNode) || acceptableTransform(annotation)) {
                fieldNode.addAnnotation(annotation);
            }
        }
        super.visitClass(cNode);
        // GROOVY-5207 So that Closures can see newly added fields
        // (not super efficient for a very large class with many @Fields but we chose simplicity
        // and understandability of this solution over more complex but efficient alternatives)
        VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(source);
        scopeVisitor.visitClass(cNode);
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) AnnotatedNode(org.codehaus.groovy.ast.AnnotatedNode) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) GroovyBugError(org.codehaus.groovy.GroovyBugError) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) VariableScopeVisitor(org.codehaus.groovy.classgen.VariableScopeVisitor)

Example 43 with FieldNode

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

the class ImmutableASTTransformation method addProperty.

private void addProperty(ClassNode cNode, PropertyNode pNode) {
    final FieldNode fn = pNode.getField();
    cNode.getFields().remove(fn);
    cNode.addProperty(pNode.getName(), pNode.getModifiers() | ACC_FINAL, pNode.getType(), pNode.getInitialExpression(), pNode.getGetterBlock(), pNode.getSetterBlock());
    final FieldNode newfn = cNode.getField(fn.getName());
    cNode.getFields().remove(newfn);
    cNode.addField(fn);
}
Also used : FieldNode(org.codehaus.groovy.ast.FieldNode)

Example 44 with FieldNode

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

the class MemoizedASTTransformation method visit.

public void visit(ASTNode[] nodes, final SourceUnit source) {
    init(nodes, source);
    AnnotationNode annotationNode = (AnnotationNode) nodes[0];
    AnnotatedNode annotatedNode = (AnnotatedNode) nodes[1];
    if (MY_TYPE.equals(annotationNode.getClassNode()) && annotatedNode instanceof MethodNode) {
        MethodNode methodNode = (MethodNode) annotatedNode;
        if (methodNode.isAbstract()) {
            addError("Annotation " + MY_TYPE_NAME + " cannot be used for abstract methods.", methodNode);
            return;
        }
        if (methodNode.isVoidMethod()) {
            addError("Annotation " + MY_TYPE_NAME + " cannot be used for void methods.", methodNode);
            return;
        }
        ClassNode ownerClassNode = methodNode.getDeclaringClass();
        MethodNode delegatingMethod = buildDelegatingMethod(methodNode, ownerClassNode);
        ownerClassNode.addMethod(delegatingMethod);
        int modifiers = FieldNode.ACC_PRIVATE | FieldNode.ACC_FINAL;
        if (methodNode.isStatic()) {
            modifiers = modifiers | FieldNode.ACC_STATIC;
        }
        int protectedCacheSize = getMemberIntValue(annotationNode, PROTECTED_CACHE_SIZE_NAME);
        int maxCacheSize = getMemberIntValue(annotationNode, MAX_CACHE_SIZE_NAME);
        MethodCallExpression memoizeClosureCallExpression = buildMemoizeClosureCallExpression(delegatingMethod, protectedCacheSize, maxCacheSize);
        String memoizedClosureFieldName = buildUniqueName(ownerClassNode, CLOSURE_LABEL, methodNode);
        FieldNode memoizedClosureField = new FieldNode(memoizedClosureFieldName, modifiers, newClass(ClassHelper.CLOSURE_TYPE), null, memoizeClosureCallExpression);
        ownerClassNode.addField(memoizedClosureField);
        BlockStatement newCode = new BlockStatement();
        MethodCallExpression closureCallExpression = callX(fieldX(memoizedClosureField), CLOSURE_CALL_METHOD_NAME, args(methodNode.getParameters()));
        closureCallExpression.setImplicitThis(false);
        newCode.addStatement(returnS(closureCallExpression));
        methodNode.setCode(newCode);
        VariableScopeVisitor visitor = new VariableScopeVisitor(source);
        visitor.visitClass(ownerClassNode);
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) MethodNode(org.codehaus.groovy.ast.MethodNode) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) FieldNode(org.codehaus.groovy.ast.FieldNode) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) AnnotatedNode(org.codehaus.groovy.ast.AnnotatedNode) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) VariableScopeVisitor(org.codehaus.groovy.classgen.VariableScopeVisitor)

Example 45 with FieldNode

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

the class DelegateASTTransformation method visit.

public void visit(ASTNode[] nodes, SourceUnit source) {
    init(nodes, source);
    AnnotatedNode parent = (AnnotatedNode) nodes[1];
    AnnotationNode node = (AnnotationNode) nodes[0];
    if (parent instanceof FieldNode) {
        FieldNode fieldNode = (FieldNode) parent;
        final ClassNode type = fieldNode.getType();
        final ClassNode owner = fieldNode.getOwner();
        if (type.equals(ClassHelper.OBJECT_TYPE) || type.equals(GROOVYOBJECT_TYPE)) {
            addError(MY_TYPE_NAME + " field '" + fieldNode.getName() + "' has an inappropriate type: " + type.getName() + ". Please add an explicit type but not java.lang.Object or groovy.lang.GroovyObject.", parent);
            return;
        }
        if (type.equals(owner)) {
            addError(MY_TYPE_NAME + " field '" + fieldNode.getName() + "' has an inappropriate type: " + type.getName() + ". Delegation to own type not supported. Please use a different type.", parent);
            return;
        }
        final List<MethodNode> fieldMethods = getAllMethods(type);
        for (ClassNode next : type.getAllInterfaces()) {
            fieldMethods.addAll(getAllMethods(next));
        }
        final boolean skipInterfaces = memberHasValue(node, MEMBER_INTERFACES, false);
        final boolean includeDeprecated = memberHasValue(node, MEMBER_DEPRECATED, true) || (type.isInterface() && !skipInterfaces);
        List<String> excludes = getMemberList(node, MEMBER_EXCLUDES);
        List<String> includes = getMemberList(node, MEMBER_INCLUDES);
        List<ClassNode> excludeTypes = getClassList(node, MEMBER_EXCLUDE_TYPES);
        List<ClassNode> includeTypes = getClassList(node, MEMBER_INCLUDE_TYPES);
        checkIncludeExclude(node, excludes, includes, excludeTypes, includeTypes, MY_TYPE_NAME);
        final List<MethodNode> ownerMethods = getAllMethods(owner);
        for (MethodNode mn : fieldMethods) {
            addDelegateMethod(node, fieldNode, owner, ownerMethods, mn, includeDeprecated, includes, excludes, includeTypes, excludeTypes);
        }
        for (PropertyNode prop : getAllProperties(type)) {
            if (prop.isStatic() || !prop.isPublic())
                continue;
            String name = prop.getName();
            addGetterIfNeeded(fieldNode, owner, prop, name, includes, excludes);
            addSetterIfNeeded(fieldNode, owner, prop, name, includes, excludes);
        }
        if (skipInterfaces)
            return;
        final Set<ClassNode> allInterfaces = getInterfacesAndSuperInterfaces(type);
        final Set<ClassNode> ownerIfaces = owner.getAllInterfaces();
        Map<String, ClassNode> genericsSpec = createGenericsSpec(fieldNode.getDeclaringClass());
        genericsSpec = createGenericsSpec(fieldNode.getType(), genericsSpec);
        for (ClassNode iface : allInterfaces) {
            if (Modifier.isPublic(iface.getModifiers()) && !ownerIfaces.contains(iface)) {
                final ClassNode[] ifaces = owner.getInterfaces();
                final ClassNode[] newIfaces = new ClassNode[ifaces.length + 1];
                for (int i = 0; i < ifaces.length; i++) {
                    newIfaces[i] = correctToGenericsSpecRecurse(genericsSpec, ifaces[i]);
                }
                newIfaces[ifaces.length] = correctToGenericsSpecRecurse(genericsSpec, iface);
                owner.setInterfaces(newIfaces);
            }
        }
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) AnnotatedNode(org.codehaus.groovy.ast.AnnotatedNode) MethodNode(org.codehaus.groovy.ast.MethodNode) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) PropertyNode(org.codehaus.groovy.ast.PropertyNode)

Aggregations

FieldNode (org.codehaus.groovy.ast.FieldNode)204 ClassNode (org.codehaus.groovy.ast.ClassNode)126 Expression (org.codehaus.groovy.ast.expr.Expression)58 MethodNode (org.codehaus.groovy.ast.MethodNode)57 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)54 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)50 Parameter (org.codehaus.groovy.ast.Parameter)49 AnnotationNode (org.codehaus.groovy.ast.AnnotationNode)43 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)43 ArrayList (java.util.ArrayList)40 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)38 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)36 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)33 AnnotatedNode (org.codehaus.groovy.ast.AnnotatedNode)31 PropertyNode (org.codehaus.groovy.ast.PropertyNode)30 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)27 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)22 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)19 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)15 CastExpression (org.codehaus.groovy.ast.expr.CastExpression)15