/// <summary>
        /// Parses one or more type constraint clauses.
        /// </summary>
        /// <param name="elementReference">A reference to the element being created.</param>
        /// <param name="unsafeCode">Indicates whether the code is marked as unsafe.</param>
        /// <returns>Returns the clauses.</returns>
        private ICollection<TypeParameterConstraintClause> ParseTypeConstraintClauses(
            Reference<ICodePart> elementReference, bool unsafeCode)
        {
            Param.AssertNotNull(elementReference, "elementReference");
            Param.Ignore(unsafeCode);

            List<TypeParameterConstraintClause> constraintClauses = new List<TypeParameterConstraintClause>();

            Symbol symbol = this.GetNextSymbol(elementReference);

            while (symbol.Text == "where")
            {
                var constraintClauseReference = new Reference<ICodePart>();

                Node<CsToken> firstToken = this.tokens.InsertLast(this.GetToken(CsTokenType.Where, SymbolType.Other, constraintClauseReference));
                Node<CsToken> typeToken = this.tokens.InsertLast(this.GetToken(CsTokenType.Other, SymbolType.Other, constraintClauseReference));
                this.tokens.Add(this.GetToken(CsTokenType.WhereColon, SymbolType.Colon, constraintClauseReference));

                List<CsToken> constraints = new List<CsToken>();

                while (true)
                {
                    symbol = this.GetNextSymbol(constraintClauseReference);

                    CsToken constraintToken = null;

                    if (symbol.SymbolType == SymbolType.Class ||
                        symbol.SymbolType == SymbolType.Struct)
                    {
                        // A constraint of type class or struct.
                        constraintToken = this.GetToken(CsTokenType.Other, symbol.SymbolType, constraintClauseReference);
                    }
                    else if (symbol.SymbolType == SymbolType.New)
                    {
                        var constructorConstraintReference = new Reference<ICodePart>();

                        // A constructor constraint.
                        MasterList<CsToken> childTokens = new MasterList<CsToken>();
                        childTokens.Add(this.GetToken(CsTokenType.Other, SymbolType.New, constraintClauseReference));

                        Bracket openParenthesis = this.GetBracketToken(CsTokenType.OpenParenthesis, SymbolType.OpenParenthesis, constraintClauseReference);
                        Bracket closeParenthesis = this.GetBracketToken(CsTokenType.CloseParenthesis, SymbolType.CloseParenthesis, constraintClauseReference);

                        Node<CsToken> openParenthesisNode = childTokens.InsertLast(openParenthesis);
                        Node<CsToken> closeParenthesisNode = childTokens.InsertLast(closeParenthesis);

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

                        constraintToken = new ConstructorConstraint(
                            childTokens,
                            CsToken.JoinLocations(childTokens.First, childTokens.Last),
                            constraintClauseReference,
                            childTokens.First.Value.Generated);

                        constructorConstraintReference.Target = constraintToken;
                    }
                    else
                    {
                        // A type constraint.
                        constraintToken = this.GetTypeToken(constraintClauseReference, unsafeCode, true);
                    }

                    this.tokens.Add(constraintToken);
                    constraints.Add(constraintToken);

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

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

                // Add the constraints as a read-only collection in a constraint clause.
                var constraintClause = new TypeParameterConstraintClause(
                    new CsTokenList(this.tokens, firstToken, this.tokens.Last), typeToken.Value, constraints.ToArray(), elementReference);

                constraintClauseReference.Target = constraintClause;
                constraintClauses.Add(constraintClause);

                symbol = this.GetNextSymbol(elementReference);
            }

            // Return the constraint clauses as a read-only collection.
            return constraintClauses.ToArray();
        }
Exemplo n.º 2
0
 private ICollection<TypeParameterConstraintClause> ParseTypeConstraintClauses(bool unsafeCode)
 {
     List<TypeParameterConstraintClause> list = new List<TypeParameterConstraintClause>();
     for (Symbol symbol = this.GetNextSymbol(); symbol.Text == "where"; symbol = this.GetNextSymbol())
     {
         Microsoft.StyleCop.Node<CsToken> firstItemNode = this.tokens.InsertLast(this.GetToken(CsTokenType.Other, SymbolType.Other));
         Microsoft.StyleCop.Node<CsToken> node2 = this.tokens.InsertLast(this.GetToken(CsTokenType.Other, SymbolType.Other));
         this.tokens.Add(this.GetToken(CsTokenType.WhereColon, SymbolType.Colon));
         List<CsToken> list2 = new List<CsToken>();
     Label_005A:
         symbol = this.GetNextSymbol();
         CsToken item = null;
         if ((symbol.SymbolType == SymbolType.Class) || (symbol.SymbolType == SymbolType.Struct))
         {
             item = this.GetToken(CsTokenType.Other, symbol.SymbolType);
         }
         else if (symbol.SymbolType == SymbolType.New)
         {
             MasterList<CsToken> childTokens = new MasterList<CsToken>();
             childTokens.Add(this.GetToken(CsTokenType.Other, SymbolType.New));
             Bracket bracketToken = this.GetBracketToken(CsTokenType.OpenParenthesis, SymbolType.OpenParenthesis);
             Bracket bracket2 = this.GetBracketToken(CsTokenType.CloseParenthesis, SymbolType.CloseParenthesis);
             Microsoft.StyleCop.Node<CsToken> node3 = childTokens.InsertLast(bracketToken);
             Microsoft.StyleCop.Node<CsToken> node4 = childTokens.InsertLast(bracket2);
             bracketToken.MatchingBracketNode = node4;
             bracket2.MatchingBracketNode = node3;
             item = new ConstructorConstraint(childTokens, CodeLocation.Join<CsToken>(childTokens.First, childTokens.Last), childTokens.First.Value.Generated);
         }
         else
         {
             item = this.GetTypeToken(unsafeCode, true);
         }
         this.tokens.Add(item);
         list2.Add(item);
         if (this.GetNextSymbol().SymbolType == SymbolType.Comma)
         {
             this.tokens.Add(this.GetToken(CsTokenType.Comma, SymbolType.Comma));
             goto Label_005A;
         }
         list.Add(new TypeParameterConstraintClause(new CsTokenList(this.tokens, firstItemNode, this.tokens.Last), node2.Value, list2.ToArray()));
     }
     return list.ToArray();
 }