Ejemplo n.º 1
0
        internal static MemberDeclarationSyntax RemoveSingleLineDocumentationComment(MemberDeclarationSyntax declaration)
        {
            if (declaration == null)
            {
                throw new ArgumentNullException(nameof(declaration));
            }

            SyntaxTriviaList leadingTrivia = declaration.GetLeadingTrivia();

            SyntaxTriviaList.Reversed.Enumerator en = leadingTrivia.Reverse().GetEnumerator();

            int i = 0;

            while (en.MoveNext())
            {
                SyntaxKind kind = en.Current.Kind();

                if (kind == SyntaxKind.WhitespaceTrivia ||
                    kind == SyntaxKind.EndOfLineTrivia)
                {
                    i++;
                }
                else if (kind == SyntaxKind.SingleLineDocumentationCommentTrivia)
                {
                    return(declaration.WithLeadingTrivia(leadingTrivia.Take(leadingTrivia.Count - (i + 1))));
                }
                else
                {
                    return(declaration);
                }
            }

            return(declaration);
        }
            static bool ShouldFixIndentation(SyntaxTriviaList leading, int indentationLength)
            {
                SyntaxTriviaList.Reversed.Enumerator en = leading.Reverse().GetEnumerator();

                if (!en.MoveNext())
                {
                    return(true);
                }

                switch (en.Current.Kind())
                {
                case SyntaxKind.WhitespaceTrivia:
                {
                    if (en.Current.Span.Length != indentationLength)
                    {
                        if (!en.MoveNext() ||
                            en.Current.IsEndOfLineTrivia())
                        {
                            return(true);
                        }
                    }

                    break;
                }

                case SyntaxKind.EndOfLineTrivia:
                {
                    return(true);
                }
                }

                return(false);
            }
Ejemplo n.º 3
0
        internal static MemberDeclarationSyntax RemoveSingleLineDocumentationComment(MemberDeclarationSyntax member)
        {
            if (member == null)
            {
                throw new ArgumentNullException(nameof(member));
            }

            SyntaxTriviaList leadingTrivia = member.GetLeadingTrivia();

            SyntaxTriviaList.Reversed.Enumerator en = leadingTrivia.Reverse().GetEnumerator();

            int i = 0;

            while (en.MoveNext())
            {
                if (en.Current.IsWhitespaceOrEndOfLineTrivia())
                {
                    i++;
                }
                else if (en.Current.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia))
                {
                    return(member.WithLeadingTrivia(leadingTrivia.Take(leadingTrivia.Count - (i + 1))));
                }
                else
                {
                    return(member);
                }
            }

            return(member);
        }
        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)));
            }
        }
Ejemplo n.º 5
0
        public static (TextSpan span, bool hasDocumentationComment) AnalyzeLeadingTrivia(SyntaxNode declaration)
        {
            SyntaxTriviaList leadingTrivia = declaration.GetLeadingTrivia();

            SyntaxTriviaList.Reversed.Enumerator en = leadingTrivia.Reverse().GetEnumerator();

            var span = default(TextSpan);

            while (en.MoveNext())
            {
                if (en.Current.Kind() == SyntaxKind.WhitespaceTrivia &&
                    !en.MoveNext())
                {
                    break;
                }

                if (en.Current.Kind() == SyntaxKind.EndOfLineTrivia)
                {
                    if (!en.MoveNext())
                    {
                        break;
                    }

                    if (en.Current.Kind() == SyntaxKind.SingleLineCommentTrivia)
                    {
                        span = (span == default(TextSpan))
                            ? en.Current.Span
                            : TextSpan.FromBounds(en.Current.SpanStart, span.End);
                    }
                }
                else
                {
                    do
                    {
                        if (SyntaxFacts.IsDocumentationCommentTrivia(en.Current.Kind()))
                        {
                            return(default(TextSpan), true);
                        }
                    } while (en.MoveNext());

                    break;
                }
            }

            return(span, false);
        }
