private IEnumerable <SuggestedActionSet> GetRefactorings( ISuggestedActionCategorySet requestedActionCategories, Document document, ITextSnapshot snapshot, Workspace workspace, IOptionService optionService, CancellationToken cancellationToken) { // For Dev14 Preview, we also want to show refactorings in the CodeFix list when users press Ctrl+. if (requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Refactoring) || requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.CodeFix)) { var refactoringsOn = optionService.GetOption(EditorComponentOnOffOptions.CodeRefactorings); if (!refactoringsOn) { return(null); } // Get the selection while on the UI thread. var selection = GetCodeRefactoringSelection(snapshot); if (!selection.HasValue) { // this is here to fail test and see why it is failed. System.Diagnostics.Trace.WriteLine("given range is not current"); return(null); } var refactorings = Task.Run( async() => await _owner._codeRefactoringService.GetRefactoringsAsync(document, selection.Value, cancellationToken).ConfigureAwait(false), cancellationToken).WaitAndGetResult(cancellationToken); return(refactorings.Select(r => OrganizeRefactorings(workspace, r))); } return(null); }
private ImmutableArray <SuggestedActionSet> GetCodeFixes( IDocumentSupportsFeatureService supportsFeatureService, ISuggestedActionCategorySet requestedActionCategories, Workspace workspace, Document document, SnapshotSpan range, CancellationToken cancellationToken) { this.AssertIsForeground(); if (_owner._codeFixService != null && supportsFeatureService.SupportsCodeFixes(document) && requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.CodeFix)) { // We only include suppressions if light bulb is asking for everything. // If the light bulb is only asking for code fixes, then we don't include suppressions. var includeSuppressionFixes = requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Any); var fixes = Task.Run( () => _owner._codeFixService.GetFixesAsync( document, range.Span.ToTextSpan(), includeSuppressionFixes, cancellationToken), cancellationToken).WaitAndGetResult(cancellationToken); var filteredFixes = FilterOnUIThread(fixes, workspace); return(OrganizeFixes(workspace, filteredFixes, includeSuppressionFixes)); } return(ImmutableArray <SuggestedActionSet> .Empty); }
private IEnumerable <SuggestedActionSet> GetCodeFixes( IDocumentSupportsSuggestionService supportSuggestion, ISuggestedActionCategorySet requestedActionCategories, Workspace workspace, Document document, SnapshotSpan range, CancellationToken cancellationToken) { if (_owner._codeFixService != null && supportSuggestion.SupportsCodeFixes(document) && requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.CodeFix)) { // We only include suppressions if lightbulb is asking for everything. // If the light bulb is only asking for code fixes, then we don't include suppressions. var includeSuppressionFixes = requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Any); var fixes = Task.Run( async() => await _owner._codeFixService.GetFixesAsync( document, range.Span.ToTextSpan(), includeSuppressionFixes, cancellationToken).ConfigureAwait(false), cancellationToken).WaitAndGetResult(cancellationToken); return(OrganizeFixes(workspace, fixes, hasSuppressionFixes: includeSuppressionFixes)); } return(null); }
private async Task <bool> HasFixesAsync( IDocumentSupportsSuggestionService supportSuggestion, ISuggestedActionCategorySet requestedActionCategories, SuggestedActionsSourceProvider provider, Document document, SnapshotSpan range, CancellationToken cancellationToken) { if (provider._codeFixService != null && supportSuggestion.SupportsCodeFixes(document) && requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.CodeFix)) { // We only consider suppressions if lightbulb is asking for everything. // If the light bulb is only asking for code fixes, then we don't consider suppressions. var considerSuppressionFixes = requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Any); var result = await Task.Run( async() => await provider._codeFixService.GetFirstDiagnosticWithFixAsync( document, range.Span.ToTextSpan(), considerSuppressionFixes, cancellationToken).ConfigureAwait(false), cancellationToken).ConfigureAwait(false); if (result.HasFix) { Logger.Log(FunctionId.SuggestedActions_HasSuggestedActionsAsync); return(true); } if (result.PartialResult) { // reset solution version number so that we can raise suggested action changed event Volatile.Write(ref _lastSolutionVersionReported, InvalidSolutionVersion); return(false); } } return(false); }
static MSBuildDiagnosticSeverity CategoriesToSeverity(ISuggestedActionCategorySet categories) { var severity = MSBuildDiagnosticSeverity.None; if (categories.Contains(PredefinedSuggestedActionCategoryNames.ErrorFix)) { severity |= MSBuildDiagnosticSeverity.Error; } if (categories.Contains(PredefinedSuggestedActionCategoryNames.CodeFix)) { severity |= MSBuildDiagnosticSeverity.Suggestion | MSBuildDiagnosticSeverity.Warning; } return(severity); }
private async Task <bool> HasRefactoringsAsync( IDocumentSupportsFeatureService supportsFeatureService, ISuggestedActionCategorySet requestedActionCategories, SuggestedActionsSourceProvider provider, Document document, ITextBuffer buffer, ITextView view, SnapshotSpan range, CancellationToken cancellationToken) { if (!requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Refactoring)) { // See if we should still show the light bulb, even if we weren't explicitly // asked for refactorings. We'll show the lightbulb if we're currently // flighting the "Refactoring" A/B test, or if a special option is set // enabling this internally. var workspace = document.Project.Solution.Workspace; var experimentationService = workspace.Services.GetService <IExperimentationService>(); if (!experimentationService.IsExperimentEnabled("Refactoring") && !workspace.Options.GetOption(EditorComponentOnOffOptions.ShowCodeRefactoringsWhenQueriedForCodeFixes)) { return(false); } } if (document.Project.Solution.Options.GetOption(EditorComponentOnOffOptions.CodeRefactorings) && provider._codeRefactoringService != null && supportsFeatureService.SupportsRefactorings(document)) { TextSpan?selection = null; if (IsForeground()) { // This operation needs to happen on UI thread because it needs to access textView.Selection. selection = TryGetCodeRefactoringSelection(buffer, view, range); } else { await InvokeBelowInputPriority(() => { // This operation needs to happen on UI thread because it needs to access textView.Selection. selection = TryGetCodeRefactoringSelection(buffer, view, range); }).ConfigureAwait(false); } if (!selection.HasValue) { // this is here to fail test and see why it is failed. Trace.WriteLine("given range is not current"); return(false); } return(await Task.Run( () => provider._codeRefactoringService.HasRefactoringsAsync( document, selection.Value, cancellationToken), cancellationToken).ConfigureAwait(false)); } return(false); }
public async Task <ISuggestedActionCategorySet> GetSuggestedActionCategoriesAsync(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken) { var provider = _owner; using (var asyncToken = _owner.OperationListener.BeginAsyncOperation(nameof(GetSuggestedActionCategoriesAsync))) { var document = range.Snapshot.GetOpenDocumentInCurrentContextWithChanges(); using (var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken)) { var linkedToken = linkedTokenSource.Token; var errorTask = Task.Run( () => GetFixLevelAsync(provider, document, range, linkedToken), linkedToken); var selection = await GetSpanAsync(range).ConfigureAwait(false); Task <string> refactoringTask = Task.FromResult((string)null); if (selection != null && requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Refactoring)) { refactoringTask = Task.Run( () => TryGetRefactoringSuggestedActionCategoryAsync(provider, document, selection, linkedToken), linkedToken); } // If we happen to get the result of the error task before the refactoring task, // and that result is non-null, we can just cancel the refactoring task. var result = await errorTask.ConfigureAwait(false) ?? await refactoringTask.ConfigureAwait(false); linkedTokenSource.Cancel(); return(result == null ? null : _suggestedActionCategoryRegistry.CreateSuggestedActionCategorySet(result)); } } }
private IEnumerable <SuggestedActionSet> GetRefactorings( IDocumentSupportsSuggestionService supportSuggestion, ISuggestedActionCategorySet requestedActionCategories, Workspace workspace, Document document, SnapshotSpan range, CancellationToken cancellationToken) { var optionService = workspace.Services.GetService <IOptionService>(); if (optionService.GetOption(EditorComponentOnOffOptions.CodeRefactorings) && _owner._codeRefactoringService != null && supportSuggestion.SupportsRefactorings(document) && requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Refactoring)) { // Get the selection while on the UI thread. var selection = TryGetCodeRefactoringSelection(_subjectBuffer, _textView, range); if (!selection.HasValue) { // this is here to fail test and see why it is failed. Trace.WriteLine("given range is not current"); return(null); } var refactorings = Task.Run( async() => await _owner._codeRefactoringService.GetRefactoringsAsync( document, selection.Value, cancellationToken).ConfigureAwait(false), cancellationToken).WaitAndGetResult(cancellationToken); return(refactorings.Select(r => OrganizeRefactorings(workspace, r))); } return(null); }
private ImmutableArray <SuggestedActionSet> GetRefactorings( IDocumentSupportsFeatureService supportsFeatureService, ISuggestedActionCategorySet requestedActionCategories, Workspace workspace, Document document, TextSpan?selectionOpt, CancellationToken cancellationToken) { this.AssertIsForeground(); if (!selectionOpt.HasValue) { // this is here to fail test and see why it is failed. Trace.WriteLine("given range is not current"); return(ImmutableArray <SuggestedActionSet> .Empty); } var selection = selectionOpt.Value; if (workspace.Options.GetOption(EditorComponentOnOffOptions.CodeRefactorings) && _owner._codeRefactoringService != null && supportsFeatureService.SupportsRefactorings(document) && requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Refactoring)) { // It may seem strange that we kick off a task, but then immediately 'Wait' on // it. However, it's deliberate. We want to make sure that the code runs on // the background so that no one takes an accidentally dependency on running on // the UI thread. var refactorings = Task.Run( () => _owner._codeRefactoringService.GetRefactoringsAsync( document, selection, cancellationToken), cancellationToken).WaitAndGetResult(cancellationToken); var filteredRefactorings = FilterOnUIThread(refactorings, workspace); // Refactorings are given the span the user currently has selected. That // way they can be accurately sorted against other refactorings/fixes that // are of the same priority. i.e. refactorings are LowPriority by default. // But we still want them to come first over a low-pri code fix that is // further away. A good example of this is "Add null parameter check" which // should be higher in the list when the caret is on a parameter, vs the // code-fix for "use expression body" which is given the entire span of a // method. var priority = selection.Length > 0 ? SuggestedActionSetPriority.Medium : SuggestedActionSetPriority.Low; return(filteredRefactorings.SelectAsArray( r => OrganizeRefactorings(workspace, r, priority, selection.ToSpan()))); } return(ImmutableArray <SuggestedActionSet> .Empty); }
async Task <List <MSBuildCodeFix> > GetSuggestedActionsAsync(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken) { // grab selection first as we are on the UI thread at this point, and can avoid switching to it later var possibleSelection = TryGetSelectedSpan(); var result = await parser.GetOrProcessAsync(range.Snapshot, cancellationToken); List <MSBuildCodeFix> actions = null; var severities = CategoriesToSeverity(requestedActionCategories); if (severities != 0) { actions = await provider.CodeFixService.GetFixes(textBuffer, result, range, severities, cancellationToken); for (int i = 0; i < actions.Count; i++) { if (!requestedActionCategories.Contains(actions[i].Category)) { actions.RemoveAt(i); i--; } } } if (possibleSelection is SnapshotSpan selection && requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Refactoring)) { var refactorings = await provider.RefactoringService.GetRefactorings(result, selection, cancellationToken); if (actions != null) { actions.AddRange(refactorings); } else { actions = refactorings; } } return(actions); }
public IEnumerable <SuggestedActionSet> GetSuggestedActions(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken) { AssertIsForeground(); using (Logger.LogBlock(FunctionId.SuggestedActions_GetSuggestedActions, cancellationToken)) { if (range.IsEmpty) { return(null); } var documentAndSnapshot = GetMatchingDocumentAndSnapshotAsync(range.Snapshot, cancellationToken).WaitAndGetResult(cancellationToken); if (!documentAndSnapshot.HasValue) { // this is here to fail test and see why it is failed. System.Diagnostics.Trace.WriteLine("given range is not current"); return(null); } var document = documentAndSnapshot.Value.Item1; var snapshot = documentAndSnapshot.Value.Item2; var workspace = document.Project.Solution.Workspace; var optionService = workspace.Services.GetService <IOptionService>(); var supportSuggestion = workspace.Services.GetService <IDocumentSupportsSuggestionService>(); IEnumerable <SuggestedActionSet> result = null; if (supportSuggestion.SupportsCodeFixes(document) && requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.CodeFix)) { var suggestions = Task.Run( async() => await _owner._codeFixService.GetFixesAsync(document, range.Span.ToTextSpan(), cancellationToken).ConfigureAwait(false), cancellationToken).WaitAndGetResult(cancellationToken); result = OrganizeFixes(workspace, suggestions); } if (supportSuggestion.SupportsRefactorings(document)) { var refactoringResult = GetRefactorings(requestedActionCategories, document, snapshot, workspace, optionService, cancellationToken); result = result == null ? refactoringResult : refactoringResult == null ? result : result.Concat(refactoringResult); } return(result); } }
private async Task <bool> HasRefactoringsAsync( IDocumentSupportsSuggestionService supportSuggestion, ISuggestedActionCategorySet requestedActionCategories, SuggestedActionsSourceProvider provider, Document document, ITextBuffer buffer, ITextView view, SnapshotSpan range, CancellationToken cancellationToken) { var optionService = document.Project.Solution.Workspace.Services.GetService <IOptionService>(); if (optionService.GetOption(EditorComponentOnOffOptions.CodeRefactorings) && provider._codeRefactoringService != null && supportSuggestion.SupportsRefactorings(document) && requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Refactoring)) { TextSpan?selection = null; if (IsForeground()) { // This operation needs to happen on UI thread because it needs to access textView.Selection. selection = TryGetCodeRefactoringSelection(buffer, view, range); } else { await InvokeBelowInputPriority(() => { // This operation needs to happen on UI thread because it needs to access textView.Selection. selection = TryGetCodeRefactoringSelection(buffer, view, range); }).ConfigureAwait(false); } if (!selection.HasValue) { // this is here to fail test and see why it is failed. Trace.WriteLine("given range is not current"); return(false); } return(await Task.Run( async() => await provider._codeRefactoringService.HasRefactoringsAsync( document, selection.Value, cancellationToken).ConfigureAwait(false), cancellationToken).ConfigureAwait(false)); } return(false); }
public async Task <ISuggestedActionCategorySet> GetSuggestedActionCategoriesAsync(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken) { if (_workspaceStatusService != null && !await _workspaceStatusService.IsFullyLoadedAsync(cancellationToken).ConfigureAwait(false)) { // never show light bulb if solution is not fully loaded yet return(null); } var provider = _owner; using (var asyncToken = _owner.OperationListener.BeginAsyncOperation(nameof(GetSuggestedActionCategoriesAsync))) { var document = range.Snapshot.GetOpenDocumentInCurrentContextWithChanges(); if (document == null) { return(null); } using (var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken)) { var linkedToken = linkedTokenSource.Token; var errorTask = Task.Run( () => GetFixLevelAsync(provider, document, range, linkedToken), linkedToken); var selection = await GetSpanAsync(range, linkedToken).ConfigureAwait(false); var refactoringTask = SpecializedTasks.Default <string>(); if (selection != null && requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Refactoring)) { refactoringTask = Task.Run( () => TryGetRefactoringSuggestedActionCategoryAsync(provider, document, selection, linkedToken), linkedToken); } // If we happen to get the result of the error task before the refactoring task, // and that result is non-null, we can just cancel the refactoring task. var result = await errorTask.ConfigureAwait(false) ?? await refactoringTask.ConfigureAwait(false); linkedTokenSource.Cancel(); return(result == null ? null : _suggestedActionCategoryRegistry.CreateSuggestedActionCategorySet(result)); } } }
private ImmutableArray <SuggestedActionSet> GetRefactorings( IDocumentSupportsFeatureService supportsFeatureService, ISuggestedActionCategorySet requestedActionCategories, Workspace workspace, Document document, TextSpan?selectionOpt, CancellationToken cancellationToken) { this.AssertIsForeground(); if (!selectionOpt.HasValue) { // this is here to fail test and see why it is failed. Trace.WriteLine("given range is not current"); return(ImmutableArray <SuggestedActionSet> .Empty); } var selection = selectionOpt.Value; if (workspace.Options.GetOption(EditorComponentOnOffOptions.CodeRefactorings) && _owner._codeRefactoringService != null && supportsFeatureService.SupportsRefactorings(document) && requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Refactoring)) { // It may seem strange that we kick off a task, but then immediately 'Wait' on // it. However, it's deliberate. We want to make sure that the code runs on // the background so that no one takes an accidentally dependency on running on // the UI thread. var refactorings = Task.Run( () => _owner._codeRefactoringService.GetRefactoringsAsync( document, selection, cancellationToken), cancellationToken).WaitAndGetResult(cancellationToken); var filteredRefactorings = FilterOnUIThread(refactorings, workspace); return(filteredRefactorings.SelectAsArray( r => OrganizeRefactorings(workspace, r, selection.ToSpan()))); } return(ImmutableArray <SuggestedActionSet> .Empty); }
public async Task <ISuggestedActionCategorySet> GetSuggestedActionCategoriesAsync( ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken) { SnapshotSpan?possibleSelection = provider.JoinableTaskContext.IsOnMainThread ? TryGetSelectedSpan() : null; var result = await parser.GetOrProcessAsync(range.Snapshot, cancellationToken); var categories = new List <string> (); var requestedSeverities = CategoriesToSeverity(requestedActionCategories); if (requestedSeverities != 0) { var severities = await provider.CodeFixService.GetFixSeverity(textBuffer, result, range, requestedSeverities, cancellationToken); if ((severities & MSBuildDiagnosticSeverity.Error) != 0) { categories.Add(PredefinedSuggestedActionCategoryNames.ErrorFix); } if ((severities & (MSBuildDiagnosticSeverity.Warning | MSBuildDiagnosticSeverity.Suggestion)) != 0) { categories.Add(PredefinedSuggestedActionCategoryNames.CodeFix); } } if (requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Refactoring)) { possibleSelection ??= await GetSelectedSpanAsync(cancellationToken); if (possibleSelection is SnapshotSpan selection && await provider.RefactoringService.HasRefactorings(result, selection, cancellationToken)) { categories.Add(PredefinedSuggestedActionCategoryNames.Refactoring); } } return(provider.CategoryRegistry.CreateSuggestedActionCategorySet(categories)); }
private async Task<bool> HasRefactoringsAsync( IDocumentSupportsFeatureService supportsFeatureService, ISuggestedActionCategorySet requestedActionCategories, SuggestedActionsSourceProvider provider, Document document, ITextBuffer buffer, ITextView view, SnapshotSpan range, CancellationToken cancellationToken) { var optionService = document.Project.Solution.Workspace.Services.GetService<IOptionService>(); if (optionService.GetOption(EditorComponentOnOffOptions.CodeRefactorings) && provider._codeRefactoringService != null && supportsFeatureService.SupportsRefactorings(document) && requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Refactoring)) { TextSpan? selection = null; if (IsForeground()) { // This operation needs to happen on UI thread because it needs to access textView.Selection. selection = TryGetCodeRefactoringSelection(buffer, view, range); } else { await InvokeBelowInputPriority(() => { // This operation needs to happen on UI thread because it needs to access textView.Selection. selection = TryGetCodeRefactoringSelection(buffer, view, range); }).ConfigureAwait(false); } if (!selection.HasValue) { // this is here to fail test and see why it is failed. Trace.WriteLine("given range is not current"); return false; } return await Task.Run( async () => await provider._codeRefactoringService.HasRefactoringsAsync( document, selection.Value, cancellationToken).ConfigureAwait(false), cancellationToken).ConfigureAwait(false); } return false; }
private async Task<bool> HasFixesAsync( IDocumentSupportsFeatureService supportsFeatureService, ISuggestedActionCategorySet requestedActionCategories, SuggestedActionsSourceProvider provider, Document document, SnapshotSpan range, CancellationToken cancellationToken) { if (provider._codeFixService != null && supportsFeatureService.SupportsCodeFixes(document) && requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.CodeFix)) { // We only consider suppressions if lightbulb is asking for everything. // If the light bulb is only asking for code fixes, then we don't consider suppressions. var considerSuppressionFixes = requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Any); var result = await Task.Run( async () => await provider._codeFixService.GetFirstDiagnosticWithFixAsync( document, range.Span.ToTextSpan(), considerSuppressionFixes, cancellationToken).ConfigureAwait(false), cancellationToken).ConfigureAwait(false); if (result.HasFix) { Logger.Log(FunctionId.SuggestedActions_HasSuggestedActionsAsync); return true; } if (result.PartialResult) { // reset solution version number so that we can raise suggested action changed event Volatile.Write(ref _lastSolutionVersionReported, InvalidSolutionVersion); return false; } } return false; }
private IEnumerable<SuggestedActionSet> GetRefactorings( IDocumentSupportsFeatureService supportsFeatureService, ISuggestedActionCategorySet requestedActionCategories, Workspace workspace, Document document, SnapshotSpan range, CancellationToken cancellationToken) { var optionService = workspace.Services.GetService<IOptionService>(); if (optionService.GetOption(EditorComponentOnOffOptions.CodeRefactorings) && _owner._codeRefactoringService != null && supportsFeatureService.SupportsRefactorings(document) && requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Refactoring)) { // Get the selection while on the UI thread. var selection = TryGetCodeRefactoringSelection(_subjectBuffer, _textView, range); if (!selection.HasValue) { // this is here to fail test and see why it is failed. Trace.WriteLine("given range is not current"); return null; } var refactorings = Task.Run( async () => await _owner._codeRefactoringService.GetRefactoringsAsync( document, selection.Value, cancellationToken).ConfigureAwait(false), cancellationToken).WaitAndGetResult(cancellationToken); return refactorings.Select(r => OrganizeRefactorings(workspace, r)); } return null; }
private IEnumerable<SuggestedActionSet> GetCodeFixes( IDocumentSupportsFeatureService supportsFeatureService, ISuggestedActionCategorySet requestedActionCategories, Workspace workspace, Document document, SnapshotSpan range, CancellationToken cancellationToken) { if (_owner._codeFixService != null && supportsFeatureService.SupportsCodeFixes(document) && requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.CodeFix)) { // We only include suppressions if lightbulb is asking for everything. // If the light bulb is only asking for code fixes, then we don't include suppressions. var includeSuppressionFixes = requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Any); var fixes = Task.Run( async () => await _owner._codeFixService.GetFixesAsync( document, range.Span.ToTextSpan(), includeSuppressionFixes, cancellationToken).ConfigureAwait(false), cancellationToken).WaitAndGetResult(cancellationToken); return OrganizeFixes(workspace, fixes, hasSuppressionFixes: includeSuppressionFixes); } return null; }
private async Task<bool> HasRefactoringsAsync( IDocumentSupportsFeatureService supportsFeatureService, ISuggestedActionCategorySet requestedActionCategories, SuggestedActionsSourceProvider provider, Document document, ITextBuffer buffer, ITextView view, SnapshotSpan range, CancellationToken cancellationToken) { if (!requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Refactoring)) { // See if we should still show the light bulb, even if we weren't explicitly // asked for refactorings. We'll show the lightbulb if we're currently // flighting the "Refactoring" A/B test, or if a special option is set // enabling this internally. var workspace = document.Project.Solution.Workspace; var experimentationService = workspace.Services.GetService<IExperimentationService>(); if (!experimentationService.IsExperimentEnabled("Refactoring") && !workspace.Options.GetOption(EditorComponentOnOffOptions.ShowCodeRefactoringsWhenQueriedForCodeFixes)) { return false; } } if (document.Project.Solution.Options.GetOption(EditorComponentOnOffOptions.CodeRefactorings) && provider._codeRefactoringService != null && supportsFeatureService.SupportsRefactorings(document)) { TextSpan? selection = null; if (IsForeground()) { // This operation needs to happen on UI thread because it needs to access textView.Selection. selection = TryGetCodeRefactoringSelection(buffer, view, range); } else { await InvokeBelowInputPriority(() => { // This operation needs to happen on UI thread because it needs to access textView.Selection. selection = TryGetCodeRefactoringSelection(buffer, view, range); }).ConfigureAwait(false); } if (!selection.HasValue) { // this is here to fail test and see why it is failed. Trace.WriteLine("given range is not current"); return false; } return await Task.Run( () => provider._codeRefactoringService.HasRefactoringsAsync( document, selection.Value, cancellationToken), cancellationToken).ConfigureAwait(false); } return false; }
private ImmutableArray<SuggestedActionSet> GetRefactorings( IDocumentSupportsFeatureService supportsFeatureService, ISuggestedActionCategorySet requestedActionCategories, Workspace workspace, Document document, SnapshotSpan range, CancellationToken cancellationToken) { this.AssertIsForeground(); if (workspace.Options.GetOption(EditorComponentOnOffOptions.CodeRefactorings) && _owner._codeRefactoringService != null && supportsFeatureService.SupportsRefactorings(document) && requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Refactoring)) { // Get the selection while on the UI thread. var selection = TryGetCodeRefactoringSelection(_subjectBuffer, _textView, range); if (!selection.HasValue) { // this is here to fail test and see why it is failed. Trace.WriteLine("given range is not current"); return ImmutableArray<SuggestedActionSet>.Empty; } // It may seem strange that we kick off a task, but then immediately 'Wait' on // it. However, it's deliberate. We want to make sure that the code runs on // the background so that no one takes an accidently dependency on running on // the UI thread. var refactorings = Task.Run( () => _owner._codeRefactoringService.GetRefactoringsAsync( document, selection.Value, cancellationToken), cancellationToken).WaitAndGetResult(cancellationToken); var filteredRefactorings = FilterOnUIThread(refactorings, workspace); return filteredRefactorings.SelectAsArray(r => OrganizeRefactorings(workspace, r)); } return ImmutableArray<SuggestedActionSet>.Empty; }
private IEnumerable<SuggestedActionSet> GetRefactorings( ISuggestedActionCategorySet requestedActionCategories, Document document, ITextSnapshot snapshot, Workspace workspace, IOptionService optionService, CancellationToken cancellationToken) { // For Dev14 Preview, we also want to show refactorings in the CodeFix list when users press Ctrl+. if (requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Refactoring) || requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.CodeFix)) { var refactoringsOn = optionService.GetOption(EditorComponentOnOffOptions.CodeRefactorings); if (!refactoringsOn) { return null; } // Get the selection while on the UI thread. var selection = GetCodeRefactoringSelection(snapshot); if (!selection.HasValue) { // this is here to fail test and see why it is failed. System.Diagnostics.Trace.WriteLine("given range is not current"); return null; } var refactorings = Task.Run( async () => await _owner._codeRefactoringService.GetRefactoringsAsync(document, selection.Value, cancellationToken).ConfigureAwait(false), cancellationToken).WaitAndGetResult(cancellationToken); return refactorings.Select(r => OrganizeRefactorings(workspace, r)); } return null; }
private ImmutableArray<SuggestedActionSet> GetCodeFixes( IDocumentSupportsFeatureService supportsFeatureService, ISuggestedActionCategorySet requestedActionCategories, Workspace workspace, Document document, SnapshotSpan range, CancellationToken cancellationToken) { this.AssertIsForeground(); if (_owner._codeFixService != null && supportsFeatureService.SupportsCodeFixes(document) && requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.CodeFix)) { // We only include suppressions if lightbulb is asking for everything. // If the light bulb is only asking for code fixes, then we don't include suppressions. var includeSuppressionFixes = requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Any); var fixes = Task.Run( () => _owner._codeFixService.GetFixesAsync( document, range.Span.ToTextSpan(), includeSuppressionFixes, cancellationToken), cancellationToken).WaitAndGetResult(cancellationToken); var filteredFixes = FilterOnUIThread(fixes, workspace); return OrganizeFixes(workspace, filteredFixes, includeSuppressionFixes); } return ImmutableArray<SuggestedActionSet>.Empty; }
public IEnumerable<SuggestedActionSet> GetSuggestedActions(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken) { AssertIsForeground(); using (Logger.LogBlock(FunctionId.SuggestedActions_GetSuggestedActions, cancellationToken)) { if (range.IsEmpty) { return null; } var documentAndSnapshot = GetMatchingDocumentAndSnapshotAsync(range.Snapshot, cancellationToken).WaitAndGetResult(cancellationToken); if (!documentAndSnapshot.HasValue) { // this is here to fail test and see why it is failed. System.Diagnostics.Trace.WriteLine("given range is not current"); return null; } var document = documentAndSnapshot.Value.Item1; var snapshot = documentAndSnapshot.Value.Item2; var workspace = document.Project.Solution.Workspace; var optionService = workspace.Services.GetService<IOptionService>(); var supportSuggestion = workspace.Services.GetService<IDocumentSupportsSuggestionService>(); IEnumerable<SuggestedActionSet> result = null; if (supportSuggestion.SupportsCodeFixes(document) && requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.CodeFix)) { var suggestions = Task.Run( async () => await _owner._codeFixService.GetFixesAsync(document, range.Span.ToTextSpan(), cancellationToken).ConfigureAwait(false), cancellationToken).WaitAndGetResult(cancellationToken); result = OrganizeFixes(workspace, suggestions); } if (supportSuggestion.SupportsRefactorings(document)) { var refactoringResult = GetRefactorings(requestedActionCategories, document, snapshot, workspace, optionService, cancellationToken); result = result == null ? refactoringResult : refactoringResult == null ? result : result.Concat(refactoringResult); } return result; } }