private async Task<Document> FixSpacingAsync(Document document, IfStatementSyntax ifStatement, CancellationToken c)
        {
            // This method will generate a new if-statement node with a single space between the if-keyword and the opening parenthesis.
            var generator = SyntaxGenerator.GetGenerator(document);
        
            // The new if-statement will need to retain the same statements as the old if-statement.
            var ifBlock = ifStatement.Statement as BlockSyntax;
            var ifBlockStatements = ifBlock.Statements;

            // The new if-statement should retain the formatting of the trivia before and after the if-statement.
            // The following statements extract the original trivia.
            var ifKeyword = ifStatement.IfKeyword;
            var leadingTrivia = ifKeyword.LeadingTrivia;
            var closeBrace = ifBlock.CloseBraceToken;
            var trailingTrivia = closeBrace.TrailingTrivia;

            // If-statements generated using SyntaxGenerator are formatted with the desired spacing by default so this is not specified explicitly.
            var newIfStatement = generator.IfStatement(ifStatement.Condition, ifBlockStatements).WithLeadingTrivia(leadingTrivia).WithTrailingTrivia(trailingTrivia);

            // This statement gets the top of the syntax tree so that the old if-statement node can be replaced with the new one.
            var root = await document.GetSyntaxRootAsync();

            // A new root is created with the old if-statement replaced by the new one.
            var newRoot = root.ReplaceNode(ifStatement, newIfStatement);

            // A new document with the new root is returned.
            var newDocument = document.WithSyntaxRoot(newRoot);
            return newDocument;
    }
        static bool GetMatch(IfStatementSyntax node, out ExpressionSyntax c, out ReturnStatementSyntax e1, out ReturnStatementSyntax e2, out ReturnStatementSyntax rs)
        {
            rs = e1 = e2 = null;
            c = node.Condition;
            //attempt to match if(condition) return else return
            e1 = ConvertIfStatementToNullCoalescingExpressionAction.GetSimpleStatement(node.Statement) as ReturnStatementSyntax;
            if (e1 == null)
                return false;
            e2 = node.Else != null ? ConvertIfStatementToNullCoalescingExpressionAction.GetSimpleStatement(node.Else.Statement) as ReturnStatementSyntax : null;
            //match
            if (e1 != null && e2 != null)
            {
                return true;
            }

            //attempt to match if(condition) return
            if (e1 != null)
            {
                rs = node.Parent.ChildThatContainsPosition(node.GetTrailingTrivia().Max(t => t.FullSpan.End) + 1).AsNode() as ReturnStatementSyntax;
                if (rs != null)
                {
                    e2 = rs;
                    return true;
                }
            }
            return false;
        }
        static bool HasConflictingNames(SyntaxNodeAnalysisContext nodeContext, IfStatementSyntax ifElseStatement)
        {
            var block = ifElseStatement.Else.Statement as BlockSyntax;
            if (block == null || block.Statements.Count == 0)
                return false;

            var member = ifElseStatement.Ancestors().FirstOrDefault(a => a is MemberDeclarationSyntax);

            var priorLocalDeclarations = new List<string>();
            foreach (var localDecl in member.DescendantNodes().Where(n => n.SpanStart < ifElseStatement.Else.SpanStart).OfType<LocalDeclarationStatementSyntax>()) {
                foreach (var v in localDecl.Declaration.Variables)
                    priorLocalDeclarations.Add(v.Identifier.ValueText);
            }

            foreach (var sym in block.Statements)
            {
                var decl = sym as LocalDeclarationStatementSyntax;
                if (decl == null)
                    continue;
                
                if (priorLocalDeclarations.Contains(s => decl.Declaration.Variables.Any(v => v.Identifier.ValueText == s)))
                    return true;
            }
            return false;
        }
        static bool GetMatch(IfStatementSyntax node, out ExpressionSyntax c, out ReturnStatementSyntax e1, out ReturnStatementSyntax e2, out ReturnStatementSyntax rs)
        {
            rs = e1 = e2 = null;
            c = node.Condition;
            //attempt to match if(condition) return else return
            e1 = ConvertIfStatementToNullCoalescingExpressionAction.GetSimpleStatement(node.Statement) as ReturnStatementSyntax;
            if (e1 == null)
                return false;
            e2 = node.Else != null ? ConvertIfStatementToNullCoalescingExpressionAction.GetSimpleStatement(node.Else.Statement) as ReturnStatementSyntax : null;
            //match
            if (e1 != null && e2 != null)
            {
                return true;
            }

            //attempt to match if(condition) return; return
            if (e1 != null)
            {
                var parentBlock = node.Parent as BlockSyntax;
                if (parentBlock == null)
                    return false;
                var index = parentBlock.Statements.IndexOf(node);
                if (index + 1 < parentBlock.Statements.Count)
                {
                    rs = parentBlock.Statements[index + 1] as ReturnStatementSyntax;
                }

                if (rs != null)
                {
                    e2 = rs;
                    return true;
                }
            }
            return false;
        }
        public static IEnumerable<StatementSyntax> LopsidedTerminalBranchesToGuardedBranches(IfStatementSyntax syntax)
        {
            Contract.Requires(syntax != null);
            Contract.Requires(syntax.Parent is BlockSyntax);

            if (syntax.Statement.IsGuaranteedToJumpOut()) return new[] { syntax };
            if (syntax.Else != null && syntax.Else.Statement.IsGuaranteedToJumpOut()) return new[] { syntax };
            var allowedJump = syntax.TryGetEquivalentJumpAfterStatement();
            if (allowedJump == null) return new[] { syntax };

            var trueBloat = syntax.Statement.Bloat();
            var falseBloat = syntax.Else == null ? 0 : syntax.Else.Statement.Bloat();
            if (trueBloat < falseBloat * 2 - 10) {
                // inline the false branch, guard with the true branch
                return syntax.Else.Statement.Statements().Prepend(
                    syntax.WithStatement(syntax.Statement.BracedTo(syntax.Statement.Statements().Concat(new[] {allowedJump})))
                          .WithElse(null));
            }
            if (falseBloat < trueBloat * 2 - 10) {
                // inline the true branch, guard with the false branch
                return syntax.Statement.Statements().Prepend(
                    syntax.WithCondition(syntax.Condition.Inverted())
                          .WithStatement(syntax.Else == null ? allowedJump : syntax.Else.Statement.BracedTo(syntax.Else.Statement.Statements().Concat(new[] {allowedJump})))
                          .WithElse(null));
            }

            return new[] { syntax };
        }
 public BoundIfStatement(IfStatementSyntax syntax, BoundExpression condition, BoundStatement consequence, BoundStatement alternativeOpt)
     : base(BoundNodeKind.IfStatement, syntax)
 {
     Condition = condition;
     Consequence = consequence;
     AlternativeOpt = alternativeOpt;
 }
示例#7
0
        protected override SyntaxNode VisitIfStatement(IfStatementSyntax node)
        {
            if (!node.DescendentNodes().OfType<BlockSyntax>().Any())
            {
                node = node.Update (node.IfKeyword, node.OpenParenToken, node.Condition, node.CloseParenToken,
                                    Syntax.Block (statements: node.Statement), node.ElseOpt);
            }

            if (node.ElseOpt != null)
            {
                ElseClauseSyntax elseOpt = node.ElseOpt;
                IfStatementSyntax ifSyntax = elseOpt.Statement as IfStatementSyntax;
                if (ifSyntax != null)
                {
                    if (!ifSyntax.DescendentNodes().OfType<BlockSyntax>().Any())
                    {
                        ifSyntax = ifSyntax.Update (ifSyntax.IfKeyword, ifSyntax.OpenParenToken, ifSyntax.Condition, ifSyntax.CloseParenToken,
                                                    Syntax.Block (statements: ifSyntax.Statement), ifSyntax.ElseOpt);

                        elseOpt = elseOpt.Update (elseOpt.ElseKeyword, ifSyntax);
                    }
                }
                else if (!elseOpt.DescendentNodes().OfType<BlockSyntax>().Any())
                    elseOpt = node.ElseOpt.Update (node.ElseOpt.ElseKeyword, Syntax.Block (statements: node.ElseOpt.Statement));

                if (elseOpt != node.ElseOpt)
                    node = node.Update (node.IfKeyword, node.OpenParenToken, node.Condition, node.CloseParenToken, node.Statement, elseOpt);
            }

            return base.VisitIfStatement (node);
        }
        private static SyntaxNode CalculateNewRoot(SyntaxNode root, IfStatementSyntax ifStatement)
        {
            SyntaxNode newRoot;
            var isTrue = ifStatement.Condition.IsKind(SyntaxKind.TrueLiteralExpression);

            if (isTrue)
            {
                var block = ifStatement.Statement as BlockSyntax;
                newRoot = block == null
                    ? root.ReplaceNode(ifStatement, ifStatement.Statement)
                    : root.ReplaceNode(ifStatement, block.Statements);
            }
            else
            {
                if (ifStatement.Else == null)
                {
                    newRoot = root.RemoveNode(ifStatement, SyntaxRemoveOptions.KeepNoTrivia);
                }
                else
                {
                    var block = ifStatement.Else.Statement as BlockSyntax;
                    newRoot = block == null
                        ? root.ReplaceNode(ifStatement, ifStatement.Else.Statement)
                        : root.ReplaceNode(ifStatement, block.Statements);
                }
            }

            return newRoot.WithAdditionalAnnotations(Formatter.Annotation);
        }
