protected virtual int LineBreaksAfter(SyntaxToken currentToken, SyntaxToken nextToken) { if (currentToken.GetKind() == EndOfDirectiveTokenKind) { return(1); } if (nextToken.GetKind() == SyntaxKind.None) { return(0); } // none of the following tests currently have meaning for structured trivia if (_isInStructuredTrivia) { return(0); } return(0); }
public override SyntaxToken VisitToken(SyntaxToken token) { SyntaxToken result = token; // only bother visiting trivia if we are removing a node in structured trivia if (this.VisitIntoStructuredTrivia) { result = base.VisitToken(token); } // the next token gets the accrued trivia. if (result.GetKind() != SyntaxKind.None && _residualTrivia != null && _residualTrivia.Count > 0) { _residualTrivia.Add(result.LeadingTrivia); result = result.WithLeadingTrivia(_residualTrivia.ToList()); _residualTrivia.Clear(); } return(result); }
private static bool IsBeforeToken(int position, SyntaxToken firstExcluded) { return(firstExcluded.GetKind() == SyntaxKind.None || position < firstExcluded.SpanStart); }
private void AddToken(TreeViewItem parentItem, SyntaxToken token) { var kind = token.GetKind(); var tag = new SyntaxTag() { SyntaxToken = token, Category = SyntaxCategory.SyntaxToken, Span = token.Span, FullSpan = token.FullSpan, Kind = kind, ParentItem = parentItem }; var item = new TreeViewItem() { Tag = tag, IsExpanded = false, Foreground = Brushes.DarkGreen, Background = token.ContainsDiagnostics ? Brushes.Pink : Brushes.White, Header = tag.Kind + " " + token.Span.ToString() }; if (SyntaxTree != null && token.ContainsDiagnostics) { item.ToolTip = string.Empty; foreach (var diagnostic in SyntaxTree.GetDiagnostics(token)) { item.ToolTip += diagnostic.ToString() + "\n"; } item.ToolTip = item.ToolTip.ToString().Trim(); } item.Selected += new RoutedEventHandler((sender, e) => { _isNavigatingFromTreeToSource = true; typeTextLabel.Visibility = Visibility.Visible; kindTextLabel.Visibility = Visibility.Visible; typeValueLabel.Content = token.GetType().Name; kindValueLabel.Content = kind; _propertyGrid.SelectedObject = token; item.IsExpanded = true; if (!_isNavigatingFromSourceToTree && SyntaxTokenNavigationToSourceRequested != null) { SyntaxTokenNavigationToSourceRequested(token); } _isNavigatingFromTreeToSource = false; e.Handled = true; }); item.Expanded += new RoutedEventHandler((sender, e) => { if (item.Items.Count == 1 && item.Items[0] == null) { // Remove placeholder child and populate real children. item.Items.RemoveAt(0); foreach (var trivia in token.LeadingTrivia) { AddTrivia(item, trivia, true); } foreach (var trivia in token.TrailingTrivia) { AddTrivia(item, trivia, false); } } }); if (parentItem == null) { treeView.Items.Clear(); treeView.Items.Add(item); } else { parentItem.Items.Add(item); } if (token.HasLeadingTrivia || token.HasTrailingTrivia) { if (IsLazy) { // Add placeholder child to indicate that real children need to be populated on expansion. item.Items.Add(null); } else { // Recursively populate all descendants. foreach (var trivia in token.LeadingTrivia) { AddTrivia(item, trivia, true); } foreach (var trivia in token.TrailingTrivia) { AddTrivia(item, trivia, false); } } } }
public static bool IsLiteral(this SyntaxToken n) { return(n.GetKind().Contains("Literal")); }
public static bool IsKeyword(this SyntaxToken n) { var kind = n.GetKind(); return(kind.EndsWith("Keyword") || (kind.Contains("Identifier") && n.Parent != null && !n.Parent.GetKind().Contains("Name"))); }
public static bool IsIdentifier(this SyntaxToken n) { return(n.GetKind().Contains("Identifier") && n.Parent != null && n.Parent.GetKind().Contains("Name")); }
protected virtual bool IsLineBreak(SyntaxToken token) { return(token.GetKind() == DefaultEndOfLineKind); }
protected virtual bool NeedsIndentAfterLineBreak(SyntaxToken token) { return(token.GetKind() != SyntaxKind.Eof); }
private void AddToken(TreeViewItem parentItem, SyntaxToken token) { var kind = token.GetKind(); var tag = new SyntaxTag() { SyntaxToken = token, Category = SyntaxCategory.SyntaxToken, Span = token.Span, FullSpan = token.FullSpan, Kind = kind, ParentItem = parentItem }; var item = CreateTreeViewItem(tag, tag.Kind + " " + token.Span.ToString(), token.ContainsDiagnostics); item.SetResourceReference(ForegroundProperty, SyntaxTokenTextBrushKey); if (SyntaxTree != null && token.ContainsDiagnostics) { item.ToolTip = string.Empty; foreach (var diagnostic in SyntaxTree.GetDiagnostics(token)) { item.ToolTip += diagnostic.ToString() + "\n"; } item.ToolTip = item.ToolTip.ToString().Trim(); } item.Selected += new RoutedEventHandler((sender, e) => { _isNavigatingFromTreeToSource = true; typeTextLabel.Visibility = Visibility.Visible; kindTextLabel.Visibility = Visibility.Visible; typeValueLabel.Content = token.GetType().Name; kindValueLabel.Content = kind; _propertyGrid.SelectedObject = token; item.IsExpanded = true; if (!_isNavigatingFromSourceToTree && SyntaxTokenNavigationToSourceRequested != null) { SyntaxTokenNavigationToSourceRequested(token); } _isNavigatingFromTreeToSource = false; e.Handled = true; }); item.Expanded += new RoutedEventHandler((sender, e) => { if (item.Items.Count == 1 && item.Items[0] == null) { // Remove placeholder child and populate real children. item.Items.RemoveAt(0); foreach (var trivia in token.LeadingTrivia) { AddTrivia(item, trivia, true); } foreach (var trivia in token.TrailingTrivia) { AddTrivia(item, trivia, false); } } }); if (parentItem == null) { treeView.Items.Clear(); treeView.Items.Add(item); } else { parentItem.Items.Add(item); } if (token.HasLeadingTrivia || token.HasTrailingTrivia) { if (IsLazy) { // Add placeholder child to indicate that real children need to be populated on expansion. item.Items.Add(null); } else { // Recursively populate all descendants. foreach (var trivia in token.LeadingTrivia) { AddTrivia(item, trivia, true); } foreach (var trivia in token.TrailingTrivia) { AddTrivia(item, trivia, false); } } } }
public bool ZeroWidthOrMissingTokens(SyntaxToken token, SyntaxTree tree, ref string errorText) { var retVal = true; if (token.ContainsDiagnostics || tree.GetDiagnostics().Any()) { if (token.IsMissing) { if (token.Span.Length == 0) { if (token.LeadingTrivia.Any() || token.TrailingTrivia.Any()) { var atleastOneSkippedTrivia = ( from leadingTrivia in token.LeadingTrivia let kind = leadingTrivia.GetKind() where kind == "SkippedTextTrivia" || kind == "SkippedTokens" select new { leadingTrivia, kind } ).Any(); if (!atleastOneSkippedTrivia) { atleastOneSkippedTrivia = ( from trailingTrivia in token.TrailingTrivia let kind = trailingTrivia.GetKind() where kind == "SkippedTextTrivia" || kind == "SkippedTokens" select new { trailingTrivia, kind } ).Any(); if (!atleastOneSkippedTrivia) { retVal = false; errorText = "Missing tokens should have at least one trivia with kind SkippedTextTrivia OR SkippedTokens"; } } } } else { retVal = false; errorText = "Missing tokens should have 0 Span width"; } } else if (token.Span.Length == 0) { var kind = token.GetKind(); if (!(kind == "EndOfFileToken" || kind == "EmptyToken" || kind == "EndOfDocumentationCommentToken" || kind == "EndOfDirectiveToken" || kind.Contains("Bad"))) { //BadToken only appears in error trees for C#. retVal = false; errorText = "Tokens with 0 Span width should have IsMissing set to 'True'"; } } } else { if (token.IsMissing) { retVal = false; errorText = "A tree with 0 errors should not contain missing tokens"; } else if (token.Span.Length == 0) { var kind = token.GetKind(); if (!(kind == "EndOfFileToken" || kind == "EmptyToken" || kind == "EndOfDocumentationCommentToken" || kind == "EndOfDirectiveToken")) { //EmptyToken can be present even in non-error cases in VB (it is used for OmittedArgument). retVal = false; errorText = "A tree with 0 errors should not contain tokens with 0 width"; } } } return(retVal); }
private bool ValidateToken(SyntaxToken token, SyntaxTree tree, string filename = "", List<Failure> failures = null) { var retVal = true; foreach (var leadingTrivia in token.LeadingTrivia) { retVal = retVal & ValidateTrivia(leadingTrivia, tree, filename, failures); } foreach (var trailingTrivia in token.TrailingTrivia) { retVal = retVal & ValidateTrivia(trailingTrivia, tree, filename, failures); } bool pass = false; foreach (var rule in m_TokenRules.Values) { var errorText = string.Empty; pass = rule.Test(token, tree, ref errorText); if (!pass) { if (failures != null) { failures.Add(new Failure(filename, rule, token.GetKind(), errorText, new FailureLocation(token.Span, tree))); } ValidationFailed(errorText, rule); } retVal = retVal & pass; } return retVal; }
public static XElement ToXml( this SyntaxToken token, SyntaxTree syntaxTree, XmlOptions options = null ) { if (options == null) { options = new XmlOptions(); } XElement retVal = new XElement( "Node", new XAttribute("IsToken", false), new XAttribute("IsTrivia", true), new XAttribute("Kind", token.GetKind()), new XAttribute("IsMissing", token.IsMissing) ); if (options.Spans) { retVal.Add( @"<Span Start=<%= token.SpanStart %> End=<%= token.Span.End %> Length=<%= token.Span.Length %>/>" ); retVal.Add( @"<FullSpan Start=<%= token.FullSpan.Start %> End=<%= token.FullSpan.End %> Length=<%= token.FullSpan.Length %>/>" ); } if (options.Text) { retVal.Add(@"<Text><%= New XCData(token.GetText()) %></Text>"); } if (options.ReflectionInfo) { AddInfo(token, retVal, options); } if (options.Errors) { if (syntaxTree.GetDiagnostics(token).Any()) { AddErrors(retVal, syntaxTree.GetDiagnostics(token), options); } } if (options.Trivia) { if (token.LeadingTrivia.Any()) { retVal.Add( @"<LeadingTrivia><%= From t In token.LeadingTrivia Select t.ToXml(syntaxTree, options) %></LeadingTrivia>" ); } if (token.TrailingTrivia.Any()) { retVal.Add( @"<TrailingTrivia><%= From t In token.TrailingTrivia Select t.ToXml(syntaxTree, options) %></TrailingTrivia>" ); } } return(retVal); }
public bool WhiteSpaceInTokens(SyntaxToken token, SyntaxTree tree, ref string errorText) { var retVal = true; var kind = token.GetKind(); if (kind != "StatementTerminatorToken" && kind != "DateLiteralToken" && kind != "StringLiteralToken" && kind != "CharacterLiteralToken" && kind != "XmlTextLiteralToken" && kind != "XmlAttributeDataToken" && kind != "XmlCommentDataToken" && kind != "XmlCDataToken" && kind != "XmlProcessingInstructionDataToken" && kind != "XmlTextLiteralNewLineToken" && kind != "LessThanEqualsToken" && kind != "GreaterThanEqualsToken" && kind != "LessThanGreaterThanToken" && kind != "ColonEqualsToken" && kind != "CaretEqualsToken" && kind != "AsteriskEqualsToken" && kind != "PlusEqualsToken" && kind != "MinusEqualsToken" && kind != "SlashEqualsToken" && kind != "BackslashEqualsToken" && kind != "LessThanLessThanToken" && kind != "GreaterThanGreaterThanToken" && kind != "LessThanLessThanEqualsToken" && kind != "GreaterThanGreaterThanEqualsToken" && kind != "AmpersandEqualsToken") { var text = token.ToString(); if ((text.Contains(" ") || text.Contains('\t') || text.Contains('\r') || text.Contains('\n') || text.Contains("\r\n"))) { retVal = false; errorText = "The text of this token should not contain any whitespace"; } } return retVal; }
public bool BadTokens(SyntaxToken token, SyntaxTree tree, ref string errorText) { var retVal = true; var kind = token.GetKind(); if (tree.GetDiagnostics().Any()) { if (kind.Contains("Bad")) { if (tree.GetDiagnostics(token).Any()) { } else { retVal = false; errorText = "Bad tokens should have at least one error on them"; } } } else if (kind.Contains("Bad")) { retVal = false; errorText = "A tree with 0 errors should not contain Bad tokens"; } return retVal; }
public bool ZeroWidthOrMissingTokens(SyntaxToken token, SyntaxTree tree, ref string errorText) { var retVal = true; if (token.ContainsDiagnostics || tree.GetDiagnostics().Any()) { if (token.IsMissing) { if (token.Span.Length == 0) { if (token.LeadingTrivia.Any() || token.TrailingTrivia.Any()) { var atleastOneSkippedTrivia = ( from leadingTrivia in token.LeadingTrivia let kind = leadingTrivia.GetKind() where kind == "SkippedTextTrivia" || kind == "SkippedTokens" select new { leadingTrivia, kind } ).Any(); if (!atleastOneSkippedTrivia) { atleastOneSkippedTrivia = ( from trailingTrivia in token.TrailingTrivia let kind = trailingTrivia.GetKind() where kind == "SkippedTextTrivia" || kind == "SkippedTokens" select new { trailingTrivia, kind } ).Any(); if (!atleastOneSkippedTrivia) { retVal = false; errorText = "Missing tokens should have at least one trivia with kind SkippedTextTrivia OR SkippedTokens"; } } } } else { retVal = false; errorText = "Missing tokens should have 0 Span width"; } } else if (token.Span.Length == 0) { var kind = token.GetKind(); if (!(kind == "EndOfFileToken" || kind == "EmptyToken" || kind == "EndOfDocumentationCommentToken" || kind == "EndOfDirectiveToken" || kind.Contains("Bad"))) { //BadToken only appears in error trees for C#. retVal = false; errorText = "Tokens with 0 Span width should have IsMissing set to 'True'"; } } } else { if (token.IsMissing) { retVal = false; errorText = "A tree with 0 errors should not contain missing tokens"; } else if (token.Span.Length == 0) { var kind = token.GetKind(); if (!(kind == "EndOfFileToken" || kind == "EmptyToken" || kind == "EndOfDocumentationCommentToken" || kind == "EndOfDirectiveToken")) { //EmptyToken can be present even in non-error cases in VB (it is used for OmittedArgument). retVal = false; errorText = "A tree with 0 errors should not contain tokens with 0 width"; } } } return retVal; }