Exemple #1
0
 public ExprArrayNodeForgeEval(
     ExprArrayNodeForge forge,
     ExprEvaluator[] evaluators)
 {
     _forge = forge;
     _evaluators = evaluators;
 }
Exemple #2
0
        public static CodegenExpression Codegen(
            ExprArrayNodeForge forge,
            CodegenMethodScope codegenMethodScope,
            ExprForgeCodegenSymbol exprSymbol,
            CodegenClassScope codegenClassScope)
        {
            var forgeRenderable = forge.ForgeRenderableArray;
            var methodNode = codegenMethodScope.MakeChild(
                forge.EvaluationType,
                typeof(ExprArrayNodeForgeEval),
                codegenClassScope);
            var block = methodNode.Block
                .DeclareVar(
                    forge.EvaluationType,
                    "array",
                    NewArrayByLength(forge.ArrayReturnType, Constant(forgeRenderable.ChildNodes.Length)));
            for (var i = 0; i < forgeRenderable.ChildNodes.Length; i++) {
                var child = forgeRenderable.ChildNodes[i].Forge;
                var childType = child.EvaluationType;
                var refname = "r" + i;
                block.DeclareVar(
                    childType,
                    refname,
                    child.EvaluateCodegen(childType, methodNode, exprSymbol, codegenClassScope));

                if (child.EvaluationType.CanNotBeNull()) {
                    if (!forge.IsMustCoerce) {
                        block.AssignArrayElement("array", Constant(i), Ref(refname));
                    }
                    else {
                        block.AssignArrayElement(
                            "array",
                            Constant(i),
                            forge.Coercer.CoerceCodegen(Ref(refname), child.EvaluationType));
                    }
                }
                else {
                    var ifNotNull = block.IfCondition(NotEqualsNull(Ref(refname)));
                    if (!forge.IsMustCoerce) {
                        ifNotNull.AssignArrayElement("array", Constant(i), Ref(refname));
                    }
                    else {
                        ifNotNull.AssignArrayElement(
                            "array",
                            Constant(i),
                            forge.Coercer.CoerceCodegen(Ref(refname), child.EvaluationType));
                    }
                }
            }

            block.MethodReturn(Ref("array"));
            return LocalMethod(methodNode);
        }
Exemple #3
0
        public static CodegenExpression CodegenEvaluateGetROCollectionScalar(
            ExprArrayNodeForge forge,
            CodegenMethodScope codegenMethodScope,
            ExprForgeCodegenSymbol exprSymbol,
            CodegenClassScope codegenClassScope)
        {
            var children = forge.ForgeRenderableArray.ChildNodes;
            if (children.Length == 0) {
                return StaticMethod(typeof(Collections), "GetEmptyList");
            }

            var methodNode = codegenMethodScope.MakeChild(
                typeof(FlexCollection),
                typeof(ExprArrayNodeForgeEval),
                codegenClassScope);
            var block = methodNode.Block
                .DeclareVar<ArrayDeque<object>>(
                    "resultList",
                    NewInstance<ArrayDeque<object>>(Constant(children.Length)));
            var count = -1;
            foreach (var child in children) {
                count++;
                var refname = "r" + count;
                var childForge = child.Forge;
                var returnType = childForge.EvaluationType;
                if (returnType == null) {
                    continue;
                }

                block.DeclareVar(
                    returnType,
                    refname,
                    childForge.EvaluateCodegen(returnType, methodNode, exprSymbol, codegenClassScope));
                var nonNullTest = returnType.CanNotBeNull() ? ConstantTrue() : NotEqualsNull(Ref(refname));
                var blockIfNotNull = block.IfCondition(nonNullTest);
                CodegenExpression added = Ref(refname);
                if (forge.IsMustCoerce) {
                    added = forge.Coercer.CoerceCodegen(Ref(refname), childForge.EvaluationType);
                }

                blockIfNotNull.Expression(ExprDotMethod(Ref("resultList"), "Add", added));
            }

            block.MethodReturn(FlexWrap(Ref("resultList")));
            return LocalMethod(methodNode);
        }
