Java Code Examples for org.codehaus.groovy.ast.ClassNode#addField()

The following examples show how to use org.codehaus.groovy.ast.ClassNode#addField() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ToStringASTTransformation.java    From groovy with Apache License 2.0 6 votes vote down vote up
public static void createToString(ClassNode cNode, boolean includeSuper, boolean includeFields, List<String> excludes, List<String> includes, boolean includeNames, boolean ignoreNulls, boolean includePackage, boolean cache, boolean includeSuperProperties, boolean allProperties, boolean allNames, boolean includeSuperFields) {
    // make a public method if none exists otherwise try a private method with leading underscore
    boolean hasExistingToString = hasDeclaredMethod(cNode, "toString", 0);
    if (hasExistingToString && hasDeclaredMethod(cNode, "_toString", 0)) return;

    final BlockStatement body = new BlockStatement();
    Expression tempToString;
    if (cache) {
        final FieldNode cacheField = cNode.addField("$to$string", ACC_PRIVATE | ACC_SYNTHETIC, ClassHelper.STRING_TYPE, null);
        final Expression savedToString = varX(cacheField);
        body.addStatement(ifS(
                equalsNullX(savedToString),
                assignS(savedToString, calculateToStringStatements(cNode, includeSuper, includeFields, includeSuperFields, excludes, includes, includeNames, ignoreNulls, includePackage, includeSuperProperties, allProperties, body, allNames))
        ));
        tempToString = savedToString;
    } else {
        tempToString = calculateToStringStatements(cNode, includeSuper, includeFields, includeSuperFields, excludes, includes, includeNames, ignoreNulls, includePackage, includeSuperProperties, allProperties, body, allNames);
    }
    body.addStatement(returnS(tempToString));

    addGeneratedMethod(cNode, hasExistingToString ? "_toString" : "toString", hasExistingToString ? ACC_PRIVATE : ACC_PUBLIC,
            ClassHelper.STRING_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, body);
}
 
Example 2
Source File: DefaultStrategy.java    From groovy with Apache License 2.0 6 votes vote down vote up
public void buildClass(BuilderASTTransformation transform, ClassNode buildee, AnnotationNode anno) {
        List<String> excludes = new ArrayList<String>();
        List<String> includes = new ArrayList<String>();
        includes.add(Undefined.STRING);
        if (!getIncludeExclude(transform, anno, buildee, excludes, includes)) return;
        if (includes.size() == 1 && Undefined.isUndefined(includes.get(0))) includes = null;
        ClassNode builder = createBuilder(anno, buildee);
        createBuilderFactoryMethod(anno, buildee, builder);
//        List<FieldNode> fields = getFields(transform, anno, buildee);
        boolean allNames = transform.memberHasValue(anno, "allNames", true);
        boolean allProperties = !transform.memberHasValue(anno, "allProperties", false);
        List<PropertyInfo> props = getPropertyInfos(transform, anno, buildee, excludes, includes, allNames, allProperties);
        for (PropertyInfo pi : props) {
            ClassNode correctedType = getCorrectedType(buildee, pi.getType(), builder);
            String fieldName = pi.getName();
            builder.addField(createFieldCopy(buildee, fieldName, correctedType));
            addGeneratedMethod(builder, createBuilderMethodForProp(builder, new PropertyInfo(fieldName, correctedType), getPrefix(anno)));
        }
        addGeneratedMethod(builder, createBuildMethod(anno, buildee, props));
    }
 
Example 3
Source File: AsmClassGenerator.java    From groovy with Apache License 2.0 6 votes vote down vote up
protected void createInterfaceSyntheticStaticFields() {
    ClassNode icl =  controller.getInterfaceClassLoadingClass();

    if (referencedClasses.isEmpty()) {
        Iterator<InnerClassNode> it = icl.getOuterClass().getInnerClasses();
        while(it.hasNext()) {
            InnerClassNode inner = it.next();
            if (inner==icl) {
                it.remove();
                return;
            }
        }
        return;
    }

    addInnerClass(icl);
    for (Map.Entry<String, ClassNode> entry : referencedClasses.entrySet()) {
        // generate a field node
        String staticFieldName = entry.getKey();
        ClassNode cn = entry.getValue();
        icl.addField(staticFieldName, ACC_STATIC + ACC_SYNTHETIC, ClassHelper.CLASS_Type.getPlainNodeReference(), new ClassExpression(cn));
    }
}
 
