Inheritance: ScriptStatement
Ejemplo n.º 1
0
 public object Invoke(TemplateContext context, ScriptNode callerContext, ScriptArray parameters, ScriptBlockStatement blockStatement)
 {
     return(_customFunction(context, callerContext, parameters));
 }
Ejemplo n.º 2
0
 public virtual ValueTask <object> InvokeAsync(TemplateContext context, ScriptNode callerContext, ScriptArray arguments, ScriptBlockStatement blockStatement)
 {
     return(new ValueTask <object>(Invoke(context, callerContext, arguments, blockStatement)));
 }
Ejemplo n.º 3
0
        public override object Invoke(TemplateContext context, ScriptNode callerContext, ScriptArray arguments, ScriptBlockStatement blockStatement)
        {
            var expectedNumberOfParameters = Parameters.Length;

            if (_hasTemplateContext)
            {
                expectedNumberOfParameters--;
                if (_hasSpan)
                {
                    expectedNumberOfParameters--;
                }
            }

            var minimumRequiredParameters = expectedNumberOfParameters - _optionalParameterCount;

            // Check parameters
            if ((_hasObjectParams && arguments.Count < minimumRequiredParameters - 1) || (!_hasObjectParams && arguments.Count < minimumRequiredParameters))
            {
                if (minimumRequiredParameters != expectedNumberOfParameters)
                {
                    throw new ScriptRuntimeException(callerContext.Span, $"Invalid number of arguments `{arguments.Count}` passed to `{callerContext}` while expecting at least `{minimumRequiredParameters}` arguments");
                }
                else
                {
                    throw new ScriptRuntimeException(callerContext.Span, $"Invalid number of arguments `{arguments.Count}` passed to `{callerContext}` while expecting `{expectedNumberOfParameters}` arguments");
                }
            }

            // Convert arguments
            object[] paramArguments = null;
            var      argMask        = 0;

            if (_hasObjectParams)
            {
                var objectParamsCount = arguments.Count - _lastParamsIndex;
                if (_hasTemplateContext)
                {
                    objectParamsCount++;
                    if (_hasSpan)
                    {
                        objectParamsCount++;
                    }
                }
                paramArguments = new object[objectParamsCount];
                _arguments[_lastParamsIndex] = paramArguments;
                argMask |= 1 << _lastParamsIndex;
            }

            // Copy TemplateContext/SourceSpan parameters
            int argOffset = 0;

            if (_hasTemplateContext)
            {
                _arguments[0] = context;
                argOffset++;
                argMask |= 1;
                if (_hasSpan)
                {
                    _arguments[1] = callerContext.Span;
                    argOffset++;
                    argMask |= 2;
                }
            }

            var argOrderedIndex = argOffset;

            // Setup any default parameters
            if (_optionalParameterCount > 0)
            {
                for (int i = Parameters.Length - 1; i >= Parameters.Length - _optionalParameterCount; i--)
                {
                    _arguments[i] = Parameters[i].DefaultValue;
                    argMask      |= 1 << i;
                }
            }

            int paramsIndex = 0;

            for (int i = 0; i < arguments.Count; i++)
            {
                Type argType = null;
                try
                {
                    int argIndex;
                    var arg      = arguments[i];
                    var namedArg = arg as ScriptNamedArgument;
                    if (namedArg != null)
                    {
                        var namedArgValue = GetValueFromNamedArgument(context, callerContext, namedArg);
                        arg      = namedArgValue.Value;
                        argIndex = namedArgValue.Index;
                        argType  = namedArgValue.Type;
                        if (_hasObjectParams && argIndex == _lastParamsIndex)
                        {
                            argType  = _paramsElementType;
                            argIndex = argIndex + paramsIndex;
                            paramsIndex++;
                        }
                    }
                    else
                    {
                        argIndex = argOrderedIndex;
                        if (_hasObjectParams && argIndex == _lastParamsIndex)
                        {
                            argType  = _paramsElementType;
                            argIndex = argIndex + paramsIndex;
                            paramsIndex++;
                        }
                        else
                        {
                            argType = Parameters[argIndex].ParameterType;
                            argOrderedIndex++;
                        }
                    }

                    var argValue = context.ToObject(callerContext.Span, arg, argType);
                    if (paramArguments != null && argIndex >= _lastParamsIndex)
                    {
                        paramArguments[argIndex - _lastParamsIndex] = argValue;
                    }
                    else
                    {
                        _arguments[argIndex] = argValue;
                        argMask |= 1 << argIndex;
                    }
                }
                catch (Exception exception)
                {
                    throw new ScriptRuntimeException(callerContext.Span, $"Unable to convert parameter #{i} of type `{arguments[i]?.GetType()}` to type `{argType}`", exception);
                }
            }

            // In case we have named arguments we need to verify that all arguments were set
            if (argMask != (1 << Parameters.Length) - 1)
            {
                if (minimumRequiredParameters != expectedNumberOfParameters)
                {
                    throw new ScriptRuntimeException(callerContext.Span, $"Invalid number of arguments `{arguments.Count}` passed to `{callerContext}` while expecting at least `{minimumRequiredParameters}` arguments");
                }
                else
                {
                    throw new ScriptRuntimeException(callerContext.Span, $"Invalid number of arguments `{arguments.Count}` passed to `{callerContext}` while expecting `{expectedNumberOfParameters}` arguments");
                }
            }

            // Call method
            try
            {
                var result = Method.Invoke(_target, _arguments);
                // NOTE: The following line should not be touch as it is being matched by ScribanAsyncCodeGen
                return(result);
            }
            catch (TargetInvocationException exception)
            {
                throw new ScriptRuntimeException(callerContext.Span, $"Unexpected exception when calling {callerContext}", exception.InnerException);
            }
        }