Exemple #4
0
        public override ExprNode Validate(ExprValidationContext validationContext)
        {
            var length = ChildNodes.Length;

            // Can be an empty array with no content
            if (ChildNodes.Length == 0) {
                forge = new ExprArrayNodeForge(this, typeof(object), CollectionUtil.OBJECTARRAY_EMPTY);
                return null;
            }

            IList<Type> comparedTypes = new List<Type>();
            for (var i = 0; i < length; i++) {
                comparedTypes.Add(ChildNodes[i].Forge.EvaluationType);
            }

            // Determine common denominator type
            Type arrayReturnType = null;
            var mustCoerce = false;
            Coercer coercer = null;
            try {
                arrayReturnType = TypeHelper.GetCommonCoercionType(comparedTypes.ToArray());

                // Determine if we need to coerce numbers when one type doesn't match any other type
                if (arrayReturnType.IsNumeric()) {
                    mustCoerce = false;
                    foreach (var comparedType in comparedTypes) {
                        if (comparedType != arrayReturnType) {
                            mustCoerce = true;
                        }
                    }

                    if (mustCoerce) {
                        coercer = SimpleNumberCoercerFactory.GetCoercer(null, arrayReturnType);
                    }
                }
            }
            catch (CoercionException) {
                // expected, such as mixing String and int values, or types (not boxed) and primitives
                // use Object[] in such cases
            }

            if (arrayReturnType == null) {
                arrayReturnType = typeof(object);
            }

            // Determine if we are dealing with constants only
            var results = new object[length];
            var index = 0;
            foreach (var child in ChildNodes) {
                if (!child.Forge.ForgeConstantType.IsCompileTimeConstant) {
                    results = null; // not using a constant result
                    break;
                }

                results[index] = ChildNodes[index].Forge.ExprEvaluator.Evaluate(null, false, null);
                index++;
            }

            // Copy constants into array and coerce, if required
            Array constantResult = null;
            if (results != null) {
                constantResult = Array.CreateInstance(arrayReturnType, length);
                for (var i = 0; i < length; i++) {
                    if (mustCoerce) {
                        var boxed = results[i];
                        if (boxed != null) {
                            object coercedResult = coercer.CoerceBoxed(boxed);
                            constantResult.SetValue(coercedResult, i);
                        }
                    }
                    else {
                        constantResult.SetValue(results[i], i);
                    }
                }
            }

            forge = new ExprArrayNodeForge(this, arrayReturnType, mustCoerce, coercer, constantResult);
            return null;
        }
Exemple #5
0
        public static CodegenExpression Codegen(
            ExprArrayNodeForge forge,
            CodegenMethodScope codegenMethodScope,
            ExprForgeCodegenSymbol exprSymbol,
            CodegenClassScope codegenClassScope)
        {
            var forgeRenderable = forge.ForgeRenderableArray;
            var methodNode = codegenMethodScope.MakeChild(
                forge.EvaluationType,
                typeof(ExprArrayNodeForgeEval),
                codegenClassScope);

            var arrayType = forge.EvaluationType;
            var block = methodNode.Block
                .DeclareVar(
                    arrayType,
                    "array",
                    NewArrayByLength(forge.ArrayReturnType, Constant(forgeRenderable.ChildNodes.Length)));
            var requiresPrimitive =
                forge.Parent.OptionalRequiredType != null &&
                forge.Parent.OptionalRequiredType.IsPrimitive;

            for (var i = 0; i < forgeRenderable.ChildNodes.Length; i++) {
                var child = forgeRenderable.ChildNodes[i].Forge;
                var childType = child.EvaluationType;
                var refname = "r" + i;

                block.DeclareVar(
                    childType,
                    refname,
                    child.EvaluateCodegen(childType, methodNode, exprSymbol, codegenClassScope));

                if (child.EvaluationType.CanNotBeNull()) {
                    if (!forge.IsMustCoerce) {
                        block
                            .AssignArrayElement(
                                "array",
                                Constant(i),
                                Unbox(Ref(refname), childType));
                    }
                    else {
                        block
                            .AssignArrayElement(
                                "array",
                                Constant(i),
                                forge.Coercer.CoerceCodegen(Ref(refname), childType));
                    }
                }
                else {
                    var ifNotNull = block.IfCondition(NotEqualsNull(Ref(refname)));
                    if (!forge.IsMustCoerce) {
                        ifNotNull
                            .AssignArrayElement(
                                "array",
                                Constant(i),
                                Unbox(Ref(refname), childType));
                    }
                    else {
                        ifNotNull
                            .AssignArrayElement(
                                "array",
                                Constant(i),
                                forge.Coercer.CoerceCodegen(Ref(refname), child.EvaluationType));
                    }

                    if (requiresPrimitive) {
                        block.IfCondition(
                                EqualsNull(Ref(refname)))
                            .BlockThrow(
                                NewInstance(typeof(EPException), Constant(PRIMITIVE_ARRAY_NULL_MSG)));
                    }
                }
            }

            block.MethodReturn(Ref("array"));
            return LocalMethod(methodNode);
        }