示例#9
0
        public static IfStatementSyntax AddBraces(IfStatementSyntax ifStatement)
        {
            Debug.Assert(ifStatement != null && NeedsBraces(ifStatement));

            return ifStatement
                .WithStatement(SyntaxFactory.Block(ifStatement.Statement))
                .WithAdditionalAnnotations(Formatter.Annotation);
        }
示例#10
0
        private Document ConvertToConditional(Document document, SemanticModel semanticModel, IfStatementSyntax ifStatement, StatementSyntax replacementStatement, CancellationToken cancellationToken)
        {
            var oldRoot = semanticModel.SyntaxTree.GetRoot();
            var newRoot = oldRoot.ReplaceNode(
                oldNode: ifStatement,
                newNode: replacementStatement.WithAdditionalAnnotations(Formatter.Annotation));

            return document.WithSyntaxRoot(newRoot);
        }
        private void HandleIf(SyntaxNodeAnalysisContext context, IfStatementSyntax ifStatement)
        {
            if (ifStatement.Statement is BlockSyntax)
            {
                return;
            }

            context.ReportDiagnostic(Diagnostic.Create(Rule, ifStatement.IfKeyword.GetLocation()));
        }
示例#12
0
 public BoundIfStatement(
     BoundExpression boundExpression,
     BoundScopeStatement boundStatements,
     IfStatementSyntax statementSyntax)
     : base(statementSyntax)
 {
     BoundExpression = boundExpression;
     BoundStatements = boundStatements;
 }
示例#13
0
 private async Task<Document> AddBracesAsync(Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken)
 {
     var nonBlockedStatement = ifStatement.Statement as ExpressionStatementSyntax;
     var newBlockedStatement = SyntaxFactory.Block(statements: nonBlockedStatement).WithAdditionalAnnotations(annotations: Formatter.Annotation);
     var newIfStatement = ifStatement.ReplaceNode(oldNode: nonBlockedStatement, newNode: newBlockedStatement);
     var root = await document.GetSyntaxRootAsync();
     var newRoot = root.ReplaceNode(oldNode: ifStatement, newNode: newIfStatement);
     var newDocument = document.WithSyntaxRoot(newRoot);
     return newDocument;
 }
示例#14
0
 public static string IfStatement(IfStatementSyntax statement)
 {
     var output = statement.IfKeyword.Text + " (";
     output += SyntaxNode(statement.Condition);
     output += ")" + NewLine + SyntaxNode(statement.Statement);
     if (statement.Else != null)
     {
         output += SyntaxNode(statement.Else);
     }
     return output;
 }
        internal static bool ParseIfStatement(IfStatementSyntax node, out ExpressionSyntax condition, out ExpressionSyntax target, out AssignmentExpressionSyntax whenTrue, out AssignmentExpressionSyntax whenFalse)
        {
            condition = null;
            target = null;
            whenTrue = null;
            whenFalse = null;

            if (node == null || node.Else == null || node.Parent is IfStatementSyntax || node.Else.Statement is IfStatementSyntax)
                return false;

            condition = node.Condition;
            //make sure to check for multiple statements
            ExpressionStatementSyntax whenTrueExprStatement, whenFalseExprStatement;
            var embeddedBlock = node.Statement as BlockSyntax;
            if (embeddedBlock != null)
            {
                if (embeddedBlock.Statements.Count > 1)
                    return false;
                var childNodes = embeddedBlock.ChildNodes();
                if (childNodes.Count() > 1)
                    return false;
                whenTrueExprStatement = childNodes.OfType<ExpressionStatementSyntax>().FirstOrDefault();
            }
            else
            {
                whenTrueExprStatement = node.Statement as ExpressionStatementSyntax;
            }

            var elseBlock = node.Else.Statement as BlockSyntax;
            if (elseBlock != null)
            {
                if (elseBlock.Statements.Count > 1)
                    return false;
                var childNodes = elseBlock.ChildNodes();
                if (childNodes.Count() > 1)
                    return false;
                whenFalseExprStatement = childNodes.OfType<ExpressionStatementSyntax>().FirstOrDefault();
            }
            else
            {
                whenFalseExprStatement = node.Else.Statement as ExpressionStatementSyntax;
            }

            if (whenTrueExprStatement == null || whenFalseExprStatement == null)
                return false;

            whenTrue = whenTrueExprStatement.Expression as AssignmentExpressionSyntax;
            whenFalse = whenFalseExprStatement.Expression as AssignmentExpressionSyntax;
            if (whenTrue == null || whenFalse == null || whenTrue.Kind() != whenFalse.Kind() ||
                !SyntaxFactory.AreEquivalent(whenTrue.Left, whenFalse.Left))
                return false;

            return true;
        }
        static bool ElseIsRedundantControlFlow(IfStatementSyntax ifElseStatement, SyntaxNodeAnalysisContext syntaxNode)
        {
            if (ifElseStatement.Else == null || ifElseStatement.Parent is ElseClauseSyntax)
                return false;

            var blockSyntax = ifElseStatement.Else.Statement as BlockSyntax;
            if (blockSyntax != null && blockSyntax.Statements.Count == 0)
                return true;

            var result = syntaxNode.SemanticModel.AnalyzeControlFlow(ifElseStatement.Statement);
            return !result.EndPointIsReachable;
        }
 private static async Task<Document> UseExistenceOperatorAsyncWithReturnAsync(Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken, ReturnStatementSyntax returnIf)
 {
     var newMemberAccess = ((MemberAccessExpressionSyntax)returnIf.Expression).ToConditionalAccessExpression();
     var newReturn = SyntaxFactory.ReturnStatement(newMemberAccess)
         .WithLeadingTrivia(ifStatement.GetLeadingTrivia())
         .WithTrailingTrivia(ifStatement.GetTrailingTrivia())
         .WithAdditionalAnnotations(Formatter.Annotation);
     var root = await document.GetSyntaxRootAsync(cancellationToken);
     var newRoot = root.ReplaceNode(ifStatement, newReturn);
     var newDocument = document.WithSyntaxRoot(newRoot);
     return newDocument;
 }
 private static async Task<Document> UseExistenceOperatorAsyncWithAssignmentAsync(Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken, ExpressionStatementSyntax expressionIf)
 {
     var memberAccessAssignment = (AssignmentExpressionSyntax)expressionIf.Expression;
     var newMemberAccess = ((MemberAccessExpressionSyntax)memberAccessAssignment.Right).ToConditionalAccessExpression();
     var newExpressionStatement = SyntaxFactory.ExpressionStatement(SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, memberAccessAssignment.Left, newMemberAccess))
         .WithLeadingTrivia(ifStatement.GetLeadingTrivia())
         .WithTrailingTrivia(ifStatement.GetTrailingTrivia())
         .WithAdditionalAnnotations(Formatter.Annotation);
     var root = await document.GetSyntaxRootAsync(cancellationToken);
     var newRoot = root.ReplaceNode(ifStatement, newExpressionStatement);
     var newDocument = document.WithSyntaxRoot(newRoot);
     return newDocument;
 }
