Search in sources :

Example 31 with GroovyBugError

use of org.codehaus.groovy.GroovyBugError in project groovy-core by groovy.

the class ReadWriteLockASTTransformation method visit.

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();
        String lockExpr = determineLock(value, cNode, mNode.isStatic(), myTypeName);
        if (lockExpr == null)
            return;
        // get lock type
        final Expression lockType;
        if (isWriteLock) {
            lockType = callX(varX(lockExpr, LOCK_TYPE), "writeLock");
        } else {
            lockType = callX(varX(lockExpr, LOCK_TYPE), "readLock");
        }
        Expression acquireLock = callX(lockType, "lock");
        Expression releaseLock = callX(lockType, "unlock");
        Statement originalCode = mNode.getCode();
        mNode.setCode(block(stmt(acquireLock), new TryCatchStatement(originalCode, stmt(releaseLock))));
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) MethodNode(org.codehaus.groovy.ast.MethodNode) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) Expression(org.codehaus.groovy.ast.expr.Expression) Statement(org.codehaus.groovy.ast.stmt.Statement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) AnnotatedNode(org.codehaus.groovy.ast.AnnotatedNode) GroovyBugError(org.codehaus.groovy.GroovyBugError) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement)

Example 32 with GroovyBugError

use of org.codehaus.groovy.GroovyBugError in project groovy-core by groovy.

the class LogASTTransformation method visit.

public void visit(ASTNode[] nodes, final SourceUnit source) {
    init(nodes, source);
    AnnotatedNode targetClass = (AnnotatedNode) nodes[1];
    AnnotationNode logAnnotation = (AnnotationNode) nodes[0];
    final GroovyClassLoader classLoader = compilationUnit != null ? compilationUnit.getTransformLoader() : source.getClassLoader();
    final LoggingStrategy loggingStrategy = createLoggingStrategy(logAnnotation, classLoader);
    if (loggingStrategy == null)
        return;
    final String logFieldName = lookupLogFieldName(logAnnotation);
    final String categoryName = lookupCategoryName(logAnnotation);
    if (!(targetClass instanceof ClassNode))
        throw new GroovyBugError("Class annotation " + logAnnotation.getClassNode().getName() + " annotated no Class, this must not happen.");
    final ClassNode classNode = (ClassNode) targetClass;
    ClassCodeExpressionTransformer transformer = new ClassCodeExpressionTransformer() {

        private FieldNode logNode;

        @Override
        protected SourceUnit getSourceUnit() {
            return source;
        }

        public Expression transform(Expression exp) {
            if (exp == null)
                return null;
            if (exp instanceof MethodCallExpression) {
                return transformMethodCallExpression(exp);
            }
            return super.transform(exp);
        }

        @Override
        public void visitClass(ClassNode node) {
            FieldNode logField = node.getField(logFieldName);
            if (logField != null && logField.getOwner().equals(node)) {
                addError("Class annotated with Log annotation cannot have log field declared", logField);
            } else if (logField != null && !Modifier.isPrivate(logField.getModifiers())) {
                addError("Class annotated with Log annotation cannot have log field declared because the field exists in the parent class: " + logField.getOwner().getName(), logField);
            } else {
                logNode = loggingStrategy.addLoggerFieldToClass(node, logFieldName, categoryName);
            }
            super.visitClass(node);
        }

        private Expression transformMethodCallExpression(Expression exp) {
            MethodCallExpression mce = (MethodCallExpression) exp;
            if (!(mce.getObjectExpression() instanceof VariableExpression)) {
                return exp;
            }
            VariableExpression variableExpression = (VariableExpression) mce.getObjectExpression();
            if (!variableExpression.getName().equals(logFieldName) || !(variableExpression.getAccessedVariable() instanceof DynamicVariable)) {
                return exp;
            }
            String methodName = mce.getMethodAsString();
            if (methodName == null)
                return exp;
            if (usesSimpleMethodArgumentsOnly(mce))
                return exp;
            variableExpression.setAccessedVariable(logNode);
            if (!loggingStrategy.isLoggingMethod(methodName))
                return exp;
            return loggingStrategy.wrapLoggingMethodCall(variableExpression, methodName, exp);
        }

        private boolean usesSimpleMethodArgumentsOnly(MethodCallExpression mce) {
            Expression arguments = mce.getArguments();
            if (arguments instanceof TupleExpression) {
                TupleExpression tuple = (TupleExpression) arguments;
                for (Expression exp : tuple.getExpressions()) {
                    if (!isSimpleExpression(exp))
                        return false;
                }
                return true;
            }
            return !isSimpleExpression(arguments);
        }

        private boolean isSimpleExpression(Expression exp) {
            if (exp instanceof ConstantExpression)
                return true;
            if (exp instanceof VariableExpression)
                return true;
            return false;
        }
    };
    transformer.visitClass(classNode);
    // GROOVY-6373: references to 'log' field are normally already FieldNodes by now, so revisit scoping
    new VariableScopeVisitor(sourceUnit, true).visitClass(classNode);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) AnnotatedNode(org.codehaus.groovy.ast.AnnotatedNode) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) GroovyBugError(org.codehaus.groovy.GroovyBugError) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) GroovyClassLoader(groovy.lang.GroovyClassLoader) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) DynamicVariable(org.codehaus.groovy.ast.DynamicVariable) VariableScopeVisitor(org.codehaus.groovy.classgen.VariableScopeVisitor) ClassCodeExpressionTransformer(org.codehaus.groovy.ast.ClassCodeExpressionTransformer)

