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

The following examples show how to use org.codehaus.groovy.ast.MethodNode#getCode() . 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: NotYetImplementedASTTransformation.java    From groovy with Apache License 2.0 6 votes vote down vote up
public void visit(ASTNode[] nodes, SourceUnit source) {
    init(nodes, source);
    AnnotationNode anno = (AnnotationNode) nodes[0];
    MethodNode methodNode = (MethodNode) nodes[1];

    ClassNode exception = getMemberClassValue(anno, "exception");
    if (exception == null) {
        exception = DEFAULT_THROW_TYPE;
    }
    ConstructorNode cons = exception.getDeclaredConstructor(new Parameter[]{new Parameter(ClassHelper.STRING_TYPE, "dummy")});
    if (cons == null) {
        addError("Error during @NotYetImplemented processing: supplied exception " + exception.getNameWithoutPackage() + " doesn't have expected String constructor", methodNode);
    }

    if (methodNode.getCode() instanceof BlockStatement && !methodNode.getCode().isEmpty()) {
        // wrap code in try/catch with return for failure path followed by throws for success path

        TryCatchStatement tryCatchStatement = tryCatchS(methodNode.getCode());
        tryCatchStatement.addCatch(catchS(param(CATCH_TYPE, "ignore"), ReturnStatement.RETURN_NULL_OR_VOID));

        ThrowStatement throwStatement = throwS(ctorX(exception, args(constX("Method is marked with @NotYetImplemented but passes unexpectedly"))));

        methodNode.setCode(block(tryCatchStatement, throwStatement));
    }
}
 
Example 2
Source File: DataSet.java    From groovy with Apache License 2.0 6 votes vote down vote up
private static void visit(Closure closure, CodeVisitorSupport visitor) {
    if (closure != null) {
        ClassNode classNode = closure.getMetaClass().getClassNode();
        if (classNode == null) {
            throw new GroovyRuntimeException(
                    "DataSet unable to evaluate expression. AST not available for closure: " + closure.getMetaClass().getTheClass().getName() +
                            ". Is the source code on the classpath?");
        }
        List methods = classNode.getDeclaredMethods("doCall");
        if (!methods.isEmpty()) {
            MethodNode method = (MethodNode) methods.get(0);
            if (method != null) {
                Statement statement = method.getCode();
                if (statement != null) {
                    statement.visit(visitor);
                }
            }
        }
    }
}
 
Example 3
Source File: SynchronizedASTTransformation.java    From groovy with Apache License 2.0 6 votes vote down vote up
public void visit(ASTNode[] nodes, SourceUnit source) {
    init(nodes, source);
    AnnotatedNode parent = (AnnotatedNode) nodes[1];
    AnnotationNode node = (AnnotationNode) nodes[0];
    if (!MY_TYPE.equals(node.getClassNode())) return;
    String value = getMemberStringValue(node, "value");

    if (parent instanceof MethodNode) {
        MethodNode mNode = (MethodNode) parent;
        if (mNode.isAbstract()) {
            addError("Error during " + MY_TYPE_NAME + " processing: annotation not allowed on abstract method '" + mNode.getName() + "'", mNode);
            return;
        }
        ClassNode cNode = mNode.getDeclaringClass();
        String lockExpr = determineLock(value, cNode, mNode);
        if (lockExpr == null) return;
        Statement origCode = mNode.getCode();
        Statement newCode = new SynchronizedStatement(varX(lockExpr), origCode);
        mNode.setCode(newCode);
    }
}
 
Example 4
Source File: MemoizedASTTransformation.java    From groovy with Apache License 2.0 6 votes vote down vote up
private static MethodNode buildDelegatingMethod(final MethodNode annotatedMethod, final ClassNode ownerClassNode) {
    Statement code = annotatedMethod.getCode();
    int access = ACC_PROTECTED;
    if (annotatedMethod.isStatic()) {
        access = ACC_PRIVATE | ACC_STATIC;
    }
    MethodNode method = new MethodNode(
            buildUniqueName(ownerClassNode, METHOD_LABEL, annotatedMethod),
            access,
            annotatedMethod.getReturnType(),
            cloneParams(annotatedMethod.getParameters()),
            annotatedMethod.getExceptions(),
            code
    );
    method.addAnnotations(filterAnnotations(annotatedMethod.getAnnotations()));
    return method;
}
 
Example 5
Source File: Verifier.java    From groovy with Apache License 2.0 6 votes vote down vote up
@Override
public void visitMethod(MethodNode node) {
    // GROOVY-3712 - if it's an MOP method, it's an error as they aren't supposed to exist before ACG is invoked
    if (MopWriter.isMopMethod(node.getName())) {
        throw new RuntimeParserException("Found unexpected MOP methods in the class node for " + classNode.getName() + "(" + node.getName() + ")", classNode);
    }

    adjustTypesIfStaticMainMethod(node);
    this.methodNode = node;
    addReturnIfNeeded(node);

    Statement stmt = node.getCode();
    if (stmt != null) {
        stmt.visit(new VerifierCodeVisitor(getClassNode()));
    }
}
 
