public void Applied() { if (UsedAsExpression && !CallingMethod.DoesReturnValue()) { parseInfo.Script.Diagnostics.Error("The chosen overload for " + CallingMethod.Name + " does not return a value.", NameRange); } }
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)); } } }
/// <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); }
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); } } } }
/// <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); }
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"); }
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)); } } }
// IExpression public IWorkshopTree Parse(ActionSet actionSet) { return(CallingMethod.Parse(actionSet.New(NameRange), GetMethodCall(actionSet))); }
// IStatement public void Translate(ActionSet actionSet) { CallingMethod.Parse(actionSet.New(NameRange), GetMethodCall(actionSet)); }
/// <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); }
/// <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); }
/// <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(); } }
// IStatement public void Translate(ActionSet actionSet) { CallingMethod.Parse(actionSet.New(NameRange), GetParameterValuesAsWorkshop(actionSet), OverloadChooser.AdditionalParameterData); }
// IExpression public IWorkshopTree Parse(ActionSet actionSet, bool asElement = true) { return(CallingMethod.Parse(actionSet.New(NameRange), GetParameterValuesAsWorkshop(actionSet), OverloadChooser.AdditionalParameterData)); }