/// <summary>
        /// Parses and returns a class, struct, or interface.
        /// </summary>
        /// <param name="elementType">The type of the element.</param>
        /// <param name="parent">The parent of the element.</param>
        /// <param name="elementReference">A reference to the element being created.</param>
        /// <param name="partialElements">The collection of partial elements found while parsing the files.</param>
        /// <param name="unsafeCode">Indicates whether the code is marked as unsafe.</param>
        /// <param name="generated">Indicates whether the code is marked as generated code.</param>
        /// <param name="xmlHeader">The element's documentation header.</param>
        /// <param name="attributes">The attributes on the element.</param>
        /// <returns>Returns the element.</returns>
        private ClassBase ParseClass(
            ElementType elementType,
            CsElement parent,
            Reference<ICodePart> elementReference,
            Dictionary<string, List<CsElement>> partialElements,
            bool unsafeCode,
            bool generated,
            XmlHeader xmlHeader,
            ICollection<Attribute> attributes)
        {
            Param.Ignore(elementType);
            Param.AssertNotNull(parent, "parent");
            Param.AssertNotNull(elementReference, "elementReference");
            Param.AssertNotNull(partialElements, "partialElements");
            Param.Ignore(unsafeCode);
            Param.Ignore(generated);
            Param.Ignore(xmlHeader);
            Param.Ignore(attributes);

            Node<CsToken> previousTokenNode = this.tokens.Last;

            // Top-level classes, structs, and interfaces received Internal access by default, while classes, structs, and interfaces
            // declared within a class receive Private access by default.
            AccessModifierType accessModifier = AccessModifierType.Internal;
            if (parent.ElementType == ElementType.Class)
            {
                accessModifier = AccessModifierType.Private;
            }

            // Get the modifiers and access.
            Dictionary<CsTokenType, CsToken> modifiers = this.GetElementModifiers(elementReference, ref accessModifier, ClassModifiers);

            unsafeCode |= modifiers.ContainsKey(CsTokenType.Unsafe);

            // Get the element keyword, depending on the element type.
            CsTokenType keywordType = CsTokenType.Class;
            SymbolType symbolType = SymbolType.Class;
            if (elementType == ElementType.Struct)
            {
                keywordType = CsTokenType.Struct;
                symbolType = SymbolType.Struct;
            }
            else if (elementType == ElementType.Interface)
            {
                keywordType = CsTokenType.Interface;
                symbolType = SymbolType.Interface;
            }
            else
            {
                Debug.Assert(
                    elementType == ElementType.Class,
                    "The method can only be called for a class, struct, or interface");
            }

            // Add the keyword token.
            this.tokens.Add(this.GetToken(keywordType, symbolType, elementReference));

            // Add the class name token.
            CsToken name = this.GetElementNameToken(elementReference, unsafeCode);
            this.tokens.Add(name);

            // Get the base classes.
            Symbol symbol = this.GetNextSymbol(elementReference);

            if (symbol.SymbolType == SymbolType.Colon)
            {
                // Add the colon token.
                this.tokens.Add(this.GetToken(CsTokenType.BaseColon, SymbolType.Colon, elementReference));

                // Get each of the base classes and interfaces.
                while (true)
                {
                    this.tokens.Add(this.GetTypeToken(elementReference, unsafeCode, false));

                    symbol = this.GetNextSymbol(elementReference);
                    if (symbol.SymbolType != SymbolType.Comma)
                    {
                        break;
                    }

                    this.tokens.Add(this.GetToken(CsTokenType.Comma, SymbolType.Comma, elementReference));
                }
            }

            // Check whether there are any type constraint clauses.
            ICollection<TypeParameterConstraintClause> typeConstraints = null;
            symbol = this.GetNextSymbol(elementReference);
            if (symbol.Text == "where")
            {
                typeConstraints = this.ParseTypeConstraintClauses(elementReference, unsafeCode);
            }

            // Create the declaration.
            Node<CsToken> firstTokenNode = previousTokenNode == null ? this.tokens.First : previousTokenNode.Next;
            CsTokenList declarationTokens = new CsTokenList(this.tokens, firstTokenNode, this.tokens.Last);
            Declaration declaration = new Declaration(
                declarationTokens, name.Text, elementType, accessModifier, modifiers);

            // Create the element.
            ClassBase item = null;
            if (keywordType == CsTokenType.Class)
            {
                item = new Class(this.document, parent, xmlHeader, attributes, declaration, typeConstraints, unsafeCode, generated);
            }
            else if (keywordType == CsTokenType.Struct)
            {
                item = new Struct(this.document, parent, xmlHeader, attributes, declaration, typeConstraints, unsafeCode, generated);
            }
            else
            {
                Debug.Assert(keywordType == CsTokenType.Interface, "Invalid element type");
                item = new Interface(this.document, parent, xmlHeader, attributes, declaration, typeConstraints, unsafeCode, generated);
            }

            elementReference.Target = item;

            // Parse the body of the element.
            this.ParseElementContainer(item, elementReference, partialElements, unsafeCode);

            return item;
        }
