public MethodNode(DeltinScriptParser.MethodContext context, BuildAstVisitor visitor) : base( new Location(visitor.file, DocRange.GetRange(context)), DocRange.GetRange(context.PART().Symbol), DocRange.GetRange(context.LEFT_PAREN().Symbol, context.RIGHT_PAREN().Symbol) ) { Name = context.PART().GetText(); if (context.call_parameters() != null) { Parameters = new Node[context.call_parameters().expr().Length]; for (int i = 0; i < Parameters.Length; i++) { Parameters[i] = visitor.Visit(context.call_parameters().expr()[i]); } } else if (context.picky_parameters() != null) { PickyParameters = new PickyParameter[context.picky_parameters().picky_parameter().Length]; for (int i = 0; i < PickyParameters.Length; i++) { PickyParameters[i] = new PickyParameter(context.picky_parameters().picky_parameter(i), visitor); } } else { Parameters = new Node[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)); } } }
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); } } } }
// Method() public override Node VisitMethod(DeltinScriptParser.MethodContext context) { string methodName = context.PART().GetText(); Node[] parameters = new Node[context.call_parameters()?.expr().Length ?? 0]; for (int i = 0; i < parameters.Length; i++) { parameters[i] = Visit(context.call_parameters().expr()[i]); } Range nameRange = Range.GetRange(context.PART().Symbol); Range parameterRange = Range.GetRange(context.LEFT_PAREN().Symbol, context.RIGHT_PAREN().Symbol); return(new MethodNode(methodName, parameters, nameRange, parameterRange, new Location(file, Range.GetRange(context)))); }
// Method() public override Node VisitMethod(DeltinScriptParser.MethodContext context) { string methodName = context.PART().GetText(); // TODO check null check spots in []. IExpressionNode[] parameters = new IExpressionNode[context.parameters()?.expr().Length ?? 0]; for (int i = 0; i < parameters.Length; i++) { parameters[i] = (IExpressionNode)Visit(context.parameters().expr()[i]); } Node node = new MethodNode(methodName, parameters, Range.GetRange(context)); CheckRange(node); return(node); }
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)); } } }
public TreeContextPart(DeltinScriptParser.MethodContext method) { this.method = method ?? throw new ArgumentNullException(nameof(method)); Range = DocRange.GetRange(method); CompletionRange = DocRange.GetRange(method.PART()); }
Element ParseMethod(DeltinScriptParser.MethodContext methodContext, bool needsToBeValue) { // Get the method name string methodName = methodContext.PART().GetText(); // Get the method type. Type methodType = Element.GetMethod(methodName); MethodInfo customMethod = CustomMethods.GetCustomMethod(methodName); if (methodType != null && customMethod != null) { throw new Exception("Conflicting Overwatch method and custom method."); } if (methodType == null && customMethod == null) { throw new SyntaxErrorException($"The method {methodName} does not exist.", methodContext.start); } bool isCustomMethod = methodType == null; // Parse parameters var parseParameters = methodContext.expr(); Parameter[] parameterData; string fullMethodName; Element method = null; if (!isCustomMethod) { parameterData = methodType.GetCustomAttributes <Parameter>().ToArray(); method = (Element)Activator.CreateInstance(methodType); fullMethodName = method.ToString(); } else { parameterData = customMethod.GetCustomAttributes <Parameter>().ToArray(); fullMethodName = CustomMethods.GetName(customMethod); } if (parseParameters.Length > parameterData.Length) { throw new SyntaxErrorException($"Too many arguments in the method {methodName} which only takes {parameterData.Length} parameters.", methodContext.start); } List <object> finalParameters = new List <object>(); for (int i = 0; i < parseParameters.Length; i++) { finalParameters.Add(ParseParameter(parseParameters[i], fullMethodName, parameterData[i])); } if (isCustomMethod) { MethodResult result = (MethodResult)customMethod.Invoke(null, new object[] { IsGlobal, finalParameters.ToArray() }); switch (result.MethodType) { case CustomMethodType.Action: if (needsToBeValue) { throw new IncorrectElementTypeException(fullMethodName, true); } break; case CustomMethodType.MultiAction_Value: case CustomMethodType.Value: if (!needsToBeValue) { throw new IncorrectElementTypeException(fullMethodName, false); } break; } if (result.Elements != null) { Actions.AddRange(result.Elements); } finalParameters = null; method = result.Result; } else { method.ParameterValues = finalParameters?.ToArray(); } return(method); }
// Method() public override Node VisitMethod(DeltinScriptParser.MethodContext context) { return(new MethodNode(context, this)); }