示例#19
0
        private BoundIfStatement BindIfStatement(IfStatementSyntax node)
        {
            Debug.Assert(node != null);

            var condition = BindBooleanExpression(node.Condition);
            var consequence = BindStatement(node.Statement);
            if (node.ElseOpt == null)
            {
                return new BoundIfStatement(node, condition, consequence, null);
            }
            var alternative = BindStatement(node.ElseOpt.Statement);
            return new BoundIfStatement(node, condition, consequence, alternative);
        }
 private static SyntaxNode MergeIfs(IfStatementSyntax ifStatement, SyntaxNode root)
 {
     var nestedIf = (IfStatementSyntax)ifStatement.Statement.GetSingleStatementFromPossibleBlock();
     var newIf = ifStatement
         .WithCondition(SyntaxFactory.BinaryExpression(SyntaxKind.LogicalAndExpression, ifStatement.Condition, nestedIf.Condition))
         .WithStatement(nestedIf.Statement)
         .WithLeadingTrivia(ifStatement.GetLeadingTrivia().AddRange(nestedIf.GetLeadingTrivia()))
         .WithAdditionalAnnotations(Formatter.Annotation);
     if (ifStatement.HasTrailingTrivia && nestedIf.HasTrailingTrivia && !ifStatement.GetTrailingTrivia().Equals(nestedIf.GetTrailingTrivia()))
         newIf = newIf.WithTrailingTrivia(ifStatement.GetTrailingTrivia().AddRange(nestedIf.GetTrailingTrivia()));
     var newRoot = root.ReplaceNode(ifStatement, newIf);
     return newRoot;
 }
        public static bool TryGetNewReturnStatement(IfStatementSyntax ifStatement, SemanticModel semanticModel, out ReturnStatementSyntax returnStatement)
        {
            returnStatement = null;

            var conditional = new ReturnConditionalAnalyzer(ifStatement, semanticModel).CreateConditional();
            if (conditional == null)
            {
                return false;
            }

            returnStatement = SyntaxFactory.ReturnStatement(conditional);

            return true;
        }
        private async Task<Document> MakeBlockAsync(Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken) {
            var nodes = new List<Tuple<SyntaxNode, SyntaxNode>>();
            StatementSyntax thenClause = ifStatement.Statement;
            if (thenClause != null && !(thenClause is BlockSyntax)) {
                nodes.Add(new Tuple<SyntaxNode, SyntaxNode>(thenClause, SyntaxFactory.Block(thenClause)));
            }

            StatementSyntax elseClause = ifStatement.Else?.Statement;
            if (elseClause != null) {
                if (elseClause is BlockSyntax == false && elseClause is IfStatementSyntax == false) {
                    nodes.Add(new Tuple<SyntaxNode, SyntaxNode>(elseClause, SyntaxFactory.Block(elseClause)));
                }
            }
            return await this.ReplaceNodesInDocumentAsync(document, cancellationToken, nodes.ToArray());
        }
        private static void CheckIf(SyntaxNodeAnalysisContext context, IfStatementSyntax ifStatement)
        {
            if (ifStatement.GetPrecedingIfsInConditionChain().Any())
            {
                return;
            }

            var lastStatementInIfChain = GetLastStatementInIfChain(ifStatement);
            if (IsStatementCandidateLoop(lastStatementInIfChain))
            {
                return;
            }

            CheckStatement(context, lastStatementInIfChain, "conditionally", "unconditionally");
        }
        private static IEnumerable<StatementSyntax> InlineLargeGuardedBranches2(IfStatementSyntax syntax)
        {
            Contract.Requires(syntax != null);

            var trueIsAGuard = syntax.Statement.IsGuaranteedToJumpOut();
            var falseIsAGuard = syntax.Else != null && syntax.Statement.IsGuaranteedToJumpOut();
            var preferTrue = trueIsAGuard;

            if (trueIsAGuard == falseIsAGuard && syntax.Else != null) {
                preferTrue = 2 * syntax.Statement.Bloat() >= syntax.Else.Bloat();
            }

            if (trueIsAGuard && preferTrue) return syntax.WithUnguardedElse();
            if (falseIsAGuard && !preferTrue) return syntax.Inverted().WithUnguardedElse();
            return new[] { syntax };
        }
        public override SyntaxNode VisitIfStatement(IfStatementSyntax node)
        {
            node = (IfStatementSyntax)base.VisitIfStatement(node);
            if (node.Statement.Kind == SyntaxKind.Block)
            {
                return node;
            }

            var block = Syntax.Block(statements: Syntax.List(node.Statement));
            return Syntax.IfStatement(
                node.IfKeyword,
                node.OpenParenToken,
                node.Condition,
                node.CloseParenToken,
                block,
                node.Else);
        }
        private async Task<Document> FixSpacingAsync(Document document, IfStatementSyntax ifStatement, CancellationToken c)
        {
            var generator = SyntaxGenerator.GetGenerator(document);

            var ifKeyword = ifStatement.IfKeyword;
            var ifBlock = ifStatement.Statement as BlockSyntax;
            var closeBrace = ifBlock.CloseBraceToken;
            var ifBlockStatements = ifBlock.Statements;
 
            var leadingTrivia = ifKeyword.LeadingTrivia;
            var trailingTrivia = closeBrace.TrailingTrivia;
            var newIfStatement = generator.IfStatement(ifStatement.Condition, ifBlockStatements).WithLeadingTrivia(leadingTrivia).WithTrailingTrivia(trailingTrivia);
      
            var root = await document.GetSyntaxRootAsync();
            var newRoot = root.ReplaceNode(ifStatement, newIfStatement);
            var newDocument = document.WithSyntaxRoot(newRoot);
            return newDocument;
        }
示例#27
0
        private static IfStatementSyntax GetParentIfStatement(IfStatementSyntax ifStatement)
        {
            var parent = ifStatement.Parent;

            while (parent is BlockSyntax)
            {
                var block = (BlockSyntax) parent;

                if (block.Statements.Count != 1)
                {
                    return null;
                }

                parent = parent.Parent;
            }

            var parentIfStatement = parent as IfStatementSyntax;
            return parentIfStatement;
        }
		public IEnumerable<string> Inspect(IfStatementSyntax ifElseStatement)
		{
			bool trueStatementIsReturnBoolLiteral =
				(ifElseStatement.Statement as ReturnStatementSyntax)
					.Call(r => r.Expression as LiteralExpressionSyntax)
					.Call(IsBoolLiteral, false);
			bool? falseStatementIsReturnBoolLiteral =
				ifElseStatement.Else
					.Call(e => e.Statement as ReturnStatementSyntax)
					.Call(r => r.Expression as LiteralExpressionSyntax)
					.Call(e => (bool?)IsBoolLiteral(e), null);

			var nextSibling = ifElseStatement.Parent.ChildNodes().SkipWhile(n => n != ifElseStatement).Skip(1).FirstOrDefault();
			falseStatementIsReturnBoolLiteral = falseStatementIsReturnBoolLiteral ??
								(nextSibling as ReturnStatementSyntax)
									.Call(r => r.Expression as LiteralExpressionSyntax)
									.Call(IsBoolLiteral, false);
			if (trueStatementIsReturnBoolLiteral && falseStatementIsReturnBoolLiteral == true)
				yield return Report(ifElseStatement, "Используйте return вместо if");
		}
        static ExpressionSyntax CheckNode(IfStatementSyntax node, out ExpressionSyntax rightSide)
        {
            rightSide = null;
            var condition = node.Condition as BinaryExpressionSyntax;
            if (condition == null || !(condition.IsKind(SyntaxKind.EqualsExpression) || condition.IsKind(SyntaxKind.NotEqualsExpression)))
                return null;
            var nullSide = condition.Right as LiteralExpressionSyntax;
            bool nullIsRight = true;
            if (nullSide == null || !nullSide.IsKind(SyntaxKind.NullLiteralExpression))
            {
                nullSide = condition.Left as LiteralExpressionSyntax;
                nullIsRight = false;
                if (nullSide == null || !nullSide.IsKind(SyntaxKind.NullLiteralExpression))
                    return null;
            }
            bool isEquality = condition.IsKind(SyntaxKind.EqualsExpression);
            StatementSyntax contentStatement;
            if (isEquality)
            {
                contentStatement = node.Statement;
                if (node.Else != null && !IsEmpty(node.Else.Statement))
                    return null;
            }
            else
            {
                contentStatement = node.Else != null ? node.Else.Statement : null;
                if (!IsEmpty(node.Statement))
                    return null;
            }

            contentStatement = GetSimpleStatement(contentStatement);
            if (contentStatement == null)
                return null;

            var assignExpr = (contentStatement as ExpressionStatementSyntax)?.Expression as AssignmentExpressionSyntax;
            if (assignExpr == null || !assignExpr.Left.IsEquivalentTo(nullIsRight ? condition.Left : condition.Right, true))
                return null;
            rightSide = assignExpr.Right;
            return nullIsRight ? condition.Left : condition.Right;
        }
        private static bool TrySearchForIfThenContinueStatement(ForEachStatementSyntax fe, out IfStatementSyntax ifStatement, out string ifType)
        {
            if (fe.Statement is BlockSyntax)
            {
                var block = ((BlockSyntax)fe.Statement);
                if ((block.Statements.Count > 1 && block.Statements.First() is IfStatementSyntax) ||
                    (block.Statements.Count > 0 && block.Statements.First() is IfStatementSyntax && ((IfStatementSyntax)block.Statements.First()).Else != null)                    )
                {
                    ifStatement = (block.Statements.FirstOrDefault() as IfStatementSyntax);
                    if (ifStatement?.Statement is ContinueStatementSyntax || 
                        ((ifStatement?.Statement as BlockSyntax)?.Statements)?.FirstOrDefault() is ContinueStatementSyntax)
                    {
                        ifType = IfWithContinueToWhere;
                        return true;
                    }
                }
            }

            ifStatement = null;
            ifType = null;
            return false;
        }
        public bool TryGetPatternPieces(
            BinaryExpressionSyntax isExpression,
            out IfStatementSyntax ifStatement,
            out LocalDeclarationStatementSyntax localDeclarationStatement,
            out VariableDeclaratorSyntax declarator,
            out CastExpressionSyntax castExpression)
        {
            ifStatement = null;
            localDeclarationStatement = null;
            declarator     = null;
            castExpression = null;

            // The is check has to be in an if check: "if (x is Type)
            if (!isExpression.Parent.IsKind(SyntaxKind.IfStatement))
            {
                return(false);
            }

            ifStatement = (IfStatementSyntax)isExpression.Parent;
            if (!ifStatement.Statement.IsKind(SyntaxKind.Block))
            {
                return(false);
            }

            var ifBlock = (BlockSyntax)ifStatement.Statement;

            if (ifBlock.Statements.Count == 0)
            {
                return(false);
            }

            var firstStatement = ifBlock.Statements[0];

            if (!firstStatement.IsKind(SyntaxKind.LocalDeclarationStatement))
            {
                return(false);
            }

            localDeclarationStatement = (LocalDeclarationStatementSyntax)firstStatement;
            if (localDeclarationStatement.Declaration.Variables.Count != 1)
            {
                return(false);
            }

            declarator = localDeclarationStatement.Declaration.Variables[0];
            if (declarator.Initializer == null)
            {
                return(false);
            }

            var declaratorValue = declarator.Initializer.Value.WalkDownParentheses();

            if (!declaratorValue.IsKind(SyntaxKind.CastExpression))
            {
                return(false);
            }

            castExpression = (CastExpressionSyntax)declaratorValue;
            if (!SyntaxFactory.AreEquivalent(isExpression.Left.WalkDownParentheses(), castExpression.Expression.WalkDownParentheses(), topLevel: false) ||
                !SyntaxFactory.AreEquivalent(isExpression.Right.WalkDownParentheses(), castExpression.Type, topLevel: false))
            {
                return(false);
            }

            return(true);
        }
 private static bool TryGetNotEqualsCondition(IfStatementSyntax ifStatement, out BinaryExpressionSyntax condition)
 {
     condition = ifStatement.Condition?.RemoveParentheses() as BinaryExpressionSyntax;
     return(condition != null &&
            condition.IsKind(SyntaxKind.NotEqualsExpression));
 }
 public override void VisitIfStatement(IfStatementSyntax node)
 {
     AddExpressionTerms(node.Condition, _expressions);
 }
