Search in sources :

Example 16 with ClosureExpression

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

the class DefaultASTDatabindingHelper method getPropertyNamesToIncludeInWhiteList.

private Set<String> getPropertyNamesToIncludeInWhiteList(final SourceUnit sourceUnit, final ClassNode classNode) {
    final Set<String> propertyNamesToIncludeInWhiteList = new HashSet<String>();
    final Set<String> unbindablePropertyNames = new HashSet<String>();
    final Set<String> bindablePropertyNames = new HashSet<String>();
    if (!classNode.getSuperClass().equals(new ClassNode(Object.class))) {
        final Set<String> parentClassPropertyNames = getPropertyNamesToIncludeInWhiteListForParentClass(sourceUnit, classNode.getSuperClass());
        bindablePropertyNames.addAll(parentClassPropertyNames);
    }
    final FieldNode constraintsFieldNode = classNode.getDeclaredField(CONSTRAINTS_FIELD_NAME);
    if (constraintsFieldNode != null && constraintsFieldNode.hasInitialExpression()) {
        final Expression constraintsInitialExpression = constraintsFieldNode.getInitialExpression();
        if (constraintsInitialExpression instanceof ClosureExpression) {
            final Map<String, Map<String, Expression>> constraintsInfo = GrailsASTUtils.getConstraintMetadata((ClosureExpression) constraintsInitialExpression);
            for (Entry<String, Map<String, Expression>> constraintConfig : constraintsInfo.entrySet()) {
                final String propertyName = constraintConfig.getKey();
                final Map<String, Expression> mapEntryExpressions = constraintConfig.getValue();
                for (Entry<String, Expression> entry : mapEntryExpressions.entrySet()) {
                    final String constraintName = entry.getKey();
                    if (BINDABLE_CONSTRAINT_NAME.equals(constraintName)) {
                        final Expression valueExpression = entry.getValue();
                        Boolean bindableValue = null;
                        if (valueExpression instanceof ConstantExpression) {
                            final Object constantValue = ((ConstantExpression) valueExpression).getValue();
                            if (constantValue instanceof Boolean) {
                                bindableValue = (Boolean) constantValue;
                            }
                        }
                        if (bindableValue != null) {
                            if (Boolean.TRUE.equals(bindableValue)) {
                                unbindablePropertyNames.remove(propertyName);
                                bindablePropertyNames.add(propertyName);
                            } else {
                                bindablePropertyNames.remove(propertyName);
                                unbindablePropertyNames.add(propertyName);
                            }
                        } else {
                            GrailsASTUtils.warning(sourceUnit, valueExpression, "The bindable constraint for property [" + propertyName + "] in class [" + classNode.getName() + "] has a value which is not a boolean literal and will be ignored.");
                        }
                    }
                }
            }
        }
    }
    final Set<String> fieldsInTransientsList = getPropertyNamesExpressedInTransientsList(classNode);
    propertyNamesToIncludeInWhiteList.addAll(bindablePropertyNames);
    final List<FieldNode> fields = classNode.getFields();
    for (FieldNode fieldNode : fields) {
        final String fieldName = fieldNode.getName();
        final boolean isDomainClass = GrailsASTUtils.isDomainClass(classNode, sourceUnit);
        if ((!unbindablePropertyNames.contains(fieldName)) && (bindablePropertyNames.contains(fieldName) || shouldFieldBeInWhiteList(fieldNode, fieldsInTransientsList, isDomainClass))) {
            propertyNamesToIncludeInWhiteList.add(fieldName);
        }
    }
    final Map<String, MethodNode> declaredMethodsMap = classNode.getDeclaredMethodsMap();
    for (Entry<String, MethodNode> methodEntry : declaredMethodsMap.entrySet()) {
        final MethodNode value = methodEntry.getValue();
        if (classNode.equals(value.getDeclaringClass())) {
            Parameter[] parameters = value.getParameters();
            if (parameters != null && parameters.length == 1) {
                final String methodName = value.getName();
                if (methodName.startsWith("set")) {
                    final Parameter parameter = parameters[0];
                    final ClassNode paramType = parameter.getType();
                    if (!paramType.equals(new ClassNode(Object.class))) {
                        final String restOfMethodName = methodName.substring(3);
                        final String propertyName = GrailsNameUtils.getPropertyName(restOfMethodName);
                        if (!unbindablePropertyNames.contains(propertyName)) {
                            propertyNamesToIncludeInWhiteList.add(propertyName);
                        }
                    }
                }
            }
        }
    }
    CLASS_NODE_TO_WHITE_LIST_PROPERTY_NAMES.put(classNode, propertyNamesToIncludeInWhiteList);
    Map<String, ClassNode> allAssociationMap = GrailsASTUtils.getAllAssociationMap(classNode);
    for (String associationName : allAssociationMap.keySet()) {
        if (!propertyNamesToIncludeInWhiteList.contains(associationName) && !unbindablePropertyNames.contains(associationName)) {
            propertyNamesToIncludeInWhiteList.add(associationName);
        }
    }
    return propertyNamesToIncludeInWhiteList;
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) MethodNode(org.codehaus.groovy.ast.MethodNode) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) Expression(org.codehaus.groovy.ast.expr.Expression) Parameter(org.codehaus.groovy.ast.Parameter) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) HashMap(java.util.HashMap) Map(java.util.Map) HashSet(java.util.HashSet)

