private static ImmutableArray <IfRefactoring> Analyze( ExpressionStatementSyntax expressionStatement, IfStatementSyntax ifStatement, IfAnalysisOptions options) { SimpleAssignmentStatement assignment; if (SimpleAssignmentStatement.TryCreate(expressionStatement, out assignment)) { ElseClauseSyntax elseClause = ifStatement.Else; if (elseClause?.Statement?.IsKind(SyntaxKind.IfStatement) == false) { SimpleAssignmentStatement assignment1; if (SimpleAssignmentStatement.TryCreate(ifStatement.GetSingleStatementOrDefault(), out assignment1)) { SimpleAssignmentStatement assignment2; if (SimpleAssignmentStatement.TryCreate(elseClause.GetSingleStatementOrDefault(), out assignment2) && assignment1.Left.IsEquivalentTo(assignment2.Left, topLevel: false) && assignment1.Left.IsEquivalentTo(assignment.Left, topLevel: false) && options.CheckSpanDirectives(ifStatement.Parent, TextSpan.FromBounds(expressionStatement.SpanStart, ifStatement.Span.End))) { return(new AssignmentAndIfElseToAssignmentWithConditionalExpression(expressionStatement, assignment.Right, ifStatement, assignment1.Right, assignment2.Right).ToImmutableArray()); } } } } return(ImmutableArray <IfRefactoring> .Empty); }
private static ImmutableArray <IfRefactoring> Analyze( IfStatementSyntax ifStatement, ReturnStatementSyntax returnStatement, IfAnalysisOptions options, SemanticModel semanticModel, CancellationToken cancellationToken) { ExpressionSyntax condition = ifStatement.Condition; if (condition?.IsMissing == false) { StatementSyntax statement = ifStatement.GetSingleStatementOrDefault(); if (statement?.IsKind(SyntaxKind.ReturnStatement) == true && options.CheckSpanDirectives(ifStatement, TextSpan.FromBounds(ifStatement.SpanStart, returnStatement.Span.End))) { return(Analyze( ifStatement, condition, ((ReturnStatementSyntax)statement).Expression, returnStatement.Expression, semanticModel, cancellationToken, options, isYield: false)); } } return(ImmutableArray <IfRefactoring> .Empty); }
private static ImmutableArray<IfRefactoring> Analyze( IfStatementSyntax ifStatement, ReturnStatementSyntax returnStatement, IfAnalysisOptions options, SemanticModel semanticModel, CancellationToken cancellationToken) { ExpressionSyntax condition = ifStatement.Condition?.WalkDownParentheses(); if (condition?.IsMissing != false) return Empty; StatementSyntax statement = ifStatement.GetSingleStatementOrDefault(); if (statement?.IsKind(SyntaxKind.ReturnStatement) != true) return Empty; if (!options.CheckSpanDirectives(ifStatement, TextSpan.FromBounds(ifStatement.SpanStart, returnStatement.Span.End))) return Empty; return Analyze( ifStatement, condition, ((ReturnStatementSyntax)statement).Expression?.WalkDownParentheses(), returnStatement.Expression?.WalkDownParentheses(), semanticModel, cancellationToken, options, isYield: false); }
public static Task <Document> RefactorAsync( Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken) { var statement = (ExpressionStatementSyntax)ifStatement.GetSingleStatementOrDefault(); MemberInvocationStatementInfo invocationInfo = SyntaxInfo.MemberInvocationStatementInfo(statement); int insertIndex = invocationInfo.Expression.Span.End - statement.FullSpan.Start; StatementSyntax newStatement = SyntaxFactory.ParseStatement(statement.ToFullString().Insert(insertIndex, "?")); IEnumerable <SyntaxTrivia> leading = ifStatement.DescendantTrivia(TextSpan.FromBounds(ifStatement.SpanStart, statement.SpanStart)); newStatement = (leading.All(f => f.IsWhitespaceOrEndOfLineTrivia())) ? newStatement.WithLeadingTrivia(ifStatement.GetLeadingTrivia()) : newStatement.WithLeadingTrivia(ifStatement.GetLeadingTrivia().Concat(leading)); IEnumerable <SyntaxTrivia> trailing = ifStatement.DescendantTrivia(TextSpan.FromBounds(statement.Span.End, ifStatement.Span.End)); newStatement = (leading.All(f => f.IsWhitespaceOrEndOfLineTrivia())) ? newStatement.WithTrailingTrivia(ifStatement.GetTrailingTrivia()) : newStatement.WithTrailingTrivia(trailing.Concat(ifStatement.GetTrailingTrivia())); return(document.ReplaceNodeAsync(ifStatement, newStatement, cancellationToken)); }
private static bool CanRefactor(SyntaxNodeAnalysisContext context, IfStatementSyntax ifStatement, ReturnStatementSyntax returnStatement) { ExpressionSyntax condition = ifStatement.Condition; if (condition?.IsKind(SyntaxKind.EqualsExpression) == true) { var equalsExpression = (BinaryExpressionSyntax)condition; if (equalsExpression.Right?.IsKind(SyntaxKind.NullLiteralExpression) == true) { IdentifierNameSyntax identifierName = GetIdentifierName(equalsExpression.Left); if (identifierName != null) { SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; var fieldSymbol = semanticModel.GetSymbol(identifierName, cancellationToken) as IFieldSymbol; if (fieldSymbol != null) { string fieldName = identifierName.Identifier.ValueText; StatementSyntax statement = ifStatement.GetSingleStatementOrDefault(); if (statement?.IsKind(SyntaxKind.ExpressionStatement) == true) { var expressionStatement = (ExpressionStatementSyntax)statement; ExpressionSyntax expression = expressionStatement.Expression; if (expression?.IsKind(SyntaxKind.SimpleAssignmentExpression) == true) { var assignment = (AssignmentExpressionSyntax)expression; ExpressionSyntax right = assignment.Right; return(right?.IsMissing == false && right.IsSingleLine() && IsBackingField(GetIdentifierName(assignment.Left), fieldName, fieldSymbol, semanticModel, cancellationToken) && IsBackingField(GetIdentifierName(returnStatement.Expression), fieldName, fieldSymbol, semanticModel, cancellationToken)); } } } } } } return(false); }
private static Task <Document> RefactorAsync( Document document, StatementSyntax statement, IfStatementSyntax ifStatement, int statementIndex, IStatementContainer container, ExpressionSyntax expression, CancellationToken cancellationToken) { var expressionStatement = (ExpressionStatementSyntax)ifStatement.GetSingleStatementOrDefault(); var assignment = (AssignmentExpressionSyntax)expressionStatement.Expression; ExpressionSyntax left = expression .WithoutTrailingTrivia() .Parenthesize(moveTrivia: true) .WithSimplifierAnnotation(); ExpressionSyntax right = assignment.Right .WithTrailingTrivia(expression.GetTrailingTrivia()) .Parenthesize(moveTrivia: true) .WithSimplifierAnnotation(); BinaryExpressionSyntax newNode = CSharpFactory.CoalesceExpression(left, right); StatementSyntax newStatement = statement.ReplaceNode(expression, newNode); IEnumerable <SyntaxTrivia> trivia = container.Node.DescendantTrivia(TextSpan.FromBounds(statement.Span.End, ifStatement.Span.End)); if (!trivia.All(f => f.IsWhitespaceOrEndOfLineTrivia())) { newStatement = newStatement.WithTrailingTrivia(trivia); newStatement = newStatement.AppendToTrailingTrivia(ifStatement.GetTrailingTrivia()); } else { newStatement = newStatement.WithTrailingTrivia(ifStatement.GetTrailingTrivia()); } SyntaxList <StatementSyntax> newStatements = container.Statements .Remove(ifStatement) .ReplaceAt(statementIndex, newStatement); return(document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken)); }
public static Task <Document> RefactorAsync( Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken) { ExpressionSyntax condition = ifStatement.Condition; AssignmentExpressionSyntax assignment = GetSimpleAssignmentExpression(ifStatement.GetSingleStatementOrDefault()); if (assignment.Right.IsKind(SyntaxKind.FalseLiteralExpression)) { condition = Negator.LogicallyNegate(condition); } ExpressionStatementSyntax newNode = SimpleAssignmentStatement(assignment.Left, condition) .WithTriviaFrom(ifStatement) .WithFormatterAnnotation(); return(document.ReplaceNodeAsync(ifStatement, newNode, cancellationToken)); }
private static Task <Document> RefactorAsync( Document document, StatementSyntax statement, IfStatementSyntax ifStatement, int statementIndex, StatementContainer container, ExpressionSyntax expression, SemanticModel semanticModel, CancellationToken cancellationToken) { var expressionStatement = (ExpressionStatementSyntax)ifStatement.GetSingleStatementOrDefault(); var assignment = (AssignmentExpressionSyntax)expressionStatement.Expression; BinaryExpressionSyntax newNode = RefactoringHelper.CreateCoalesceExpression( semanticModel.GetTypeSymbol(assignment.Left, cancellationToken), expression.WithoutTrailingTrivia(), assignment.Right.WithTrailingTrivia(expression.GetTrailingTrivia()), statement.SpanStart, semanticModel); StatementSyntax newStatement = statement.ReplaceNode(expression, newNode); IEnumerable <SyntaxTrivia> trivia = container.Node.DescendantTrivia(TextSpan.FromBounds(statement.Span.End, ifStatement.Span.End)); if (!trivia.All(f => f.IsWhitespaceOrEndOfLineTrivia())) { newStatement = newStatement.WithTrailingTrivia(trivia); newStatement = newStatement.AppendToTrailingTrivia(ifStatement.GetTrailingTrivia()); } else { newStatement = newStatement.WithTrailingTrivia(ifStatement.GetTrailingTrivia()); } SyntaxList <StatementSyntax> newStatements = container.Statements .Remove(ifStatement) .ReplaceAt(statementIndex, newStatement); return(document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken)); }
private static ImmutableArray <IfRefactoring> Analyze( LocalDeclarationStatementSyntax localDeclarationStatement, IfStatementSyntax ifStatement, IfAnalysisOptions options) { VariableDeclaratorSyntax declarator = localDeclarationStatement .Declaration? .Variables .SingleOrDefault(throwException: false); if (declarator != null) { ElseClauseSyntax elseClause = ifStatement.Else; if (elseClause?.Statement?.IsKind(SyntaxKind.IfStatement) == false) { SimpleAssignmentStatement assignment1; if (SimpleAssignmentStatement.TryCreate(ifStatement.GetSingleStatementOrDefault(), out assignment1)) { SimpleAssignmentStatement assignment2; if (SimpleAssignmentStatement.TryCreate(elseClause.GetSingleStatementOrDefault(), out assignment2) && assignment1.Left.IsKind(SyntaxKind.IdentifierName) && assignment2.Left.IsKind(SyntaxKind.IdentifierName)) { string identifier1 = ((IdentifierNameSyntax)assignment1.Left).Identifier.ValueText; string identifier2 = ((IdentifierNameSyntax)assignment2.Left).Identifier.ValueText; if (string.Equals(identifier1, identifier2, StringComparison.Ordinal) && string.Equals(identifier1, declarator.Identifier.ValueText, StringComparison.Ordinal) && options.CheckSpanDirectives(ifStatement.Parent, TextSpan.FromBounds(localDeclarationStatement.SpanStart, ifStatement.Span.End))) { return(new LocalDeclarationAndIfElseAssignmentWithConditionalExpression(localDeclarationStatement, ifStatement, assignment1.Right, assignment2.Right).ToImmutableArray()); } } } } } return(ImmutableArray <IfRefactoring> .Empty); }
public static async Task <Document> RefactorAsync( Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken) { ExpressionSyntax condition = ifStatement.Condition; AssignmentExpressionSyntax assignment = GetSimpleAssignmentExpression(ifStatement.GetSingleStatementOrDefault()); if (assignment.Right.IsKind(SyntaxKind.FalseLiteralExpression)) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); condition = CSharpUtility.LogicallyNegate(condition, semanticModel, cancellationToken); } ExpressionStatementSyntax newNode = SimpleAssignmentStatement(assignment.Left, condition) .WithTriviaFrom(ifStatement) .WithFormatterAnnotation(); return(await document.ReplaceNodeAsync(ifStatement, newNode, cancellationToken).ConfigureAwait(false)); }
public static bool CanRefactor( IfStatementSyntax ifStatement, SemanticModel semanticModel, CancellationToken cancellationToken = default(CancellationToken)) { if (ifStatement.IsTopmostIf()) { ElseClauseSyntax elseClause = ifStatement.Else; if (elseClause != null) { ExpressionSyntax condition = ifStatement.Condition; if (condition != null) { ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(condition, cancellationToken); if (typeSymbol?.IsBoolean() == true) { AssignmentExpressionSyntax trueExpression = GetSimpleAssignmentExpression(ifStatement.GetSingleStatementOrDefault()); ExpressionSyntax trueRight = trueExpression?.Right; if (trueRight?.IsBooleanLiteralExpression() == true) { AssignmentExpressionSyntax falseExpression = GetSimpleAssignmentExpression(elseClause.GetSingleStatementOrDefault()); ExpressionSyntax falseRight = falseExpression?.Right; if (falseRight?.IsBooleanLiteralExpression() == true) { var trueBooleanLiteral = (LiteralExpressionSyntax)trueRight; var falseBooleanLiteral = (LiteralExpressionSyntax)falseRight; if (trueBooleanLiteral.IsKind(SyntaxKind.TrueLiteralExpression) != falseBooleanLiteral.IsKind(SyntaxKind.TrueLiteralExpression) && trueExpression.Left?.IsEquivalentTo(falseExpression.Left, topLevel: false) == true) { return(true); } } } } } } } return(false); }
public static ImmutableArray <IfRefactoring> Analyze( IfStatementSyntax ifStatement, IfAnalysisOptions options, SemanticModel semanticModel, CancellationToken cancellationToken = default(CancellationToken)) { if (ifStatement.IsTopmostIf()) { ExpressionSyntax condition = ifStatement.Condition; if (condition != null) { ElseClauseSyntax elseClause = ifStatement.Else; if (elseClause != null) { if (options.CheckSpanDirectives(ifStatement)) { StatementSyntax statement1 = ifStatement.GetSingleStatementOrDefault(); if (statement1 != null) { SyntaxKind kind1 = statement1.Kind(); if (kind1 == SyntaxKind.ExpressionStatement || kind1 == SyntaxKind.ReturnStatement || kind1 == SyntaxKind.YieldReturnStatement) { StatementSyntax statement2 = elseClause.GetSingleStatementOrDefault(); if (statement2?.IsKind(kind1) == true) { switch (kind1) { case SyntaxKind.ExpressionStatement: { return(Analyze(ifStatement, condition, (ExpressionStatementSyntax)statement1, (ExpressionStatementSyntax)statement2, semanticModel, cancellationToken, options)); } case SyntaxKind.ReturnStatement: { return(Analyze(ifStatement, condition, ((ReturnStatementSyntax)statement1).Expression, ((ReturnStatementSyntax)statement2).Expression, semanticModel, cancellationToken, options, isYield: false)); } case SyntaxKind.YieldReturnStatement: { return(Analyze(ifStatement, condition, ((YieldStatementSyntax)statement1).Expression, ((YieldStatementSyntax)statement2).Expression, semanticModel, cancellationToken, options, isYield: true)); } } } } } } } else { StatementSyntax nextStatement = ifStatement.NextStatement(); if (nextStatement?.IsKind(SyntaxKind.ReturnStatement) == true) { return(Analyze(ifStatement, (ReturnStatementSyntax)nextStatement, options, semanticModel, cancellationToken)); } } } } return(ImmutableArray <IfRefactoring> .Empty); }
private static ImmutableArray <IfRefactoring> Analyze( ExpressionStatementSyntax expressionStatement, IfStatementSyntax ifStatement, IfAnalysisOptions options) { SimpleAssignmentStatementInfo assignment = SyntaxInfo.SimpleAssignmentStatementInfo(expressionStatement); if (!assignment.Success) { return(Empty); } ElseClauseSyntax elseClause = ifStatement.Else; if (elseClause?.Statement?.IsKind(SyntaxKind.IfStatement) != false) { return(Empty); } SimpleAssignmentStatementInfo assignment1 = SyntaxInfo.SimpleAssignmentStatementInfo(ifStatement.GetSingleStatementOrDefault()); if (!assignment1.Success) { return(Empty); } SimpleAssignmentStatementInfo assignment2 = SyntaxInfo.SimpleAssignmentStatementInfo(elseClause.GetSingleStatementOrDefault()); if (!assignment2.Success) { return(Empty); } if (!SyntaxComparer.AreEquivalent(assignment1.Left, assignment2.Left, assignment.Left)) { return(Empty); } if (!options.CheckSpanDirectives(ifStatement.Parent, TextSpan.FromBounds(expressionStatement.SpanStart, ifStatement.Span.End))) { return(Empty); } return(new AssignmentAndIfElseToAssignmentWithConditionalExpression(expressionStatement, assignment.Right, ifStatement, assignment1.Right, assignment2.Right).ToImmutableArray()); }
public static ImmutableArray <IfRefactoring> Analyze( IfStatementSyntax ifStatement, IfAnalysisOptions options, SemanticModel semanticModel, CancellationToken cancellationToken = default(CancellationToken)) { if (!ifStatement.IsTopmostIf()) { return(Empty); } ExpressionSyntax condition = ifStatement.Condition?.WalkDownParentheses(); if (condition == null) { return(Empty); } ElseClauseSyntax elseClause = ifStatement.Else; if (elseClause != null) { if (!options.CheckSpanDirectives(ifStatement)) { return(Empty); } StatementSyntax statement1 = ifStatement.GetSingleStatementOrDefault(); if (statement1 == null) { return(Empty); } SyntaxKind kind1 = statement1.Kind(); if (kind1.Is( SyntaxKind.ExpressionStatement, SyntaxKind.ReturnStatement, SyntaxKind.YieldReturnStatement)) { StatementSyntax statement2 = elseClause.GetSingleStatementOrDefault(); if (statement2?.Kind() == kind1) { switch (kind1) { case SyntaxKind.ExpressionStatement: { return(Analyze( ifStatement, condition, (ExpressionStatementSyntax)statement1, (ExpressionStatementSyntax)statement2, options, semanticModel, cancellationToken)); } case SyntaxKind.ReturnStatement: { return(Analyze( ifStatement, condition, ((ReturnStatementSyntax)statement1).Expression?.WalkDownParentheses(), ((ReturnStatementSyntax)statement2).Expression?.WalkDownParentheses(), options, isYield: false, semanticModel: semanticModel, cancellationToken: cancellationToken)); } case SyntaxKind.YieldReturnStatement: { return(Analyze( ifStatement, condition, ((YieldStatementSyntax)statement1).Expression?.WalkDownParentheses(), ((YieldStatementSyntax)statement2).Expression?.WalkDownParentheses(), options, isYield: true, semanticModel: semanticModel, cancellationToken: cancellationToken)); } } } } } else if (ifStatement.NextStatementOrDefault() is ReturnStatementSyntax returnStatement) { return(Analyze(ifStatement, returnStatement, options, semanticModel, cancellationToken)); } return(Empty); }
private static ImmutableArray <IfRefactoring> Analyze( LocalDeclarationStatementSyntax localDeclarationStatement, IfStatementSyntax ifStatement, IfAnalysisOptions options) { VariableDeclaratorSyntax declarator = localDeclarationStatement .Declaration? .Variables .SingleOrDefault(shouldthrow: false); if (declarator == null) { return(Empty); } ElseClauseSyntax elseClause = ifStatement.Else; if (elseClause?.Statement?.IsKind(SyntaxKind.IfStatement) != false) { return(Empty); } SimpleAssignmentStatementInfo assignment1 = SyntaxInfo.SimpleAssignmentStatementInfo(ifStatement.GetSingleStatementOrDefault()); if (!assignment1.Success) { return(Empty); } SimpleAssignmentStatementInfo assignment2 = SyntaxInfo.SimpleAssignmentStatementInfo(elseClause.GetSingleStatementOrDefault()); if (!assignment2.Success) { return(Empty); } if (!assignment1.Left.IsKind(SyntaxKind.IdentifierName)) { return(Empty); } if (!assignment2.Left.IsKind(SyntaxKind.IdentifierName)) { return(Empty); } string identifier1 = ((IdentifierNameSyntax)assignment1.Left).Identifier.ValueText; string identifier2 = ((IdentifierNameSyntax)assignment2.Left).Identifier.ValueText; if (!string.Equals(identifier1, identifier2, StringComparison.Ordinal)) { return(Empty); } if (!string.Equals(identifier1, declarator.Identifier.ValueText, StringComparison.Ordinal)) { return(Empty); } if (!options.CheckSpanDirectives(ifStatement.Parent, TextSpan.FromBounds(localDeclarationStatement.SpanStart, ifStatement.Span.End))) { return(Empty); } return(new LocalDeclarationAndIfElseAssignmentWithConditionalExpression(localDeclarationStatement, ifStatement, assignment1.Right, assignment2.Right).ToImmutableArray()); }
public static Task <Document> InlineLazyInitializationAsync( Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken) { StatementContainer container = StatementContainer.Create(ifStatement); SyntaxList <StatementSyntax> statements = container.Statements; int index = statements.IndexOf(ifStatement); StatementSyntax expressionStatement = (ExpressionStatementSyntax)statements[index + 1]; MemberInvocationStatement invocation = MemberInvocationStatement.Create((ExpressionStatementSyntax)expressionStatement); ExpressionSyntax expression = invocation.Expression; SimpleAssignmentStatement assignment = SimpleAssignmentStatement.Create((ExpressionStatementSyntax)ifStatement.GetSingleStatementOrDefault()); BinaryExpressionSyntax coalesceExpression = CSharpFactory.CoalesceExpression(expression.WithoutTrivia(), ParenthesizedExpression(assignment.AssignmentExpression)); ParenthesizedExpressionSyntax newExpression = ParenthesizedExpression(coalesceExpression) .WithTriviaFrom(expression); StatementSyntax newExpressionStatement = expressionStatement.ReplaceNode(expression, newExpression); IEnumerable <SyntaxTrivia> trivia = container.Node.DescendantTrivia(TextSpan.FromBounds(ifStatement.FullSpan.Start, expressionStatement.FullSpan.Start)); if (trivia.Any(f => !f.IsWhitespaceOrEndOfLineTrivia())) { newExpressionStatement = newExpressionStatement.PrependToLeadingTrivia(trivia); } SyntaxList <StatementSyntax> newStatements = statements .Replace(expressionStatement, newExpressionStatement) .RemoveAt(index); return(document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken)); }