Example 4
Source File: Verifier.java    From groovy with Apache License 2.0 5 votes vote down vote up
private static void addFastPathHelperFieldsAndHelperMethod(ClassNode node, final String classInternalName, boolean knownSpecialCase) {
    if (node.getNodeMetaData(ClassNodeSkip.class) != null) return;
    FieldNode stMCB = checkFieldDoesNotExist(node, STATIC_METACLASS_BOOL);
    if (stMCB == null) {
        stMCB = node.addField(
                STATIC_METACLASS_BOOL,
                ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC | ACC_TRANSIENT,
                ClassHelper.boolean_TYPE, null);
        stMCB.setSynthetic(true);
    }
}
 
Example 5
Source File: ClassCompletionVerifierTest.java    From groovy with Apache License 2.0 5 votes vote down vote up
public void testDetectsIncorrectMemberVisibilityInInterface() throws Exception {
    ClassNode node = new ClassNode("zzz", ACC_ABSTRACT | ACC_INTERFACE, ClassHelper.OBJECT_TYPE);
    node.addMethod(new MethodNode("prim", ACC_PRIVATE, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null));
    node.addMethod(new MethodNode("prom", ACC_PROTECTED, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null));
    node.addField("prif", ACC_PRIVATE, ClassHelper.OBJECT_TYPE, null);
    node.addField("prof", ACC_PROTECTED, ClassHelper.OBJECT_TYPE, null);
    addDummyConstructor(node);
    verifier.visitClass(node);
    checkErrorCount(4);
    checkErrorMessage(EXPECTED_PROTECTED_FIELD_ERROR_MESSAGE);
    checkErrorMessage(EXPECTED_PRIVATE_FIELD_ERROR_MESSAGE);
    checkErrorMessage(EXPECTED_PROTECTED_METHOD_ERROR_MESSAGE);
    checkErrorMessage(EXPECTED_PRIVATE_METHOD_ERROR_MESSAGE);
}
 
Example 6
Source File: PropertyTest.java    From groovy with Apache License 2.0 5 votes vote down vote up
public void testFields() throws Exception {
    ClassNode classNode = new ClassNode("Foo", ACC_PUBLIC, ClassHelper.OBJECT_TYPE);
    classNode.addField("x", ACC_PUBLIC, ClassHelper.OBJECT_TYPE, null);
    classNode.addField("y", ACC_PUBLIC, ClassHelper.Integer_TYPE, null);
    classNode.addField("z", ACC_PRIVATE, ClassHelper.STRING_TYPE, null);

    Class fooClass = loadClass(classNode);
    assertTrue("Loaded a new class", fooClass != null);

    assertField(fooClass, "x", Modifier.PUBLIC, ClassHelper.OBJECT_TYPE);
    assertField(fooClass, "y", Modifier.PUBLIC, ClassHelper.Integer_TYPE);
    assertField(fooClass, "z", Modifier.PRIVATE, ClassHelper.STRING_TYPE);
}
 
Example 7
Source File: DefaultStrategy.java    From groovy with Apache License 2.0 5 votes vote down vote up
public void buildMethod(BuilderASTTransformation transform, MethodNode mNode, AnnotationNode anno) {
    if (transform.getMemberValue(anno, "includes") != null || transform.getMemberValue(anno, "excludes") != null) {
        transform.addError("Error during " + BuilderASTTransformation.MY_TYPE_NAME +
                " processing: includes/excludes only allowed on classes", anno);
    }
    ClassNode buildee = mNode.getDeclaringClass();
    ClassNode builder = createBuilder(anno, buildee);
    createBuilderFactoryMethod(anno, buildee, builder);
    for (Parameter parameter : mNode.getParameters()) {
        builder.addField(createFieldCopy(buildee, parameter));
        addGeneratedMethod(builder, createBuilderMethodForProp(builder, new PropertyInfo(parameter.getName(), parameter.getType()), getPrefix(anno)));
    }
    addGeneratedMethod(builder, createBuildMethodForMethod(anno, buildee, mNode, mNode.getParameters()));
}
 
