예제 #1
0
        /// <summary>Creates a macro from a Define_macroContext.</summary>
        /// <param name="objectScope">The scope of the macro if there is no static attribute.</param>
        /// <param name="staticScope">The scope of the macro if there is a static attribute.</param>
        /// <param name="macroContext">The context of the macro.</param>
        /// <returns>A DefinedMacro if the macro has parameters, a MacroVar if there are no parameters.</returns>
        public DefinedMacro GetMacro(Scope objectScope, Scope staticScope, MacroFunctionContext macroContext)
        {
            // Get the return type.
            CodeType returnType = CodeType.GetCodeTypeFromContext(this, macroContext.Type);

            DefinedMacro newMacro = new DefinedMacro(this, objectScope, staticScope, macroContext, returnType);

            TranslateInfo.ApplyBlock((IApplyBlock)newMacro);
            return(newMacro);
        }
        public DefinedMacro(ParseInfo parseInfo, Scope objectScope, Scope staticScope, MacroFunctionContext context, CodeType returnType)
            : base(parseInfo, context.Identifier.Text, new LanguageServer.Location(parseInfo.Script.Uri, context.Identifier.Range))
        {
            _context = context;
            DocRange nameRange = context.Identifier.Range;

            Attributes.ContainingType = (Static ? staticScope : objectScope).This;

            // Get the attributes.
            MethodAttributeAppender  attributeResult = new MethodAttributeAppender(Attributes);
            FunctionAttributesGetter attributeInfo   = new MacroAttributesGetter(context, attributeResult);

            attributeInfo.GetAttributes(parseInfo.Script.Diagnostics);

            // Copy attribute results
            Static      = attributeResult.Static;
            AccessLevel = attributeResult.AccessLevel;

            SetupScope(Static ? staticScope : objectScope);
            CodeType        = returnType;
            DoesReturnValue = true;

            SetupParameters(context.Parameters, false);

            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 macro 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(
                        attributeInfo.ObtainedAttributes.First(at => at.Type == MethodAttributeType.Override).Range,
                        overriding.DefinedAt
                        );
                }
            }

            containingScope.AddMethod(this, parseInfo.Script.Diagnostics, DefinedAt.range, !Attributes.Override);

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

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