Example 17 with ClosureExpression

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

the class TraitReceiverTransformer method transform.

@Override
public Expression transform(final Expression exp) {
    ClassNode weavedType = weaved.getOriginType();
    if (exp instanceof BinaryExpression) {
        return transformBinaryExpression((BinaryExpression) exp, weavedType);
    } else if (exp instanceof StaticMethodCallExpression) {
        StaticMethodCallExpression call = (StaticMethodCallExpression) exp;
        ClassNode ownerType = call.getOwnerType();
        if (traitClass.equals(ownerType)) {
            MethodCallExpression result = new MethodCallExpression(new VariableExpression(weaved), call.getMethod(), transform(call.getArguments()));
            result.setSafe(false);
            result.setImplicitThis(false);
            result.setSpreadSafe(false);
            result.setSourcePosition(call);
            return result;
        }
    } else if (exp instanceof MethodCallExpression) {
        MethodCallExpression call = (MethodCallExpression) exp;
        Expression obj = call.getObjectExpression();
        if (call.isImplicitThis() || "this".equals(obj.getText())) {
            return transformMethodCallOnThis(call);
        } else if ("super".equals(obj.getText())) {
            return transformSuperMethodCall(call);
        }
    } else if (exp instanceof FieldExpression) {
        return transformFieldExpression((FieldExpression) exp);
    } else if (exp instanceof VariableExpression) {
        VariableExpression vexp = (VariableExpression) exp;
        Variable accessedVariable = vexp.getAccessedVariable();
        if (accessedVariable instanceof FieldNode) {
            FieldNode fn = (FieldNode) accessedVariable;
            Expression receiver = createFieldHelperReceiver();
            MethodCallExpression mce;
            boolean isStatic = fn.isStatic();
            if (isStatic) {
                receiver = createStaticReceiver(receiver);
            }
            mce = new MethodCallExpression(receiver, Traits.helperGetterName(fn), ArgumentListExpression.EMPTY_ARGUMENTS);
            mce.setSourcePosition(exp);
            mce.setImplicitThis(false);
            markDynamicCall(mce, fn, isStatic);
            return mce;
        } else if (accessedVariable instanceof PropertyNode) {
            String propName = accessedVariable.getName();
            if (knownFields.contains(propName)) {
                String method = Traits.helperGetterName(new FieldNode(propName, 0, ClassHelper.OBJECT_TYPE, weavedType, null));
                MethodCallExpression mce = new MethodCallExpression(createFieldHelperReceiver(), method, ArgumentListExpression.EMPTY_ARGUMENTS);
                mce.setSourcePosition(exp);
                mce.setImplicitThis(false);
                return mce;
            } else {
                return new PropertyExpression(new VariableExpression(weaved), accessedVariable.getName());
            }
        } else if (accessedVariable instanceof DynamicVariable) {
            return new PropertyExpression(new VariableExpression(weaved), accessedVariable.getName());
        }
        if (vexp.isThisExpression()) {
            VariableExpression res = new VariableExpression(weaved);
            res.setSourcePosition(exp);
            return res;
        }
        if (vexp.isSuperExpression()) {
            throwSuperError(vexp);
        }
    } else if (exp instanceof PropertyExpression) {
        PropertyExpression pexp = (PropertyExpression) exp;
        Expression object = pexp.getObjectExpression();
        if (pexp.isImplicitThis() || "this".equals(object.getText())) {
            String propName = pexp.getPropertyAsString();
            if (knownFields.contains(propName)) {
                String method = Traits.helperGetterName(new FieldNode(propName, 0, ClassHelper.OBJECT_TYPE, weavedType, null));
                MethodCallExpression mce = new MethodCallExpression(createFieldHelperReceiver(), method, ArgumentListExpression.EMPTY_ARGUMENTS);
                mce.setSourcePosition(exp);
                mce.setImplicitThis(false);
                return mce;
            }
        }
    } else if (exp instanceof ClosureExpression) {
        MethodCallExpression mce = new MethodCallExpression(exp, "rehydrate", new ArgumentListExpression(new VariableExpression(weaved), new VariableExpression(weaved), new VariableExpression(weaved)));
        mce.setImplicitThis(false);
        mce.setSourcePosition(exp);
        ((ClosureExpression) exp).getCode().visit(this);
        // The rewrite we do is causing some troubles with type checking, which will
        // not be able to perform closure parameter type inference
        // so we store the replacement, which will be done *after* type checking.
        exp.putNodeMetaData(TraitASTTransformation.POST_TYPECHECKING_REPLACEMENT, mce);
        return exp;
    }
    // todo: unary expressions (field++, field+=, ...)
    return super.transform(exp);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) Variable(org.codehaus.groovy.ast.Variable) DynamicVariable(org.codehaus.groovy.ast.DynamicVariable) FieldNode(org.codehaus.groovy.ast.FieldNode) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) 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) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) TernaryExpression(org.codehaus.groovy.ast.expr.TernaryExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) DynamicVariable(org.codehaus.groovy.ast.DynamicVariable) PropertyNode(org.codehaus.groovy.ast.PropertyNode) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression)