Example 6
Source File: AnnotationVisitor.java    From groovy with Apache License 2.0 6 votes vote down vote up
public void checkCircularReference(ClassNode searchClass, ClassNode attrType, Expression startExp) {
    if (!isValidAnnotationClass(attrType)) return;
    if (!(startExp instanceof AnnotationConstantExpression)) {
        addError("Found '" + startExp.getText() + "' when expecting an Annotation Constant", startExp);
        return;
    }
    AnnotationConstantExpression ace = (AnnotationConstantExpression) startExp;
    AnnotationNode annotationNode = (AnnotationNode) ace.getValue();
    if (annotationNode.getClassNode().equals(searchClass)) {
        addError("Circular reference discovered in " + searchClass.getName(), startExp);
        return;
    }
    ClassNode cn = annotationNode.getClassNode();
    for (MethodNode method : cn.getMethods()) {
        if (method.getReturnType().equals(searchClass)) {
            addError("Circular reference discovered in " + cn.getName(), startExp);
        }
        ReturnStatement code = (ReturnStatement) method.getCode();
        if (code == null) continue;
        checkCircularReference(searchClass, method.getReturnType(), code.getExpression());
    }
}
 
Example 7
Source File: AnnotationVisitor.java    From groovy with Apache License 2.0 5 votes vote down vote up
private boolean checkIfMandatoryAnnotationValuesPassed(AnnotationNode node) {
    boolean ok = true;
    Map attributes = node.getMembers();
    ClassNode classNode = node.getClassNode();
    for (MethodNode mn : classNode.getMethods()) {
        String methodName = mn.getName();
        // if the annotation attribute has a default, getCode() returns a ReturnStatement with the default value
        if (mn.getCode() == null && !attributes.containsKey(methodName)) {
            addError("No explicit/default value found for annotation attribute '" + methodName + "'", node);
            ok = false;
        }
    }
    return ok;
}
 
Example 8
Source File: VetoableASTTransformation.java    From groovy with Apache License 2.0 5 votes vote down vote up
/**
 * Wrap an existing setter.
 */
private static void wrapSetterMethod(ClassNode classNode, boolean bindable, String propertyName) {
    String getterName = "get" + capitalize(propertyName);
    MethodNode setter = classNode.getSetterMethod(getSetterName(propertyName));

    if (setter != null) {
        // Get the existing code block
        Statement code = setter.getCode();

        Expression oldValue = localVarX("$oldValue");
        Expression newValue = localVarX("$newValue");
        Expression proposedValue = varX(setter.getParameters()[0].getName());
        BlockStatement block = new BlockStatement();

        // create a local variable to hold the old value from the getter
        block.addStatement(declS(oldValue, callThisX(getterName)));

        // add the fireVetoableChange method call
        block.addStatement(stmt(callThisX("fireVetoableChange", args(
                constX(propertyName), oldValue, proposedValue))));

        // call the existing block, which will presumably set the value properly
        block.addStatement(code);

        if (bindable) {
            // get the new value to emit in the event
            block.addStatement(declS(newValue, callThisX(getterName)));

            // add the firePropertyChange method call
            block.addStatement(stmt(callThisX("firePropertyChange", args(constX(propertyName), oldValue, newValue))));
        }

        // replace the existing code block with our new one
        setter.setCode(block);
    }
}
 
Example 9
Source File: BindableASTTransformation.java    From groovy with Apache License 2.0 5 votes vote down vote up
private static void wrapSetterMethod(ClassNode classNode, String propertyName) {
    String getterName = "get" + capitalize(propertyName);
    MethodNode setter = classNode.getSetterMethod(getSetterName(propertyName));

    if (setter != null) {
        // Get the existing code block
        Statement code = setter.getCode();

        Expression oldValue = localVarX("$oldValue");
        Expression newValue = localVarX("$newValue");
        BlockStatement block = new BlockStatement();

        // create a local variable to hold the old value from the getter
        block.addStatement(declS(oldValue, callThisX(getterName)));

        // call the existing block, which will presumably set the value properly
        block.addStatement(code);

        // get the new value to emit in the event
        block.addStatement(declS(newValue, callThisX(getterName)));

        // add the firePropertyChange method call
        block.addStatement(stmt(callThisX("firePropertyChange", args(constX(propertyName), oldValue, newValue))));

        // replace the existing code block with our new one
        setter.setCode(block);
    }
}
 
