protected override void CompleteDialogExtention()
        {
            base.CompleteDialogExtention();

            CompletionOptions.Add(new XrmButtonViewModel("Option 1", () => ApplicationController.UserMessage("Dummy"), ApplicationController));
            CompletionOptions.Add(new XrmButtonViewModel("option 2", () => ApplicationController.UserMessage("Dummy 2"), ApplicationController));
        }
Ejemplo n.º 2
0
        internal sealed override async Task <CompletionDescription> GetDescriptionWorkerAsync(
            Document document, CompletionItem item, CompletionOptions options, SymbolDescriptionOptions displayOptions, CancellationToken cancellationToken)
        {
            var description = await GetDescriptionAsync(item, document, displayOptions, cancellationToken).ConfigureAwait(false);

            return(UpdateDescription(description));
        }
Ejemplo n.º 3
0
        internal override CompletionRules GetRules(CompletionOptions options)
        {
            var enterRule   = options.EnterKeyBehavior;
            var snippetRule = options.SnippetsBehavior;

            // Although EnterKeyBehavior is a per-language setting, the meaning of an unset setting (Default) differs between C# and VB
            // In C# the default means Never to maintain previous behavior
            if (enterRule == EnterKeyRule.Default)
            {
                enterRule = EnterKeyRule.Never;
            }

            if (snippetRule == SnippetsRule.Default)
            {
                snippetRule = SnippetsRule.AlwaysInclude;
            }

            // use interlocked + stored rules to reduce # of times this gets created when option is different than default
            var newRules = _latestRules.WithDefaultEnterKeyRule(enterRule)
                           .WithSnippetsRule(snippetRule);

            Interlocked.Exchange(ref _latestRules, newRules);

            return(newRules);
        }
Ejemplo n.º 4
0
            public CompletionListUpdater(
                IAsyncCompletionSession session,
                AsyncCompletionSessionDataSnapshot data,
                RecentItemsManager recentItemsManager,
                IGlobalOptionService globalOptions)
            {
                _session            = session;
                _data               = data;
                _recentItemsManager = recentItemsManager;

                _filterText = _session.ApplicableToSpan.GetText(_data.Snapshot);

                if (!_session.Properties.TryGetProperty(CompletionSource.HasSuggestionItemOptions, out bool hasSuggestedItemOptions))
                {
                    // This is the scenario when the session is created out of Roslyn, in some other provider, e.g. in Debugger.
                    // For now, the default hasSuggestedItemOptions is false.
                    hasSuggestedItemOptions = false;
                }

                _hasSuggestedItemOptions = hasSuggestedItemOptions || _data.DisplaySuggestionItem;

                // We prefer using the original snapshot, which should always be available from items provided by Roslyn's CompletionSource.
                // Only use data.Snapshot in the theoretically possible but rare case when all items we are handling are from some non-Roslyn CompletionSource.
                var snapshotForDocument = TryGetInitialTriggerLocation(_data, out var intialTriggerLocation)
                    ? intialTriggerLocation.Snapshot
                    : _data.Snapshot;

                _document = snapshotForDocument?.TextBuffer.AsTextContainer().GetOpenDocumentInCurrentContext();
                if (_document != null)
                {
                    _completionService = _document.GetLanguageService <CompletionService>();
                    _completionRules   = _completionService?.GetRules(CompletionOptions.From(_document.Project)) ?? CompletionRules.Default;

                    // Let us make the completion Helper used for non-Roslyn items case-sensitive.
                    // We can change this if get requests from partner teams.
                    _completionHelper = CompletionHelper.GetHelper(_document);
                    _filterMethod     = _completionService == null
                        ? ((itemsWithPatternMatches, text) => CompletionService.FilterItems(_completionHelper, itemsWithPatternMatches, text))
                        : ((itemsWithPatternMatches, text) => _completionService.FilterItems(_document, itemsWithPatternMatches, text));

                    // Nothing to highlight if user hasn't typed anything yet.
                    _highlightMatchingPortions = _filterText.Length > 0 &&
                                                 globalOptions.GetOption(CompletionViewOptions.HighlightMatchingPortionsOfCompletionListItems, _document.Project.Language);

                    _showCompletionItemFilters = globalOptions.GetOption(CompletionViewOptions.ShowCompletionItemFilters, _document.Project.Language);
                }
                else
                {
                    _completionService = null;
                    _completionRules   = CompletionRules.Default;

                    // Let us make the completion Helper used for non-Roslyn items case-sensitive.
                    // We can change this if get requests from partner teams.
                    _completionHelper = new CompletionHelper(isCaseSensitive: true);
                    _filterMethod     = (itemsWithPatternMatches, text) => CompletionService.FilterItems(_completionHelper, itemsWithPatternMatches, text);

                    _highlightMatchingPortions = false;
                    _showCompletionItemFilters = true;
                }
            }
        internal override async Task <CompletionDescription> GetDescriptionWorkerAsync(
            Document document, CompletionItem item, CompletionOptions options, SymbolDescriptionOptions displayOptions, CancellationToken cancellationToken)
        {
            var position = SymbolCompletionItem.GetContextPosition(item);

            // What EditorBrowsable settings were we previously passed in (if it mattered)?
            if (item.Properties.TryGetValue(HideAdvancedMembers, out var hideAdvancedMembersString) &&
                bool.TryParse(hideAdvancedMembersString, out var hideAdvancedMembers))
            {
                options = options with {
                    HideAdvancedMembers = hideAdvancedMembers
                };
            }

            var(token, semanticModel, symbols) = await GetSymbolsAsync(document, position, options, cancellationToken).ConfigureAwait(false);

            if (symbols.Length == 0)
            {
                return(CompletionDescription.Empty);
            }

            Contract.ThrowIfNull(semanticModel);

            var name        = SymbolCompletionItem.GetSymbolName(item);
            var kind        = SymbolCompletionItem.GetKind(item);
            var bestSymbols = symbols.WhereAsArray(s => s.Kind == kind && s.Name == name);

            return(await SymbolCompletionItem.GetDescriptionAsync(item, bestSymbols, document, semanticModel, displayOptions, cancellationToken).ConfigureAwait(false));
        }
Ejemplo n.º 6
0
        public async Task GettingCompletionListShoudNotRunSourceGenerator(bool forkBeforeFreeze)
        {
            var sourceMarkup = @"
using System;

namespace N
{
    public class C1
    {
        $$
    }
}";

            MarkupTestFile.GetPosition(sourceMarkup.NormalizeLineEndings(), out var source, out int?position);

            var generatorRanCount = 0;
            var generator         = new CallbackGenerator(onInit: _ => { }, onExecute: _ => Interlocked.Increment(ref generatorRanCount));

            using var workspace = WorkspaceTestUtilities.CreateWorkspaceWithPartialSemantics();
            var analyzerReference = new TestGeneratorReference(generator);
            var project           = SolutionUtilities.AddEmptyProject(workspace.CurrentSolution)
                                    .AddAnalyzerReference(analyzerReference)
                                    .AddDocument("Document1.cs", sourceMarkup, filePath: "Document1.cs").Project;

            Assert.True(workspace.SetCurrentSolution(_ => project.Solution, WorkspaceChangeKind.SolutionChanged));

            var document          = workspace.CurrentSolution.Projects.Single().Documents.Single();
            var compeltionService = document.GetLanguageService <CompletionService>();

            Assert.Equal(0, generatorRanCount);

            if (forkBeforeFreeze)
            {
                // Forking before freezing means we'll have to do extra work to produce the final compilation,
                // but we should still not be running generators.
                document = document.WithText(SourceText.From(sourceMarkup.Replace("C1", "C2")));
            }

            // We want to make sure import completion providers are also participating.
            var options    = CompletionOptions.From(document.Project.Solution.Options, document.Project.Language);
            var newOptions = options with {
                ShowItemsFromUnimportedNamespaces = true
            };

            var(completionList, _) = await compeltionService.GetCompletionsInternalAsync(document, position.Value, options : newOptions);

            // We expect completion to run on frozen partial semantic, which won't run source generator.
            Assert.Equal(0, generatorRanCount);

            var expectedItem = forkBeforeFreeze ? "C2" : "C1";

            Assert.True(completionList.Items.Select(item => item.DisplayText).Contains(expectedItem));
        }
    }
