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

The following examples show how to use org.codehaus.groovy.ast.ClassNode#getDeclaredMethod() . 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: TraitComposer.java    From groovy with Apache License 2.0 6 votes vote down vote up
/**
 * Creates, if necessary, a super forwarder method, for stackable traits.
 * @param forwarder a forwarder method
 * @param genericsSpec
 */
private static void createSuperForwarder(ClassNode targetNode, MethodNode forwarder, final Map<String,ClassNode> genericsSpec) {
    List<ClassNode> interfaces = new ArrayList<ClassNode>(Traits.collectAllInterfacesReverseOrder(targetNode, new LinkedHashSet<ClassNode>()));
    String name = forwarder.getName();
    Parameter[] forwarderParameters = forwarder.getParameters();
    LinkedHashSet<ClassNode> traits = new LinkedHashSet<ClassNode>();
    List<MethodNode> superForwarders = new LinkedList<MethodNode>();
    for (ClassNode node : interfaces) {
        if (Traits.isTrait(node)) {
            MethodNode method = node.getDeclaredMethod(name, forwarderParameters);
            if (method!=null) {
                // a similar method exists, we need a super bridge
                // trait$super$foo(Class currentTrait, ...)
                traits.add(node);
                superForwarders.add(method);
            }
        }
    }
    for (MethodNode superForwarder : superForwarders) {
        doCreateSuperForwarder(targetNode, superForwarder, traits.toArray(ClassNode.EMPTY_ARRAY), genericsSpec);
    }
}
 
Example 2
Source File: TraitComposer.java    From groovy with Apache License 2.0 6 votes vote down vote up
/**
 * Creates a method to dispatch to "super traits" in a "stackable" fashion. The generated method looks like this:
 * <p>
 * <code>ReturnType trait$super$method(Class clazz, Arg1 arg1, Arg2 arg2, ...) {
 *     if (SomeTrait.is(A) { return SomeOtherTrait$Trait$Helper.method(this, arg1, arg2) }
 *     super.method(arg1,arg2)
 * }</code>
 * </p>
 * @param targetNode
 * @param forwarderMethod
 * @param interfacesToGenerateForwarderFor
 * @param genericsSpec
 */
private static void doCreateSuperForwarder(ClassNode targetNode, MethodNode forwarderMethod, ClassNode[] interfacesToGenerateForwarderFor, Map<String,ClassNode> genericsSpec) {
    Parameter[] parameters = forwarderMethod.getParameters();
    Parameter[] superForwarderParams = new Parameter[parameters.length];
    for (int i = 0; i < parameters.length; i++) {
        Parameter parameter = parameters[i];
        ClassNode originType = parameter.getOriginType();
        superForwarderParams[i] = new Parameter(correctToGenericsSpecRecurse(genericsSpec, originType), parameter.getName());
    }
    for (int i = 0; i < interfacesToGenerateForwarderFor.length; i++) {
        final ClassNode current = interfacesToGenerateForwarderFor[i];
        final ClassNode next = i < interfacesToGenerateForwarderFor.length - 1 ? interfacesToGenerateForwarderFor[i + 1] : null;
        String forwarderName = Traits.getSuperTraitMethodName(current, forwarderMethod.getName());
        if (targetNode.getDeclaredMethod(forwarderName, superForwarderParams) == null) {
            ClassNode returnType = correctToGenericsSpecRecurse(genericsSpec, forwarderMethod.getReturnType());
            Statement delegate = next == null ? createSuperFallback(forwarderMethod, returnType) : createDelegatingForwarder(forwarderMethod, next);
            MethodNode methodNode = targetNode.addMethod(forwarderName, Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, returnType, superForwarderParams, ClassNode.EMPTY_ARRAY, delegate);
            methodNode.setGenericsTypes(forwarderMethod.getGenericsTypes());
        }
    }
}
 
Example 3
Source File: ClassNodeUtils.java    From groovy with Apache License 2.0 5 votes vote down vote up
/**
 * Return an existing method if one exists or else create a new method and mark it as {@code @Generated}.
 *
 * @see ClassNode#addMethod(String, int, ClassNode, Parameter[], ClassNode[], Statement)
 */
public static MethodNode addGeneratedMethod(ClassNode cNode, String name,
                            int modifiers,
                            ClassNode returnType,
                            Parameter[] parameters,
                            ClassNode[] exceptions,
                            Statement code) {
    MethodNode existing = cNode.getDeclaredMethod(name, parameters);
    if (existing != null) return existing;
    MethodNode result = new MethodNode(name, modifiers, returnType, parameters, exceptions, code);
    addGeneratedMethod(cNode, result);
    return result;
}
 
