public virtual Task <Document> InlineAsync( ExpressionStatementSyntax expressionStatement, SyntaxList <StatementSyntax> statements, CancellationToken cancellationToken = default(CancellationToken)) { int count = statements.Count; StatementSyntax[] newStatements = RewriteStatements(statements); newStatements[0] = newStatements[0].WithLeadingTrivia(expressionStatement.GetLeadingTrivia()); newStatements[count - 1] = newStatements[count - 1].WithTrailingTrivia(expressionStatement.GetTrailingTrivia()); StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(expressionStatement); if (statementsInfo.Success) { StatementsInfo newInfo = statementsInfo.WithStatements(statementsInfo.Statements.ReplaceRange(expressionStatement, newStatements)); return(Document.ReplaceNodeAsync(statementsInfo.Node, newInfo.Node, cancellationToken)); } else { return(Document.ReplaceNodeAsync(expressionStatement, Block(newStatements), cancellationToken)); } }
public static Task <Document> RefactorAsync( Document document, UsingStatementSyntax usingStatement, CancellationToken cancellationToken = default(CancellationToken)) { StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(usingStatement); int index = statementsInfo.Statements.IndexOf(usingStatement); StatementsInfo newStatementsInfo = statementsInfo.RemoveAt(index); var statements = new List <StatementSyntax>() { SyntaxFactory.LocalDeclarationStatement(usingStatement.Declaration) }; statements.AddRange(GetStatements(usingStatement)); if (statements.Count > 0) { statements[0] = statements[0] .WithLeadingTrivia(usingStatement.GetLeadingTrivia()); statements[statements.Count - 1] = statements[statements.Count - 1] .WithTrailingTrivia(usingStatement.GetTrailingTrivia()); } newStatementsInfo = newStatementsInfo.WithStatements(newStatementsInfo.Statements.InsertRange(index, statements)); return(document.ReplaceNodeAsync(statementsInfo.Node, newStatementsInfo.Node.WithFormatterAnnotation(), cancellationToken)); }
private static Task <Document> RefactorAsync( Document document, SingleLocalDeclarationStatementInfo localInfo, SemanticModel semanticModel, CancellationToken cancellationToken) { StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(localInfo.Statement); var localSymbol = (ILocalSymbol)semanticModel.GetDeclaredSymbol(localInfo.Declarator, cancellationToken); IdentifierNameSyntax identifierName = FindLastReference(localSymbol, statementsInfo.Node, semanticModel, cancellationToken); TextSpan span; if (identifierName == null) { span = localInfo.Statement.Span; } else { int position = identifierName.SpanStart; span = TextSpan.FromBounds(localInfo.Statement.SpanStart, statementsInfo.First(f => f.Span.Contains(position)).Span.End); } StatementsSelection selectedStatements = StatementsSelection.Create(statementsInfo, span); var refactoring = new WrapStatements.WrapInUsingStatementRefactoring(); return(refactoring.RefactorAsync(document, selectedStatements, cancellationToken)); }
public override async Task <Document> RefactorAsync(Document document, CancellationToken cancellationToken = default(CancellationToken)) { StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(IfStatement); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; int index = statements.IndexOf(IfStatement); SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ExpressionSyntax expression = IfRefactoringHelper.GetBooleanExpression( IfStatement.Condition, Expression1, Expression2, semanticModel, cancellationToken); StatementSyntax newStatement = CreateStatement(expression) .WithLeadingTrivia(IfStatement.GetLeadingTrivia()) .WithTrailingTrivia(statements[index + 1].GetTrailingTrivia()) .WithFormatterAnnotation(); SyntaxList <StatementSyntax> newStatements = statements .RemoveAt(index) .ReplaceAt(index, newStatement); return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false)); }
private static bool NullCheckExists(ExpressionSyntax expression, StatementSyntax statement) { StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(statement); if (!statementsInfo.Success) { return(false); } SyntaxList <StatementSyntax> statements = statementsInfo.Statements; int index = statements.IndexOf(statement); if (index >= statements.Count - 1) { return(false); } StatementSyntax nextStatement = statements[index + 1]; if (!(nextStatement is IfStatementSyntax ifStatement)) { return(false); } NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(ifStatement.Condition, NullCheckKind.NotEqualsToNull); if (!nullCheck.Success) { return(false); } return(SyntaxComparer.AreEquivalent(expression, nullCheck.Expression)); }
private static Task <Document> DuplicateStatementAsync( Document document, StatementSyntax statement, CancellationToken cancellationToken = default(CancellationToken)) { StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(statement); if (statementsInfo.Success) { int index = statementsInfo.Statements.IndexOf(statement); if (index == 0 && statementsInfo.IsInBlock && statementsInfo.Block.OpenBraceToken.GetFullSpanEndLine() == statement.GetFullSpanStartLine()) { statement = statement.PrependToLeadingTrivia(CSharpFactory.NewLine()); } SyntaxList <StatementSyntax> newStatements = statementsInfo.Statements.Insert(index + 1, statement.WithNavigationAnnotation()); StatementsInfo newInfo = statementsInfo.WithStatements(newStatements); return(document.ReplaceNodeAsync(statementsInfo.Node, newInfo.Node, cancellationToken)); } else { SyntaxList <StatementSyntax> statements = SyntaxFactory.List(new StatementSyntax[] { statement, statement.WithNavigationAnnotation() }); BlockSyntax block = SyntaxFactory.Block(statements); return(document.ReplaceNodeAsync(statement, block, cancellationToken)); } }
public static Task <Document> RefactorAsync( Document document, LocalFunctionStatementSyntax localFunction, CancellationToken cancellationToken = default(CancellationToken)) { if (document == null) { throw new ArgumentNullException(nameof(document)); } if (localFunction == null) { throw new ArgumentNullException(nameof(localFunction)); } StatementsInfo statementsInfos = SyntaxInfo.StatementsInfo(localFunction); SyntaxList <StatementSyntax> statements = statementsInfos.Statements; int index = statements.IndexOf(localFunction); if (index == 0 && statementsInfos.Block.OpenBraceToken.GetFullSpanEndLine() == localFunction.GetFullSpanStartLine()) { localFunction = localFunction.WithLeadingTrivia(localFunction.GetLeadingTrivia().Insert(0, NewLine())); } SyntaxList <StatementSyntax> newStatements = statements.Insert(index + 1, localFunction.WithNavigationAnnotation()); return(document.ReplaceStatementsAsync(statementsInfos, newStatements, cancellationToken)); }
public static Task <Document> RefactorAsync( Document document, AssignmentExpressionSyntax assignmentExpression, CancellationToken cancellationToken) { var statement = (StatementSyntax)assignmentExpression.Parent; StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(statement); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; int index = statements.IndexOf(statement); statements = statements.RemoveAt(index); var returnStatement = (ReturnStatementSyntax)statement.NextStatementOrDefault(); IEnumerable <SyntaxTrivia> trivia = statementsInfo .Node .DescendantTrivia(TextSpan.FromBounds(statement.SpanStart, returnStatement.SpanStart)) .Where(f => !f.IsWhitespaceOrEndOfLineTrivia()); trivia = statement .GetLeadingTrivia() .Concat(trivia); returnStatement = returnStatement .WithExpression(assignmentExpression.Right.WithTriviaFrom(returnStatement.Expression)) .WithLeadingTrivia(trivia); statements = statements.ReplaceAt(index, returnStatement); return(document.ReplaceStatementsAsync(statementsInfo, statements, cancellationToken)); }
public static async Task ComputeRefactoringAsync( RefactoringContext context, LocalDeclarationStatementSyntax localDeclaration) { StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(localDeclaration); if (!statementsInfo.Success) { return; } SingleLocalDeclarationStatementInfo localInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo(localDeclaration); if (!localInfo.Success) { return; } if (!context.Span.IsEmptyAndContainedInSpan(localInfo.EqualsToken)) { return; } ExpressionSyntax value = localInfo.Initializer?.Value; if (value == null) { return; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); TypeSyntax type = localInfo.Type; if (type.IsVar) { ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(value, context.CancellationToken); if (typeSymbol?.SupportsExplicitDeclaration() != true) { return; } type = typeSymbol.ToMinimalTypeSyntax(semanticModel, type.SpanStart); } else { ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, context.CancellationToken); if (typeSymbol?.IsErrorType() != false) { return; } } context.RegisterRefactoring( "Split declaration and initialization", cancellationToken => RefactorAsync(context.Document, localInfo, type, statementsInfo, cancellationToken)); }
public static Task <Document> RefactorAsync( Document document, VariableDeclaratorSyntax declarator, CancellationToken cancellationToken = default(CancellationToken)) { var declaration = (VariableDeclarationSyntax)declarator.Parent; var localDeclaration = (LocalDeclarationStatementSyntax)declaration.Parent; StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(localDeclaration); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; int index = statements.IndexOf(localDeclaration); StatementSyntax nextStatement = statements[index + 1]; var expressionStatement = (ExpressionStatementSyntax)nextStatement; var assignment = (AssignmentExpressionSyntax)expressionStatement.Expression; ExpressionSyntax right = assignment.Right; EqualsValueClauseSyntax initializer = declarator.Initializer; ExpressionSyntax value = initializer?.Value; VariableDeclaratorSyntax newDeclarator = (value != null) ? declarator.ReplaceNode(value, right) : declarator.WithInitializer(EqualsValueClause(right)); LocalDeclarationStatementSyntax newLocalDeclaration = localDeclaration.ReplaceNode(declarator, newDeclarator); SyntaxTriviaList trailingTrivia = localDeclaration.GetTrailingTrivia(); if (!trailingTrivia.IsEmptyOrWhitespace()) { newLocalDeclaration = newLocalDeclaration.WithTrailingTrivia(trailingTrivia.Concat(nextStatement.GetTrailingTrivia())); } else { newLocalDeclaration = newLocalDeclaration.WithTrailingTrivia(nextStatement.GetTrailingTrivia()); } SyntaxTriviaList leadingTrivia = nextStatement.GetLeadingTrivia(); if (!leadingTrivia.IsEmptyOrWhitespace()) { newLocalDeclaration = newLocalDeclaration.WithLeadingTrivia(newLocalDeclaration.GetLeadingTrivia().Concat(leadingTrivia)); } SyntaxList <StatementSyntax> newStatements = statements .Replace(localDeclaration, newLocalDeclaration) .RemoveAt(index + 1); return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken)); }
internal static void ComputeRefactoring(RefactoringContext context, BinaryExpressionSelection binaryExpressionSelection) { BinaryExpressionSyntax binaryExpression = binaryExpressionSelection.BinaryExpression; SyntaxKind kind = binaryExpression.Kind(); if (kind == SyntaxKind.LogicalAndExpression || kind == SyntaxKind.LogicalOrExpression) { BinaryExpressionSyntax condition = GetCondition(binaryExpression); if (condition != null) { SyntaxNode parent = condition.Parent; switch (parent?.Kind()) { case SyntaxKind.IfStatement: { if (kind == SyntaxKind.LogicalAndExpression) { var refactoring = new ExtractConditionFromIfToNestedIfRefactoring(); context.RegisterRefactoring( refactoring.Title, cancellationToken => refactoring.RefactorAsync(context.Document, (IfStatementSyntax)parent, condition, binaryExpressionSelection, cancellationToken)); } else if (kind == SyntaxKind.LogicalOrExpression) { StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo((StatementSyntax)parent); if (statementsInfo.Success) { var refactoring = new ExtractConditionFromIfToIfRefactoring(); context.RegisterRefactoring( refactoring.Title, cancellationToken => refactoring.RefactorAsync(context.Document, statementsInfo, condition, binaryExpressionSelection, cancellationToken)); } } break; } case SyntaxKind.WhileStatement: { if (kind == SyntaxKind.LogicalAndExpression) { var refactoring = new ExtractConditionFromWhileToNestedIfRefactoring(); context.RegisterRefactoring( refactoring.Title, cancellationToken => refactoring.RefactorAsync(context.Document, (WhileStatementSyntax)parent, condition, binaryExpressionSelection, cancellationToken)); } break; } } } } }
public bool Analyze( MemberInvocationExpressionInfo invocationInfo, StatementSyntax statement, string name, SemanticModel semanticModel, CancellationToken cancellationToken) { if (statement.SpanOrTrailingTriviaContainsDirectives()) { return(false); } StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(statement); if (!statementsInfo.Success) { return(false); } SyntaxList <StatementSyntax> statements = statementsInfo.Statements; if (statements.Count == 1) { return(false); } if (!semanticModel.TryGetMethodInfo(invocationInfo.InvocationExpression, out MethodInfo methodInfo, cancellationToken)) { return(false); } ITypeSymbol typeSymbol = methodInfo.ReturnType; int i = statements.IndexOf(statement); if (i != 0 && IsFixableStatement(statements[i - 1], name, typeSymbol, semanticModel, cancellationToken)) { return(false); } int j = i; while (j < statements.Count - 1) { if (!IsFixableStatement(statements[j + 1], name, typeSymbol, semanticModel, cancellationToken)) { break; } j++; } return(j > i); }
public override async Task <Document> RefactorAsync(Document document, CancellationToken cancellationToken = default(CancellationToken)) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); int position = IfStatement.SpanStart; ITypeSymbol targetType = GetTargetType(position, semanticModel, cancellationToken); BinaryExpressionSyntax coalesceExpression = RefactoringHelper.CreateCoalesceExpression( targetType, Left.WithoutTrivia(), Right.WithoutTrivia(), position, semanticModel); StatementSyntax statement = CreateStatement(coalesceExpression); if (IfStatement.IsSimpleIf()) { StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(IfStatement); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; int index = statements.IndexOf(IfStatement); StatementSyntax newNode = statement .WithLeadingTrivia(IfStatement.GetLeadingTrivia()) .WithTrailingTrivia(statements[index + 1].GetTrailingTrivia()) .WithFormatterAnnotation(); SyntaxList <StatementSyntax> newStatements = statements .RemoveAt(index) .ReplaceAt(index, newNode); return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false)); } else { StatementSyntax newNode = statement .WithTriviaFrom(IfStatement) .WithFormatterAnnotation(); return(await document.ReplaceNodeAsync(IfStatement, newNode, cancellationToken).ConfigureAwait(false)); } }
private static async Task <Document> RefactorAsync( Document document, ExpressionSyntax expression, StatementSyntax statement, CancellationToken cancellationToken) { if (statement.IsEmbedded()) { return(await document.ReplaceNodeAsync(statement, Block(statement, CreateNullCheck(expression)), cancellationToken).ConfigureAwait(false)); } else { StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(statement); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; int statementIndex = statements.IndexOf(statement); SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ISymbol symbol = (statement is LocalDeclarationStatementSyntax localDeclaration) ? semanticModel.GetDeclaredSymbol(localDeclaration.Declaration.Variables.First(), cancellationToken) : semanticModel.GetSymbol(expression, cancellationToken); int lastStatementIndex = IncludeAllReferencesOfSymbol(symbol, expression.Kind(), statements, statementIndex + 1, semanticModel, cancellationToken); if (lastStatementIndex != -1) { if (lastStatementIndex < statements.Count - 1) { lastStatementIndex = IncludeAllReferencesOfVariablesDeclared(statements, statementIndex + 1, lastStatementIndex, semanticModel, cancellationToken); } return(await RefactorAsync( document, expression, statements, statementsInfo, statementIndex, lastStatementIndex, cancellationToken).ConfigureAwait(false)); } } return(await document.InsertNodeAfterAsync(statement, CreateNullCheck(expression), cancellationToken).ConfigureAwait(false)); }
public override Task <Document> RefactorAsync( Document document, CancellationToken cancellationToken = default(CancellationToken)) { StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(IfStatement); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; int index = statements.IndexOf(IfStatement); TStatement newStatement = CreateNewStatement(); SyntaxList <StatementSyntax> newStatements = statements .RemoveAt(index) .ReplaceAt(index - 1, newStatement); return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken)); }
public virtual async Task <Solution> InlineAndRemoveAsync( ExpressionStatementSyntax expressionStatement, SyntaxList <StatementSyntax> statements, CancellationToken cancellationToken = default(CancellationToken)) { if (expressionStatement.SyntaxTree == Declaration.SyntaxTree) { DocumentEditor editor = await DocumentEditor.CreateAsync(Document, cancellationToken).ConfigureAwait(false); StatementSyntax[] newStatements = RewriteStatements(statements); int count = statements.Count; newStatements[0] = newStatements[0].WithLeadingTrivia(expressionStatement.GetLeadingTrivia()); newStatements[count - 1] = newStatements[count - 1].WithTrailingTrivia(expressionStatement.GetTrailingTrivia()); StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(expressionStatement); if (statementsInfo.Success) { StatementsInfo newStatementsInfo = statementsInfo.WithStatements(statementsInfo.Statements.ReplaceRange(expressionStatement, newStatements)); editor.ReplaceNode(statementsInfo.Node, newStatementsInfo.Node); } else { editor.ReplaceNode(expressionStatement, Block(newStatements)); } editor.RemoveNode(Declaration); return(editor.GetChangedDocument().Solution()); } else { Document newDocument = await InlineAsync(expressionStatement, statements, cancellationToken).ConfigureAwait(false); DocumentId documentId = Document.Solution().GetDocumentId(Declaration.SyntaxTree); newDocument = await newDocument.Solution().GetDocument(documentId).RemoveMemberAsync(Declaration, cancellationToken).ConfigureAwait(false); return(newDocument.Solution()); } }
public static async Task <Document> RefactorAsync( Document document, IfStatementSyntax ifStatement, SyntaxKind jumpKind, bool recursive, CancellationToken cancellationToken = default(CancellationToken)) { StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(ifStatement); CSharpSyntaxNode node = statementsInfo.Node; SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var rewriter = new ReduceIfStatementRewriter(jumpKind, recursive, semanticModel, cancellationToken); SyntaxNode newNode = rewriter.Visit(node); return(await document.ReplaceNodeAsync(node, newNode, cancellationToken).ConfigureAwait(false)); }
public override async Task <Document> RefactorAsync(Document document, CancellationToken cancellationToken = default(CancellationToken)) { ExpressionSyntax expression = Expression; if (Negate) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); expression = LogicalNegationHelper.LogicallyNegate(expression, semanticModel, cancellationToken); } StatementSyntax statement = CreateStatement(expression); if (IfStatement.IsSimpleIf()) { StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(IfStatement); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; int index = statements.IndexOf(IfStatement); StatementSyntax newNode = statement .WithLeadingTrivia(IfStatement.GetLeadingTrivia()) .WithTrailingTrivia(statements[index + 1].GetTrailingTrivia()) .WithFormatterAnnotation(); SyntaxList <StatementSyntax> newStatements = statements .RemoveAt(index) .ReplaceAt(index, newNode); return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false)); } else { StatementSyntax newNode = statement .WithTriviaFrom(IfStatement) .WithFormatterAnnotation(); return(await document.ReplaceNodeAsync(IfStatement, newNode, cancellationToken).ConfigureAwait(false)); } }
public static void AnalyzeIfStatement(SyntaxNodeAnalysisContext context) { if (context.Node.ContainsDiagnostics) { return; } var ifStatement = (IfStatementSyntax)context.Node; if (!ifStatement.IsSimpleIf()) { StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(ifStatement); if (statementsInfo.Success) { int index = statementsInfo.Statements.IndexOf(ifStatement); ReturnStatementSyntax returnStatement = FindReturnStatementBelow(statementsInfo.Statements, index); if (returnStatement?.ContainsDiagnostics == false) { ExpressionSyntax expression = returnStatement.Expression; if (expression != null && !ifStatement.SpanOrTrailingTriviaContainsDirectives() && !returnStatement.SpanOrLeadingTriviaContainsDirectives()) { SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; ISymbol symbol = semanticModel.GetSymbol(expression, cancellationToken); if (IsLocalDeclaredInScopeOrNonRefOrOutParameterOfEnclosingSymbol(symbol, statementsInfo.Node, semanticModel, cancellationToken) && ifStatement .GetChain() .All(ifOrElse => IsSymbolAssignedInLastStatement(ifOrElse, symbol, semanticModel, cancellationToken))) { context.ReportDiagnostic(DiagnosticDescriptors.UseReturnInsteadOfAssignment, ifStatement); } } } } } }
public override Task <Document> RefactorAsync(Document document, CancellationToken cancellationToken = default(CancellationToken)) { StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(IfStatement); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; int index = statements.IndexOf(IfStatement); ConditionalExpressionSyntax conditionalExpression = IfRefactoringHelper.CreateConditionalExpression(IfStatement.Condition, Expression1, Expression2); StatementSyntax newStatement = CreateStatement(conditionalExpression) .WithLeadingTrivia(IfStatement.GetLeadingTrivia()) .WithTrailingTrivia(statements[index + 1].GetTrailingTrivia()) .WithFormatterAnnotation(); SyntaxList <StatementSyntax> newStatements = statements .RemoveAt(index) .ReplaceAt(index, newStatement); return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken)); }
private static void RegisterRefactoring( RefactoringContext context, StatementSyntax statement, InitializerExpressionSyntax initializer, ExpressionSyntax expression) { StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(statement); if (statementsInfo.Success) { context.RegisterRefactoring( Title, cancellationToken => RefactorAsync( context.Document, statementsInfo, statement, initializer, expression.WithoutTrivia(), cancellationToken)); } }
private static Task <Document> RefactorAsync( Document document, LocalDeclarationStatementSyntax localDeclaration, ConditionalExpressionSyntax conditionalExpression, SemanticModel semanticModel, CancellationToken cancellationToken = default(CancellationToken)) { VariableDeclaratorSyntax variableDeclarator = localDeclaration.Declaration.Variables[0]; LocalDeclarationStatementSyntax newLocalDeclaration = localDeclaration.RemoveNode(variableDeclarator.Initializer, SyntaxRemoveOptions.KeepExteriorTrivia); TypeSyntax type = newLocalDeclaration.Declaration.Type; if (type.IsVar) { newLocalDeclaration = newLocalDeclaration.ReplaceNode( type, semanticModel.GetTypeSymbol(conditionalExpression) .ToMinimalTypeSyntax(semanticModel, type.SpanStart) .WithTriviaFrom(type)); } IdentifierNameSyntax left = IdentifierName(variableDeclarator.Identifier.ValueText); IfStatementSyntax ifStatement = IfElseStatement( conditionalExpression.Condition.WalkDownParentheses().WithoutTrivia(), SimpleAssignmentStatement(left, conditionalExpression.WhenTrue.WithoutTrivia()), SimpleAssignmentStatement(left, conditionalExpression.WhenFalse.WithoutTrivia())); StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(localDeclaration); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; SyntaxList <StatementSyntax> newStatements = statements .Replace(localDeclaration, newLocalDeclaration.WithFormatterAnnotation()) .Insert(statements.IndexOf(localDeclaration) + 1, ifStatement.WithFormatterAnnotation()); return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken)); }
private static Task <Document> RefactorAsync( Document document, ExpressionSyntax expression, StatementSyntax statement, int statementCount, CancellationToken cancellationToken) { StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(statement); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; int statementIndex = statements.IndexOf(statement); return(RefactorAsync( document, expression, statements, statementsInfo, statementIndex, statementIndex + statementCount, cancellationToken)); }
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)); }
private static Task <Document> RefactorAsync( Document document, SingleLocalDeclarationStatementInfo localInfo, TypeSyntax type, CancellationToken cancellationToken) { LocalDeclarationStatementSyntax localStatement = localInfo.Statement; StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(localStatement); int index = statementsInfo.IndexOf(localStatement); VariableDeclaratorSyntax declarator = localInfo.Declarator; VariableDeclaratorSyntax newDeclarator = declarator.WithInitializer(null); VariableDeclarationSyntax newDeclaration = localInfo.Declaration.ReplaceNode(declarator, newDeclarator); if (type != null) { newDeclaration = newDeclaration.WithType(type.WithTriviaFrom(newDeclaration.Type)); } LocalDeclarationStatementSyntax newLocalStatement = localStatement .WithDeclaration(newDeclaration) .WithTrailingTrivia(NewLine()) .WithFormatterAnnotation(); ExpressionStatementSyntax assignmentStatement = SimpleAssignmentStatement(IdentifierName(localInfo.Identifier), localInfo.Initializer.Value) .WithTrailingTrivia(localStatement.GetTrailingTrivia()) .WithFormatterAnnotation(); StatementsInfo newStatementsInfo = statementsInfo .Insert(index + 1, assignmentStatement) .ReplaceAt(index, newLocalStatement); return(document.ReplaceStatementsAsync(statementsInfo, newStatementsInfo, cancellationToken)); }
public static async Task <Document> RefactorAsync( Document document, LocalDeclarationStatementSyntax localDeclaration, CancellationToken cancellationToken) { StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(localDeclaration); int index = statementsInfo.Statements.IndexOf(localDeclaration); StatementSyntax nextStatement = statementsInfo.Statements[index + 1]; SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ExpressionSyntax value = GetExpressionToInline(localDeclaration, semanticModel, cancellationToken); StatementSyntax newStatement = GetStatementWithInlinedExpression(nextStatement, value); SyntaxTriviaList leadingTrivia = localDeclaration.GetLeadingTrivia(); IEnumerable <SyntaxTrivia> trivia = statementsInfo .Node .DescendantTrivia(TextSpan.FromBounds(localDeclaration.SpanStart, nextStatement.Span.Start)); if (!trivia.All(f => f.IsWhitespaceOrEndOfLineTrivia())) { newStatement = newStatement.WithLeadingTrivia(leadingTrivia.Concat(trivia)); } else { newStatement = newStatement.WithLeadingTrivia(leadingTrivia); } SyntaxList <StatementSyntax> newStatements = statementsInfo.Statements .Replace(nextStatement, newStatement) .RemoveAt(index); return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false)); }
private static Task <Document> RefactorAsync <TNode>( Document document, WhileStatementSyntax whileStatement, ForStatementSyntax forStatement, List <TNode> list, CancellationToken cancellationToken) where TNode : StatementSyntax { forStatement = forStatement .TrimLeadingTrivia() .PrependToLeadingTrivia(list[0].GetLeadingTrivia()); StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(whileStatement); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; int index = statements.IndexOf(list[0]); IEnumerable <StatementSyntax> newStatements = statements.Take(index) .Concat(new ForStatementSyntax[] { forStatement }) .Concat(statements.Skip(index + list.Count + 1)); return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken)); }
public async Task <Document> RefactorAsync( Document document, ExpressionStatementSyntax expressionStatement, CancellationToken cancellationToken) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); InvocationExpressionSyntax invocationExpression = GetInvocationExpression(expressionStatement); semanticModel.TryGetMethodInfo(invocationExpression, out MethodInfo methodInfo, cancellationToken); MemberInvocationExpressionInfo invocationInfo = SyntaxInfo.MemberInvocationExpressionInfo(invocationExpression); ITypeSymbol typeSymbol = methodInfo.ReturnType; string name = ((IdentifierNameSyntax)WalkDownMethodChain(invocationInfo).Expression).Identifier.ValueText; StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(expressionStatement); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; int index = statements.IndexOf(expressionStatement); string indentation = CSharpFormatter.GetIncreasedIndentation(expressionStatement, cancellationToken).ToString(); var sb = new StringBuilder(invocationExpression.ToString()); int j = index; while (j < statements.Count - 1) { StatementSyntax statement = statements[j + 1]; if (!IsFixableStatement(statement, name, typeSymbol, semanticModel, cancellationToken)) { break; } sb.AppendLine(); sb.Append(indentation); sb.Append(GetTextToAppend((ExpressionStatementSyntax)statement)); j++; } StatementSyntax lastStatement = statements[j]; SyntaxList <StatementSyntax> newStatements = statements; while (j > index) { newStatements = newStatements.RemoveAt(j); j--; } ExpressionSyntax newInvocationExpression = SyntaxFactory.ParseExpression(sb.ToString()); SyntaxTriviaList trailingTrivia = statementsInfo .Node .DescendantTrivia(TextSpan.FromBounds(invocationExpression.Span.End, lastStatement.Span.End)) .ToSyntaxTriviaList() .EmptyIfWhitespace() .AddRange(lastStatement.GetTrailingTrivia()); ExpressionStatementSyntax newExpressionStatement = expressionStatement .ReplaceNode(invocationExpression, newInvocationExpression) .WithLeadingTrivia(expressionStatement.GetLeadingTrivia()) .WithTrailingTrivia(trailingTrivia) .WithFormatterAndSimplifierAnnotations(); newStatements = newStatements.ReplaceAt(index, newExpressionStatement); return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false)); }
public static async Task <Document> RefactorAsync( Document document, StatementSyntax statement, CancellationToken cancellationToken) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(statement); int index = statementsInfo.Statements.IndexOf(statement); switch (statement.Kind()) { case SyntaxKind.IfStatement: { var ifStatement = (IfStatementSyntax)statement; IfStatementInfo ifStatementInfo = SyntaxInfo.IfStatementInfo(ifStatement); IEnumerable <ExpressionStatementSyntax> expressionStatements = ifStatementInfo .Nodes .Select(ifOrElse => (ExpressionStatementSyntax)GetLastStatementOrDefault(ifOrElse.Statement)); IfStatementSyntax newIfStatement = ifStatement.ReplaceNodes( expressionStatements, (f, _) => { var assignment = (AssignmentExpressionSyntax)f.Expression; return(ReturnStatement(assignment.Right).WithTriviaFrom(f)); }); StatementsInfo newStatementsInfo = await RefactorAsync( document, statementsInfo, ifStatement, newIfStatement, index, ifStatementInfo.Nodes.Length, ifStatementInfo.EndsWithElse, semanticModel, cancellationToken).ConfigureAwait(false); return(await document.ReplaceNodeAsync(statementsInfo.Node, newStatementsInfo.Node, cancellationToken).ConfigureAwait(false)); } case SyntaxKind.SwitchStatement: { var switchStatement = (SwitchStatementSyntax)statement; SyntaxList <SwitchSectionSyntax> newSections = switchStatement .Sections .Select(CreateNewSection) .ToSyntaxList(); SwitchStatementSyntax newSwitchStatement = switchStatement.WithSections(newSections); StatementsInfo newStatementsInfo = await RefactorAsync( document, statementsInfo, switchStatement, newSwitchStatement, index, switchStatement.Sections.Count, switchStatement.Sections.Any(f => f.ContainsDefaultLabel()), semanticModel, cancellationToken).ConfigureAwait(false); return(await document.ReplaceNodeAsync(statementsInfo.Node, newStatementsInfo.Node, cancellationToken).ConfigureAwait(false)); } } Debug.Fail(statement.Kind().ToString()); return(document); }
public static void AnalyzeLocalDeclarationStatement(SyntaxNodeAnalysisContext context) { if (context.Node.ContainsDiagnostics) { return; } var localDeclaration = (LocalDeclarationStatementSyntax)context.Node; if (localDeclaration.IsConst) { return; } StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(localDeclaration); if (!statementsInfo.Success) { return; } SyntaxList <StatementSyntax> statements = statementsInfo.Statements; if (statements.Count <= 1) { return; } int index = statements.IndexOf(localDeclaration); if (index == statements.Count - 1) { return; } LocalDeclarationStatementInfo localInfo = SyntaxInfo.LocalDeclarationStatementInfo(localDeclaration); if (!localInfo.Success) { return; } ITypeSymbol typeSymbol = context.SemanticModel.GetTypeSymbol(localInfo.Type, context.CancellationToken); if (typeSymbol?.SupportsConstantValue() != true) { return; } foreach (VariableDeclaratorSyntax declarator in localInfo.Variables) { if (!HasConstantValue(declarator.Initializer?.Value, typeSymbol, context.SemanticModel, context.CancellationToken)) { return; } } if (!CanBeMarkedAsConst(localInfo.Variables, statements, index + 1)) { return; } context.ReportDiagnostic(DiagnosticDescriptors.MarkLocalVariableAsConst, localInfo.Type); }