예제 #1
0
        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;
 }
예제 #4
0
            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();
                }
            }
예제 #5
0
            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);
                }
            }
예제 #6
0
            /// <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);
            }
예제 #10
0
 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);
            }
예제 #14
0
        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>());
        }