Example #1
0
        private static void Write(
            ExpressionSyntax expression,
            ExpressionSyntax nextExpression,
            SyntaxToken token,
            string newText,
            SyntaxNodeTextBuilder builder)
        {
            if (FormatConditionalExpressionAnalyzer.IsFixable(expression, token))
            {
                if (!expression.GetTrailingTrivia().IsEmptyOrWhitespace() ||
                    !token.LeadingTrivia.IsEmptyOrWhitespace())
                {
                    builder.AppendTrailingTrivia(expression);
                    builder.AppendLeadingTrivia(token);
                }

                builder.AppendTrailingTrivia(token);
                builder.AppendLeadingTrivia(nextExpression);
                builder.Append(newText);
                builder.AppendSpan(nextExpression);
            }
            else
            {
                builder.AppendTrailingTrivia(expression);
                builder.AppendFullSpan(token);
                builder.AppendLeadingTriviaAndSpan(nextExpression);
            }
        }
Example #2
0
        public static Task <Document> RefactorAsync(
            Document document,
            ConditionalExpressionSyntax conditionalExpression,
            CancellationToken cancellationToken)
        {
            ExpressionSyntax condition     = conditionalExpression.Condition;
            ExpressionSyntax whenTrue      = conditionalExpression.WhenTrue;
            ExpressionSyntax whenFalse     = conditionalExpression.WhenFalse;
            SyntaxToken      questionToken = conditionalExpression.QuestionToken;
            SyntaxToken      colonToken    = conditionalExpression.ColonToken;

            StringBuilder sb = StringBuilderCache.GetInstance();

            var builder = new SyntaxNodeTextBuilder(conditionalExpression, sb);

            builder.AppendLeadingTrivia();
            builder.AppendSpan(condition);

            Write(condition, whenTrue, questionToken, "? ", builder);

            Write(whenTrue, whenFalse, colonToken, ": ", builder);

            builder.AppendTrailingTrivia();

            ExpressionSyntax newNode = SyntaxFactory.ParseExpression(StringBuilderCache.GetStringAndFree(sb));

            return(document.ReplaceNodeAsync(conditionalExpression, newNode, cancellationToken));
        }
        private static void Write(
            ExpressionSyntax expression,
            ExpressionSyntax nextExpression,
            SyntaxToken token,
            string newText,
            SyntaxNodeTextBuilder builder)
        {
            if (IsFixable(expression, token))
            {
                if (expression.GetTrailingTrivia().Any(f => !f.IsWhitespaceOrEndOfLineTrivia()) ||
                    token.LeadingTrivia.Any(f => !f.IsWhitespaceOrEndOfLineTrivia()))
                {
                    builder.AppendTrailingTrivia(expression);
                    builder.AppendLeadingTrivia(token);
                }

                builder.AppendTrailingTrivia(token);
                builder.AppendLeadingTrivia(nextExpression);
                builder.Append(newText);
                builder.AppendSpan(nextExpression);
            }
            else
            {
                builder.AppendTrailingTrivia(expression);
                builder.AppendFullSpan(token);
                builder.AppendLeadingTriviaAndSpan(nextExpression);
            }
        }
        private static Task <Document> RefactorAsync(
            Document document,
            InterpolatedStringExpressionSyntax interpolatedString,
            CancellationToken cancellationToken)
        {
            StringBuilder sb = StringBuilderCache.GetInstance();

            var b = new SyntaxNodeTextBuilder(interpolatedString, sb);

            var arguments = new List <ArgumentSyntax>()
            {
                null
            };

            if (interpolatedString.IsVerbatim())
            {
                b.Append("@");
            }

            b.Append("\"");

            int index = 0;

            foreach (InterpolatedStringContentSyntax content in interpolatedString.Contents)
            {
                switch (content.Kind())
                {
                case SyntaxKind.Interpolation:
                {
                    var interpolation = (InterpolationSyntax)content;

                    b.Append("{");
                    b.Append(index.ToString(CultureInfo.InvariantCulture));
                    index++;

                    InterpolationAlignmentClauseSyntax alignmentClause = interpolation.AlignmentClause;
                    if (alignmentClause != null)
                    {
                        b.Append(",");
                        b.AppendSpan(alignmentClause.Value);
                    }

                    InterpolationFormatClauseSyntax formatClause = interpolation.FormatClause;
                    if (formatClause != null)
                    {
                        b.Append(":");
                        b.AppendSpan(formatClause.FormatStringToken);
                    }

                    b.Append("}");

                    arguments.Add(Argument(interpolation.Expression));
                    break;
                }

                case SyntaxKind.InterpolatedStringText:
                {
                    b.AppendSpan(content);
                    break;
                }
                }
            }

            b.Append("\"");

            arguments[0] = Argument(ParseExpression(StringBuilderCache.GetStringAndFree(sb)));

            InvocationExpressionSyntax invocation = SimpleMemberInvocationExpression(
                CSharpTypeFactory.StringType(),
                IdentifierName("Format"),
                ArgumentList(SeparatedList(arguments)));

            invocation = invocation.WithTriviaFrom(interpolatedString).WithFormatterAnnotation();

            return(document.ReplaceNodeAsync(interpolatedString, invocation, cancellationToken));
        }