Ejemplo n.º 6
0
        private static void AnalyzeEndRegionDirectiveTrivia(SyntaxNodeAnalysisContext context)
        {
            var endRegionDirective = (EndRegionDirectiveTriviaSyntax)context.Node;

            if (IsPrecededWithEmptyLineOrRegionDirective())
            {
                return;
            }

            DiagnosticHelpers.ReportDiagnostic(
                context,
                DiagnosticDescriptors.AddEmptyLineBeforeEndRegionDirective,
                Location.Create(endRegionDirective.SyntaxTree, endRegionDirective.Span.WithLength(0)));

            bool IsPrecededWithEmptyLineOrRegionDirective()
            {
                SyntaxTrivia parentTrivia = endRegionDirective.ParentTrivia;

                SyntaxTriviaList.Reversed.Enumerator en = parentTrivia.Token.LeadingTrivia.Reverse().GetEnumerator();

                while (en.MoveNext())
                {
                    if (en.Current == parentTrivia)
                    {
                        if (!en.MoveNext())
                        {
                            return(false);
                        }

                        if (en.Current.IsWhitespaceTrivia() &&
                            !en.MoveNext())
                        {
                            return(false);
                        }

                        if (en.Current.IsKind(SyntaxKind.RegionDirectiveTrivia))
                        {
                            return(true);
                        }

                        if (!en.Current.IsEndOfLineTrivia())
                        {
                            return(false);
                        }

                        if (!en.MoveNext())
                        {
                            return(true);
                        }

                        if (en.Current.IsWhitespaceTrivia() &&
                            !en.MoveNext())
                        {
                            return(false);
                        }

                        return(en.Current.IsEndOfLineTrivia());
                    }
                }

                return(false);
            }
        }
Ejemplo n.º 7
0
        public static Task <Document> FixBinaryExpressionAsync(
            Document document,
            BinaryExpressionSyntax binaryExpression,
            TextSpan span,
            CancellationToken cancellationToken)
        {
            IndentationAnalysis indentationAnalysis = AnalyzeIndentation(binaryExpression, cancellationToken);

            string indentation;

            if (indentationAnalysis.Indentation == binaryExpression.GetLeadingTrivia().LastOrDefault() &&
                AnalyzerOptions.AddNewLineAfterBinaryOperatorInsteadOfBeforeIt.IsEnabled(document, binaryExpression))
            {
                indentation = indentationAnalysis.Indentation.ToString();
            }
            else
            {
                indentation = indentationAnalysis.GetIncreasedIndentation();
            }

            string endOfLineAndIndentation = DetermineEndOfLine(binaryExpression).ToString() + indentation;

            var textChanges = new List <TextChange>();
            int prevIndex   = binaryExpression.Span.End;

            SyntaxKind binaryKind = binaryExpression.Kind();

            while (true)
            {
                SyntaxToken token = binaryExpression.OperatorToken;

                if (token.Span.End > span.End)
                {
                    continue;
                }

                if (token.SpanStart < span.Start)
                {
                    break;
                }

                ExpressionSyntax left          = binaryExpression.Left;
                ExpressionSyntax right         = binaryExpression.Right;
                SyntaxTriviaList leftTrailing  = left.GetTrailingTrivia();
                SyntaxTriviaList tokenTrailing = token.TrailingTrivia;

                if (IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(leftTrailing))
                {
                    if (!SetIndentation(token))
                    {
                        break;
                    }
                }
                else if (IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(tokenTrailing))
                {
                    if (!SetIndentation(right))
                    {
                        break;
                    }
                }
                else if (leftTrailing.IsEmptyOrWhitespace() &&
                         tokenTrailing.IsEmptyOrWhitespace())
                {
                    if (AnalyzerOptions.AddNewLineAfterBinaryOperatorInsteadOfBeforeIt.IsEnabled(document, binaryExpression))
                    {
                        if (!SetIndentation(right))
                        {
                            break;
                        }
                    }
                    else if (!SetIndentation(token))
                    {
                        break;
                    }
                }

                if (!left.IsKind(binaryKind))
                {
                    break;
                }

                binaryExpression = (BinaryExpressionSyntax)left;
            }

            if (textChanges.Count > 0)
            {
                SyntaxTriviaList leading = binaryExpression.GetLeadingTrivia();

                if (!leading.Any())
                {
                    SyntaxTrivia trivia = binaryExpression.GetFirstToken().GetPreviousToken().TrailingTrivia.LastOrDefault();

                    if (trivia.IsEndOfLineTrivia() &&
                        trivia.Span.End == binaryExpression.SpanStart)
                    {
                        textChanges.Add(new TextSpan(binaryExpression.SpanStart, 0), indentation);
                    }
                }
            }

            FormattingVerifier.VerifyChangedSpansAreWhitespace(binaryExpression, textChanges);

            return(document.WithTextChangesAsync(textChanges, cancellationToken));

            bool SetIndentation(SyntaxNodeOrToken nodeOrToken)
            {
                SyntaxTriviaList leading = nodeOrToken.GetLeadingTrivia();

                SyntaxTriviaList.Reversed.Enumerator en = leading.Reverse().GetEnumerator();

                if (!en.MoveNext())
                {
                    SyntaxTrivia trivia = binaryExpression.FindTrivia(nodeOrToken.SpanStart - 1);

                    string newText = (trivia.IsEndOfLineTrivia()) ? indentation : endOfLineAndIndentation;

                    int start = (trivia.IsWhitespaceTrivia()) ? trivia.SpanStart : nodeOrToken.SpanStart;

                    TextSpan span = (trivia.IsWhitespaceTrivia())
                        ? trivia.Span
                        : new TextSpan(nodeOrToken.SpanStart, 0);

                    textChanges.Add(span, newText);
                    SetIndendation(nodeOrToken, prevIndex);
                    prevIndex = start;
                    return(true);
                }

                SyntaxTrivia last = en.Current;

                SyntaxKind kind = en.Current.Kind();

                if (kind == SyntaxKind.WhitespaceTrivia)
                {
                    if (en.Current.Span.Length != indentation.Length)
                    {
                        if (!en.MoveNext() ||
                            en.Current.IsEndOfLineTrivia())
                        {
                            SyntaxTrivia trivia = binaryExpression.FindTrivia(nodeOrToken.FullSpan.Start - 1);

                            if (trivia.IsEndOfLineTrivia())
                            {
                                AddTextChange((leading.IsEmptyOrWhitespace()) ? leading.Span : last.Span);
                                SetIndendation(nodeOrToken, prevIndex);
                                prevIndex = trivia.SpanStart;
                                return(true);
                            }
                        }
                    }
                }
                else if (kind == SyntaxKind.EndOfLineTrivia)
                {
                    SyntaxTrivia trivia = binaryExpression.FindTrivia(nodeOrToken.FullSpan.Start - 1);

                    if (trivia.IsEndOfLineTrivia())
                    {
                        AddTextChange((leading.IsEmptyOrWhitespace()) ? leading.Span : last.Span);
                        SetIndendation(nodeOrToken, prevIndex);
                        prevIndex = trivia.SpanStart;
                        return(true);
                    }
                }

                prevIndex = leading.Span.Start - 1;
                return(true);

                void AddTextChange(TextSpan span) => textChanges.Add(span, indentation);
            }

            void SetIndendation(SyntaxNodeOrToken nodeOrToken, int endIndex)
            {
                ImmutableArray <IndentationInfo> indentations = FindIndentations(
                    binaryExpression,
                    TextSpan.FromBounds(nodeOrToken.SpanStart, endIndex))
                                                                .ToImmutableArray();

                if (!indentations.Any())
                {
                    return;
                }

                int firstIndentationLength = indentations[0].Span.Length;

                for (int j = 0; j < indentations.Length; j++)
                {
                    IndentationInfo indentationInfo = indentations[j];

                    string replacement = indentation + indentationAnalysis.GetSingleIndentation();

                    if (j > 0 &&
                        indentationInfo.Span.Length > firstIndentationLength)
                    {
                        replacement += indentationInfo.ToString().Substring(firstIndentationLength);
                    }

                    if (indentationInfo.Span.Length != replacement.Length)
                    {
                        textChanges.Add(indentationInfo.Span, replacement);
                    }
                }
            }
        }
