Java Code Examples for org.codehaus.groovy.ast.MethodNode#getModifiers()

The following examples show how to use org.codehaus.groovy.ast.MethodNode#getModifiers() . 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: AbstractExtensionMethodCache.java    From groovy with Apache License 2.0 6 votes vote down vote up
private void accumulate(Map<String, List<MethodNode>> accumulator, boolean isStatic, MethodNode metaMethod,
                               Function<MethodNode, String> mapperFunction) {

    Parameter[] types = metaMethod.getParameters();
    Parameter[] parameters = new Parameter[types.length - 1];
    System.arraycopy(types, 1, parameters, 0, parameters.length);
    ExtensionMethodNode node = new ExtensionMethodNode(
            metaMethod,
            metaMethod.getName(),
            metaMethod.getModifiers(),
            metaMethod.getReturnType(),
            parameters,
            ClassNode.EMPTY_ARRAY, null,
            isStatic);
    node.setGenericsTypes(metaMethod.getGenericsTypes());
    ClassNode declaringClass = types[0].getType();
    node.setDeclaringClass(declaringClass);

    String key = mapperFunction.apply(metaMethod);

    List<MethodNode> nodes = accumulator.computeIfAbsent(key, k -> new ArrayList<>());
    nodes.add(node);
}
 
Example 2
Source File: InnerClassCompletionVisitor.java    From groovy with Apache License 2.0 6 votes vote down vote up
private void addSyntheticMethod(final InnerClassNode node, final String methodName, final int modifiers,
        final ClassNode returnType, final Parameter[] parameters, final BiConsumer<BlockStatement, Parameter[]> consumer) {
    MethodNode method = node.getMethod(methodName, parameters);
    if (method != null) {
        // GROOVY-8914: pre-compiled classes lose synthetic boolean - TODO fix earlier as per GROOVY-4346 then remove extra check here
        if (isStatic(node) && !method.isSynthetic() && (method.getModifiers() & ACC_SYNTHETIC) == 0) {
            // if there is a user-defined methodNode, add compiler error and continue
            addError("\"" + methodName + "\" implementations are not supported on static inner classes as " +
                "a synthetic version of \"" + methodName + "\" is added during compilation for the purpose " +
                "of outer class delegation.",
                method);
        }
        return;
    }

    BlockStatement methodBody = block();
    consumer.accept(methodBody, parameters);
    node.addSyntheticMethod(methodName, modifiers, returnType, parameters, ClassNode.EMPTY_ARRAY, methodBody);
}
 
Example 3
Source File: GroovyVirtualSourceProvider.java    From netbeans with Apache License 2.0 5 votes vote down vote up
private void genMethod(ClassNode clazz, MethodNode methodNode, PrintWriter out, boolean ignoreSynthetic) {
    String name = methodNode.getName();
    if ((ignoreSynthetic && methodNode.isSynthetic()) || name.startsWith("super$")) { // NOI18N
        return;
    }
// </netbeans>
    if (methodNode.getName().equals("<clinit>")) {
        return;
    }
    if (!clazz.isInterface()) {
        printModifiers(out, methodNode.getModifiers());
    }
    printType(methodNode.getReturnType(), out);
    out.print(" ");
    out.print(methodNode.getName());

    printParams(methodNode, out);

    ClassNode[] exceptions = methodNode.getExceptions();
    if (exceptions != null && exceptions.length > 0) {
        out.print(" throws ");
        for (int i = 0; i < exceptions.length; i++) {
            if (i > 0) {
                out.print(", ");
            }
            printType(exceptions[i], out);
        }
    }

    if ((methodNode.getModifiers() & Opcodes.ACC_ABSTRACT) != 0) {
        out.println(";");
    } else {
        out.print(" { ");
        ClassNode retType = methodNode.getReturnType();
        printReturn(out, retType);
        out.println("}");
    }
}
 
Example 4
Source File: TraitASTTransformation.java    From groovy with Apache License 2.0 5 votes vote down vote up
private static boolean methodNeedsReplacement(ClassNode classNode, MethodNode m) {
    // no method found, we need to replace
    if (m == null) return true;
    // method is in current class, nothing to be done
    if (m.getDeclaringClass() == classNode) return false;
    // do not overwrite final
    if ((m.getModifiers() & ACC_FINAL) != 0) return false;
    return true;
}
 
