/// <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;
            }
Exemple #4
0
        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);
        }
Exemple #5
0
 /// <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);
        }
Exemple #8
0
        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);
            }
        }
Exemple #9
0
 public static CSharpSyntaxWrappingOptions GetCSharpSyntaxWrappingOptions(this AnalyzerConfigOptions options, CodeActionOptions fallbackOptions)
 => new(
 protected override SyntaxWrappingOptions GetWrappingOptions(AnalyzerConfigOptions options, CodeActionOptions ideOptions)
 => options.GetCSharpSyntaxWrappingOptions(ideOptions);
Exemple #11
0
        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));
        }
Exemple #12
0
 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);
        }
Exemple #14
0
 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);
Exemple #15
0
 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);
Exemple #16
0
 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);
Exemple #17
0
 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);