Ejemplo n.º 4
0
        public object Evaluate(TemplateContext context, ScriptNode callerContext, ScriptArray parameters, ScriptBlockStatement blockStatement)
        {
            if (parameters.Count == 0)
            {
                throw new ScriptRuntimeException(callerContext.Span, "Expecting at least the name of the template to include for the <include> function");
            }

            string templateName = null;
            try
            {
                templateName = ScriptValueConverter.ToString(callerContext.Span, parameters[0]);
            }
            catch (Exception ex)
            {
                throw new ScriptRuntimeException(callerContext.Span, $"Unexpected exception while converting first parameter for <include> function. Expecting a string", ex);
            }

            // If template name is empty, throw an exception
            if (templateName == null || string.IsNullOrEmpty(templateName = templateName.Trim()))
            {
                throw new ScriptRuntimeException(callerContext.Span, $"Include template name cannot be null or empty");
            }

            // Compute a new parameters for the include
            var newParameters = new ScriptArray(parameters.Count - 1);
            for (int i = 1; i < parameters.Count; i++)
            {
                newParameters[i] = parameters[i];
            }

            context.SetValue(ScriptVariable.Arguments, newParameters, true);

            Template template;

            if (!context.CachedTemplates.TryGetValue(templateName, out template))
            {
                if (context.TemplateLoader == null)
                {
                    throw new ScriptRuntimeException(callerContext.Span,
                        $"Unable to include <{templateName}>. No TemplateLoader registered in TemplateContext.Options.TemplateLoader");
                }

                string templateFilePath;

                var templateText = context.TemplateLoader.Load(context, callerContext.Span, templateName, out templateFilePath);

                if (templateText == null)
                {
                    throw new ScriptRuntimeException(callerContext.Span, $"The result of including <{templateName}> cannot be null");
                }

                // IF template file path is not defined, we use the template name instead
                templateFilePath = templateFilePath ?? templateName;

                // Clone parser options
                var parserOptions = context.TemplateLoaderParserOptions.Clone();

                // Parse include in default modes (while top page can be using front matter)
                parserOptions.Mode = parserOptions.Mode == ScriptMode.ScriptOnly
                    ? ScriptMode.ScriptOnly
                    : ScriptMode.Default;

                template = Template.Parse(templateText, templateFilePath, parserOptions);

                // If the template has any errors, throw an exception
                if (template.HasErrors)
                {
                    throw new ScriptParserRuntimeException(callerContext.Span, $"Error while parsing template <{templateName}> from [{templateFilePath}]", template.Messages);
                }

                context.CachedTemplates.Add(templateName, template);
            }

            // Query the pending includes stored in the context
            HashSet<string> pendingIncludes;
            object pendingIncludesObject;
            if (!context.Tags.TryGetValue(typeof(IncludeFunction), out pendingIncludesObject))
            {
                pendingIncludesObject = pendingIncludes = new HashSet<string>();
                context.Tags[typeof (IncludeFunction)] = pendingIncludesObject;
            }
            else
            {
                pendingIncludes = (HashSet<string>) pendingIncludesObject;
            }

            // Make sure that we cannot recursively include a template
            if (pendingIncludes.Contains(templateName))
            {
                throw new ScriptRuntimeException(callerContext.Span, $"The include [{templateName}] cannot be used recursively");
            }
            pendingIncludes.Add(templateName);

            context.PushOutput();
            object result = null;
            try
            {
                template.Render(context);
            }
            finally
            {
                result = context.PopOutput();
                pendingIncludes.Remove(templateName);
            }

            return result;
        }
Ejemplo n.º 5
0
 public abstract object Invoke(TemplateContext context, ScriptNode callerContext, ScriptArray arguments, ScriptBlockStatement blockStatement);
