public override SyntaxNode VisitUsingDirective(UsingDirectiveSyntax node) { // The strip list is used to remove using directives that will be moved. if (this.stripList.Contains(node)) { var nextToken = node.SemicolonToken.GetNextToken(); if (!nextToken.IsKind(SyntaxKind.None)) { var index = TriviaHelper.IndexOfFirstNonBlankLineTrivia(nextToken.LeadingTrivia); if (index != 0) { this.tokensToStrip.AddLast(nextToken); } } return(null); } // The replacement map is used to replace using declarations in place in sorted order (inside directive trivia) UsingDirectiveSyntax replacementNode; if (this.replaceMap.TryGetValue(node, out replacementNode)) { return(replacementNode); } return(base.VisitUsingDirective(node)); }
private static void HandleSyntaxTreeAnalysis(SyntaxTreeAnalysisContext context) { var firstToken = context.Tree.GetRoot().GetFirstToken(includeZeroWidth: true); if (firstToken.HasLeadingTrivia) { var leadingTrivia = firstToken.LeadingTrivia; var firstNonBlankLineTriviaIndex = TriviaHelper.IndexOfFirstNonBlankLineTrivia(leadingTrivia); switch (firstNonBlankLineTriviaIndex) { case 0: // no blank lines break; case -1: // only blank lines context.ReportDiagnostic(Diagnostic.Create(Descriptor, Location.Create(context.Tree, leadingTrivia.Span))); break; default: var textSpan = TextSpan.FromBounds(leadingTrivia[0].Span.Start, leadingTrivia[firstNonBlankLineTriviaIndex].Span.Start); context.ReportDiagnostic(Diagnostic.Create(Descriptor, Location.Create(context.Tree, textSpan))); break; } } }
private static void HandleSyntaxTree(SyntaxTreeAnalysisContext context) { if (context.Tree.IsWhitespaceOnly(context.CancellationToken)) { // Handling of empty documents is now the responsibility of the analyzers return; } var firstToken = context.Tree.GetRoot().GetFirstToken(includeZeroWidth: true); if (firstToken.HasLeadingTrivia) { var leadingTrivia = firstToken.LeadingTrivia; var firstNonBlankLineTriviaIndex = TriviaHelper.IndexOfFirstNonBlankLineTrivia(leadingTrivia); switch (firstNonBlankLineTriviaIndex) { case 0: // no blank lines break; case -1: // only blank lines context.ReportDiagnostic(Diagnostic.Create(Descriptor, Location.Create(context.Tree, leadingTrivia.Span))); break; default: var textSpan = TextSpan.FromBounds(leadingTrivia[0].Span.Start, leadingTrivia[firstNonBlankLineTriviaIndex].Span.Start); context.ReportDiagnostic(Diagnostic.Create(Descriptor, Location.Create(context.Tree, textSpan))); break; } } }
/// <inheritdoc/> public override async Task RegisterCodeFixesAsync(CodeFixContext context) { foreach (Diagnostic diagnostic in context.Diagnostics.Where(d => FixableDiagnostics.Contains(d.Id))) { var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); var firstToken = syntaxRoot.GetFirstToken(includeZeroWidth: true); var leadingTrivia = firstToken.LeadingTrivia; var newTriviaList = SyntaxFactory.TriviaList(); var firstNonBlankLineTriviaIndex = TriviaHelper.IndexOfFirstNonBlankLineTrivia(leadingTrivia); if (firstNonBlankLineTriviaIndex != -1) { for (var index = firstNonBlankLineTriviaIndex; index < leadingTrivia.Count; index++) { newTriviaList = newTriviaList.Add(leadingTrivia[index]); } } var newFirstToken = firstToken.WithLeadingTrivia(newTriviaList); var newSyntaxRoot = syntaxRoot.ReplaceToken(firstToken, newFirstToken); var newDocument = context.Document.WithSyntaxRoot(newSyntaxRoot); context.RegisterCodeFix(CodeAction.Create("Remove blank lines at the start of the file", token => Task.FromResult(newDocument)), diagnostic); } }
public override SyntaxToken VisitToken(SyntaxToken token) { if (this.tokensToStrip.Contains(token)) { this.tokensToStrip.Remove(token); var index = TriviaHelper.IndexOfFirstNonBlankLineTrivia(token.LeadingTrivia); var newLeadingTrivia = (index == -1) ? SyntaxFactory.TriviaList() : SyntaxFactory.TriviaList(token.LeadingTrivia.Skip(index)); return(token.WithLeadingTrivia(newLeadingTrivia)); } return(base.VisitToken(token)); }
private static async Task <SyntaxNode> GetTransformedSyntaxRootAsync(Document document, CancellationToken token) { var syntaxRoot = await document.GetSyntaxRootAsync(token).ConfigureAwait(false); var firstToken = syntaxRoot.GetFirstToken(includeZeroWidth: true); var leadingTrivia = firstToken.LeadingTrivia; var newTriviaList = SyntaxFactory.TriviaList(); var firstNonBlankLineTriviaIndex = TriviaHelper.IndexOfFirstNonBlankLineTrivia(leadingTrivia); if (firstNonBlankLineTriviaIndex != -1) { for (var index = firstNonBlankLineTriviaIndex; index < leadingTrivia.Count; index++) { newTriviaList = newTriviaList.Add(leadingTrivia[index]); } } var newFirstToken = firstToken.WithLeadingTrivia(newTriviaList); var newSyntaxRoot = syntaxRoot.ReplaceToken(firstToken, newFirstToken); return(newSyntaxRoot); }
private static List <BaseFieldDeclarationSyntax> DeclarationSplitter( Document document, VariableDeclarationSyntax declaration, Func <VariableDeclarationSyntax, BaseFieldDeclarationSyntax> declarationFactory, SyntaxTriviaList declarationTrailingTrivia) { SeparatedSyntaxList <VariableDeclaratorSyntax> variables = declaration.Variables; VariableDeclaratorSyntax first = variables.First(); BaseFieldDeclarationSyntax previous = null; var newFieldDeclarations = new List <BaseFieldDeclarationSyntax>(variables.Count); foreach (SyntaxNodeOrToken nodeOrToken in variables.GetWithSeparators()) { if (previous == null) { VariableDeclaratorSyntax variable = (VariableDeclaratorSyntax)nodeOrToken.AsNode(); variable = variable.WithIdentifier(variable.Identifier.WithoutLeadingWhitespace()); var variableDeclarator = SyntaxFactory.SingletonSeparatedList(variable); previous = declarationFactory(declaration.WithVariables(variableDeclarator)); if (variable != first) { var triviaList = previous.GetLeadingTrivia().WithoutDirectiveTrivia(); // Remove all leading blank lines var nonBlankLinetriviaIndex = TriviaHelper.IndexOfFirstNonBlankLineTrivia(triviaList); if (nonBlankLinetriviaIndex > 0) { triviaList = triviaList.RemoveRange(0, nonBlankLinetriviaIndex); } // Add a blank line if the first line contains a comment. var nonWhitespaceTriviaIndex = TriviaHelper.IndexOfFirstNonWhitespaceTrivia(triviaList, false); if (nonWhitespaceTriviaIndex >= 0) { switch (triviaList[nonWhitespaceTriviaIndex].Kind()) { case SyntaxKind.SingleLineCommentTrivia: case SyntaxKind.MultiLineCommentTrivia: triviaList = triviaList.Insert(0, SyntaxFactory.CarriageReturnLineFeed); break; } } previous = previous.WithLeadingTrivia(triviaList); } } else { SyntaxToken commaToken = nodeOrToken.AsToken(); SyntaxTriviaList trailingTrivia = commaToken.TrailingTrivia; if (trailingTrivia.Any()) { if (!trailingTrivia.Last().IsKind(SyntaxKind.EndOfLineTrivia)) { trailingTrivia = trailingTrivia.WithoutTrailingWhitespace().Add(FormattingHelper.GetNewLineTrivia(document)); } } else { trailingTrivia = SyntaxTriviaList.Create(FormattingHelper.GetNewLineTrivia(document)); } newFieldDeclarations.Add(previous.WithTrailingTrivia(trailingTrivia)); previous = null; } } newFieldDeclarations.Add(previous.WithTrailingTrivia(declarationTrailingTrivia)); return(newFieldDeclarations); }