Ejemplo n.º 7
0
        public override InitializeResult OnInitialize(InitializeParams parameters)
        {
            this.RemoteConsole.NoLogsMessageNotification = NoLogsMessageNotification;
            var    rootDirectory = new DirectoryInfo(parameters.rootPath);
            string workspaceName = rootDirectory.Name + "#" + parameters.processId;

            // Initialize the workspace
            typeCobolWorkspace = new Workspace(rootDirectory.FullName, workspaceName, _MessagesActionsQueue, Logger);
            //Propagate LSR testing options.
            if (LsrSourceTesting)
            {
                typeCobolWorkspace.IsLsrSourceTesting = LsrSourceTesting;
            }
            if (LsrScannerTesting)
            {
                typeCobolWorkspace.IsLsrScannerTesting = LsrScannerTesting;
            }
            if (LsrPreprocessTesting)
            {
                typeCobolWorkspace.IsLsrPreprocessinTesting = LsrPreprocessTesting;
            }
            if (LsrParserTesting)
            {
                typeCobolWorkspace.IsLsrParserTesting = LsrParserTesting;
            }
            if (LsrSemanticTesting)
            {
                typeCobolWorkspace.IsLsrSemanticTesting = LsrSemanticTesting;
            }

            typeCobolWorkspace.UseAntlrProgramParsing = UseAntlrProgramParsing;
            typeCobolWorkspace.TimerDisabledOption    = TimerDisabledOption;
            typeCobolWorkspace.LoadingIssueEvent     += LoadingIssueDetected;
            typeCobolWorkspace.ExceptionTriggered    += ExceptionTriggered;
            typeCobolWorkspace.WarningTrigger        += WarningTrigger;
            // Return language server capabilities
            var initializeResult = base.OnInitialize(parameters);

            initializeResult.capabilities.textDocumentSync = TextDocumentSyncKind.Incremental;
            initializeResult.capabilities.hoverProvider    = true;
            CompletionOptions completionOptions = new CompletionOptions();

            completionOptions.resolveProvider   = false;
            completionOptions.triggerCharacters = new string[] { "::" };
            initializeResult.capabilities.completionProvider = completionOptions;
            SignatureHelpOptions sigHelpOptions = new SignatureHelpOptions {
                triggerCharacters = new string[0]
            };

            initializeResult.capabilities.signatureHelpProvider = sigHelpOptions;

            return(initializeResult);
        }
Ejemplo n.º 8
0
        public void SimpleTest(string expected)
        {
            var model = new CompletionOptions {
                ResolveProvider = false,
            };
            var result = Fixture.SerializeObject(model);

            result.Should().Be(expected);

            var deresult = new Serializer(ClientVersion.Lsp3).DeserializeObject <CompletionOptions>(expected);

            deresult.Should().BeEquivalentTo(model);
        }
        public override CompletionInfo GetCompletionItems(int position, CompletionOptions options, CancellationToken cancellationToken)
        {
            var result = _service.GetCompletionItems(position - _offset, options, cancellationToken);

            if (_offset > 0)
            {
                return(new CompletionInfo(result.Items, result.EditStart + _offset, result.EditLength));
            }
            else
            {
                return(result);
            }
        }
Ejemplo n.º 10
0
        public void SimpleTest(string expected)
        {
            var model = new CompletionOptions()
            {
                ResolveProvider = false,
            };
            var result = Fixture.SerializeObject(model);

            result.Should().Be(expected);

            var deresult = JsonConvert.DeserializeObject <CompletionOptions>(expected);

            deresult.ShouldBeEquivalentTo(model);
        }
Ejemplo n.º 11
0
        public static CompletionOptions GetOptions(this ICompletionSession session, IServiceProvider serviceProvider)
        {
            var pyService = serviceProvider.GetPythonToolsService();

            var options = new CompletionOptions {
                ConvertTabsToSpaces = session.TextView.Options.IsConvertTabsToSpacesEnabled(),
                IndentSize          = session.TextView.Options.GetIndentSize(),
                TabSize             = session.TextView.Options.GetTabSize(),
                IntersectMembers    = pyService.AdvancedOptions.IntersectMembers,
                HideAdvancedMembers = pyService.LangPrefs.HideAdvancedMembers,
                FilterCompletions   = pyService.AdvancedOptions.FilterCompletions,
            };

            return(options);
        }
