예제 #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));
                }
            }
        }
예제 #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));
                }
            }
        }