示例#1
0
        /// <summary>
        /// Reads an expression wrapped in parenthesis.
        /// </summary>
        /// <param name="sourceCode">
        /// The source code containing the expression.
        /// </param>
        /// <param name="parentReference">
        /// The parent code part.
        /// </param>
        /// <returns>
        /// Returns the expression.
        /// </returns>
        private ParenthesizedExpression GetConditionalPreprocessorParenthesizedExpression(SourceCode sourceCode, Reference <ICodePart> parentReference)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");
            Param.AssertNotNull(parentReference, "parentReference");

            // Get the opening parenthesis.
            this.AdvanceToNextConditionalDirectiveCodeSymbol(parentReference);
            Symbol firstSymbol = this.symbols.Peek(1);

            if (firstSymbol == null || firstSymbol.SymbolType != SymbolType.OpenParenthesis)
            {
                throw new SyntaxException(sourceCode, firstSymbol.LineNumber);
            }

            Reference <ICodePart> expressionReference = new Reference <ICodePart>();

            this.symbols.Advance();
            Bracket openParenthesis = new Bracket(firstSymbol.Text, CsTokenType.OpenParenthesis, firstSymbol.Location, expressionReference, this.symbols.Generated);

            Node <CsToken> openParenthesisNode = this.tokens.InsertLast(openParenthesis);

            // Get the inner expression.
            Expression innerExpression = this.GetNextConditionalPreprocessorExpression(sourceCode, ExpressionPrecedence.None);

            if (innerExpression == null)
            {
                throw new SyntaxException(sourceCode, firstSymbol.LineNumber);
            }

            // Get the closing parenthesis.
            this.AdvanceToNextConditionalDirectiveCodeSymbol(expressionReference);
            Symbol symbol = this.symbols.Peek(1);

            if (symbol == null || symbol.SymbolType != SymbolType.CloseParenthesis)
            {
                throw new SyntaxException(sourceCode, firstSymbol.LineNumber);
            }

            this.symbols.Advance();
            Bracket        closeParenthesis     = new Bracket(symbol.Text, CsTokenType.CloseParenthesis, symbol.Location, expressionReference, this.symbols.Generated);
            Node <CsToken> closeParenthesisNode = this.tokens.InsertLast(closeParenthesis);

            openParenthesis.MatchingBracketNode  = closeParenthesisNode;
            closeParenthesis.MatchingBracketNode = openParenthesisNode;

            // Create the token list for the expression.
            CsTokenList partialTokens = new CsTokenList(this.tokens, openParenthesisNode, this.tokens.Last);

            // Create and return the expression.
            ParenthesizedExpression expression = new ParenthesizedExpression(partialTokens, innerExpression);

            expressionReference.Target = expression;

            return(expression);
        }
