Search in sources :

Example 6 with RuntimeParserException

use of org.codehaus.groovy.syntax.RuntimeParserException in project groovy by apache.

the class VerifierCodeVisitorTest method assertInvalidName.

protected void assertInvalidName(String name) {
    try {
        VerifierCodeVisitor.assertValidIdentifier(name, "variable name", new ASTNode());
        fail("Should have thrown exception due to invalid name: " + name);
    } catch (RuntimeParserException e) {
        System.out.println("Caught invalid exception: " + e);
    }
}
Also used : ASTNode(org.codehaus.groovy.ast.ASTNode) RuntimeParserException(org.codehaus.groovy.syntax.RuntimeParserException)

Example 7 with RuntimeParserException

use of org.codehaus.groovy.syntax.RuntimeParserException in project groovy-core by groovy.

the class Verifier method visitConstructor.

public void visitConstructor(ConstructorNode node) {
    CodeVisitorSupport checkSuper = new CodeVisitorSupport() {

        boolean firstMethodCall = true;

        String type = null;

        public void visitMethodCallExpression(MethodCallExpression call) {
            if (!firstMethodCall)
                return;
            firstMethodCall = false;
            String name = call.getMethodAsString();
            // the name might be null if the method name is a GString for example
            if (name == null)
                return;
            if (!name.equals("super") && !name.equals("this"))
                return;
            type = name;
            call.getArguments().visit(this);
            type = null;
        }

        public void visitConstructorCallExpression(ConstructorCallExpression call) {
            if (!call.isSpecialCall())
                return;
            type = call.getText();
            call.getArguments().visit(this);
            type = null;
        }

        public void visitVariableExpression(VariableExpression expression) {
            if (type == null)
                return;
            String name = expression.getName();
            if (!name.equals("this") && !name.equals("super"))
                return;
            throw new RuntimeParserException("cannot reference " + name + " inside of " + type + "(....) before supertype constructor has been called", expression);
        }
    };
    Statement s = node.getCode();
    if (s == null) {
        return;
    } else {
        s.visit(new VerifierCodeVisitor(this));
    }
    s.visit(checkSuper);
}
Also used : MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) RuntimeParserException(org.codehaus.groovy.syntax.RuntimeParserException)

Example 8 with RuntimeParserException

use of org.codehaus.groovy.syntax.RuntimeParserException in project groovy-core by groovy.

the class Verifier method addCovariantMethods.

protected void addCovariantMethods(ClassNode classNode) {
    Map methodsToAdd = new HashMap();
    Map genericsSpec = new HashMap();
    // unimplemented abstract methods from interfaces
    Map abstractMethods = new HashMap();
    Map<String, MethodNode> allInterfaceMethods = new HashMap<String, MethodNode>();
    ClassNode[] interfaces = classNode.getInterfaces();
    for (ClassNode iface : interfaces) {
        Map ifaceMethodsMap = iface.getDeclaredMethodsMap();
        abstractMethods.putAll(ifaceMethodsMap);
        allInterfaceMethods.putAll(ifaceMethodsMap);
    }
    collectSuperInterfaceMethods(classNode, allInterfaceMethods);
    List<MethodNode> declaredMethods = new ArrayList<MethodNode>(classNode.getMethods());
    // remove all static, private and package private methods
    for (Iterator methodsIterator = declaredMethods.iterator(); methodsIterator.hasNext(); ) {
        MethodNode m = (MethodNode) methodsIterator.next();
        abstractMethods.remove(m.getTypeDescriptor());
        if (m.isStatic() || !(m.isPublic() || m.isProtected())) {
            methodsIterator.remove();
        }
        MethodNode intfMethod = allInterfaceMethods.get(m.getTypeDescriptor());
        if (intfMethod != null && ((m.getModifiers() & ACC_SYNTHETIC) == 0) && !m.isPublic() && !m.isStaticConstructor()) {
            throw new RuntimeParserException("The method " + m.getName() + " should be public as it implements the corresponding method from interface " + intfMethod.getDeclaringClass(), m);
        }
    }
    addCovariantMethods(classNode, declaredMethods, abstractMethods, methodsToAdd, genericsSpec);
    Map<String, MethodNode> declaredMethodsMap = new HashMap<String, MethodNode>();
    if (methodsToAdd.size() > 0) {
        for (MethodNode mn : declaredMethods) {
            declaredMethodsMap.put(mn.getTypeDescriptor(), mn);
        }
    }
    for (Object o : methodsToAdd.entrySet()) {
        Map.Entry entry = (Map.Entry) o;
        MethodNode method = (MethodNode) entry.getValue();
        // we skip bridge methods implemented in current class already
        MethodNode mn = declaredMethodsMap.get(entry.getKey());
        if (mn != null && mn.getDeclaringClass().equals(classNode))
            continue;
        addPropertyMethod(method);
    }
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Iterator(java.util.Iterator) GroovyObject(groovy.lang.GroovyObject) RuntimeParserException(org.codehaus.groovy.syntax.RuntimeParserException) HashMap(java.util.HashMap) Map(java.util.Map)

Example 9 with RuntimeParserException

use of org.codehaus.groovy.syntax.RuntimeParserException in project groovy-core by groovy.

the class Verifier method checkReturnInObjectInitializer.

private void checkReturnInObjectInitializer(List init) {
    CodeVisitorSupport cvs = new CodeVisitorSupport() {

        @Override
        public void visitClosureExpression(ClosureExpression expression) {
        // return is OK in closures in object initializers
        }

        public void visitReturnStatement(ReturnStatement statement) {
            throw new RuntimeParserException("'return' is not allowed in object initializer", statement);
        }
    };
    for (Iterator iterator = init.iterator(); iterator.hasNext(); ) {
        Statement stm = (Statement) iterator.next();
        stm.visit(cvs);
    }
}
Also used : Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) Iterator(java.util.Iterator) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) RuntimeParserException(org.codehaus.groovy.syntax.RuntimeParserException)