示例#34
0
        public static BracesAnalysis AnalyzeBraces(IfStatementSyntax ifStatement)
        {
            bool anyHasEmbedded      = false;
            bool anyHasBlock         = false;
            bool allSupportsEmbedded = true;

            int cnt = 0;

            foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade())
            {
                cnt++;

                StatementSyntax statement = ifOrElse.Statement;

                if (!anyHasEmbedded &&
                    statement.Kind() != SyntaxKind.Block)
                {
                    anyHasEmbedded = true;
                }

                if (!anyHasBlock &&
                    statement.Kind() == SyntaxKind.Block)
                {
                    anyHasBlock = true;
                }

                if (allSupportsEmbedded &&
                    !SupportsEmbedded(statement))
                {
                    allSupportsEmbedded = false;
                }

                if (cnt > 1 &&
                    anyHasEmbedded &&
                    !allSupportsEmbedded)
                {
                    return(BracesAnalysisFlags.AddBraces);
                }
            }

            if (cnt > 1 &&
                allSupportsEmbedded &&
                anyHasBlock)
            {
                if (anyHasEmbedded)
                {
                    return(BracesAnalysisFlags.AddBraces | BracesAnalysisFlags.RemoveBraces);
                }
                else
                {
                    return(BracesAnalysisFlags.RemoveBraces);
                }
            }

            return(BracesAnalysisFlags.None);

            bool SupportsEmbedded(StatementSyntax statement)
            {
                if (statement.IsParentKind(SyntaxKind.IfStatement) &&
                    ((IfStatementSyntax)statement.Parent).Condition?.IsMultiLine() == true)
                {
                    return(false);
                }

                if (statement.Kind() == SyntaxKind.Block)
                {
                    var block = (BlockSyntax)statement;

                    statement = block.Statements.SingleOrDefault(shouldThrow: false);

                    if (statement == null)
                    {
                        return(false);
                    }
                }

                return(!statement.IsKind(SyntaxKind.LocalDeclarationStatement, SyntaxKind.LabeledStatement) &&
                       statement.IsSingleLine());
            }
        }
示例#35
0
 public override void VisitIfStatement(IfStatementSyntax node)
 {
     base.VisitIfStatement(node);
     _counter++;
 }
示例#36
0
 internal static void Analyze(SyntaxNodeAnalysisContext context, IfStatementSyntax ifStatement)
 {
     Analyze(context, ifStatement, ifStatement.CloseParenToken, ifStatement.Statement);
 }
