public DefinedMethod(ParseInfo parseInfo, Scope scope, DeltinScriptParser.Define_methodContext context)
            : base(parseInfo, scope, context.name.Text, new Location(parseInfo.Script.Uri, DocRange.GetRange(context.name)))
        {
            this.context = context;

            // Check if recursion is enabled.
            IsRecursive = context.RECURSIVE() != null;

            // Get the type.
            ReturnType = CodeType.GetCodeTypeFromContext(parseInfo, context.code_type());

            // Get the access level.
            AccessLevel = context.accessor().GetAccessLevel();

            // Setup the parameters and parse the block.
            SetupParameters(context.setParameters());

            if (context.block() == null)
            {
                parseInfo.Script.Diagnostics.Error("Expected block.", DocRange.GetRange(context.name));
            }

            scope.AddMethod(this, parseInfo.Script.Diagnostics, DocRange.GetRange(context.name));

            // Add the hover info.
            parseInfo.Script.AddHover(DocRange.GetRange(context.name), GetLabel(true));
        }
        private void ValidateReturns(ScriptFile script, DeltinScriptParser.Define_methodContext context)
        {
            ReturnAction[] returns = GetReturns();
            if (returns.Any(ret => ret.ReturningValue != null))
            {
                doesReturnValue = true;

                // If there is only one return statement, return the reference to
                // the return statement to reduce the number of actions.
                multiplePaths = returns.Length > 1;

                // Syntax error if there are any paths that don't return a value.
                CheckPath(script, new PathInfo(block, DocRange.GetRange(context.name), true));

                // If one return statement returns a value, the rest must as well.
                foreach (var ret in returns)
                {
                    if (ret.ReturningValue == null)
                    {
                        script.Diagnostics.Error("Must return a value.", ret.ErrorRange);
                    }
                }
            }
        }
Esempio n. 3
0
        public DefinedMethod(ParseInfo parseInfo, Scope objectScope, Scope staticScope, DeltinScriptParser.Define_methodContext context, CodeType containingType)
            : base(parseInfo, context.name.Text, new Location(parseInfo.Script.Uri, DocRange.GetRange(context.name)))
        {
            this.context = context;
            Attributes.ContainingType = containingType;

            DocRange nameRange = DocRange.GetRange(context.name);

            // Get the attributes.
            GetAttributes();

            SetupScope(Static ? staticScope : objectScope);
            methodScope.MethodContainer = true;
            BlockScope = methodScope.Child();

            // Get the type.
            if (context.VOID() == null)
            {
                doesReturnValue = true;
                ReturnType      = CodeType.GetCodeTypeFromContext(parseInfo, context.code_type());
            }

            // Setup the parameters and parse the block.
            if (!IsSubroutine)
            {
                SetupParameters(context.setParameters(), false);
            }
            else
            {
                subroutineDefaultGlobal = context.PLAYER() == null;
                Attributes.Parallelable = true;
                parseInfo.TranslateInfo.AddSubroutine(this);

                // Subroutines should not have parameters.
                SetupParameters(context.setParameters(), true);
            }

            // Override attribute.
            if (Attributes.Override)
            {
                IMethod overriding = objectScope.GetMethodOverload(this);

                // No method with the name and parameters found.
                if (overriding == null)
                {
                    parseInfo.Script.Diagnostics.Error("Could not find a method to override.", nameRange);
                }
                else if (!overriding.Attributes.IsOverrideable)
                {
                    parseInfo.Script.Diagnostics.Error("The specified method is not marked as virtual.", nameRange);
                }
                else
                {
                    overriding.Attributes.AddOverride(this);
                }

                if (overriding != null && overriding.DefinedAt != null)
                {
                    // Make the override keyword go to the base method.
                    parseInfo.Script.AddDefinitionLink(
                        attributes.First(at => at.Type == MethodAttributeType.Override).Range,
                        overriding.DefinedAt
                        );

                    if (!Attributes.Recursive)
                    {
                        Attributes.Recursive = overriding.Attributes.Recursive;
                    }
                }
            }

            if (Attributes.IsOverrideable && AccessLevel == AccessLevel.Private)
            {
                parseInfo.Script.Diagnostics.Error("A method marked as virtual or abstract must have the protection level 'public' or 'protected'.", nameRange);
            }

            // Syntax error if the block is missing.
            if (context.block() == null)
            {
                parseInfo.Script.Diagnostics.Error("Expected block.", nameRange);
            }

            // Add to the scope. Check for conflicts if the method is not overriding.
            containingScope.AddMethod(this, parseInfo.Script.Diagnostics, nameRange, !Attributes.Override);

            // Add the hover info.
            parseInfo.Script.AddHover(DocRange.GetRange(context.name), GetLabel(true));

            if (Attributes.IsOverrideable)
            {
                parseInfo.Script.AddCodeLensRange(new ImplementsCodeLensRange(this, parseInfo.Script, CodeLensSourceType.Function, nameRange));
            }

            parseInfo.TranslateInfo.ApplyBlock(this);
        }
 public MethodAttributesGetter(DeltinScriptParser.Define_methodContext context, IFunctionAppendResult result) : base(result)
 {
     Context = context;
 }