Ejemplo n.º 12
0
        public override CompletionInfo GetCompletionItems(int position, CompletionOptions options = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (this.TryGetBoundCode(cancellationToken, true, out var code) && code.HasSemantics)
            {
                // have try-catch to keep editor from crashing from parser bugs
                try
                {
                    return(new KustoCompleter(code, options ?? CompletionOptions.Default, cancellationToken)
                           .GetCompletionItems(position));
                }
                catch (Exception)
                {
                }
            }

            return(CompletionInfo.Empty);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Initializes a new instance with the specified properties.
        /// </summary>
        /// <param name="moniker">The unique, non-localized identifier for the
        /// completion set.</param>
        /// <param name="displayName">The localized name of the completion set.
        /// </param>
        /// <param name="applicableTo">The tracking span to which the
        /// completions apply.</param>
        /// <param name="completions">The list of completions.</param>
        /// <param name="options">The options to use for filtering and
        /// selecting items.</param>
        /// <param name="comparer">The comparer to use to order the provided
        /// completions.</param>
        /// <param name="matchInsertionText">If true, matches user input against
        /// the insertion text; otherwise, uses the display text.</param>
        public FuzzyCompletionSet(
            string moniker,
            string displayName,
            ITrackingSpan applicableTo,
            IEnumerable <DynamicallyVisibleCompletion> completions,
            CompletionOptions options,
            IComparer <Completion> comparer,
            bool matchInsertionText = false
            ) :
            base(moniker, displayName, applicableTo, null, null)
        {
            _matchInsertionText = matchInsertionText;
            _completions        = new BulkObservableCollection <Completion>();
            _completions.AddRange(completions
                                  .Where(c => c != null && !string.IsNullOrWhiteSpace(c.DisplayText))
                                  .OrderBy(c => c, comparer)
                                  );
            _comparer = new FuzzyStringMatcher(FuzzyMatchMode.Default);

            _shouldFilter       = options.FilterCompletions;
            _shouldHideAdvanced = options.HideAdvancedMembers && !_completions.All(IsAdvanced);

            if (!_completions.Any())
            {
                _completions = null;
            }

            if (_completions != null && _shouldFilter | _shouldHideAdvanced)
            {
                _filteredCompletions = new FilteredObservableCollection <Completion>(_completions);

                foreach (var c in _completions.Cast <DynamicallyVisibleCompletion>())
                {
                    c.Visible = !_shouldHideAdvanced || !IsAdvanced(c);
                }
                _filteredCompletions.Filter(IsVisible);
            }

            CommitByDefault = DefaultCommitByDefault;
        }
        private async Task CreateSpellCheckCodeIssueAsync(
            CodeFixContext context, SyntaxToken nameToken, bool isGeneric, CancellationToken cancellationToken)
        {
            var document = context.Document;
            var service  = CompletionService.GetService(document);

            // Disable snippets and unimported types from ever appearing in the completion items.
            // -    It's very unlikely the user would ever misspell a snippet, then use spell-checking to fix it,
            //      then try to invoke the snippet.
            // -    We believe spell-check should only compare what you have typed to what symbol would be offered here.
            var options = CompletionOptions.From(document.Project.Solution.Options, document.Project.Language) with
            {
                SnippetsBehavior = SnippetsRule.NeverInclude,
                ShowItemsFromUnimportedNamespaces = false,
                IsExpandedCompletion        = false,
                TargetTypedCompletionFilter = false
            };

            var(completionList, _) = await service.GetCompletionsInternalAsync(
                document, nameToken.SpanStart, options, cancellationToken : cancellationToken).ConfigureAwait(false);

            if (completionList == null)
            {
                return;
            }

            var nameText          = nameToken.ValueText;
            var similarityChecker = WordSimilarityChecker.Allocate(nameText, substringsAreSimilar: true);

            try
            {
                await CheckItemsAsync(
                    context, nameToken, isGeneric,
                    completionList, similarityChecker).ConfigureAwait(false);
            }
            finally
            {
                similarityChecker.Free();
            }
        }
        public async Task <(ImmutableArray <ImmutableArray <CompletionItem> >, bool)> GetAllTopLevelTypesAsync(
            Project currentProject,
            SyntaxContext syntaxContext,
            bool forceCacheCreation,
            CompletionOptions options,
            CancellationToken cancellationToken)
        {
            var(getCacheResults, isPartialResult) = await GetCacheEntriesAsync(currentProject, forceCacheCreation, cancellationToken).ConfigureAwait(false);

            var currentCompilation = await currentProject.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false);

            return(getCacheResults.SelectAsArray(GetItemsFromCacheResult), isPartialResult);

            ImmutableArray <CompletionItem> GetItemsFromCacheResult(TypeImportCompletionCacheEntry cacheEntry)
            => cacheEntry.GetItemsForContext(
                currentCompilation,
                Language,
                GenericTypeSuffix,
                syntaxContext.IsAttributeNameContext,
                IsCaseSensitive,
                options.HideAdvancedMembers);
        }
 public override bool IsInsertionTrigger(SourceText text, int insertedCharacterPosition, CompletionOptions options)
 => CompletionUtilities.IsTriggerAfterSpaceOrStartOfWordCharacter(text, insertedCharacterPosition, options);