Example 4
Source File: UnionTypeClassNode.java    From groovy with Apache License 2.0 5 votes vote down vote up
@Override
public MethodNode getDeclaredMethod(final String name, final Parameter[] parameters) {
    for (ClassNode delegate : delegates) {
        MethodNode node = delegate.getDeclaredMethod(name, parameters);
        if (node != null) return node;
    }
    return null;
}
 
Example 5
Source File: StaticInvocationWriter.java    From groovy with Apache License 2.0 5 votes vote down vote up
@Override
protected boolean makeDirectCall(final Expression origin, final Expression receiver, final Expression message, final Expression arguments, final MethodCallerMultiAdapter adapter, final boolean implicitThis, final boolean containsSpreadExpression) {
    if (origin instanceof MethodCallExpression && isSuperExpression(receiver)) {
        ClassNode superClass = receiver.getNodeMetaData(StaticCompilationMetadataKeys.PROPERTY_OWNER);
        if (superClass != null && !controller.getCompileStack().isLHS()) {
            // GROOVY-7300
            MethodCallExpression mce = (MethodCallExpression) origin;
            MethodNode node = superClass.getDeclaredMethod(mce.getMethodAsString(), Parameter.EMPTY_ARRAY);
            mce.setMethodTarget(node);
        }
    }
    return super.makeDirectCall(origin, receiver, message, arguments, adapter, implicitThis, containsSpreadExpression);
}
 
Example 6
Source File: TemplateASTTransformer.java    From groovy with Apache License 2.0 4 votes vote down vote up
private void transformRunMethod(final ClassNode classNode, final SourceUnit source) {
    MethodNode runMethod = classNode.getDeclaredMethod("run", Parameter.EMPTY_ARRAY);
    Statement code = runMethod.getCode();
    MarkupBuilderCodeTransformer transformer = new MarkupBuilderCodeTransformer(source, classNode, config.isAutoEscape());
    code.visit(transformer);
}
 
Example 7
Source File: TraitTypeCheckingExtension.java    From groovy with Apache License 2.0 4 votes vote down vote up
@Override
public List<MethodNode> handleMissingMethod(final ClassNode receiver, final String name, final ArgumentListExpression argumentList, final ClassNode[] argumentTypes, final MethodCall call) {
    String[] decomposed = Traits.decomposeSuperCallName(name);
    if (decomposed != null) {
        return convertToDynamicCall(call, receiver, decomposed, argumentTypes);
    }
    if (call instanceof MethodCallExpression) {
        MethodCallExpression mce = (MethodCallExpression) call;
        if (mce.getReceiver() instanceof VariableExpression) {
            VariableExpression var = (VariableExpression) mce.getReceiver();

            // GROOVY-7322
            // static method call in trait?
            ClassNode type = null;
            if (isStaticTraitReceiver(receiver, var)) {
                type = receiver.getGenericsTypes()[0].getType();
            } else if (isThisTraitReceiver(var)) {
                type = receiver;
            }
            if (Traits.isTrait(type) && !(type instanceof UnionTypeClassNode)) {
                List<ClassNode> candidates = new ArrayList<ClassNode>();
                candidates.add(type);
                while (!candidates.isEmpty()) {
                    ClassNode next = candidates.remove(0);
                    ClassNode helper = Traits.findHelper(next);
                    Parameter[] params = new Parameter[argumentTypes.length + 1];
                    params[0] = new Parameter(ClassHelper.CLASS_Type.getPlainNodeReference(), "staticSelf");
                    for (int i = 1; i < params.length; i++) {
                        params[i] = new Parameter(argumentTypes[i-1], "p" + i);
                    }
                    MethodNode method = helper.getDeclaredMethod(name, params);
                    if (method != null) {
                        return Collections.singletonList(makeDynamic(call, method.getReturnType()));
                    }
                    // GROOVY-8272 support inherited static methods
                    candidates.addAll(Arrays.asList(next.getInterfaces()));
                }
            }
        }

        ClassNode dynamic = mce.getNodeMetaData(TraitASTTransformation.DO_DYNAMIC);
        if (dynamic!=null) {
            return Collections.singletonList(makeDynamic(call, dynamic));
        }
    }
    return NOTFOUND;
}
 
