private void ScanMultiLineString(LineProgress p, bool isVerbatimString) { bool markText = !this.IgnoreVerbatimStrings; if (markText) { p.StartNaturalText(); } // For verbatim strings, skip the leading format identifier. We keep it so that we can skip escape // sequence checking in it. if (isVerbatimString) { p.Advance(2); } while (!p.EndOfLine) { if (p.Char() == '"' && p.NextChar() == '"') // "" is allowed within multi-line string. { p.Advance(2); } else if (p.Char() == '"') // End of multi-line string { if (markText) { p.EndNaturalText(); } p.Advance(); p.State = State.Default; return; } else { p.Advance(); } } // End of line. Emit as human readable, but remain in MultiLineString state. if (markText) { p.EndNaturalText(); } Debug.Assert(p.State == State.MultiLineString); }
private static void ScanDocCommentXmlString(LineProgress p) { while (!p.EndOfLine) { if (p.Char() == '"') { p.Advance(1); p.State = State.DocCommentXml; return; // Done with string in doc comment XML. } p.Advance(); } // End of line. Never found the '"' to close the string, but whatever. We revert to default state. p.State = State.Default; }
private void ScanString(LineProgress p) { bool markText = !this.IgnoreNormalStrings; if (markText) { p.StartNaturalText(); } while (!p.EndOfLine) { if (p.Char() == '\\') // Escaped character. Skip over it. { p.Advance(2); } else if (p.Char() == '"') // End of string { if (markText) { p.EndNaturalText(); } p.Advance(); p.State = State.Default; return; } else { p.Advance(); } } // End of line. String wasn't closed. Oh well. Revert to Default state. if (markText) { p.EndNaturalText(); } p.State = State.Default; }
private static void ScanCharacter(LineProgress p) { if (!p.EndOfLine && p.Char() == '\\') // escaped character. Eat it. { p.Advance(2); } else if (!p.EndOfLine && p.Char() != '\'') // non-escaped character. Eat it. { p.Advance(1); } if (!p.EndOfLine && p.Char() == '\'') // closing ' for character, as expected. { p.Advance(1); p.State = State.Default; return; } // Didn't find closing ' for character. Oh well. p.State = State.Default; }
private void ScanMultiLineString(LineProgress p) { bool markText = !this.IgnoreVerbatimStrings; if (markText) { p.StartNaturalText(); } while (!p.EndOfLine) { if (p.Char() == '"' && p.NextChar() == '"') // "" is allowed within multi-line string. { p.Advance(2); } else if (p.Char() == '"') // End of multi-line string { if (markText) { p.EndNaturalText(); } p.Advance(); p.State = State.Default; return; } else { p.Advance(); } } // End of line. Emit as human readable, but remain in MultiLineString state. if (markText) { p.EndNaturalText(); } Debug.Assert(p.State == State.MultiLineString); }
private void ScanDocComment(LineProgress p) { p.StartNaturalText(); while (!p.EndOfLine) { if (p.Char() == '<') { // Note that we can only ignore an unwanted element if it is contained on the same line. // Elements that can span lines like "code", will still be spell checked here. if (p.NextChar() != '/' || !this.IgnoredXmlElements.Contains(p.DetermineElementName())) { p.EndNaturalText(); } else { p.IgnoreSpan(); } p.Advance(); p.State = State.DocCommentXml; ScanDocCommentXml(p); p.StartNaturalText(); } else { p.Advance(); } } // End of line. Record what we have and revert to default state. p.EndNaturalText(); if (p.State == State.DocComment) { p.State = State.Default; } }
private State ScanLine(State state, ITextSnapshotLine line, List <SnapshotSpan> naturalTextSpans = null) { LineProgress p = new LineProgress(line, state, naturalTextSpans); while (!p.EndOfLine) { switch (p.State) { case State.Default: ScanDefault(p); break; case State.MultiLineComment: ScanMultiLineComment(p); break; case State.MultiLineDocComment: ScanMultiLineDocComment(p); break; case State.MultiLineString: ScanMultiLineString(p); break; default: Debug.Fail("Invalid state at beginning of line."); break; } } // End Of Line state must be one of these. Debug.Assert(p.State == State.Default || p.State == State.MultiLineString || p.State == State.MultiLineComment || p.State == State.MultiLineDocComment); return(p.State); }
private void ScanDefault(LineProgress p) { while (!p.EndOfLine) { if (p.Char() == '/' && p.NextChar() == '/' && p.NextNextChar() == '/') // Doc comment { p.Advance(3); if (this.IgnoreXmlDocComments && (p.EndOfLine || p.Char() != '/')) { p.AdvanceToEndOfLine(); return; } if (this.IgnoreQuadrupleSlashComments && !p.EndOfLine && p.Char() == '/') { p.AdvanceToEndOfLine(); return; } p.State = State.DocComment; ScanDocComment(p); } else if (p.Char() == '/' && p.NextChar() == '/') // Single line comment { p.Advance(2); if (!this.IgnoreStandardSingleLineComments) { p.StartNaturalText(); p.AdvanceToEndOfLine(); p.EndNaturalText(); } else { p.AdvanceToEndOfLine(); } p.State = State.Default; return; } else if (p.Char() == '/' && p.NextChar() == '*') // Multi-line comment or multi-line doc comment { p.Advance(2); // "/***" is just a regular multi-line comment, not a doc comment if (p.EndOfLine || p.Char() != '*' || p.NextChar() == '*') { p.State = State.MultiLineComment; ScanMultiLineComment(p); } else { p.State = State.MultiLineDocComment; ScanMultiLineDocComment(p); } } else if (((p.Char() == '@' || p.Char() == 'R') && p.NextChar() == '"') || (p.Char() == '@' && p.NextChar() == '$' && p.NextNextChar() == '"')) // Verbatim, raw, or verbatim interpolated string { // Keep the leading text so that we can handle escape sequences properly p.State = State.MultiLineString; ScanMultiLineString(p, true); } else if (p.Char() == '"') // Single-line string { p.Advance(1); p.State = State.String; ScanString(p, false); } else if ((p.Char() == '$' && p.NextChar() == '"') || (p.Char() == '$' && p.NextChar() == '@' && p.NextNextChar() == '"')) // Interpolated or interpolated verbatim string { // Keep the leading text so that we can handle the format specifiers properly p.State = State.String; ScanString(p, true); } else if (p.Char() == '\'') // Character literal { p.Advance(1); p.State = State.Character; ScanCharacter(p); } else if (p.Char() == '#') // Possible preprocessor keyword, check for a region { p.Advance(1); int segmentLength = 0; // If found, treat it like a single line comment if (p.NextSegment(6) == "region") { segmentLength = 6; } else if (p.NextSegment(9) == "endregion") { segmentLength = 9; } else if (p.NextSegment(13) == "pragma region") { segmentLength = 13; } else if (p.NextSegment(16) == "pragma endregion") { segmentLength = 16; } if (segmentLength != 0) { p.Advance(segmentLength); p.StartNaturalText(); p.AdvanceToEndOfLine(); p.EndNaturalText(); p.State = State.Default; return; } } else { p.Advance(); } } }
private void ScanDefault(LineProgress p) { while (!p.EndOfLine) { if (p.Char() == '/' && p.NextChar() == '/' && p.NextNextChar() == '/') // Doc comment { p.Advance(3); if (this.IgnoreXmlDocComments && (p.EndOfLine || p.Char() != '/')) { p.AdvanceToEndOfLine(); return; } if (this.IgnoreQuadrupleSlashComments && !p.EndOfLine && p.Char() == '/') { p.AdvanceToEndOfLine(); return; } p.State = State.DocComment; ScanDocComment(p); } else if (p.Char() == '/' && p.NextChar() == '/') // Single line comment { p.Advance(2); if (!this.IgnoreStandardSingleLineComments) { p.StartNaturalText(); p.AdvanceToEndOfLine(); p.EndNaturalText(); } else { p.AdvanceToEndOfLine(); } p.State = State.Default; return; } else if (p.Char() == '/' && p.NextChar() == '*') // Multi-line comment or multi-line doc comment { p.Advance(2); // "/***" is just a regular multi-line comment, not a doc comment if (p.EndOfLine || p.Char() != '*' || p.NextChar() == '*') { p.State = State.MultiLineComment; ScanMultiLineComment(p); } else { p.State = State.MultiLineDocComment; ScanMultiLineDocComment(p); } } else if (p.Char() == '@' && p.NextChar() == '"') // Verbatim string { p.Advance(2); p.State = State.MultiLineString; ScanMultiLineString(p); } else if (p.Char() == '"') // Single-line string { p.Advance(1); p.State = State.String; ScanString(p); } else if (p.Char() == '\'') // Character literal { p.Advance(1); p.State = State.Character; ScanCharacter(p); } else if (p.Char() == '#') // Possible preprocessor keyword, check for #region { p.Advance(1); // If found, treat it like a single line comment if (p.NextSegment(6) == "region") { p.StartNaturalText(); p.AdvanceToEndOfLine(); p.EndNaturalText(); p.State = State.Default; return; } } else { p.Advance(); } } }