Example 10
Source File: StatementWriter.java    From groovy with Apache License 2.0 5 votes vote down vote up
private boolean isMethodOrConstructorNonEmptyBlock(final BlockStatement block) {
    MethodNode methodNode = controller.getMethodNode();
    if (methodNode == null) {
        methodNode = controller.getConstructorNode();
    }
    return (methodNode != null && methodNode.getCode() == block && !block.isEmpty());
}
 
Example 11
Source File: ReturnAdder.java    From groovy with Apache License 2.0 5 votes vote down vote up
/**
 * Adds return statements to given method whenever an implicit return is detected.
 */
public void visitMethod(final MethodNode node) {
    if (!node.isVoidMethod()) {
        Statement code = node.getCode();
        if (code != null) { // happens with @interface methods
            code = addReturnsIfNeeded(code, node.getVariableScope());
            if (doAdd) node.setCode(code);
        }
    }
}
 
Example 12
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 13
Source File: ReadWriteLockASTTransformation.java    From groovy with Apache License 2.0 5 votes vote down vote up
public void visit(ASTNode[] nodes, SourceUnit source) {
    init(nodes, source);
    AnnotatedNode parent = (AnnotatedNode) nodes[1];
    AnnotationNode node = (AnnotationNode) nodes[0];
    final boolean isWriteLock;
    if (READ_LOCK_TYPE.equals(node.getClassNode())) {
        isWriteLock = false;
    } else if (WRITE_LOCK_TYPE.equals(node.getClassNode())) {
        isWriteLock = true;
    } else {
        throw new GroovyBugError("Internal error: expecting [" + READ_LOCK_TYPE.getName() + ", " + WRITE_LOCK_TYPE.getName() + "]" + " but got: " + node.getClassNode().getName());
    }

    String myTypeName = "@" + node.getClassNode().getNameWithoutPackage();

    String value = getMemberStringValue(node, "value");

    if (parent instanceof MethodNode) {
        MethodNode mNode = (MethodNode) parent;
        ClassNode cNode = mNode.getDeclaringClass();
        FieldNode lockExpr = determineLock(value, cNode, mNode.isStatic(), myTypeName);
        if (lockExpr == null) return;

        // get lock type
        final MethodCallExpression lockType = callX(varX(lockExpr), isWriteLock ? "writeLock" : "readLock");
        lockType.setImplicitThis(false);

        MethodCallExpression acquireLock = callX(lockType, "lock");
        acquireLock.setImplicitThis(false);

        MethodCallExpression releaseLock = callX(lockType, "unlock");
        releaseLock.setImplicitThis(false);

        Statement originalCode = mNode.getCode();

        mNode.setCode(block(
                stmt(acquireLock),
                new TryCatchStatement(originalCode, stmt(releaseLock))));
    }
}
 
Example 14
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 15
Source File: BeanUtils.java    From groovy with Apache License 2.0 4 votes vote down vote up
public static void addPseudoProperties(ClassNode origType, ClassNode cNode, List<PropertyNode> result, Set<String> names, boolean includeStatic, boolean includePseudoGetters, boolean includePseudoSetters) {
    if (!includePseudoGetters && !includePseudoSetters) return;
    List<MethodNode> methods = cNode.getAllDeclaredMethods();
    for (MethodNode mNode : methods) {
        if (!includeStatic && mNode.isStatic()) continue;
        if (hasAnnotation(mNode, INTERNAL_TYPE)) continue;
        String name = mNode.getName();
        if ((name.length() <= 3 && !name.startsWith(IS_PREFIX)) || name.equals("getClass") || name.equals("getMetaClass") || name.equals("getDeclaringClass")) {
            // Optimization: skip invalid propertyNames
            continue;
        }
        if (mNode.getDeclaringClass() != origType && mNode.isPrivate()) {
            // skip private super methods
            continue;
        }
        int paramCount = mNode.getParameters().length;
        ClassNode paramType = mNode.getReturnType();
        String propName = null;
        Statement getter = null;
        Statement setter = null;
        if (paramCount == 0) {
            if (includePseudoGetters && name.startsWith(GET_PREFIX)) {
                // Simple getter
                propName = decapitalize(name.substring(3));
                getter = mNode.getCode();
            } else if (includePseudoGetters && name.startsWith(IS_PREFIX) && paramType.equals(ClassHelper.boolean_TYPE)) {
                // boolean getter
                propName = decapitalize(name.substring(2));
                getter = mNode.getCode();
            }
        } else if (paramCount == 1) {
            if (includePseudoSetters && name.startsWith(SET_PREFIX)) {
                // Simple setter
                propName = decapitalize(name.substring(3));
                setter = mNode.getCode();
                paramType = mNode.getParameters()[0].getType();

            }
        }
        if (propName != null) {
            addIfMissing(cNode, result, names, mNode, paramType, propName, getter, setter);
        }
    }
}
 
Example 16
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 17
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 18
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);
    }
}