Search in sources :

Example 16 with CastExpression

use of org.codehaus.groovy.ast.expr.CastExpression in project groovy-core by groovy.

the class CastExpressionOptimizer method transformCastExpression.

public Expression transformCastExpression(final CastExpression cast) {
    if (cast.isCoerce()) {
        Expression expression = cast.getExpression();
        ClassNode exprInferredType = transformer.getTypeChooser().resolveType(expression, transformer.getClassNode());
        ClassNode castType = cast.getType();
        if (castType.isArray() && expression instanceof ListExpression) {
            ArrayExpression arrayExpression = new ArrayExpression(castType.getComponentType(), ((ListExpression) expression).getExpressions());
            arrayExpression.setSourcePosition(cast);
            return transformer.transform(arrayExpression);
        }
        if (isOptimizable(exprInferredType, castType)) {
            // coerce is not needed
            CastExpression trn = new CastExpression(castType, transformer.transform(expression));
            trn.setSourcePosition(cast);
            trn.copyNodeMetaData(cast);
            return trn;
        }
    } else if (ClassHelper.char_TYPE.equals(cast.getType())) {
        Expression expression = cast.getExpression();
        if (expression instanceof ConstantExpression) {
            ConstantExpression ce = (ConstantExpression) expression;
            if (ClassHelper.STRING_TYPE.equals(ce.getType())) {
                String val = (String) ce.getValue();
                if (val != null && val.length() == 1) {
                    ConstantExpression result = new ConstantExpression(val.charAt(0), true);
                    result.setSourcePosition(cast);
                    return result;
                }
            }
        }
    }
    return transformer.superTransform(cast);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression)

Example 17 with CastExpression

use of org.codehaus.groovy.ast.expr.CastExpression in project groovy-core by groovy.

the class EqualsAndHashCodeASTTransformation method createEquals.

public static void createEquals(ClassNode cNode, boolean includeFields, boolean callSuper, boolean useCanEqual, List<String> excludes, List<String> includes) {
    if (useCanEqual)
        createCanEqual(cNode);
    // make a public method if none exists otherwise try a private method with leading underscore
    boolean hasExistingEquals = hasDeclaredMethod(cNode, "equals", 1);
    if (hasExistingEquals && hasDeclaredMethod(cNode, "_equals", 1))
        return;
    final BlockStatement body = new BlockStatement();
    VariableExpression other = varX("other");
    // some short circuit cases for efficiency
    body.addStatement(ifS(equalsNullX(other), returnS(constX(Boolean.FALSE, true))));
    body.addStatement(ifS(sameX(varX("this"), other), returnS(constX(Boolean.TRUE, true))));
    if (useCanEqual) {
        body.addStatement(ifS(notX(isInstanceOfX(other, GenericsUtils.nonGeneric(cNode))), returnS(constX(Boolean.FALSE, true))));
    } else {
        body.addStatement(ifS(notX(hasClassX(other, GenericsUtils.nonGeneric(cNode))), returnS(constX(Boolean.FALSE, true))));
    }
    VariableExpression otherTyped = varX("otherTyped", GenericsUtils.nonGeneric(cNode));
    CastExpression castExpression = new CastExpression(GenericsUtils.nonGeneric(cNode), other);
    castExpression.setStrict(true);
    body.addStatement(declS(otherTyped, castExpression));
    if (useCanEqual) {
        body.addStatement(ifS(notX(callX(otherTyped, "canEqual", varX("this"))), returnS(constX(Boolean.FALSE, true))));
    }
    List<PropertyNode> pList = getInstanceProperties(cNode);
    for (PropertyNode pNode : pList) {
        if (shouldSkip(pNode.getName(), excludes, includes))
            continue;
        boolean canBeSelf = StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(pNode.getOriginType(), cNode);
        if (!canBeSelf) {
            body.addStatement(ifS(notX(hasEqualPropertyX(pNode, otherTyped)), returnS(constX(Boolean.FALSE, true))));
        } else {
            body.addStatement(ifS(notX(hasSamePropertyX(pNode, otherTyped)), ifElseS(differentSelfRecursivePropertyX(pNode, otherTyped), returnS(constX(Boolean.FALSE, true)), ifS(notX(bothSelfRecursivePropertyX(pNode, otherTyped)), ifS(notX(hasEqualPropertyX(pNode, otherTyped)), returnS(constX(Boolean.FALSE, true)))))));
        }
    }
    List<FieldNode> fList = new ArrayList<FieldNode>();
    if (includeFields) {
        fList.addAll(getInstanceNonPropertyFields(cNode));
    }
    for (FieldNode fNode : fList) {
        if (shouldSkip(fNode.getName(), excludes, includes))
            continue;
        body.addStatement(ifS(notX(hasSameFieldX(fNode, otherTyped)), ifElseS(differentSelfRecursiveFieldX(fNode, otherTyped), returnS(constX(Boolean.FALSE, true)), ifS(notX(bothSelfRecursiveFieldX(fNode, otherTyped)), ifS(notX(hasEqualFieldX(fNode, otherTyped)), returnS(constX(Boolean.FALSE, true)))))));
    }
    if (callSuper) {
        body.addStatement(ifS(notX(isTrueX(callSuperX("equals", other))), returnS(constX(Boolean.FALSE, true))));
    }
    // default
    body.addStatement(returnS(constX(Boolean.TRUE, true)));
    cNode.addMethod(new MethodNode(hasExistingEquals ? "_equals" : "equals", hasExistingEquals ? ACC_PRIVATE : ACC_PUBLIC, ClassHelper.boolean_TYPE, params(param(OBJECT_TYPE, other.getName())), ClassNode.EMPTY_ARRAY, body));
}
Also used : FieldNode(org.codehaus.groovy.ast.FieldNode) MethodNode(org.codehaus.groovy.ast.MethodNode) PropertyNode(org.codehaus.groovy.ast.PropertyNode) ArrayList(java.util.ArrayList) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression)