Example 8
Source File: InitializerStrategy.java    From groovy with Apache License 2.0 5 votes vote down vote up
private static List<FieldNode> convertParamsToFields(ClassNode builder, Parameter[] parameters) {
    List<FieldNode> fieldNodes = new ArrayList<FieldNode>();
    for (Parameter parameter: parameters) {
        Map<String,ClassNode> genericsSpec = createGenericsSpec(builder);
        ClassNode correctedType = correctToGenericsSpecRecurse(genericsSpec, parameter.getType());
        FieldNode fieldNode = new FieldNode(parameter.getName(), parameter.getModifiers(), correctedType, builder, DEFAULT_INITIAL_VALUE);
        fieldNodes.add(fieldNode);
        builder.addField(fieldNode);
    }
    return fieldNodes;
}
 
Example 9
Source File: ExternalStrategy.java    From groovy with Apache License 2.0 5 votes vote down vote up
public void build(BuilderASTTransformation transform, AnnotatedNode annotatedNode, AnnotationNode anno) {
    if (!(annotatedNode instanceof ClassNode)) {
        transform.addError("Error during " + BuilderASTTransformation.MY_TYPE_NAME + " processing: building for " +
                annotatedNode.getClass().getSimpleName() + " not supported by " + getClass().getSimpleName(), annotatedNode);
        return;
    }
    ClassNode builder = (ClassNode) annotatedNode;
    String prefix = transform.getMemberStringValue(anno, "prefix", "");
    ClassNode buildee = transform.getMemberClassValue(anno, "forClass");
    if (buildee == null) {
        transform.addError("Error during " + MY_TYPE_NAME + " processing: 'forClass' must be specified for " + getClass().getName(), anno);
        return;
    }
    List<String> excludes = new ArrayList<String>();
    List<String> includes = new ArrayList<String>();
    includes.add(Undefined.STRING);
    if (!getIncludeExclude(transform, anno, buildee, excludes, includes)) return;
    if (includes.size() == 1 && Undefined.isUndefined(includes.get(0))) includes = null;
    if (unsupportedAttribute(transform, anno, "builderClassName")) return;
    if (unsupportedAttribute(transform, anno, "builderMethodName")) return;
    if (unsupportedAttribute(transform, anno, "force")) return;
    boolean allNames = transform.memberHasValue(anno, "allNames", true);
    boolean allProperties = !transform.memberHasValue(anno, "allProperties", false);
    List<PropertyInfo> props = getPropertyInfos(transform, anno, buildee, excludes, includes, allNames, allProperties);
    if (includes != null) {
        for (String name : includes) {
            checkKnownProperty(transform, anno, name, props);
        }
    }
    for (PropertyInfo prop : props) {
        builder.addField(createFieldCopy(builder, prop));
        addGeneratedMethod(builder, createBuilderMethodForField(builder, prop, prefix));
    }
    addGeneratedMethod(builder, createBuildMethod(transform, anno, buildee, props));
}
 
Example 10
Source File: Verifier.java    From groovy with Apache License 2.0 5 votes vote down vote up
private static FieldNode setMetaClassFieldIfNotExists(ClassNode node, FieldNode metaClassField) {
    if (metaClassField != null) return metaClassField;
    final String classInternalName = BytecodeHelper.getClassInternalName(node);
    metaClassField =
            node.addField("metaClass", ACC_PRIVATE | ACC_TRANSIENT | ACC_SYNTHETIC, ClassHelper.METACLASS_TYPE,
                    bytecodeX(ClassHelper.METACLASS_TYPE, mv -> {
                        mv.visitVarInsn(ALOAD, 0);
                        mv.visitMethodInsn(INVOKEVIRTUAL, classInternalName, "$getStaticMetaClass", "()Lgroovy/lang/MetaClass;", false);
                    })
            );
    metaClassField.setSynthetic(true);
    return metaClassField;
}
 
