Search in sources :

Example 51 with SyntaxException

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

the class BindableASTTransformation method addListenerToProperty.

private void addListenerToProperty(SourceUnit source, AnnotationNode node, ClassNode declaringClass, FieldNode field) {
    String fieldName = field.getName();
    for (PropertyNode propertyNode : declaringClass.getProperties()) {
        if (propertyNode.getName().equals(fieldName)) {
            if (field.isStatic()) {
                // noinspection ThrowableInstanceNeverThrown
                source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage(new SyntaxException("@groovy.beans.Bindable cannot annotate a static property.", node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()), source));
            } else {
                if (needsPropertyChangeSupport(declaringClass, source)) {
                    addPropertyChangeSupport(declaringClass);
                }
                createListenerSetter(declaringClass, propertyNode);
            }
            return;
        }
    }
    // noinspection ThrowableInstanceNeverThrown
    source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage(new SyntaxException("@groovy.beans.Bindable must be on a property, not a field.  Try removing the private, protected, or public modifier.", node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()), source));
}
Also used : SyntaxErrorMessage(org.codehaus.groovy.control.messages.SyntaxErrorMessage) PropertyNode(org.codehaus.groovy.ast.PropertyNode) SyntaxException(org.codehaus.groovy.syntax.SyntaxException)

Example 52 with SyntaxException

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

the class BinaryExpressionHelper method eval.

public void eval(BinaryExpression expression) {
    switch(expression.getOperation().getType()) {
        case // = assignment
        EQUAL:
            evaluateEqual(expression, false);
            break;
        case // ==
        COMPARE_EQUAL:
            evaluateCompareExpression(compareEqualMethod, expression);
            break;
        case COMPARE_NOT_EQUAL:
            evaluateCompareExpression(compareNotEqualMethod, expression);
            break;
        case COMPARE_TO:
            evaluateCompareTo(expression);
            break;
        case COMPARE_GREATER_THAN:
            evaluateCompareExpression(compareGreaterThanMethod, expression);
            break;
        case COMPARE_GREATER_THAN_EQUAL:
            evaluateCompareExpression(compareGreaterThanEqualMethod, expression);
            break;
        case COMPARE_LESS_THAN:
            evaluateCompareExpression(compareLessThanMethod, expression);
            break;
        case COMPARE_LESS_THAN_EQUAL:
            evaluateCompareExpression(compareLessThanEqualMethod, expression);
            break;
        case LOGICAL_AND:
            evaluateLogicalAndExpression(expression);
            break;
        case LOGICAL_OR:
            evaluateLogicalOrExpression(expression);
            break;
        case BITWISE_AND:
            evaluateBinaryExpression("and", expression);
            break;
        case BITWISE_AND_EQUAL:
            evaluateBinaryExpressionWithAssignment("and", expression);
            break;
        case BITWISE_OR:
            evaluateBinaryExpression("or", expression);
            break;
        case BITWISE_OR_EQUAL:
            evaluateBinaryExpressionWithAssignment("or", expression);
            break;
        case BITWISE_XOR:
            evaluateBinaryExpression("xor", expression);
            break;
        case BITWISE_XOR_EQUAL:
            evaluateBinaryExpressionWithAssignment("xor", expression);
            break;
        case PLUS:
            evaluateBinaryExpression("plus", expression);
            break;
        case PLUS_EQUAL:
            evaluateBinaryExpressionWithAssignment("plus", expression);
            break;
        case MINUS:
            evaluateBinaryExpression("minus", expression);
            break;
        case MINUS_EQUAL:
            evaluateBinaryExpressionWithAssignment("minus", expression);
            break;
        case MULTIPLY:
            evaluateBinaryExpression("multiply", expression);
            break;
        case MULTIPLY_EQUAL:
            evaluateBinaryExpressionWithAssignment("multiply", expression);
            break;
        case DIVIDE:
            evaluateBinaryExpression("div", expression);
            break;
        case DIVIDE_EQUAL:
            // SPG don't use divide since BigInteger implements directly
            // and we want to dispatch through DefaultGroovyMethods to get a BigDecimal result
            evaluateBinaryExpressionWithAssignment("div", expression);
            break;
        case INTDIV:
            evaluateBinaryExpression("intdiv", expression);
            break;
        case INTDIV_EQUAL:
            evaluateBinaryExpressionWithAssignment("intdiv", expression);
            break;
        case MOD:
            evaluateBinaryExpression("mod", expression);
            break;
        case MOD_EQUAL:
            evaluateBinaryExpressionWithAssignment("mod", expression);
            break;
        case POWER:
            evaluateBinaryExpression("power", expression);
            break;
        case POWER_EQUAL:
            evaluateBinaryExpressionWithAssignment("power", expression);
            break;
        case LEFT_SHIFT:
            evaluateBinaryExpression("leftShift", expression);
            break;
        case LEFT_SHIFT_EQUAL:
            evaluateBinaryExpressionWithAssignment("leftShift", expression);
            break;
        case RIGHT_SHIFT:
            evaluateBinaryExpression("rightShift", expression);
            break;
        case RIGHT_SHIFT_EQUAL:
            evaluateBinaryExpressionWithAssignment("rightShift", expression);
            break;
        case RIGHT_SHIFT_UNSIGNED:
            evaluateBinaryExpression("rightShiftUnsigned", expression);
            break;
        case RIGHT_SHIFT_UNSIGNED_EQUAL:
            evaluateBinaryExpressionWithAssignment("rightShiftUnsigned", expression);
            break;
        case KEYWORD_INSTANCEOF:
            evaluateInstanceof(expression);
            break;
        case FIND_REGEX:
            evaluateCompareExpression(findRegexMethod, expression);
            break;
        case MATCH_REGEX:
            evaluateCompareExpression(matchRegexMethod, expression);
            break;
        case LEFT_SQUARE_BRACKET:
            if (controller.getCompileStack().isLHS()) {
                evaluateEqual(expression, false);
            } else {
                evaluateBinaryExpression("getAt", expression);
            }
            break;
        case KEYWORD_IN:
            evaluateCompareExpression(isCaseMethod, expression);
            break;
        case COMPARE_IDENTICAL:
        case COMPARE_NOT_IDENTICAL:
            Token op = expression.getOperation();
            Throwable cause = new SyntaxException("Operator " + op + " not supported", op.getStartLine(), op.getStartColumn(), op.getStartLine(), op.getStartColumn() + 3);
            throw new GroovyRuntimeException(cause);
        default:
            throw new GroovyBugError("Operation: " + expression.getOperation() + " not supported");
    }
}
Also used : SyntaxException(org.codehaus.groovy.syntax.SyntaxException) GroovyRuntimeException(groovy.lang.GroovyRuntimeException) GroovyBugError(org.codehaus.groovy.GroovyBugError) Token(org.codehaus.groovy.syntax.Token)

