예제 #1
0
        private static UsingDirectiveSyntax ConsolidateUsingDirective(UsingDirectiveSyntax usingDirective)
        {
            var leadingTrivia = usingDirective.GetLeadingTrivia()
                                .Where(trivia => !trivia.IsKind(SyntaxKind.EndOfLineTrivia))
                                .ToList();

            return(usingDirective.WithLeadingTrivia(new SyntaxTriviaList(leadingTrivia)));
        }
        private static void AnalyzeCompilationUnit(SyntaxNodeAnalysisContext context)
        {
            var compilationUnit = (CompilationUnitSyntax)context.Node;

            UsingDirectiveSyntax usingDirective = compilationUnit.Usings.FirstOrDefault();

            if (usingDirective == null)
            {
                return;
            }

            SyntaxTriviaList.Reversed.Enumerator en = usingDirective.GetLeadingTrivia().Reverse().GetEnumerator();

            if (en.MoveNext())
            {
                if (en.Current.IsWhitespaceTrivia() &&
                    !en.MoveNext())
                {
                    if (IsPrecededWithExternAliasDirective())
                    {
                        ReportDiagnostic(usingDirective.SpanStart);
                    }
                }
                else if (en.Current.IsEndOfLineTrivia() &&
                         en.MoveNext() &&
                         en.Current.IsKind(SyntaxKind.SingleLineCommentTrivia))
                {
                    ReportDiagnostic(usingDirective.SpanStart);
                }
            }
            else if (IsPrecededWithExternAliasDirective())
            {
                ReportDiagnostic(usingDirective.SpanStart);
            }

            bool IsPrecededWithExternAliasDirective()
            {
                ExternAliasDirectiveSyntax externAliasDirective = compilationUnit.Externs.LastOrDefault();

                return(externAliasDirective?.FullSpan.End == usingDirective.FullSpan.Start &&
                       SyntaxTriviaAnalysis.IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(externAliasDirective.GetTrailingTrivia()));
            }

            void ReportDiagnostic(int position)
            {
                DiagnosticHelpers.ReportDiagnostic(
                    context,
                    DiagnosticDescriptors.AddEmptyLineBeforeUsingDirectiveList,
                    Location.Create(compilationUnit.SyntaxTree, new TextSpan(position, 0)));
            }
        }
