public ExprDotNodeForgeStaticMethodEval(
     ExprDotNodeForgeStaticMethod forge,
     ExprEvaluator[] childEvals,
     ExprDotEval[] chainEval)
 {
     _forge = forge;
     _childEvals = childEvals;
     _chainEval = chainEval;
 }
        public static CodegenExpression CodegenGet(
            CodegenExpression beanExpression,
            ExprDotNodeForgeStaticMethod forge,
            CodegenMethodScope codegenMethodScope,
            CodegenClassScope codegenClassScope)
        {
            var exprSymbol = new ExprForgeCodegenSymbol(true, null);
            var methodNode = codegenMethodScope.MakeChildWithScope(
                    forge.EvaluationType,
                    typeof(ExprDotNodeForgeStaticMethodEval),
                    exprSymbol,
                    codegenClassScope)
                .AddParam(ExprForgeCodegenNames.PARAMS);

            var args = AllArgumentExpressions(
                forge.ChildForges,
                forge.StaticMethod,
                methodNode,
                exprSymbol,
                codegenClassScope);
            exprSymbol.DerivedSymbolsCodegen(methodNode, methodNode.Block, codegenClassScope);
            AppendArgExpressions(args, methodNode.Block);

            // try block
            var tryBlock = methodNode.Block.TryCatch();
            var invoke = CodegenInvokeExpression(
                forge.TargetObject,
                forge.StaticMethod,
                args,
                codegenClassScope);
            tryBlock.BlockReturn(invoke);

            // exception handling
            AppendCatch(
                tryBlock,
                forge.StaticMethod,
                forge.OptionalStatementName,
                forge.ClassOrPropertyName,
                forge.IsRethrowExceptions,
                args);

            // end method
            methodNode.Block.MethodReturn(ConstantNull());

            return LocalMethod(
                methodNode,
                NewArrayWithInit(typeof(EventBean), beanExpression),
                ConstantTrue(),
                ConstantNull());
        }
        public static CodegenExpression CodegenExprEval(
            ExprDotNodeForgeStaticMethod forge,
            CodegenMethodScope codegenMethodScope,
            ExprForgeCodegenSymbol exprSymbol,
            CodegenClassScope codegenClassScope)
        {
            CodegenExpression isCachedMember = null;
            CodegenExpression cachedResultMember = null;
            if (forge.IsConstantParameters) {
                isCachedMember = codegenClassScope.AddDefaultFieldUnshared(false, typeof(bool), ConstantFalse());
                cachedResultMember = codegenClassScope.AddDefaultFieldUnshared(false, typeof(object), ConstantNull());
            }

            var returnType = forge.StaticMethod.ReturnType;

            var methodNode = codegenMethodScope.MakeChild(
                forge.EvaluationType,
                typeof(ExprDotNodeForgeStaticMethodEval),
                codegenClassScope);

            var block = methodNode.Block;

            // check cached
            if (forge.IsConstantParameters) {
                var ifCached = block.IfCondition(isCachedMember);
                if (returnType == typeof(void)) {
                    ifCached.BlockReturnNoValue();
                }
                else {
                    ifCached.BlockReturn(Cast(forge.EvaluationType, cachedResultMember));
                }
            }

            // generate args
            var args = AllArgumentExpressions(
                forge.ChildForges,
                forge.StaticMethod,
                methodNode,
                exprSymbol,
                codegenClassScope);
            AppendArgExpressions(args, methodNode.Block);

            // try block
            var tryBlock = block.TryCatch();
            var invoke = CodegenInvokeExpression(
                forge.TargetObject,
                forge.StaticMethod,
                args,
                codegenClassScope);
            if (returnType == typeof(void)) {
                tryBlock.Expression(invoke);
                if (forge.IsConstantParameters) {
                    tryBlock.AssignRef(isCachedMember, ConstantTrue());
                }

                tryBlock.BlockReturnNoValue();
            }
            else {
                tryBlock.DeclareVar(returnType, "result", invoke);

                if (forge.ChainForges.Length == 0) {
                    var typeInformation = ConstantNull();
                    if (codegenClassScope.IsInstrumented) {
                        typeInformation = codegenClassScope.AddOrGetDefaultFieldSharable(
                            new EPTypeCodegenSharable(new ClassEPType(forge.EvaluationType), codegenClassScope));
                    }

                    tryBlock.Apply(
                        InstrumentationCode.Instblock(
                            codegenClassScope,
                            "qExprDotChain",
                            typeInformation,
                            Ref("result"),
                            Constant(0)));
                    if (forge.IsConstantParameters) {
                        tryBlock.AssignRef(cachedResultMember, Ref("result"));
                        tryBlock.AssignRef(isCachedMember, ConstantTrue());
                    }

                    tryBlock.Apply(InstrumentationCode.Instblock(codegenClassScope, "aExprDotChain"))
                        .BlockReturn(Ref("result"));
                }
                else {
                    EPType typeInfo;
                    if (forge.ResultWrapLambda != null) {
                        typeInfo = forge.ResultWrapLambda.TypeInfo;
                    }
                    else {
                        typeInfo = new ClassEPType(typeof(object));
                    }

                    var typeInformation = ConstantNull();
                    if (codegenClassScope.IsInstrumented) {
                        typeInformation = codegenClassScope.AddOrGetDefaultFieldSharable(
                            new EPTypeCodegenSharable(typeInfo, codegenClassScope));
                    }

                    tryBlock.Apply(
                            InstrumentationCode.Instblock(
                                codegenClassScope,
                                "qExprDotChain",
                                typeInformation,
                                Ref("result"),
                                Constant(forge.ChainForges.Length)))
                        .DeclareVar(
                            forge.EvaluationType,
                            "chain",
                            ExprDotNodeUtility.EvaluateChainCodegen(
                                methodNode,
                                exprSymbol,
                                codegenClassScope,
                                Ref("result"),
                                returnType,
                                forge.ChainForges,
                                forge.ResultWrapLambda));
                    if (forge.IsConstantParameters) {
                        tryBlock.AssignRef(cachedResultMember, Ref("chain"));
                        tryBlock.AssignRef(isCachedMember, ConstantTrue());
                    }

                    tryBlock.Apply(InstrumentationCode.Instblock(codegenClassScope, "aExprDotChain"))
                        .BlockReturn(Ref("chain"));
                }
            }

            // exception handling
            AppendCatch(
                tryBlock,
                forge.StaticMethod,
                forge.OptionalStatementName,
                forge.ClassOrPropertyName,
                forge.IsRethrowExceptions,
                args);

            // end method
            if (returnType == typeof(void)) {
                block.MethodEnd();
            }
            else {
                block.MethodReturn(ConstantNull());
            }

            return LocalMethod(methodNode);
        }