Example 5
Source File: GenericsUtils.java    From groovy with Apache License 2.0 5 votes vote down vote up
public static MethodNode correctToGenericsSpec(Map<String, ClassNode> genericsSpec, MethodNode mn) {
    if (genericsSpec == null) return mn;
    if (mn.getGenericsTypes() != null) genericsSpec = addMethodGenerics(mn, genericsSpec);
    ClassNode correctedType = correctToGenericsSpecRecurse(genericsSpec, mn.getReturnType());
    Parameter[] origParameters = mn.getParameters();
    Parameter[] newParameters = new Parameter[origParameters.length];
    for (int i = 0; i < origParameters.length; i++) {
        Parameter origParameter = origParameters[i];
        newParameters[i] = new Parameter(correctToGenericsSpecRecurse(genericsSpec, origParameter.getType()), origParameter.getName(), origParameter.getInitialExpression());
    }
    return new MethodNode(mn.getName(), mn.getModifiers(), correctedType, newParameters, mn.getExceptions(), mn.getCode());
}
 
Example 6
Source File: MopWriter.java    From groovy with Apache License 2.0 5 votes vote down vote up
/**
 * Filters a list of method for MOP methods. For all methods that are no
 * MOP methods a MOP method is created if the method is not public and the
 * call would be a call on "this" (isThis == true). If the call is not on
 * "this", then the call is a call on "super" and all methods are used,
 * unless they are already a MOP method.
 *
 * @param methods unfiltered list of methods for MOP
 * @param isThis  if true, then we are creating a MOP method on "this", "super" else
 *
 * @see #generateMopCalls(LinkedList, boolean)
 */
private void visitMopMethodList(List<MethodNode> methods, boolean isThis, Set<MopKey> useOnlyIfDeclaredHereToo, List<String> orNameMentionedHere) {
    Map<MopKey, MethodNode> mops = new HashMap<>();
    LinkedList<MethodNode> mopCalls = new LinkedList<>();
    for (MethodNode mn : methods) {
        // mop methods are helper for this and super calls and do direct calls
        // to the target methods. Such a method cannot be abstract or a bridge
        if ((mn.getModifiers() & (ACC_ABSTRACT | ACC_BRIDGE)) != 0) continue;
        if (mn.isStatic()) continue;
        // no this$ methods for non-private isThis=true
        // super$ method for non-private isThis=false
        // --> results in XOR
        boolean isPrivate = Modifier.isPrivate(mn.getModifiers());
        if (isThis ^ isPrivate) continue;
        String methodName = mn.getName();
        if (isMopMethod(methodName)) {
            mops.put(new MopKey(methodName, mn.getParameters()), mn);
            continue;
        }
        if (methodName.startsWith("<")) continue;
        if (!useOnlyIfDeclaredHereToo.contains(new MopKey(methodName, mn.getParameters())) &&
                !orNameMentionedHere.contains(methodName)) {
            continue;
        }
        String name = getMopMethodName(mn, isThis);
        MopKey key = new MopKey(name, mn.getParameters());
        if (mops.containsKey(key)) continue;
        mops.put(key, mn);
        mopCalls.add(mn);
    }
    generateMopCalls(mopCalls, isThis);
    mopCalls.clear();
    mops.clear();
}
 
Example 7
Source File: JavaStubGenerator.java    From groovy with Apache License 2.0 5 votes vote down vote up
private boolean isCandidateTraitMethod(ClassNode trait, MethodNode traitMethod) {
    boolean precompiled = trait.redirect() instanceof DecompiledClassNode;
    if (!precompiled) return !traitMethod.isAbstract();
    List<MethodNode> helperMethods = Traits.findHelper(trait).getMethods();
    for (MethodNode helperMethod : helperMethods) {
        boolean isSynthetic = (traitMethod.getModifiers() & Opcodes.ACC_SYNTHETIC) != 0;
        if (helperMethod.getName().equals(traitMethod.getName()) && !isSynthetic && !traitMethod.getName().contains("$")) {
            Parameter[] origParams = helperMethod.getParameters();
            Parameter[] newParams = Arrays.copyOfRange(origParams, 1, origParams.length);
            if (sameParameterTypes(newParams, traitMethod.getParameters())) return true;
        }
    }
    return false;
}
 
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: AsmClassGenerator.java    From groovy with Apache License 2.0 4 votes vote down vote up
@Override
protected void visitConstructorOrMethod(final MethodNode node, final boolean isConstructor) {
    controller.resetLineNumber();
    Parameter[] parameters = node.getParameters();
    String methodType = BytecodeHelper.getMethodDescriptor(node.getReturnType(), parameters);
    String signature = BytecodeHelper.getGenericsMethodSignature(node);
    int modifiers = node.getModifiers();
    if (isVargs(node.getParameters())) modifiers |= ACC_VARARGS;
    MethodVisitor mv = classVisitor.visitMethod(modifiers, node.getName(), methodType, signature, buildExceptions(node.getExceptions()));
    controller.setMethodVisitor(mv);

    visitAnnotations(node, mv);
    for (int i = 0, n = parameters.length; i < n; i += 1) {
        visitParameterAnnotations(parameters[i], i, mv);
    }

    // add parameter names to the MethodVisitor (jdk8+ only)
    if (Optional.ofNullable(controller.getClassNode().getCompileUnit())
            .orElseGet(context::getCompileUnit).getConfig().getParameters()) {
        for (Parameter parameter : parameters) {
            // TODO: handle ACC_SYNTHETIC for enum method parameters?
            mv.visitParameter(parameter.getName(), 0);
        }
    }

    if (controller.getClassNode().isAnnotationDefinition() && !node.isStaticConstructor()) {
        visitAnnotationDefault(node, mv);
    } else if (!node.isAbstract()) {
        Statement code = node.getCode();
        mv.visitCode();

        BytecodeInstruction instruction; // fast path for getters, setters, etc.
        if (code instanceof BytecodeSequence && (instruction = ((BytecodeSequence) code).getBytecodeInstruction()) != null) {
           instruction.visit(mv);
        } else {
            visitStdMethod(node, isConstructor, parameters, code);
        }

        try {
            mv.visitMaxs(0, 0);
        } catch (Exception e) {
            Writer writer = null;
            if (mv instanceof TraceMethodVisitor) {
                TraceMethodVisitor tracer = (TraceMethodVisitor) mv;
                writer = new StringBuilderWriter();
                PrintWriter p = new PrintWriter(writer);
                tracer.p.print(p);
                p.flush();
            }
            StringBuilder message = new StringBuilder(64);
            message.append("ASM reporting processing error for ");
            message.append(controller.getClassNode().toString()).append("#").append(node.getName());
            message.append(" with signature ").append(node.getTypeDescriptor());
            message.append(" in ").append(sourceFile).append(":").append(node.getLineNumber());
            if (writer != null) {
                message.append("\nLast known generated bytecode in last generated method or constructor:\n");
                message.append(writer);
            }
            throw new GroovyRuntimeException(message.toString(), e);
        }
    }
    mv.visitEnd();
}
 