Example 53 with SyntaxException

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

the class InvocationWriter method makeMOPBasedConstructorCall.

private void makeMOPBasedConstructorCall(List<ConstructorNode> constructors, ConstructorCallExpression call, ClassNode callNode) {
    MethodVisitor mv = controller.getMethodVisitor();
    OperandStack operandStack = controller.getOperandStack();
    call.getArguments().visit(controller.getAcg());
    // keep Object[] on stack
    mv.visitInsn(DUP);
    // to select the constructor we need also the number of
    // available constructors and the class we want to make
    // the call on
    BytecodeHelper.pushConstant(mv, -1);
    controller.getAcg().visitClassExpression(new ClassExpression(callNode));
    operandStack.remove(1);
    // removes one Object[] leaves the int containing the
    // call flags and the constructor number
    selectConstructorAndTransformArguments.call(mv);
    // load "this"
    if (controller.isConstructor()) {
        mv.visitVarInsn(ALOAD, 0);
    } else {
        mv.visitTypeInsn(NEW, BytecodeHelper.getClassInternalName(callNode));
    }
    mv.visitInsn(SWAP);
    TreeMap<Integer, ConstructorNode> sortedConstructors = new TreeMap<Integer, ConstructorNode>();
    for (ConstructorNode constructor : constructors) {
        String typeDescriptor = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, constructor.getParameters());
        int hash = BytecodeHelper.hashCode(typeDescriptor);
        ConstructorNode sameHashNode = sortedConstructors.put(hash, constructor);
        if (sameHashNode != null) {
            controller.getSourceUnit().addError(new SyntaxException("Unable to compile class " + controller.getClassNode().getName() + " due to hash collision in constructors", call.getLineNumber(), call.getColumnNumber()));
        }
    }
    Label[] targets = new Label[constructors.size()];
    int[] indices = new int[constructors.size()];
    Iterator<Integer> hashIt = sortedConstructors.keySet().iterator();
    Iterator<ConstructorNode> constructorIt = sortedConstructors.values().iterator();
    for (int i = 0; i < targets.length; i++) {
        targets[i] = new Label();
        indices[i] = hashIt.next();
    }
    // create switch targets
    Label defaultLabel = new Label();
    Label afterSwitch = new Label();
    mv.visitLookupSwitchInsn(defaultLabel, indices, targets);
    for (int i = 0; i < targets.length; i++) {
        mv.visitLabel(targets[i]);
        // to extract the parameters.
        if (controller.isConstructor()) {
            // in this case we need one "this", so a SWAP will exchange
            // "this" and Object[], a DUP_X1 will then copy the Object[]
            // / to the last place in the stack:
            // Object[],this -SWAP-> this,Object[]
            // this,Object[] -DUP_X1-> Object[],this,Object[]
            mv.visitInsn(SWAP);
            mv.visitInsn(DUP_X1);
        } else {
            // in this case we need two "this" in between and the Object[]
            // at the bottom of the stack as well as on top for our invokeSpecial
            // So we do DUP_X1, DUP2_X1, POP
            // Object[],this -DUP_X1-> this,Object[],this
            // this,Object[],this -DUP2_X1-> Object[],this,this,Object[],this
            // Object[],this,this,Object[],this -POP->  Object[],this,this,Object[]
            mv.visitInsn(DUP_X1);
            mv.visitInsn(DUP2_X1);
            mv.visitInsn(POP);
        }
        ConstructorNode cn = constructorIt.next();
        String descriptor = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, cn.getParameters());
        // unwrap the Object[] and make transformations if needed
        // that means, to duplicate the Object[], make a cast with possible
        // unboxing and then swap it with the Object[] for each parameter
        // vargs need special attention and transformation though
        Parameter[] parameters = cn.getParameters();
        int lengthWithoutVargs = parameters.length;
        if (parameters.length > 0 && parameters[parameters.length - 1].getType().isArray()) {
            lengthWithoutVargs--;
        }
        for (int p = 0; p < lengthWithoutVargs; p++) {
            loadAndCastElement(operandStack, mv, parameters, p);
        }
        if (parameters.length > lengthWithoutVargs) {
            ClassNode type = parameters[lengthWithoutVargs].getType();
            BytecodeHelper.pushConstant(mv, lengthWithoutVargs);
            controller.getAcg().visitClassExpression(new ClassExpression(type));
            operandStack.remove(1);
            castToVargsArray.call(mv);
            BytecodeHelper.doCast(mv, type);
        } else {
            // at the end we remove the Object[]
            // the vargs case simply the last swap so no pop is needed
            mv.visitInsn(POP);
        }
        // make the constructor call
        mv.visitMethodInsn(INVOKESPECIAL, BytecodeHelper.getClassInternalName(callNode), "<init>", descriptor, false);
        mv.visitJumpInsn(GOTO, afterSwitch);
    }
    mv.visitLabel(defaultLabel);
    // this part should never be reached!
    mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException");
    mv.visitInsn(DUP);
    mv.visitLdcInsn("This class has been compiled with a super class which is binary incompatible with the current super class found on classpath. You should recompile this class with the new version.");
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V", false);
    mv.visitInsn(ATHROW);
    mv.visitLabel(afterSwitch);
    // result on the stack, which we can remove now if inside a constructor.
    if (!controller.isConstructor()) {
        // in case we are not in a constructor we have an additional
        // object on the stack, the result of our constructor call
        // which we want to keep, so we swap with the dummy object and
        // do normal removal of it. In the end, the call result will be
        // on the stack then
        mv.visitInsn(SWAP);
        // for call result
        operandStack.push(callNode);
    }
    mv.visitInsn(POP);
}
Also used : Label(org.objectweb.asm.Label) TreeMap(java.util.TreeMap) MethodVisitor(org.objectweb.asm.MethodVisitor) SyntaxException(org.codehaus.groovy.syntax.SyntaxException)