示例#2
0
        /// <summary>
        /// Parses an attribute.
        /// </summary>
        /// <param name="parentReference">
        /// The parent code unit.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the attribute lies within a block of unsafe code.
        /// </param>
        /// <param name="masterDocument">
        /// The master document object.
        /// </param>
        /// <returns>
        /// Returns the attribute.
        /// </returns>
        internal Attribute ParseAttribute(Reference<ICodePart> parentReference, bool unsafeCode, CsDocument masterDocument)
        {
            Param.AssertNotNull(parentReference, "parentReference");
            Param.Ignore(unsafeCode);
            Param.AssertNotNull(masterDocument, "masterDocument");

            Debug.Assert(this.document == null, "A CodeParser instance may only be used once.");
            this.document = masterDocument;

            Reference<ICodePart> attributeReference = new Reference<ICodePart>();

            // Get the first symbol and make sure it is the right type.
            Symbol firstSymbol = this.symbols.Peek(1);
            Debug.Assert(firstSymbol != null && firstSymbol.SymbolType == SymbolType.OpenSquareBracket, "Expected an opening square bracket");

            // The list of attribute expressions in the attribute.
            List<AttributeExpression> attributeExpressions = new List<AttributeExpression>();

            // Move past the opening square bracket.
            Bracket openingBracket = new Bracket(firstSymbol.Text, CsTokenType.OpenAttributeBracket, firstSymbol.Location, attributeReference, this.symbols.Generated);
            Node<CsToken> openingBracketNode = this.tokens.InsertLast(openingBracket);
            this.symbols.Advance();

            // Get each of the child attribute expressions within this attribute.
            while (true)
            {
                // Move to the next symbol.
                this.AdvanceToNextCodeSymbol(attributeReference);
                Symbol symbol = this.symbols.Peek(1);
                if (symbol == null)
                {
                    throw new SyntaxException(this.document.SourceCode, firstSymbol.LineNumber);
                }

                // Check the type. If this is the closing bracket then we are done.
                if (symbol.SymbolType == SymbolType.CloseSquareBracket)
                {
                    Bracket closingBracket = new Bracket(symbol.Text, CsTokenType.CloseAttributeBracket, symbol.Location, attributeReference, this.symbols.Generated);
                    Node<CsToken> closingBracketNode = this.tokens.InsertLast(closingBracket);
                    this.symbols.Advance();

                    openingBracket.MatchingBracketNode = closingBracketNode;
                    closingBracket.MatchingBracketNode = openingBracketNode;

                    break;
                }

                // Check to see if there is a target specified.
                LiteralExpression target = null;

                this.AdvanceToNextCodeSymbol(attributeReference);
                symbol = this.symbols.Peek(1);
                if (symbol == null)
                {
                    throw new SyntaxException(this.document.SourceCode, firstSymbol.LineNumber);
                }

                Node<CsToken> previousTokenNode = this.tokens.Last;
                Reference<ICodePart> attributeExpressionReference = new Reference<ICodePart>();

                if (symbol.SymbolType == SymbolType.Other || symbol.SymbolType == SymbolType.Return)
                {
                    // Peek ahead to the next symbol and check if it's a colon.
                    int index = this.GetNextCodeSymbolIndex(2);
                    if (index != -1)
                    {
                        Symbol colon = this.symbols.Peek(index);

                        if (colon.SymbolType == SymbolType.Colon)
                        {
                            // This is a target. Get the literal target expression and move past the colon.
                            // Change the type of the target symbol to OTHER so that it will be parsed
                            // correctly by the literal expression parser.
                            symbol.SymbolType = SymbolType.Other;

                            // Get the literal expression.
                            Reference<ICodePart> targetReference = new Reference<ICodePart>();
                            target = this.GetLiteralExpression(targetReference, unsafeCode);
                            Debug.Assert(target != null, "We should always succeed getting a Literal here since we have already seen a type of Other.");

                            targetReference.Target = target;

                            // Add the colon.
                            this.AdvanceToNextCodeSymbol(attributeExpressionReference);
                            this.tokens.Add(new CsToken(colon.Text, CsTokenType.AttributeColon, colon.Location, attributeExpressionReference, this.symbols.Generated));

                            this.symbols.Advance();

                            this.AdvanceToNextCodeSymbol(attributeExpressionReference);
                        }
                    }
                }

                // Now get the attribute call expression.
                Expression initialization = this.GetNextExpression(ExpressionPrecedence.None, attributeExpressionReference, unsafeCode);
                if (initialization == null)
                {
                    throw new SyntaxException(this.document.SourceCode, firstSymbol.LineNumber);
                }

                // Create and add the attribute expression.
                Debug.Assert(previousTokenNode.Next != null, "Nothing was added to the token list!");

                AttributeExpression attributeExpression = new AttributeExpression(
                    new CsTokenList(this.tokens, previousTokenNode.Next, this.tokens.Last), target, initialization);

                attributeExpressions.Add(attributeExpression);
                attributeExpressionReference.Target = attributeExpression;

                // Get the next item, which must either be a comma or the closing attribute bracket.
                this.AdvanceToNextCodeSymbol(attributeReference);
                symbol = this.symbols.Peek(1);
                if (symbol == null)
                {
                    throw new SyntaxException(this.document.SourceCode, firstSymbol.LineNumber);
                }

                if (symbol.SymbolType == SymbolType.Comma)
                {
                    // Add the comma and continue.
                    this.tokens.Add(this.GetToken(CsTokenType.Comma, SymbolType.Comma, attributeReference));
                }
                else if (symbol.SymbolType != SymbolType.CloseSquareBracket)
                {
                    // This type of symbol is unexpected.
                    throw new SyntaxException(this.document.SourceCode, firstSymbol.LineNumber);
                }
            }

            // Get the location of the attribute.
            CodeLocation location = CsToken.JoinLocations(this.tokens.First, this.tokens.Last);

            // Create and return the attribute.
            Attribute attribute = new Attribute(
                this.tokens, location, parentReference, attributeExpressions.ToArray(), this.tokens.First.Value.Generated || this.tokens.Last.Value.Generated);

            attributeReference.Target = attribute;
            return attribute;
        }
