private Model( DisconnectedBufferGraph disconnectedBufferGraph, IList <CompletionItem> totalItems, IList <CompletionItem> filteredItems, CompletionItem selectedItem, bool isHardSelection, bool isUnique, bool useSuggestionCompletionMode, CompletionItem builder, CompletionItem defaultBuilder, CompletionTriggerInfo triggerInfo, ITrackingPoint commitSpanEndPoint, bool dismissIfEmpty) { Contract.ThrowIfNull(selectedItem); Contract.ThrowIfFalse(totalItems.Count != 0, "Must have at least one item."); Contract.ThrowIfFalse(filteredItems.Count != 0, "Must have at least one filtered item."); Contract.ThrowIfFalse(filteredItems.Contains(selectedItem) || defaultBuilder == selectedItem, "Selected item must be in filtered items."); _disconnectedBufferGraph = disconnectedBufferGraph; this.TotalItems = totalItems; this.FilteredItems = filteredItems; this.SelectedItem = selectedItem; this.IsHardSelection = isHardSelection; this.IsUnique = isUnique; this.UseSuggestionCompletionMode = useSuggestionCompletionMode; this.Builder = builder; this.DefaultBuilder = defaultBuilder; this.TriggerInfo = triggerInfo; this.CommitTrackingSpanEndPoint = commitSpanEndPoint; this.DismissIfEmpty = dismissIfEmpty; }
public void TestEnter() { const string markup = @" class c { public int value {set; get; }} class d { void foo() { c foo = new c { v$$ } }"; using (var workspace = CSharpWorkspaceFactory.CreateWorkspaceFromFile(markup)) { var hostDocument = workspace.Documents.Single(); var position = hostDocument.CursorPosition.Value; var document = workspace.CurrentSolution.GetDocument(hostDocument.Id); var triggerInfo = CompletionTriggerInfo.CreateTypeCharTriggerInfo('a'); var completionList = GetCompletionList(document, position, triggerInfo); var item = completionList.Items.First(); var completionService = document.Project.LanguageServices.GetService <ICompletionService>(); var completionRules = completionService.GetCompletionRules(); Assert.False(completionRules.SendEnterThroughToEditor(item, string.Empty, workspace.Options), "Expected false from SendEnterThroughToEditor()"); } }
protected void VerifyCommitCharacters(string initialMarkup, string textTypedSoFar, char[] validChars, char[] invalidChars = null) { Assert.NotNull(validChars); invalidChars = invalidChars ?? new [] { 'x' }; using (var workspace = CSharpWorkspaceFactory.CreateWorkspaceFromFile(initialMarkup)) { var hostDocument = workspace.DocumentWithCursor; var documentId = workspace.GetDocumentId(hostDocument); var document = workspace.CurrentSolution.GetDocument(documentId); var position = hostDocument.CursorPosition.Value; var completionList = GetCompletionList(document, position, CompletionTriggerInfo.CreateInvokeCompletionTriggerInfo()); var item = completionList.Items.First(i => i.DisplayText.StartsWith(textTypedSoFar)); var completionService = document.Project.LanguageServices.GetService <ICompletionService>(); var completionRules = completionService.GetCompletionRules(); foreach (var ch in validChars) { Assert.True(completionRules.IsCommitCharacter(item, ch, textTypedSoFar), $"Expected '{ch}' to be a commit character"); } foreach (var ch in invalidChars) { Assert.False(completionRules.IsCommitCharacter(item, ch, textTypedSoFar), $"Expected '{ch}' NOT to be a commit character"); } } }
private void VerifyProviderCommitCheckResults(Document document, int position, string itemToCommit, string expectedCodeAfterCommit, char? commitCharOpt, string textTypedSoFar) { var textBuffer = WorkspaceFixture.Workspace.Documents.Single().TextBuffer; var textSnapshot = textBuffer.CurrentSnapshot.AsText(); var items = GetCompletionList(document, position, CompletionTriggerInfo.CreateInvokeCompletionTriggerInfo()).Items; var firstItem = items.First(i => CompareItems(i.DisplayText, itemToCommit)); var completionRules = GetCompletionRules(document); var commitChar = commitCharOpt ?? '\t'; var text = document.GetTextAsync().Result; if (commitChar == '\t' || completionRules.IsCommitCharacter(firstItem, commitChar, textTypedSoFar)) { var textChange = completionRules.GetTextChange(firstItem, commitChar, textTypedSoFar); // Adjust TextChange to include commit character, so long as it isn't TAB. if (commitChar != '\t') { textChange = new TextChange(textChange.Span, textChange.NewText.TrimEnd(commitChar) + commitChar); } text = text.WithChanges(textChange); } else { // nothing was committed, but we should insert the commit character. var textChange = new TextChange(new TextSpan(firstItem.FilterSpan.End, 0), commitChar.ToString()); text = text.WithChanges(textChange); } Assert.Equal(expectedCodeAfterCommit, text.ToString()); }
private Model( DisconnectedBufferGraph disconnectedBufferGraph, IList <CompletionItem> totalItems, IList <CompletionItem> filteredItems, CompletionItem selectedItem, ImmutableArray <CompletionItemFilter> completionItemFilters, ImmutableDictionary <CompletionItemFilter, bool> filterState, IReadOnlyDictionary <CompletionItem, string> completionItemToFilterText, bool isHardSelection, bool isUnique, bool useSuggestionCompletionMode, CompletionItem builder, CompletionItem defaultBuilder, CompletionTriggerInfo triggerInfo, ITrackingPoint commitSpanEndPoint, bool dismissIfEmpty) { Contract.ThrowIfFalse(totalItems.Count != 0, "Must have at least one item."); _disconnectedBufferGraph = disconnectedBufferGraph; this.TotalItems = totalItems; this.FilteredItems = filteredItems; this.FilterState = filterState; this.SelectedItem = selectedItem; this.CompletionItemFilters = completionItemFilters; this.CompletionItemToFilterText = completionItemToFilterText; this.IsHardSelection = isHardSelection; this.IsUnique = isUnique; this.UseSuggestionCompletionMode = useSuggestionCompletionMode; this.Builder = builder; this.DefaultBuilder = defaultBuilder; this.TriggerInfo = triggerInfo; this.CommitTrackingSpanEndPoint = commitSpanEndPoint; this.DismissIfEmpty = dismissIfEmpty; }
public override Task <ICompletionDataList> HandleCodeCompletionAsync(CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, CancellationToken token = default(CancellationToken)) { if (triggerInfo.TriggerCharacter == null) { return(null); } if (completionContext.TriggerOffset > 1 && (char.IsLetterOrDigit(Editor.GetCharAt(completionContext.TriggerOffset - 2)) || Editor.GetCharAt(completionContext.TriggerOffset - 2) == '_')) { return(null); } if (IsComment(completionContext) || IsString(completionContext)) { return(null); } if (IsCommand(completionContext)) { var list = new CompletionDataList(CMakeCompletionDataLists.Commands); list.TriggerWordLength = 1; return(Task.FromResult <ICompletionDataList> (list)); } return(null); }
private bool TryInvokeSnippetCompletion(TabKeyCommandArgs args, ICompletionService completionService) { var subjectBuffer = args.SubjectBuffer; var caretPoint = args.TextView.GetCaretPoint(subjectBuffer).Value.Position; var text = subjectBuffer.AsTextContainer().CurrentText; // Delete the ? and invoke completion Workspace workspace = null; if (Workspace.TryGetWorkspace(subjectBuffer.AsTextContainer(), out workspace)) { var documentId = workspace.GetDocumentIdInCurrentContext(subjectBuffer.AsTextContainer()); if (documentId != null) { var document = workspace.CurrentSolution.GetDocument(documentId); if (document != null) { var syntaxFacts = document.GetLanguageService <ISyntaxFactsService>(); if (caretPoint >= 2 && text[caretPoint - 1] == '?' && QuestionMarkIsPrecededByIdentifierAndWhitespace(text, caretPoint - 2, syntaxFacts)) { var textChange = new TextChange(TextSpan.FromBounds(caretPoint - 1, caretPoint), string.Empty); workspace.ApplyTextChanges(documentId, textChange, CancellationToken.None); this.StartNewModelComputation(completionService, CompletionTriggerInfo.CreateSnippetTriggerInfo(), filterItems: false); return(true); } } } } return(false); }
public IEnumerable <ISelectedCompletionData> GetCompletion(CompletionTriggerInfo trigger, int position) { if (trigger.TriggerCharacter == '.') { return(_simp.GetCompletionData()); } return(null); }
private bool MatchesFilterText( CompletionItem item, string filterText, ICompletionRules completionRules, CompletionTriggerInfo triggerInfo, CompletionFilterReason reason) { return(completionRules.MatchesFilterText(item, filterText, triggerInfo, reason) ?? false); }
public static async Task<CompletionList> GetCompletionListAsync(Document document, int position, CompletionTriggerInfo triggerInfo, OptionSet options = null, CancellationToken cancellationToken = default(CancellationToken)) { var providers = GetCompletionListProviders(document); var list = await InnerCompletionService.GetCompletionListAsync(document, position, triggerInfo.Inner, options, providers, cancellationToken).ConfigureAwait(false); return list == null ? null : new CompletionList(list); }
private async Task<IEnumerable<CompletionItem>> GetItemsAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken) { if (document == null) { return null; } return await GetItemsWorkerAsync(document, position, triggerInfo, cancellationToken).ConfigureAwait(false); }
public IEnumerable <CompletionItemGroup> GetGroups( IDocument document, int position, CompletionTriggerInfo triggerInfo, IEnumerable <ICompletionProvider> completionProviders, CancellationToken cancellationToken) { return(InvokeWrappedMethod <IEnumerable <CompletionItemGroup> >( MethodBase.GetCurrentMethod(), document, position, triggerInfo, completionProviders, cancellationToken)); }
private bool IsBetterFilterMatch( CompletionItem item, CompletionItem bestItem, string filterText, ICompletionRules completionRules, CompletionTriggerInfo triggerInfo, CompletionFilterReason filterReason) { return(completionRules.IsBetterFilterMatch(item, bestItem, filterText, triggerInfo, filterReason) ?? false); }
private bool StartNewModelComputation(ICompletionService completionService, CompletionTriggerInfo triggerInfo, bool filterItems, bool dismissIfEmptyAllowed = true) { AssertIsForeground(); Contract.ThrowIfTrue(sessionOpt != null); if (this.TextView.Selection.Mode == TextSelectionMode.Box) { Trace.WriteLine("Box selection, cannot have completion"); // No completion with multiple selection return(false); } // The caret may no longer be mappable into our subject buffer. var caret = TextView.GetCaretPoint(SubjectBuffer); if (!caret.HasValue) { Trace.WriteLine("Caret is not mappable to subject buffer, cannot have completion"); return(false); } if (this.TextView.Caret.Position.VirtualBufferPosition.IsInVirtualSpace) { // Convert any virtual whitespace to real whitespace by doing an empty edit at the caret position. _editorOperationsFactoryService.GetEditorOperations(TextView).InsertText(""); } var computation = new ModelComputation <Model>(this, PrioritizedTaskScheduler.AboveNormalInstance); this.sessionOpt = new Session(this, computation, GetCompletionRules(), Presenter.CreateSession(TextView, SubjectBuffer, null)); var completionProviders = triggerInfo.TriggerReason == CompletionTriggerReason.Snippets ? GetSnippetCompletionProviders() : GetCompletionProviders(); sessionOpt.ComputeModel(completionService, triggerInfo, GetOptions(), completionProviders); var filterReason = triggerInfo.TriggerReason == CompletionTriggerReason.BackspaceOrDeleteCommand ? CompletionFilterReason.BackspaceOrDelete : CompletionFilterReason.TypeChar; if (filterItems) { sessionOpt.FilterModel(filterReason, dismissIfEmptyAllowed: dismissIfEmptyAllowed); } else { sessionOpt.IdentifyBestMatchAndFilterToAllItems(filterReason, dismissIfEmptyAllowed: dismissIfEmptyAllowed); } return(true); }
public async Task <IList <CompletionItem> > GetCompletion(CompletionTriggerInfo trigger, int position) { var groups = await CompletionService.GetCompletionItemGroupsAsync( GetCurrentDocument(), position, trigger).ConfigureAwait(false); if (groups == null) { return(new CompletionItem[0]); } return(groups.SelectMany(t => t.Items).ToArray()); }
public CompletionItemGroup GetGroup(SourceText text, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken = default(CancellationToken)) { var items = this.GetItems(text, position, triggerInfo, cancellationToken); if (items == null || !items.Any()) { return(null); } return(new CompletionItemGroup(items)); }
private CompletionItemGroup GetCompletionGroup(string markup) { var provider = CreateProvider(); string code; int cursorPosition; MarkupTestFile.GetPosition(markup, out code, out cursorPosition); var document = CreateDocument(code); var triggerInfo = CompletionTriggerInfo.CreateInvokeCompletionTriggerInfo(); return(provider.GetGroupAsync(document, cursorPosition, triggerInfo, CancellationToken.None).Result); }
protected OptionSet GetOptions(Document document, CompletionTriggerInfo triggerInfo, AbstractSyntaxContext context) { var optionService = context.GetWorkspaceService <IOptionService>(); var filterOutOfScopeLocals = !triggerInfo.IsDebugger; var hideAdvancedMembers = document.ShouldHideAdvancedMembers(); var options = optionService .GetOptions() .WithChangedOption(RecommendationOptions.FilterOutOfScopeLocals, context.SemanticModel.Language, filterOutOfScopeLocals) .WithChangedOption(RecommendationOptions.HideAdvancedMembers, context.SemanticModel.Language, hideAdvancedMembers); return(options); }
bool ShouldTriggerCompletionOnCharTyped( WordAtPosition word, CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo) { if (session.IsCompletionTriggerCharacter(triggerInfo.TriggerCharacter)) { return(true); } return(ShouldTriggerCompletionAtPosition(word, completionContext)); }
private bool IsHardSelection( Model model, CompletionItem bestFilterMatch, ITextSnapshot textSnapshot, IList <ICompletionRules> completionRulesList, CompletionTriggerInfo triggerInfo, CompletionFilterReason reason) { if (model.Builder != null) { return(bestFilterMatch != null && bestFilterMatch.DisplayText == model.Builder.DisplayText); } if (bestFilterMatch == null || model.UseSuggestionCompletionMode) { return(false); } // We don't have a builder and we have a best match. Normally this will be hard // selected, except for a few cases. Specifically, if no filter text has been // provided, and this is not a preselect match then we will soft select it. This // happens when the completion list comes up implicitly and there is something in // the MRU list. In this case we do want to select it, but not with a hard // selection. Otherwise you can end up with the following problem: // // dim i as integer =<space> // // Completion will comes up after = with 'integer' selected (Because of MRU). We do // not want 'space' to commit this. var viewSpan = model.GetSubjectBufferFilterSpanInViewBuffer(bestFilterMatch.FilterSpan); var fullFilterText = model.GetCurrentTextInSnapshot(viewSpan, textSnapshot, endPoint: null); foreach (var completionRules in completionRulesList) { var shouldSoftSelect = completionRules.ShouldSoftSelectItem(GetExternallyUsableCompletionItem(bestFilterMatch), fullFilterText, triggerInfo); if (shouldSoftSelect == true) { return(false); } } // If the user moved the caret left after they started typing, the 'best' match may not match at all // against the full text span that this item would be replacing. if (!MatchesFilterText(bestFilterMatch, fullFilterText, completionRulesList, triggerInfo, reason)) { return(false); } // There was either filter text, or this was a preselect match. In either case, we // can hard select this. return(true); }
protected override async Task <IEnumerable <CompletionItem> > GetItemsWorkerAsync( Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.Completion_SymbolCompletionProvider_GetItemsWorker, cancellationToken)) { var regularItems = await GetItemsWorkerAsync(document, position, triggerInfo, preselect : false, cancellationToken : cancellationToken).ConfigureAwait(false); var preselectedItems = await GetItemsWorkerAsync(document, position, triggerInfo, preselect : true, cancellationToken : cancellationToken).ConfigureAwait(false); return(regularItems.Concat(preselectedItems)); } }
public async Task<CompletionItemGroup> GetGroupAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken = default(CancellationToken)) { var builder = await this.GetBuilderAsync(document, position, triggerInfo, cancellationToken).ConfigureAwait(false); if (builder == null) { return null; } return new CompletionItemGroup( SpecializedCollections.EmptyEnumerable<CompletionItem>(), builder, isExclusive: false); }
public async Task <CompletionResult> GetCompletionData(int position, char?triggerChar, bool useSignatureHelp) { IList <ICompletionDataEx> completionData = null; IOverloadProviderEx overloadProvider = null; bool?isCompletion = null; var document = _roslynHost.GetDocument(_documentId); if (useSignatureHelp || triggerChar != null) { var signatureHelpProvider = _roslynHost.GetService <ISignatureHelpProvider>(); var isSignatureHelp = useSignatureHelp || signatureHelpProvider.IsTriggerCharacter(triggerChar.Value); if (isSignatureHelp) { var signatureHelp = await signatureHelpProvider.GetItemsAsync( document, position, new SignatureHelpTriggerInfo( useSignatureHelp ? SignatureHelpTriggerReason.InvokeSignatureHelpCommand : SignatureHelpTriggerReason.TypeCharCommand, triggerChar)) .ConfigureAwait(false); if (signatureHelp != null) { overloadProvider = new RoslynOverloadProvider(signatureHelp); } } else { isCompletion = await CompletionService.IsCompletionTriggerCharacterAsync(document, position - 1).ConfigureAwait(false); } } if (overloadProvider == null && isCompletion != false) { var data = await CompletionService.GetCompletionListAsync( document, position, triggerChar != null ?CompletionTriggerInfo.CreateTypeCharTriggerInfo(triggerChar.Value) : CompletionTriggerInfo.CreateInvokeCompletionTriggerInfo() ).ConfigureAwait(false); completionData = data?.Items.Select(item => new RoslynCompletionData(item, _snippetService.SnippetManager)).ToArray <ICompletionDataEx>() ?? Array.Empty <ICompletionDataEx>(); } return(new CompletionResult(completionData, overloadProvider)); }
protected override async Task <IEnumerable <CompletionItem> > GetItemsWorkerAsync( Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken) { var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (syntaxTree.IsInNonUserCode(position, cancellationToken)) { return(null); } var token = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken); token = token.GetPreviousTokenIfTouchingWord(position); if (token.Kind() != SyntaxKind.OpenParenToken && token.Kind() != SyntaxKind.CommaToken) { return(null); } var attributeArgumentList = token.Parent as AttributeArgumentListSyntax; var attributeSyntax = token.Parent.Parent as AttributeSyntax; if (attributeSyntax == null || attributeArgumentList == null) { return(null); } // We actually want to collect two sets of named parameters to present the user. The // normal named parameters that come from the attribute constructors. These will be // presented like "foo:". And also the named parameters that come from the writable // fields/properties in the attribute. These will be presented like "bar =". var existingNamedParameters = GetExistingNamedParameters(attributeArgumentList, position); var workspace = document.Project.Solution.Workspace; var semanticModel = await document.GetSemanticModelForNodeAsync(attributeSyntax, cancellationToken).ConfigureAwait(false); var nameColonItems = await GetNameColonItemsAsync(workspace, semanticModel, position, token, attributeSyntax, existingNamedParameters, cancellationToken).ConfigureAwait(false); var nameEqualsItems = await GetNameEqualsItemsAsync(workspace, semanticModel, position, token, attributeSyntax, existingNamedParameters, cancellationToken).ConfigureAwait(false); // If we're after a name= parameter, then we only want to show name= parameters. if (IsAfterNameEqualsArgument(token)) { return(nameEqualsItems); } return(nameColonItems.Concat(nameEqualsItems)); }
private void VerifyItemWithMscorlib45Worker(string xmlString, string expectedItem, string expectedDescription) { using (var testWorkspace = TestWorkspaceFactory.CreateWorkspace(xmlString)) { var position = testWorkspace.Documents.Single(d => d.Name == "SourceDocument").CursorPosition.Value; var solution = testWorkspace.CurrentSolution; var documentId = testWorkspace.Documents.Single(d => d.Name == "SourceDocument").Id; var document = solution.GetDocument(documentId); var triggerInfo = new CompletionTriggerInfo(); var completionList = GetCompletionList(document, position, triggerInfo); var item = completionList.Items.FirstOrDefault(i => i.DisplayText == expectedItem); Assert.Equal(expectedDescription, item.GetDescriptionAsync().Result.GetFullText()); } }
private async Task CheckResultsAsync(Document document, int position, string expectedItemOrNull, string expectedDescriptionOrNull, bool usePreviousCharAsTrigger, bool checkForAbsence, Glyph?glyph) { var code = (await document.GetTextAsync()).ToString(); CompletionTriggerInfo triggerInfo = new CompletionTriggerInfo(); if (usePreviousCharAsTrigger) { triggerInfo = CompletionTriggerInfo.CreateTypeCharTriggerInfo(triggerCharacter: code.ElementAt(position - 1)); } var completionList = await GetCompletionListAsync(document, position, triggerInfo); var items = completionList == null ? default(ImmutableArray <CompletionItem>) : completionList.Items; if (checkForAbsence) { if (items == null) { return; } if (expectedItemOrNull == null) { Assert.Empty(items); } else { AssertEx.None( items, c => CompareItems(c.DisplayText, expectedItemOrNull) && (expectedDescriptionOrNull != null ? c.GetDescriptionAsync().Result.GetFullText() == expectedDescriptionOrNull : true)); } } else { if (expectedItemOrNull == null) { Assert.NotEmpty(items); } else { AssertEx.Any(items, c => CompareItems(c.DisplayText, expectedItemOrNull) && (expectedDescriptionOrNull != null ? c.GetDescriptionAsync().Result.GetFullText() == expectedDescriptionOrNull : true) && (glyph.HasValue ? c.Glyph == glyph.Value : true)); } } }
private void CheckResults(Document document, int position, string expectedItemOrNull, string expectedDescriptionOrNull, bool usePreviousCharAsTrigger, bool checkForAbsence, Glyph?glyph) { var code = document.GetTextAsync().Result.ToString(); CompletionTriggerInfo completionTriggerInfo = new CompletionTriggerInfo(); if (usePreviousCharAsTrigger) { completionTriggerInfo = CompletionTriggerInfo.CreateTypeCharTriggerInfo(triggerCharacter: code.ElementAt(position - 1)); } var group = CompletionProvider.GetGroupAsync(document, position, completionTriggerInfo).Result; var completions = group == null ? null : group.Items; if (checkForAbsence) { if (completions == null) { return; } if (expectedItemOrNull == null) { Assert.Empty(completions); } else { AssertEx.None( completions, c => CompareItems(c.DisplayText, expectedItemOrNull) && (expectedDescriptionOrNull != null ? c.GetDescriptionAsync().Result.GetFullText() == expectedDescriptionOrNull : true)); } } else { if (expectedItemOrNull == null) { Assert.NotEmpty(completions); } else { AssertEx.Any(completions, c => CompareItems(c.DisplayText, expectedItemOrNull) && (expectedDescriptionOrNull != null ? c.GetDescriptionAsync().Result.GetFullText() == expectedDescriptionOrNull : true) && (glyph.HasValue ? c.Glyph == glyph.Value : true)); } } }
private async Task VerifyExclusiveAsync(string markup, bool exclusive) { using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromFileAsync(markup)) { var hostDocument = workspace.Documents.Single(); var position = hostDocument.CursorPosition.Value; var document = workspace.CurrentSolution.GetDocument(hostDocument.Id); var triggerInfo = CompletionTriggerInfo.CreateTypeCharTriggerInfo('a'); var completionList = await GetCompletionListAsync(document, position, triggerInfo); if (completionList != null) { Assert.True(exclusive == completionList.IsExclusive, "group.IsExclusive == " + completionList.IsExclusive); } } }
public void ComputeModel( ICompletionService completionService, CompletionTriggerInfo triggerInfo, IEnumerable <CompletionListProvider> completionProviders, bool isDebugger) { AssertIsForeground(); // If we've already computed a model then we can just ignore this request and not // generate any tasks. if (this.Computation.InitialUnfilteredModel != null) { return; } new ModelComputer(this, completionService, triggerInfo, completionProviders, isDebugger).Do(); }
private IEnumerable <CompletionItem> GetItems(SourceText text, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken) { var line = text.Lines.GetLineFromPosition(position); var lineText = text.ToString(TextSpan.FromBounds(line.Start, position)); var match = s_directiveRegex.Match(lineText); if (!match.Success) { return(null); } var quotedPathGroup = match.Groups[1]; var quotedPath = quotedPathGroup.Value; var endsWithQuote = PathCompletionUtilities.EndsWithQuote(quotedPath); if (endsWithQuote && (position >= line.Start + match.Length)) { return(null); } var buffer = text.Container.GetTextBuffer(); var snapshot = text.FindCorrespondingEditorTextSnapshot(); if (snapshot == null) { return(null); } var fileSystem = PathCompletionUtilities.GetCurrentWorkingDirectoryDiscoveryService(snapshot); var searchPaths = ImmutableArray.Create <string>(fileSystem.CurrentDirectory); var helper = new FileSystemCompletionHelper( this, GetTextChangeSpan(text, position, quotedPathGroup), fileSystem, Glyph.OpenFolder, Glyph.CSharpFile, searchPaths: searchPaths, allowableExtensions: new[] { ".csx" }); var pathThroughLastSlash = this.GetPathThroughLastSlash(text, position, quotedPathGroup); return(helper.GetItems(pathThroughLastSlash, documentPath: null)); }
private void CheckResults(Document document, int position, bool isBuilder) { var triggerInfo = CompletionTriggerInfo.CreateTypeCharTriggerInfo('a'); var completionList = GetCompletionList(document, position, triggerInfo); if (isBuilder) { Assert.NotNull(completionList); Assert.NotNull(completionList.Builder); } else { if (completionList != null) { Assert.True(completionList.Builder == null, "group.Builder == " + (completionList.Builder != null ? completionList.Builder.DisplayText : "null")); } } }
bool ShouldTriggerCompletion( WordAtPosition word, CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo) { switch (triggerInfo.CompletionTriggerReason) { case CompletionTriggerReason.CharTyped: return(ShouldTriggerCompletionOnCharTyped(word, completionContext, triggerInfo)); case CompletionTriggerReason.BackspaceOrDeleteCommand: return(ShouldTriggerCompletionAtPosition(word, completionContext)); default: // Always trigger when Ctrl+Space typed. return(true); } }
private bool MatchesFilterText( CompletionItem item, string filterText, IList <ICompletionRules> completionRulesList, CompletionTriggerInfo triggerInfo, CompletionFilterReason reason) { foreach (var completionRule in completionRulesList) { var result = completionRule.MatchesFilterText(item, filterText, triggerInfo, reason); if (result.HasValue) { return(result.Value); } } return(false); }
private async Task<IEnumerable<CompletionItem>> GetItemsAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken) { if (document == null) { return null; } // If we were triggered by typign a character, then do a semantic check to make sure // we're still applicable. If not, then return immediately. if (triggerInfo.TriggerReason == CompletionTriggerReason.TypeCharCommand) { var isSemanticTriggerCharacter = await IsSemanticTriggerCharacterAsync(document, position - 1, cancellationToken).ConfigureAwait(false); if (!isSemanticTriggerCharacter) { return null; } } return await GetItemsWorkerAsync(document, position, triggerInfo, cancellationToken).ConfigureAwait(false); }
protected override async Task<IEnumerable<CompletionItem>> GetItemsWorkerAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken) { var workspace = document.Project.Solution.Workspace; var semanticModel = await document.GetSemanticModelForSpanAsync(new TextSpan(position, 0), cancellationToken).ConfigureAwait(false); var typeAndLocation = GetInitializedType(document, semanticModel, position, cancellationToken); if (typeAndLocation == null) { return null; } var initializedType = typeAndLocation.Item1 as INamedTypeSymbol; var initializerLocation = typeAndLocation.Item2; if (initializedType == null) { return null; } // Find the members that can be initialized. If we have a NamedTypeSymbol, also get the overridden members. IEnumerable<ISymbol> members = semanticModel.LookupSymbols(position, initializedType); members = members.Where(m => IsInitializable(m, initializedType) && m.CanBeReferencedByName && IsLegalFieldOrProperty(m) && !m.IsImplicitlyDeclared); // Filter out those members that have already been typed var alreadyTypedMembers = GetInitializedMembers(semanticModel.SyntaxTree, position, cancellationToken); var uninitializedMembers = members.Where(m => !alreadyTypedMembers.Contains(m.Name)); uninitializedMembers = uninitializedMembers.Where(m => m.IsEditorBrowsable(document.ShouldHideAdvancedMembers(), semanticModel.Compilation)); var text = await semanticModel.SyntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false); var changes = GetTextChangeSpan(text, position); // Return the members return uninitializedMembers.Select( m => CreateItem(workspace, m.Name, changes, CommonCompletionUtilities.CreateDescriptionFactory(workspace, semanticModel, initializerLocation.SourceSpan.Start, m), m.GetGlyph())); }
protected OptionSet GetOptions(Document document, CompletionTriggerInfo triggerInfo, AbstractSyntaxContext context) { var optionService = context.GetWorkspaceService<IOptionService>(); var filterOutOfScopeLocals = !triggerInfo.IsDebugger; var hideAdvancedMembers = document.ShouldHideAdvancedMembers(); var options = optionService .GetOptions() .WithChangedOption(RecommendationOptions.FilterOutOfScopeLocals, context.SemanticModel.Language, filterOutOfScopeLocals) .WithChangedOption(RecommendationOptions.HideAdvancedMembers, context.SemanticModel.Language, hideAdvancedMembers); return options; }
private async Task<IEnumerable<CompletionItem>> GetItemsWorkerAsync(Document document, int position, CompletionTriggerInfo triggerInfo, bool preselect, CancellationToken cancellationToken) { var relatedDocumentIds = document.GetLinkedDocumentIds(); var relatedDocuments = relatedDocumentIds.Concat(document.Id).Select(document.Project.Solution.GetDocument); lock (s_cacheGate) { // Invalidate the cache if it's for a different position or a different set of Documents. // It's fairly likely that we'll only have to check the first document, unless someone // specially constructed a Solution with mismatched linked files. if (s_cachedPosition != position || !relatedDocuments.All(s_cachedDocuments.ContainsKey)) { s_cachedPosition = position; s_cachedDocuments.Clear(); foreach (var related in relatedDocuments) { s_cachedDocuments.Add(related, null); } } } var context = await GetOrCreateContext(document, position, cancellationToken).ConfigureAwait(false); var options = GetOptions(document, triggerInfo, context); if (!relatedDocumentIds.Any()) { IEnumerable<ISymbol> itemsForCurrentDocument = await GetSymbolsWorker(position, preselect, context, options, cancellationToken).ConfigureAwait(false); itemsForCurrentDocument = itemsForCurrentDocument ?? SpecializedCollections.EmptyEnumerable<ISymbol>(); return await CreateItemsAsync(position, itemsForCurrentDocument, context, null, null, preselect, cancellationToken).ConfigureAwait(false); } var contextAndSymbolLists = await GetPerContextSymbols(document, position, options, relatedDocumentIds.Concat(document.Id), preselect, cancellationToken).ConfigureAwait(false); Dictionary<ISymbol, AbstractSyntaxContext> orignatingContextMap = null; var unionedSymbolsList = UnionSymbols(contextAndSymbolLists, out orignatingContextMap); var missingSymbolsMap = FindSymbolsMissingInLinkedContexts(unionedSymbolsList, contextAndSymbolLists); var totalProjects = contextAndSymbolLists.Select(t => t.Item1.ProjectId).ToList(); var textChangeSpan = await GetTextChangeSpanAsync(position, context, cancellationToken).ConfigureAwait(false); return CreateItems(position, unionedSymbolsList, textChangeSpan, orignatingContextMap, missingSymbolsMap, totalProjects, preselect: preselect, cancellationToken: cancellationToken); }
protected override async Task<IEnumerable<CompletionItem>> GetItemsWorkerAsync( Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.Completion_SymbolCompletionProvider_GetItemsWorker, cancellationToken)) { var regularItems = await GetItemsWorkerAsync(document, position, triggerInfo, preselect: false, cancellationToken: cancellationToken).ConfigureAwait(false); var preselectedItems = await GetItemsWorkerAsync(document, position, triggerInfo, preselect: true, cancellationToken: cancellationToken).ConfigureAwait(false); return regularItems.Concat(preselectedItems); } }
private async Task<IEnumerable<CompletionItem>> GetItemsWorkerAsync(Document document, int position, CompletionTriggerInfo triggerInfo, bool preselect, CancellationToken cancellationToken) { var context = await CreateContext(document, position, cancellationToken).ConfigureAwait(false); var options = GetOptions(document, triggerInfo, context); var relatedDocuments = document.GetLinkedDocumentIds(); if (!relatedDocuments.Any()) { IEnumerable<ISymbol> itemsForCurrentDocument = await GetSymbolsWorker(position, preselect, context, options, cancellationToken).ConfigureAwait(false); itemsForCurrentDocument = itemsForCurrentDocument ?? SpecializedCollections.EmptyEnumerable<ISymbol>(); return await CreateItemsAsync(position, itemsForCurrentDocument, context, null, null, preselect, cancellationToken).ConfigureAwait(false); } var contextAndSymbolLists = await GetPerContextSymbols(document, position, options, relatedDocuments.Concat(document.Id), preselect, cancellationToken).ConfigureAwait(false); Dictionary<ISymbol, AbstractSyntaxContext> orignatingContextMap = null; var unionedSymbolsList = UnionSymbols(contextAndSymbolLists, out orignatingContextMap); var missingSymbolsMap = FindSymbolsMissingInLinkedContexts(unionedSymbolsList, contextAndSymbolLists); var totalProjects = contextAndSymbolLists.Select(t => t.Item1.ProjectId).ToList(); var textChangeSpan = await GetTextChangeSpanAsync(position, context, cancellationToken).ConfigureAwait(false); return CreateItems(position, unionedSymbolsList, textChangeSpan, orignatingContextMap, missingSymbolsMap, totalProjects, preselect: preselect, cancellationToken: cancellationToken); }
protected virtual Task<CompletionItem> GetBuilderAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken) { return SpecializedTasks.Default<CompletionItem>(); }
protected abstract Task<IEnumerable<CompletionItem>> GetItemsWorkerAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken);
protected abstract Task<CompletionItem> GetBuilderAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken);
/// <summary> /// Returns a CompletionItemGroup for the specified position in the text. /// </summary> public abstract CompletionList GetCompletionList(SourceText text, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken = default(CancellationToken));
protected virtual Task<bool> IsExclusiveAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken) { return SpecializedTasks.False; }