Ejemplo n.º 1
0
        protected override CodegenExpression CodegenEvaluateInternal(
            CodegenMethodScope parent,
            SubselectForgeNRSymbol symbols,
            CodegenClassScope classScope)
        {
            var method = parent.MakeChild(typeof(bool?), this.GetType(), classScope);
            var left = symbols.GetAddLeftResult(method);
            method.Block.DeclareVar<bool>("hasNullRow", ConstantFalse());
            var @foreach = method.Block.ForEach(typeof(EventBean), "theEvent", symbols.GetAddMatchingEvents(method));
            {
                @foreach.AssignArrayElement(NAME_EPS, Constant(0), Ref("theEvent"));
                if (filterEval != null) {
                    CodegenLegoBooleanExpression.CodegenContinueIfNotNullAndNotPass(
                        @foreach,
                        filterEval.EvaluationType,
                        filterEval.EvaluateCodegen(typeof(bool?), method, symbols, classScope));
                }

                @foreach.IfRefNullReturnNull(left);

                Type valueRightType;
                if (selectEval != null) {
                    valueRightType = Boxing.GetBoxedType(selectEval.EvaluationType);
                    @foreach.DeclareVar(
                        valueRightType,
                        "valueRight",
                        selectEval.EvaluateCodegen(valueRightType, method, symbols, classScope));
                }
                else {
                    valueRightType = subselect.RawEventType.UnderlyingType;
                    @foreach.DeclareVar(
                        valueRightType,
                        "valueRight",
                        Cast(valueRightType, ExprDotUnderlying(ArrayAtIndex(symbols.GetAddEPS(method), Constant(0)))));
                }

                var ifRight = @foreach.IfCondition(NotEqualsNull(Ref("valueRight")));
                {
                    if (coercer == null) {
                        ifRight.IfCondition(ExprDotMethod(left, "Equals", Ref("valueRight")))
                            .BlockReturn(Constant(!isNotIn));
                    }
                    else {
                        ifRight.DeclareVar<object>("left", coercer.CoerceCodegen(left, symbols.LeftResultType))
                            .DeclareVar<object>("right", coercer.CoerceCodegen(Ref("valueRight"), valueRightType))
                            .DeclareVar<bool>("eq", ExprDotMethod(Ref("left"), "Equals", Ref("right")))
                            .IfCondition(Ref("eq"))
                            .BlockReturn(Constant(!isNotIn));
                    }
                }
                ifRight.IfElse().AssignRef("hasNullRow", ConstantTrue());
            }

            method.Block
                .IfCondition(Ref("hasNullRow"))
                .BlockReturn(ConstantNull())
                .MethodReturn(Constant(isNotIn));
            return LocalMethod(method);
        }
        protected override CodegenExpression CodegenEvaluateInternal(
            CodegenMethodScope parent,
            SubselectForgeNRSymbol symbols,
            CodegenClassScope classScope)
        {
            var method = parent.MakeChild(typeof(bool?), GetType(), classScope);
            method.Block
                .DeclareVar<bool>("hasRows", ConstantFalse())
                .DeclareVar<bool>("hasNullRow", ConstantFalse());
            var @foreach = method.Block.ForEach(
                typeof(EventBean),
                "subselectEvent",
                symbols.GetAddMatchingEvents(method));
            {
                @foreach.AssignArrayElement(NAME_EPS, Constant(0), Ref("subselectEvent"));
                if (filterOrHavingEval != null) {
                    CodegenLegoBooleanExpression.CodegenContinueIfNotNullAndNotPass(
                        @foreach,
                        filterOrHavingEval.EvaluationType,
                        filterOrHavingEval.EvaluateCodegen(typeof(bool?), method, symbols, classScope));
                }

                @foreach.AssignRef("hasRows", ConstantTrue());

                Type valueRightType;
                if (selectEval != null) {
                    valueRightType = selectEval.EvaluationType.GetBoxedType();
                    @foreach.DeclareVar(
                        valueRightType,
                        "valueRight",
                        selectEval.EvaluateCodegen(valueRightType, method, symbols, classScope));
                }
                else {
                    valueRightType = typeof(object);
                    @foreach.DeclareVar(
                        valueRightType,
                        "valueRight",
                        ExprDotUnderlying(ArrayAtIndex(symbols.GetAddEPS(method), Constant(0))));
                }

                @foreach.IfRefNull("valueRight")
                    .AssignRef("hasNullRow", ConstantTrue())
                    .IfElse()
                    .IfCondition(NotEqualsNull(symbols.GetAddLeftResult(method)))
                    .IfCondition(
                        Not(
                            computer.Codegen(
                                symbols.GetAddLeftResult(method),
                                symbols.LeftResultType,
                                Ref("valueRight"),
                                valueRightType)))
                    .BlockReturn(ConstantFalse());
            }

            method.Block
                .IfCondition(Not(Ref("hasRows")))
                .BlockReturn(ConstantTrue())
                .IfCondition(EqualsNull(symbols.GetAddLeftResult(method)))
                .BlockReturn(ConstantNull())
                .IfCondition(Ref("hasNullRow"))
                .BlockReturn(ConstantNull())
                .MethodReturn(ConstantTrue());
            return LocalMethod(method);
        }