private static PageResult GetCodePageResult(ScriptContext context, string code, Dictionary <string, object> args)
        {
            PageResult pageResult = null;

            try
            {
                var page = context.CodeSharpPage(code);
                pageResult = new PageResult(page);
                args.Each((x, y) => pageResult.Args[x] = y);
                return(pageResult);
            }
            catch (Exception e)
            {
                if (ScriptContextUtils.ShouldRethrow(e))
                {
                    throw;
                }
                throw ScriptContextUtils.HandleException(e, pageResult ?? new PageResult(context.EmptyPage));
            }
        }
示例#2
0
        public override Task WriteAsync(ScriptScopeContext scope, PageBlockFragment block, CancellationToken token)
        {
            var invokerCtx = (Tuple <string, MethodInvoker>)scope.Context.CacheMemory.GetOrAdd(block.Argument, key => {
                var literal = block.Argument.Span.ParseVarName(out var name);
                var strName = name.ToString();
                literal     = literal.AdvancePastWhitespace();

                literal  = literal.AdvancePastWhitespace();
                var args = TypeConstants.EmptyStringList;
                if (!literal.IsEmpty)
                {
                    literal = literal.ParseArgumentsList(out var argIdentifiers);
                    args    = argIdentifiers.Map(x => x.Name);
                }

                var strFragment = (PageStringFragment)block.Body[0];

                var script       = ScriptPreprocessors.TransformStatementBody(strFragment.ValueString);
                var parsedScript = scope.Context.OneTimePage(script);

                MethodInvoker invoker = null;

                // Allow recursion by initializing lazy Delegate
                object LazyInvoker(object instance, object[] paramValues)
                {
                    if (invoker == null)
                    {
                        throw new NotSupportedException($"Uninitialized function '{strName}'");
                    }

                    return(invoker(instance, paramValues));
                }

                invoker = (instance, paramValues) => {
                    scope.PageResult.StackDepth++;
                    try
                    {
                        var pageResult = new PageResult(parsedScript)
                        {
                            Args =
                            {
                                [strName] = (MethodInvoker)LazyInvoker
                            },
                            StackDepth = scope.PageResult.StackDepth
                        };

                        var len = Math.Min(paramValues.Length, args.Count);
                        for (int i = 0; i < len; i++)
                        {
                            var paramValue           = paramValues[i];
                            pageResult.Args[args[i]] = paramValue;
                        }

                        var discard = ScriptContextUtils.GetPageResultOutput(pageResult);
                        if (pageResult.ReturnValue == null)
                        {
                            throw new NotSupportedException(ScriptContextUtils.ErrorNoReturn);
                        }

                        return(pageResult.ReturnValue.Result);
                    }
                    finally
                    {
                        scope.PageResult.StackDepth--;
                    }
                };

                return(Tuple.Create(strName, invoker));
            });

            scope.PageResult.Args[invokerCtx.Item1] = invokerCtx.Item2;

            return(TypeConstants.EmptyTask);
        }