示例#3
0
        private MasterList<CsToken> GetGenericArgumentList(Reference<ICodePart> genericTypeReference, bool unsafeCode, CsToken name, int startIndex, out int endIndex)
        {
            Param.AssertNotNull(genericTypeReference, "genericTypeReference");
            Param.Ignore(unsafeCode);
            Param.Ignore(name);
            Param.AssertGreaterThanOrEqualToZero(startIndex, "startIndex");

            endIndex = -1;
            MasterList<CsToken> genericArgumentListTokens = null;

            // Move past whitespace and comments.
            int index = startIndex;
            while (true)
            {
                Symbol next = this.symbols.Peek(index);
                if (next == null
                    || (next.SymbolType != SymbolType.WhiteSpace && next.SymbolType != SymbolType.EndOfLine && next.SymbolType != SymbolType.SingleLineComment
                        && next.SymbolType != SymbolType.MultiLineComment && next.SymbolType != SymbolType.PreprocessorDirective))
                {
                    break;
                }

                ++index;
            }

            // The next symbol should be an opening bracket, if this is a generic.
            Symbol symbol = this.symbols.Peek(index);
            if (symbol != null && symbol.SymbolType == SymbolType.LessThan)
            {
                // This might be a generic. Assume that it is and start creating tokens.
                genericArgumentListTokens = new MasterList<CsToken>();

                // Add the name if one was provided.
                if (name != null)
                {
                    genericArgumentListTokens.Add(name);
                }

                Node<CsToken> openingGenericBracketNode = null;

                // Add everything up to the opening bracket into the token list.
                for (int i = startIndex; i <= index; ++i)
                {
                    symbol = this.symbols.Peek(i);
                    Debug.Assert(symbol != null, "The next symbol should not be null");

                    if (symbol.SymbolType == SymbolType.LessThan)
                    {
                        if (openingGenericBracketNode != null)
                        {
                            // This is not a generic statement.
                            return null;
                        }

                        Bracket openingGenericBracket = new Bracket(
                            symbol.Text, CsTokenType.OpenGenericBracket, symbol.Location, genericTypeReference, this.symbols.Generated);
                        openingGenericBracketNode = genericArgumentListTokens.InsertLast(openingGenericBracket);
                    }
                    else
                    {
                        genericArgumentListTokens.Add(this.ConvertSymbol(symbol, TokenTypeFromSymbolType(symbol.SymbolType), genericTypeReference));
                    }
                }

                // Loop through the rest of the symbols.
                while (true)
                {
                    symbol = this.symbols.Peek(++index);
                    if (symbol == null)
                    {
                        // The code ran out before we found the end of the generic.
                        throw new SyntaxException(this.document.SourceCode, name.LineNumber);
                    }
                    else if (symbol.SymbolType == SymbolType.GreaterThan)
                    {
                        if (openingGenericBracketNode == null)
                        {
                            // This is not a generic statement.
                            return null;
                        }

                        // This is the end of the generic statement. Add the closing bracket to the token list.
                        Bracket closingGenericBracket = new Bracket(
                            symbol.Text, CsTokenType.CloseGenericBracket, symbol.Location, genericTypeReference, this.symbols.Generated);
                        Node<CsToken> closingGenericBracketNode = genericArgumentListTokens.InsertLast(closingGenericBracket);

                        ((Bracket)openingGenericBracketNode.Value).MatchingBracketNode = closingGenericBracketNode;
                        closingGenericBracket.MatchingBracketNode = openingGenericBracketNode;

                        endIndex = index;
                        break;
                    }
                    else if (symbol.SymbolType == SymbolType.Out || symbol.SymbolType == SymbolType.In)
                    {
                        // Get the in or out keyword.
                        genericArgumentListTokens.Add(
                            this.ConvertSymbol(symbol, symbol.SymbolType == SymbolType.In ? CsTokenType.In : CsTokenType.Out, genericTypeReference));
                    }
                    else if (symbol.SymbolType == SymbolType.Other)
                    {
                        int lastIndex = 0;
                        Reference<ICodePart> wordReference = new Reference<ICodePart>();
                        CsToken word = this.GetTypeTokenAux(wordReference, genericTypeReference, unsafeCode, true, false, index, out lastIndex);
                        if (word == null)
                        {
                            throw new SyntaxException(this.document.SourceCode, symbol.LineNumber);
                        }

                        // Advance the index to the end of the token.
                        index = lastIndex;

                        // Add the token.
                        genericArgumentListTokens.Add(word);
                    }
                    else if (symbol.SymbolType == SymbolType.WhiteSpace || symbol.SymbolType == SymbolType.EndOfLine || symbol.SymbolType == SymbolType.SingleLineComment
                             || symbol.SymbolType == SymbolType.MultiLineComment || symbol.SymbolType == SymbolType.PreprocessorDirective)
                    {
                        // Add these to the token list.
                        genericArgumentListTokens.Add(this.ConvertSymbol(symbol, TokenTypeFromSymbolType(symbol.SymbolType), genericTypeReference));
                    }
                    else if (symbol.SymbolType == SymbolType.Comma)
                    {
                        genericArgumentListTokens.Add(this.ConvertSymbol(symbol, CsTokenType.Comma, genericTypeReference));
                    }
                    else if (symbol.SymbolType == SymbolType.OpenSquareBracket)
                    {
                        // An attribute on the generic type.
                        genericArgumentListTokens.Add(this.GetAttribute(genericTypeReference, unsafeCode));
                    }
                    else
                    {
                        // Any other symbol signifies that this is not a generic statement.
                        genericArgumentListTokens = null;
                        break;
                    }
                }
            }

            return genericArgumentListTokens;
        }
        /// <summary>
        /// Reads an expression wrapped in parenthesis.
        /// </summary>
        /// <param name="sourceCode">
        /// The source code containing the expression.
        /// </param>
        /// <param name="parentReference">
        /// The parent code part.
        /// </param>
        /// <returns>
        /// Returns the expression.
        /// </returns>
        private ParenthesizedExpression GetConditionalPreprocessorParenthesizedExpression(SourceCode sourceCode, Reference<ICodePart> parentReference)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");
            Param.AssertNotNull(parentReference, "parentReference");

            // Get the opening parenthesis.
            this.AdvanceToNextConditionalDirectiveCodeSymbol(parentReference);
            Symbol firstSymbol = this.symbols.Peek(1);
            if (firstSymbol == null || firstSymbol.SymbolType != SymbolType.OpenParenthesis)
            {
                throw new SyntaxException(sourceCode, firstSymbol.LineNumber);
            }

            Reference<ICodePart> expressionReference = new Reference<ICodePart>();

            this.symbols.Advance();
            Bracket openParenthesis = new Bracket(firstSymbol.Text, CsTokenType.OpenParenthesis, firstSymbol.Location, expressionReference, this.symbols.Generated);

            Node<CsToken> openParenthesisNode = this.tokens.InsertLast(openParenthesis);

            // Get the inner expression.
            Expression innerExpression = this.GetNextConditionalPreprocessorExpression(sourceCode, ExpressionPrecedence.None);
            if (innerExpression == null)
            {
                throw new SyntaxException(sourceCode, firstSymbol.LineNumber);
            }

            // Get the closing parenthesis.
            this.AdvanceToNextConditionalDirectiveCodeSymbol(expressionReference);
            Symbol symbol = this.symbols.Peek(1);
            if (symbol == null || symbol.SymbolType != SymbolType.CloseParenthesis)
            {
                throw new SyntaxException(sourceCode, firstSymbol.LineNumber);
            }

            this.symbols.Advance();
            Bracket closeParenthesis = new Bracket(symbol.Text, CsTokenType.CloseParenthesis, symbol.Location, expressionReference, this.symbols.Generated);
            Node<CsToken> closeParenthesisNode = this.tokens.InsertLast(closeParenthesis);

            openParenthesis.MatchingBracketNode = closeParenthesisNode;
            closeParenthesis.MatchingBracketNode = openParenthesisNode;

            // Create the token list for the expression.
            CsTokenList partialTokens = new CsTokenList(this.tokens, openParenthesisNode, this.tokens.Last);

            // Create and return the expression.
            ParenthesizedExpression expression = new ParenthesizedExpression(partialTokens, innerExpression);
            expressionReference.Target = expression;

            return expression;
        }
