public static void TestAssertingEndText( string sampleClassCode, TextSpan refactoringSiteTextSpan, Action <string> assertion, int refactoringNumber = 0) { TestAsertingRefactorings( sampleClassCode, refactoringSiteTextSpan, (workspace, document, proposedCodeRefactorings) => { CodeAction refactoring = proposedCodeRefactorings.ElementAt(refactoringNumber); CodeActionOperation operation = refactoring .GetOperationsAsync(CancellationToken.None) .Result .Single(); operation.Apply(workspace, CancellationToken.None); Document newDocument = workspace.CurrentSolution.GetDocument(document.Id); SourceText newText = newDocument.GetTextAsync(CancellationToken.None).Result; string text = newText.ToString(); assertion(text); }); }
/// <summary> /// Apply the inputted CodeAction to the inputted document. /// Meant to be used to apply codefixes. /// </summary> /// <param name="document">The Document to apply the fix on</param> /// <param name="codeAction">A CodeAction that will be applied to the Document.</param> /// <returns>A Document with the changes from the CodeAction</returns> private static async Task <Document> ApplyFix(Document document, CodeAction codeAction) { try { var operations = await codeAction.GetOperationsAsync(CancellationToken.None); var solution = operations.OfType <ApplyChangesOperation>().Single().ChangedSolution; return(solution.GetDocument(document.Id)); } catch (AggregateException e) { if (e.InnerExceptions.Count <= 0) { throw; } foreach (var ex in e.InnerExceptions) { Console.WriteLine("Exception thrown during code fix: " + ex.Message); Console.WriteLine(ex.StackTrace.ToString()); } throw; } }
protected override async Task <IEnumerable <CodeActionOperation> > ComputeOperationsAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var previewDialogService = _workspace.Services.GetService <IPreviewDialogService>(); if (previewDialogService == null) { return(null); } var changedSolution = previewDialogService.PreviewChanges( EditorFeaturesResources.PreviewChanges, "vs.codefix.previewchanges", _originalCodeAction.Title, EditorFeaturesResources.PreviewChangesRootNodeText, CodeAnalysis.Glyph.OpenFolder, _changeSummary.NewSolution, _changeSummary.OldSolution, showCheckBoxes: false); if (changedSolution == null) { // User pressed the cancel button. return(null); } cancellationToken.ThrowIfCancellationRequested(); return(await _originalCodeAction.GetOperationsAsync(cancellationToken).ConfigureAwait(false)); }
internal override async Task <ImmutableArray <CodeActionOperation> > GetOperationsCoreAsync(IProgressTracker progressTracker, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var previewDialogService = _workspace.Services.GetService <IPreviewDialogService>(); if (previewDialogService == null) { return(ImmutableArray <CodeActionOperation> .Empty); } var changedSolution = previewDialogService.PreviewChanges( EditorFeaturesResources.Preview_Changes, "vs.codefix.previewchanges", _originalCodeAction.Title, EditorFeaturesResources.Changes, CodeAnalysis.Glyph.OpenFolder, _changeSummary.NewSolution, _changeSummary.OldSolution, showCheckBoxes: false); if (changedSolution == null) { // User pressed the cancel button. return(ImmutableArray <CodeActionOperation> .Empty); } cancellationToken.ThrowIfCancellationRequested(); return(await _originalCodeAction.GetOperationsAsync(cancellationToken).ConfigureAwait(false)); }
public static void CodeAction(CodeAction codeAction, Document document, string expectedCode) { var operations = codeAction.GetOperationsAsync(CancellationToken.None).GetAwaiter().GetResult().ToList(); if (operations.Count == 0) { throw RoslynTestKitException.NoOperationForCodeAction(codeAction); } var workspace = document.Project.Solution.Workspace; foreach (var operation in operations) { operation.Apply(workspace, CancellationToken.None); } var newDocument = workspace.CurrentSolution.GetDocument(document.Id); var sourceText = newDocument.GetTextAsync(CancellationToken.None).GetAwaiter().GetResult(); var actualCode = sourceText.ToString(); if (actualCode != expectedCode) { DiffHelper.TryToReportDiffWithExternalTool(expectedCode, actualCode); var diff = DiffHelper.GenerateInlineDiff(expectedCode, actualCode); throw new TransformedCodeDifferentThanExpectedException(actualCode, expectedCode, diff); } }
/// <summary> /// Apply the inputted CodeAction to the inputted document. /// Meant to be used to apply codefixes. /// </summary> /// <param name="document">The Document to apply the fix on.</param> /// <param name="codeAction">A CodeAction that will be applied to the Document.</param> /// <returns>A Document with the changes from the CodeAction</returns> private static Document ApplyFix(Document document, CodeAction codeAction) { var operations = codeAction.GetOperationsAsync(CancellationToken.None).Result; var solution = operations.OfType <ApplyChangesOperation>().Single().ChangedSolution; return(solution.GetDocument(document.Id)); }
private async Task <Document> ConvertCodeActionToChangedDocument(CodeAction action, CancellationToken cancellationToken) { var operations = await action.GetOperationsAsync(cancellationToken).ConfigureAwait(false); if (operations == null) { return(document); } if (operations.Count() > 1) { Console.WriteLine($"{DiagnosticId} : Only single operation is supported. Operation count = {operations.Count()} : {document.FilePath}"); return(document); } var applyOperation = operations.First() as ApplyChangesOperation; if (applyOperation == null) { return(document); } var changedDocument = applyOperation.ChangedSolution?.Projects?.First()?.GetDocument(document.Id); return(changedDocument != null ? changedDocument : document); }
internal static async void RunAction(DocumentContext context, CodeAction action, CancellationToken cancellationToken) { var operations = await action.GetOperationsAsync(cancellationToken).ConfigureAwait(false); if (operations == null) { return; } foreach (var op in operations) { if (op == null) { continue; } try { op.Apply(context.RoslynWorkspace, cancellationToken); } catch (Exception e) { LoggingService.LogError("Error while appyling operation : " + op, e); } } if ((bool)hasCodeActionsProperty.GetValue(action)) { var result = (ImmutableArray <CodeAction>)getCodeActionsMethod.Invoke(action, null); foreach (var nested in result) { RunAction(context, nested, cancellationToken); } } }
/// <summary> /// Apply the inputted CodeAction to the inputted document. /// Meant to be used to apply codefixes. /// </summary> /// <param name="document">The Document to apply the fix on</param> /// <param name="codeAction">A CodeAction that will be applied to the Document.</param> /// <returns>A Document with the changes from the CodeAction</returns> private Document ApplyFix(Document document, CodeAction codeAction) { ImmutableArray <CodeActionOperation> operations = codeAction.GetOperationsAsync(CancellationToken.None).Result; Solution solution = operations.OfType <ApplyChangesOperation>().Single().ChangedSolution; return(solution.GetDocument(document.Id)); }
internal static async Task RunAction(DocumentContext context, CodeAction action, CancellationToken cancellationToken) { var operations = await action.GetOperationsAsync(cancellationToken).ConfigureAwait(false); if (operations == null) { return; } foreach (var op in operations) { if (op == null) { continue; } try { op.Apply(context.RoslynWorkspace, cancellationToken); } catch (Exception e) { LoggingService.LogError("Error while applying operation : " + op, e); } } foreach (var nested in action.NestedCodeActions) { await RunAction(context, nested, cancellationToken).ConfigureAwait(false); } }
private async Task <string> ExecuteTest(string sourceCode) { var(diagnostic, document, workspace) = await TestSetup.SetupAsync(sourceCode); var codeFixProvider = new JsonAnalyzerCodeFixProvider(); CodeAction codeAction = null; if (!diagnostic.Any()) { return((await document.GetTextAsync(CancellationToken.None)).ToString()); } var context = new CodeFixContext(document, diagnostic[0], (action, _) => { codeAction = action; }, CancellationToken.None); await codeFixProvider.RegisterCodeFixesAsync(context); if (codeAction == null) { throw new Exception("Code action was not registered"); } var operations = await codeAction.GetOperationsAsync(CancellationToken.None); foreach (var operation in operations) { operation.Apply(workspace, CancellationToken.None); } var updateDocument = workspace.CurrentSolution.GetDocument(document.Id); var actual = (await updateDocument !.GetTextAsync()).ToString(); return(actual); }
protected void Test( string markup, string expected, int actionIndex = 0, bool compareTokens = false) { if (!markup.Contains('\r')) { markup = markup.Replace("\n", "\r\n"); } if (!expected.Contains('\r')) { expected = expected.Replace("\n", "\r\n"); } MarkupTestFile.GetSpan(markup, out string code, out TextSpan span); Document document = CreateDocument(code); IEnumerable <CodeAction> actions = GetRefactoring(document, span); Assert.NotNull(actions); CodeAction action = actions.ElementAt(actionIndex); Assert.NotNull(action); ApplyChangesOperation edit = action.GetOperationsAsync(CancellationToken.None).Result.OfType <ApplyChangesOperation>().First(); VerifyDocument(expected, compareTokens, edit.ChangedSolution.GetDocument(document.Id)); }
public static void CodeAction(CodeAction codeAction, Document document, string expectedCode) { var operations = codeAction.GetOperationsAsync(CancellationToken.None).GetAwaiter().GetResult().ToList(); if (operations.Count == 0) { throw RoslynTestKitException.NoOperationForCodeAction(codeAction); } if (operations.Count > 1) { throw RoslynTestKitException.MoreThanOneOperationForCodeAction(codeAction, operations); } var operation = operations.Single(); var workspace = document.Project.Solution.Workspace; operation.Apply(workspace, CancellationToken.None); var newDocument = workspace.CurrentSolution.GetDocument(document.Id); var sourceText = newDocument.GetTextAsync(CancellationToken.None).GetAwaiter().GetResult(); var text = sourceText.ToString(); if (text != expectedCode) { TryToReportDiff(expectedCode, text); throw new TransformedCodeDifferentThanExpectedException(text, expectedCode); } }
private async Task TestFixAllAsync(int codepage, FixAllScope scope) { string[] testCode = new[] { "class Foo { }", "class Bar { }" }; this.fileEncoding = Encoding.GetEncoding(codepage); // Create a project using the specified encoding Project project = this.CreateProject(testCode); Project oldProject = project; Workspace workspace = project.Solution.Workspace; var codeFixer = this.GetCSharpCodeFixProvider(); var fixAllProvider = codeFixer.GetFixAllProvider(); var diagnostics = new List <Diagnostic>(); var descriptor = this.GetCSharpDiagnosticAnalyzers().First().SupportedDiagnostics.First(); foreach (var document in project.Documents) { // Create a diagnostic for the document to fix var diagnostic = Diagnostic.Create( descriptor, Location.Create(await document.GetSyntaxTreeAsync().ConfigureAwait(false), TextSpan.FromBounds(0, 0))); diagnostics.Add(diagnostic); } FixAllContext fixAllContext = new FixAllContext( project.Documents.First(), codeFixer, scope, nameof(SA1412CodeFixProvider) + "." + this.fileEncoding.WebName, new[] { SA1412StoreFilesAsUtf8.DiagnosticId }, TestDiagnosticProvider.Create(diagnostics.ToImmutableArray()), CancellationToken.None); CodeAction codeAction = await fixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false); var operation = codeAction.GetOperationsAsync(CancellationToken.None).ConfigureAwait(false).GetAwaiter().GetResult()[0]; operation.Apply(workspace, CancellationToken.None); // project should now have the "fixed document" in it. // Because of limitations in roslyn the fixed document should // have a different DocumentId then the broken document project = workspace.CurrentSolution.Projects.First(); Assert.Equal(2, project.DocumentIds.Count); for (int i = 0; i < project.DocumentIds.Count; i++) { DocumentId documentId = project.DocumentIds[i]; SourceText sourceText = await project.GetDocument(documentId).GetTextAsync().ConfigureAwait(false); Assert.Equal(testCode[i], sourceText.ToString()); Assert.Equal(Encoding.UTF8, sourceText.Encoding); Assert.NotEqual(oldProject.DocumentIds[i], project.DocumentIds[i]); } }
/// <summary> /// Apply the inputted <see cref="CodeAction"/> to the inputted document. /// Meant to be used to apply code fixes. /// </summary> /// <param name="project">The <see cref="Project"/> to apply the fix on</param> /// <param name="codeAction">A <see cref="CodeAction"/> that will be applied to the /// <paramref name="project"/>.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that the task will observe.</param> /// <returns>A <see cref="Project"/> with the changes from the <see cref="CodeAction"/>.</returns> private static async Task <Project> ApplyFixAsync(Project project, CodeAction codeAction, CancellationToken cancellationToken) { var operations = await codeAction.GetOperationsAsync(cancellationToken).ConfigureAwait(false); var solution = operations.OfType <ApplyChangesOperation>().Single().ChangedSolution; return(solution.GetProject(project.Id)); }
public async Task <Document> ApplyRefactoring(Document originalDocument, CodeAction codeAction) { var operations = await codeAction.GetOperationsAsync(default(CancellationToken)); var solution = operations.OfType <ApplyChangesOperation>().Single().ChangedSolution; return(solution.GetDocument(originalDocument.Id)); }
/// <summary> /// Apply the inputted CodeAction to the inputted document. /// Meant to be used to apply codefixes. /// </summary> /// <param name="document">The Document to apply the fix on</param> /// <param name="codeAction">A CodeAction that will be applied to the Document.</param> /// <returns>A Document with the changes from the CodeAction</returns> private static async Task <Document> ApplyFixAsync(Document document, CodeAction codeAction) { var operations = await codeAction.GetOperationsAsync(CancellationToken.None); var solution = operations.OfType <ApplyChangesOperation>().Single().ChangedSolution; return(solution.GetDocument(document.Id)); }
public static async Task <Document> ApplyChanges(this Document document, CodeAction codeAction, CancellationToken cancellationToken = default) { var operations = await codeAction.GetOperationsAsync(cancellationToken); var solution = operations.OfType <ApplyChangesOperation>().Single().ChangedSolution; return(solution.GetDocument(document.Id)); }
private static async Task ApplyActions(AdhocWorkspace workspace, CodeAction action, CancellationTokenSource cts) { var operations = await action.GetOperationsAsync(cts.Token); foreach (var operation in operations) { operation.Apply(workspace, cts.Token); } }
private async Task ExecuteCodeAction(CodeAction codeAction) { var operations = await codeAction.GetOperationsAsync(CancellationToken.None).ConfigureAwait(true); foreach (var operation in operations) { operation.Apply(_roslynHost.GetDocument(_documentId).Project.Solution.Workspace, CancellationToken.None); } }
public static async Task <Document> ApplyCodeAction(this Document document, CodeAction codeAction) { var operations = await codeAction.GetOperationsAsync(CancellationToken.None).ConfigureAwait(false); return(operations .OfType <ApplyChangesOperation>() .Single() .ChangedSolution .GetDocument(document.Id)); }
protected Task <ImmutableArray <CodeActionOperation> > GetOperationsAsync( IProgressTracker progressTracker, CancellationToken cancellationToken ) { return(Task.Run( () => CodeAction.GetOperationsAsync(progressTracker, cancellationToken), cancellationToken )); }
public static Document ApplyCodeAction(this Document document, CodeAction codeAction) { return(codeAction .GetOperationsAsync(CancellationToken.None) .Result .OfType <ApplyChangesOperation>() .Single() .ChangedSolution .GetDocument(document.Id)); }
public static async Task <Document> ApplyCodeActionAsync(this Document document, CodeAction codeAction) { ImmutableArray <CodeActionOperation> operations = await codeAction.GetOperationsAsync(CancellationToken.None); return(operations .OfType <ApplyChangesOperation>() .Single() .ChangedSolution .GetDocument(document.Id)); }
internal static Task <ImmutableArray <CodeActionOperation> > VerifyActionAndGetOperationsAsync( CodeAction action, TestParameters parameters) { Assert.NotNull(action); if (parameters.priority != null) { Assert.Equal(parameters.priority.Value, action.Priority); } return(action.GetOperationsAsync(CancellationToken.None)); }
internal static Task <ImmutableArray <CodeActionOperation> > VerifyActionAndGetOperationsAsync( CodeAction action, TestParameters parameters) { Assert.False(action is null, "No action was offered when one was expected."); if (parameters.priority != null) { Assert.Equal(parameters.priority.Value, action.Priority); } return(action.GetOperationsAsync(CancellationToken.None)); }
internal async Task <ImmutableArray <CodeActionOperation> > GetOperationsAsync(CancellationToken cancellationToken = default(CancellationToken)) { Diagnostic diagnostic = this.DiagnosticsToFix.First(); Document document = this.Solution.GetDocument(diagnostic.Location.SourceTree); var diagnosticsProvider = TesterDiagnosticProvider.Create(this.DiagnosticsToFix); var context = new FixAllContext(document, this.CodeFixProvider, FixAllScope.Solution, this.CodeFixEquivalenceKey, this.DiagnosticsToFix.Select(x => x.Id), diagnosticsProvider, cancellationToken); CodeAction action = await this.FixAllProvider.GetFixAsync(context).ConfigureAwait(false); return(await action.GetOperationsAsync(cancellationToken).ConfigureAwait(false)); }
internal async Task <ImmutableArray <CodeActionOperation> > GetOperationsAsync(CancellationToken cancellationToken) { Diagnostic diagnostic = this.DocumentDiagnosticsToFix.Values.SelectMany(i => i.Values).Concat(this.ProjectDiagnosticsToFix.Values).First().First(); Document document = this.Solution.GetDocument(diagnostic.Location.SourceTree); HashSet <string> diagnosticIds = new HashSet <string>(this.DocumentDiagnosticsToFix.Values.SelectMany(i => i.Values).Concat(this.ProjectDiagnosticsToFix.Values).SelectMany(i => i.Select(j => j.Id))); var diagnosticsProvider = new TesterDiagnosticProvider(this.DocumentDiagnosticsToFix, this.ProjectDiagnosticsToFix); var context = new FixAllContext(document, this.CodeFixProvider, FixAllScope.Solution, this.CodeFixEquivalenceKey, diagnosticIds, diagnosticsProvider, cancellationToken); CodeAction action = await this.FixAllProvider.GetFixAsync(context).ConfigureAwait(false); return(await action.GetOperationsAsync(cancellationToken).ConfigureAwait(false)); }
private async Task <IEnumerable <CodeActionOperation> > GetFixAllOperationsAsync(CodeAction codeAction, FixAllContext fixAllContext) { // We have computed the fix all occurrences code fix. // Now fetch the new solution with applied fix and bring up the Preview changes dialog. var cancellationToken = fixAllContext.CancellationToken; var workspace = fixAllContext.Project.Solution.Workspace; cancellationToken.ThrowIfCancellationRequested(); var operations = await codeAction.GetOperationsAsync(cancellationToken).ConfigureAwait(false); if (operations == null) { return(null); } cancellationToken.ThrowIfCancellationRequested(); var newSolution = await codeAction.GetChangedSolutionInternalAsync(cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesPreviewChanges, cancellationToken)) { var previewService = workspace.Services.GetService <IPreviewDialogService>(); var glyph = fixAllContext.Project.Language == LanguageNames.CSharp ? Glyph.CSharpProject : Glyph.BasicProject; var changedSolution = previewService.PreviewChanges( string.Format(EditorFeaturesResources.PreviewChangesOf, EditorFeaturesResources.FixAllOccurrences), "vs.codefix.fixall", codeAction.Title, EditorFeaturesResources.FixAllOccurrences, glyph, newSolution, fixAllContext.Project.Solution); if (changedSolution == null) { // User clicked cancel. FixAllLogger.LogPreviewChangesResult(applied: false); return(null); } FixAllLogger.LogPreviewChangesResult(applied: true, allChangesApplied: changedSolution == newSolution); newSolution = changedSolution; } // Get a code action, with apply changes operation replaced with the newSolution. return(GetNewFixAllOperations(operations, newSolution, cancellationToken)); }
/// <summary> /// Apply the inputted <see cref="CodeAction"/> to the inputted document. /// Meant to be used to apply code fixes. /// </summary> /// <param name="project">The <see cref="Project"/> to apply the code action on.</param> /// <param name="codeAction">A <see cref="CodeAction"/> that will be applied to the /// <paramref name="project"/>.</param> /// <param name="verifier">The verifier to use for test assertions.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that the task will observe.</param> /// <returns>A <see cref="Project"/> with the changes from the <see cref="CodeAction"/>.</returns> protected async Task <Project> ApplyCodeActionAsync(Project project, CodeAction codeAction, IVerifier verifier, CancellationToken cancellationToken) { var operations = await codeAction.GetOperationsAsync(cancellationToken).ConfigureAwait(false); var solution = operations.OfType <ApplyChangesOperation>().Single().ChangedSolution; var changedProject = solution.GetProject(project.Id); if (changedProject != project) { project = await RecreateProjectDocumentsAsync(changedProject, verifier, cancellationToken).ConfigureAwait(false); } return(project); }