예제 #1
0
            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));
            }
예제 #2
0
        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;
                }
            }
        }
예제 #4
0
        /// <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);
            }
        }
예제 #5
0
            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));
            }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }