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> /// 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(); }
/// <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) { // A const used in place of a number. 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; } } } } }
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(); }
private void GetTypeTokenArrayBrackets(MasterList<CsToken> typeTokens, ref int startIndex) { Symbol symbol; int nextCodeSymbolIndex = this.GetNextCodeSymbolIndex(startIndex); if ((nextCodeSymbolIndex == -1) || (this.symbols.Peek(nextCodeSymbolIndex).SymbolType != SymbolType.OpenSquareBracket)) { return; } for (int i = startIndex; i <= (nextCodeSymbolIndex - 1); i++) { Symbol symbol2 = this.symbols.Peek(startIndex); typeTokens.Add(this.ConvertSymbol(symbol2, TokenTypeFromSymbolType(symbol2.SymbolType))); startIndex++; } Microsoft.StyleCop.Node<CsToken> node = null; Label_0067: 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))); startIndex++; goto Label_0067; } if (symbol.SymbolType == SymbolType.Number) { typeTokens.Add(this.ConvertSymbol(symbol, CsTokenType.Number)); startIndex++; goto Label_0067; } if (symbol.SymbolType == SymbolType.Other) { typeTokens.Add(this.ConvertSymbol(symbol, CsTokenType.Other)); startIndex++; goto Label_0067; } if (symbol.SymbolType == SymbolType.Comma) { typeTokens.Add(this.ConvertSymbol(symbol, CsTokenType.Comma)); startIndex++; goto Label_0067; } if (symbol.SymbolType == SymbolType.OpenSquareBracket) { if (node != null) { throw new SyntaxException(this.document.SourceCode, symbol.LineNumber); } Bracket item = new Bracket(symbol.Text, CsTokenType.OpenSquareBracket, symbol.Location, this.symbols.Generated); node = typeTokens.InsertLast(item); startIndex++; goto Label_0067; } if (symbol.SymbolType == SymbolType.CloseSquareBracket) { if (node == null) { throw new SyntaxException(this.document.SourceCode, symbol.LineNumber); } Bracket bracket2 = new Bracket(symbol.Text, CsTokenType.CloseSquareBracket, symbol.Location, this.symbols.Generated); Microsoft.StyleCop.Node<CsToken> node2 = typeTokens.InsertLast(bracket2); startIndex++; ((Bracket) node.Value).MatchingBracketNode = node2; bracket2.MatchingBracketNode = node; node = null; int count = this.GetNextCodeSymbolIndex(startIndex); if ((count != -1) && (this.symbols.Peek(count).SymbolType != SymbolType.OpenSquareBracket)) { return; } goto Label_0067; } if (node != null) { throw new SyntaxException(this.document.SourceCode, symbol.LineNumber); } }
private MasterList<CsToken> GetGenericArgumentList(bool unsafeCode, CsToken name, int startIndex, out int endIndex) { endIndex = -1; MasterList<CsToken> list = null; int count = startIndex; while (true) { Symbol symbol = this.symbols.Peek(count); if ((symbol == null) || (((symbol.SymbolType != SymbolType.WhiteSpace) && (symbol.SymbolType != SymbolType.EndOfLine)) && (((symbol.SymbolType != SymbolType.SingleLineComment) && (symbol.SymbolType != SymbolType.MultiLineComment)) && (symbol.SymbolType != SymbolType.PreprocessorDirective)))) { break; } count++; } Symbol symbol2 = this.symbols.Peek(count); if ((symbol2 == null) || (symbol2.SymbolType != SymbolType.LessThan)) { return list; } list = new MasterList<CsToken>(); if (name != null) { list.Add(name); } Microsoft.StyleCop.Node<CsToken> node = null; for (int i = startIndex; i <= count; i++) { symbol2 = this.symbols.Peek(i); if (symbol2.SymbolType == SymbolType.LessThan) { if (node != null) { return null; } Bracket item = new Bracket(symbol2.Text, CsTokenType.OpenGenericBracket, symbol2.Location, this.symbols.Generated); node = list.InsertLast(item); } else { list.Add(this.ConvertSymbol(symbol2, TokenTypeFromSymbolType(symbol2.SymbolType))); } } Label_00F4: symbol2 = this.symbols.Peek(++count); if (symbol2 == null) { throw new SyntaxException(this.document.SourceCode, name.LineNumber); } if (symbol2.SymbolType == SymbolType.GreaterThan) { if (node == null) { return null; } Bracket bracket2 = new Bracket(symbol2.Text, CsTokenType.CloseGenericBracket, symbol2.Location, this.symbols.Generated); Microsoft.StyleCop.Node<CsToken> node2 = list.InsertLast(bracket2); ((Bracket) node.Value).MatchingBracketNode = node2; bracket2.MatchingBracketNode = node; endIndex = count; return list; } if (symbol2.SymbolType == SymbolType.Other) { int num3 = 0; CsToken token = this.GetTypeTokenAux(unsafeCode, true, false, count, out num3); if (token == null) { throw new SyntaxException(this.document.SourceCode, symbol2.LineNumber); } count = num3; list.Add(token); goto Label_00F4; } if (((symbol2.SymbolType == SymbolType.WhiteSpace) || (symbol2.SymbolType == SymbolType.EndOfLine)) || (((symbol2.SymbolType == SymbolType.SingleLineComment) || (symbol2.SymbolType == SymbolType.MultiLineComment)) || (symbol2.SymbolType == SymbolType.PreprocessorDirective))) { list.Add(this.ConvertSymbol(symbol2, TokenTypeFromSymbolType(symbol2.SymbolType))); goto Label_00F4; } if (symbol2.SymbolType == SymbolType.Comma) { list.Add(this.ConvertSymbol(symbol2, CsTokenType.Comma)); goto Label_00F4; } return null; }