示例#1
0
 public ScriptFunction()
 {
     _varParamKind = ScriptVarParamKind.Direct;
 }
示例#2
0
        protected DynamicCustomFunction(MethodInfo method)
        {
            Method      = method ?? throw new ArgumentNullException(nameof(method));
            _returnType = method.ReturnType;

            Parameters = method.GetParameters();
#if !SCRIBAN_NO_ASYNC
            IsAwaitable = method.ReturnType.GetMethod(nameof(Task.GetAwaiter)) != null;
#endif

            _paramsIndex = -1;
            if (Parameters.Length > 0)
            {
                // Check if we have TemplateContext+SourceSpan as first parameters
                if (typeof(TemplateContext).IsAssignableFrom(Parameters[0].ParameterType))
                {
                    _hasTemplateContext = true;
                    if (Parameters.Length > 1)
                    {
                        _hasSpan = typeof(SourceSpan).IsAssignableFrom(Parameters[1].ParameterType);
                    }
                }

                var lastParam = Parameters[Parameters.Length - 1];
                if (lastParam.ParameterType.IsArray)
                {
                    foreach (var param in lastParam.GetCustomAttributes(typeof(ParamArrayAttribute), false))
                    {
                        _varParamKind      = ScriptVarParamKind.LastParameter;
                        _paramsElementType = lastParam.ParameterType.GetElementType();
                        _paramsIndex       = Parameters.Length - 1;
                        break;
                    }
                }
            }

            _expectedNumberOfParameters = Parameters.Length;
            _firstIndexOfUserParameters = 0;

            if (_varParamKind == ScriptVarParamKind.None)
            {
                for (int i = 0; i < Parameters.Length; i++)
                {
                    if (Parameters[i].IsOptional)
                    {
                        _optionalParameterCount++;
                    }
                }
            }

            if (_hasTemplateContext)
            {
                _firstIndexOfUserParameters++;
                if (_hasSpan)
                {
                    _firstIndexOfUserParameters++;
                }
            }

            _expectedNumberOfParameters -= _firstIndexOfUserParameters;
            _minimumRequiredParameters   = _expectedNumberOfParameters - _optionalParameterCount;
            if (_varParamKind == ScriptVarParamKind.LastParameter)
            {
                _minimumRequiredParameters--;
            }

            // Compute parameters
            _parameterInfos = new ScriptParameterInfo[_expectedNumberOfParameters];
            for (int i = 0; i < _expectedNumberOfParameters; i++)
            {
                var realIndex     = _firstIndexOfUserParameters + i;
                var parameterInfo = Parameters[realIndex];
                var parameterType = realIndex == Parameters.Length - 1 && _varParamKind == ScriptVarParamKind.LastParameter ? _paramsElementType : parameterInfo.ParameterType;
                _parameterInfos[i] = parameterInfo.HasDefaultValue
                    ? new ScriptParameterInfo(parameterType, parameterInfo.Name, parameterInfo.DefaultValue)
                    : new ScriptParameterInfo(parameterType, parameterInfo.Name);
            }
        }