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 static Task <Document> RefactorAsync( Document document, ObjectCreationExpressionSyntax objectCreation, StatementsSelection selectedStatements, CancellationToken cancellationToken = default(CancellationToken)) { StatementsInfo statementsInfo = selectedStatements.Info; ExpressionStatementSyntax[] expressionStatements = selectedStatements .Skip(1) .Cast <ExpressionStatementSyntax>() .ToArray(); StatementSyntax firstStatement = selectedStatements.First(); SyntaxList <StatementSyntax> newStatements = statementsInfo.Statements.Replace( firstStatement, firstStatement.ReplaceNode( objectCreation, objectCreation.WithInitializer(CreateInitializer(objectCreation, expressionStatements)))); int count = expressionStatements.Length; int index = selectedStatements.StartIndex + 1; while (count > 0) { newStatements = newStatements.RemoveAt(index); count--; } return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken)); }
public static ImmutableArray <IfRefactoring> Analyze( StatementsSelection selectedStatements, SemanticModel semanticModel, CancellationToken cancellationToken) { return(Analyze(selectedStatements, DefaultOptions, semanticModel, cancellationToken)); }
private static bool VerifyLocalDeclarationStatements( StatementsSelection selectedStatements, SemanticModel semanticModel, CancellationToken cancellationToken) { SyntaxList <StatementSyntax> statements = selectedStatements.Statements; ITypeSymbol typeSymbol = null; for (int i = selectedStatements.StartIndex; i < selectedStatements.EndIndex; i++) { StatementSyntax statement = statements[i]; if (!(statement is LocalDeclarationStatementSyntax localDeclaration)) { return(false); } VariableDeclarationSyntax declaration = localDeclaration.Declaration; foreach (VariableDeclaratorSyntax variable in declaration.Variables) { var symbol = (ILocalSymbol)semanticModel.GetDeclaredSymbol(variable, cancellationToken); if (symbol == null) { continue; } if (symbol.Type.IsErrorType()) { continue; } if (typeSymbol == null) { typeSymbol = symbol.Type; } else if (!typeSymbol.Equals(symbol.Type)) { return(false); } for (int j = selectedStatements.EndIndex + 1; j < statements.Count; j++) { foreach (SyntaxNode node in statements[j].DescendantNodes()) { if (node.IsKind(SyntaxKind.IdentifierName) && symbol.Equals(semanticModel.GetSymbol(node, cancellationToken))) { return(false); } } } } } return(true); }
public static ImmutableArray <IfRefactoring> Analyze( StatementsSelection selectedStatements, IfAnalysisOptions options, SemanticModel semanticModel, CancellationToken cancellationToken) { if (selectedStatements.Count != 2) { return(Empty); } StatementSyntax[] statements = selectedStatements.ToArray(); StatementSyntax statement1 = statements[0]; StatementSyntax statement2 = statements[1]; if (statement1.ContainsDiagnostics) { return(Empty); } if (statement2.ContainsDiagnostics) { return(Empty); } SyntaxKind kind1 = statement1.Kind(); SyntaxKind kind2 = statement2.Kind(); if (kind1 == SyntaxKind.IfStatement) { if (kind2 == SyntaxKind.ReturnStatement) { var ifStatement = (IfStatementSyntax)statement1; if (ifStatement.IsSimpleIf()) { return(Analyze(ifStatement, (ReturnStatementSyntax)statement2, options, semanticModel, cancellationToken)); } } } else if (options.UseConditionalExpression) { if (kind1 == SyntaxKind.LocalDeclarationStatement) { if (kind2 == SyntaxKind.IfStatement) { return(Analyze((LocalDeclarationStatementSyntax)statement1, (IfStatementSyntax)statement2, options)); } } else if (kind1 == SyntaxKind.ExpressionStatement && kind2 == SyntaxKind.IfStatement) { return(Analyze((ExpressionStatementSyntax)statement1, (IfStatementSyntax)statement2, options)); } } return(Empty); }
public static async Task ComputeRefactoringAsync(RefactoringContext context, BlockSyntax block) { if (SelectedStatementsRefactoring.IsAnyRefactoringEnabled(context) && StatementsSelection.TryCreate(block, context.Span, out StatementsSelection selectedStatements)) { await SelectedStatementsRefactoring.ComputeRefactoringAsync(context, selectedStatements).ConfigureAwait(false); } }
public static async Task ComputeRefactoringAsync(RefactoringContext context, StatementsSelection selectedStatements) { if (!(selectedStatements.LastOrDefault() is WhileStatementSyntax whileStatement)) { return; } if (selectedStatements.Count == 1) { context.RegisterRefactoring( Title, cancellationToken => RefactorAsync(context.Document, whileStatement, cancellationToken)); } else { switch (selectedStatements.First().Kind()) { case SyntaxKind.LocalDeclarationStatement: { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (VerifyLocalDeclarationStatements(selectedStatements, semanticModel, context.CancellationToken)) { List <LocalDeclarationStatementSyntax> localDeclarations = selectedStatements .Take(selectedStatements.Count - 1) .Cast <LocalDeclarationStatementSyntax>() .ToList(); context.RegisterRefactoring( Title, cancellationToken => RefactorAsync(context.Document, whileStatement, localDeclarations, cancellationToken)); } break; } case SyntaxKind.ExpressionStatement: { if (VerifyExpressionStatements(selectedStatements)) { List <ExpressionStatementSyntax> expressionStatements = selectedStatements .Take(selectedStatements.Count - 1) .Cast <ExpressionStatementSyntax>() .ToList(); context.RegisterRefactoring( Title, cancellationToken => RefactorAsync(context.Document, whileStatement, expressionStatements, cancellationToken)); } break; } } } }
public static void ComputeRefactorings(RefactoringContext context, StatementsSelection selectedStatements) { List <IfStatementSyntax> ifStatements = GetIfStatements(selectedStatements); if (ifStatements?.Count > 1) { context.RegisterRefactoring( "Merge if statements", cancellationToken => { return(RefactorAsync( context.Document, selectedStatements.Info, ifStatements.ToImmutableArray(), cancellationToken)); }); } }
public static void ComputeRefactorings(RefactoringContext context, StatementsSelection selectedStatements) { using (IEnumerator <StatementSyntax> en = selectedStatements.GetEnumerator()) { if (en.MoveNext() && en.Current.IsKind(SyntaxKind.ExpressionStatement)) { var statement = (ExpressionStatementSyntax)en.Current; if (statement.Expression?.IsKind(SyntaxKind.SimpleAssignmentExpression) == true && en.MoveNext() && en.Current.IsKind(SyntaxKind.ReturnStatement)) { var returnStatement = (ReturnStatementSyntax)en.Current; if (returnStatement.Expression != null && !en.MoveNext()) { var assignment = (AssignmentExpressionSyntax)statement.Expression; if (assignment.Left?.IsMissing == false && assignment.Right?.IsMissing == false && SyntaxComparer.AreEquivalent(assignment.Left, returnStatement.Expression)) { context.RegisterRefactoring( "Merge statements", cancellationToken => { return(RefactorAsync( context.Document, statement, returnStatement, cancellationToken)); }); } } } } } }
public async Task ComputeRefactoringAsync(RefactoringContext context, StatementsSelection selectedStatements) { SingleLocalDeclarationStatementInfo localInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo(selectedStatements.FirstOrDefault() as LocalDeclarationStatementSyntax); if (!localInfo.Success) { return; } ExpressionSyntax value = localInfo.Initializer?.Value; if (value == null) { return; } if (value.Kind() == SyntaxKind.DefaultExpression) { return; } if (value is LiteralExpressionSyntax) { return; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); var typeSymbol = semanticModel.GetTypeSymbol(localInfo.Type, context.CancellationToken) as INamedTypeSymbol; if (typeSymbol?.Implements(SpecialType.System_IDisposable) != true) { return; } context.RegisterRefactoring( $"Using '{localInfo.IdentifierText}'", cancellationToken => RefactorAsync(context.Document, selectedStatements, cancellationToken)); }
public Task <Document> RefactorAsync( Document document, StatementsSelection selectedStatements, CancellationToken cancellationToken = default(CancellationToken)) { StatementsInfo statementsInfo = selectedStatements.Info; StatementSyntax[] statements = selectedStatements.ToArray(); int index = selectedStatements.StartIndex; SyntaxTriviaList leadingTrivia = statements[0].GetLeadingTrivia(); SyntaxTriviaList trailingTrivia = statements[statements.Length - 1].GetTrailingTrivia(); statements[0] = statements[0].WithLeadingTrivia(); statements[statements.Length - 1] = statements[statements.Length - 1].WithTrailingTrivia(); SyntaxList <StatementSyntax> newStatements = statementsInfo.Statements; int cnt = statements.Length; while (cnt > 0) { newStatements = newStatements.RemoveAt(index); cnt--; } TStatement statement = CreateStatement(statements.ToImmutableArray()); statement = statement .WithLeadingTrivia(leadingTrivia) .WithTrailingTrivia(trailingTrivia) .WithFormatterAnnotation(); newStatements = newStatements.Insert(index, statement); return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken)); }
private static bool VerifyExpressionStatements(StatementsSelection selectedStatements) { for (int i = selectedStatements.StartIndex; i < selectedStatements.EndIndex; i++) { StatementSyntax statement = selectedStatements.Statements[i]; if (!(statement is ExpressionStatementSyntax expressionStatement)) { return(false); } if (!CanBeInitializer(expressionStatement.Expression)) { return(false); } } return(true); bool CanBeInitializer(ExpressionSyntax expression) { switch (expression.Kind()) { case SyntaxKind.SimpleAssignmentExpression: case SyntaxKind.InvocationExpression: case SyntaxKind.PreIncrementExpression: case SyntaxKind.PreDecrementExpression: case SyntaxKind.PostIncrementExpression: case SyntaxKind.PostDecrementExpression: case SyntaxKind.ObjectCreationExpression: case SyntaxKind.AwaitExpression: return(true); default: return(false); } } }
private static Task <Document> RefactorAsync( Document document, IfStatementSyntax ifStatement, StatementsSelection selectedStatements, CancellationToken cancellationToken) { IfStatementInfo ifStatementInfo = SyntaxInfo.IfStatementInfo(ifStatement); StatementSyntax newStatement = null; if (selectedStatements.Count == 1 && !ifStatementInfo.Nodes.Any(f => f.Statement?.IsKind(SyntaxKind.Block) == true)) { newStatement = selectedStatements.First(); } else { newStatement = SyntaxFactory.Block(selectedStatements); } ElseClauseSyntax elseClause = SyntaxFactory.ElseClause(newStatement).WithFormatterAnnotation(); IfStatementSyntax lastIfStatement = ifStatementInfo.Nodes.Last(); IfStatementSyntax newIfStatement = ifStatement.ReplaceNode( lastIfStatement, lastIfStatement.WithElse(elseClause)); SyntaxList <StatementSyntax> newStatements = selectedStatements.Statements.Replace(ifStatement, newIfStatement); for (int i = newStatements.Count - 1; i >= selectedStatements.StartIndex; i--) { newStatements = newStatements.RemoveAt(i); } return(document.ReplaceStatementsAsync(selectedStatements.Info, newStatements, cancellationToken)); }
public static void ComputeRefactoring(RefactoringContext context, StatementsSelection selectedStatements) { StatementSyntax lastStatement = selectedStatements.Last(); if (lastStatement.IsKind(SyntaxKind.ReturnStatement) && selectedStatements.EndIndex == selectedStatements.Statements.IndexOf(lastStatement) && selectedStatements.StartIndex > 0) { var returnStatement = (ReturnStatementSyntax)lastStatement; ExpressionSyntax expression = returnStatement.Expression; if (expression != null) { StatementSyntax prevStatement = selectedStatements.Statements[selectedStatements.StartIndex - 1]; if (prevStatement.IsKind(SyntaxKind.IfStatement)) { var ifStatement = (IfStatementSyntax)prevStatement; IfStatementInfo ifStatementInfo = SyntaxInfo.IfStatementInfo(ifStatement); if (ifStatementInfo.EndsWithIf && ifStatementInfo .Nodes .Where(f => f.IsIf) .All(f => IsLastStatementReturnStatement(f))) { context.RegisterRefactoring( "Wrap in else clause", cancellationToken => RefactorAsync(context.Document, ifStatement, selectedStatements, cancellationToken)); } } } } }
public static async Task ComputeRefactoringAsync(RefactoringContext context, StatementsSelection selectedStatements) { if (selectedStatements.Any()) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.WrapInUsingStatement)) { var refactoring = new WrapStatements.WrapInUsingStatementRefactoring(); await refactoring.ComputeRefactoringAsync(context, selectedStatements).ConfigureAwait(false); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.CollapseToInitializer)) { await CollapseToInitializerRefactoring.ComputeRefactoringsAsync(context, selectedStatements).ConfigureAwait(false); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.MergeIfStatements)) { MergeIfStatementsRefactoring.ComputeRefactorings(context, selectedStatements); } 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 (IfRefactoring refactoring in IfRefactoring.Analyze(selectedStatements, options, semanticModel, context.CancellationToken)) { context.RegisterRefactoring( refactoring.Title, cancellationToken => refactoring.RefactorAsync(context.Document, cancellationToken)); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.MergeLocalDeclarations)) { await MergeLocalDeclarationsRefactoring.ComputeRefactoringsAsync(context, selectedStatements).ConfigureAwait(false); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.MergeAssignmentExpressionWithReturnStatement)) { MergeAssignmentExpressionWithReturnStatementRefactoring.ComputeRefactorings(context, selectedStatements); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.CheckExpressionForNull)) { await CheckExpressionForNullRefactoring.ComputeRefactoringAsync(context, selectedStatements).ConfigureAwait(false); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceWhileWithFor)) { await ReplaceWhileWithForRefactoring.ComputeRefactoringAsync(context, selectedStatements).ConfigureAwait(false); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.WrapInElseClause)) { WrapInElseClauseRefactoring.ComputeRefactoring(context, selectedStatements); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.WrapInCondition)) { context.RegisterRefactoring( WrapInIfStatementRefactoring.Title, cancellationToken => { var refactoring = new WrapInIfStatementRefactoring(); return(refactoring.RefactorAsync(context.Document, selectedStatements, cancellationToken)); }); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.WrapInTryCatch)) { context.RegisterRefactoring( WrapInTryCatchRefactoring.Title, cancellationToken => { var refactoring = new WrapInTryCatchRefactoring(); return(refactoring.RefactorAsync(context.Document, selectedStatements, cancellationToken)); }); } } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, StatementsSelection selectedStatements) { if (selectedStatements.Count > 1) { StatementSyntax firstStatement = selectedStatements.First(); SemanticModel semanticModel = null; ISymbol symbol = null; ObjectCreationExpressionSyntax objectCreation = null; SyntaxKind kind = firstStatement.Kind(); if (kind == SyntaxKind.LocalDeclarationStatement) { var localDeclaration = (LocalDeclarationStatementSyntax)firstStatement; VariableDeclaratorSyntax variable = localDeclaration .Declaration? .Variables .SingleOrDefault(shouldthrow: false); objectCreation = variable?.Initializer?.Value as ObjectCreationExpressionSyntax; if (objectCreation != null) { semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); symbol = semanticModel.GetDeclaredSymbol(variable, context.CancellationToken); } } else if (kind == SyntaxKind.ExpressionStatement) { var expressionStatement = (ExpressionStatementSyntax)firstStatement; if (expressionStatement.Expression is AssignmentExpressionSyntax assignment) { objectCreation = assignment.Right as ObjectCreationExpressionSyntax; if (objectCreation != null) { semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); symbol = semanticModel.GetSymbol(assignment.Left, context.CancellationToken); } } } if (objectCreation != null && symbol?.IsErrorType() == false && selectedStatements .Skip(1) .All(f => IsValidAssignmentStatement(f, symbol, semanticModel, context.CancellationToken))) { context.RegisterRefactoring( "Collapse to initializer", cancellationToken => { return(RefactorAsync( context.Document, objectCreation, selectedStatements, cancellationToken)); }); } } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, SwitchSectionSyntax switchSection) { if (SelectedStatementsRefactoring.IsAnyRefactoringEnabled(context) && StatementsSelection.TryCreate(switchSection, context.Span, out StatementsSelection selectedStatements)) { await SelectedStatementsRefactoring.ComputeRefactoringAsync(context, selectedStatements).ConfigureAwait(false); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.SplitSwitchLabels)) { SplitSwitchLabelsRefactoring.ComputeRefactoring(context, switchSection); } if (context.Span.IsEmpty && context.IsAnyRefactoringEnabled( RefactoringIdentifiers.AddBracesToSwitchSection, RefactoringIdentifiers.AddBracesToSwitchSections, RefactoringIdentifiers.RemoveBracesFromSwitchSection, RefactoringIdentifiers.RemoveBracesFromSwitchSections)) { var switchStatement = (SwitchStatementSyntax)switchSection.Parent; SyntaxList <SwitchSectionSyntax> sections = switchStatement.Sections; switch (CSharpAnalysis.AnalyzeBraces(switchSection)) { case BracesAnalysisResult.AddBraces: { if (context.IsRefactoringEnabled(RefactoringIdentifiers.AddBracesToSwitchSection)) { context.RegisterRefactoring( AddBracesToSwitchSectionRefactoring.Title, cancellationToken => AddBracesToSwitchSectionRefactoring.RefactorAsync(context.Document, switchSection, cancellationToken)); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.AddBracesToSwitchSections) && sections.Any(f => f != switchSection && AddBracesToSwitchSectionRefactoring.CanAddBraces(f))) { context.RegisterRefactoring( AddBracesToSwitchSectionsRefactoring.Title, cancellationToken => AddBracesToSwitchSectionsRefactoring.RefactorAsync(context.Document, switchStatement, null, cancellationToken)); } break; } case BracesAnalysisResult.RemoveBraces: { if (context.IsRefactoringEnabled(RefactoringIdentifiers.RemoveBracesFromSwitchSection)) { context.RegisterRefactoring( RemoveBracesFromSwitchSectionRefactoring.Title, cancellationToken => RemoveBracesFromSwitchSectionRefactoring.RefactorAsync(context.Document, switchSection, cancellationToken)); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.RemoveBracesFromSwitchSections) && sections.Any(f => f != switchSection && RemoveBracesFromSwitchSectionRefactoring.CanRemoveBraces(f))) { context.RegisterRefactoring( RemoveBracesFromSwitchSectionsRefactoring.Title, cancellationToken => RemoveBracesFromSwitchSectionsRefactoring.RefactorAsync(context.Document, switchStatement, null, cancellationToken)); } break; } } } }
internal static async Task ComputeRefactoringAsync(RefactoringContext context, StatementsSelection selectedStatements) { if (selectedStatements.Count <= 1) { return; } StatementSyntax statement = selectedStatements.First(); SyntaxKind kind = statement.Kind(); if (kind == SyntaxKind.LocalDeclarationStatement) { var localDeclaration = (LocalDeclarationStatementSyntax)statement; SingleLocalDeclarationStatementInfo localInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo(localDeclaration); SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (!CanRefactor(localInfo, semanticModel, context.CancellationToken)) { return; } RegisterRefactoring(context, IdentifierName(localInfo.Identifier), localDeclaration, selectedStatements.Count - 1); } else if (kind == SyntaxKind.ExpressionStatement) { var expressionStatement = (ExpressionStatementSyntax)statement; SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(expressionStatement); SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (!CanRefactor(assignmentInfo, assignmentInfo.Left, semanticModel, context.CancellationToken)) { return; } RegisterRefactoring(context, assignmentInfo.Left, expressionStatement, selectedStatements.Count - 1); } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, StatementsSelection selectedStatements) { if (selectedStatements.Count > 1) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (AreLocalDeclarations(selectedStatements, semanticModel, context.CancellationToken)) { context.RegisterRefactoring( "Merge local declarations", cancellationToken => { return(RefactorAsync( context.Document, selectedStatements.Info, selectedStatements.Cast <LocalDeclarationStatementSyntax>().ToArray(), cancellationToken)); }); } } }