示例#5
0
        /// <summary>
        /// Parses the iterators from a for-statement.
        /// </summary>
        /// <param name="statementReference">
        /// A reference to the statement being created.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the code is located within an unsafe block.
        /// </param>
        /// <param name="openParenthesis">
        /// The opening parenthesis.
        /// </param>
        /// <param name="openParenthesisNode">
        /// The opening parenthesis node.
        /// </param>
        /// <returns>
        /// Returns the list of iterators.
        /// </returns>
        private List<Expression> ParseForStatementIterators(
            Reference<ICodePart> statementReference, bool unsafeCode, Bracket openParenthesis, Node<CsToken> openParenthesisNode)
        {
            Param.AssertNotNull(statementReference, "statementReference");
            Param.Ignore(unsafeCode);
            Param.AssertNotNull(openParenthesis, "openParenthesis");
            Param.AssertNotNull(openParenthesisNode, "openParenthesisNode");

            // Get the iterators.
            List<Expression> iterators = new List<Expression>();

            while (true)
            {
                // Check the type of the next symbol.
                Symbol symbol = this.GetNextSymbol(statementReference);

                if (symbol.SymbolType == SymbolType.CloseParenthesis)
                {
                    // This is the end of the iterator list. Add the parenthesis and break.
                    Bracket closeParenthesis = this.GetBracketToken(CsTokenType.CloseParenthesis, SymbolType.CloseParenthesis, statementReference);
                    Node<CsToken> closeParenthesisNode = this.tokens.InsertLast(closeParenthesis);

                    openParenthesis.MatchingBracketNode = closeParenthesisNode;
                    closeParenthesis.MatchingBracketNode = openParenthesisNode;
                    break;
                }

                // Get the next iterator expression.
                Expression iterator = this.GetNextExpression(ExpressionPrecedence.None, statementReference, unsafeCode);
                if (iterator == null || iterator.Tokens.First == null)
                {
                    throw new SyntaxException(this.document.SourceCode, symbol.LineNumber);
                }

                // Add the initializer to the list.
                iterators.Add(iterator);

                // If the next symbol is a comma, save it.
                symbol = this.GetNextSymbol(statementReference);

                if (symbol.SymbolType == SymbolType.Comma)
                {
                    this.tokens.Add(this.GetToken(CsTokenType.Comma, SymbolType.Comma, statementReference));
                }
                else if (symbol.SymbolType != SymbolType.CloseParenthesis)
                {
                    // If it's not a comma it must be a closing parenthesis.
                    throw new SyntaxException(this.document.SourceCode, symbol.LineNumber);
                }
            }

            return iterators;
        }
        /// <summary>
        /// Gets array brackets symbol for a type token, if they exist.
        /// </summary>
        /// <param name="typeTokenReference">
        /// A reference to the type token.
        /// </param>
        /// <param name="typeTokens">
        /// The tokens within the type token.
        /// </param>
        /// <param name="startIndex">
        /// The start index within the symbols.
        /// </param>
        private void GetTypeTokenArrayBrackets(Reference<ICodePart> typeTokenReference, MasterList<CsToken> typeTokens, ref int startIndex)
        {
            Param.AssertNotNull(typeTokenReference, "typeTokenReference");
            Param.AssertNotNull(typeTokens, "typeTokens");
            Param.AssertGreaterThanOrEqualToZero(startIndex, "startIndex");

            int index = this.GetNextCodeSymbolIndex(startIndex);
            if (index != -1)
            {
                Symbol symbol = this.symbols.Peek(index);
                if (symbol.SymbolType == SymbolType.OpenSquareBracket)
                {
                    // Add the tokens up to this point.
                    for (int i = startIndex; i <= index - 1; ++i)
                    {
                        Symbol symbolToConvert = this.symbols.Peek(startIndex);
                        typeTokens.Add(this.ConvertSymbol(symbolToConvert, TokenTypeFromSymbolType(symbolToConvert.SymbolType), typeTokenReference));

                        ++startIndex;
                    }

                    // Now collect the brackets.
                    Node<CsToken> openingBracketNode = null;
                    while (true)
                    {
                        symbol = this.symbols.Peek(startIndex);
                        if (symbol.SymbolType == SymbolType.WhiteSpace || symbol.SymbolType == SymbolType.EndOfLine || symbol.SymbolType == SymbolType.SingleLineComment
                            || symbol.SymbolType == SymbolType.MultiLineComment || symbol.SymbolType == SymbolType.PreprocessorDirective)
                        {
                            typeTokens.Add(this.ConvertSymbol(symbol, TokenTypeFromSymbolType(symbol.SymbolType), typeTokenReference));
                            ++startIndex;
                        }
                        else if (symbol.SymbolType == SymbolType.Number)
                        {
                            typeTokens.Add(this.ConvertSymbol(symbol, CsTokenType.Number, typeTokenReference));
                            ++startIndex;
                        }
                        else if (symbol.SymbolType == SymbolType.Other)
                        {
                            // Could be a constant or a reference to a constant.
                            typeTokens.Add(this.ConvertSymbol(symbol, CsTokenType.Other, typeTokenReference));
                            ++startIndex;
                        }
                        else if (symbol.SymbolType == SymbolType.Dot)
                        {
                            // Could be a dot in here like: int a[Constants.DefaultSize];
                            typeTokens.Add(this.ConvertSymbol(symbol, CsTokenType.Other, typeTokenReference));
                            ++startIndex;
                        }
                        else if (symbol.SymbolType == SymbolType.Comma)
                        {
                            typeTokens.Add(this.ConvertSymbol(symbol, CsTokenType.Comma, typeTokenReference));
                            ++startIndex;
                        }
                        else if (symbol.SymbolType == SymbolType.OpenSquareBracket)
                        {
                            if (openingBracketNode != null)
                            {
                                throw new SyntaxException(this.document.SourceCode, symbol.LineNumber);
                            }

                            Bracket openingBracket = new Bracket(symbol.Text, CsTokenType.OpenSquareBracket, symbol.Location, typeTokenReference, this.symbols.Generated);
                            openingBracketNode = typeTokens.InsertLast(openingBracket);
                            ++startIndex;
                        }
                        else if (symbol.SymbolType == SymbolType.CloseSquareBracket)
                        {
                            if (openingBracketNode == null)
                            {
                                throw new SyntaxException(this.document.SourceCode, symbol.LineNumber);
                            }

                            Bracket closingBracket = new Bracket(symbol.Text, CsTokenType.CloseSquareBracket, symbol.Location, typeTokenReference, this.symbols.Generated);
                            Node<CsToken> closingBracketNode = typeTokens.InsertLast(closingBracket);
                            ++startIndex;

                            ((Bracket)openingBracketNode.Value).MatchingBracketNode = closingBracketNode;
                            closingBracket.MatchingBracketNode = openingBracketNode;

                            openingBracketNode = null;

                            // Check whether the next character is another opening bracket.
                            int temp = this.GetNextCodeSymbolIndex(startIndex);
                            if (temp != -1 && this.symbols.Peek(temp).SymbolType != SymbolType.OpenSquareBracket)
                            {
                                break;
                            }
                        }
                        else
                        {
                            if (openingBracketNode != null)
                            {
                                throw new SyntaxException(this.document.SourceCode, symbol.LineNumber);
                            }

                            break;
                        }
                    }
                }
            }
        }
示例#7
0
        /// <summary>
        /// Gets friendly output text for "opening" or "closing", depending on the type of the bracket.
        /// </summary>
        /// <param name="bracket">
        /// The bracket.
        /// </param>
        /// <returns>
        /// Returns the opening or closing text.
        /// </returns>
        private static string GetOpeningOrClosingBracketText(Bracket bracket)
        {
            Param.AssertNotNull(bracket, "bracket");

            switch (bracket.CsTokenType)
            {
                case CsTokenType.OpenAttributeBracket:
                case CsTokenType.OpenCurlyBracket:
                case CsTokenType.OpenGenericBracket:
                case CsTokenType.OpenParenthesis:
                case CsTokenType.OpenSquareBracket:
                    return Strings.Opening;

                case CsTokenType.CloseAttributeBracket:
                case CsTokenType.CloseCurlyBracket:
                case CsTokenType.CloseGenericBracket:
                case CsTokenType.CloseParenthesis:
                case CsTokenType.CloseSquareBracket:
                    return Strings.Closing;

                default:
                    Debug.Fail("Invalid bracket type.");
                    return string.Empty;
            }
        }