Ejemplo n.º 8
0
        public static Task <Document> FixCallChainAsync(
            Document document,
            ExpressionSyntax expression,
            TextSpan span,
            CancellationToken cancellationToken = default)
        {
            IndentationAnalysis indentationAnalysis = AnalyzeIndentation(expression, cancellationToken);
            string indentation             = indentationAnalysis.GetIncreasedIndentation();
            string endOfLineAndIndentation = DetermineEndOfLine(expression).ToString() + indentation;

            var textChanges = new List <TextChange>();
            int prevIndex   = expression.Span.End;

            foreach (SyntaxNode node in new MethodChain(expression))
            {
                SyntaxKind kind = node.Kind();

                if (kind == SyntaxKind.SimpleMemberAccessExpression)
                {
                    var memberAccess = (MemberAccessExpressionSyntax)node;

                    if (!SetIndentation(memberAccess.OperatorToken))
                    {
                        break;
                    }
                }
                else if (kind == SyntaxKind.MemberBindingExpression)
                {
                    var memberBinding = (MemberBindingExpressionSyntax)node;

                    if (!SetIndentation(memberBinding.OperatorToken))
                    {
                        break;
                    }
                }
            }

            FormattingVerifier.VerifyChangedSpansAreWhitespace(expression, textChanges);

            return(document.WithTextChangesAsync(textChanges, cancellationToken));

            bool SetIndentation(SyntaxToken token)
            {
                if (token.Span.End > span.End)
                {
                    return(true);
                }

                if (token.SpanStart < span.Start)
                {
                    return(false);
                }

                SyntaxTriviaList leading = token.LeadingTrivia;

                SyntaxTriviaList.Reversed.Enumerator en = leading.Reverse().GetEnumerator();

                if (!en.MoveNext())
                {
                    SyntaxTrivia trivia = expression.FindTrivia(token.SpanStart - 1);

                    string newText = (trivia.IsEndOfLineTrivia()) ? indentation : endOfLineAndIndentation;

                    textChanges.Add(new TextSpan(token.SpanStart, 0), newText);

                    SetIndendation(token, prevIndex);
                    prevIndex = (trivia.IsEndOfLineTrivia()) ? trivia.SpanStart : token.SpanStart;
                    return(true);
                }

                SyntaxTrivia last = en.Current;

                SyntaxKind kind = en.Current.Kind();

                if (kind == SyntaxKind.WhitespaceTrivia)
                {
                    if (en.Current.Span.Length != indentation.Length)
                    {
                        if (!en.MoveNext() ||
                            en.Current.IsEndOfLineTrivia())
                        {
                            SyntaxTrivia trivia = expression.FindTrivia(token.FullSpan.Start - 1);

                            if (trivia.IsEndOfLineTrivia())
                            {
                                textChanges.Add((leading.IsEmptyOrWhitespace()) ? leading.Span : last.Span, indentation);
                                SetIndendation(token, prevIndex);
                                prevIndex = trivia.SpanStart;
                                return(true);
                            }
                        }
                    }
                }
                else if (kind == SyntaxKind.EndOfLineTrivia)
                {
                    SyntaxTrivia trivia = expression.FindTrivia(token.FullSpan.Start - 1);

                    if (trivia.IsEndOfLineTrivia())
                    {
                        textChanges.Add((leading.IsEmptyOrWhitespace()) ? leading.Span : last.Span, indentation);
                        SetIndendation(token, prevIndex);
                        prevIndex = trivia.SpanStart;
                        return(true);
                    }
                }

                prevIndex = leading.Span.Start - 1;
                return(true);
            }

            void SetIndendation(SyntaxToken token, int endIndex)
            {
                ImmutableArray <IndentationInfo> indentations = FindIndentations(
                    expression,
                    TextSpan.FromBounds(token.SpanStart, endIndex))
                                                                .ToImmutableArray();

                if (!indentations.Any())
                {
                    return;
                }

                int firstIndentationLength = indentations[0].Span.Length;

                for (int j = 0; j < indentations.Length; j++)
                {
                    IndentationInfo indentationInfo = indentations[j];

                    string replacement = indentation + indentationAnalysis.GetSingleIndentation();

                    if (j > 0 &&
                        indentationInfo.Span.Length > firstIndentationLength)
                    {
                        replacement += indentationInfo.ToString().Substring(firstIndentationLength);
                    }

                    if (indentationInfo.Span.Length != replacement.Length)
                    {
                        textChanges.Add(indentationInfo.Span, replacement);
                    }
                }
            }
        }