Example 11
Source File: EnumHelper.java    From groovy with Apache License 2.0 5 votes vote down vote up
public static FieldNode addEnumConstant(ClassNode enumClass, String name, Expression init) {
    int modifiers = PUBLIC_FS | Opcodes.ACC_ENUM;
    if (init != null && !(init instanceof ListExpression)) {
        ListExpression list = new ListExpression();
        list.addExpression(init);
        init = list;
    }
    FieldNode fn = new FieldNode(name, modifiers, enumClass.getPlainNodeReference(), enumClass, init);
    enumClass.addField(fn);
    return fn;
}
 
Example 12
Source File: EqualsAndHashCodeASTTransformation.java    From groovy with Apache License 2.0 5 votes vote down vote up
public static void createHashCode(ClassNode cNode, boolean cacheResult, boolean includeFields, boolean callSuper, List<String> excludes, List<String> includes, boolean allNames, boolean allProperties) {
    // make a public method if none exists otherwise try a private method with leading underscore
    boolean hasExistingHashCode = hasDeclaredMethod(cNode, "hashCode", 0);
    if (hasExistingHashCode && hasDeclaredMethod(cNode, "_hashCode", 0)) return;

    final BlockStatement body = new BlockStatement();
    // TODO use pList and fList
    if (cacheResult) {
        final FieldNode hashField = cNode.addField("$hash$code", ACC_PRIVATE | ACC_SYNTHETIC, ClassHelper.int_TYPE, null);
        final Expression hash = varX(hashField);
        body.addStatement(ifS(
                isZeroX(hash),
                calculateHashStatements(cNode, hash, includeFields, callSuper, excludes, includes, allNames, allProperties)
        ));
        body.addStatement(returnS(hash));
    } else {
        body.addStatement(calculateHashStatements(cNode, null, includeFields, callSuper, excludes, includes, allNames, allProperties));
    }

    addGeneratedMethod(cNode,
            hasExistingHashCode ? "_hashCode" : "hashCode",
            hasExistingHashCode ? ACC_PRIVATE : ACC_PUBLIC,
            ClassHelper.int_TYPE,
            Parameter.EMPTY_ARRAY,
            ClassNode.EMPTY_ARRAY,
            body);
}
 
Example 13
Source File: ImmutableASTTransformation.java    From groovy with Apache License 2.0 5 votes vote down vote up
private static 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);
}
 
Example 14
Source File: SortableASTTransformation.java    From groovy with Apache License 2.0 5 votes vote down vote up
private static void createComparatorFor(ClassNode classNode, PropertyNode property, boolean reversed) {
    String propName = StringGroovyMethods.capitalize((CharSequence) property.getName());
    String className = classNode.getName() + "$" + propName + "Comparator";
    ClassNode superClass = makeClassSafeWithGenerics(AbstractComparator.class, classNode);
    InnerClassNode cmpClass = new InnerClassNode(classNode, className, ACC_PRIVATE | ACC_STATIC, superClass);
    addGeneratedInnerClass(classNode, cmpClass);

    addGeneratedMethod(cmpClass,
            "compare",
            ACC_PUBLIC,
            ClassHelper.int_TYPE,
            params(param(newClass(classNode), ARG0), param(newClass(classNode), ARG1)),
            ClassNode.EMPTY_ARRAY,
            createCompareMethodBody(property, reversed)
    );

    String fieldName = "this$" + propName + "Comparator";
    // private final Comparator this$<property>Comparator = new <type>$<property>Comparator();
    FieldNode cmpField = classNode.addField(
            fieldName,
            ACC_STATIC | ACC_FINAL | ACC_PRIVATE | ACC_SYNTHETIC,
            COMPARATOR_TYPE,
            ctorX(cmpClass));

    addGeneratedMethod(classNode,
            "comparatorBy" + propName,
            ACC_PUBLIC | ACC_STATIC,
            COMPARATOR_TYPE,
            Parameter.EMPTY_ARRAY,
            ClassNode.EMPTY_ARRAY,
            returnS(fieldX(cmpField))
    );
}
 