Ejemplo n.º 17
0
        /// <param name="kind">The type of template tag we are processing</param>
        /// <param name="templateText">The text of the template tag which we are offering a completion in</param>
        /// <param name="templateStart">The offset in the buffer where the template starts</param>
        /// <param name="triggerPoint">The point in the buffer where the completion was triggered</param>
        internal CompletionSet GetCompletionSet(CompletionOptions options, VsProjectAnalyzer analyzer, TemplateTokenKind kind, string templateText, int templateStart, SnapshotPoint triggerPoint, out ITrackingSpan applicableSpan)
        {
            int position = triggerPoint.Position - templateStart;
            IEnumerable <CompletionInfo> tags;
            IDjangoCompletionContext     context;

            applicableSpan = GetWordSpan(templateText, templateStart, triggerPoint);

            switch (kind)
            {
            case TemplateTokenKind.Block:
                var block = DjangoBlock.Parse(templateText);
                if (block != null)
                {
                    if (position <= block.ParseInfo.Start + block.ParseInfo.Command.Length)
                    {
                        // we are completing before the command
                        // TODO: Return a new set of tags?  Do nothing?  Do this based upon ctrl-space?
                        tags = FilterBlocks(CompletionInfo.ToCompletionInfo(analyzer.GetTags(), StandardGlyphGroup.GlyphKeyword), triggerPoint);
                    }
                    else
                    {
                        // we are in the arguments, let the block handle the completions
                        context = new ProjectBlockCompletionContext(analyzer, _buffer);
                        tags    = block.GetCompletions(context, position);
                    }
                }
                else
                {
                    // no tag entered yet, provide the known list of tags.
                    tags = FilterBlocks(CompletionInfo.ToCompletionInfo(analyzer.GetTags(), StandardGlyphGroup.GlyphKeyword), triggerPoint);
                }
                break;

            case TemplateTokenKind.Variable:
                var variable = DjangoVariable.Parse(templateText);
                context = new ProjectBlockCompletionContext(analyzer, _buffer);
                if (variable != null)
                {
                    tags = variable.GetCompletions(context, position);
                }
                else
                {
                    // show variable names
                    tags = CompletionInfo.ToCompletionInfo(context.Variables, StandardGlyphGroup.GlyphGroupVariable);
                }

                break;

            default:
                throw new InvalidOperationException();
            }

            var completions = tags
                              .OrderBy(tag => tag.DisplayText, StringComparer.OrdinalIgnoreCase)
                              .Select(tag => new DynamicallyVisibleCompletion(
                                          tag.DisplayText,
                                          tag.InsertionText,
                                          StripDocumentation(tag.Documentation),
                                          _glyphService.GetGlyph(tag.Glyph, StandardGlyphItem.GlyphItemPublic),
                                          "tag"));

            return(new FuzzyCompletionSet(
                       "PythonDjangoTags",
                       Resources.DjangoTagsCompletionSetDisplayName,
                       applicableSpan,
                       completions,
                       options,
                       CompletionComparer.UnderscoresLast));
        }
