/// <summary> /// Parses the iterators from a for-statement. /// </summary> /// <param name="forStatementProxy">Proxy object for the statement being created.</param> /// <param name="unsafeCode">Indicates whether the code is located within an unsafe block.</param> /// <param name="openParenthesis">The opening parentheis.</param> /// <returns>Returns the list of iterators.</returns> private List<Expression> GetForStatementIterators(CodeUnitProxy forStatementProxy, bool unsafeCode, BracketToken openParenthesis) { Param.AssertNotNull(forStatementProxy, "forStatementProxy"); Param.Ignore(unsafeCode); Param.AssertNotNull(openParenthesis, "openParenthesis"); // Get the iterators. var iterators = new List<Expression>(); while (true) { // Check the type of the next symbol. Symbol symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.CloseParenthesis) { // This is the end of the iterator list. Add the parenthesis and break. BracketToken closeParenthesis = (BracketToken)this.GetToken(forStatementProxy, TokenType.CloseParenthesis, SymbolType.CloseParenthesis); openParenthesis.MatchingBracket = closeParenthesis; closeParenthesis.MatchingBracket = openParenthesis; break; } // Get the next iterator expression. Expression iterator = this.GetNextExpression(forStatementProxy, ExpressionPrecedence.None, unsafeCode); if (iterator == null || iterator.Children.Count == 0) { throw new SyntaxException(this.document, symbol.LineNumber); } // Add the initializer to the list. iterators.Add(iterator); // If the next symbol is a comma, save it. symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.Comma) { this.GetToken(forStatementProxy, TokenType.Comma, SymbolType.Comma); } else if (symbol.SymbolType != SymbolType.CloseParenthesis) { // If it's not a comma it must be a closing parenthesis. throw new SyntaxException(this.document, symbol.LineNumber); } } return iterators; }
/// <summary> /// Gets the symbols that form a generic argument list. /// </summary> /// <param name="unsafeCode">Indicates whether the code is unsafe.</param> /// <param name="genericArgumentListItems">The collection to add the symbols into.</param> /// <param name="startIndex">The index at which to start looking for symbols.</param> /// <param name="openingGenericBracket">Returns the opening generic bracket.</param> /// <param name="endIndex">Returns the index of the end of the argument list.</param> /// <returns>Returns false if the symbols are not part of a generic argument list.</returns> private bool GetGenericArgumentListSymbols( bool unsafeCode, List<LexicalElement> genericArgumentListItems, int startIndex, out BracketToken openingGenericBracket, out int endIndex) { Param.Ignore(unsafeCode); Param.AssertNotNull(genericArgumentListItems, "genericArgumentListItems"); Param.AssertGreaterThanOrEqualToZero(startIndex, "startIndex"); openingGenericBracket = null; endIndex = -1; // Loop through the rest of the symbols. while (true) { Symbol symbol = this.symbols.Peek(startIndex); if (symbol == null) { // The code ran out before we found the end of the generic. throw new SyntaxException(this.document, this.GetBestLineNumber()); } else if (symbol.SymbolType == SymbolType.LessThan) { if (openingGenericBracket != null) { // This is not a generic statement. return false; } openingGenericBracket = new OpenGenericBracketToken(this.document, symbol.Text, symbol.Location, this.symbols.Generated); genericArgumentListItems.Add(openingGenericBracket); } else if (symbol.SymbolType == SymbolType.GreaterThan) { if (openingGenericBracket == null) { // This is not a generic statement. return false; } // This is the end of the generic statement. Add the closing bracket to the token list. var closingGenericBracket = new CloseGenericBracketToken(this.document, symbol.Text, symbol.Location, this.symbols.Generated); genericArgumentListItems.Add(closingGenericBracket); openingGenericBracket.MatchingBracket = closingGenericBracket; closingGenericBracket.MatchingBracket = openingGenericBracket; endIndex = startIndex; break; } else if (symbol.SymbolType == SymbolType.Other) { int lastIndex = 0; Token word = this.GetTypeTokenAux(unsafeCode, true, false, startIndex, out lastIndex); if (word == null) { throw new SyntaxException(this.document, symbol.LineNumber); } // Advance the index to the end of the token. startIndex = lastIndex; // Add the token. genericArgumentListItems.Add(word); } else if (symbol.SymbolType == SymbolType.Out) { genericArgumentListItems.Add(this.ConvertTokenSymbol(symbol, TokenType.Out)); } else if (symbol.SymbolType == SymbolType.In) { genericArgumentListItems.Add(this.ConvertTokenSymbol(symbol, TokenType.In)); } else if (symbol.SymbolType == SymbolType.WhiteSpace || symbol.SymbolType == SymbolType.EndOfLine || symbol.SymbolType == SymbolType.SingleLineComment || symbol.SymbolType == SymbolType.MultiLineComment || symbol.SymbolType == SymbolType.PreprocessorDirective || symbol.SymbolType == SymbolType.SkippedSection) { // Add these to the token list. genericArgumentListItems.Add(this.PeekNonTokenSymbol(symbol)); } else if (symbol.SymbolType == SymbolType.Comma) { genericArgumentListItems.Add(this.ConvertTokenSymbol(symbol, TokenType.Comma)); } else { // Any other symbol signifies that this is not a generic statement. genericArgumentListItems = null; break; } ++startIndex; } return true; }
/// <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(BracketToken bracket) { Param.AssertNotNull(bracket, "bracket"); switch (bracket.TokenType) { case TokenType.OpenAttributeBracket: case TokenType.OpenCurlyBracket: case TokenType.OpenGenericBracket: case TokenType.OpenParenthesis: case TokenType.OpenSquareBracket: return Strings.Opening; case TokenType.CloseAttributeBracket: case TokenType.CloseCurlyBracket: case TokenType.CloseGenericBracket: case TokenType.CloseParenthesis: case TokenType.CloseSquareBracket: return Strings.Closing; default: Debug.Fail("Invalid bracket type."); return string.Empty; } }