/// <summary> /// Gets, filters, and orders code fixes. /// </summary> public static async ValueTask <ImmutableArray <UnifiedSuggestedActionSet> > GetFilterAndOrderCodeFixesAsync( Workspace workspace, ICodeFixService codeFixService, Document document, TextSpan selection, CodeActionRequestPriority priority, CodeActionOptions options, Func <string, IDisposable?> addOperationScope, CancellationToken cancellationToken) { // Intentionally switch to a threadpool thread to compute fixes. We do not want to accidentally // run any of this on the UI thread and potentially allow any code to take a dependency on that. var fixes = await Task.Run(() => codeFixService.GetFixesAsync( document, selection, priority, options, addOperationScope, cancellationToken), cancellationToken).ConfigureAwait(false); var filteredFixes = fixes.WhereAsArray(c => c.Fixes.Length > 0); var organizedFixes = await OrganizeFixesAsync(workspace, filteredFixes, cancellationToken).ConfigureAwait(false); return(organizedFixes); }
/// <inheritdoc/> public async Task <Solution> SyncNamespacesAsync( ImmutableArray <Project> projects, CodeActionOptions options, CancellationToken cancellationToken) { // all projects must be of the same language Debug.Assert(projects.All(project => project.Language == projects[0].Language)); var solution = projects[0].Solution; var diagnosticAnalyzers = ImmutableArray.Create <DiagnosticAnalyzer>(DiagnosticAnalyzer); var diagnosticsByProject = await GetDiagnosticsByProjectAsync(projects, diagnosticAnalyzers, cancellationToken).ConfigureAwait(false); // If no diagnostics are reported, then there is nothing to fix. if (diagnosticsByProject.Values.All(diagnostics => diagnostics.IsEmpty)) { return(solution); } var fixAllContext = await GetFixAllContextAsync(solution, CodeFixProvider, diagnosticsByProject, options, cancellationToken).ConfigureAwait(false); var fixAllProvider = CodeFixProvider.GetFixAllProvider(); RoslynDebug.AssertNotNull(fixAllProvider); return(await ApplyCodeFixAsync(fixAllProvider, fixAllContext, cancellationToken).ConfigureAwait(false)); }
internal TestParameters( ParseOptions parseOptions = null, CompilationOptions compilationOptions = null, OptionsCollection options = null, CodeActionOptions?codeActionOptions = null, IdeAnalyzerOptions?ideAnalyzerOptions = null, object fixProviderData = null, int index = 0, CodeActionPriority?priority = null, bool retainNonFixableDiagnostics = false, bool includeDiagnosticsOutsideSelection = false, string title = null, TestHost testHost = TestHost.InProcess, string workspaceKind = null) { this.parseOptions = parseOptions; this.compilationOptions = compilationOptions; this.options = options; this.codeActionOptions = codeActionOptions ?? CodeActionOptions.Default; #if CODE_STYLE this.ideAnalyzerOptions = ideAnalyzerOptions ?? IdeAnalyzerOptions.CodeStyleDefault; #else this.ideAnalyzerOptions = ideAnalyzerOptions ?? IdeAnalyzerOptions.Default; #endif this.fixProviderData = fixProviderData; this.index = index; this.priority = priority; this.retainNonFixableDiagnostics = retainNonFixableDiagnostics; this.includeDiagnosticsOutsideSelection = includeDiagnosticsOutsideSelection; this.title = title; this.testHost = testHost; this.workspaceKind = workspaceKind; }
public async Task <Document> CleanupAsync( Document document, EnabledDiagnosticOptions enabledDiagnostics, IProgressTracker progressTracker, CodeActionOptions options, SyntaxFormattingOptions formattingOptions, CancellationToken cancellationToken) { // add one item for the 'format' action we'll do last if (enabledDiagnostics.FormatDocument) { progressTracker.AddItems(1); } // and one for 'remove/sort usings' if we're going to run that. var organizeUsings = enabledDiagnostics.OrganizeUsings.IsRemoveUnusedImportEnabled || enabledDiagnostics.OrganizeUsings.IsSortImportsEnabled; if (organizeUsings) { progressTracker.AddItems(1); } document = await ApplyCodeFixesAsync( document, enabledDiagnostics.Diagnostics, progressTracker, options, cancellationToken).ConfigureAwait(false); // do the remove usings after code fix, as code fix might remove some code which can results in unused usings. if (organizeUsings) { progressTracker.Description = this.OrganizeImportsDescription; document = await RemoveSortUsingsAsync( document, enabledDiagnostics.OrganizeUsings, formattingOptions, cancellationToken).ConfigureAwait(false); progressTracker.ItemCompleted(); } if (enabledDiagnostics.FormatDocument) { progressTracker.Description = FeaturesResources.Formatting_document; using (Logger.LogBlock(FunctionId.CodeCleanup_Format, cancellationToken)) { document = await Formatter.FormatAsync(document, formattingOptions, cancellationToken).ConfigureAwait(false); progressTracker.ItemCompleted(); } } return(document); }
/// <summary> /// Creates a code refactoring context to be passed into <see cref="CodeRefactoringProvider.ComputeRefactoringsAsync(CodeRefactoringContext)"/> method. /// </summary> internal CodeRefactoringContext( Document document, TextSpan span, Action <CodeAction, TextSpan?> registerRefactoring, CodeActionOptions options, CancellationToken cancellationToken) { // NOTE/TODO: Don't make this overload public & obsolete the `Action<CodeAction> registerRefactoring` // overload to stop leaking the Lambda implementation detail. Document = document ?? throw new ArgumentNullException(nameof(document)); Span = span; _registerRefactoring = registerRefactoring ?? throw new ArgumentNullException(nameof(registerRefactoring)); Options = options; CancellationToken = cancellationToken; }
private static async Task <FixAllContext> GetFixAllContextAsync( Solution solution, CodeFixProvider codeFixProvider, ImmutableDictionary <Project, ImmutableArray <Diagnostic> > diagnosticsByProject, CodeActionOptions options, CancellationToken cancellationToken) { var diagnosticProvider = new DiagnosticProvider(diagnosticsByProject); var firstDiagnostic = diagnosticsByProject .SelectMany(kvp => kvp.Value) .FirstOrDefault(); RoslynDebug.AssertNotNull(firstDiagnostic?.Location?.SourceTree); var document = solution.GetRequiredDocument(firstDiagnostic.Location.SourceTree); // This will allow us access to the equivalence key CodeAction?action = null; var context = new CodeFixContext( document, firstDiagnostic.Location.SourceSpan, ImmutableArray.Create(firstDiagnostic), (a, _) => action ??= a, options, cancellationToken); await codeFixProvider.RegisterCodeFixesAsync(context).ConfigureAwait(false); return(new FixAllContext( new FixAllState( fixAllProvider: null, diagnosticSpan: firstDiagnostic.Location.SourceSpan, document, document.Project, codeFixProvider, FixAllScope.Solution, codeActionEquivalenceKey: action?.EquivalenceKey !, // FixAllState supports null equivalence key. This should still be supported. diagnosticIds: codeFixProvider.FixableDiagnosticIds, fixAllDiagnosticProvider: diagnosticProvider, _ => options), new ProgressTracker(), cancellationToken)); }
private async Task <Document> ApplyCodeFixesAsync( Document document, ImmutableArray <DiagnosticSet> enabledDiagnosticSets, IProgressTracker progressTracker, CodeActionOptions options, CancellationToken cancellationToken) { // Add a progress item for each enabled option we're going to fixup. progressTracker.AddItems(enabledDiagnosticSets.Length); foreach (var diagnosticSet in enabledDiagnosticSets) { cancellationToken.ThrowIfCancellationRequested(); progressTracker.Description = diagnosticSet.Description; document = await ApplyCodeFixesForSpecificDiagnosticIdsAsync( document, diagnosticSet.DiagnosticIds, progressTracker, options, cancellationToken).ConfigureAwait(false); // Mark this option as being completed. progressTracker.ItemCompleted(); } return(document); }
public void OptionsAreMessagePackSerializable(string language) { var messagePackOptions = MessagePackSerializerOptions.Standard.WithResolver(MessagePackFormatters.DefaultResolver); using var workspace = new AdhocWorkspace(); var languageServices = workspace.Services.GetLanguageServices(language); var options = new object[] { SimplifierOptions.GetDefault(languageServices), SyntaxFormattingOptions.GetDefault(languageServices), CodeCleanupOptions.GetDefault(languageServices), CodeGenerationOptions.GetDefault(languageServices), IdeCodeStyleOptions.GetDefault(languageServices), CodeActionOptions.GetDefault(languageServices), IndentationOptions.GetDefault(languageServices), ExtractMethodGenerationOptions.GetDefault(languageServices), // some non-default values: new VisualBasicIdeCodeStyleOptions( new IdeCodeStyleOptions.CommonOptions() { AllowStatementImmediatelyAfterBlock = new CodeStyleOption2 <bool>(false, NotificationOption2.Error) }, PreferredModifierOrder: new CodeStyleOption2 <string>("Public Private", NotificationOption2.Error)) }; foreach (var original in options) { using var stream = new MemoryStream(); MessagePackSerializer.Serialize(stream, original, messagePackOptions); stream.Position = 0; var deserialized = MessagePackSerializer.Deserialize(original.GetType(), stream, messagePackOptions); Assert.Equal(original, deserialized); } }
public static CSharpSyntaxWrappingOptions GetCSharpSyntaxWrappingOptions(this AnalyzerConfigOptions options, CodeActionOptions fallbackOptions) => new(
protected override SyntaxWrappingOptions GetWrappingOptions(AnalyzerConfigOptions options, CodeActionOptions ideOptions) => options.GetCSharpSyntaxWrappingOptions(ideOptions);
private async Task <Document> ApplyCodeFixesForSpecificDiagnosticIdAsync(Document document, string diagnosticId, IProgressTracker progressTracker, CodeActionOptions options, CancellationToken cancellationToken) { var tree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var textSpan = new TextSpan(0, tree.Length); var fixCollection = await _codeFixService.GetDocumentFixAllForIdInSpanAsync( document, textSpan, diagnosticId, options, cancellationToken).ConfigureAwait(false); if (fixCollection == null) { return(document); } var fixAllService = document.Project.Solution.Workspace.Services.GetRequiredService <IFixAllGetFixesService>(); var solution = await fixAllService.GetFixAllChangedSolutionAsync( new FixAllContext(fixCollection.FixAllState, progressTracker, cancellationToken)).ConfigureAwait(false); return(solution.GetDocument(document.Id) ?? throw new NotSupportedException(FeaturesResources.Removal_of_document_not_supported)); }
public static CSharpSyntaxWrappingOptions Create(AnalyzerConfigOptions options, CodeActionOptions ideOptions) => new(
private async Task <Document> ApplyCodeFixesForSpecificDiagnosticIdsAsync( Document document, ImmutableArray <string> diagnosticIds, IProgressTracker progressTracker, CodeActionOptions options, CancellationToken cancellationToken) { foreach (var diagnosticId in diagnosticIds) { using (Logger.LogBlock(FunctionId.CodeCleanup_ApplyCodeFixesAsync, diagnosticId, cancellationToken)) { document = await _codeFixService.ApplyCodeFixesForSpecificDiagnosticIdAsync( document, diagnosticId, progressTracker, options, cancellationToken).ConfigureAwait(false); } } return(document); }
public static Task <ImmutableArray <CodeFixCollection> > GetFixesAsync(this ICodeFixService service, Document document, TextSpan range, CodeActionOptions options, CancellationToken cancellationToken) => service.StreamFixesAsync(document, range, options, cancellationToken).ToImmutableArrayAsync(cancellationToken);
public static IAsyncEnumerable <CodeFixCollection> StreamFixesAsync(this ICodeFixService service, Document document, TextSpan range, CodeActionOptions options, CancellationToken cancellationToken) => service.StreamFixesAsync(document, range, CodeActionRequestPriority.None, options, addOperationScope: _ => null, cancellationToken);
public static Task <ImmutableArray <CodeFixCollection> > GetFixesAsync(this ICodeFixService service, Document document, TextSpan textSpan, CodeActionRequestPriority priority, CodeActionOptions options, Func <string, IDisposable?> addOperationScope, CancellationToken cancellationToken) => service.StreamFixesAsync(document, textSpan, priority, options, addOperationScope, cancellationToken).ToImmutableArrayAsync(cancellationToken);
public static Task <ImmutableArray <CodeFixCollection> > GetFixesAsync(this ICodeFixService service, Document document, TextSpan range, CodeActionOptions options, CancellationToken cancellationToken) => service.GetFixesAsync(document, range, CodeActionRequestPriority.None, options, addOperationScope: _ => null, cancellationToken);
protected abstract SyntaxWrappingOptions GetWrappingOptions(AnalyzerConfigOptions options, CodeActionOptions ideOptions);
public static Task <ImmutableArray <CodeRefactoring> > GetRefactoringsAsync(this ICodeRefactoringService service, Document document, TextSpan state, CodeActionOptions options, CancellationToken cancellationToken) => service.GetRefactoringsAsync(document, state, CodeActionRequestPriority.None, options, addOperationScope: _ => null, cancellationToken);