Ejemplo n.º 18
0
 public override bool IsInsertionTrigger(SourceText text, int characterPosition, CompletionOptions options)
 => text[characterPosition] is ('<' or '"') ||
Ejemplo n.º 19
0
 public override bool IsInsertionTrigger(SourceText text, int characterPosition, CompletionOptions options)
 => CompletionUtilities.IsTriggerCharacter(text, characterPosition, options);
Ejemplo n.º 20
0
 internal override CompletionRules GetRules(CompletionOptions options)
 => CompletionRules.Default;
Ejemplo n.º 21
0
 public override CompletionInfo GetCompletionItems(int position, CompletionOptions options, CancellationToken cancellationToken)
 {
     return(CompletionInfo.Empty);
 }
 private protected override Task VerifyWorkerAsync(
     string code, int position, string expectedItemOrNull, string expectedDescriptionOrNull,
     SourceCodeKind sourceCodeKind, bool usePreviousCharAsTrigger, bool checkForAbsence,
     int?glyph, int?matchPriority, bool?hasSuggestionItem, string displayTextSuffix,
     string displayTextPrefix, string inlineDescription, bool?isComplexTextEdit,
     List <CompletionFilter> matchingFilters, CompletionItemFlags?flags = null, CompletionOptions options = null, bool skipSpeculation = false)
 {
     return(base.VerifyWorkerAsync(code, position,
                                   expectedItemOrNull, expectedDescriptionOrNull,
                                   SourceCodeKind.Regular, usePreviousCharAsTrigger, checkForAbsence,
                                   glyph, matchPriority, hasSuggestionItem, displayTextSuffix,
                                   displayTextPrefix, inlineDescription, isComplexTextEdit, matchingFilters, flags, options));
 }
        public sealed override bool IsInsertionTrigger(SourceText text, int insertedCharacterPosition, CompletionOptions options)
        {
            // Should trigger in these cases ($$ is the cursor position)
            // [InternalsVisibleTo($$         -> user enters "
            // [InternalsVisibleTo("$$")]     -> user enters any character
            var ch = text[insertedCharacterPosition];

            if (ch == '\"')
            {
                return(true);
            }
            else
            {
                if (insertedCharacterPosition > 0)
                {
                    ch = text[insertedCharacterPosition - 1];
                    if (ch == '\"')
                    {
                        return(ShouldTriggerAfterQuotes(text, insertedCharacterPosition));
                    }
                }
            }

            return(false);
        }
        internal sealed override bool ShouldTriggerCompletion(HostLanguageServices languageServices, SourceText text, int caretPosition, CompletionTrigger trigger, CompletionOptions options)
        {
            foreach (var language in GetLanguageProviders(languageServices))
            {
                var completionProvider = (language as IEmbeddedLanguageFeatures)?.CompletionProvider;
                if (completionProvider != null)
                {
                    if (completionProvider.ShouldTriggerCompletion(text, caretPosition, trigger))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
 internal override Task <CompletionDescription?> GetDescriptionAsync(Document document, CompletionItem item, CompletionOptions options, SymbolDescriptionOptions displayOptions, CancellationToken cancellationToken)
 => GetLanguage(item).CompletionProvider.GetDescriptionAsync(document, item, cancellationToken);
 public override bool IsInsertionTrigger(SourceText text, int insertedCharacterPosition, CompletionOptions options)
 {
     return(_provider.IsInsertionTrigger(text, insertedCharacterPosition));
 }
 internal sealed override bool ShouldTriggerCompletion(HostLanguageServices languageServices, SourceText text, int caretPosition, CompletionTrigger trigger, CompletionOptions options, OptionSet passThroughOptions)
 => ShouldTriggerCompletionImpl(text, caretPosition, trigger, options.TriggerOnTypingLetters);
Ejemplo n.º 28
0
        protected override async Task <ImmutableArray <(ISymbol symbol, bool preselect)> > GetSymbolsAsync(
            CompletionContext?completionContext, CSharpSyntaxContext context, int position, CompletionOptions options, CancellationToken cancellationToken)
        {
            var result = await base.GetSymbolsAsync(completionContext, context, position, options, cancellationToken).ConfigureAwait(false);

            if (result.Any())
            {
                var type  = (ITypeSymbol)result.Single().symbol;
                var alias = await type.FindApplicableAliasAsync(position, context.SemanticModel, cancellationToken).ConfigureAwait(false);

                if (alias != null)
                {
                    return(ImmutableArray.Create((alias, result.Single().preselect)));
                }
            }

            return(result);
        }
 internal override Task <CompletionDescription> GetDescriptionWorkerAsync(Document document, CompletionItem item, CompletionOptions options, SymbolDescriptionOptions displayOptions, CancellationToken cancellationToken)
 => ImportCompletionItem.GetCompletionDescriptionAsync(document, item, displayOptions, cancellationToken);
Ejemplo n.º 30
0
        public async Task <LSP.CompletionItem> HandleRequestAsync(LSP.CompletionItem completionItem, RequestContext context, CancellationToken cancellationToken)
        {
            var document = context.Document;

            Contract.ThrowIfNull(document);

            var completionService = document.Project.LanguageServices.GetRequiredService <CompletionService>();
            var cacheEntry        = GetCompletionListCacheEntry(completionItem);

            if (cacheEntry == null)
            {
                // Don't have a cache associated with this completion item, cannot resolve.
                context.TraceInformation("No cache entry found for the provided completion item at resolve time.");
                return(completionItem);
            }

            var list = cacheEntry.CompletionList;

            // Find the matching completion item in the completion list
            var selectedItem = list.Items.FirstOrDefault(cachedCompletionItem => MatchesLSPCompletionItem(completionItem, cachedCompletionItem));

            if (selectedItem == null)
            {
                return(completionItem);
            }

            var options        = CompletionOptions.From(document.Project);
            var displayOptions = SymbolDescriptionOptions.From(document.Project);
            var description    = await completionService.GetDescriptionAsync(document, selectedItem, options, displayOptions, cancellationToken).ConfigureAwait(false) !;

            if (description != null)
            {
                var supportsVSExtensions = context.ClientCapabilities.HasVisualStudioLspCapability();
                if (supportsVSExtensions)
                {
                    var vsCompletionItem = (LSP.VSInternalCompletionItem)completionItem;
                    vsCompletionItem.Description = new ClassifiedTextElement(description.TaggedParts
                                                                             .Select(tp => new ClassifiedTextRun(tp.Tag.ToClassificationTypeName(), tp.Text)));
                }
                else
                {
                    var clientSupportsMarkdown = context.ClientCapabilities.TextDocument?.Completion?.CompletionItem?.DocumentationFormat.Contains(LSP.MarkupKind.Markdown) == true;
                    completionItem.Documentation = ProtocolConversions.GetDocumentationMarkupContent(description.TaggedParts, document, clientSupportsMarkdown);
                }
            }

            // We compute the TextEdit resolves for complex text edits (e.g. override and partial
            // method completions) here. Lazily resolving TextEdits is technically a violation of
            // the LSP spec, but is currently supported by the VS client anyway. Once the VS client
            // adheres to the spec, this logic will need to change and VS will need to provide
            // official support for TextEdit resolution in some form.
            if (selectedItem.IsComplexTextEdit)
            {
                Contract.ThrowIfTrue(completionItem.InsertText != null);
                Contract.ThrowIfTrue(completionItem.TextEdit != null);

                var snippetsSupported = context.ClientCapabilities.TextDocument?.Completion?.CompletionItem?.SnippetSupport ?? false;

                completionItem.TextEdit = await GenerateTextEditAsync(
                    document, completionService, selectedItem, snippetsSupported, cancellationToken).ConfigureAwait(false);
            }

            return(completionItem);
        }