예제 #3
0
        private UsingDirectiveSyntax WithLeadingNewlineCount(UsingDirectiveSyntax node, int newlineCount)
        {
            // Count current leading newlines
            int currentNewlineCount = 0;

            foreach (SyntaxTrivia trivia in node.GetLeadingTrivia())
            {
                if (trivia.Kind() == SyntaxKind.EndOfLineTrivia)
                {
                    currentNewlineCount++;
                }
                break;
            }

            if (currentNewlineCount == newlineCount)
            {
                // If count is already correct, leave alone
                return(node);
            }
            else if (currentNewlineCount > newlineCount)
            {
                // If too many, exclude the excess ones
                return(node.WithLeadingTrivia(node.GetLeadingTrivia().Skip(currentNewlineCount - newlineCount)));
            }
            else
            {
                // If too few, insert new leading ones
                SyntaxTriviaList newLeadingTrivia = node.GetLeadingTrivia();
                for (int i = currentNewlineCount; i < newlineCount; ++i)
                {
                    newLeadingTrivia = newLeadingTrivia.Insert(0, SyntaxFactory.CarriageReturnLineFeed);
                }

                return(node.WithLeadingTrivia(newLeadingTrivia));
            }
        }
        /// <summary>
        /// Check if <see cref="UsingDirectiveSyntax"/> is preceded by a preprocessor directive.
        /// </summary>
        /// <param name="usingDirective">The using directive.</param>
        /// <returns>True if the <see cref="UsingDirectiveSyntax"/> is preceded by a preprocessor directive, otherwise false.</returns>
        internal static bool IsPrecededByPreprocessorDirective(this UsingDirectiveSyntax usingDirective)
        {
            if (!usingDirective.HasLeadingTrivia)
            {
                return(false);
            }

            foreach (var trivia in usingDirective.GetLeadingTrivia())
            {
                if (trivia.IsDirective)
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #5
0
        private static UsingDirectiveSyntax RemoveLeadingAndTrailingCompilerDirectives(UsingDirectiveSyntax usingSyntax)
        {
            UsingDirectiveSyntax usingDirectiveToUse = usingSyntax;

            if (usingDirectiveToUse.HasLeadingTrivia)
            {
                if (usingDirectiveToUse.HasLeadingTrivia)
                {
                    var newLeadingTrivia = RemoveCompilerDirectives(usingDirectiveToUse.GetLeadingTrivia());
                    usingDirectiveToUse = usingDirectiveToUse.WithLeadingTrivia(newLeadingTrivia);
                }
                if (usingDirectiveToUse.HasTrailingTrivia)
                {
                    var newTrailingTrivia = RemoveCompilerDirectives(usingDirectiveToUse.GetTrailingTrivia());
                    usingDirectiveToUse = usingDirectiveToUse.WithTrailingTrivia(newTrailingTrivia);
                }
            }

            return(usingDirectiveToUse);
        }
        private static Task <Document> AddBlankLineBeforeUsingDirectiveAsync(
            Document document,
            UsingDirectiveSyntax usingDirective,
            CancellationToken cancellationToken)
        {
            SyntaxTriviaList leadingTrivia = usingDirective.GetLeadingTrivia();

            int index = leadingTrivia.Count;

            if (index > 0 &&
                leadingTrivia.Last().IsWhitespaceTrivia())
            {
                index--;
            }

            SyntaxTriviaList newLeadingTrivia = leadingTrivia.Insert(index, SyntaxTriviaAnalysis.DetermineEndOfLine(usingDirective));

            UsingDirectiveSyntax newUsingDirective = usingDirective.WithLeadingTrivia(newLeadingTrivia);

            return(document.ReplaceNodeAsync(usingDirective, newUsingDirective, cancellationToken));
        }
        private static void AnalyzeUsings(SyntaxNodeAnalysisContext context, SyntaxList <UsingDirectiveSyntax> usings)
        {
            int count = usings.Count;

            if (count <= 1)
            {
                return;
            }

            UsingDirectiveSyntax usingDirective1 = usings[0];

            for (int i = 1; i < count; i++, usingDirective1 = usings[i - 1])
            {
                if (usingDirective1.StaticKeyword.IsKind(SyntaxKind.StaticKeyword))
                {
                    return;
                }

                if (usingDirective1.Alias != null)
                {
                    return;
                }

                UsingDirectiveSyntax usingDirective2 = usings[i];

                if (usingDirective2.StaticKeyword.IsKind(SyntaxKind.StaticKeyword))
                {
                    return;
                }

                if (usingDirective2.Alias != null)
                {
                    return;
                }

                SyntaxTriviaList trailingTrivia = usingDirective1.GetTrailingTrivia();

                if (!SyntaxTriviaAnalysis.IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(trailingTrivia))
                {
                    continue;
                }

                IdentifierNameSyntax rootNamespace1 = usingDirective1.GetRootNamespace();

                if (rootNamespace1 == null)
                {
                    continue;
                }

                IdentifierNameSyntax rootNamespace2 = usingDirective2.GetRootNamespace();

                if (rootNamespace2 == null)
                {
                    continue;
                }

                SyntaxTriviaList leadingTrivia = usingDirective2.GetLeadingTrivia();

                bool isEmptyLine = SyntaxTriviaAnalysis.StartsWithOptionalWhitespaceThenEndOfLineTrivia(leadingTrivia);

                if (string.Equals(rootNamespace1.Identifier.ValueText, rootNamespace2.Identifier.ValueText, StringComparison.Ordinal))
                {
                    if (isEmptyLine)
                    {
                        DiagnosticHelpers.ReportDiagnosticIfNotSuppressed(
                            context,
                            DiagnosticDescriptors.RemoveEmptyLineBetweenUsingDirectivesWithSameRootNamespace,
                            Location.Create(context.Node.SyntaxTree, leadingTrivia[0].Span.WithLength(0)));
                    }
                }
                else if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.AddEmptyLineBetweenUsingDirectivesWithDifferentRootNamespaceOrViceVersa))
                {
                    if (isEmptyLine)
                    {
                        if (!context.IsAnalyzerSuppressed(AnalyzerOptions.RemoveEmptyLineBetweenUsingDirectivesWithDifferentRootNamespace))
                        {
                            DiagnosticHelpers.ReportDiagnostic(
                                context,
                                DiagnosticDescriptors.ReportOnly.RemoveEmptyLineBetweenUsingDirectivesWithDifferentRootNamespace,
                                Location.Create(context.Node.SyntaxTree, leadingTrivia[0].Span.WithLength(0)),
                                properties: DiagnosticProperties.AnalyzerOption_Invert);
                        }
                    }
                    else if (context.IsAnalyzerSuppressed(AnalyzerOptions.RemoveEmptyLineBetweenUsingDirectivesWithDifferentRootNamespace))
                    {
                        DiagnosticHelpers.ReportDiagnostic(
                            context,
                            DiagnosticDescriptors.AddEmptyLineBetweenUsingDirectivesWithDifferentRootNamespaceOrViceVersa,
                            Location.Create(context.Node.SyntaxTree, trailingTrivia.Last().Span.WithLength(0)));
                    }
                }
            }
        }