示例#37
0
        internal static SyntaxToken GetFirstExcludedToken(StatementSyntax statement)
        {
            Debug.Assert(statement != null);
            switch (statement.Kind())
            {
            case SyntaxKind.Block:
                return(((BlockSyntax)statement).CloseBraceToken);

            case SyntaxKind.BreakStatement:
                return(((BreakStatementSyntax)statement).EosToken);

            case SyntaxKind.CheckedStatement:
            case SyntaxKind.UncheckedStatement:
                return(((CheckedStatementSyntax)statement).Block.CloseBraceToken);

            case SyntaxKind.ContinueStatement:
                return(((ContinueStatementSyntax)statement).EosToken);

            case SyntaxKind.LocalDeclarationStatement:
                return(((LocalDeclarationStatementSyntax)statement).EosToken);

            case SyntaxKind.DoStatement:
                return(((DoStatementSyntax)statement).EosToken);

            case SyntaxKind.EmptyStatement:
                return(((EmptyStatementSyntax)statement).EosToken);

            case SyntaxKind.ExpressionStatement:
                return(((ExpressionStatementSyntax)statement).EosToken);

            case SyntaxKind.FixedStatement:
                return(GetFirstExcludedToken(((FixedStatementSyntax)statement).Statement));

            case SyntaxKind.ForStatement:
                return(GetFirstExcludedToken(((ForStatementSyntax)statement).Statement));

            case SyntaxKind.GotoDefaultStatement:
            case SyntaxKind.GotoCaseStatement:
            case SyntaxKind.GotoStatement:
                return(((GotoStatementSyntax)statement).EosToken);

            case SyntaxKind.IfStatement:
                IfStatementSyntax ifStmt  = (IfStatementSyntax)statement;
                ElseClauseSyntax  elseOpt = ifStmt.Else;
                return(GetFirstExcludedToken(elseOpt == null ? ifStmt.Statement : elseOpt.Statement));

            case SyntaxKind.LabeledStatement:
                return(GetFirstExcludedToken(((LabeledStatementSyntax)statement).Statement));

            case SyntaxKind.LockStatement:
                return(GetFirstExcludedToken(((LockStatementSyntax)statement).Statement));

            case SyntaxKind.ReturnStatement:
                return(((ReturnStatementSyntax)statement).EosToken);

            case SyntaxKind.SwitchStatement:
                return(((SwitchStatementSyntax)statement).CloseBraceToken);

            case SyntaxKind.ThrowStatement:
                return(((ThrowStatementSyntax)statement).EosToken);

            case SyntaxKind.TryStatement:
                TryStatementSyntax tryStmt = (TryStatementSyntax)statement;

                FinallyClauseSyntax finallyClause = tryStmt.Finally;
                if (finallyClause != null)
                {
                    return(finallyClause.Block.CloseBraceToken);
                }

                CatchClauseSyntax lastCatch = tryStmt.Catches.LastOrDefault();
                if (lastCatch != null)
                {
                    return(lastCatch.Block.CloseBraceToken);
                }
                return(tryStmt.Block.CloseBraceToken);

            case SyntaxKind.UnsafeStatement:
                return(((UnsafeStatementSyntax)statement).Block.CloseBraceToken);

            case SyntaxKind.UsingStatement:
                return(GetFirstExcludedToken(((UsingStatementSyntax)statement).Statement));

            case SyntaxKind.WhileStatement:
                return(GetFirstExcludedToken(((WhileStatementSyntax)statement).Statement));

            case SyntaxKind.YieldReturnStatement:
            case SyntaxKind.YieldBreakStatement:
                return(((YieldStatementSyntax)statement).EosToken);

            case SyntaxKind.LocalFunctionStatement:
                LocalFunctionStatementSyntax localFunctionStmt = (LocalFunctionStatementSyntax)statement;
                if (localFunctionStmt.Body != null)
                {
                    return(GetFirstExcludedToken(localFunctionStmt.Body));
                }
                if (localFunctionStmt.EosToken != default(SyntaxToken))
                {
                    return(localFunctionStmt.EosToken);
                }
                return(localFunctionStmt.ParameterList.GetLastToken());

            default:
                throw ExceptionUtilities.UnexpectedValue(statement.Kind());
            }
        }
        private static async Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken)
        {
            ExpressionSyntax condition = ifStatement.Condition;

            ElseClauseSyntax elseClause = ifStatement.Else;

            if ((ifStatement.Statement as BlockSyntax)?.Statements.Any() == false)
            {
                SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                ExpressionSyntax newCondition = Negator.LogicallyNegate(condition, semanticModel, cancellationToken);

                StatementSyntax statement = elseClause.Statement;

                if (statement is IfStatementSyntax nestedIf)
                {
                    newCondition = LogicalAndExpression(newCondition.Parenthesize(), nestedIf.Condition.Parenthesize());

                    statement = nestedIf.Statement;
                }

                cancellationToken.ThrowIfCancellationRequested();

                IfStatementSyntax newNode = ifStatement.Update(
                    ifStatement.IfKeyword,
                    ifStatement.OpenParenToken,
                    newCondition,
                    ifStatement.CloseParenToken,
                    statement,
                    default(ElseClauseSyntax));

                newNode = newNode.WithFormatterAnnotation();

                return(await document.ReplaceNodeAsync(ifStatement, newNode, cancellationToken).ConfigureAwait(false));
            }
            else if (elseClause != null)
            {
                WhileStatementSyntax whileStatement;

                if (ifStatement.Parent is BlockSyntax block)
                {
                    whileStatement = (WhileStatementSyntax)block.Parent;
                }
                else
                {
                    block          = Block();
                    whileStatement = (WhileStatementSyntax)ifStatement.Parent;
                }

                cancellationToken.ThrowIfCancellationRequested();

                BlockSyntax newBlock = (ifStatement.Statement is BlockSyntax ifBlock)
                    ? block.WithStatements(ifBlock.Statements)
                    : block.WithStatements(SingletonList(ifStatement.Statement));

                SyntaxNode newNode = whileStatement.Update(
                    whileStatement.WhileKeyword,
                    whileStatement.OpenParenToken,
                    ifStatement.Condition,
                    whileStatement.CloseParenToken,
                    newBlock);

                newNode = newNode.WithFormatterAnnotation();

                return(await document.ReplaceNodeAsync(whileStatement, newNode, cancellationToken).ConfigureAwait(false));
            }
            else
            {
                var block = (BlockSyntax)ifStatement.Parent;

                SyntaxList <StatementSyntax> statements = block.Statements;

                BlockSyntax newBlock = block.WithStatements(statements.Remove(ifStatement));

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

                ExpressionSyntax newCondition = Negator.LogicallyNegate(condition, semanticModel, cancellationToken);

                SyntaxNode newNode = block.Parent;

                switch (block.Parent)
                {
                case WhileStatementSyntax whileStatement:
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    if (statements.IsFirst(ifStatement))
                    {
                        newNode = whileStatement.Update(
                            whileStatement.WhileKeyword,
                            whileStatement.OpenParenToken,
                            newCondition,
                            whileStatement.CloseParenToken,
                            newBlock);
                    }
                    else
                    {
                        newNode = DoStatement(
                            Token(whileStatement.WhileKeyword.LeadingTrivia, SyntaxKind.DoKeyword, whileStatement.CloseParenToken.TrailingTrivia),
                            newBlock.WithoutTrailingTrivia(),
                            WhileKeyword(),
                            OpenParenToken(),
                            newCondition,
                            CloseParenToken(),
                            SemicolonToken().WithTrailingTrivia(newBlock.GetTrailingTrivia()));
                    }

                    break;
                }

                case DoStatementSyntax doStatement:
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    if (statements.IsLast(ifStatement))
                    {
                        newNode = doStatement.Update(
                            doStatement.DoKeyword,
                            newBlock,
                            doStatement.WhileKeyword,
                            doStatement.OpenParenToken,
                            newCondition,
                            doStatement.CloseParenToken,
                            doStatement.SemicolonToken);
                    }
                    else
                    {
                        newNode = WhileStatement(
                            Token(doStatement.DoKeyword.LeadingTrivia, SyntaxKind.WhileKeyword, SyntaxTriviaList.Empty),
                            OpenParenToken(),
                            newCondition,
                            Token(SyntaxTriviaList.Empty, SyntaxKind.CloseParenToken, doStatement.DoKeyword.TrailingTrivia),
                            newBlock.WithTrailingTrivia(doStatement.GetTrailingTrivia()));
                    }

                    break;
                }

                default:
                {
                    Debug.Fail(block.Parent.Kind().ToString());
                    break;
                }
                }

                newNode = newNode.WithFormatterAnnotation();

                return(await document.ReplaceNodeAsync(block.Parent, newNode, cancellationToken).ConfigureAwait(false));
            }
        }
 private static bool IsPartOfLazyInitialization(IfStatementSyntax ifStatement, SyntaxList <StatementSyntax> statements)
 {
     return(statements.Count == 2 &&
            statements.IndexOf(ifStatement) == 0 &&
            statements[1].IsKind(SyntaxKind.ReturnStatement));
 }
 private static Task <Document> RefactorAsync(
     Document document,
     StatementSyntax statement,
     IfStatementSyntax ifStatement,
     int statementIndex,
     in StatementListInfo statementsInfo,
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, IfStatementSyntax ifStatement)
        {
            SyntaxToken ifKeyword = ifStatement.IfKeyword;

            bool isTopmostIf = ifStatement.IsTopmostIf();

            if (context.Span.IsEmptyAndContainedInSpan(ifKeyword) ||
                context.Span.IsBetweenSpans(ifStatement))
            {
                if (isTopmostIf &&
                    context.IsAnyRefactoringEnabled(
                        RefactoringIdentifiers.UseCoalesceExpressionInsteadOfIf,
                        RefactoringIdentifiers.UseConditionalExpressionInsteadOfIf,
                        RefactoringIdentifiers.SimplifyIf))
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    IfAnalysisOptions options = GetIfAnalysisOptions(context);

                    foreach (IfAnalysis analysis in IfAnalysis.Analyze(ifStatement, options, semanticModel, context.CancellationToken))
                    {
                        string refactoringId = GetRefactoringIdentifier(analysis);

                        if (context.IsRefactoringEnabled(refactoringId))
                        {
                            context.RegisterRefactoring(
                                analysis.Title,
                                ct => IfRefactoring.RefactorAsync(context.Document, analysis, ct),
                                refactoringId);
                        }
                    }
                }

                if (context.IsAnyRefactoringEnabled(RefactoringIdentifiers.InvertIf, RefactoringIdentifiers.InvertIfElse) &&
                    isTopmostIf &&
                    context.Span.IsEmptyAndContainedInSpan(ifKeyword))
                {
                    InvertIfRefactoring.ComputeRefactoring(context, ifStatement);
                }

                if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceIfWithSwitch) &&
                    isTopmostIf)
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    ReplaceIfWithSwitchRefactoring.ComputeRefactoring(context, ifStatement, semanticModel);
                }

                if (context.IsRefactoringEnabled(RefactoringIdentifiers.SplitIfStatement))
                {
                    SplitIfStatementRefactoring.ComputeRefactoring(context, ifStatement);
                }

                if (context.IsRefactoringEnabled(RefactoringIdentifiers.MergeIfWithParentIf) &&
                    isTopmostIf &&
                    context.Span.IsEmptyAndContainedInSpan(ifKeyword))
                {
                    MergeIfWithParentIfRefactoring.ComputeRefactoring(context, ifStatement);
                }
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.InvertIf) &&
                context.Span.IsEmptyAndContainedInSpan(ifKeyword))
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                ReduceIfNestingAnalysisResult analysis = ReduceIfNestingAnalysis.Analyze(
                    ifStatement,
                    semanticModel,
                    options: ReduceIfNestingOptions.AllowNestedFix
                    | ReduceIfNestingOptions.AllowIfInsideIfElse
                    | ReduceIfNestingOptions.AllowLoop
                    | ReduceIfNestingOptions.AllowSwitchSection,
                    cancellationToken: context.CancellationToken);

                if (analysis.Success)
                {
                    context.RegisterRefactoring(
                        "Invert if",
                        ct => ReduceIfNestingRefactoring.RefactorAsync(context.Document, ifStatement, analysis.JumpKind, false, ct),
                        RefactoringIdentifiers.InvertIf);

                    if (ReduceIfNestingAnalysis.IsFixableRecursively(ifStatement, analysis.JumpKind))
                    {
                        context.RegisterRefactoring(
                            "Invert if (recursively)",
                            ct => ReduceIfNestingRefactoring.RefactorAsync(context.Document, ifStatement, analysis.JumpKind, true, ct),
                            EquivalenceKey.Join(RefactoringIdentifiers.InvertIf, "Recursive"));
                    }
                }
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.SplitIfElse) &&
                context.Span.IsEmptyAndContainedInSpan(ifKeyword))
            {
                SplitIfElseRefactoring.ComputeRefactoring(context, ifStatement);
            }
        }
 private static IfStatementSyntax GetNewIfStatement(IfStatementSyntax ifStatement, IfStatementSyntax ifStatement2)
 {
     if (ifStatement.Statement.IsKind(SyntaxKind.Block))
     {
         if (ifStatement2.Statement.IsKind(SyntaxKind.Block))
         {
             return(ifStatement.ReplaceNode(ifStatement2, ((BlockSyntax)ifStatement2.Statement).Statements));
         }
         else
         {
             return(ifStatement.ReplaceNode(ifStatement2, ifStatement2.Statement));
         }
     }
     else
     {
         return(ifStatement.ReplaceNode(ifStatement.Statement, ifStatement2.Statement));
     }
 }
        private async Task <Document> UseExistenceOperatorAsyncWithAssignment(Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken, ExpressionStatementSyntax expressionIf, ExpressionStatementSyntax expressionElse)
        {
            var memberAccessAssignment = (AssignmentExpressionSyntax)expressionIf.Expression;
            var newMemberAccess        = ((MemberAccessExpressionSyntax)memberAccessAssignment.Right).ToConditionalAccessExpression();
            var newExpressionStatement = SyntaxFactory.ExpressionStatement(SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, memberAccessAssignment.Left, newMemberAccess))
                                         .WithLeadingTrivia(ifStatement.GetLeadingTrivia())
                                         .WithTrailingTrivia(ifStatement.GetTrailingTrivia())
                                         .WithAdditionalAnnotations(Formatter.Annotation);
            var root = await document.GetSyntaxRootAsync();

            var newRoot     = root.ReplaceNode <SyntaxNode, StatementSyntax>(ifStatement, newExpressionStatement);
            var newDocument = document.WithSyntaxRoot(newRoot);

            return(newDocument);
        }
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindNode(root, context.Span, out ExpressionSyntax expression))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.CannotImplicitlyConvertTypeExplicitConversionExists:
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    TypeInfo typeInfo = semanticModel.GetTypeInfo(expression, context.CancellationToken);

                    ITypeSymbol type          = typeInfo.Type;
                    ITypeSymbol convertedType = typeInfo.ConvertedType;

                    if ((type is INamedTypeSymbol namedType) &&
                        namedType.IsNullableType())
                    {
                        if (convertedType?.SpecialType == SpecialType.System_Boolean ||
                            AddComparisonWithBooleanLiteralRefactoring.IsCondition(expression))
                        {
                            if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddComparisonWithBooleanLiteral))
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    AddComparisonWithBooleanLiteralRefactoring.GetTitle(expression),
                                    cancellationToken => AddComparisonWithBooleanLiteralRefactoring.RefactorAsync(context.Document, expression, cancellationToken),
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.AddComparisonWithBooleanLiteral));

                                context.RegisterCodeFix(codeAction, diagnostic);
                            }
                        }
                        else if (namedType.TypeArguments[0].Equals(convertedType))
                        {
                            if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.UseCoalesceExpression))
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    "Use coalesce expression",
                                    cancellationToken =>
                                    {
                                        ExpressionSyntax defaultValue = convertedType.GetDefaultValueSyntax(context.Document.GetDefaultSyntaxOptions());

                                        ExpressionSyntax newNode = CoalesceExpression(expression.WithoutTrivia(), defaultValue)
                                                                   .WithTriviaFrom(expression)
                                                                   .Parenthesize()
                                                                   .WithFormatterAnnotation();

                                        return(context.Document.ReplaceNodeAsync(expression, newNode, cancellationToken));
                                    },
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.UseCoalesceExpression));

                                context.RegisterCodeFix(codeAction, diagnostic);
                            }
                        }
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeMemberTypeAccordingToReturnExpression) &&
                        expression.IsParentKind(SyntaxKind.ReturnStatement, SyntaxKind.YieldReturnStatement))
                    {
                        ChangeMemberTypeRefactoring.ComputeCodeFix(context, diagnostic, expression, semanticModel);
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddCastExpression))
                    {
                        CodeFixRegistrator.AddCastExpression(context, diagnostic, expression, convertedType, semanticModel);
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeTypeAccordingToInitializer))
                    {
                        ChangeTypeAccordingToInitializerRefactoring.ComputeCodeFix(context, diagnostic, expression, semanticModel);
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.CreateSingletonArray) &&
                        type?.IsErrorType() == false &&
                        !type.Equals(convertedType) &&
                        (convertedType is IArrayTypeSymbol arrayType) &&
                        semanticModel.IsImplicitConversion(expression, arrayType.ElementType))
                    {
                        CodeAction codeAction = CodeAction.Create(
                            "Create singleton array",
                            cancellationToken => CreateSingletonArrayRefactoring.RefactorAsync(context.Document, expression, arrayType.ElementType, semanticModel, cancellationToken),
                            GetEquivalenceKey(diagnostic, CodeFixIdentifiers.CreateSingletonArray));

                        context.RegisterCodeFix(codeAction, diagnostic);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.ConstantValueCannotBeConverted:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.UseUncheckedExpression))
                    {
                        break;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Use 'unchecked'",
                        cancellationToken =>
                        {
                            CheckedExpressionSyntax newNode = CSharpFactory.UncheckedExpression(expression.WithoutTrivia());

                            newNode = newNode.WithTriviaFrom(expression);

                            return(context.Document.ReplaceNodeAsync(expression, newNode, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case CompilerDiagnosticIdentifiers.ExpressionBeingAssignedMustBeConstant:
                {
                    SyntaxNode parent = expression.Parent;

                    if (parent?.IsKind(SyntaxKind.EqualsValueClause) != true)
                    {
                        break;
                    }

                    parent = parent.Parent;

                    if (parent?.IsKind(SyntaxKind.VariableDeclarator) != true)
                    {
                        break;
                    }

                    parent = parent.Parent;

                    if (!(parent is VariableDeclarationSyntax variableDeclaration))
                    {
                        break;
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveConstModifier) &&
                        variableDeclaration.Parent is LocalDeclarationStatementSyntax localDeclarationStatement)
                    {
                        SyntaxTokenList modifiers = localDeclarationStatement.Modifiers;

                        if (!modifiers.Contains(SyntaxKind.ConstKeyword))
                        {
                            break;
                        }

                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, localDeclarationStatement, SyntaxKind.ConstKeyword);
                    }
                    else if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceConstantWithField) &&
                             variableDeclaration.Variables.Count == 1 &&
                             (variableDeclaration.Parent is FieldDeclarationSyntax fieldDeclaration) &&
                             fieldDeclaration.Modifiers.Contains(SyntaxKind.ConstKeyword))
                    {
                        CodeAction codeAction = CodeAction.Create(
                            ReplaceConstantWithFieldRefactoring.Title,
                            cancellationToken => ReplaceConstantWithFieldRefactoring.RefactorAsync(context.Document, fieldDeclaration, cancellationToken),
                            GetEquivalenceKey(diagnostic));

                        context.RegisterCodeFix(codeAction, diagnostic);
                        break;
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CannotConvertNullToTypeBecauseItIsNonNullableValueType:
                case CompilerDiagnosticIdentifiers.CannotConvertNullToTypeParameterBecauseItCouldBeNonNullableValueType:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue))
                    {
                        break;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    CodeFixRegistrator.ReplaceNullWithDefaultValue(context, diagnostic, expression, semanticModel);
                    break;
                }

                case CompilerDiagnosticIdentifiers.ResultOfExpressionIsAlwaysConstantSinceValueIsNeverEqualToNull:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveConditionThatIsAlwaysEqualToTrueOrFalse))
                    {
                        break;
                    }

                    NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(expression, allowedStyles: NullCheckStyles.ComparisonToNull);

                    if (!nullCheck.Success)
                    {
                        break;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Remove condition",
                        cancellationToken =>
                        {
                            cancellationToken.ThrowIfCancellationRequested();

                            SyntaxNode newRoot = RemoveCondition(root, expression, nullCheck.Style == NullCheckStyles.NotEqualsToNull);

                            cancellationToken.ThrowIfCancellationRequested();

                            return(Task.FromResult(context.Document.WithSyntaxRoot(newRoot)));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);

                    break;
                }

                case CompilerDiagnosticIdentifiers.OnlyAssignmentCallIncrementDecrementAndNewObjectExpressionsCanBeUsedAsStatement:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveParentheses) &&
                        expression is ParenthesizedExpressionSyntax parenthesizedExpression &&
                        parenthesizedExpression?.IsMissing == false)
                    {
                        CodeAction codeAction = CodeAction.Create(
                            "Remove parentheses",
                            cancellationToken => RemoveRedundantParenthesesRefactoring.RefactorAsync(context.Document, parenthesizedExpression, cancellationToken),
                            GetEquivalenceKey(diagnostic));

                        context.RegisterCodeFix(codeAction, diagnostic);
                        break;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    if (expression.Parent is ArrowExpressionClauseSyntax arrowExpresssionClause)
                    {
                        if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeMemberTypeAccordingToReturnExpression))
                        {
                            break;
                        }

                        ChangeMemberTypeRefactoring.ComputeCodeFix(context, diagnostic, expression, semanticModel);
                    }
                    else if (expression.Parent is ExpressionStatementSyntax expressionStatement)
                    {
                        if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddArgumentList) &&
                            expression.IsKind(
                                SyntaxKind.IdentifierName,
                                SyntaxKind.SimpleMemberAccessExpression))
                        {
                            SyntaxNode invocationExpression = InvocationExpression(expression);

                            if (semanticModel.GetSpeculativeMethodSymbol(expression.SpanStart, invocationExpression) != null)
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    "Add argument list",
                                    cancellationToken => context.Document.ReplaceNodeAsync(expression, invocationExpression, cancellationToken),
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.AddArgumentList));

                                context.RegisterCodeFix(codeAction, diagnostic);
                            }
                        }

                        if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceComparisonWithAssignment) &&
                            expression.IsKind(SyntaxKind.EqualsExpression))
                        {
                            BinaryExpressionInfo info = SyntaxInfo.BinaryExpressionInfo(expression);

                            if (!info.Success)
                            {
                                break;
                            }

                            ITypeSymbol leftTypeSymbol = semanticModel.GetTypeSymbol(info.Left, context.CancellationToken);

                            if (leftTypeSymbol?.IsErrorType() != false)
                            {
                                break;
                            }

                            if (!semanticModel.IsImplicitConversion(info.Right, leftTypeSymbol))
                            {
                                break;
                            }

                            CodeAction codeAction = CodeAction.Create(
                                "Replace comparison with assignment",
                                cancellationToken =>
                                {
                                    AssignmentExpressionSyntax simpleAssignment = SimpleAssignmentExpression(info.Left, info.Right).WithTriviaFrom(expression);
                                    return(context.Document.ReplaceNodeAsync(expression, simpleAssignment, cancellationToken));
                                },
                                GetEquivalenceKey(diagnostic, CodeFixIdentifiers.ReplaceComparisonWithAssignment));

                            context.RegisterCodeFix(codeAction, diagnostic);
                        }

                        if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceConditionalExpressionWithIfElse) &&
                            (expression is ConditionalExpressionSyntax conditionalExpression) &&
                            conditionalExpression.Condition != null)
                        {
                            ExpressionSyntax whenTrue  = conditionalExpression.WhenTrue;
                            ExpressionSyntax whenFalse = conditionalExpression.WhenFalse;

                            if (whenTrue != null &&
                                whenFalse != null &&
                                semanticModel.GetTypeSymbol(whenTrue, context.CancellationToken)?.SpecialType == SpecialType.System_Void &&
                                semanticModel.GetTypeSymbol(whenFalse, context.CancellationToken)?.SpecialType == SpecialType.System_Void)
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    "Replace ?: with if-else",
                                    cancellationToken =>
                                    {
                                        IfStatementSyntax newNode = IfStatement(
                                            conditionalExpression.Condition.WalkDownParentheses(),
                                            Block(ExpressionStatement(whenTrue)),
                                            ElseClause(Block(ExpressionStatement(whenFalse))));

                                        newNode = newNode
                                                  .WithTriviaFrom(expressionStatement)
                                                  .WithFormatterAnnotation();

                                        return(context.Document.ReplaceNodeAsync(expressionStatement, newNode, cancellationToken));
                                    },
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.ReplaceConditionalExpressionWithIfElse));

                                context.RegisterCodeFix(codeAction, diagnostic);
                            }
                        }

                        if (semanticModel.GetSymbol(expression, context.CancellationToken)?.IsErrorType() != false)
                        {
                            break;
                        }

                        ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression, context.CancellationToken);

                        if (typeSymbol?.IsErrorType() != false)
                        {
                            break;
                        }

                        if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.IntroduceLocalVariable) &&
                            !expressionStatement.IsEmbedded())
                        {
                            bool addAwait = typeSymbol.OriginalDefinition.EqualsOrInheritsFromTaskOfT() &&
                                            semanticModel.GetEnclosingSymbol(expressionStatement.SpanStart, context.CancellationToken).IsAsyncMethod();

                            CodeAction codeAction = CodeAction.Create(
                                IntroduceLocalVariableRefactoring.GetTitle(expression),
                                cancellationToken => IntroduceLocalVariableRefactoring.RefactorAsync(context.Document, expressionStatement, typeSymbol, addAwait, semanticModel, cancellationToken),
                                GetEquivalenceKey(diagnostic, CodeFixIdentifiers.IntroduceLocalVariable));

                            context.RegisterCodeFix(codeAction, diagnostic);
                        }

                        if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.IntroduceField))
                        {
                            CodeAction codeAction = CodeAction.Create(
                                $"Introduce field for '{expression}'",
                                cancellationToken => IntroduceFieldRefactoring.RefactorAsync(context.Document, expressionStatement, typeSymbol, semanticModel, cancellationToken),
                                GetEquivalenceKey(diagnostic, CodeFixIdentifiers.IntroduceField));

                            context.RegisterCodeFix(codeAction, diagnostic);
                        }
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CannotImplicitlyConvertType:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceYieldReturnWithForEach) &&
                        expression.IsParentKind(SyntaxKind.YieldReturnStatement))
                    {
                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        ReplaceYieldReturnWithForEachRefactoring.ComputeCodeFix(context, diagnostic, expression, semanticModel);
                        break;
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeMemberTypeAccordingToReturnExpression) &&
                        expression.IsParentKind(SyntaxKind.ReturnStatement, SyntaxKind.YieldReturnStatement))
                    {
                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        ChangeMemberTypeRefactoring.ComputeCodeFix(context, diagnostic, expression, semanticModel);
                        break;
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeTypeAccordingToInitializer))
                    {
                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        CodeFixRegistrationResult result = ChangeTypeAccordingToInitializerRefactoring.ComputeCodeFix(context, diagnostic, expression, semanticModel);

                        if (!result.Success)
                        {
                            RemoveAssignmentOfVoidExpression(context, diagnostic, expression, semanticModel);
                        }

                        break;
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceStringLiteralWithCharacterLiteral) &&
                        expression?.Kind() == SyntaxKind.StringLiteralExpression)
                    {
                        var literalExpression = (LiteralExpressionSyntax)expression;

                        if (literalExpression.Token.ValueText.Length == 1)
                        {
                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            if (semanticModel.GetTypeInfo(expression, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Char)
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    "Replace string literal with character literal",
                                    cancellationToken => ReplaceStringLiteralWithCharacterLiteralRefactoring.RefactorAsync(context.Document, literalExpression, cancellationToken),
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.ReplaceStringLiteralWithCharacterLiteral));

                                context.RegisterCodeFix(codeAction, diagnostic);
                            }
                        }
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.UseYieldReturnInsteadOfReturn) &&
                        expression.IsParentKind(SyntaxKind.ReturnStatement))
                    {
                        var returnStatement = (ReturnStatementSyntax)expression.Parent;

                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        ISymbol containingSymbol = semanticModel.GetEnclosingSymbol(returnStatement.SpanStart, context.CancellationToken);

                        if (containingSymbol?.Kind == SymbolKind.Method &&
                            ((IMethodSymbol)containingSymbol).ReturnType.OriginalDefinition.IsIEnumerableOrIEnumerableOfT())
                        {
                            CodeAction codeAction = CodeAction.Create(
                                "Use yield return instead of return",
                                cancellationToken => UseYieldReturnInsteadOfReturnRefactoring.RefactorAsync(context.Document, returnStatement, SyntaxKind.YieldReturnStatement, semanticModel, cancellationToken),
                                GetEquivalenceKey(diagnostic, CodeFixIdentifiers.UseYieldReturnInsteadOfReturn));

                            context.RegisterCodeFix(codeAction, diagnostic);
                        }
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.LeftHandSideOfAssignmentMustBeVariablePropertyOrIndexer:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveConstModifier))
                    {
                        return;
                    }

                    if (!expression.IsKind(SyntaxKind.IdentifierName))
                    {
                        return;
                    }

                    if (!expression.IsParentKind(SyntaxKind.SimpleAssignmentExpression))
                    {
                        return;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    SymbolInfo symbolInfo = semanticModel.GetSymbolInfo(expression, context.CancellationToken);

                    if (symbolInfo.CandidateReason != CandidateReason.NotAVariable)
                    {
                        return;
                    }

                    if (!(symbolInfo.CandidateSymbols.SingleOrDefault(shouldThrow: false) is ILocalSymbol localSymbol))
                    {
                        return;
                    }

                    if (!localSymbol.IsConst)
                    {
                        return;
                    }

                    SyntaxNode node = localSymbol.GetSyntaxOrDefault(context.CancellationToken);

                    if (!node.IsKind(SyntaxKind.VariableDeclarator))
                    {
                        return;
                    }

                    node = node.Parent;

                    if (!node.IsKind(SyntaxKind.VariableDeclaration))
                    {
                        return;
                    }

                    node = node.Parent;

                    if (!(node is LocalDeclarationStatementSyntax localDeclaration))
                    {
                        return;
                    }

                    SyntaxToken constModifier = localDeclaration.Modifiers.Find(SyntaxKind.ConstKeyword);

                    if (!constModifier.IsKind(SyntaxKind.ConstKeyword))
                    {
                        return;
                    }

                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, localDeclaration, constModifier);

                    break;
                }

                case CompilerDiagnosticIdentifiers.ReadOnlyFieldCannotBeAssignedTo:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.MakeFieldWritable))
                    {
                        break;
                    }

                    SimpleAssignmentExpressionInfo simpleAssignment = SyntaxInfo.SimpleAssignmentExpressionInfo(expression.Parent);

                    if (!simpleAssignment.Success)
                    {
                        return;
                    }

                    if (simpleAssignment.Left != expression)
                    {
                        return;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    SymbolInfo symbolInfo = semanticModel.GetSymbolInfo(expression, context.CancellationToken);

                    if (symbolInfo.CandidateReason != CandidateReason.NotAVariable)
                    {
                        return;
                    }

                    if (!(symbolInfo.CandidateSymbols.SingleOrDefault(shouldThrow: false) is IFieldSymbol fieldSymbol))
                    {
                        return;
                    }

                    if (fieldSymbol.DeclaredAccessibility != Accessibility.Private)
                    {
                        return;
                    }

                    if (!(fieldSymbol.GetSyntax().Parent.Parent is FieldDeclarationSyntax fieldDeclaration))
                    {
                        return;
                    }

                    TypeDeclarationSyntax containingTypeDeclaration = fieldDeclaration.FirstAncestor <TypeDeclarationSyntax>();

                    if (!expression.Ancestors().Any(f => f == containingTypeDeclaration))
                    {
                        return;
                    }

                    ModifiersCodeFixRegistrator.RemoveModifier(
                        context,
                        diagnostic,
                        fieldDeclaration,
                        SyntaxKind.ReadOnlyKeyword,
                        title: $"Make '{fieldSymbol.Name}' writable");

                    break;
                }
                }
            }
        }
 public override void VisitIfStatement(IfStatementSyntax node)
 => CheckToken(node.IfKeyword);