Example 18 with CastExpression

use of org.codehaus.groovy.ast.expr.CastExpression in project groovy-core by groovy.

the class TraitComposer method createSuperFallback.

private static Statement createSuperFallback(MethodNode forwarderMethod, ClassNode returnType) {
    ArgumentListExpression args = new ArgumentListExpression();
    Parameter[] forwarderMethodParameters = forwarderMethod.getParameters();
    for (final Parameter forwarderMethodParameter : forwarderMethodParameters) {
        args.addExpression(new VariableExpression(forwarderMethodParameter));
    }
    BinaryExpression instanceOfExpr = new BinaryExpression(new VariableExpression("this"), Token.newSymbol(Types.KEYWORD_INSTANCEOF, -1, -1), new ClassExpression(Traits.GENERATED_PROXY_CLASSNODE));
    MethodCallExpression superCall = new MethodCallExpression(new VariableExpression("super"), forwarderMethod.getName(), args);
    superCall.setImplicitThis(false);
    CastExpression proxyReceiver = new CastExpression(Traits.GENERATED_PROXY_CLASSNODE, new VariableExpression("this"));
    MethodCallExpression getProxy = new MethodCallExpression(proxyReceiver, "getProxyTarget", ArgumentListExpression.EMPTY_ARGUMENTS);
    getProxy.setImplicitThis(true);
    StaticMethodCallExpression proxyCall = new StaticMethodCallExpression(ClassHelper.make(InvokerHelper.class), "invokeMethod", new ArgumentListExpression(getProxy, new ConstantExpression(forwarderMethod.getName()), new ArrayExpression(ClassHelper.OBJECT_TYPE, args.getExpressions())));
    IfStatement stmt = new IfStatement(new BooleanExpression(instanceOfExpr), new ExpressionStatement(new CastExpression(returnType, proxyCall)), new ExpressionStatement(superCall));
    return stmt;
}
Also used : InvokerHelper(org.codehaus.groovy.runtime.InvokerHelper) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) Parameter(org.codehaus.groovy.ast.Parameter) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression)

Example 19 with CastExpression

use of org.codehaus.groovy.ast.expr.CastExpression in project groovy by apache.

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());
            newMethod.putNodeMetaData(DEFAULT_PARAMETER_GENERATED, true);
        }
    });
}
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) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) List(java.util.List) ArrayList(java.util.ArrayList) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) RuntimeParserException(org.codehaus.groovy.syntax.RuntimeParserException)

Example 20 with CastExpression

use of org.codehaus.groovy.ast.expr.CastExpression in project groovy by apache.

the class TraitASTTransformation method processField.