예제 #8
0
        private static void AnalyzeUsings(SyntaxNodeAnalysisContext context, SyntaxList <UsingDirectiveSyntax> usings)
        {
            int count = usings.Count;

            if (count <= 1)
            {
                return;
            }

            UsingDirectiveSyntax usingDirective1 = usings[0];

            for (int i = 1; i < count; i++, usingDirective1 = usings[i - 1])
            {
                if (usingDirective1.StaticKeyword.IsKind(SyntaxKind.StaticKeyword))
                {
                    return;
                }

                if (usingDirective1.Alias != null)
                {
                    return;
                }

                UsingDirectiveSyntax usingDirective2 = usings[i];

                if (usingDirective2.StaticKeyword.IsKind(SyntaxKind.StaticKeyword))
                {
                    return;
                }

                if (usingDirective2.Alias != null)
                {
                    return;
                }

                SyntaxTriviaList trailingTrivia = usingDirective1.GetTrailingTrivia();

                if (!SyntaxTriviaAnalysis.IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(trailingTrivia))
                {
                    continue;
                }

                IdentifierNameSyntax rootNamespace1 = usingDirective1.GetRootNamespace();

                if (rootNamespace1 == null)
                {
                    continue;
                }

                IdentifierNameSyntax rootNamespace2 = usingDirective2.GetRootNamespace();

                if (rootNamespace2 == null)
                {
                    continue;
                }

                SyntaxTriviaList leadingTrivia = usingDirective2.GetLeadingTrivia();

                bool isEmptyLine = SyntaxTriviaAnalysis.StartsWithOptionalWhitespaceThenEndOfLineTrivia(leadingTrivia);

                if (string.Equals(rootNamespace1.Identifier.ValueText, rootNamespace2.Identifier.ValueText, StringComparison.Ordinal))
                {
                    if (isEmptyLine)
                    {
                        if (DiagnosticRules.RemoveBlankLineBetweenUsingDirectivesWithSameRootNamespace.IsEffective(context))
                        {
                            DiagnosticHelpers.ReportDiagnostic(
                                context,
                                DiagnosticRules.RemoveBlankLineBetweenUsingDirectivesWithSameRootNamespace,
                                Location.Create(context.Node.SyntaxTree, leadingTrivia[0].Span.WithLength(0)));
                        }

                        if (DiagnosticRules.BlankLineBetweenUsingDirectives.IsEffective(context) &&
                            context.GetBlankLineBetweenUsingDirectives() == UsingDirectiveBlankLineStyle.Never)
                        {
                            DiagnosticHelpers.ReportDiagnostic(
                                context,
                                DiagnosticRules.BlankLineBetweenUsingDirectives,
                                Location.Create(context.Node.SyntaxTree, leadingTrivia[0].Span.WithLength(0)),
                                properties: DiagnosticProperties.AnalyzerOption_Invert,
                                "Remove");
                        }
                    }
                }
                else if (DiagnosticRules.BlankLineBetweenUsingDirectives.IsEffective(context))
                {
                    UsingDirectiveBlankLineStyle style = context.GetBlankLineBetweenUsingDirectives();

                    if (isEmptyLine)
                    {
                        if (style == UsingDirectiveBlankLineStyle.Never)
                        {
                            DiagnosticHelpers.ReportDiagnostic(
                                context,
                                DiagnosticRules.BlankLineBetweenUsingDirectives,
                                Location.Create(context.Node.SyntaxTree, leadingTrivia[0].Span.WithLength(0)),
                                properties: DiagnosticProperties.AnalyzerOption_Invert,
                                "Remove");
                        }
                    }
                    else if (style == UsingDirectiveBlankLineStyle.SeparateGroups)
                    {
                        DiagnosticHelpers.ReportDiagnostic(
                            context,
                            DiagnosticRules.BlankLineBetweenUsingDirectives,
                            Location.Create(context.Node.SyntaxTree, trailingTrivia.Last().Span.WithLength(0)),
                            "Add");
                    }
                }
            }
        }