Example 15
Source File: SingletonASTTransformation.java    From groovy with Apache License 2.0 5 votes vote down vote up
private void createField(ClassNode classNode, String propertyName, boolean isLazy, boolean isStrict) {
    int modifiers = isLazy ? ACC_PRIVATE | ACC_STATIC | ACC_VOLATILE : ACC_PUBLIC | ACC_FINAL | ACC_STATIC;
    Expression initialValue = isLazy ? null : ctorX(classNode);
    final FieldNode fieldNode = classNode.addField(propertyName, modifiers, newClass(classNode), initialValue);
    createConstructor(classNode, fieldNode, propertyName, isStrict);
    final BlockStatement body = new BlockStatement();
    body.addStatement(isLazy ? lazyBody(classNode, fieldNode) : nonLazyBody(fieldNode));
    addGeneratedMethod(classNode, getGetterName(propertyName), ACC_STATIC | ACC_PUBLIC, newClass(classNode), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, body);
}
 
Example 16
Source File: DriverCompilationCustomizer.java    From arcusplatform with Apache License 2.0 4 votes vote down vote up
@Override
public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException {
   LOGGER.trace("Customize [phase: {} {}, classNode: {}]", source.getPhase(), source.getPhaseDescription(), classNode);
   if(classNode.getField("_HASH") == null) {
      String hash = hash(source);
      if(hash != null) {
         classNode.addField(
               "_HASH", 
               Modifier.PUBLIC | Modifier.FINAL, 
               new ClassNode(String.class), 
               new ConstantExpression(hash)
         );
      }
   }
   
   ClassNode groovyCapabilityDefinition = new ClassNode(GroovyCapabilityDefinition.class);
   for(CapabilityDefinition definition: capabilityRegistry.listCapabilityDefinitions()) {
      if(classNode.getProperty(definition.getCapabilityName()) != null) {
         continue;
      }
      
      if(!isDeviceCapability(definition)) {
         continue;
      }
      
      String fieldName = definition.getNamespace();
      FieldNode field = classNode.addField(
            fieldName,
            Modifier.PRIVATE | Modifier.FINAL, 
            groovyCapabilityDefinition,
            new StaticMethodCallExpression(
                  new ClassNode(GroovyCapabilityDefinitionFactory.class),
                  "create",
                  new TupleExpression(
                        new ConstantExpression(definition.getCapabilityName()),
                        VariableExpression.THIS_EXPRESSION
                  )
            )
      );
      
      
      classNode.addProperty(
            definition.getCapabilityName(),
            Modifier.PUBLIC | Modifier.FINAL,
            groovyCapabilityDefinition,
            new FieldExpression(field),
            new ReturnStatement(new FieldExpression(field)),
            null
       );
   }
}
 
