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];
            }
        }
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;
                }
            }

            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 #3
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);
                    }
                }
            }
        }
        // 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))));
        }
Exemple #5
0
        // 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);
        }
Exemple #6
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));
                }
            }
        }
 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);
        }