コード例 #1
0
 public void Applied()
 {
     if (UsedAsExpression && !CallingMethod.DoesReturnValue())
     {
         parseInfo.Script.Diagnostics.Error("The chosen overload for " + CallingMethod.Name + " does not return a value.", NameRange);
     }
 }
コード例 #2
0
        public CallMethodAction(ParseInfo parseInfo, Scope scope, DeltinScriptParser.MethodContext methodContext, bool usedAsExpression, Scope getter)
        {
            this.parseInfo = parseInfo;
            string methodName = methodContext.PART().GetText();

            NameRange = DocRange.GetRange(methodContext.PART());

            UsedAsExpression = usedAsExpression;

            if (methodContext.ASYNC() != null)
            {
                if (methodContext.NOT() == null)
                {
                    Parallel = CallParallel.AlreadyRunning_RestartRule;
                }
                else
                {
                    Parallel = CallParallel.AlreadyRunning_DoNothing;
                }
            }

            var options = scope.GetMethodsByName(methodName);

            if (options.Length == 0)
            {
                parseInfo.Script.Diagnostics.Error($"No method by the name of '{methodName}' exists in the current context.", NameRange);
            }
            else
            {
                OverloadChooser = new OverloadChooser(options, parseInfo, scope, getter, NameRange, DocRange.GetRange(methodContext), new OverloadError("method '" + methodName + "'"));
                OverloadChooser.Apply(methodContext.call_parameters());

                CallingMethod   = (IMethod)OverloadChooser.Overload;
                ParameterValues = OverloadChooser.Values;

                if (CallingMethod != null)
                {
                    CallingMethod.Call(parseInfo, NameRange);

                    // Todo: move this to DefinedFunction.Call.
                    if (CallingMethod is DefinedFunction definedFunction)
                    {
                        definedFunction.OnBlockApply(this);
                        parseInfo.CurrentCallInfo?.Call(definedFunction, NameRange);
                    }

                    if (Parallel != CallParallel.NoParallel && !CallingMethod.Attributes.Parallelable)
                    {
                        parseInfo.Script.Diagnostics.Error($"The method '{CallingMethod.Name}' cannot be called in parallel.", NameRange);
                    }

                    parseInfo.Script.AddHover(DocRange.GetRange(methodContext), CallingMethod.GetLabel(true));
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Check if current request is match the given parameters of the method.
        /// </summary>
        /// <param name="context">The HttpContext</param>
        /// <param name="callingMethod">The method to compare.</param>
        /// <returns>True if matched otherwise false.</returns>
        public bool IsMatch(HttpListenerContext context, CallingMethod callingMethod)
        {
            if (!WebApiTypeMatched(callingMethod))
            {
                return(false);
            }
            var queryData = context.Request.QueryString;

            var argCount = 0;

            foreach (var parameter in callingMethod.Parameters)
            {
                var paramType = parameter.ParameterType;
                //FromBody
                if (parameter.FromType == FromType.FromBody)
                {
                    if (context.Request.ContentLength64 == 0)
                    {
                        //We do not actually check the body data, just check if there is body data.
                        return(false);
                    }
                }
                else if (parameter.FromType == FromType.FromUrl)
                {
                    if (!_properties.ContainsKey(paramType))
                    {
                        _properties.Add(paramType, paramType.GetProperties().Where(x => x.CanRead && x.CanWrite).ToArray());
                    }

                    var properties = _properties[paramType];
                    foreach (var property in properties)
                    {
                        if (!queryData.AllKeys.Contains(property.Name))
                        {
                            return(false);
                        }
                    }
                }
                else
                {
                    if (!queryData.AllKeys.Contains(parameter.Name))
                    {
                        return(false);
                    }
                }

                argCount++;
            }

            return(argCount == callingMethod.Parameters.Count);
        }
コード例 #4
0
        public CallMethodAction(ParseInfo parseInfo, Scope scope, DeltinScriptParser.MethodContext methodContext, bool usedAsExpression, Scope getter)
        {
            this.translateInfo = parseInfo.TranslateInfo;
            string methodName = methodContext.PART().GetText();

            NameRange = DocRange.GetRange(methodContext.PART());

            var options = scope.GetMethodsByName(methodName);

            if (options.Length == 0)
            {
                parseInfo.Script.Diagnostics.Error($"No method by the name of '{methodName}' exists in the current context.", NameRange);
            }
            else
            {
                OverloadChooser = new OverloadChooser(options, parseInfo, getter, NameRange, DocRange.GetRange(methodContext), new OverloadError("method '" + methodName + "'"));

                if (methodContext.call_parameters() != null)
                {
                    OverloadChooser.SetContext(methodContext.call_parameters());
                }
                else if (methodContext.picky_parameters() != null)
                {
                    OverloadChooser.SetContext(methodContext.picky_parameters());
                }
                else
                {
                    OverloadChooser.SetContext();
                }

                CallingMethod   = (IMethod)OverloadChooser.Overload;
                ParameterValues = OverloadChooser.Values;

                if (CallingMethod != null)
                {
                    if (CallingMethod is DefinedFunction)
                    {
                        var definedFunction = (DefinedFunction)CallingMethod;
                        definedFunction.Call(parseInfo.Script, NameRange);
                        parseInfo.CurrentCallInfo?.Call(definedFunction, NameRange);
                    }

                    parseInfo.Script.AddHover(DocRange.GetRange(methodContext), CallingMethod.GetLabel(true));

                    if (usedAsExpression && !CallingMethod.DoesReturnValue())
                    {
                        parseInfo.Script.Diagnostics.Error("The chosen overload for " + methodName + " does not return a value.", NameRange);
                    }
                }
            }
        }
コード例 #5
0
        /// <summary>
        /// Check if current request is match the given parameters of the method.
        /// </summary>
        /// <param name="context">The HttpContext</param>
        /// <param name="callingMethod">The method to compare.</param>
        /// <returns>True if matched otherwise false.</returns>
        public bool IsMatch(HttpListenerContext context, CallingMethod callingMethod)
        {
            if (callingMethod.WebApiType != WebApiType.Get)
            {
                return(false);
            }

            var queryData = context.Request.QueryString;

            var argCount = 0;

            foreach (var parameter in callingMethod.Parameters)
            {
                if (parameter.FromType == FromType.FromUrl)
                {
                    var paramType = parameter.ParameterType;
                    if (!_properties.ContainsKey(paramType))
                    {
                        _properties.Add(paramType,
                                        paramType.GetProperties().Where(x => x.CanRead && x.CanWrite).ToArray());
                    }

                    var properties = _properties[paramType];
                    foreach (var property in properties)
                    {
                        if (!queryData.AllKeys.Contains(property.Name))
                        {
                            return(false);
                        }
                    }
                }
                else
                {
                    if (!queryData.AllKeys.Contains(parameter.Name))
                    {
                        return(false);
                    }
                }

                argCount++;
            }

            return(argCount == callingMethod.Parameters.Count);
        }
コード例 #6
0
        public void TestCallingMethod()
        {
            var method = new CallingMethod();

            Console.WriteLine("\nFileName={0}", method.FileName);
            Console.WriteLine("FilePath={0}", method.FilePath);
            Console.WriteLine("LineNumber={0}", method.LineNumber);
            Console.WriteLine("MethodName={0}", method.MethodName);
            Console.WriteLine("MethodNameFull={0}", method.MethodNameFull);
            Console.WriteLine("MethodSignature={0}", method.MethodSignature);
            Console.WriteLine("MethodSignatureFull={0}", method.MethodSignatureFull);
            Console.WriteLine("Namespace={0}", method.Namespace);
            Console.WriteLine("ReturnName={0}", method.ReturnName);
            Console.WriteLine("MediaTypeNames.Text={0}", method.Text);
            Console.WriteLine("TypeName={0}", method.TypeName);
            Console.WriteLine("TypeNameFull={0}", method.TypeNameFull);

            ErrorLog.LogError("This is a unit test -ignore", method, "FNSBA");
        }
コード例 #7
0
        public CallMethodAction(ParseInfo parseInfo, Scope scope, DeltinScriptParser.MethodContext methodContext, bool usedAsExpression, Scope getter)
        {
            this.parseInfo = parseInfo;
            string methodName = methodContext.PART().GetText();

            NameRange = DocRange.GetRange(methodContext.PART());

            UsedAsExpression = usedAsExpression;

            if (methodContext.ASYNC() != null)
            {
                if (methodContext.NOT() == null)
                {
                    Parallel = CallParallel.AlreadyRunning_RestartRule;
                }
                else
                {
                    Parallel = CallParallel.AlreadyRunning_DoNothing;
                }
            }

            // Get all functions with the same name in the current scope.
            var options = scope.GetMethodsByName(methodName);

            // If none are found, throw a syntax error.
            if (options.Length == 0)
            {
                parseInfo.Script.Diagnostics.Error($"No method by the name of '{methodName}' exists in the current context.", NameRange);
            }
            else
            {
                // Make an OverloadChooser to choose an Overload.
                OverloadChooser = new OverloadChooser(options, parseInfo, scope, getter, NameRange, DocRange.GetRange(methodContext), new OverloadError("method '" + methodName + "'"));
                // Apply the parameters.
                OverloadChooser.Apply(methodContext.call_parameters());

                // Get the best function.
                CallingMethod   = (IMethod)OverloadChooser.Overload;
                ParameterValues = OverloadChooser.Values;

                // CallingMethod may be null if no good functions are found.
                if (CallingMethod != null)
                {
                    CallingMethod.Call(parseInfo, NameRange);

                    // If the function's block needs to be applied, check optional restricted calls when 'Applied()' runs.
                    if (CallingMethod is IApplyBlock applyBlock)
                    {
                        applyBlock.OnBlockApply(this);
                    }
                    else // Otherwise, the optional restricted calls can be resolved right away.
                    {
                        // Get optional parameter's restricted calls.
                        OverloadChooser.Match?.CheckOptionalsRestrictedCalls(parseInfo, NameRange);
                    }

                    // Check if the function can be called in parallel.
                    if (Parallel != CallParallel.NoParallel && !CallingMethod.Attributes.Parallelable)
                    {
                        parseInfo.Script.Diagnostics.Error($"The method '{CallingMethod.Name}' cannot be called in parallel.", NameRange);
                    }

                    parseInfo.Script.AddHover(DocRange.GetRange(methodContext), CallingMethod.GetLabel(true));
                }
            }
        }
コード例 #8
0
 // IExpression
 public IWorkshopTree Parse(ActionSet actionSet)
 {
     return(CallingMethod.Parse(actionSet.New(NameRange), GetMethodCall(actionSet)));
 }
コード例 #9
0
 // IStatement
 public void Translate(ActionSet actionSet)
 {
     CallingMethod.Parse(actionSet.New(NameRange), GetMethodCall(actionSet));
 }
コード例 #10
0
 /// <summary>
 /// Check if match the WebApiType
 /// </summary>
 /// <param name="callingMethod">The method to check</param>
 /// <returns>True if matched otherwise false.</returns>
 protected virtual bool WebApiTypeMatched(CallingMethod callingMethod)
 {
     return(callingMethod.WebApiType == WebApiType.Post);
 }
コード例 #11
0
 /// <summary>
 /// Check if match the WebApiType
 /// </summary>
 /// <param name="callingMethod">The method to check</param>
 /// <returns>True if matched otherwise false.</returns>
 protected override bool WebApiTypeMatched(CallingMethod callingMethod)
 {
     return(callingMethod.WebApiType == WebApiType.Delete);
 }
コード例 #12
0
        /// <summary>
        /// Dispatch the http context to the router.
        /// </summary>
        /// <param name="context">The context to be dispatched.</param>
        public void DispatchCall(HttpListenerContext context)
        {
            var handlerExist = false;
            var httpMethod   = context.Request.HttpMethod.ToLower();

            Logger.Write($"Handle request [{httpMethod}]: {context.Request.Url}");
            try
            {
                var urlInfo = WebApiUrlInfoParser.Parser(_applicationName, context.Request.Url);
                if (urlInfo != null)
                {
                    var key = $"{urlInfo.Version}/{urlInfo.HandlerName}";
                    if (_handlers.ContainsKey(key))
                    {
                        var           matcher       = _matchers[httpMethod];
                        CallingMethod callingMethod = null;
                        if (!string.IsNullOrEmpty(urlInfo.ActionName))
                        {
                            callingMethod = _handlers[key].GetCallingMethod(urlInfo.ActionName);
                            if (callingMethod != null)
                            {
                                if (!matcher.IsMatch(context, callingMethod))
                                {
                                    callingMethod = null;
                                }
                            }
                        }
                        else
                        {
                            var callingMethods = _handlers[key].GetCallingMethods();
                            foreach (var method in callingMethods)
                            {
                                if (matcher.IsMatch(context, method))
                                {
                                    callingMethod = method;
                                    break;
                                }
                            }
                        }
                        if (callingMethod != null)
                        {
                            if (_parsers.ContainsKey(httpMethod))
                            {
                                var parser = _parsers[httpMethod];
                                var args   = parser.Parse(context, callingMethod.Parameters.ToArray());
                                //The parser will add context into the args, so the final count is parameter count + 1.
                                if (args != null && args.Length == callingMethod.Parameters.Count + 1)
                                {
                                    handlerExist = true;
                                    try
                                    {
                                        callingMethod.Call(args);
                                    }
                                    catch (Exception ex)
                                    {
                                        var argStr = new StringBuilder();
                                        foreach (var arg in args)
                                        {
                                            argStr.AppendLine($"{arg.Name} = {arg.Value}");
                                        }

                                        Logger.Write(
                                            $"Call method {callingMethod.Name} with args:{Environment.NewLine + argStr + Environment.NewLine} error :{ex}");
                                        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                                        context.Response.Close();
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Write($"Handle request error: {ex}");
            }

            if (!handlerExist)
            {
                Logger.Write($"Handler for request: {context.Request.Url} not found.");
                context.Response.StatusCode = (int)HttpStatusCode.NotFound;
                context.Response.Close();
            }
        }
コード例 #13
0
 // IStatement
 public void Translate(ActionSet actionSet)
 {
     CallingMethod.Parse(actionSet.New(NameRange), GetParameterValuesAsWorkshop(actionSet), OverloadChooser.AdditionalParameterData);
 }
コード例 #14
0
 // IExpression
 public IWorkshopTree Parse(ActionSet actionSet, bool asElement = true)
 {
     return(CallingMethod.Parse(actionSet.New(NameRange), GetParameterValuesAsWorkshop(actionSet), OverloadChooser.AdditionalParameterData));
 }