Example 18 with ClosureExpression

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

the class ControllerActionTransformer method processClosures.

private void processClosures(ClassNode classNode, SourceUnit source, GeneratorContext context) {
    List<PropertyNode> propertyNodes = new ArrayList<PropertyNode>(classNode.getProperties());
    Expression initialExpression;
    ClosureExpression closureAction;
    for (PropertyNode property : propertyNodes) {
        initialExpression = property.getInitialExpression();
        if (!property.isStatic() && initialExpression != null && initialExpression.getClass().equals(ClosureExpression.class)) {
            closureAction = (ClosureExpression) initialExpression;
            if (converterEnabled) {
                transformClosureToMethod(classNode, closureAction, property, source, context);
            } else {
                addMethodToInvokeClosure(classNode, property, source, context);
            }
        }
    }
}
Also used : ListExpression(org.codehaus.groovy.ast.expr.ListExpression) MapExpression(org.codehaus.groovy.ast.expr.MapExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) GrailsASTUtils.buildGetPropertyExpression(org.grails.compiler.injection.GrailsASTUtils.buildGetPropertyExpression) GrailsASTUtils.buildSetPropertyExpression(org.grails.compiler.injection.GrailsASTUtils.buildSetPropertyExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) TernaryExpression(org.codehaus.groovy.ast.expr.TernaryExpression) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) EmptyExpression(org.codehaus.groovy.ast.expr.EmptyExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) GrailsASTUtils.buildGetMapExpression(org.grails.compiler.injection.GrailsASTUtils.buildGetMapExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) MapEntryExpression(org.codehaus.groovy.ast.expr.MapEntryExpression) ArrayList(java.util.ArrayList) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression)

Example 19 with ClosureExpression

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

the class FieldASTTransformation method visitClosureExpression.

@Override
public void visitClosureExpression(final ClosureExpression expression) {
    ClosureExpression old = currentClosure;
    currentClosure = expression;
    super.visitClosureExpression(expression);
    currentClosure = old;
}
Also used : ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression)

Example 20 with ClosureExpression

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

the class MemoizedASTTransformation method buildMemoizeClosureCallExpression.

private MethodCallExpression buildMemoizeClosureCallExpression(MethodNode privateMethod, int protectedCacheSize, int maxCacheSize) {
    Parameter[] srcParams = privateMethod.getParameters();
    Parameter[] newParams = cloneParams(srcParams);
    List<Expression> argList = new ArrayList<Expression>(newParams.length);
    for (int i = 0; i < srcParams.length; i++) {
        argList.add(varX(newParams[i]));
    }
    ClosureExpression expression = new ClosureExpression(newParams, stmt(callThisX(privateMethod.getName(), args(argList))));
    MethodCallExpression mce;
    if (protectedCacheSize == 0 && maxCacheSize == 0) {
        mce = callX(expression, MEMOIZE_METHOD_NAME);
    } else if (protectedCacheSize == 0) {
        mce = callX(expression, MEMOIZE_AT_MOST_METHOD_NAME, args(constX(maxCacheSize)));
    } else if (maxCacheSize == 0) {
        mce = callX(expression, MEMOIZE_AT_LEAST_METHOD_NAME, args(constX(protectedCacheSize)));
    } else {
        mce = callX(expression, MEMOIZE_BETWEEN_METHOD_NAME, args(constX(protectedCacheSize), constX(maxCacheSize)));
    }
    mce.setImplicitThis(false);
    return mce;
}
Also used : MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ArrayList(java.util.ArrayList) Parameter(org.codehaus.groovy.ast.Parameter) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression)

Aggregations

ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)50 Expression (org.codehaus.groovy.ast.expr.Expression)39 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)34 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)33 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)31 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)28 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)21 ClassNode (org.codehaus.groovy.ast.ClassNode)18 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)18 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)17 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)16 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)16 DeclarationExpression (org.codehaus.groovy.ast.expr.DeclarationExpression)16 Parameter (org.codehaus.groovy.ast.Parameter)15 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)15 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)13 FieldNode (org.codehaus.groovy.ast.FieldNode)10 ListExpression (org.codehaus.groovy.ast.expr.ListExpression)10 ArrayList (java.util.ArrayList)9 DynamicVariable (org.codehaus.groovy.ast.DynamicVariable)9