Example 10
Source File: JavaStubGenerator.java    From groovy with Apache License 2.0 4 votes vote down vote up
private void printMethod(PrintWriter out, ClassNode clazz, MethodNode methodNode) {
    if (methodNode.getName().equals("<clinit>")) return;
    if (methodNode.isPrivate() || !Utilities.isJavaIdentifier(methodNode.getName())) return;
    if (methodNode.isSynthetic() && methodNode.getName().equals("$getStaticMetaClass")) return;

    printAnnotations(out, methodNode);
    if (!isInterfaceOrTrait(clazz)) {
        int modifiers = methodNode.getModifiers();
        if (isDefaultTraitImpl(methodNode)) {
            modifiers ^= Opcodes.ACC_ABSTRACT;
        }
        printModifiers(out, modifiers & ~(clazz.isEnum() ? Opcodes.ACC_ABSTRACT : 0));
    }

    printGenericsBounds(out, methodNode.getGenericsTypes());
    out.print(" ");
    printType(out, methodNode.getReturnType());
    out.print(" ");
    out.print(methodNode.getName());

    printParams(out, methodNode);

    ClassNode[] exceptions = methodNode.getExceptions();
    printExceptions(out, exceptions);

    if (Traits.isTrait(clazz)) {
        out.println(";");
    } else if (isAbstract(methodNode) && !clazz.isEnum()) {
        if (clazz.isAnnotationDefinition() && methodNode.hasAnnotationDefault()) {
            Statement fs = methodNode.getFirstStatement();
            if (fs instanceof ExpressionStatement) {
                ExpressionStatement es = (ExpressionStatement) fs;
                Expression re = es.getExpression();
                out.print(" default ");
                ClassNode rt = methodNode.getReturnType();
                boolean classReturn = ClassHelper.CLASS_Type.equals(rt) || (rt.isArray() && ClassHelper.CLASS_Type.equals(rt.getComponentType()));
                if (re instanceof ListExpression) {
                    out.print("{ ");
                    ListExpression le = (ListExpression) re;
                    boolean first = true;
                    for (Expression expression : le.getExpressions()) {
                        if (first) first = false;
                        else out.print(", ");
                        printValue(out, expression, classReturn);
                    }
                    out.print(" }");
                } else {
                    printValue(out, re, classReturn);
                }
            }
        }
        out.println(";");
    } else {
        out.print(" { ");
        ClassNode retType = methodNode.getReturnType();
        printReturn(out, retType);
        out.println("}");
    }
}
 
Example 11
Source File: JavaStubGenerator.java    From groovy with Apache License 2.0 4 votes vote down vote up
private static boolean isAbstract(final MethodNode methodNode) {
    if (isDefaultTraitImpl(methodNode)) {
        return false;
    }
    return (methodNode.getModifiers() & Opcodes.ACC_ABSTRACT) != 0;
}
 
Example 12
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);
    }
}