Ejemplo n.º 6
0
            public object Evaluate(TemplateContext context, ScriptNode callerContext, ScriptArray parameters, ScriptBlockStatement blockStatement)
            {
                // Check parameters
                if ((hasObjectParams && parameters.Count < parametersInfo.Length - 1) || (!hasObjectParams && parameters.Count != parametersInfo.Length))
                {
                    throw new ScriptRuntimeException(callerContext.Span, $"Invalid number of arguments passed [{parameters.Count}] while expecting [{parametersInfo.Length}] for [{callerContext}]");
                }

                // Convert arguments
                var arguments = new object[parametersInfo.Length];

                object[] paramArguments = null;
                if (hasObjectParams)
                {
                    paramArguments             = new object[parameters.Count - lastParamsIndex];
                    arguments[lastParamsIndex] = paramArguments;
                }

                for (int i = 0; i < parameters.Count; i++)
                {
                    var destType = hasObjectParams && i >= lastParamsIndex ? typeof(object) : parametersInfo[i].ParameterType;
                    try
                    {
                        var argValue = ScriptValueConverter.ToObject(callerContext.Span, parameters[i], destType);
                        if (hasObjectParams && i >= lastParamsIndex)
                        {
                            paramArguments[i - lastParamsIndex] = argValue;
                        }
                        else
                        {
                            arguments[i] = argValue;
                        }
                    }
                    catch (Exception exception)
                    {
                        throw new ScriptRuntimeException(callerContext.Span, $"Unable to convert parameter #{i} of type [{parameters[i]?.GetType()}] to type [{destType}]", exception);
                    }
                }

                // Call method
                try
                {
                    var result = method.Invoke(target, arguments);
                    return(result);
                }
                catch (Exception exception)
                {
                    throw new ScriptRuntimeException(callerContext.Span, $"Unexpected exception when calling {callerContext}", exception);
                }
            }
Ejemplo n.º 7
0
        public override async ValueTask <object> InvokeAsync(TemplateContext context, ScriptNode callerContext, ScriptArray scriptArguments, ScriptBlockStatement blockStatement)
        {
            Array paramArguments = null;
            var   arguments      = PrepareArguments(context, callerContext, scriptArguments, ref paramArguments);

            try
            {
                // Call the method via reflection
                var result = InvokeImpl(context, callerContext.Span, arguments);
                return(IsAwaitable ? await ConfigureAwait(result) : result);
            }
            catch (TargetInvocationException exception)
            {
                if (exception.InnerException != null)
                {
                    throw exception.InnerException;
                }
                throw new ScriptRuntimeException(callerContext.Span, $"Unexpected exception when calling {callerContext}");
            }
            finally
            {
                context.ReleaseReflectionArguments(arguments);
            }
        }
Ejemplo n.º 8
0
 public object Evaluate(TemplateContext context, ScriptNode callerContext, ScriptArray parameters, ScriptBlockStatement blockStatement)
 {
     return customFunction(context, callerContext, parameters);
 }
Ejemplo n.º 9
0
            public object Evaluate(TemplateContext context, ScriptNode callerContext, ScriptArray parameters, ScriptBlockStatement blockStatement)
            {
                // Check parameters
                if ((hasObjectParams && parameters.Count < parametersInfo.Length - 1) || (!hasObjectParams && parameters.Count != parametersInfo.Length))
                {
                    throw new ScriptRuntimeException(callerContext.Span, $"Invalid number of arguments passed [{parameters.Count}] while expecting [{parametersInfo.Length}] for [{callerContext}]");
                }

                // Convert arguments
                var arguments = new object[parametersInfo.Length];
                object[] paramArguments = null;
                if (hasObjectParams)
                {
                    paramArguments = new object[parameters.Count - lastParamsIndex];
                    arguments[lastParamsIndex] = paramArguments;
                }

                for (int i = 0; i < parameters.Count; i++)
                {
                    var destType = hasObjectParams && i >= lastParamsIndex ? typeof(object) : parametersInfo[i].ParameterType;
                    try
                    {
                        var argValue = ScriptValueConverter.ToObject(callerContext.Span, parameters[i], destType);
                        if (hasObjectParams && i >= lastParamsIndex)
                        {
                            paramArguments[i - lastParamsIndex] = argValue;
                        }
                        else
                        {
                            arguments[i] = argValue;
                        }
                    }
                    catch (Exception exception)
                    {
                        throw new ScriptRuntimeException(callerContext.Span, $"Unable to convert parameter #{i} of type [{parameters[i]?.GetType()}] to type [{destType}]", exception);
                    }
                }

                // Call method
                try
                {
                    var result = method.Invoke(target, arguments);
                    return result;
                }
                catch (Exception exception)
                {
                    throw new ScriptRuntimeException(callerContext.Span, $"Unexpected exception when calling {callerContext}", exception);
                }
            }
 public ValueTask <object> InvokeAsync(TemplateContext context, ScriptNode callerContext, ScriptArray arguments, ScriptBlockStatement blockStatement)
 {
     return(new ValueTask <object>(_customFunction(context, callerContext, arguments)));
 }