Example 54 with SyntaxException

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

the class NAryOperationRewriter method transformPostfixExpression.

private Expression transformPostfixExpression(final PostfixExpression exp) {
    if (isInternalFieldAccess(exp.getExpression())) {
        Token operation = exp.getOperation();
        sourceUnit.addError(new SyntaxException("Postfix expressions on trait fields/properties  are not supported in traits.", operation.getStartLine(), operation.getStartColumn()));
        return exp;
    } else {
        return super.transform(exp);
    }
}
Also used : SyntaxException(org.codehaus.groovy.syntax.SyntaxException) Token(org.codehaus.groovy.syntax.Token)

Example 55 with SyntaxException

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

the class TraitASTTransformation method createHelperClass.

private void createHelperClass(final ClassNode cNode) {
    ClassNode helper = new InnerClassNode(cNode, Traits.helperClassName(cNode), ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_SYNTHETIC, ClassHelper.OBJECT_TYPE, ClassNode.EMPTY_ARRAY, null);
    cNode.setModifiers(ACC_PUBLIC | ACC_INTERFACE | ACC_ABSTRACT);
    checkInnerClasses(cNode);
    MethodNode initializer = createInitMethod(false, cNode, helper);
    MethodNode staticInitializer = createInitMethod(true, cNode, helper);
    // apply the verifier to have the property nodes generated
    generatePropertyMethods(cNode);
    // prepare fields
    List<FieldNode> fields = new ArrayList<FieldNode>();
    Set<String> fieldNames = new HashSet<String>();
    for (FieldNode field : cNode.getFields()) {
        if (!"metaClass".equals(field.getName()) && (!field.isSynthetic() || field.getName().indexOf('$') < 0)) {
            fields.add(field);
            fieldNames.add(field.getName());
        }
    }
    ClassNode fieldHelper = null;
    if (!fields.isEmpty()) {
        fieldHelper = new InnerClassNode(cNode, Traits.fieldHelperClassName(cNode), ACC_STATIC | ACC_PUBLIC | ACC_INTERFACE | ACC_ABSTRACT, ClassHelper.OBJECT_TYPE);
    }
    // add methods
    List<MethodNode> methods = new ArrayList<MethodNode>(cNode.getMethods());
    List<MethodNode> nonPublicAPIMethods = new LinkedList<MethodNode>();
    for (final MethodNode methodNode : methods) {
        boolean declared = methodNode.getDeclaringClass() == cNode;
        if (declared) {
            if (!methodNode.isSynthetic() && (methodNode.isProtected() || methodNode.getModifiers() == 0)) {
                unit.addError(new SyntaxException("Cannot have protected/package private method in a trait (" + cNode.getName() + "#" + methodNode.getTypeDescriptor() + ")", methodNode.getLineNumber(), methodNode.getColumnNumber()));
                return;
            }
            helper.addMethod(processMethod(cNode, methodNode, fieldHelper, fieldNames));
            if (methodNode.isPrivate() || methodNode.isStatic()) {
                nonPublicAPIMethods.add(methodNode);
            }
        }
    }
    // remove methods which should not appear in the trait interface
    for (MethodNode privateMethod : nonPublicAPIMethods) {
        cNode.removeMethod(privateMethod);
    }
    // add fields
    for (FieldNode field : fields) {
        processField(field, initializer, staticInitializer, fieldHelper, cNode, fieldNames);
    }
    // clear properties to avoid generation of methods
    cNode.getProperties().clear();
    // copy annotations
    copyClassAnnotations(cNode, helper);
    // reuse the full list of fields
    fields = new ArrayList<FieldNode>(cNode.getFields());
    for (FieldNode field : fields) {
        cNode.removeField(field.getName());
    }
    // visit AST xforms
    registerASTTranformations(helper);
    unit.getAST().addClass(helper);
    if (fieldHelper != null) {
        unit.getAST().addClass(fieldHelper);
    }
    // resolve scope (for closures)
    resolveScope(helper);
    if (fieldHelper != null) {
        resolveScope(fieldHelper);
    }
}
Also used : InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) ArrayList(java.util.ArrayList) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) LinkedList(java.util.LinkedList) MethodNode(org.codehaus.groovy.ast.MethodNode) SyntaxException(org.codehaus.groovy.syntax.SyntaxException) HashSet(java.util.HashSet)

Aggregations

SyntaxException (org.codehaus.groovy.syntax.SyntaxException)56 SyntaxErrorMessage (org.codehaus.groovy.control.messages.SyntaxErrorMessage)19 ClassNode (org.codehaus.groovy.ast.ClassNode)15 Expression (org.codehaus.groovy.ast.expr.Expression)12 MethodNode (org.codehaus.groovy.ast.MethodNode)11 SourceUnit (org.codehaus.groovy.control.SourceUnit)10 AnnotationNode (org.codehaus.groovy.ast.AnnotationNode)8 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)8 FieldNode (org.codehaus.groovy.ast.FieldNode)7 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)7 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)7 ArrayList (java.util.ArrayList)6 Parameter (org.codehaus.groovy.ast.Parameter)6 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)6 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)6 Token (org.codehaus.groovy.syntax.Token)6 LinkedList (java.util.LinkedList)5 PropertyNode (org.codehaus.groovy.ast.PropertyNode)5 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)5 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)5