Example 10 with RuntimeParserException

use of org.codehaus.groovy.syntax.RuntimeParserException in project groovy-core by groovy.

the class Verifier method getCovariantImplementation.

private MethodNode getCovariantImplementation(final MethodNode oldMethod, final MethodNode overridingMethod, Map genericsSpec) {
    // method name
    if (!oldMethod.getName().equals(overridingMethod.getName()))
        return null;
    if ((overridingMethod.getModifiers() & ACC_BRIDGE) != 0)
        return null;
    if (oldMethod.isPrivate())
        return null;
    // parameters
    boolean normalEqualParameters = equalParametersNormal(overridingMethod, oldMethod);
    boolean genericEqualParameters = equalParametersWithGenerics(overridingMethod, oldMethod, genericsSpec);
    if (!normalEqualParameters && !genericEqualParameters)
        return null;
    //correct to method level generics for the overriding method
    genericsSpec = GenericsUtils.addMethodGenerics(overridingMethod, genericsSpec);
    // return type
    ClassNode mr = overridingMethod.getReturnType();
    ClassNode omr = oldMethod.getReturnType();
    boolean equalReturnType = mr.equals(omr);
    ClassNode testmr = correctToGenericsSpec(genericsSpec, omr);
    if (!isAssignable(mr, testmr)) {
        throw new RuntimeParserException("The return type of " + overridingMethod.getTypeDescriptor() + " in " + overridingMethod.getDeclaringClass().getName() + " is incompatible with " + testmr.getName() + " in " + oldMethod.getDeclaringClass().getName(), overridingMethod);
    }
    if (equalReturnType && normalEqualParameters)
        return null;
    if ((oldMethod.getModifiers() & ACC_FINAL) != 0) {
        throw new RuntimeParserException("Cannot override final method " + oldMethod.getTypeDescriptor() + " in " + oldMethod.getDeclaringClass().getName(), overridingMethod);
    }
    if (oldMethod.isStatic() != overridingMethod.isStatic()) {
        throw new RuntimeParserException("Cannot override method " + oldMethod.getTypeDescriptor() + " in " + oldMethod.getDeclaringClass().getName() + " with disparate static modifier", overridingMethod);
    }
    if (!equalReturnType) {
        boolean oldM = ClassHelper.isPrimitiveType(oldMethod.getReturnType());
        boolean newM = ClassHelper.isPrimitiveType(overridingMethod.getReturnType());
        if (oldM || newM) {
            String message = "";
            if (oldM && newM) {
                message = " with old and new method having different primitive return types";
            } else if (newM) {
                message = " with new method having a primitive return type and old method not";
            } else /* oldM */
            {
                message = " with old method having a primitive return type and new method not";
            }
            throw new RuntimeParserException("Cannot override method " + oldMethod.getTypeDescriptor() + " in " + oldMethod.getDeclaringClass().getName() + message, overridingMethod);
        }
    }
    // if we reach this point we have at least one parameter or return type, that
    // is different in its specified form. That means we have to create a bridge method!
    MethodNode newMethod = new MethodNode(oldMethod.getName(), overridingMethod.getModifiers() | ACC_SYNTHETIC | ACC_BRIDGE, oldMethod.getReturnType().getPlainNodeReference(), cleanParameters(oldMethod.getParameters()), oldMethod.getExceptions(), null);
    List instructions = new ArrayList(1);
    instructions.add(new BytecodeInstruction() {

        public void visit(MethodVisitor mv) {
            mv.visitVarInsn(ALOAD, 0);
            Parameter[] para = oldMethod.getParameters();
            Parameter[] goal = overridingMethod.getParameters();
            int doubleSlotOffset = 0;
            for (int i = 0; i < para.length; i++) {
                ClassNode type = para[i].getType();
                BytecodeHelper.load(mv, type, i + 1 + doubleSlotOffset);
                if (type.redirect() == ClassHelper.double_TYPE || type.redirect() == ClassHelper.long_TYPE) {
                    doubleSlotOffset++;
                }
                if (!type.equals(goal[i].getType())) {
                    BytecodeHelper.doCast(mv, goal[i].getType());
                }
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, BytecodeHelper.getClassInternalName(classNode), overridingMethod.getName(), BytecodeHelper.getMethodDescriptor(overridingMethod.getReturnType(), overridingMethod.getParameters()), false);
            BytecodeHelper.doReturn(mv, oldMethod.getReturnType());
        }
    });
    newMethod.setCode(new BytecodeSequence(instructions));
    return newMethod;
}
Also used : ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) RuntimeParserException(org.codehaus.groovy.syntax.RuntimeParserException) MethodVisitor(org.objectweb.asm.MethodVisitor)

Aggregations

RuntimeParserException (org.codehaus.groovy.syntax.RuntimeParserException)13 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)7 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)7 ReturnStatement (org.codehaus.groovy.ast.stmt.ReturnStatement)7 ArrayList (java.util.ArrayList)6 Statement (org.codehaus.groovy.ast.stmt.Statement)5 List (java.util.List)4 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)4 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)4 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)4 Iterator (java.util.Iterator)3 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)3 GroovyObject (groovy.lang.GroovyObject)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 ASTNode (org.codehaus.groovy.ast.ASTNode)2 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)2 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)2 CastExpression (org.codehaus.groovy.ast.expr.CastExpression)2 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)2