Example #5
0
        public static async Task <Document> RefactorAsync(
            Document document,
            BinaryExpressionSyntax logicalAnd,
            CancellationToken cancellationToken)
        {
            ExpressionSyntax left  = logicalAnd.Left;
            ExpressionSyntax right = logicalAnd.Right.WalkDownParentheses();

            if (logicalAnd.Left.IsKind(SyntaxKind.LogicalAndExpression))
            {
                left = ((BinaryExpressionSyntax)logicalAnd.Left).Right;
            }

            NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(left, allowedStyles: NullCheckStyles.NotEqualsToNull);

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            ExpressionSyntax expression = nullCheck.Expression;

            bool isNullable = semanticModel.GetTypeSymbol(expression, cancellationToken).IsNullableType();

            ExpressionSyntax expression2 = UseConditionalAccessAnalyzer.FindExpressionThatCanBeConditionallyAccessed(
                expression,
                right,
                isNullable: isNullable);

            var builder = new SyntaxNodeTextBuilder(logicalAnd, StringBuilderCache.GetInstance(logicalAnd.FullSpan.Length));

            builder.Append(TextSpan.FromBounds(logicalAnd.FullSpan.Start, left.Span.Start));
            builder.AppendSpan(expression);
            builder.Append("?");
            builder.Append(TextSpan.FromBounds(expression2.Span.End, right.Span.End));

            switch (right.Kind())
            {
            case SyntaxKind.LogicalOrExpression:
            case SyntaxKind.LogicalAndExpression:
            case SyntaxKind.BitwiseOrExpression:
            case SyntaxKind.BitwiseAndExpression:
            case SyntaxKind.ExclusiveOrExpression:
            case SyntaxKind.EqualsExpression:
            case SyntaxKind.NotEqualsExpression:
            case SyntaxKind.LessThanExpression:
            case SyntaxKind.LessThanOrEqualExpression:
            case SyntaxKind.GreaterThanExpression:
            case SyntaxKind.GreaterThanOrEqualExpression:
            case SyntaxKind.IsExpression:
            case SyntaxKind.AsExpression:
            case SyntaxKind.IsPatternExpression:
            {
                break;
            }

            case SyntaxKind.LogicalNotExpression:
            {
                builder.Append(" == false");
                break;
            }

            default:
            {
                builder.Append(" == true");
                break;
            }
            }

            builder.AppendTrailingTrivia();

            string text = StringBuilderCache.GetStringAndFree(builder.StringBuilder);

            ParenthesizedExpressionSyntax newNode = SyntaxFactory.ParseExpression(text)
                                                    .WithFormatterAnnotation()
                                                    .Parenthesize();

            return(await document.ReplaceNodeAsync(logicalAnd, newNode, cancellationToken).ConfigureAwait(false));
        }
        public static async Task <Document> RefactorAsync(
            Document document,
            BinaryExpressionSyntax binaryExpression,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            SyntaxKind kind = binaryExpression.Kind();

            (ExpressionSyntax left, ExpressionSyntax right) = UseConditionalAccessAnalyzer.GetFixableExpressions(binaryExpression, kind, semanticModel, cancellationToken);

            NullCheckStyles allowedStyles = (kind == SyntaxKind.LogicalAndExpression)
                ? NullCheckStyles.NotEqualsToNull
                : NullCheckStyles.EqualsToNull;

            NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(left, allowedStyles: allowedStyles);

            ExpressionSyntax expression = nullCheck.Expression;

            bool isNullable = semanticModel.GetTypeSymbol(expression, cancellationToken).IsNullableType();

            ExpressionSyntax expression2 = UseConditionalAccessAnalyzer.FindExpressionThatCanBeConditionallyAccessed(
                expression,
                right,
                isNullable: isNullable,
                semanticModel,
                cancellationToken);

            var builder = new SyntaxNodeTextBuilder(binaryExpression, StringBuilderCache.GetInstance(binaryExpression.FullSpan.Length));

            builder.Append(TextSpan.FromBounds(binaryExpression.FullSpan.Start, left.SpanStart));

            int parenDiff = GetParenTokenDiff();

            if (parenDiff > 0)
            {
                builder.Append('(', parenDiff);
            }

            builder.AppendSpan(expression);
            builder.Append("?");
            builder.Append(TextSpan.FromBounds(expression2.Span.End, right.Span.End));

            switch (right.Kind())
            {
            case SyntaxKind.LogicalOrExpression:
            case SyntaxKind.LogicalAndExpression:
            case SyntaxKind.BitwiseOrExpression:
            case SyntaxKind.BitwiseAndExpression:
            case SyntaxKind.ExclusiveOrExpression:
            case SyntaxKind.EqualsExpression:
            case SyntaxKind.NotEqualsExpression:
            case SyntaxKind.LessThanExpression:
            case SyntaxKind.LessThanOrEqualExpression:
            case SyntaxKind.GreaterThanExpression:
            case SyntaxKind.GreaterThanOrEqualExpression:
            case SyntaxKind.IsExpression:
            case SyntaxKind.AsExpression:
            case SyntaxKind.IsPatternExpression:
            {
                break;
            }

            case SyntaxKind.LogicalNotExpression:
            {
                builder.Append((kind == SyntaxKind.LogicalAndExpression) ? " == false" : " != true");
                break;
            }

            default:
            {
                builder.Append((kind == SyntaxKind.LogicalAndExpression) ? " == true" : " != false");
                break;
            }
            }

            if (parenDiff < 0)
            {
                builder.Append(')', -parenDiff);
            }

            builder.Append(TextSpan.FromBounds(right.Span.End, binaryExpression.FullSpan.End));

            string text = StringBuilderCache.GetStringAndFree(builder.StringBuilder);

            ParenthesizedExpressionSyntax newNode = SyntaxFactory.ParseExpression(text)
                                                    .WithFormatterAnnotation()
                                                    .Parenthesize();

            return(await document.ReplaceNodeAsync(binaryExpression, newNode, cancellationToken).ConfigureAwait(false));

            int GetParenTokenDiff()
            {
                int count = 0;

                foreach (SyntaxToken token in binaryExpression.DescendantTokens(TextSpan.FromBounds(left.SpanStart, expression2.Span.End)))
                {
                    SyntaxKind tokenKind = token.Kind();

                    if (tokenKind == SyntaxKind.OpenParenToken)
                    {
                        if (token.IsParentKind(SyntaxKind.ParenthesizedExpression))
                        {
                            count++;
                        }
                    }
                    else if (tokenKind == SyntaxKind.CloseParenToken)
                    {
                        if (token.IsParentKind(SyntaxKind.ParenthesizedExpression))
                        {
                            count--;
                        }
                    }
                }

                return(count);
            }
        }