Пример #2
0
        private ClassBase ParseClass(ElementType elementType, CsElement parent, Dictionary<string, List<CsElement>> partialElements, bool unsafeCode, bool generated, XmlHeader xmlHeader, ICollection<Microsoft.StyleCop.CSharp.Attribute> attributes)
        {
            Microsoft.StyleCop.Node<CsToken> last = this.tokens.Last;
            AccessModifierType accessModifier = AccessModifierType.Internal;
            if (parent.ElementType == ElementType.Class)
            {
                accessModifier = AccessModifierType.Private;
            }
            Dictionary<CsTokenType, CsToken> elementModifiers = this.GetElementModifiers(ref accessModifier, ClassModifiers);
            unsafeCode |= elementModifiers.ContainsKey(CsTokenType.Unsafe);
            CsTokenType tokenType = CsTokenType.Class;
            SymbolType symbolType = SymbolType.Class;
            if (elementType == ElementType.Struct)
            {
                tokenType = CsTokenType.Struct;
                symbolType = SymbolType.Struct;
            }
            else if (elementType == ElementType.Interface)
            {
                tokenType = CsTokenType.Interface;
                symbolType = SymbolType.Interface;
            }
            this.tokens.Add(this.GetToken(tokenType, symbolType));
            CsToken elementNameToken = this.GetElementNameToken(unsafeCode);
            this.tokens.Add(elementNameToken);
            if (this.GetNextSymbol().SymbolType == SymbolType.Colon)
            {
                this.tokens.Add(this.GetToken(CsTokenType.BaseColon, SymbolType.Colon));
                while (true)
                {
                    this.tokens.Add(this.GetTypeToken(unsafeCode, false));
                    if (this.GetNextSymbol().SymbolType != SymbolType.Comma)
                    {
                        break;
                    }
                    this.tokens.Add(this.GetToken(CsTokenType.Comma, SymbolType.Comma));
                }
            }
            ICollection<TypeParameterConstraintClause> typeConstraints = null;
            if (this.GetNextSymbol().Text == "where")
            {
                typeConstraints = this.ParseTypeConstraintClauses(unsafeCode);
            }
            Microsoft.StyleCop.Node<CsToken> firstItemNode = (last == null) ? this.tokens.First : last.Next;
            CsTokenList tokens = new CsTokenList(this.tokens, firstItemNode, this.tokens.Last);
            Declaration declaration = new Declaration(tokens, elementNameToken.Text, elementType, accessModifier, elementModifiers);
            ClassBase element = null;
            switch (tokenType)
            {
                case CsTokenType.Class:
                    element = new Class(this.document, parent, xmlHeader, attributes, declaration, typeConstraints, unsafeCode, generated);
                    break;

                case CsTokenType.Struct:
                    element = new Struct(this.document, parent, xmlHeader, attributes, declaration, typeConstraints, unsafeCode, generated);
                    break;

                default:
                    element = new Interface(this.document, parent, xmlHeader, attributes, declaration, typeConstraints, unsafeCode, generated);
                    break;
            }
            this.ParseElementContainer(element, partialElements, unsafeCode);
            return element;
        }