示例#46
0
 public override void VisitIfStatement(IfStatementSyntax node)
 {
     VisitPossibleEmbeddedStatement(node.Statement, enclosing);
     Visit(node.Else, enclosing);
 }
示例#47
0
 public override void VisitIfStatement(IfStatementSyntax node)
 {
     return;
 }
示例#48
0
 private static bool IsElseIfWithoutElse(IfStatementSyntax node)
 {
     return(node.Parent.IsKind(SyntaxKind.ElseClause) &&
            node.Else == null);
 }
示例#49
0
 public override void VisitIfStatement(IfStatementSyntax node)
 {
     AddLocation(node.IfKeyword);
     base.VisitIfStatement(node);
 }
        private bool TryCheckVariableAndIfStatementForm(
            SyntaxNodeAnalysisContext syntaxContext,
            IfStatementSyntax ifStatement,
            BinaryExpressionSyntax condition,
            ExpressionStatementSyntax expressionStatement,
            InvocationExpressionSyntax invocationExpression,
            ReportDiagnostic severity)
        {
            var cancellationToken = syntaxContext.CancellationToken;

            cancellationToken.ThrowIfCancellationRequested();

            // look for the form "if (a != null)" or "if (null != a)"
            if (!ifStatement.Parent.IsKind(SyntaxKind.Block))
            {
                return(false);
            }

            if (!IsNullCheckExpression(condition.Left, condition.Right) &&
                !IsNullCheckExpression(condition.Right, condition.Left))
            {
                return(false);
            }

            var expression = invocationExpression.Expression;

            if (!expression.IsKind(SyntaxKind.IdentifierName))
            {
                return(false);
            }

            var conditionName = condition.Left is IdentifierNameSyntax
                ? (IdentifierNameSyntax)condition.Left
                : (IdentifierNameSyntax)condition.Right;

            var invocationName = (IdentifierNameSyntax)expression;

            if (!Equals(conditionName.Identifier.ValueText, invocationName.Identifier.ValueText))
            {
                return(false);
            }

            // Now make sure the previous statement is "var a = ..."
            var parentBlock = (BlockSyntax)ifStatement.Parent;
            var ifIndex     = parentBlock.Statements.IndexOf(ifStatement);

            if (ifIndex == 0)
            {
                return(false);
            }

            var previousStatement = parentBlock.Statements[ifIndex - 1];

            if (!previousStatement.IsKind(SyntaxKind.LocalDeclarationStatement))
            {
                return(false);
            }

            var localDeclarationStatement = (LocalDeclarationStatementSyntax)previousStatement;
            var variableDeclaration       = localDeclarationStatement.Declaration;

            var declarator = variableDeclaration;

            if (declarator.Initializer == null)
            {
                return(false);
            }

            cancellationToken.ThrowIfCancellationRequested();
            if (!Equals(declarator.Identifier.ValueText, conditionName.Identifier.ValueText))
            {
                return(false);
            }

            // Syntactically this looks good.  Now make sure that the local is a delegate type.
            var semanticModel = syntaxContext.SemanticModel;
            var localSymbol   = (ILocalSymbol)semanticModel.GetDeclaredSymbol(declarator, cancellationToken);

            // Ok, we made a local just to check it for null and invoke it.  Looks like something
            // we can suggest an improvement for!
            // But first make sure we're only using the local only within the body of this if statement.
            var analysis = semanticModel.AnalyzeDataFlow(localDeclarationStatement, ifStatement);

            if (analysis.ReadOutside.Contains(localSymbol) || analysis.WrittenOutside.Contains(localSymbol))
            {
                return(false);
            }

            // Looks good!
            var tree = semanticModel.SyntaxTree;
            var additionalLocations = new List <Location>
            {
                Location.Create(tree, localDeclarationStatement.Span),
                Location.Create(tree, ifStatement.Span),
                Location.Create(tree, expressionStatement.Span)
            };

            ReportDiagnostics(syntaxContext,
                              localDeclarationStatement, ifStatement, expressionStatement,
                              severity, additionalLocations, Constants.VariableAndIfStatementForm);

            return(true);
        }
