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)); }
public static void AnalyzeIfStatement(SyntaxNodeAnalysisContext context) { var ifStatement = (IfStatementSyntax)context.Node; if (ifStatement.IsSimpleIf() && !ifStatement.ContainsDiagnostics && ifStatement.TryGetContainingList(out SyntaxList <StatementSyntax> statements) && !IsPartOfLazyInitialization(ifStatement, statements)) { NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(ifStatement.Condition, semanticModel: context.SemanticModel, cancellationToken: context.CancellationToken); if (nullCheck.Success) { SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(ifStatement.GetSingleStatementOrDefault()); if (assignmentInfo.Success && SyntaxComparer.AreEquivalent(assignmentInfo.Left, nullCheck.Expression) && assignmentInfo.Right.IsSingleLine() && !ifStatement.SpanContainsDirectives()) { int index = statements.IndexOf(ifStatement); if (index > 0) { StatementSyntax previousStatement = statements[index - 1]; if (!previousStatement.ContainsDiagnostics && CanRefactor(previousStatement, ifStatement, nullCheck.Expression, ifStatement.Parent)) { context.ReportDiagnostic(DiagnosticDescriptors.UseCoalesceExpression, previousStatement); } } if (index < statements.Count - 1) { StatementSyntax nextStatement = statements[index + 1]; if (!nextStatement.ContainsDiagnostics) { MemberInvocationStatementInfo invocationInfo = SyntaxInfo.MemberInvocationStatementInfo(nextStatement); if (invocationInfo.Success && SyntaxComparer.AreEquivalent(nullCheck.Expression, invocationInfo.Expression) && !ifStatement.Parent.ContainsDirectives(TextSpan.FromBounds(ifStatement.SpanStart, nextStatement.Span.End))) { context.ReportDiagnostic(DiagnosticDescriptors.InlineLazyInitialization, ifStatement); } } } } } } }
public static void AnalyzeIfStatement(SyntaxNodeAnalysisContext context, INamedTypeSymbol expressionType) { var ifStatement = (IfStatementSyntax)context.Node; if (ifStatement.IsSimpleIf() && !ifStatement.ContainsDiagnostics) { NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(ifStatement.Condition, allowedKinds: NullCheckKind.NotEqualsToNull); if (nullCheck.Success) { MemberInvocationStatementInfo invocationInfo = SyntaxInfo.MemberInvocationStatementInfo(ifStatement.GetSingleStatementOrDefault()); if (invocationInfo.Success && SyntaxComparer.AreEquivalent(nullCheck.Expression, invocationInfo.Expression) && !ifStatement.IsInExpressionTree(expressionType, context.SemanticModel, context.CancellationToken) && !ifStatement.SpanContainsDirectives()) { context.ReportDiagnostic(DiagnosticDescriptors.UseConditionalAccess, ifStatement); } } } }
public static Task <Document> InlineLazyInitializationAsync( Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken) { StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(ifStatement); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; int index = statements.IndexOf(ifStatement); StatementSyntax expressionStatement = (ExpressionStatementSyntax)statements[index + 1]; MemberInvocationStatementInfo invocationInfo = SyntaxInfo.MemberInvocationStatementInfo((ExpressionStatementSyntax)expressionStatement); ExpressionSyntax expression = invocationInfo.Expression; SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo((ExpressionStatementSyntax)ifStatement.GetSingleStatementOrDefault()); BinaryExpressionSyntax coalesceExpression = CSharpFactory.CoalesceExpression(expression.WithoutTrivia(), ParenthesizedExpression(assignmentInfo.AssignmentExpression)); ParenthesizedExpressionSyntax newExpression = ParenthesizedExpression(coalesceExpression) .WithTriviaFrom(expression); StatementSyntax newExpressionStatement = expressionStatement.ReplaceNode(expression, newExpression); IEnumerable <SyntaxTrivia> trivia = statementsInfo.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.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken)); }