Example 17
Source File: Verifier.java    From groovy with Apache License 2.0 4 votes vote down vote up
private void addStaticMetaClassField(final ClassNode node, final String classInternalName) {
    String _staticClassInfoFieldName = "$staticClassInfo";
    while (node.getDeclaredField(_staticClassInfoFieldName) != null)
        _staticClassInfoFieldName = _staticClassInfoFieldName + "$";
    final String staticMetaClassFieldName = _staticClassInfoFieldName;

    FieldNode staticMetaClassField = node.addField(staticMetaClassFieldName, ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, ClassHelper.make(ClassInfo.class, false), null);
    staticMetaClassField.setSynthetic(true);

    node.addSyntheticMethod(
            "$getStaticMetaClass",
            ACC_PROTECTED,
            ClassHelper.make(MetaClass.class),
            Parameter.EMPTY_ARRAY,
            ClassNode.EMPTY_ARRAY,
            new BytecodeSequence(new BytecodeInstruction() {
                @Override
                public void visit(MethodVisitor mv) {
                    mv.visitVarInsn(ALOAD, 0);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
                    if (BytecodeHelper.isClassLiteralPossible(node) || BytecodeHelper.isSameCompilationUnit(classNode, node)) {
                        BytecodeHelper.visitClassLiteral(mv, node);
                    } else {
                        mv.visitMethodInsn(INVOKESTATIC, classInternalName, "$get$$class$" + classInternalName.replace('/', '$'), "()Ljava/lang/Class;", false);
                    }
                    Label l1 = new Label();
                    mv.visitJumpInsn(IF_ACMPEQ, l1);

                    mv.visitVarInsn(ALOAD, 0);
                    mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/ScriptBytecodeAdapter", "initMetaClass", "(Ljava/lang/Object;)Lgroovy/lang/MetaClass;", false);
                    mv.visitInsn(ARETURN);

                    mv.visitLabel(l1);

                    mv.visitFieldInsn(GETSTATIC, classInternalName, staticMetaClassFieldName, "Lorg/codehaus/groovy/reflection/ClassInfo;");
                    mv.visitVarInsn(ASTORE, 1);
                    mv.visitVarInsn(ALOAD, 1);
                    Label l0 = new Label();
                    mv.visitJumpInsn(IFNONNULL, l0);

                    mv.visitVarInsn(ALOAD, 0);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
                    mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/reflection/ClassInfo", "getClassInfo", "(Ljava/lang/Class;)Lorg/codehaus/groovy/reflection/ClassInfo;", false);
                    mv.visitInsn(DUP);
                    mv.visitVarInsn(ASTORE, 1);
                    mv.visitFieldInsn(PUTSTATIC, classInternalName, staticMetaClassFieldName, "Lorg/codehaus/groovy/reflection/ClassInfo;");

                    mv.visitLabel(l0);

                    mv.visitVarInsn(ALOAD, 1);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "org/codehaus/groovy/reflection/ClassInfo", "getMetaClass", "()Lgroovy/lang/MetaClass;", false);
                    mv.visitInsn(ARETURN);
                }
            })
    );
}
 
Example 18
Source File: InitializerStrategy.java    From groovy with Apache License 2.0 4 votes vote down vote up
private static void addFields(ClassNode buildee, List<FieldNode> filteredFields, ClassNode builder) {
    for (FieldNode filteredField : filteredFields) {
        builder.addField(createFieldCopy(buildee, filteredField));
    }
}
 
Example 19
Source File: MemoizedASTTransformation.java    From groovy with Apache License 2.0 4 votes vote down vote up
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);
        addGeneratedMethod(ownerClassNode, 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, ownerClassNode instanceof InnerClassNode);
        if (ownerClassNode instanceof InnerClassNode) {
            visitor.visitClass(((InnerClassNode) ownerClassNode).getOuterMostClass());
        } else {
            visitor.visitClass(ownerClassNode);
        }
    }
}
 
Example 20
Source File: FieldASTTransformation.java    From groovy with Apache License 2.0 4 votes vote down vote up
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);
        // provide setter for CLI Builder purposes unless final
        if (fieldNode.isFinal()) {
            if (!de.getAnnotations(OPTION_TYPE).isEmpty()) {
                addError("Can't have a final field also annotated with @" + OPTION_TYPE.getNameWithoutPackage(), de);
            }
        } else {
            String setterName = getSetterName(variableName);
            cNode.addMethod(setterName, ACC_PUBLIC | ACC_SYNTHETIC, ClassHelper.VOID_TYPE, params(param(ve.getType(), variableName)), ClassNode.EMPTY_ARRAY, block(
                    stmt(assignX(propX(varX("this"), variableName), varX(variableName)))
            ));
        }

        // 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(this, 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);
    }
}