示例#51
0
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, IfStatementSyntax ifStatement)
        {
            if (ifStatement.IsTopmostIf() &&
                (context.Span.IsEmptyAndContainedInSpan(ifStatement.IfKeyword) || context.Span.IsBetweenSpans(ifStatement)))
            {
                if (context.IsAnyRefactoringEnabled(
                        RefactoringIdentifiers.UseCoalesceExpressionInsteadOfIf,
                        RefactoringIdentifiers.UseConditionalExpressionInsteadOfIf,
                        RefactoringIdentifiers.SimplifyIf))
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    var options = new IfAnalysisOptions(
                        useCoalesceExpression: context.IsRefactoringEnabled(RefactoringIdentifiers.UseCoalesceExpressionInsteadOfIf),
                        useConditionalExpression: context.IsRefactoringEnabled(RefactoringIdentifiers.UseConditionalExpressionInsteadOfIf),
                        useBooleanExpression: context.IsRefactoringEnabled(RefactoringIdentifiers.SimplifyIf),
                        useExpression: false);

                    foreach (IfAnalysis analysis in IfAnalysis.Analyze(ifStatement, options, semanticModel, context.CancellationToken))
                    {
                        context.RegisterRefactoring(
                            analysis.Title,
                            cancellationToken => IfRefactoring.RefactorAsync(context.Document, analysis, cancellationToken));
                    }
                }

                if (context.IsRefactoringEnabled(RefactoringIdentifiers.SwapIfElse))
                {
                    SwapIfElseRefactoring.ComputeRefactoring(context, ifStatement);
                }

                if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceIfWithSwitch))
                {
                    await ReplaceIfWithSwitchRefactoring.ComputeRefactoringAsync(context, ifStatement).ConfigureAwait(false);
                }

                if (context.IsRefactoringEnabled(RefactoringIdentifiers.SplitIfStatement))
                {
                    SplitIfStatementRefactoring.ComputeRefactoring(context, ifStatement);
                }

                if (context.IsRefactoringEnabled(RefactoringIdentifiers.MergeIfWithParentIf) &&
                    context.Span.IsEmptyAndContainedInSpan(ifStatement.IfKeyword))
                {
                    MergeIfWithParentIfRefactoring.ComputeRefactoring(context, ifStatement);
                }
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReduceIfNesting) &&
                context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(ifStatement.IfKeyword))
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                ReduceIfNestingAnalysisResult analysis = ReduceIfNestingAnalysis.Analyze(
                    ifStatement,
                    semanticModel,
                    options: ReduceIfNestingOptions.AllowNestedFix
                    | ReduceIfNestingOptions.AllowIfInsideIfElse
                    | ReduceIfNestingOptions.AllowLoop
                    | ReduceIfNestingOptions.AllowSwitchSection,
                    taskSymbol: semanticModel.GetTypeByMetadataName(MetadataNames.System_Threading_Tasks_Task),
                    cancellationToken: context.CancellationToken);

                if (analysis.Success)
                {
                    context.RegisterRefactoring(
                        "Reduce if nesting",
                        cancellationToken => ReduceIfNestingRefactoring.RefactorAsync(context.Document, ifStatement, analysis.JumpKind, false, cancellationToken));

                    if (ReduceIfNestingAnalysis.IsFixableRecursively(ifStatement, analysis.JumpKind))
                    {
                        context.RegisterRefactoring(
                            "Reduce if nesting (recursively)",
                            cancellationToken => ReduceIfNestingRefactoring.RefactorAsync(context.Document, ifStatement, analysis.JumpKind, true, cancellationToken));
                    }
                }
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.SplitIfElse) &&
                context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(ifStatement.IfKeyword))
            {
                SplitIfElseRefactoring.ComputeRefactoring(context, ifStatement);
            }
        }