Ejemplo n.º 9
0
        private static void AnalyzeExpression(SyntaxNodeAnalysisContext context)
        {
            var expression = (ExpressionSyntax)context.Node;

            if (expression.IsParentKind(
                    SyntaxKind.ConditionalAccessExpression,
                    SyntaxKind.SimpleMemberAccessExpression,
                    SyntaxKind.ElementAccessExpression,
                    SyntaxKind.MemberBindingExpression,
                    SyntaxKind.InvocationExpression))
            {
                return;
            }

            MethodChain.Enumerator en = new MethodChain(expression).GetEnumerator();

            if (!en.MoveNext())
            {
                return;
            }

            TextLineCollection lines = null;
            int startLine            = -1;
            IndentationAnalysis indentationAnalysis = default;

            do
            {
                context.CancellationToken.ThrowIfCancellationRequested();

                SyntaxKind kind = en.Current.Kind();

                if (kind == SyntaxKind.SimpleMemberAccessExpression)
                {
                    var memberAccess = (MemberAccessExpressionSyntax)en.Current;

                    if (AnalyzeToken(memberAccess.OperatorToken))
                    {
                        return;
                    }
                }
                else if (en.Current.Kind() == SyntaxKind.MemberBindingExpression)
                {
                    var memberBinding = (MemberBindingExpressionSyntax)en.Current;

                    if (AnalyzeToken(memberBinding.OperatorToken))
                    {
                        return;
                    }
                }
            } while (en.MoveNext());

            bool AnalyzeToken(SyntaxToken token)
            {
                SyntaxTriviaList.Reversed.Enumerator en = token.LeadingTrivia.Reverse().GetEnumerator();

                if (!en.MoveNext())
                {
                    if (lines == null)
                    {
                        lines     = expression.SyntaxTree.GetText().Lines;
                        startLine = lines.IndexOf(expression.SpanStart);
                    }

                    int endLine = lines.IndexOf(token.SpanStart);

                    if (startLine != endLine)
                    {
                        ReportDiagnostic();
                    }

                    return(true);
                }

                switch (en.Current.Kind())
                {
                case SyntaxKind.WhitespaceTrivia:
                {
                    if (indentationAnalysis.IsDefault)
                    {
                        indentationAnalysis = AnalyzeIndentation(expression);
                    }

                    if (en.Current.Span.Length != indentationAnalysis.IncreasedIndentationLength)
                    {
                        if (!en.MoveNext() ||
                            en.Current.IsEndOfLineTrivia())
                        {
                            if (expression.FindTrivia(token.FullSpan.Start - 1).IsEndOfLineTrivia())
                            {
                                ReportDiagnostic();
                                return(true);
                            }
                        }

                        break;
                    }

                    break;
                }

                case SyntaxKind.EndOfLineTrivia:
                {
                    if (expression.FindTrivia(token.FullSpan.Start - 1).IsEndOfLineTrivia())
                    {
                        ReportDiagnostic();
                        return(true);
                    }

                    break;
                }
                }

                return(false);
            }

            void ReportDiagnostic()
            {
                DiagnosticHelpers.ReportDiagnostic(
                    context,
                    DiagnosticDescriptors.FixFormattingOfCallChain,
                    expression);
            }
        }
        private static void AnalyzeBinaryExpression(SyntaxNodeAnalysisContext context)
        {
            var topBinaryExpression = (BinaryExpressionSyntax)context.Node;

            SyntaxKind binaryKind = topBinaryExpression.Kind();

            if (topBinaryExpression.IsParentKind(binaryKind))
            {
                return;
            }

            if (topBinaryExpression.IsSingleLine(includeExteriorTrivia: false))
            {
                return;
            }

            int?indentationLength = null;

            BinaryExpressionSyntax binaryExpression = topBinaryExpression;

            while (true)
            {
                context.CancellationToken.ThrowIfCancellationRequested();

                ExpressionSyntax left  = binaryExpression.Left;
                SyntaxToken      token = binaryExpression.OperatorToken;

                SyntaxTriviaList leftTrailing  = left.GetTrailingTrivia();
                SyntaxTriviaList tokenTrailing = token.TrailingTrivia;

                if (IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(leftTrailing))
                {
                    if (Analyze(token))
                    {
                        return;
                    }
                }
                else if (IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(tokenTrailing))
                {
                    if (Analyze(binaryExpression.Right))
                    {
                        return;
                    }
                }
                else if (leftTrailing.IsEmptyOrWhitespace() &&
                         tokenTrailing.IsEmptyOrWhitespace())
                {
                    ReportDiagnostic();
                    return;
                }

                if (!left.IsKind(binaryKind))
                {
                    break;
                }

                binaryExpression = (BinaryExpressionSyntax)left;
            }

            bool Analyze(SyntaxNodeOrToken nodeOrToken)
            {
                SyntaxTriviaList.Reversed.Enumerator en = nodeOrToken.GetLeadingTrivia().Reverse().GetEnumerator();

                if (!en.MoveNext())
                {
                    if ((indentationLength ??= GetIndentationLength()) == -1)
                    {
                        return(true);
                    }

                    ReportDiagnostic();
                    return(true);
                }

                switch (en.Current.Kind())
                {
                case SyntaxKind.WhitespaceTrivia:
                {
                    if ((indentationLength ??= GetIndentationLength()) == -1)
                    {
                        return(true);
                    }

                    if (en.Current.Span.Length != indentationLength)
                    {
                        if (!en.MoveNext() ||
                            en.Current.IsEndOfLineTrivia())
                        {
                            if (topBinaryExpression.FindTrivia(nodeOrToken.FullSpan.Start - 1).IsEndOfLineTrivia())
                            {
                                ReportDiagnostic();
                                return(true);
                            }
                        }

                        break;
                    }

                    break;
                }

                case SyntaxKind.EndOfLineTrivia:
                {
                    if (topBinaryExpression.FindTrivia(nodeOrToken.FullSpan.Start - 1).IsEndOfLineTrivia())
                    {
                        if ((indentationLength ??= GetIndentationLength()) == -1)
                        {
                            return(true);
                        }

                        ReportDiagnostic();
                        return(true);
                    }

                    break;
                }
                }

                return(false);
            }

            int GetIndentationLength()
            {
                IndentationAnalysis indentationAnalysis = AnalyzeIndentation(topBinaryExpression);

                if (indentationAnalysis.IndentSize == 0)
                {
                    return(-1);
                }

                SyntaxTriviaList leadingTrivia = topBinaryExpression.GetLeadingTrivia();

                if (leadingTrivia.Any() &&
                    leadingTrivia.Last() == indentationAnalysis.Indentation &&
                    context.GetConfigOptions().GetBinaryOperatorNewLinePosition() == NewLinePosition.After)
                {
                    return(indentationAnalysis.IndentationLength);
                }
                else
                {
                    return(indentationAnalysis.IncreasedIndentationLength);
                }
            }

            void ReportDiagnostic()
            {
                DiagnosticHelpers.ReportDiagnostic(
                    context,
                    DiagnosticRules.FixFormattingOfBinaryExpressionChain,
                    topBinaryExpression);
            }
        }
        private static void AnalyzeCompilationUnit(SyntaxNodeAnalysisContext context)
        {
            var compilationUnit = (CompilationUnitSyntax)context.Node;

            SyntaxToken endOfFile = compilationUnit.EndOfFileToken;

            SyntaxTriviaList.Reversed.Enumerator en = endOfFile.LeadingTrivia.Reverse().GetEnumerator();

            bool?preferNewLineAtEndOfFile = context.PreferNewLineAtEndOfFile();

            if (preferNewLineAtEndOfFile == null)
            {
                return;
            }

            if (preferNewLineAtEndOfFile == false)
            {
                if (en.MoveNext() &&
                    (!en.Current.IsWhitespaceTrivia() ||
                     en.MoveNext()))
                {
                    if (en.Current.IsEndOfLineTrivia())
                    {
                        ReportDiagnostic(context, endOfFile);
                    }
                    else if (SyntaxFacts.IsPreprocessorDirective(en.Current.Kind()) &&
                             en.Current.GetStructure() is DirectiveTriviaSyntax directiveTrivia &&
                             directiveTrivia.GetTrailingTrivia().LastOrDefault().IsEndOfLineTrivia())
                    {
                        ReportDiagnostic(context, endOfFile);
                    }
                }
                else
                {
                    SyntaxTriviaList trailing = endOfFile.GetPreviousToken().TrailingTrivia;

                    if (trailing.Any())
                    {
                        Debug.Assert(endOfFile.FullSpan.Start == trailing.Span.End);

                        if (endOfFile.FullSpan.Start == trailing.Span.End &&
                            trailing.LastOrDefault().IsEndOfLineTrivia())
                        {
                            ReportDiagnostic(context, endOfFile);
                        }
                    }
                }
            }
            else if (en.MoveNext())
            {
                if (CSharpFacts.IsCommentTrivia(en.Current.Kind()) ||
                    SyntaxFacts.IsPreprocessorDirective(en.Current.Kind()))
                {
                    ReportDiagnostic(context, endOfFile);
                }
                else if (en.Current.IsWhitespaceOrEndOfLineTrivia() &&
                         endOfFile.LeadingTrivia.Span.Start == 0)
                {
                    while (en.MoveNext())
                    {
                        if (!en.Current.IsWhitespaceOrEndOfLineTrivia())
                        {
                            return;
                        }
                    }

                    ReportDiagnostic(context, endOfFile);
                }
            }
            else if (endOfFile.SpanStart > 0)
            {
                SyntaxTriviaList trailing = endOfFile.GetPreviousToken().TrailingTrivia;

                if (!trailing.Any())
                {
                    ReportDiagnostic(context, endOfFile);
                }
                else
                {
                    Debug.Assert(endOfFile.FullSpan.Start == trailing.Span.End);

                    if (endOfFile.FullSpan.Start == trailing.Span.End &&
                        !trailing.Last().IsEndOfLineTrivia())
                    {
                        ReportDiagnostic(context, endOfFile);
                    }
                }
            }