Exemple #1
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));
                }
            }
        }
Exemple #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;
                }
            }

            // 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));
                }
            }
        }
Exemple #3
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();
            }
        }