public static Task <Document> AddNewLineBeforeInsteadOfAfterAsync( Document document, SyntaxNodeOrToken left, SyntaxNodeOrToken middle, SyntaxNodeOrToken right, CancellationToken cancellationToken = default) { StringBuilder sb = StringBuilderCache.GetInstance(); SyntaxTriviaList trailingTrivia = middle.GetTrailingTrivia(); if (IsOptionalWhitespaceThenEndOfLineTrivia(trailingTrivia)) { sb.Append(DetermineEndOfLine(middle).ToString()); } else { sb.Append(trailingTrivia.ToString()); } sb.Append(right.GetLeadingTrivia().ToString()); sb.Append(middle.ToString()); sb.Append(" "); return(document.WithTextChangeAsync( TextSpan.FromBounds(left.Span.End, right.SpanStart), StringBuilderCache.GetStringAndFree(sb), cancellationToken)); }
public static Task <Document> AddNewLineAfterInsteadOfBeforeAsync( Document document, SyntaxNodeOrToken left, SyntaxNodeOrToken middle, SyntaxNodeOrToken right, CancellationToken cancellationToken = default) { StringBuilder sb = StringBuilderCache.GetInstance(); sb.Append(" "); sb.Append(middle.ToString()); SyntaxTriviaList trailingTrivia = left.GetTrailingTrivia(); if (SyntaxTriviaAnalysis.IsOptionalWhitespaceThenEndOfLineTrivia(trailingTrivia)) { sb.Append(SyntaxTriviaAnalysis.GetEndOfLine(left).ToString()); } else { sb.Append(trailingTrivia.ToString()); } sb.Append(middle.GetLeadingTrivia().ToString()); string newText = StringBuilderCache.GetStringAndFree(sb); var textChange = new TextChange( TextSpan.FromBounds(left.Span.End, right.SpanStart), newText); return(document.WithTextChangeAsync(textChange, cancellationToken)); }
public override SyntaxNode VisitInitializerExpression(InitializerExpressionSyntax node) { if (!node.DescendantTrivia().All(SyntaxUtils.IsWhitespace)) { return(node); // nothing to do here } if (node.IsKind(SyntaxKind.ComplexElementInitializerExpression)) { return(VisitElementInitializer(node)); } if (!node.IsKind(SyntaxKind.CollectionInitializerExpression) && !node.IsKind(SyntaxKind.ArrayInitializerExpression)) { return(node); } var indent = node.GetIndentation(); var exprList = node.Expressions; SyntaxNodeOrToken prevNode = node.OpenBraceToken; foreach (var nodeOrToken in exprList.GetWithSeparators()) { if (nodeOrToken.IsNode && prevNode.GetTrailingTrivia().Any(SyntaxKind.EndOfLineTrivia)) { var tok = nodeOrToken.AsNode().GetFirstToken(); AddChange(tok, tok.WithLeadingWhitespace(indent + '\t')); } prevNode = nodeOrToken; } if (prevNode.GetTrailingTrivia().Any(SyntaxKind.EndOfLineTrivia)) { AddChange(node.CloseBraceToken, node.CloseBraceToken.WithLeadingWhitespace(indent)); } return(base.VisitInitializerExpression(node)); }
private void AddTriviaIfAvailable(SyntaxNodeOrToken node, TreeViewItem treeNodeItem) { if (node.HasLeadingTrivia) { var trivia = node.GetLeadingTrivia()[0]; WriteTriviaNode(treeNodeItem, trivia, "Leading Trivia - "); } if (node.HasTrailingTrivia) { var trivia = node.GetTrailingTrivia()[0]; WriteTriviaNode(treeNodeItem, trivia, "Trailing Trivia - "); } }
/// <summary> /// Search the Children of this object for an EOL Trivia after the position of the replacedNode /// </summary> /// <param name="objToSearch">The Node or Token to search the children of (and then itself) for a SyntaxKind.EndOfLineTrivia</param> /// <param name="endReplacedSpan">The character position at the end of the replacedNode - dont want EOLs from before the replacement</param> /// <param name="foundEOL">the object to get back to the top when we find it</param> /// <returns>True if we found it</returns> bool FindEOLAfter(SyntaxNodeOrToken objToSearch, int endReplacedSpan, ref SyntaxTrivia foundEOL) { // Guard for the object is before the replacedNode if (objToSearch.FullSpan.End < endReplacedSpan) { return(false); } // Search each child for the trivia foreach (SyntaxNodeOrToken n in objToSearch.ChildNodesAndTokens()) { if (n.FullSpan.End < endReplacedSpan) { continue; } if (FindEOLAfter(n, endReplacedSpan, ref foundEOL)) { return(true); } } // Now search this object foreach (SyntaxTrivia item in objToSearch.GetLeadingTrivia()) { //Dont bother if the start of the element is before the replaced Node if (objToSearch.FullSpan.Start < endReplacedSpan) { continue; } if (item.Kind() == SyntaxKind.EndOfLineTrivia) { foundEOL = item; return(true); } } foreach (SyntaxTrivia item in objToSearch.GetTrailingTrivia()) { if (item.Kind() == SyntaxKind.EndOfLineTrivia) { foundEOL = item; return(true); } } return(false); }
static IEnumerable <(object element, ElementType type, int nestedLevel)> GetTrivia(SyntaxNodeOrToken target, int nestedLevel) { if (target.HasLeadingTrivia) { foreach (var trivia in target.GetLeadingTrivia()) { yield return(trivia, ElementType.SyntaxTrivia, nestedLevel); } } if (target.HasTrailingTrivia) { foreach (var trivia in target.GetTrailingTrivia()) { yield return(trivia, ElementType.SyntaxTrivia, nestedLevel); } } }
static void SeekTrivia(SyntaxNodeOrToken target, int nestedLevel) { if (target.HasLeadingTrivia) { foreach (var trivia in target.GetLeadingTrivia()) { ConsoleWrite(trivia, nestedLevel); } } if (target.HasTrailingTrivia) { foreach (var trivia in target.GetTrailingTrivia()) { ConsoleWrite(trivia, nestedLevel); } } }
private Nodes SyntaxNodeToNodes(SyntaxNodeOrToken s) { Nodes node = new Nodes(); node.Kind = s.Kind(); node.Language = s.Kind().ToString() + " [" + s.SpanStart + "..." + s.Span.End + "]"; node.syntaxNode = s; if (s.HasLeadingTrivia) { SyntaxTriviaList d = s.GetLeadingTrivia(); foreach (SyntaxTrivia t in d) { Nodes tr = new Nodes(); tr.Language = "Leading: " + t.ToString() + " [" + t.SpanStart + "..." + t.Span.End + "]"; node.nodes.Add(tr); } node.IsLeadingTrivia = true; } if (s.HasTrailingTrivia) { SyntaxTriviaList d = s.GetTrailingTrivia(); foreach (SyntaxTrivia t in d) { Nodes tr = new Nodes(); tr.Language = "Trailing: " + t.ToString() + " [" + t.SpanStart + "..." + t.Span.End + "]"; node.nodes.Add(tr); } node.IsTrailingTrivia = true; } foreach (SyntaxNodeOrToken c in s.ChildNodesAndTokens()) { Nodes ng = SyntaxNodeToNodes(c); node.nodes.Add(ng); } return(node); }
/// <summary> /// Prints full hierarchy of the specified syntax node or token as string representation. /// </summary> /// <param name="builder">The builder used to create a string representation.</param> /// <param name="nodeOrToken">The syntax node or token to print.</param> /// <param name="depth">The initial indent depth.</param> /// <param name="indent">The indent value used for nested nodes.</param> public static void PrintSyntaxNodeOrToken(StringBuilder builder, SyntaxNodeOrToken nodeOrToken, int depth = 0, int indent = 4) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (depth < 0) { throw new ArgumentOutOfRangeException(nameof(depth)); } if (indent < 0) { throw new ArgumentOutOfRangeException(nameof(indent)); } builder.Append(' ', indent * depth); builder.Append($"{nodeOrToken.Kind()} {nodeOrToken.Span}"); builder.AppendLine(); foreach (SyntaxTrivia trivia in nodeOrToken.GetLeadingTrivia()) { builder.Append(' ', indent * (depth + 1)); builder.Append($"Lead: {trivia.Kind()} {trivia.Span}"); builder.AppendLine(); } foreach (SyntaxTrivia trivia in nodeOrToken.GetTrailingTrivia()) { builder.Append(' ', indent * (depth + 1)); builder.Append($"Trail: {trivia.Kind()} {trivia.Span}"); builder.AppendLine(); } foreach (SyntaxNodeOrToken childNodeOrToken in nodeOrToken.ChildNodesAndTokens()) { PrintSyntaxNodeOrToken(builder, childNodeOrToken, depth + 1, indent); } }
private static void Analyze <TNode>( SyntaxNodeAnalysisContext context, SyntaxNodeOrToken openNodeOrToken, SeparatedSyntaxList <TNode> nodes) where TNode : SyntaxNode { TNode first = nodes.FirstOrDefault(); if (first == null) { return; } TextSpan span = nodes.GetSpan(includeExteriorTrivia: false); if (span.IsSingleLine(first.SyntaxTree)) { SyntaxTriviaList trailing = openNodeOrToken.GetTrailingTrivia(); if (!IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(trailing)) { return; } int indentationLength = GetIncreasedIndentationLength(openNodeOrToken.Parent); if (indentationLength == 0) { return; } if (ShouldFixIndentation(first.GetLeadingTrivia(), indentationLength)) { ReportDiagnostic(); } } else { TextLineCollection lines = null; IndentationAnalysis indentationAnalysis = IndentationAnalysis.Create(openNodeOrToken.Parent); int indentationLength = indentationAnalysis.IncreasedIndentationLength; if (indentationLength == 0) { return; } for (int i = nodes.Count - 1; i >= 0; i--) { SyntaxTriviaList trailing = (i == 0) ? openNodeOrToken.GetTrailingTrivia() : nodes.GetSeparator(i - 1).TrailingTrivia; if (IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(trailing)) { if (ShouldFixIndentation(nodes[i].GetLeadingTrivia(), indentationLength)) { ReportDiagnostic(); break; } } else { if (nodes.Count > 1 && ShouldWrapAndIndent(context.Node, i)) { ReportDiagnostic(); break; } if (nodes.Count == 1 && first.IsKind(SyntaxKind.Argument)) { var argument = (ArgumentSyntax)(SyntaxNode)first; LambdaBlock lambdaBlock = GetLambdaBlock(argument, lines ??= first.SyntaxTree.GetText().Lines); if (lambdaBlock.Block != null) { SyntaxToken token = lambdaBlock.Token; SyntaxTriviaList leading = token.LeadingTrivia; if (leading.Any()) { SyntaxTrivia trivia = leading.Last(); if (trivia.IsWhitespaceTrivia() && trivia.SpanStart == lambdaBlock.LineStartIndex && trivia.Span.Length != indentationAnalysis.IndentationLength) { ReportDiagnostic(); break; } } else if (lambdaBlock.LineStartIndex == token.SpanStart) { ReportDiagnostic(); break; } return; } } if (lines == null) { lines = first.SyntaxTree.GetText().Lines; } int lineIndex = lines.IndexOf(span.Start); if (lineIndex < lines.Count - 1) { int lineStartIndex = lines[lineIndex + 1].Start; if (first.Span.Contains(lineStartIndex)) { SyntaxToken token = first.FindToken(lineStartIndex); if (!token.IsKind(SyntaxKind.None)) { SyntaxTriviaList leading = token.LeadingTrivia; if (leading.Any()) { if (leading.FullSpan.Contains(lineStartIndex)) { SyntaxTrivia trivia = leading.Last(); if (trivia.IsWhitespaceTrivia() && trivia.SpanStart == lineStartIndex && trivia.Span.Length != indentationLength) { ReportDiagnostic(); break; } } } else if (lineStartIndex == token.SpanStart) { ReportDiagnostic(); break; } } } } } } } void ReportDiagnostic() { DiagnosticHelpers.ReportDiagnostic( context, DiagnosticDescriptors.FixFormattingOfList, Location.Create(first.SyntaxTree, nodes.Span), GetTitle()); }
private int GetSimilarity(SyntaxNodeOrToken node1, SyntaxNodeOrToken node2) { // count the characters in the common/identical nodes int w = 0; _nodeSimilaritySet.Clear(); _tokenTextSimilaritySet.Clear(); if (node1.IsToken && node2.IsToken) { var text1 = node1.ToString(); var text2 = node2.ToString(); if (text1 == text2) { // main text of token is the same w += text1.Length; } foreach (var tr in node1.GetLeadingTrivia()) { _nodeSimilaritySet.Add(tr.UnderlyingNode); } foreach (var tr in node1.GetTrailingTrivia()) { _nodeSimilaritySet.Add(tr.UnderlyingNode); } foreach (var tr in node2.GetLeadingTrivia()) { if (_nodeSimilaritySet.Contains(tr.UnderlyingNode)) { w += tr.FullSpan.Length; } } foreach (var tr in node2.GetTrailingTrivia()) { if (_nodeSimilaritySet.Contains(tr.UnderlyingNode)) { w += tr.FullSpan.Length; } } } else { foreach (var n1 in node1.ChildNodesAndTokens()) { _nodeSimilaritySet.Add(n1.UnderlyingNode); if (n1.IsToken) { _tokenTextSimilaritySet.Add(n1.ToString()); } } foreach (var n2 in node2.ChildNodesAndTokens()) { if (_nodeSimilaritySet.Contains(n2.UnderlyingNode)) { w += n2.FullSpan.Length; } else if (n2.IsToken) { var tokenText = n2.ToString(); if (_tokenTextSimilaritySet.Contains(tokenText)) { w += tokenText.Length; } } } } return w; }