Example 8
Source File: BaseScriptASTTransformation.java    From groovy with Apache License 2.0 4 votes vote down vote up
private void changeBaseScriptType(final AnnotatedNode parent, final ClassNode cNode, final ClassNode baseScriptType) {
    if (!cNode.isScriptBody()) {
        addError("Annotation " + MY_TYPE_NAME + " can only be used within a Script.", parent);
        return;
    }

    if (!baseScriptType.isScript()) {
        addError("Declared type " + baseScriptType + " does not extend groovy.lang.Script class!", parent);
        return;
    }

    cNode.setSuperClass(baseScriptType);

    // Method in base script that will contain the script body code.
    MethodNode runScriptMethod = ClassHelper.findSAM(baseScriptType);

    // If they want to use a name other than than "run", then make the change.
    if (isCustomScriptBodyMethod(runScriptMethod)) {
        MethodNode defaultMethod = cNode.getDeclaredMethod("run", Parameter.EMPTY_ARRAY);
        // GROOVY-6706: Sometimes an NPE is thrown here.
        // The reason is that our transform is getting called more than once sometimes.  
        if (defaultMethod != null) {
            cNode.removeMethod(defaultMethod);
            MethodNode methodNode = new MethodNode(runScriptMethod.getName(), runScriptMethod.getModifiers() & ~ACC_ABSTRACT
                    , runScriptMethod.getReturnType(), runScriptMethod.getParameters(), runScriptMethod.getExceptions()
                    , defaultMethod.getCode());
            // The AST node metadata has the flag that indicates that this method is a script body.
            // It may also be carrying data for other AST transforms.
            methodNode.copyNodeMetaData(defaultMethod);
            addGeneratedMethod(cNode, methodNode);
        }
    }

    // If the new script base class does not have a contextual constructor (g.l.Binding), then we won't either.
    // We have to do things this way (and rely on just default constructors) because the logic that generates
    // the constructors for our script class have already run.
    if (cNode.getSuperClass().getDeclaredConstructor(CONTEXT_CTOR_PARAMETERS) == null) {
        ConstructorNode orphanedConstructor = cNode.getDeclaredConstructor(CONTEXT_CTOR_PARAMETERS);
        cNode.removeConstructor(orphanedConstructor);
    }
}
 
Example 9
Source File: TraitComposer.java    From groovy with Apache License 2.0 4 votes vote down vote up
private static MethodNode findExistingMethod(final ClassNode cNode, final String name, final Parameter[] params) {
    return cNode.getDeclaredMethod(name, params);
}
 
Example 10
Source File: ASTTransformer.java    From pom-manipulation-ext with Apache License 2.0 4 votes vote down vote up
private void changeBaseScriptType(final AnnotatedNode parent, final ClassNode cNode, final ClassNode baseScriptType) {
    if (!cNode.isScriptBody()) {
        addError( "Annotation " + getType() + " can only be used within a Script.", parent);
        return;
    }

    if (!baseScriptType.isScript()) {
        addError("Declared type " + baseScriptType + " does not extend groovy.lang.Script class!", parent);
        return;
    }

    List<AnnotationNode> annotations = parent.getAnnotations( DEPRECATED_COMMAND_TYPE );
    if (cNode.getAnnotations( DEPRECATED_COMMAND_TYPE ).isEmpty()) { // #388 prevent "Duplicate annotation for class" AnnotationFormatError
        cNode.addAnnotations(annotations);
    }
    annotations = parent.getAnnotations( COMMAND_TYPE );
    if (cNode.getAnnotations( COMMAND_TYPE ).isEmpty()) { // #388 prevent "Duplicate annotation for class" AnnotationFormatError

        cNode.addAnnotations(annotations);
    }

    cNode.setSuperClass(baseScriptType);

    // Method in base script that will contain the script body code.
    MethodNode runScriptMethod = ClassHelper.findSAM(baseScriptType);

    // If they want to use a name other than than "run", then make the change.
    if (isCustomScriptBodyMethod(runScriptMethod)) {
        MethodNode defaultMethod = cNode.getDeclaredMethod("run", Parameter.EMPTY_ARRAY);
        // GROOVY-6706: Sometimes an NPE is thrown here.
        // The reason is that our transform is getting called more than once sometimes.
        if (defaultMethod != null) {
            cNode.removeMethod(defaultMethod);
            MethodNode methodNode = new MethodNode(runScriptMethod.getName(), runScriptMethod.getModifiers() & ~ACC_ABSTRACT
                            , runScriptMethod.getReturnType(), runScriptMethod.getParameters(), runScriptMethod.getExceptions()
                            , defaultMethod.getCode());
            // The AST node metadata has the flag that indicates that this method is a script body.
            // It may also be carrying data for other AST transforms.
            methodNode.copyNodeMetaData(defaultMethod);
            addGeneratedMethod(cNode, methodNode);
        }
    }

    // If the new script base class does not have a contextual constructor (g.l.Binding), then we won't either.
    // We have to do things this way (and rely on just default constructors) because the logic that generates
    // the constructors for our script class have already run.
    if (cNode.getSuperClass().getDeclaredConstructor(CONTEXT_CTOR_PARAMETERS) == null) {
        ConstructorNode orphanedConstructor = cNode.getDeclaredConstructor(CONTEXT_CTOR_PARAMETERS);
        cNode.removeConstructor(orphanedConstructor);
    }
}