예제 #1
0
        private static void HandleSingleLineComment(SyntaxTreeAnalysisContext context, SyntaxTrivia singleLineComment)
        {
            int index = 0;

            // PERF: Explicitly cast to IReadOnlyList so we only box once.
            IReadOnlyList <SyntaxTrivia> list = TriviaHelper.GetContainingTriviaList(singleLineComment, out index);
            var firstNonWhiteSpace            = TriviaHelper.IndexOfFirstNonWhitespaceTrivia(list);

            // When we encounter a block of single line comments, we only want to raise this diagnostic
            // on the first or last line.  This ensures that whitespace in code commented out using
            // the Comment Selection option in Visual Studio will not raise the diagnostic for every
            // blank line in the code which is commented out.
            bool isFirst = index == firstNonWhiteSpace;

            if (!isFirst)
            {
                // This is -2 because we need to go back past the end of line trivia as well.
                var lastNonWhiteSpace = TriviaHelper.IndexOfTrailingWhitespace(list) - 2;
                if (index != lastNonWhiteSpace)
                {
                    return;
                }
            }

            if (IsNullOrWhiteSpace(singleLineComment.ToString(), 2))
            {
                var diagnostic = Diagnostic.Create(Descriptor, singleLineComment.GetLocation());
                context.ReportDiagnostic(diagnostic);
            }
        }
        private static async Task <SyntaxNode> GetTransformedSyntaxRootAsync(Document document, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var settings = document.Project.AnalyzerOptions.GetStyleCopSettings(root.SyntaxTree, cancellationToken);

            var        fileHeader = FileHeaderHelpers.ParseFileHeader(root);
            SyntaxNode newSyntaxRoot;

            if (fileHeader.IsMissing)
            {
                newSyntaxRoot = AddHeader(document, root, GetFileName(document), settings);
            }
            else
            {
                var trivia       = root.GetLeadingTrivia();
                var commentIndex = TriviaHelper.IndexOfFirstNonWhitespaceTrivia(trivia, false);

                // Safe to do this as fileHeader.IsMissing is false.
                var isMultiLineComment = trivia[commentIndex].IsKind(SyntaxKind.MultiLineCommentTrivia);

                var xmlFileHeader = FileHeaderHelpers.ParseXmlFileHeader(root);
                if (isMultiLineComment && !xmlFileHeader.IsMalformed)
                {
                    newSyntaxRoot = ReplaceWellFormedMultiLineCommentHeader(document, root, settings, commentIndex, xmlFileHeader);
                }
                else
                {
                    newSyntaxRoot = ReplaceHeader(document, root, settings, xmlFileHeader.IsMalformed);
                }
            }

            return(newSyntaxRoot);
        }
        /// <summary>
        /// Checks if a given <see cref="SyntaxTree"/> only contains whitespaces. We don't want to analyze empty files.
        /// </summary>
        /// <param name="tree">The syntax tree to examine.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> that the task will observe.</param>
        /// <returns>
        /// <para><see langword="true"/> if <paramref name="tree"/> only contains whitespaces; otherwise, <see langword="false"/>.</para>
        /// </returns>
        private static bool IsEmpty(SyntaxTree tree, CancellationToken cancellationToken)
        {
            var root       = tree.GetRoot(cancellationToken);
            var firstToken = root.GetFirstToken(includeZeroWidth: true);

            return(firstToken.IsKind(SyntaxKind.EndOfFileToken) &&
                   TriviaHelper.IndexOfFirstNonWhitespaceTrivia(firstToken.LeadingTrivia, true) == -1);
        }
예제 #4
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);
        }