Example 33 with GroovyBugError

use of org.codehaus.groovy.GroovyBugError in project groovy-core by groovy.

the class AnnotationCollectorTransform method getTargetListFromClass.

private static List<AnnotationNode> getTargetListFromClass(ClassNode alias) {
    Class<?> c = alias.getTypeClass();
    Object[][] data;
    try {
        Method m = c.getMethod("value");
        data = (Object[][]) m.invoke(null);
    } catch (Exception e) {
        throw new GroovyBugError(e);
    }
    return makeListOfAnnotations(data);
}
Also used : GroovyBugError(org.codehaus.groovy.GroovyBugError) Method(java.lang.reflect.Method) SyntaxException(org.codehaus.groovy.syntax.SyntaxException)

Example 34 with GroovyBugError

use of org.codehaus.groovy.GroovyBugError in project groovy-core by groovy.

the class Java5 method makeInterfaceTypes.

private void makeInterfaceTypes(CompileUnit cu, ClassNode classNode, Class clazz) {
    Type[] interfaceTypes = clazz.getGenericInterfaces();
    if (interfaceTypes.length == 0) {
        classNode.setInterfaces(ClassNode.EMPTY_ARRAY);
    } else {
        ClassNode[] ret = new ClassNode[interfaceTypes.length];
        for (int i = 0; i < interfaceTypes.length; i++) {
            Type type = interfaceTypes[i];
            while (!(type instanceof Class)) {
                ParameterizedType pt = (ParameterizedType) type;
                Type t2 = pt.getRawType();
                if (t2 == type) {
                    throw new GroovyBugError("Cannot transform generic signature of " + clazz + " with generic interface " + interfaceTypes[i] + " to a class.");
                }
                type = t2;
            }
            ret[i] = makeClassNode(cu, interfaceTypes[i], (Class) type);
        }
        classNode.setInterfaces(ret);
    }
}
Also used : ParameterizedType(java.lang.reflect.ParameterizedType) ClassNode(org.codehaus.groovy.ast.ClassNode) GenericArrayType(java.lang.reflect.GenericArrayType) WildcardType(java.lang.reflect.WildcardType) GenericsType(org.codehaus.groovy.ast.GenericsType) ElementType(java.lang.annotation.ElementType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) GroovyBugError(org.codehaus.groovy.GroovyBugError)