예제 #9
0
        private static void AnalyzeUsings(SyntaxNodeAnalysisContext context, SyntaxList <UsingDirectiveSyntax> usings)
        {
            int count = usings.Count;

            if (count <= 1)
            {
                return;
            }

            UsingDirectiveSyntax usingDirective1 = usings[0];

            for (int i = 1; i < count; i++, usingDirective1 = usings[i - 1])
            {
                if (usingDirective1.StaticKeyword.IsKind(SyntaxKind.StaticKeyword))
                {
                    return;
                }

                if (usingDirective1.Alias != null)
                {
                    return;
                }

                UsingDirectiveSyntax usingDirective2 = usings[i];

                if (usingDirective2.StaticKeyword.IsKind(SyntaxKind.StaticKeyword))
                {
                    return;
                }

                if (usingDirective2.Alias != null)
                {
                    return;
                }

                SyntaxTriviaList trailingTrivia = usingDirective1.GetTrailingTrivia();

                if (!SyntaxTriviaAnalysis.IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(trailingTrivia))
                {
                    continue;
                }

                IdentifierNameSyntax rootNamespace1 = usingDirective1.GetRootNamespace();

                if (rootNamespace1 == null)
                {
                    continue;
                }

                IdentifierNameSyntax rootNamespace2 = usingDirective2.GetRootNamespace();

                if (rootNamespace2 == null)
                {
                    continue;
                }

                SyntaxTriviaList leadingTrivia = usingDirective2.GetLeadingTrivia();

                bool isEmptyLine = SyntaxTriviaAnalysis.StartsWithOptionalWhitespaceThenEndOfLineTrivia(leadingTrivia);

                if (string.Equals(rootNamespace1.Identifier.ValueText, rootNamespace2.Identifier.ValueText, StringComparison.Ordinal))
                {
                    if (isEmptyLine)
                    {
                        ReportDiagnostic(
                            context,
                            DiagnosticDescriptors.RemoveEmptyLineBetweenUsingDirectivesWithSameRootNamespace,
                            leadingTrivia[0]);
                    }
                }
                else if (isEmptyLine)
                {
                    ReportDiagnostic(
                        context,
                        DiagnosticDescriptors.RemoveEmptyLineBetweenUsingDirectivesWithDifferentRootNamespace,
                        leadingTrivia[0]);
                }
                else
                {
                    ReportDiagnostic(
                        context,
                        DiagnosticDescriptors.AddEmptyLineBetweenUsingDirectivesWithDifferentRootNamespace,
                        trailingTrivia.Last());
                }
            }
        }