public IEnumerable<SuggestedActionSet> GetSuggestedActions(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested || !range.Snapshot.TextBuffer.ContentType.TypeName.EqualsOrdinal(RContentTypeDefinition.ContentType)) { return Enumerable.Empty<SuggestedActionSet>(); } List<SuggestedActionSet> actionSets = new List<SuggestedActionSet>(); var caretPosition = _textView.Caret.Position.BufferPosition; SnapshotPoint? bufferPoint = _textView.MapDownToR(caretPosition); if (bufferPoint.HasValue) { AstRoot ast = _document?.EditorTree.AstRoot; int bufferPosition = bufferPoint.Value.Position; _lastNode = ast?.GetNodeOfTypeFromPosition<TokenNode>(bufferPosition); if (_lastNode != null) { foreach (IRSuggestedActionProvider actionProvider in _suggestedActionProviders) { if (actionProvider.HasSuggestedActions(_textView, _textBuffer, bufferPosition)) { IEnumerable<ISuggestedAction> actions = actionProvider.GetSuggestedActions(_textView, _textBuffer, bufferPosition); Span applicableSpan = new Span(_lastNode.Start, _lastNode.Length); SuggestedActionSet actionSet = new SuggestedActionSet(actions, applicableToSpan: applicableSpan); actionSets.Add(actionSet); } } } } return actionSets; }
public SuggestedActionWithNestedActions( SuggestedActionsSourceProvider sourceProvider, Workspace workspace, ITextBuffer subjectBuffer, object provider, CodeAction codeAction, SuggestedActionSet nestedActionSet) : base(sourceProvider, workspace, subjectBuffer, provider, codeAction) { NestedActionSet = nestedActionSet; }
public SuggestedActionWithNestedFlavors( SuggestedActionsSourceProvider sourceProvider, Workspace workspace, ITextBuffer subjectBuffer, object provider, CodeAction codeAction, SuggestedActionSet additionalFlavors = null) : base(sourceProvider, workspace, subjectBuffer, provider, codeAction) { _additionalFlavors = additionalFlavors; }
private SuggestedActionSet FilterActionSetByTitle(SuggestedActionSet set, HashSet <string> seenTitles) { var actions = ArrayBuilder <ISuggestedAction> .GetInstance(); foreach (var action in set.Actions) { if (seenTitles.Add(action.DisplayText)) { actions.Add(action); } } try { return(actions.Count == 0 ? null : new SuggestedActionSet(set.CategoryName, actions.ToImmutable(), set.Title, set.Priority, set.ApplicableToSpan)); } finally { actions.Free(); } }
private void AddCodeActions( Workspace workspace, IDictionary <CodeFixGroupKey, IList <SuggestedAction> > map, ArrayBuilder <CodeFixGroupKey> order, CodeFixCollection fixCollection, Func <CodeAction, SuggestedActionSet> getFixAllSuggestedActionSet, ImmutableArray <CodeFix> codeFixes) { foreach (var fix in codeFixes) { SuggestedAction suggestedAction; if (fix.Action.NestedCodeActions.Length > 0) { var nestedActions = fix.Action.NestedCodeActions.SelectAsArray( nestedAction => new CodeFixSuggestedAction( ThreadingContext, _owner, workspace, _subjectBuffer, fix, fixCollection.Provider, nestedAction, getFixAllSuggestedActionSet(nestedAction))); var set = new SuggestedActionSet(categoryName: null, actions: nestedActions, priority: GetSuggestedActionSetPriority(fix.Action.Priority), applicableToSpan: fix.PrimaryDiagnostic.Location.SourceSpan.ToSpan()); suggestedAction = new SuggestedActionWithNestedActions( ThreadingContext, _owner, workspace, _subjectBuffer, fixCollection.Provider, fix.Action, set); } else { suggestedAction = new CodeFixSuggestedAction( ThreadingContext, _owner, workspace, _subjectBuffer, fix, fixCollection.Provider, fix.Action, getFixAllSuggestedActionSet(fix.Action)); } AddFix(fix, suggestedAction, map, order); } }
/// <summary> /// Arrange refactorings into groups. /// </summary> /// <remarks> /// Refactorings are returned in priority order determined based on <see cref="ExtensionOrderAttribute"/>. /// Priority for all <see cref="SuggestedActionSet"/>s containing refactorings is set to <see cref="SuggestedActionSetPriority.Low"/> /// and should show up after fixes but before suppression fixes in the light bulb menu. /// </remarks> private SuggestedActionSet OrganizeRefactorings( Workspace workspace, CodeRefactoring refactoring, SuggestedActionSetPriority priority, Span applicableSpan) { var refactoringSuggestedActions = ArrayBuilder <SuggestedAction> .GetInstance(); foreach (var action in refactoring.Actions) { if (action.NestedCodeActions.Length > 0) { var nestedActions = action.NestedCodeActions.SelectAsArray( na => new CodeRefactoringSuggestedAction( ThreadingContext, _owner, workspace, _subjectBuffer, refactoring.Provider, na)); var set = new SuggestedActionSet(categoryName: null, actions: nestedActions, priority: SuggestedActionSetPriority.Medium, applicableToSpan: applicableSpan); refactoringSuggestedActions.Add(new SuggestedActionWithNestedActions( ThreadingContext, _owner, workspace, _subjectBuffer, refactoring.Provider, action, set)); } else { refactoringSuggestedActions.Add(new CodeRefactoringSuggestedAction( ThreadingContext, _owner, workspace, _subjectBuffer, refactoring.Provider, action)); } } return(new SuggestedActionSet( PredefinedSuggestedActionCategoryNames.Refactoring, refactoringSuggestedActions.ToImmutableAndFree(), priority: priority, applicableToSpan: applicableSpan)); }
/// <summary> /// Groups fixes by the diagnostic being addressed by each fix. /// </summary> private void GroupFixes(Workspace workspace, IEnumerable <CodeFixCollection> fixCollections, IDictionary <Diagnostic, IList <SuggestedAction> > map, IList <Diagnostic> order, bool hasSuppressionFixes) { foreach (var fixCollection in fixCollections) { var fixes = fixCollection.Fixes; var fixCount = fixes.Length; Func <CodeAction, SuggestedActionSet> getFixAllSuggestedActionSet = codeAction => CodeFixSuggestedAction.GetFixAllSuggestedActionSet(codeAction, fixCount, fixCollection.FixAllContext, workspace, _subjectBuffer, _owner._editHandler); foreach (var fix in fixes) { // Suppression fixes are handled below. if (!(fix.Action is SuppressionCodeAction)) { SuggestedAction suggestedAction; if (fix.Action.HasCodeActions) { var nestedActions = new List <SuggestedAction>(); foreach (var nestedAction in fix.Action.GetCodeActions()) { nestedActions.Add(new CodeFixSuggestedAction(workspace, _subjectBuffer, _owner._editHandler, fix, nestedAction, fixCollection.Provider, getFixAllSuggestedActionSet(nestedAction))); } var diag = fix.Diagnostics[0]; var set = new SuggestedActionSet(nestedActions, SuggestedActionSetPriority.Medium, GetApplicableToSpan(diag)); suggestedAction = new SuggestedAction(workspace, _subjectBuffer, _owner._editHandler, fix.Action, fixCollection.Provider, new[] { set }); } else { suggestedAction = new CodeFixSuggestedAction(workspace, _subjectBuffer, _owner._editHandler, fix, fix.Action, fixCollection.Provider, getFixAllSuggestedActionSet(fix.Action)); } AddFix(fix, suggestedAction, map, order); } } if (hasSuppressionFixes) { // Add suppression fixes to the end of a given SuggestedActionSet so that they always show up last in a group. foreach (var fix in fixes) { if (fix.Action is SuppressionCodeAction) { SuggestedAction suggestedAction; if (fix.Action.HasCodeActions) { suggestedAction = new SuppressionSuggestedAction(workspace, _subjectBuffer, _owner._editHandler, fix, fixCollection.Provider, getFixAllSuggestedActionSet); } else { suggestedAction = new CodeFixSuggestedAction(workspace, _subjectBuffer, _owner._editHandler, fix, fix.Action, fixCollection.Provider, getFixAllSuggestedActionSet(fix.Action)); } AddFix(fix, suggestedAction, map, order); } } } } }
/// <summary> /// Groups fixes by the diagnostic being addressed by each fix. /// </summary> private void GroupFixes(Workspace workspace, IEnumerable<CodeFixCollection> fixCollections, IDictionary<DiagnosticData, IList<SuggestedAction>> map, IList<DiagnosticData> order, bool hasSuppressionFixes) { foreach (var fixCollection in fixCollections) { var fixes = fixCollection.Fixes; var fixCount = fixes.Length; Func<CodeAction, SuggestedActionSet> getFixAllSuggestedActionSet = codeAction => CodeFixSuggestedAction.GetFixAllSuggestedActionSet(codeAction, fixCount, fixCollection.FixAllContext, workspace, _subjectBuffer, _owner._editHandler, _owner._waitIndicator); foreach (var fix in fixes) { // Suppression fixes are handled below. if (!(fix.Action is SuppressionCodeAction)) { SuggestedAction suggestedAction; if (fix.Action.HasCodeActions) { var nestedActions = new List<SuggestedAction>(); foreach (var nestedAction in fix.Action.GetCodeActions()) { nestedActions.Add(new CodeFixSuggestedAction(workspace, _subjectBuffer, _owner._editHandler, _owner._waitIndicator, fix, nestedAction, fixCollection.Provider, getFixAllSuggestedActionSet(nestedAction))); } var diag = fix.PrimaryDiagnostic; var set = new SuggestedActionSet(nestedActions, SuggestedActionSetPriority.Medium, diag.Location.SourceSpan.ToSpan()); suggestedAction = new SuggestedAction(workspace, _subjectBuffer, _owner._editHandler, _owner._waitIndicator, fix.Action, fixCollection.Provider, new[] { set }); } else { suggestedAction = new CodeFixSuggestedAction(workspace, _subjectBuffer, _owner._editHandler, _owner._waitIndicator, fix, fix.Action, fixCollection.Provider, getFixAllSuggestedActionSet(fix.Action)); } AddFix(fix, suggestedAction, map, order); } } if (hasSuppressionFixes) { // Add suppression fixes to the end of a given SuggestedActionSet so that they always show up last in a group. foreach (var fix in fixes) { if (fix.Action is SuppressionCodeAction) { SuggestedAction suggestedAction; if (fix.Action.HasCodeActions) { suggestedAction = new SuppressionSuggestedAction(workspace, _subjectBuffer, _owner._editHandler, _owner._waitIndicator, fix, fixCollection.Provider, getFixAllSuggestedActionSet); } else { suggestedAction = new CodeFixSuggestedAction(workspace, _subjectBuffer, _owner._editHandler, _owner._waitIndicator, fix, fix.Action, fixCollection.Provider, getFixAllSuggestedActionSet(fix.Action)); } AddFix(fix, suggestedAction, map, order); } } } } }
private SuggestedActionSet InlineActions(SuggestedActionSet actionSet) { if (!actionSet.Actions.Any(IsInlineable)) { return actionSet; } var newActions = new List<ISuggestedAction>(); foreach (var action in actionSet.Actions) { if (IsInlineable(action)) { // Looks like something we can inline. var childActionSets = ((SuggestedAction)action).GetActionSets(); if (childActionSets.Length != 1) { return actionSet; } newActions.AddRange(childActionSets[0].Actions); } newActions.Add(action); } return new SuggestedActionSet(newActions, actionSet.Title, actionSet.Priority, actionSet.ApplicableToSpan); }
public RecommendationItem(int score, CodeSearchResponse.SearchResultValue searchResultValue) { Score = score; SuggestedActionSet = new SuggestedActionSet(new ISuggestedAction[] { new MsAzureCodeAction(searchResultValue.Repository.Name, searchResultValue.FileName, searchResultValue.Path, CreateFileUri(searchResultValue), CreateRepoUri(searchResultValue)) }); }
/// <summary> /// Groups fixes by the diagnostic being addressed by each fix. /// </summary> private void GroupFixes( Workspace workspace, IEnumerable <CodeFixCollection> fixCollections, IDictionary <CodeFixGroupKey, IList <SuggestedAction> > map, IList <CodeFixGroupKey> order, bool hasSuppressionFixes) { foreach (var fixCollection in fixCollections) { var fixes = fixCollection.Fixes; var fixCount = fixes.Length; Func <CodeAction, SuggestedActionSet> getFixAllSuggestedActionSet = codeAction => CodeFixSuggestedAction.GetFixAllSuggestedActionSet( codeAction, fixCount, fixCollection.FixAllState, fixCollection.SupportedScopes, fixCollection.FirstDiagnostic, workspace, _subjectBuffer, _owner._editHandler, _owner._waitIndicator, _owner._listener); foreach (var fix in fixes) { // Suppression fixes are handled below. if (!(fix.Action is SuppressionCodeAction)) { SuggestedAction suggestedAction; if (fix.Action.HasCodeActions) { var nestedActions = new List <SuggestedAction>(); foreach (var nestedAction in fix.Action.GetCodeActions()) { nestedActions.Add(new CodeFixSuggestedAction(workspace, _subjectBuffer, _owner._editHandler, _owner._waitIndicator, fix, nestedAction, fixCollection.Provider, getFixAllSuggestedActionSet(nestedAction), _owner._listener)); } var diag = fix.PrimaryDiagnostic; var set = new SuggestedActionSet(nestedActions, SuggestedActionSetPriority.Medium, diag.Location.SourceSpan.ToSpan()); suggestedAction = new SuggestedAction(workspace, _subjectBuffer, _owner._editHandler, _owner._waitIndicator, fix.Action, fixCollection.Provider, _owner._listener, new[] { set }); } else { suggestedAction = new CodeFixSuggestedAction( workspace, _subjectBuffer, _owner._editHandler, _owner._waitIndicator, fix, fix.Action, fixCollection.Provider, getFixAllSuggestedActionSet(fix.Action), _owner._listener); } AddFix(fix, suggestedAction, map, order); } } if (hasSuppressionFixes) { // Add suppression fixes to the end of a given SuggestedActionSet so that they always show up last in a group. foreach (var fix in fixes) { if (fix.Action is SuppressionCodeAction) { SuggestedAction suggestedAction; if (fix.Action.HasCodeActions) { suggestedAction = new SuppressionSuggestedAction( workspace, _subjectBuffer, _owner._editHandler, _owner._waitIndicator, fix, fixCollection.Provider, getFixAllSuggestedActionSet, _owner._listener); } else { suggestedAction = new CodeFixSuggestedAction( workspace, _subjectBuffer, _owner._editHandler, _owner._waitIndicator, fix, fix.Action, fixCollection.Provider, getFixAllSuggestedActionSet(fix.Action), _owner._listener); } AddFix(fix, suggestedAction, map, order); } } } } }
private void AddCodeActions( Workspace workspace, IDictionary<CodeFixGroupKey, IList<SuggestedAction>> map, ArrayBuilder<CodeFixGroupKey> order, CodeFixCollection fixCollection, Func<CodeAction, SuggestedActionSet> getFixAllSuggestedActionSet, ImmutableArray<CodeFix> codeFixes) { foreach (var fix in codeFixes) { SuggestedAction suggestedAction; if (fix.Action.NestedCodeActions.Length > 0) { var nestedActions = fix.Action.NestedCodeActions.SelectAsArray( nestedAction => new CodeFixSuggestedAction( _owner, workspace, _subjectBuffer, fix, fixCollection.Provider, nestedAction, getFixAllSuggestedActionSet(nestedAction))); var set = new SuggestedActionSet( nestedActions, SuggestedActionSetPriority.Medium, fix.PrimaryDiagnostic.Location.SourceSpan.ToSpan()); suggestedAction = new SuggestedActionWithNestedActions( _owner, workspace, _subjectBuffer, fixCollection.Provider, fix.Action, set); } else { suggestedAction = new CodeFixSuggestedAction( _owner, workspace, _subjectBuffer, fix, fixCollection.Provider, fix.Action, getFixAllSuggestedActionSet(fix.Action)); } AddFix(fix, suggestedAction, map, order); } }
private SuggestedActionSet InlineActions(SuggestedActionSet actionSet) { var newActions = ArrayBuilder<ISuggestedAction>.GetInstance(); foreach (var action in actionSet.Actions) { var actionWithNestedActions = action as SuggestedActionWithNestedActions; // Only inline if the underlying code action allows it. if (actionWithNestedActions?.CodeAction.IsInlinable == true) { newActions.AddRange(actionWithNestedActions.NestedActionSet.Actions); } else { newActions.Add(action); } } return new SuggestedActionSet( newActions.ToImmutableAndFree(), actionSet.Title, actionSet.Priority, actionSet.ApplicableToSpan); }
public IEnumerable <SuggestedActionSet> GetSuggestedActions( ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken) { TextExtent extent; UE4MacroStatement ue4Statement; if (TryGetWordUnderCaret(out extent) && extent.IsSignificant && _ue4Processor.TryGetUE4Macro(extent.Span.End, out ue4Statement)) { bool inMeta; _ue4Processor.ParseSpecifiers(extent.Span.End, ref ue4Statement, out inMeta); UE4Specifier[] datasource; switch (ue4Statement.MacroConst) { case UE4Macros.UCLASS: datasource = new[] { UE4SpecifiersSource.UC }.SelectMany(a => a).ToArray(); break; case UE4Macros.UFUNCTION: datasource = new[] { UE4SpecifiersSource.UF }.SelectMany(a => a).ToArray(); break; case UE4Macros.UPROPERTY: datasource = new[] { UE4SpecifiersSource.UP }.SelectMany(a => a).ToArray(); break; case UE4Macros.UINTERFACE: datasource = new[] { UE4SpecifiersSource.UI }.SelectMany(a => a).ToArray(); break; case UE4Macros.USTRUCT: datasource = new[] { UE4SpecifiersSource.US }.SelectMany(a => a).ToArray(); break; default: datasource = new UE4Specifier[0]; break; } var specifiersNotInList = ue4Statement.Specifiers .Select(c => c.Split(new [] { '=' }, StringSplitOptions.RemoveEmptyEntries)[0].Trim().ToUpper()) //only take specifier and not its params .Where(c => !datasource.Select(s => s.Name.ToUpper()).Contains(c)); //toupper compare var moreThanOneSpecInGroup = datasource.Where(s => ue4Statement.Specifiers.Contains(s.Name)) .Where(c => c.Group != null) .GroupBy(s => s.Group) .Any(g => g.Count() > 1); var removeInvalid = new SuggestedActionSet( specifiersNotInList.Select( s => { var specStart = ue4Statement.SpecifiersSpan.Start + ue4Statement.SpecifiersSpan.GetText().ToUpper().IndexOf(s, StringComparison.Ordinal); var specEnd = specStart + s.Length; var ss = new SnapshotSpan(specStart, specEnd); return(new UE4SpecifierNotValidSuggestedAction( _textView.TextSnapshot.CreateTrackingSpan(ss.Span, SpanTrackingMode.EdgeInclusive), ue4Statement)); }).ToArray(), SuggestedActionSetPriority.None, ue4Statement.SpecifiersSpan); return(new[] { removeInvalid }); } return(Enumerable.Empty <SuggestedActionSet>()); }