private void processField(final FieldNode field, final MethodNode initializer, final MethodNode staticInitializer, final ClassNode fieldHelper, final ClassNode helper, final ClassNode trait, final Set<String> knownFields) {
    if (field.isProtected()) {
        unit.addError(new SyntaxException("Cannot have protected field in a trait (" + trait.getName() + "#" + field.getName() + ")", field.getLineNumber(), field.getColumnNumber()));
        return;
    }
    Expression initialExpression = field.getInitialExpression();
    MethodNode selectedMethod = field.isStatic() ? staticInitializer : initializer;
    if (initialExpression != null) {
        if (field.isFinal()) {
            String baseName = field.isStatic() ? Traits.STATIC_INIT_METHOD : Traits.INIT_METHOD;
            MethodNode fieldInitializer = new MethodNode(baseName + Traits.remappedFieldName(trait, field.getName()), ACC_STATIC | ACC_PUBLIC | ACC_SYNTHETIC, field.getOriginType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, returnS(initialExpression));
            helper.addMethod(fieldInitializer);
        }
        VariableExpression thisObject = new VariableExpression(selectedMethod.getParameters()[0]);
        ExpressionStatement initCode = new ExpressionStatement(initialExpression);
        processBody(thisObject, initCode, trait, helper, fieldHelper, knownFields);
        BlockStatement code = (BlockStatement) selectedMethod.getCode();
        MethodCallExpression mce;
        if (field.isStatic()) {
            mce = new MethodCallExpression(new ClassExpression(INVOKERHELPER_CLASSNODE), "invokeStaticMethod", new ArgumentListExpression(thisObject, new ConstantExpression(Traits.helperSetterName(field)), initCode.getExpression()));
        } else {
            mce = new MethodCallExpression(new CastExpression(createReceiverType(field.isStatic(), fieldHelper), thisObject), Traits.helperSetterName(field), new CastExpression(field.getOriginType(), initCode.getExpression()));
        }
        mce.setImplicitThis(false);
        mce.setSourcePosition(initialExpression);
        code.addStatement(new ExpressionStatement(mce));
    }
    // define setter/getter helper methods (setter added even for final fields for legacy compatibility)
    fieldHelper.addMethod(Traits.helperSetterName(field), ACC_PUBLIC | ACC_ABSTRACT, field.getOriginType(), new Parameter[] { new Parameter(field.getOriginType(), "val") }, ClassNode.EMPTY_ARRAY, null);
    fieldHelper.addMethod(Traits.helperGetterName(field), ACC_PUBLIC | ACC_ABSTRACT, field.getOriginType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null);
    // dummy fields are only used to carry annotations if instance field
    // and to differentiate from static fields otherwise
    int mods = field.getModifiers() & Traits.FIELD_PREFIX_MASK;
    String dummyFieldName = String.format("$0x%04x", mods) + Traits.remappedFieldName(field.getOwner(), field.getName());
    FieldNode dummyField = new FieldNode(dummyFieldName, ACC_STATIC | ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC, field.getOriginType(), fieldHelper, field.isFinal() ? initialExpression : null);
    // copy annotations from field to dummy field
    List<AnnotationNode> copied = new LinkedList<AnnotationNode>();
    List<AnnotationNode> notCopied = new LinkedList<AnnotationNode>();
    GeneralUtils.copyAnnotatedNodeAnnotations(field, copied, notCopied);
    dummyField.addAnnotations(copied);
    fieldHelper.addField(dummyField);
    // retain legacy field (will be given lower precedence than above)
    dummyFieldName = (field.isStatic() ? Traits.STATIC_FIELD_PREFIX : Traits.FIELD_PREFIX) + (field.isPublic() ? Traits.PUBLIC_FIELD_PREFIX : Traits.PRIVATE_FIELD_PREFIX) + Traits.remappedFieldName(field.getOwner(), field.getName());
    dummyField = new FieldNode(dummyFieldName, ACC_STATIC | ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC, field.getOriginType(), fieldHelper, null);
    // copy annotations from field to legacy dummy field
    copied = new LinkedList<AnnotationNode>();
    notCopied = new LinkedList<AnnotationNode>();
    GeneralUtils.copyAnnotatedNodeAnnotations(field, copied, notCopied);
    dummyField.addAnnotations(copied);
    fieldHelper.addField(dummyField);
}
Also used : FieldNode(org.codehaus.groovy.ast.FieldNode) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) LinkedList(java.util.LinkedList) MethodNode(org.codehaus.groovy.ast.MethodNode) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) SyntaxException(org.codehaus.groovy.syntax.SyntaxException) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) Parameter(org.codehaus.groovy.ast.Parameter) CastExpression(org.codehaus.groovy.ast.expr.CastExpression)

Aggregations

CastExpression (org.codehaus.groovy.ast.expr.CastExpression)24 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)18 Expression (org.codehaus.groovy.ast.expr.Expression)16 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)15 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)14 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)12 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)10 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)10 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)9 ArrayList (java.util.ArrayList)7 ClassNode (org.codehaus.groovy.ast.ClassNode)7 MethodNode (org.codehaus.groovy.ast.MethodNode)7 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)7 ArrayExpression (org.codehaus.groovy.ast.expr.ArrayExpression)6 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)6 List (java.util.List)5 Parameter (org.codehaus.groovy.ast.Parameter)5 BooleanExpression (org.codehaus.groovy.ast.expr.BooleanExpression)5 StaticMethodCallExpression (org.codehaus.groovy.ast.expr.StaticMethodCallExpression)5 LinkedList (java.util.LinkedList)4