示例#52
0
 internal Enumerator(IfStatementSyntax ifStatement)
 {
     _ifOrElse = ifStatement;
     _count    = -1;
 }
 public IfReturnToReturnWithBooleanExpression(
     IfStatementSyntax ifStatement,
     ExpressionSyntax expression1,
     ExpressionSyntax expression2) : base(ifStatement, expression1, expression2)
 {
 }
示例#54
0
 internal IfStatementCascade(IfStatementSyntax ifStatement)
 {
     IfStatement = ifStatement;
 }
 public IfReturnToReturnWithConditionalExpression(
     IfStatementSyntax ifStatement,
     ExpressionSyntax expression1,
     ExpressionSyntax expression2) : base(ifStatement, expression1, expression2)
 {
 }
示例#56
0
 internal EnumeratorImpl(IfStatementSyntax ifStatement)
 {
     _en = new Enumerator(ifStatement);
 }
        private static void ReportDiagnostic(SyntaxNodeAnalysisContext context, IfStatementSyntax ifStatement, IfStatementSyntax nestedIf)
        {
            context.ReportDiagnostic(DiagnosticDescriptors.MergeIfStatementWithNestedIfStatement, ifStatement);

            context.ReportToken(DiagnosticDescriptors.MergeIfStatementWithNestedIfStatementFadeOut, nestedIf.IfKeyword);
            context.ReportToken(DiagnosticDescriptors.MergeIfStatementWithNestedIfStatementFadeOut, nestedIf.OpenParenToken);
            context.ReportToken(DiagnosticDescriptors.MergeIfStatementWithNestedIfStatementFadeOut, nestedIf.CloseParenToken);

            if (ifStatement.Statement.IsKind(SyntaxKind.Block) &&
                nestedIf.Statement.IsKind(SyntaxKind.Block))
            {
                context.ReportBraces(DiagnosticDescriptors.MergeIfStatementWithNestedIfStatementFadeOut, (BlockSyntax)nestedIf.Statement);
            }
        }
示例#58
0
 public IfReturnToReturnWithCoalesceExpression(
     IfStatementSyntax ifStatement,
     ExpressionSyntax left,
     ExpressionSyntax right) : base(ifStatement, left, right)
 {
 }
示例#59
0
 /// <inheritdoc />
 public override void VisitIfStatement(IfStatementSyntax node)
 {
     this.ifStatements.Add(node);
     base.VisitIfStatement(node);
 }
        private async Task <Document> UseExistenceOperatorAsyncWithReturn(Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken, ReturnStatementSyntax returnIf, ReturnStatementSyntax returnElse)
        {
            var newMemberAccess = ((MemberAccessExpressionSyntax)returnIf.Expression).ToConditionalAccessExpression();
            var newReturn       = SyntaxFactory.ReturnStatement(newMemberAccess)
                                  .WithLeadingTrivia(ifStatement.GetLeadingTrivia())
                                  .WithTrailingTrivia(ifStatement.GetTrailingTrivia())
                                  .WithAdditionalAnnotations(Formatter.Annotation);
            var root = await document.GetSyntaxRootAsync();

            var newRoot     = root.ReplaceNode <SyntaxNode, StatementSyntax>(ifStatement, newReturn);
            var newDocument = document.WithSyntaxRoot(newRoot);

            return(newDocument);
        }