/// <summary> /// Scans through the window and generates a WhiteSpace SyntaxNode/Trivia /// </summary> /// <param name="TextWindow"></param> /// <returns></returns> public static SyntaxTrivia Scan(SlidingTextWindow TextWindow) { // Default to OnlyWhiteSpace true Boolean bIsOnlySpaces = true; Boolean bEndOfTrivia = false; String sCharactersScannedSoFar = String.Empty; while (!bEndOfTrivia && TextWindow.HasCharactersLeftToProcess()) { // Peek at a character char ch = TextWindow.PeekCharacter(); switch (ch) { case '\t': // Horizontal tab case '\v': // Vertical Tab case '\f': // Form-feed case '\u001A': bIsOnlySpaces = false; goto case ' '; case ' ': sCharactersScannedSoFar += TextWindow.PopCharacter(); break; case '\r': // Carriage Return case '\n': // Line-feed // End iteration bEndOfTrivia = true; break; default: if (ch > 127 && SyntaxUtilities.IsWhiteSpace(ch)) { goto case '\t'; } bEndOfTrivia = true; break; } } // Return the specific instance where possible if (sCharactersScannedSoFar.Length == 0) { return(null); } if (bIsOnlySpaces && sCharactersScannedSoFar.Length == 1) { return(SyntaxFactory.Space); } else { return(SyntaxFactory.WhiteSpace(sCharactersScannedSoFar)); } }
/// <summary> /// Used to analyse the current textwindow and retrieve/skip any /// trivia which includes things such as whitespace, newlines, /// comments and multi-line comments /// Returns them as a flat list /// </summary> /// <param name="bIsTrailing"></param> /// <returns></returns> private List <SyntaxTrivia> LexSyntaxTrivia(Boolean bIsTrailing = false) { // Initialise variables List <SyntaxTrivia> aoReturnList = new List <SyntaxTrivia>(); Boolean bNewLineCharFound = false; // Just keep lexing until we are told to stop // or we run out of characters to process while (TextWindow.HasCharactersLeftToProcess()) { // Check the next character and switch based on that char xcNextChar = TextWindow.PeekCharacter(); if (SyntaxUtilities.IsWhiteSpace(xcNextChar)) { // Try and scan the item SyntaxTrivia oNewItem = WhiteSpaceScanner.Scan(TextWindow); // Insert it aoReturnList.Add(oNewItem); } else if (SyntaxUtilities.IsNewLineCharacter(xcNextChar)) { bNewLineCharFound = true; // Do not steal trailing comments if a newline has been found if (bIsTrailing) { break; } // Try and scan the item SyntaxTrivia oNewItem = NewLineScanner.Scan(TextWindow); // Insert it aoReturnList.Add(oNewItem); } // Handle Comments else if (xcNextChar == '-') { // Do not touch a single -, only play with -- if (TextWindow.PeekCharacter(1) != '-') { return(aoReturnList); } // Only pick up inlines if they are directly trailing an item // Do not steal another nodes leading comments if (bNewLineCharFound && bIsTrailing) { break; } SyntaxTrivia oComment = CommentScanner.ScanSingleLineComment(TextWindow); aoReturnList.Add(oComment); } else if (xcNextChar == '/') { // Do not touch a single /, only play with /* if (TextWindow.PeekCharacter(1) != '*') { return(aoReturnList); } // Do not steal trailing comments if a newline has been found if (bNewLineCharFound && bIsTrailing) { break; } SyntaxTrivia oComment = CommentScanner.ScanMultiLineComment(TextWindow); aoReturnList.Add(oComment); } else { break; } } return(aoReturnList); }