Search in sources :

Example 1 with RuntimeParserException

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

the class Verifier method getCovariantImplementation.

private MethodNode getCovariantImplementation(final MethodNode oldMethod, final MethodNode overridingMethod, Map genericsSpec, boolean ignoreError) {
    // 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)) {
        if (ignoreError)
            return null;
        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) List(java.util.List) ArrayList(java.util.ArrayList) RuntimeParserException(org.codehaus.groovy.syntax.RuntimeParserException) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 2 with RuntimeParserException

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

the class Verifier method visitMethod.

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);
    }
    this.methodNode = node;
    adjustTypesIfStaticMainMethod(node);
    addReturnIfNeeded(node);
    Statement statement;
    statement = node.getCode();
    if (statement != null)
        statement.visit(new VerifierCodeVisitor(this));
}
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) RuntimeParserException(org.codehaus.groovy.syntax.RuntimeParserException)

Example 3 with RuntimeParserException

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

the class Verifier method addDefaultParameterMethods.

/**
 * Creates a new helper method for each combination of default parameter expressions
 */
protected void addDefaultParameterMethods(final ClassNode node) {
    List methods = new ArrayList(node.getMethods());
    addDefaultParameters(methods, new DefaultArgsAction() {

        public void call(ArgumentListExpression arguments, Parameter[] newParams, MethodNode method) {
            final BlockStatement code = new BlockStatement();
            MethodNode newMethod = new MethodNode(method.getName(), method.getModifiers(), method.getReturnType(), newParams, method.getExceptions(), code);
            // GROOVY-5681 and GROOVY-5632
            for (Expression argument : arguments.getExpressions()) {
                if (argument instanceof CastExpression) {
                    argument = ((CastExpression) argument).getExpression();
                }
                if (argument instanceof ConstructorCallExpression) {
                    ClassNode type = argument.getType();
                    if (type instanceof InnerClassNode && ((InnerClassNode) type).isAnonymous()) {
                        type.setEnclosingMethod(newMethod);
                    }
                }
                // check whether closure shared variables refer to params with default values (GROOVY-5632)
                if (argument instanceof ClosureExpression) {
                    final List<Parameter> newMethodNodeParameters = Arrays.asList(newParams);
                    CodeVisitorSupport visitor = new CodeVisitorSupport() {

                        @Override
                        public void visitVariableExpression(VariableExpression expression) {
                            Variable v = expression.getAccessedVariable();
                            if (!(v instanceof Parameter))
                                return;
                            Parameter param = (Parameter) v;
                            if (param.hasInitialExpression() && code.getVariableScope().getDeclaredVariable(param.getName()) == null && !newMethodNodeParameters.contains(param)) {
                                VariableExpression localVariable = new VariableExpression(param.getName(), ClassHelper.makeReference());
                                DeclarationExpression declarationExpression = new DeclarationExpression(localVariable, Token.newSymbol(Types.EQUAL, -1, -1), new ConstructorCallExpression(ClassHelper.makeReference(), param.getInitialExpression()));
                                code.addStatement(new ExpressionStatement(declarationExpression));
                                code.getVariableScope().putDeclaredVariable(localVariable);
                            }
                        }
                    };
                    visitor.visitClosureExpression((ClosureExpression) argument);
                }
            }
            MethodCallExpression expression = new MethodCallExpression(VariableExpression.THIS_EXPRESSION, method.getName(), arguments);
            expression.setMethodTarget(method);
            expression.setImplicitThis(true);
            if (method.isVoidMethod()) {
                code.addStatement(new ExpressionStatement(expression));
            } else {
                code.addStatement(new ReturnStatement(expression));
            }
            List<AnnotationNode> annotations = method.getAnnotations();
            if (annotations != null) {
                newMethod.addAnnotations(annotations);
            }
            MethodNode oldMethod = node.getDeclaredMethod(method.getName(), newParams);
            if (oldMethod != null) {
                throw new RuntimeParserException("The method with default parameters \"" + method.getTypeDescriptor() + "\" defines a method \"" + newMethod.getTypeDescriptor() + "\" that is already defined.", method);
            }
            addPropertyMethod(newMethod);
            newMethod.setGenericsTypes(method.getGenericsTypes());
        }
    });
}
Also used : ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ArrayList(java.util.ArrayList) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) ArrayList(java.util.ArrayList) List(java.util.List) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) RuntimeParserException(org.codehaus.groovy.syntax.RuntimeParserException)

Example 4 with RuntimeParserException

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

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 5 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)

Aggregations

RuntimeParserException (org.codehaus.groovy.syntax.RuntimeParserException)20 ArrayList (java.util.ArrayList)8 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)8 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)8 ReturnStatement (org.codehaus.groovy.ast.stmt.ReturnStatement)8 Statement (org.codehaus.groovy.ast.stmt.Statement)6 ClassNode (org.codehaus.groovy.ast.ClassNode)5 MethodNode (org.codehaus.groovy.ast.MethodNode)5 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)5 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)5 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)5 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)5 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)4 Parameter (org.codehaus.groovy.ast.Parameter)4 List (java.util.List)3 ASTNode (org.codehaus.groovy.ast.ASTNode)3 CodeVisitorSupport (org.codehaus.groovy.ast.CodeVisitorSupport)3 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)3 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)3 CastExpression (org.codehaus.groovy.ast.expr.CastExpression)3