Example 35 with GroovyBugError

use of org.codehaus.groovy.GroovyBugError in project groovy-core by groovy.

the class AntlrParserPlugin method importDef.

protected void importDef(AST importNode) {
    try {
        // GROOVY-6094
        output.putNodeMetaData(ImportNode.class, ImportNode.class);
        boolean isStatic = importNode.getType() == STATIC_IMPORT;
        List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
        AST node = importNode.getFirstChild();
        if (isType(ANNOTATIONS, node)) {
            processAnnotations(annotations, node);
            node = node.getNextSibling();
        }
        String alias = null;
        if (isType(LITERAL_as, node)) {
            //import is like "import Foo as Bar"
            node = node.getFirstChild();
            AST aliasNode = node.getNextSibling();
            alias = identifier(aliasNode);
        }
        if (node.getNumberOfChildren() == 0) {
            String name = identifier(node);
            // import is like  "import Foo"
            ClassNode type = ClassHelper.make(name);
            configureAST(type, importNode);
            addImport(type, name, alias, annotations);
            return;
        }
        AST packageNode = node.getFirstChild();
        String packageName = qualifiedName(packageNode);
        AST nameNode = packageNode.getNextSibling();
        if (isType(STAR, nameNode)) {
            if (isStatic) {
                // import is like "import static foo.Bar.*"
                // packageName is actually a className in this case
                ClassNode type = ClassHelper.make(packageName);
                configureAST(type, importNode);
                addStaticStarImport(type, packageName, annotations);
            } else {
                // import is like "import foo.*"
                addStarImport(packageName, annotations);
            }
            if (alias != null)
                throw new GroovyBugError("imports like 'import foo.* as Bar' are not " + "supported and should be caught by the grammar");
        } else {
            String name = identifier(nameNode);
            if (isStatic) {
                // import is like "import static foo.Bar.method"
                // packageName is really class name in this case
                ClassNode type = ClassHelper.make(packageName);
                configureAST(type, importNode);
                addStaticImport(type, name, alias, annotations);
            } else {
                // import is like "import foo.Bar"
                ClassNode type = ClassHelper.make(packageName + "." + name);
                configureAST(type, importNode);
                addImport(type, name, alias, annotations);
            }
        }
    } finally {
        // we're using node metadata here in order to fix GROOVY-6094
        // without breaking external APIs
        Object node = output.getNodeMetaData(ImportNode.class);
        if (node != null && node != ImportNode.class) {
            configureAST((ImportNode) node, importNode);
        }
        output.removeNodeMetaData(ImportNode.class);
    }
}
Also used : AST(antlr.collections.AST) ArrayList(java.util.ArrayList) GroovyBugError(org.codehaus.groovy.GroovyBugError)

Aggregations

GroovyBugError (org.codehaus.groovy.GroovyBugError)71 ClassNode (org.codehaus.groovy.ast.ClassNode)31 AnnotationNode (org.codehaus.groovy.ast.AnnotationNode)11 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)11 MethodNode (org.codehaus.groovy.ast.MethodNode)11 GenericsType (org.codehaus.groovy.ast.GenericsType)9 AnnotatedNode (org.codehaus.groovy.ast.AnnotatedNode)8 FieldNode (org.codehaus.groovy.ast.FieldNode)8 SyntaxException (org.codehaus.groovy.syntax.SyntaxException)8 MethodVisitor (org.objectweb.asm.MethodVisitor)8 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)7 Closure (groovy.lang.Closure)6 GroovyRuntimeException (groovy.lang.GroovyRuntimeException)6 IOException (java.io.IOException)6 ArrayList (java.util.ArrayList)6 LinkedList (java.util.LinkedList)5 Expression (org.codehaus.groovy.ast.expr.Expression)5 GroovyClassLoader (groovy.lang.GroovyClassLoader)4 InvocationTargetException (java.lang.reflect.InvocationTargetException)4 Collection (java.util.Collection)4