diff --git a/src/EditorFeatures/Core/EditorFeatures.csproj b/src/EditorFeatures/Core/EditorFeatures.csproj
index 77f4543178928c6e58c1dbfc619e4096041fbca0..91a08e3f711d206587f6666b6adda09bb0084af1 100644
--- a/src/EditorFeatures/Core/EditorFeatures.csproj
+++ b/src/EditorFeatures/Core/EditorFeatures.csproj
@@ -199,13 +199,12 @@
-
+
-
@@ -268,7 +267,6 @@
-
@@ -475,7 +473,6 @@
-
@@ -783,4 +780,4 @@
-
+
\ No newline at end of file
diff --git a/src/EditorFeatures/Core/Extensibility/Completion/CompletionItemEventArgs.cs b/src/EditorFeatures/Core/Extensibility/Completion/CompletionItemEventArgs.cs
new file mode 100644
index 0000000000000000000000000000000000000000..ef07a437a7d408adcaf3b3eb928c1ad7c960f538
--- /dev/null
+++ b/src/EditorFeatures/Core/Extensibility/Completion/CompletionItemEventArgs.cs
@@ -0,0 +1,18 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.CodeAnalysis.Completion;
+
+namespace Microsoft.CodeAnalysis.Editor
+{
+ internal class CompletionItemEventArgs : EventArgs
+ {
+ public CompletionItem CompletionItem { get; }
+
+ public CompletionItemEventArgs(
+ CompletionItem completionItem)
+ {
+ CompletionItem = completionItem;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/EditorFeatures/Core/Extensibility/Completion/ICompletionPresenterSession.cs b/src/EditorFeatures/Core/Extensibility/Completion/ICompletionPresenterSession.cs
index bbbb118789fb604b7dcf099cf93e0af857f34415..46f9473ee9bbaf2b1af8b595663bd10792665afd 100644
--- a/src/EditorFeatures/Core/Extensibility/Completion/ICompletionPresenterSession.cs
+++ b/src/EditorFeatures/Core/Extensibility/Completion/ICompletionPresenterSession.cs
@@ -11,8 +11,8 @@ namespace Microsoft.CodeAnalysis.Editor
internal interface ICompletionPresenterSession : IIntelliSensePresenterSession
{
void PresentItems(
- ITrackingSpan triggerSpan, IList items, PresentationItem selectedItem,
- PresentationItem suggestionModeItem, bool suggestionMode, bool isSoftSelected,
+ ITrackingSpan triggerSpan, IList items, CompletionItem selectedItem,
+ CompletionItem suggestionModeItem, bool suggestionMode, bool isSoftSelected,
ImmutableArray completionItemFilters,
string filterText);
@@ -21,8 +21,8 @@ internal interface ICompletionPresenterSession : IIntelliSensePresenterSession
void SelectPreviousPageItem();
void SelectNextPageItem();
- event EventHandler ItemSelected;
- event EventHandler ItemCommitted;
+ event EventHandler ItemSelected;
+ event EventHandler ItemCommitted;
event EventHandler FilterStateChanged;
}
}
diff --git a/src/EditorFeatures/Core/Extensibility/Completion/PresentationItem.cs b/src/EditorFeatures/Core/Extensibility/Completion/PresentationItem.cs
deleted file mode 100644
index e3b91c3900c9c2d504f1b4a0d1216ed22d9e4e42..0000000000000000000000000000000000000000
--- a/src/EditorFeatures/Core/Extensibility/Completion/PresentationItem.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.CodeAnalysis.Completion;
-
-namespace Microsoft.CodeAnalysis.Editor
-{
- internal abstract class PresentationItem
- {
- public abstract CompletionItem Item { get; }
- public abstract bool IsSuggestionModeItem { get; }
- public abstract CompletionService CompletionService { get; }
-
- public abstract Task GetDescriptionAsync(Document document, CancellationToken cancellationToken);
- }
-}
\ No newline at end of file
diff --git a/src/EditorFeatures/Core/Extensibility/Completion/PresentationItemEventArgs.cs b/src/EditorFeatures/Core/Extensibility/Completion/PresentationItemEventArgs.cs
deleted file mode 100644
index 002523ef6bb023e6d91053ad2d167326578ec4d7..0000000000000000000000000000000000000000
--- a/src/EditorFeatures/Core/Extensibility/Completion/PresentationItemEventArgs.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-
-namespace Microsoft.CodeAnalysis.Editor
-{
- internal class PresentationItemEventArgs : EventArgs
- {
- public PresentationItem PresentationItem { get; }
-
- public PresentationItemEventArgs(PresentationItem presentationItem)
- {
- this.PresentationItem = presentationItem;
- }
- }
-}
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session.cs
index 4c61a88fd2c6d91f8e9f2433bc46706a8480f76a..c5b6fc25d71b51f357920089cccc6172a98aa00c 100644
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session.cs
+++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session.cs
@@ -76,20 +76,20 @@ private SnapshotPoint GetCaretPointInViewBuffer()
return Controller.GetCaretPointInViewBuffer();
}
- private void OnPresenterSessionItemCommitted(object sender, PresentationItemEventArgs e)
+ private void OnPresenterSessionItemCommitted(object sender, CompletionItemEventArgs e)
{
AssertIsForeground();
Contract.ThrowIfFalse(ReferenceEquals(this.PresenterSession, sender));
- this.Controller.CommitItem(e.PresentationItem);
+ this.Controller.CommitItem(e.CompletionItem);
}
- private void OnPresenterSessionItemSelected(object sender, PresentationItemEventArgs e)
+ private void OnPresenterSessionItemSelected(object sender, CompletionItemEventArgs e)
{
AssertIsForeground();
Contract.ThrowIfFalse(ReferenceEquals(this.PresenterSession, sender));
- SetModelSelectedItem(m => e.PresentationItem.IsSuggestionModeItem ? m.DefaultSuggestionModeItem : e.PresentationItem);
+ SetModelSelectedItem(m => e.CompletionItem);
}
private void OnPresenterSessionCompletionItemFilterStateChanged(
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session_ComputeModel.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session_ComputeModel.cs
index 39efc94864c6cfd2cae3e19a8f1e8c08d522144c..d611327719e1ad5896061052d2454df97509dd86 100644
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session_ComputeModel.cs
+++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session_ComputeModel.cs
@@ -106,17 +106,13 @@ private async Task DoInBackgroundAsync(CancellationToken cancellationToke
return null;
}
+ var suggestionMode = _useSuggestionMode || completionList.SuggestionModeItem != null;
return Model.CreateModel(
_documentOpt,
_disconnectedBufferGraph,
completionList,
- selectedItem: completionList.Items.First(),
- isHardSelection: false,
- isUnique: false,
- useSuggestionMode: _useSuggestionMode,
- trigger: _trigger,
- completionService: _completionService,
- workspace: _documentOpt != null ? _documentOpt.Project.Solution.Workspace : null);
+ useSuggestionMode: suggestionMode,
+ trigger: _trigger);
}
}
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session_FilterModel.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session_FilterModel.cs
index 29746ab539f3c3d2afa0ff8a07f53f9e9a5f4fe8..b4b6dfa36a9f29facf36626a102822b934d8c28b 100644
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session_FilterModel.cs
+++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session_FilterModel.cs
@@ -165,13 +165,13 @@ internal partial class Session
return model;
}
- if (ItemIsFilteredOut(currentItem.Item, filterState))
+ if (ItemIsFilteredOut(currentItem, filterState))
{
continue;
}
// Check if the item matches the filter text typed so far.
- var matchesFilterText = MatchesFilterText(helper, currentItem.Item, filterText, model.Trigger, filterReason, recentItems);
+ var matchesFilterText = MatchesFilterText(helper, currentItem, filterText, model.Trigger, filterReason, recentItems);
if (matchesFilterText)
{
@@ -243,7 +243,7 @@ private Boolean IsAfterDot(Model model, ITextSnapshot textSnapshot, Dictionary r.MatchedFilterText)
- .Select(t => t.PresentationItem.Item)
+ .Select(t => t.CompletionItem)
.AsImmutable();
var chosenItems = service.FilterItems(
document, matchingCompletionItems, filterText);
@@ -252,12 +252,10 @@ private Boolean IsAfterDot(Model model, ITextSnapshot textSnapshot, Dictionary r.PresentationItem.Item == bestOrFirstCompletionItem).First().PresentationItem;
+ var bestOrFirstCompletionItem = bestCompletionItem ?? filterResults.First().CompletionItem;
var hardSelection = IsHardSelection(
- model, bestOrFirstPresentationItem, textSnapshot, helper, filterReason);
+ model, bestOrFirstCompletionItem, textSnapshot, helper, filterReason);
// Determine if we should consider this item 'unique' or not. A unique item
// will be automatically committed if the user hits the 'invoke completion'
@@ -271,8 +269,8 @@ private Boolean IsAfterDot(Model model, ITextSnapshot textSnapshot, Dictionary 0;
- var result = model.WithFilteredItems(filterResults.Select(r => r.PresentationItem).AsImmutable())
- .WithSelectedItem(bestOrFirstPresentationItem)
+ var result = model.WithFilteredItems(filterResults.Select(r => r.CompletionItem).AsImmutable())
+ .WithSelectedItem(bestOrFirstCompletionItem)
.WithHardSelection(hardSelection)
.WithIsUnique(isUnique);
@@ -322,12 +320,12 @@ private Model HandleDeletionTrigger(Model model, List filterResult
// (which can happen if the user deletes down to a single character and we
// include everything), then we just soft select the first item.
- var filteredItems = filterResults.Select(r => r.PresentationItem).AsImmutable();
+ var filteredItems = filterResults.Select(r => r.CompletionItem).AsImmutable();
model = model.WithFilteredItems(filteredItems);
if (bestFilterResult != null)
{
- return model.WithSelectedItem(bestFilterResult.Value.PresentationItem)
+ return model.WithSelectedItem(bestFilterResult.Value.CompletionItem)
.WithHardSelection(true)
.WithIsUnique(matchCount == 1);
}
@@ -340,8 +338,8 @@ private Model HandleDeletionTrigger(Model model, List filterResult
private bool IsBetterDeletionMatch(FilterResult result1, FilterResult result2)
{
- var item1 = result1.PresentationItem.Item;
- var item2 = result2.PresentationItem.Item;
+ var item1 = result1.CompletionItem;
+ var item2 = result2.CompletionItem;
var prefixLength1 = item1.FilterText.GetCaseInsensitivePrefixLength(result1.FilterText);
var prefixLength2 = item2.FilterText.GetCaseInsensitivePrefixLength(result2.FilterText);
@@ -370,13 +368,13 @@ private bool IsBetterDeletionMatch(FilterResult result1, FilterResult result2)
private struct FilterResult
{
- public readonly PresentationItem PresentationItem;
+ public readonly CompletionItem CompletionItem;
public readonly bool MatchedFilterText;
public readonly string FilterText;
- public FilterResult(PresentationItem presentationItem, string filterText, bool matchedFilterText)
+ public FilterResult(CompletionItem completionItem, string filterText, bool matchedFilterText)
{
- PresentationItem = presentationItem;
+ CompletionItem = completionItem;
MatchedFilterText = matchedFilterText;
FilterText = filterText;
}
@@ -402,7 +400,7 @@ public FilterResult(PresentationItem presentationItem, string filterText, bool m
// If the user has turned on some filtering states, and we filtered down to
// nothing, then we do want the UI to show that to them. That way the user
// can turn off filters they don't want and get the right set of items.
- return model.WithFilteredItems(ImmutableArray.Empty)
+ return model.WithFilteredItems(ImmutableArray.Empty)
.WithFilterText("")
.WithHardSelection(false)
.WithIsUnique(false);
@@ -503,16 +501,11 @@ private static bool IsAllDigits(string filterText)
private bool IsHardSelection(
Model model,
- PresentationItem bestFilterMatch,
+ CompletionItem bestFilterMatch,
ITextSnapshot textSnapshot,
CompletionHelper completionHelper,
CompletionFilterReason reason)
{
- if (model.SuggestionModeItem != null)
- {
- return bestFilterMatch != null && bestFilterMatch.Item.DisplayText == model.SuggestionModeItem.Item.DisplayText;
- }
-
if (bestFilterMatch == null || model.UseSuggestionMode)
{
return false;
@@ -529,11 +522,11 @@ private static bool IsAllDigits(string filterText)
//
// Completion will comes up after = with 'integer' selected (Because of MRU). We do
// not want 'space' to commit this.
- var viewSpan = model.GetViewBufferSpan(bestFilterMatch.Item.Span);
+ var viewSpan = model.GetViewBufferSpan(bestFilterMatch.Span);
var fullFilterText = model.GetCurrentTextInSnapshot(viewSpan, textSnapshot, endPoint: null);
var trigger = model.Trigger;
- var shouldSoftSelect = ShouldSoftSelectItem(bestFilterMatch.Item, fullFilterText, trigger);
+ var shouldSoftSelect = ShouldSoftSelectItem(bestFilterMatch, fullFilterText, trigger);
if (shouldSoftSelect)
{
return false;
@@ -541,7 +534,7 @@ private static bool IsAllDigits(string filterText)
// 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(completionHelper, bestFilterMatch.Item, fullFilterText, trigger, reason, this.Controller.GetRecentItems()))
+ if (!MatchesFilterText(completionHelper, bestFilterMatch, fullFilterText, trigger, reason, this.Controller.GetRecentItems()))
{
return false;
}
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session_SetModelBuilderState.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session_SetModelBuilderState.cs
index 2f88018d24624459771cfec24ba9e11cd5e50a4c..aca0825113b6c35a22d24414ae5ed1d62ee4f1c2 100644
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session_SetModelBuilderState.cs
+++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session_SetModelBuilderState.cs
@@ -28,15 +28,17 @@ public void SetModelBuilderState(bool includeBuilder)
// already in soft select mode.
var softSelect = includeBuilder || model.IsSoftSelection;
- // If the selected item is the builder, select the first filtered item instead.
- if (model.SelectedItem == model.DefaultSuggestionModeItem)
+ if (model.SelectedItem == model.SuggestionModeItem &&
+ !includeBuilder)
{
- return model.WithSelectedItem(model.FilteredItems.First())
- .WithHardSelection(!softSelect);
+ // Use had the builder selected, but turned off the builder. Switch to the
+ // first filtered item.
+ model = model.WithSelectedItem(model.FilteredItems.First());
}
- return model.WithHardSelection(!softSelect).WithUseSuggestionMode(includeBuilder);
+ return model.WithHardSelection(!softSelect)
+ .WithUseSuggestionMode(includeBuilder);
}
}
}
-}
+}
\ No newline at end of file
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session_SetModelSelectedItem.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session_SetModelSelectedItem.cs
index 104598dd04cdd16c5b773152c66ae6eaefd0a7c0..eae98395be52af5a3d9dab554875c2313c886b5f 100644
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session_SetModelSelectedItem.cs
+++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.Session_SetModelSelectedItem.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using Microsoft.CodeAnalysis.Completion;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.Completion
@@ -11,7 +12,7 @@ internal partial class Controller
{
internal partial class Session
{
- private void SetModelSelectedItem(Func selector)
+ private void SetModelSelectedItem(Func selector)
{
AssertIsForeground();
@@ -29,7 +30,7 @@ public void SetModelIsHardSelection(bool isHardSelection)
private Model SetModelSelectedItemInBackground(
Model model,
- Func selector)
+ Func selector)
{
if (model == null)
{
@@ -38,7 +39,7 @@ public void SetModelIsHardSelection(bool isHardSelection)
// Switch to hard selection.
var selectedItem = selector(model);
- Contract.ThrowIfFalse(model.TotalItems.Contains(selectedItem) || model.DefaultSuggestionModeItem == selectedItem);
+ Contract.Assert(model.TotalItems.Contains(selectedItem) || model.SuggestionModeItem == selectedItem);
if (model.FilteredItems.Contains(selectedItem))
{
@@ -52,7 +53,7 @@ public void SetModelIsHardSelection(bool isHardSelection)
{
// Item wasn't in the filtered list, so we need to recreate the filtered list
// with that item in it.
- var filteredItemsSet = new HashSet(model.FilteredItems,
+ var filteredItemsSet = new HashSet(model.FilteredItems,
ReferenceEqualityComparer.Instance);
var newFilteredItems = model.TotalItems.Where(
@@ -64,4 +65,4 @@ public void SetModelIsHardSelection(bool isHardSelection)
}
}
}
-}
+}
\ No newline at end of file
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.cs
index b0177e510bad86b6a3030f08296719f085c09d56..6eb512b2a68c4c9c28fba1e3d9e3685f5eeececf 100644
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.cs
+++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.cs
@@ -124,13 +124,13 @@ internal override void OnModelUpdated(Model modelOpt)
else
{
var selectedItem = modelOpt.SelectedItem;
- var viewSpan = selectedItem == null ? (ViewTextSpan?)null : modelOpt.GetViewBufferSpan(selectedItem.Item.Span);
+ var viewSpan = selectedItem == null ? (ViewTextSpan?)null : modelOpt.GetViewBufferSpan(selectedItem.Span);
var triggerSpan = viewSpan == null ? null : modelOpt.GetCurrentSpanInSnapshot(viewSpan.Value, this.TextView.TextSnapshot)
.CreateTrackingSpan(SpanTrackingMode.EdgeInclusive);
sessionOpt.PresenterSession.PresentItems(
- triggerSpan, modelOpt.FilteredItems, selectedItem, modelOpt.SuggestionModeItem,
- this.SubjectBuffer.GetFeatureOnOffOption(EditorCompletionOptions.UseSuggestionMode),
+ triggerSpan, modelOpt.FilteredItems, selectedItem,
+ modelOpt.SuggestionModeItem, modelOpt.UseSuggestionMode,
modelOpt.IsSoftSelection, modelOpt.CompletionItemFilters, modelOpt.FilterText);
}
}
@@ -237,7 +237,7 @@ private OptionSet GetOptions()
: workspace.Options;
}
- private void CommitItem(PresentationItem item)
+ private void CommitItem(CompletionItem item)
{
AssertIsForeground();
@@ -245,8 +245,10 @@ private void CommitItem(PresentationItem item)
Contract.ThrowIfNull(this.sessionOpt);
Contract.ThrowIfNull(this.sessionOpt.Computation.InitialUnfilteredModel);
+ var model = sessionOpt.InitialUnfilteredModel;
+
// If the selected item is the builder, there's not actually any work to do to commit
- if (item.IsSuggestionModeItem)
+ if (item == model.SuggestionModeItem)
{
this.StopModelComputation();
return;
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_Backspace.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_Backspace.cs
index 9691fac72214f8497126d1007f22d8c7158926bf..4cc8c834217de39f3982023e887b3430f6507068 100644
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_Backspace.cs
+++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_Backspace.cs
@@ -151,16 +151,16 @@ internal bool AllFilterTextsEmpty(Model model, SnapshotPoint caretPoint)
private bool IsFilterTextEmpty(
Model model,
SnapshotPoint caretPoint,
- PresentationItem item,
+ CompletionItem item,
Dictionary textSpanToText,
Dictionary textSpanToViewSpan)
{
// Easy first check. See if the caret point is before the start of the item.
ViewTextSpan filterSpanInViewBuffer;
- if (!textSpanToViewSpan.TryGetValue(item.Item.Span, out filterSpanInViewBuffer))
+ if (!textSpanToViewSpan.TryGetValue(item.Span, out filterSpanInViewBuffer))
{
- filterSpanInViewBuffer = model.GetViewBufferSpan(item.Item.Span);
- textSpanToViewSpan[item.Item.Span] = filterSpanInViewBuffer;
+ filterSpanInViewBuffer = model.GetViewBufferSpan(item.Span);
+ textSpanToViewSpan[item.Span] = filterSpanInViewBuffer;
}
if (caretPoint < filterSpanInViewBuffer.TextSpan.Start)
@@ -170,7 +170,7 @@ internal bool AllFilterTextsEmpty(Model model, SnapshotPoint caretPoint)
var textSnapshot = caretPoint.Snapshot;
- var currentText = model.GetCurrentTextInSnapshot(item.Item.Span, textSnapshot, textSpanToText);
+ var currentText = model.GetCurrentTextInSnapshot(item.Span, textSnapshot, textSpanToText);
var currentTextSpan = new TextSpan(filterSpanInViewBuffer.TextSpan.Start, currentText.Length);
return currentText.Length == 0;
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_CaretPositionChanged.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_CaretPositionChanged.cs
index 3abbfb2128d7309337454c1eab5a6a16667e8382..f51b3fdb1b057a2135b943ac230352b048118fe4 100644
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_CaretPositionChanged.cs
+++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_CaretPositionChanged.cs
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
+using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.Text;
@@ -48,7 +49,7 @@ internal override void OnCaretPositionChanged(object sender, EventArgs args)
// We want the filter span non-empty because we still want completion in the following case:
// A a = new | -> A a = new (|
- var currentSpan = model.GetViewBufferSpan(model.SelectedItem.Item.Span).TextSpan;
+ var currentSpan = model.GetViewBufferSpan(model.SelectedItem.Span).TextSpan;
if (caretPoint == currentSpan.Start && currentSpan.Length > 0)
{
sessionOpt.SetModelIsHardSelection(false);
@@ -75,16 +76,16 @@ internal bool IsCaretOutsideAllItemBounds(Model model, SnapshotPoint caretPoint)
private bool IsCaretOutsideItemBounds(
Model model,
SnapshotPoint caretPoint,
- PresentationItem item,
+ CompletionItem item,
Dictionary textSpanToText,
Dictionary textSpanToViewSpan)
{
// Easy first check. See if the caret point is before the start of the item.
ViewTextSpan filterSpanInViewBuffer;
- if (!textSpanToViewSpan.TryGetValue(item.Item.Span, out filterSpanInViewBuffer))
+ if (!textSpanToViewSpan.TryGetValue(item.Span, out filterSpanInViewBuffer))
{
- filterSpanInViewBuffer = model.GetViewBufferSpan(item.Item.Span);
- textSpanToViewSpan[item.Item.Span] = filterSpanInViewBuffer;
+ filterSpanInViewBuffer = model.GetViewBufferSpan(item.Span);
+ textSpanToViewSpan[item.Span] = filterSpanInViewBuffer;
}
if (caretPoint < filterSpanInViewBuffer.TextSpan.Start)
@@ -94,10 +95,10 @@ internal bool IsCaretOutsideAllItemBounds(Model model, SnapshotPoint caretPoint)
var textSnapshot = caretPoint.Snapshot;
- var currentText = model.GetCurrentTextInSnapshot(item.Item.Span, textSnapshot, textSpanToText);
+ var currentText = model.GetCurrentTextInSnapshot(item.Span, textSnapshot, textSpanToText);
var currentTextSpan = new TextSpan(filterSpanInViewBuffer.TextSpan.Start, currentText.Length);
return !currentTextSpan.IntersectsWith(caretPoint);
}
}
-}
+}
\ No newline at end of file
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_Commit.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_Commit.cs
index 3144afc3b4b961a6cdb863facd9510813ef6f68f..b6f713a3e01de76de8adae67ec0185b967a43e86 100644
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_Commit.cs
+++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_Commit.cs
@@ -27,13 +27,13 @@ private CompletionProvider GetCompletionProvider(CompletionItem item)
}
private void CommitOnNonTypeChar(
- PresentationItem item, Model model)
+ CompletionItem item, Model model)
{
Commit(item, model, commitChar: null, initialTextSnapshot: null, nextHandler: null);
}
private void Commit(
- PresentationItem item, Model model, char? commitChar,
+ CompletionItem item, Model model, char? commitChar,
ITextSnapshot initialTextSnapshot, Action nextHandler)
{
AssertIsForeground();
@@ -58,10 +58,10 @@ private CompletionProvider GetCompletionProvider(CompletionItem item)
// We want to merge with any of our other programmatic edits (e.g. automatic brace completion)
transaction.MergePolicy = AutomaticCodeChangeMergePolicy.Instance;
- var provider = GetCompletionProvider(item.Item) as ICustomCommitCompletionProvider;
+ var provider = GetCompletionProvider(item) as ICustomCommitCompletionProvider;
if (provider != null)
{
- provider.Commit(item.Item, this.TextView, this.SubjectBuffer, model.TriggerSnapshot, commitChar);
+ provider.Commit(item, this.TextView, this.SubjectBuffer, model.TriggerSnapshot, commitChar);
}
else
{
@@ -95,7 +95,7 @@ private CompletionProvider GetCompletionProvider(CompletionItem item)
Contract.ThrowIfNull(completionService, nameof(completionService));
completionChange = completionService.GetChangeAsync(
- triggerDocument, item.Item, commitChar, CancellationToken.None).WaitAndGetResult(CancellationToken.None);
+ triggerDocument, item, commitChar, CancellationToken.None).WaitAndGetResult(CancellationToken.None);
var textChange = completionChange.TextChange;
var triggerSnapshotSpan = new SnapshotSpan(triggerSnapshot, textChange.Span.ToSpan());
@@ -133,7 +133,7 @@ private CompletionProvider GetCompletionProvider(CompletionItem item)
}
// Let the completion rules know that this item was committed.
- this.MakeMostRecentItem(item.Item.DisplayText);
+ this.MakeMostRecentItem(item.DisplayText);
}
private void RollbackToBeforeTypeChar(ITextSnapshot initialTextSnapshot)
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_ReturnKey.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_ReturnKey.cs
index 1f90e91c2d3639a19527fc819c7eb4cf3bda629b..b32cfed8b891bba05319a4ea27c4ad9438dd2101 100644
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_ReturnKey.cs
+++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_ReturnKey.cs
@@ -76,7 +76,7 @@ private void CommitOnEnter(out bool sendThrough, out bool committed)
}
// If the selected item is the builder, dismiss
- if (model.SelectedItem.IsSuggestionModeItem)
+ if (model.SelectedItem == model.SuggestionModeItem)
{
sendThrough = false;
committed = false;
@@ -86,13 +86,13 @@ private void CommitOnEnter(out bool sendThrough, out bool committed)
if (sendThrough)
{
// Get the text that the user has currently entered into the buffer
- var viewSpan = model.GetViewBufferSpan(model.SelectedItem.Item.Span);
+ var viewSpan = model.GetViewBufferSpan(model.SelectedItem.Span);
var textTypedSoFar = model.GetCurrentTextInSnapshot(
viewSpan, this.TextView.TextSnapshot, this.GetCaretPointInViewBuffer());
var service = GetCompletionService();
sendThrough = SendEnterThroughToEditor(
- service.GetRules(), model.SelectedItem.Item, textTypedSoFar);
+ service.GetRules(), model.SelectedItem, textTypedSoFar);
}
this.CommitOnNonTypeChar(model.SelectedItem, model);
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_TabKey.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_TabKey.cs
index f6d9aed1fb15917fa4605558d19cce14b372cc2d..bd5f94bc4207c2a4f611dc27bb5ef513df94a71c 100644
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_TabKey.cs
+++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_TabKey.cs
@@ -170,7 +170,7 @@ private void CommitOnTab(out bool committed)
}
// If the selected item is the builder, there's not actually any work to do to commit
- if (model.SelectedItem.IsSuggestionModeItem)
+ if (model.SelectedItem == model.SuggestionModeItem)
{
committed = true;
this.StopModelComputation();
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_TypeChar.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_TypeChar.cs
index 498c44b97eb8c4d8280f1174def51533920c879f..7c92ab9e645bb3a94d17dca91e4760df12d9c3e0 100644
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_TypeChar.cs
+++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_TypeChar.cs
@@ -1,8 +1,6 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
-using System.Collections.Generic;
-using System.Linq;
using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.Editor.Commands;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
@@ -311,7 +309,7 @@ private bool IsCommitCharacter(char ch)
return false;
}
- if (model.SelectedItem.IsSuggestionModeItem)
+ if (model.SelectedItem == model.SuggestionModeItem)
{
return char.IsLetterOrDigit(ch);
}
@@ -322,9 +320,9 @@ private bool IsCommitCharacter(char ch)
return false;
}
- var textTypedSoFar = GetTextTypedSoFar(model, model.SelectedItem.Item);
+ var textTypedSoFar = GetTextTypedSoFar(model, model.SelectedItem);
return IsCommitCharacter(
- completionService.GetRules(), model.SelectedItem.Item, ch, textTypedSoFar);
+ completionService.GetRules(), model.SelectedItem, ch, textTypedSoFar);
}
///
@@ -378,13 +376,13 @@ private bool IsFilterCharacter(char ch)
return false;
}
- if (model.SelectedItem.IsSuggestionModeItem)
+ if (model.SelectedItem == model.SuggestionModeItem)
{
return char.IsLetterOrDigit(ch);
}
- var textTypedSoFar = GetTextTypedSoFar(model, model.SelectedItem.Item);
- return IsFilterCharacter(model.SelectedItem.Item, ch, textTypedSoFar);
+ var textTypedSoFar = GetTextTypedSoFar(model, model.SelectedItem);
+ return IsFilterCharacter(model.SelectedItem, ch, textTypedSoFar);
}
private static bool TextTypedSoFarMatchesItem(CompletionItem item, char ch, string textTypedSoFar)
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/DescriptionModifyingPresentationItem.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/DescriptionModifyingPresentationItem.cs
deleted file mode 100644
index 8dfb3eeef8c76b75e0e2c338ad33c8ea4b451046..0000000000000000000000000000000000000000
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/DescriptionModifyingPresentationItem.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Diagnostics;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.CodeAnalysis.Completion;
-using Microsoft.CodeAnalysis.Snippets;
-using Microsoft.CodeAnalysis.Text;
-
-namespace Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.Completion
-{
- internal class DescriptionModifyingPresentationItem : PresentationItem
- {
- public override CompletionItem Item { get; }
- public override bool IsSuggestionModeItem { get; }
- public override CompletionService CompletionService { get; }
-
- public DescriptionModifyingPresentationItem(CompletionItem item, CompletionService completionService, bool isSuggestionModeItem = false)
- {
- Debug.Assert(item != null);
- Debug.Assert(completionService != null);
-
- this.Item = item;
- this.CompletionService = completionService;
- this.IsSuggestionModeItem = isSuggestionModeItem;
- }
-
- public override async Task GetDescriptionAsync(Document document, CancellationToken cancellationToken)
- {
- var languageServices = document.Project.LanguageServices;
- var snippetService = languageServices.GetService();
-
- var description = await this.CompletionService.GetDescriptionAsync(document, this.Item, cancellationToken).ConfigureAwait(false);
- var parts = description.TaggedParts;
-
- var change = await GetTextChangeAsync(this.CompletionService, document, this.Item, '\t').ConfigureAwait(false);
- var insertionText = change.NewText;
-
- var note = string.Empty;
- if (snippetService != null && snippetService.SnippetShortcutExists_NonBlocking(insertionText))
- {
- note = string.Format(FeaturesResources.Note_colon_Tab_twice_to_insert_the_0_snippet, insertionText);
- }
-
- if (!string.IsNullOrEmpty(note))
- {
- if (parts.Any())
- {
- parts = parts.Add(new TaggedText(TextTags.LineBreak, Environment.NewLine));
- }
-
- parts = parts.Add(new TaggedText(TextTags.Text, note));
- }
-
- return description.WithTaggedParts(parts);
- }
-
- ///
- /// Internal for testing purposes only.
- ///
- internal static async Task GetTextChangeAsync(
- CompletionService service, Document document, CompletionItem item,
- char? commitKey = null, CancellationToken cancellationToken = default(CancellationToken))
- {
- var change = await service.GetChangeAsync(document, item, commitKey, cancellationToken).ConfigureAwait(false);
-
- // normally the items that produce multiple changes are not expecting to trigger the behaviors that rely on looking at the text
- return change.TextChange;
- }
- }
-}
\ No newline at end of file
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Model.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Model.cs
index 12d466747a77f2eba03aa70509fb432f220241b6..5830c23a08d44c0acab73f522160fbe08fd3df8c 100644
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Model.cs
+++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Model.cs
@@ -20,10 +20,9 @@ internal class Model
public Document TriggerDocument { get; }
public CompletionList OriginalList { get; }
- public ImmutableArray TotalItems { get; }
- public ImmutableArray FilteredItems { get; }
+ public ImmutableArray FilteredItems { get; }
- public PresentationItem SelectedItem { get; }
+ public CompletionItem SelectedItem { get; }
public ImmutableArray CompletionItemFilters { get; }
public ImmutableDictionary FilterState { get; }
@@ -32,14 +31,16 @@ internal class Model
public bool IsHardSelection { get; }
public bool IsUnique { get; }
- // The item the model will use to represent selecting and interacting with when in suggestion mode.
- // All models always have this property set.
- public PresentationItem DefaultSuggestionModeItem { get; }
+ ///
+ /// SuggestionMode item is the "builder" we would display in intellisense. It's
+ /// always non-null, but will only be shown if is true.
+ /// If it provided by some then we
+ /// will use that. Otherwise, we'll have a simple empty-default item that we'll use.
+ ///
+ public CompletionItem SuggestionModeItem { get; }
+ public bool UseSuggestionMode { get; }
- // The suggestion mode item, if any, provided by the completion service.
- public PresentationItem SuggestionModeItem { get; }
public CompletionTrigger Trigger { get; }
- public bool UseSuggestionMode { get; }
// When committing a completion item, the span replaced ends at this point.
public ITrackingPoint CommitTrackingSpanEndPoint { get; }
@@ -50,27 +51,25 @@ internal class Model
Document triggerDocument,
DisconnectedBufferGraph disconnectedBufferGraph,
CompletionList originalList,
- ImmutableArray totalItems,
- ImmutableArray filteredItems,
- PresentationItem selectedItem,
+ ImmutableArray filteredItems,
+ CompletionItem selectedItem,
ImmutableArray completionItemFilters,
ImmutableDictionary filterState,
string filterText,
bool isHardSelection,
bool isUnique,
bool useSuggestionMode,
- PresentationItem suggestionModeItem,
- PresentationItem defaultSuggestionModeItem,
+ CompletionItem suggestionModeItem,
CompletionTrigger trigger,
ITrackingPoint commitSpanEndPoint,
bool dismissIfEmpty)
{
- Contract.ThrowIfFalse(totalItems.Length != 0, "Must have at least one item.");
+ Contract.ThrowIfFalse(originalList.Items.Length != 0, "Must have at least one item.");
+ Contract.ThrowIfNull(selectedItem);
this.TriggerDocument = triggerDocument;
_disconnectedBufferGraph = disconnectedBufferGraph;
this.OriginalList = originalList;
- this.TotalItems = totalItems;
this.FilteredItems = filteredItems;
this.FilterState = filterState;
this.SelectedItem = selectedItem;
@@ -78,30 +77,24 @@ internal class Model
this.FilterText = filterText;
this.IsHardSelection = isHardSelection;
this.IsUnique = isUnique;
- this.UseSuggestionMode = useSuggestionMode;
- this.SuggestionModeItem = suggestionModeItem;
- this.DefaultSuggestionModeItem = defaultSuggestionModeItem;
this.Trigger = trigger;
this.CommitTrackingSpanEndPoint = commitSpanEndPoint;
this.DismissIfEmpty = dismissIfEmpty;
+
+ this.UseSuggestionMode = useSuggestionMode;
+ this.SuggestionModeItem = suggestionModeItem ?? CreateDefaultSuggestionModeItem();
}
public static Model CreateModel(
Document triggerDocument,
DisconnectedBufferGraph disconnectedBufferGraph,
CompletionList originalList,
- CompletionItem selectedItem,
- bool isHardSelection,
- bool isUnique,
bool useSuggestionMode,
- CompletionTrigger trigger,
- CompletionService completionService,
- Workspace workspace)
+ CompletionTrigger trigger)
{
- ImmutableArray totalItems;
- CompletionItem suggestionModeItem = originalList.SuggestionModeItem;
- PresentationItem suggestionModePresentationItem;
- PresentationItem defaultSuggestionModePresentationItem;
+ var selectedItem = originalList.Items.First();
+ var isHardSelection = false;
+ var isUnique = false;
// Get the set of actual filters used by all the completion items
// that are in the list.
@@ -126,58 +119,26 @@ internal class Model
// By default we do not filter anything out.
ImmutableDictionary filterState = null;
- if (completionService != null &&
- workspace != null &&
- workspace.Kind != WorkspaceKind.Interactive && // TODO (https://github.com/dotnet/roslyn/issues/5107): support in interactive
- workspace.Options.GetOption(InternalFeatureOnOffOptions.Snippets) &&
- trigger.Kind != CompletionTriggerKind.Snippets)
- {
- // In order to add snippet expansion notes to completion item descriptions, update
- // all of the provided CompletionItems to DescriptionModifyingCompletionItem which will proxy
- // requests to the original completion items and add the snippet expansion note to
- // the description if necessary. We won't do this if the list was triggered to show
- // snippet shortcuts.
-
- var totalItemsBuilder = ArrayBuilder.GetInstance();
- foreach (var item in originalList.Items)
- {
- totalItemsBuilder.Add(new DescriptionModifyingPresentationItem(item, completionService));
- }
-
- totalItems = totalItemsBuilder.ToImmutableAndFree();
- defaultSuggestionModePresentationItem = new DescriptionModifyingPresentationItem(
- CreateDefaultSuggestionModeItem(), completionService, isSuggestionModeItem: true);
- suggestionModePresentationItem = suggestionModeItem != null ? new DescriptionModifyingPresentationItem(suggestionModeItem, completionService, isSuggestionModeItem: true) : null;
- }
- else
- {
- totalItems = originalList.Items.Select(item => new SimplePresentationItem(item, completionService)).ToImmutableArray();
- defaultSuggestionModePresentationItem = new SimplePresentationItem(CreateDefaultSuggestionModeItem(), completionService, isSuggestionModeItem: true);
- suggestionModePresentationItem = suggestionModeItem != null ? new SimplePresentationItem(suggestionModeItem, completionService, isSuggestionModeItem: true) : null;
- }
-
- var selectedPresentationItem = totalItems.FirstOrDefault(it => it.Item == selectedItem);
-
return new Model(
triggerDocument,
disconnectedBufferGraph,
originalList,
- totalItems,
- totalItems,
- selectedPresentationItem,
+ originalList.Items,
+ selectedItem,
actualItemFilters,
filterState,
"",
isHardSelection,
isUnique,
useSuggestionMode,
- suggestionModePresentationItem,
- defaultSuggestionModePresentationItem,
+ originalList.SuggestionModeItem,
trigger,
GetDefaultTrackingSpanEnd(originalList.Span, disconnectedBufferGraph),
originalList.Rules.DismissIfEmpty);
}
+ public ImmutableArray TotalItems => this.OriginalList.Items;
+
private static ITrackingPoint GetDefaultTrackingSpanEnd(
TextSpan defaultTrackingSpanInSubjectBuffer,
DisconnectedBufferGraph disconnectedBufferGraph)
@@ -188,10 +149,7 @@ internal class Model
PointTrackingMode.Positive);
}
- private static CompletionItem CreateDefaultSuggestionModeItem()
- {
- return CompletionItem.Create(displayText: "");
- }
+ private static CompletionItem CreateDefaultSuggestionModeItem() => CompletionItem.Create(displayText: "");
public bool IsSoftSelection
{
@@ -202,14 +160,14 @@ public bool IsSoftSelection
}
private Model With(
- Optional> filteredItems = default(Optional>),
- Optional selectedItem = default(Optional),
+ Optional> filteredItems = default(Optional>),
+ Optional selectedItem = default(Optional),
Optional> filterState = default(Optional>),
Optional filterText = default(Optional),
Optional isHardSelection = default(Optional),
Optional isUnique = default(Optional),
Optional useSuggestionMode = default(Optional),
- Optional suggestionModeItem = default(Optional),
+ Optional suggestionModeItem = default(Optional),
Optional commitTrackingSpanEndPoint = default(Optional))
{
var newFilteredItems = filteredItems.HasValue ? filteredItems.Value : FilteredItems;
@@ -236,18 +194,18 @@ public bool IsSoftSelection
}
return new Model(
- TriggerDocument, _disconnectedBufferGraph, OriginalList, TotalItems, newFilteredItems,
+ TriggerDocument, _disconnectedBufferGraph, OriginalList, newFilteredItems,
newSelectedItem, CompletionItemFilters, newFilterState, newFilterText,
newIsHardSelection, newIsUnique, newUseSuggestionMode, newSuggestionModeItem,
- DefaultSuggestionModeItem, Trigger, newCommitTrackingSpanEndPoint, DismissIfEmpty);
+ Trigger, newCommitTrackingSpanEndPoint, DismissIfEmpty);
}
- public Model WithFilteredItems(ImmutableArray filteredItems)
+ public Model WithFilteredItems(ImmutableArray filteredItems)
{
return With(filteredItems: filteredItems, selectedItem: filteredItems.FirstOrDefault());
}
- public Model WithSelectedItem(PresentationItem selectedItem)
+ public Model WithSelectedItem(CompletionItem selectedItem)
{
return With(selectedItem: selectedItem);
}
@@ -262,7 +220,7 @@ public Model WithIsUnique(bool isUnique)
return With(isUnique: isUnique);
}
- public Model WithSuggestionModeItem(PresentationItem suggestionModeItem)
+ public Model WithSuggestionModeItem(CompletionItem suggestionModeItem)
{
return With(suggestionModeItem: suggestionModeItem);
}
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/CompletionPresenterSession.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/CompletionPresenterSession.cs
index 6831988216789bd1eec0c7a87fdcccb5817a7321..08a79aa710218a43a509a294bdd95f3fd986c496 100644
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/CompletionPresenterSession.cs
+++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/CompletionPresenterSession.cs
@@ -21,11 +21,10 @@ internal sealed class CompletionPresenterSession : ForegroundThreadAffinitizedOb
internal readonly IGlyphService GlyphService;
private readonly ITextView _textView;
- private readonly ITextBuffer _subjectBuffer;
public event EventHandler Dismissed;
- public event EventHandler ItemCommitted;
- public event EventHandler ItemSelected;
+ public event EventHandler ItemCommitted;
+ public event EventHandler ItemSelected;
public event EventHandler FilterStateChanged;
private readonly ICompletionSet _completionSet;
@@ -38,10 +37,7 @@ internal sealed class CompletionPresenterSession : ForegroundThreadAffinitizedOb
// this scenario.
private bool _isDismissed;
- public ITextBuffer SubjectBuffer
- {
- get { return _subjectBuffer; }
- }
+ public ITextBuffer SubjectBuffer { get; }
public CompletionPresenterSession(
ICompletionSetFactory completionSetFactory,
@@ -53,7 +49,7 @@ public ITextBuffer SubjectBuffer
_completionBroker = completionBroker;
this.GlyphService = glyphService;
_textView = textView;
- _subjectBuffer = subjectBuffer;
+ SubjectBuffer = subjectBuffer;
_completionSet = completionSetFactory.CreateCompletionSet(this, textView, subjectBuffer);
_completionSet.SelectionStatusChanged += OnCompletionSetSelectionStatusChanged;
@@ -61,9 +57,9 @@ public ITextBuffer SubjectBuffer
public void PresentItems(
ITrackingSpan triggerSpan,
- IList completionItems,
- PresentationItem selectedItem,
- PresentationItem suggestionModeItem,
+ IList completionItems,
+ CompletionItem selectedItem,
+ CompletionItem suggestionModeItem,
bool suggestionMode,
bool isSoftSelected,
ImmutableArray completionItemFilters,
@@ -132,13 +128,14 @@ private void OnEditorSessionDismissed()
this.Dismissed?.Invoke(this, new EventArgs());
}
- internal void OnCompletionItemCommitted(PresentationItem presentationItem)
+ internal void OnCompletionItemCommitted(CompletionItem completionItem)
{
AssertIsForeground();
- this.ItemCommitted?.Invoke(this, new PresentationItemEventArgs(presentationItem));
+ this.ItemCommitted?.Invoke(this, new CompletionItemEventArgs(completionItem));
}
- private void OnCompletionSetSelectionStatusChanged(object sender, ValueChangedEventArgs eventArgs)
+ private void OnCompletionSetSelectionStatusChanged(
+ object sender, ValueChangedEventArgs eventArgs)
{
AssertIsForeground();
@@ -147,11 +144,10 @@ private void OnCompletionSetSelectionStatusChanged(object sender, ValueChangedEv
return;
}
- var item = _completionSet.GetPresentationItem(eventArgs.NewValue.Completion);
- var itemSelected = this.ItemSelected;
- if (itemSelected != null && item != null)
+ var item = _completionSet.GetCompletionItem(eventArgs.NewValue.Completion);
+ if (item != null)
{
- itemSelected(this, new PresentationItemEventArgs(item));
+ this.ItemSelected?.Invoke(this, new CompletionItemEventArgs(item));
}
}
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/CustomCommitCompletion.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/CustomCommitCompletion.cs
index c4c010cb55f84f10d24c8a00ef3f00c0639393d0..861a15d46f82cff94d952d8000cc1519e5065b1f 100644
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/CustomCommitCompletion.cs
+++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/CustomCommitCompletion.cs
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Completion;
@@ -16,21 +17,23 @@ internal sealed class CustomCommitCompletion : Completion3, ICustomCommit
{
private static readonly string s_glyphCompletionWarning = "GlyphCompletionWarning";
private readonly CompletionPresenterSession _completionPresenterSession;
- internal readonly PresentationItem PresentationItem;
+ internal readonly CompletionItem CompletionItem;
private readonly ImageMoniker _imageMoniker;
+ private readonly string _displayText;
public CustomCommitCompletion(
- CompletionPresenterSession completionPresenterSession,
- PresentationItem presentationItem)
- : base()
+ CompletionPresenterSession completionPresenterSession,
+ CompletionItem completionItem,
+ string displayText)
{
// PERF: Note that the base class contains a constructor taking the displayText string
// but we're intentionally NOT using that here because it allocates a private CompletionState
// object. By overriding the public property getters (DisplayText, InsertionText, etc.) the
// extra allocation is avoided.
_completionPresenterSession = completionPresenterSession;
- this.PresentationItem = presentationItem;
- _imageMoniker = ImageMonikers.GetImageMoniker(PresentationItem.Item.Tags);
+ this.CompletionItem = completionItem;
+ _displayText = displayText ?? completionItem.DisplayText;
+ _imageMoniker = ImageMonikers.GetImageMoniker(CompletionItem.Tags);
}
public void Commit()
@@ -38,24 +41,12 @@ public void Commit()
// If a commit happens through the UI then let the session know. It will, in turn,
// let the underlying controller know, and the controller can commit the completion
// item.
- _completionPresenterSession.OnCompletionItemCommitted(PresentationItem);
+ _completionPresenterSession.OnCompletionItemCommitted(CompletionItem);
}
- public override string DisplayText
- {
- get
- {
- return this.PresentationItem.Item.DisplayText;
- }
- }
+ public override string DisplayText => _displayText;
- public override string InsertionText
- {
- get
- {
- return this.DisplayText; // [sic] Same as DisplayText
- }
- }
+ public override string InsertionText => DisplayText;
public override string Description
{
@@ -74,7 +65,8 @@ public override string Description
public async Task GetDescriptionAsync(CancellationToken cancellationToken)
{
var document = await GetDocumentAsync(cancellationToken).ConfigureAwait(false);
- return await this.PresentationItem.GetDescriptionAsync(document, cancellationToken).ConfigureAwait(false);
+ var service = CompletionService.GetService(document);
+ return await service.GetDescriptionAsync(document, this.CompletionItem, cancellationToken).ConfigureAwait(false);
}
private Task GetDocumentAsync(CancellationToken cancellationToken)
@@ -97,11 +89,11 @@ public override string IconAutomationText
}
}
- public override System.Collections.Generic.IEnumerable AttributeIcons
+ public override IEnumerable AttributeIcons
{
get
{
- if (this.PresentationItem.Item.Tags.Contains(CompletionTags.Warning))
+ if (this.CompletionItem.Tags.Contains(CompletionTags.Warning))
{
return new[] { new CompletionIcon2(Glyph.CompletionWarning.GetImageMoniker(), s_glyphCompletionWarning, s_glyphCompletionWarning) };
}
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/ICompletionSet.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/ICompletionSet.cs
index 4105f1226bb1fe7dbd5f1905708e41f5838c9a2d..30320a2f440110acac149a220ddb9b187547662b 100644
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/ICompletionSet.cs
+++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/ICompletionSet.cs
@@ -16,13 +16,13 @@ internal interface ICompletionSet
CompletionSet CompletionSet { get; }
void SetCompletionItems(
- IList completionItems,
- PresentationItem selectedItem,
- PresentationItem presetBuilder,
+ IList completionItems,
+ CompletionItem selectedItem,
+ CompletionItem suggestionModeItem,
bool suggestionMode,
bool isSoftSelected,
ImmutableArray completionItemFilters,
string filterText);
- PresentationItem GetPresentationItem(VSCompletion completion);
+ CompletionItem GetCompletionItem(VSCompletion completion);
}
}
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/Roslyn14CompletionSet.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/Roslyn14CompletionSet.cs
index 446deb6b7b83d00d774438bf2a69b41991d6c49a..44c8cf37c0a983ada57d6955170ce32c4a2269c6 100644
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/Roslyn14CompletionSet.cs
+++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/Roslyn14CompletionSet.cs
@@ -31,7 +31,9 @@ internal class Roslyn14CompletionSet : ForegroundThreadAffinitizedObject
protected readonly ITextBuffer SubjectBuffer;
protected readonly CompletionPresenterSession CompletionPresenterSession;
- protected Dictionary PresentationItemMap;
+
+ protected Dictionary CompletionItemMap;
+ protected CompletionItem SuggestionModeItem;
protected string FilterText;
@@ -57,9 +59,9 @@ public void SetTrackingSpan(ITrackingSpan trackingSpan)
}
public void SetCompletionItems(
- IList completionItems,
- PresentationItem selectedItem,
- PresentationItem presetBuilder,
+ IList completionItems,
+ CompletionItem selectedItem,
+ CompletionItem suggestionModeItem,
bool suggestionMode,
bool isSoftSelected,
ImmutableArray completionItemFilters,
@@ -67,54 +69,51 @@ public void SetTrackingSpan(ITrackingSpan trackingSpan)
{
this.AssertIsForeground();
- VSCompletion selectedCompletionItem = null;
-
// Initialize the completion map to a reasonable default initial size (+1 for the builder)
- PresentationItemMap = PresentationItemMap ?? new Dictionary(completionItems.Count + 1);
+ CompletionItemMap = CompletionItemMap ?? new Dictionary(completionItems.Count + 1);
FilterText = filterText;
+ SuggestionModeItem = suggestionModeItem;
+
+ this.SetupFilters(completionItemFilters);
+
+ CreateCompletionListBuilder(selectedItem, suggestionModeItem, suggestionMode);
+ CreateNormalCompletionListItems(completionItems);
+
+ var selectedCompletionItem = GetVSCompletion(selectedItem);
+ VsCompletionSet.SelectionStatus = new CompletionSelectionStatus(
+ selectedCompletionItem,
+ isSelected: !isSoftSelected, isUnique: selectedCompletionItem != null);
+ }
+ private void CreateCompletionListBuilder(
+ CompletionItem selectedItem,
+ CompletionItem suggestionModeItem,
+ bool suggestionMode)
+ {
try
{
VsCompletionSet.WritableCompletionBuilders.BeginBulkOperation();
VsCompletionSet.WritableCompletionBuilders.Clear();
- this.SetupFilters(completionItemFilters);
-
- var applicableToText = VsCompletionSet.ApplicableTo.GetText(
- VsCompletionSet.ApplicableTo.TextBuffer.CurrentSnapshot);
-
- SimplePresentationItem filteredSuggestionModeItem = null;
- if (selectedItem != null)
+ if (suggestionMode)
{
- var completionItem = CompletionItem.Create(displayText: applicableToText);
- completionItem.Span = VsCompletionSet.ApplicableTo.GetSpan(
- VsCompletionSet.ApplicableTo.TextBuffer.CurrentSnapshot).Span.ToTextSpan();
-
- filteredSuggestionModeItem = new SimplePresentationItem(
- completionItem,
- selectedItem.CompletionService,
- isSuggestionModeItem: true);
- }
-
- var showBuilder = suggestionMode || presetBuilder != null;
- var bestSuggestionModeItem = applicableToText.Length > 0 ? filteredSuggestionModeItem : presetBuilder ?? filteredSuggestionModeItem;
+ var applicableToText = VsCompletionSet.ApplicableTo.GetText(
+ VsCompletionSet.ApplicableTo.TextBuffer.CurrentSnapshot);
- if (showBuilder && bestSuggestionModeItem != null)
- {
- var suggestionModeCompletion = GetVSCompletion(bestSuggestionModeItem);
- VsCompletionSet.WritableCompletionBuilders.Add(suggestionModeCompletion);
-
- if (selectedItem != null && selectedItem.IsSuggestionModeItem)
- {
- selectedCompletionItem = suggestionModeCompletion;
- }
+ var text = applicableToText.Length > 0 ? applicableToText : suggestionModeItem.DisplayText;
+ var vsCompletion = GetVSCompletion(suggestionModeItem, text);
+
+ VsCompletionSet.WritableCompletionBuilders.Add(vsCompletion);
}
}
finally
{
VsCompletionSet.WritableCompletionBuilders.EndBulkOperation();
}
+ }
+ private void CreateNormalCompletionListItems(IList completionItems)
+ {
try
{
VsCompletionSet.WritableCompletions.BeginBulkOperation();
@@ -124,45 +123,35 @@ public void SetTrackingSpan(ITrackingSpan trackingSpan)
{
var completionItem = GetVSCompletion(item);
VsCompletionSet.WritableCompletions.Add(completionItem);
-
- if (item == selectedItem)
- {
- selectedCompletionItem = completionItem;
- }
}
}
finally
{
VsCompletionSet.WritableCompletions.EndBulkOperation();
}
-
- VsCompletionSet.SelectionStatus = new CompletionSelectionStatus(
- selectedCompletionItem, isSelected: !isSoftSelected, isUnique: selectedCompletionItem != null);
}
protected virtual void SetupFilters(ImmutableArray completionItemFilters)
{
}
- private VSCompletion GetVSCompletion(PresentationItem item)
+ private VSCompletion GetVSCompletion(CompletionItem item, string displayText = null)
{
VSCompletion value;
- if (!PresentationItemMap.TryGetValue(item, out value))
+ if (!CompletionItemMap.TryGetValue(item, out value))
{
- value = new CustomCommitCompletion(
- CompletionPresenterSession,
- item);
- PresentationItemMap.Add(item, value);
+ value = new CustomCommitCompletion(CompletionPresenterSession, item, displayText);
+ CompletionItemMap.Add(item, value);
}
return value;
}
- public PresentationItem GetPresentationItem(VSCompletion completion)
+ public CompletionItem GetCompletionItem(VSCompletion completion)
{
// Linear search is ok since this is only called by the user manually selecting
// an item. Creating a reverse mapping uses too much memory and affects GCs.
- foreach (var kvp in PresentationItemMap)
+ foreach (var kvp in CompletionItemMap)
{
if (kvp.Value == completion)
{
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/VisualStudio14CompletionSet.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/VisualStudio14CompletionSet.cs
index e34d605d79ea75822ef30c24e55f9cb554f7b0a6..ea21e53268d495425740575e1d3a1b86a71f1680 100644
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/VisualStudio14CompletionSet.cs
+++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Presentation/VisualStudio14CompletionSet.cs
@@ -51,14 +51,18 @@ void ICompletionSet.SetTrackingSpan(ITrackingSpan trackingSpan)
_roslynCompletionSet.SetTrackingSpan(trackingSpan);
}
- void ICompletionSet.SetCompletionItems(IList completionItems, PresentationItem selectedItem, PresentationItem presetBuilder, bool suggestionMode, bool isSoftSelected, ImmutableArray completionItemFilters, string filterText)
+ void ICompletionSet.SetCompletionItems(
+ IList completionItems, CompletionItem selectedItem,
+ CompletionItem suggestionModeItem, bool suggestionMode, bool isSoftSelected, ImmutableArray completionItemFilters, string filterText)
{
- _roslynCompletionSet.SetCompletionItems(completionItems, selectedItem, presetBuilder, suggestionMode, isSoftSelected, completionItemFilters, filterText);
+ _roslynCompletionSet.SetCompletionItems(
+ completionItems, selectedItem, suggestionModeItem, suggestionMode,
+ isSoftSelected, completionItemFilters, filterText);
}
- PresentationItem ICompletionSet.GetPresentationItem(VSCompletion completion)
+ CompletionItem ICompletionSet.GetCompletionItem(VSCompletion completion)
{
- return _roslynCompletionSet.GetPresentationItem(completion);
+ return _roslynCompletionSet.GetCompletionItem(completion);
}
#endregion
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/SimplePresentationItem.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/SimplePresentationItem.cs
deleted file mode 100644
index c8bbc1d2e10acd95ff92a400ace3202a72b302da..0000000000000000000000000000000000000000
--- a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/SimplePresentationItem.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Diagnostics;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.CodeAnalysis.Completion;
-
-namespace Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.Completion
-{
- internal class SimplePresentationItem : PresentationItem
- {
- public override CompletionItem Item { get; }
- public override bool IsSuggestionModeItem { get; }
- public override CompletionService CompletionService { get; }
-
- public SimplePresentationItem(CompletionItem item, CompletionService completionService, bool isSuggestionModeItem = false)
- {
- Debug.Assert(item != null);
- Debug.Assert(completionService != null);
-
- this.Item = item;
- this.CompletionService = completionService;
- this.IsSuggestionModeItem = isSuggestionModeItem;
- }
-
- public override Task GetDescriptionAsync(Document document, CancellationToken cancellationToken)
- {
- return this.CompletionService.GetDescriptionAsync(document, this.Item, cancellationToken);
- }
- }
-}
diff --git a/src/EditorFeatures/Next/IntelliSense/Completion/Presentation/Roslyn15CompletionSet.cs b/src/EditorFeatures/Next/IntelliSense/Completion/Presentation/Roslyn15CompletionSet.cs
index 1e43094203f020a616355b6f01f4892f0753af90..9e834f14dfcb1117cabb3b7ba6b9ed1799c6eaf9 100644
--- a/src/EditorFeatures/Next/IntelliSense/Completion/Presentation/Roslyn15CompletionSet.cs
+++ b/src/EditorFeatures/Next/IntelliSense/Completion/Presentation/Roslyn15CompletionSet.cs
@@ -76,12 +76,12 @@ public IReadOnlyList GetHighlightedSpansInDisplayText(string displayText)
var completionHelper = this.GetCompletionHelper();
if (completionHelper != null)
{
- var presentationItem = this.PresentationItemMap.Keys.FirstOrDefault(k => k.Item.DisplayText == displayText);
+ var completionItem = this.CompletionItemMap.Keys.FirstOrDefault(k => k.DisplayText == displayText);
- if (presentationItem != null && !presentationItem.IsSuggestionModeItem)
+ if (completionItem != null && completionItem != SuggestionModeItem)
{
var highlightedSpans = completionHelper.GetHighlightedSpans(
- presentationItem.Item, FilterText, CultureInfo.CurrentCulture);
+ completionItem, FilterText, CultureInfo.CurrentCulture);
if (highlightedSpans != null)
{
return highlightedSpans.Select(s => s.ToSpan()).ToArray();
diff --git a/src/EditorFeatures/Next/IntelliSense/Completion/Presentation/VisualStudio15CompletionSet.cs b/src/EditorFeatures/Next/IntelliSense/Completion/Presentation/VisualStudio15CompletionSet.cs
index 0bfbcbdeb82fb1c69fad076c42eee4819fe40277..5377fc6065ee3d076fc4a01d3f34bd72eebaae0a 100644
--- a/src/EditorFeatures/Next/IntelliSense/Completion/Presentation/VisualStudio15CompletionSet.cs
+++ b/src/EditorFeatures/Next/IntelliSense/Completion/Presentation/VisualStudio15CompletionSet.cs
@@ -77,14 +77,14 @@ void ICompletionSet.SetTrackingSpan(ITrackingSpan trackingSpan)
_roslynCompletionSet.SetTrackingSpan(trackingSpan);
}
- void ICompletionSet.SetCompletionItems(IList completionItems, PresentationItem selectedItem, PresentationItem presetBuilder, bool suggestionMode, bool isSoftSelected, ImmutableArray completionItemFilters, string filterText)
+ void ICompletionSet.SetCompletionItems(IList completionItems, CompletionItem selectedItem, CompletionItem presetBuilder, bool suggestionMode, bool isSoftSelected, ImmutableArray completionItemFilters, string filterText)
{
_roslynCompletionSet.SetCompletionItems(completionItems, selectedItem, presetBuilder, suggestionMode, isSoftSelected, completionItemFilters, filterText);
}
- PresentationItem ICompletionSet.GetPresentationItem(VSCompletion completion)
+ CompletionItem ICompletionSet.GetCompletionItem(VSCompletion completion)
{
- return _roslynCompletionSet.GetPresentationItem(completion);
+ return _roslynCompletionSet.GetCompletionItem(completion);
}
#endregion
diff --git a/src/EditorFeatures/Test/Completion/AbstractCompletionProviderTests.cs b/src/EditorFeatures/Test/Completion/AbstractCompletionProviderTests.cs
index 831f7f14b0e4e61003230fa74d5cb23d14453cea..cb4dbaad100f1fe8a8f630af2a31a65c53aa0e62 100644
--- a/src/EditorFeatures/Test/Completion/AbstractCompletionProviderTests.cs
+++ b/src/EditorFeatures/Test/Completion/AbstractCompletionProviderTests.cs
@@ -430,8 +430,7 @@ protected virtual void SetWorkspaceOptions(TestWorkspace workspace)
if (commitChar == '\t' ||
Controller.IsCommitCharacter(service.GetRules(), firstItem, commitChar, textTypedSoFar + commitChar))
{
- var textChange = await DescriptionModifyingPresentationItem.GetTextChangeAsync(
- service, document, firstItem, commitChar);
+ var textChange = (await service.GetChangeAsync(document, firstItem, commitChar, CancellationToken.None)).TextChange;
// Adjust TextChange to include commit character, so long as it isn't TAB.
if (commitChar != '\t')
diff --git a/src/EditorFeatures/Test2/IntelliSense/CSharpCompletionCommandHandlerTests.vb b/src/EditorFeatures/Test2/IntelliSense/CSharpCompletionCommandHandlerTests.vb
index f69fec4acfa5a6a3e4b9ab2e3dd1130f3634cd42..b664c087e078e1cbc9415c5c99398ce16b1f658e 100644
--- a/src/EditorFeatures/Test2/IntelliSense/CSharpCompletionCommandHandlerTests.vb
+++ b/src/EditorFeatures/Test2/IntelliSense/CSharpCompletionCommandHandlerTests.vb
@@ -648,7 +648,7 @@ class C
state.SendTypeChars(" ")
Await state.WaitForAsynchronousOperationsAsync()
Await state.AssertSelectedCompletionItem(displayText:="string", isHardSelected:=True)
- Assert.True(state.CurrentCompletionPresenterSession.PresentationItems.Any(Function(c) c.Item.DisplayText = "int"))
+ Assert.True(state.CurrentCompletionPresenterSession.CompletionItems.Any(Function(c) c.DisplayText = "int"))
End Using
End Function
@@ -673,9 +673,9 @@ class Foo
state.SendTypeChars("a")
Await state.AssertCompletionSession()
- Assert.True(state.CurrentCompletionPresenterSession.PresentationItems.Any(Function(i) i.Item.DisplayText = "num:"))
- Assert.False(state.CurrentCompletionPresenterSession.PresentationItems.Any(Function(i) i.Item.DisplayText = "System"))
- Assert.False(state.CurrentCompletionPresenterSession.PresentationItems.Any(Function(c) c.Item.DisplayText = "int"))
+ Assert.True(state.CurrentCompletionPresenterSession.CompletionItems.Any(Function(i) i.DisplayText = "num:"))
+ Assert.False(state.CurrentCompletionPresenterSession.CompletionItems.Any(Function(i) i.DisplayText = "System"))
+ Assert.False(state.CurrentCompletionPresenterSession.CompletionItems.Any(Function(c) c.DisplayText = "int"))
End Using
End Function
@@ -698,7 +698,7 @@ class Foo
state.SendTypeChars(", ")
Await state.WaitForAsynchronousOperationsAsync()
Await state.AssertSelectedCompletionItem(displayText:="Numeros", isHardSelected:=True)
- Assert.Equal(1, state.CurrentCompletionPresenterSession.PresentationItems.Where(Function(c) c.Item.DisplayText = "Numeros").Count())
+ Assert.Equal(1, state.CurrentCompletionPresenterSession.CompletionItems.Where(Function(c) c.DisplayText = "Numeros").Count())
End Using
End Function
@@ -721,7 +721,7 @@ class Foo
state.SendTypeChars(", ")
Await state.WaitForAsynchronousOperationsAsync()
Await state.AssertSelectedCompletionItem(displayText:="Numeros", isHardSelected:=True)
- Assert.Equal(1, state.CurrentCompletionPresenterSession.PresentationItems.Where(Function(c) c.Item.DisplayText = "Numeros").Count())
+ Assert.Equal(1, state.CurrentCompletionPresenterSession.CompletionItems.Where(Function(c) c.DisplayText = "Numeros").Count())
End Using
End Function
@@ -791,13 +791,13 @@ class Program
state.SendTypeChars("i")
Await state.AssertCompletionSession()
- Assert.True(state.CurrentCompletionPresenterSession.PresentationItems.Any(Function(i) i.Item.DisplayText = "@int:"))
+ Assert.True(state.CurrentCompletionPresenterSession.CompletionItems.Any(Function(i) i.DisplayText = "@int:"))
state.SendTypeChars("n")
Await state.WaitForAsynchronousOperationsAsync()
- Assert.True(state.CurrentCompletionPresenterSession.PresentationItems.Any(Function(i) i.Item.DisplayText = "@int:"))
+ Assert.True(state.CurrentCompletionPresenterSession.CompletionItems.Any(Function(i) i.DisplayText = "@int:"))
state.SendTypeChars("t")
Await state.WaitForAsynchronousOperationsAsync()
- Assert.True(state.CurrentCompletionPresenterSession.PresentationItems.Any(Function(i) i.Item.DisplayText = "@int:"))
+ Assert.True(state.CurrentCompletionPresenterSession.CompletionItems.Any(Function(i) i.DisplayText = "@int:"))
End Using
End Function
@@ -1145,7 +1145,7 @@ class A
]]>)
state.SendTypeChars("X")
Await state.AssertCompletionSession()
- Assert.False(state.CurrentCompletionPresenterSession.PresentationItems.Any(Function(i) i.Item.DisplayText = "X"))
+ Assert.False(state.CurrentCompletionPresenterSession.CompletionItems.Any(Function(i) i.DisplayText = "X"))
End Using
End Function
@@ -1503,7 +1503,7 @@ class AtAttribute : System.Attribute { }]]>)
state.SendTypeChars("At")
Await state.WaitForAsynchronousOperationsAsync()
Await state.AssertSelectedCompletionItem("At")
- Assert.Equal("At", state.CurrentCompletionPresenterSession.SelectedItem.Item.FilterText)
+ Assert.Equal("At", state.CurrentCompletionPresenterSession.SelectedItem.FilterText)
End Using
End Function
@@ -1579,7 +1579,7 @@ class C
state.SendTypeChars("Thing1")
Await state.WaitForAsynchronousOperationsAsync()
Await state.AssertSelectedCompletionItem("Thing1")
- Assert.True(state.CurrentCompletionPresenterSession.SelectedItem.Item.Tags.Contains(CompletionTags.Warning))
+ Assert.True(state.CurrentCompletionPresenterSession.SelectedItem.Tags.Contains(CompletionTags.Warning))
state.SendBackspace()
state.SendBackspace()
state.SendBackspace()
@@ -1589,7 +1589,7 @@ class C
state.SendTypeChars("M")
Await state.WaitForAsynchronousOperationsAsync()
Await state.AssertSelectedCompletionItem("M")
- Assert.False(state.CurrentCompletionPresenterSession.SelectedItem.Item.Tags.Contains(CompletionTags.Warning))
+ Assert.False(state.CurrentCompletionPresenterSession.SelectedItem.Tags.Contains(CompletionTags.Warning))
End Using
End Function
diff --git a/src/EditorFeatures/Test2/IntelliSense/TestCompletionPresenterSession.vb b/src/EditorFeatures/Test2/IntelliSense/TestCompletionPresenterSession.vb
index 6518e938d83a9b41b5a7e3e0670c1d97e37968f2..a4587157d98166884580206b55f6f094cc53440c 100644
--- a/src/EditorFeatures/Test2/IntelliSense/TestCompletionPresenterSession.vb
+++ b/src/EditorFeatures/Test2/IntelliSense/TestCompletionPresenterSession.vb
@@ -12,14 +12,14 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
Private ReadOnly _testState As IIntelliSenseTestState
Public TriggerSpan As ITrackingSpan
- Public PresentationItems As IList(Of PresentationItem)
- Public SelectedItem As PresentationItem
+ Public CompletionItems As IList(Of CompletionItem)
+ Public SelectedItem As CompletionItem
Public IsSoftSelected As Boolean
- Public SuggestionModeItem As PresentationItem
+ Public SuggestionModeItem As CompletionItem
Public Event Dismissed As EventHandler(Of EventArgs) Implements ICompletionPresenterSession.Dismissed
- Public Event ItemSelected As EventHandler(Of PresentationItemEventArgs) Implements ICompletionPresenterSession.ItemSelected
- Public Event ItemCommitted As EventHandler(Of PresentationItemEventArgs) Implements ICompletionPresenterSession.ItemCommitted
+ Public Event ItemSelected As EventHandler(Of CompletionItemEventArgs) Implements ICompletionPresenterSession.ItemSelected
+ Public Event ItemCommitted As EventHandler(Of CompletionItemEventArgs) Implements ICompletionPresenterSession.ItemCommitted
Public Event CompletionFiltersChanged As EventHandler(Of CompletionItemFilterStateChangedEventArgs) Implements ICompletionPresenterSession.FilterStateChanged
Public Sub New(testState As IIntelliSenseTestState)
@@ -27,16 +27,16 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
End Sub
Public Sub PresentItems(triggerSpan As ITrackingSpan,
- presentationItems As IList(Of PresentationItem),
- selectedItem As PresentationItem,
- suggestionModeItem As PresentationItem,
+ completionItems As IList(Of CompletionItem),
+ selectedItem As CompletionItem,
+ suggestionModeItem As CompletionItem,
suggestionMode As Boolean,
isSoftSelected As Boolean,
completionItemFilters As ImmutableArray(Of CompletionItemFilter),
filterText As String) Implements ICompletionPresenterSession.PresentItems
_testState.CurrentCompletionPresenterSession = Me
Me.TriggerSpan = triggerSpan
- Me.PresentationItems = presentationItems
+ Me.CompletionItems = completionItems
Me.SelectedItem = selectedItem
Me.IsSoftSelected = isSoftSelected
Me.SuggestionModeItem = suggestionModeItem
@@ -46,21 +46,21 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
_testState.CurrentCompletionPresenterSession = Nothing
End Sub
- Public Sub SetSelectedItem(item As PresentationItem)
+ Public Sub SetSelectedItem(item As CompletionItem)
Me.SelectedItem = item
- RaiseEvent ItemSelected(Me, New PresentationItemEventArgs(item))
+ RaiseEvent ItemSelected(Me, New CompletionItemEventArgs(item))
End Sub
- Private Function GetFilteredItemAt(index As Integer) As PresentationItem
- index = Math.Max(0, Math.Min(PresentationItems.Count - 1, index))
- Return PresentationItems(index)
+ Private Function GetFilteredItemAt(index As Integer) As CompletionItem
+ index = Math.Max(0, Math.Min(CompletionItems.Count - 1, index))
+ Return CompletionItems(index)
End Function
Private Sub SelectPreviousItem() Implements ICompletionPresenterSession.SelectPreviousItem
If IsSoftSelected Then
IsSoftSelected = False
Else
- SetSelectedItem(GetFilteredItemAt(PresentationItems.IndexOf(SelectedItem) - 1))
+ SetSelectedItem(GetFilteredItemAt(CompletionItems.IndexOf(SelectedItem) - 1))
End If
End Sub
@@ -68,18 +68,18 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
If IsSoftSelected Then
IsSoftSelected = False
Else
- SetSelectedItem(GetFilteredItemAt(PresentationItems.IndexOf(SelectedItem) + 1))
+ SetSelectedItem(GetFilteredItemAt(CompletionItems.IndexOf(SelectedItem) + 1))
End If
End Sub
Private Const s_itemsPerPage = 9
Public Sub SelectPreviousPageItem() Implements ICompletionPresenterSession.SelectPreviousPageItem
- SetSelectedItem(GetFilteredItemAt(PresentationItems.IndexOf(SelectedItem) - s_itemsPerPage))
+ SetSelectedItem(GetFilteredItemAt(CompletionItems.IndexOf(SelectedItem) - s_itemsPerPage))
End Sub
Public Sub SelectNextPageItem() Implements ICompletionPresenterSession.SelectNextPageItem
- SetSelectedItem(GetFilteredItemAt(PresentationItems.IndexOf(SelectedItem) + s_itemsPerPage))
+ SetSelectedItem(GetFilteredItemAt(CompletionItems.IndexOf(SelectedItem) + s_itemsPerPage))
End Sub
End Class
End Namespace
diff --git a/src/EditorFeatures/Test2/IntelliSense/TestState.vb b/src/EditorFeatures/Test2/IntelliSense/TestState.vb
index e08bb2c66b7a8df740fefcf2b1ce0bac9d2b464a..2ea81e26ff6e560490e32cb15ac7c8d14b87fb7e 100644
--- a/src/EditorFeatures/Test2/IntelliSense/TestState.vb
+++ b/src/EditorFeatures/Test2/IntelliSense/TestState.vb
@@ -188,7 +188,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
MyBase.SendCommitUniqueCompletionListItem(Sub(a, n) handler.ExecuteCommand(a, n), Sub() Return)
End Sub
- Public Overloads Sub SendSelectCompletionItemThroughPresenterSession(item As PresentationItem)
+ Public Overloads Sub SendSelectCompletionItemThroughPresenterSession(item As CompletionItem)
CurrentCompletionPresenterSession.SetSelectedItem(item)
End Sub
@@ -226,17 +226,18 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
Public Function CompletionItemsContainsAll(displayText As String()) As Boolean
AssertNoAsynchronousOperationsRunning()
- Return displayText.All(Function(v) CurrentCompletionPresenterSession.PresentationItems.Any(
- Function(i) i.Item.DisplayText = v))
+ Return displayText.All(Function(v) CurrentCompletionPresenterSession.CompletionItems.Any(
+ Function(i) i.DisplayText = v))
End Function
Public Function CompletionItemsContainsAny(displayText As String()) As Boolean
AssertNoAsynchronousOperationsRunning()
- Return displayText.Any(Function(v) CurrentCompletionPresenterSession.PresentationItems.Any(
- Function(i) i.Item.DisplayText = v))
+ Return displayText.Any(Function(v) CurrentCompletionPresenterSession.CompletionItems.Any(
+ Function(i) i.DisplayText = v))
End Function
- Public Async Function AssertSelectedCompletionItem(Optional displayText As String = Nothing,
+ Public Async Function AssertSelectedCompletionItem(
+ Optional displayText As String = Nothing,
Optional description As String = Nothing,
Optional isSoftSelected As Boolean? = Nothing,
Optional isHardSelected As Boolean? = Nothing,
@@ -251,11 +252,11 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
End If
If displayText IsNot Nothing Then
- Assert.Equal(displayText, Me.CurrentCompletionPresenterSession.SelectedItem.Item.DisplayText)
+ Assert.Equal(displayText, Me.CurrentCompletionPresenterSession.SelectedItem.DisplayText)
End If
If shouldFormatOnCommit.HasValue Then
- Assert.Equal(shouldFormatOnCommit.Value, Me.CurrentCompletionPresenterSession.SelectedItem.Item.Rules.FormatOnCommit)
+ Assert.Equal(shouldFormatOnCommit.Value, Me.CurrentCompletionPresenterSession.SelectedItem.Rules.FormatOnCommit)
End If
#If False Then
@@ -266,7 +267,9 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
If description IsNot Nothing Then
Dim document = Me.Workspace.CurrentSolution.Projects.First().Documents.First()
- Dim itemDescription = Await Me.CurrentCompletionPresenterSession.SelectedItem.GetDescriptionAsync(document, CancellationToken.None)
+ Dim service = CompletionService.GetService(document)
+ Dim itemDescription = Await service.GetDescriptionAsync(
+ document, Me.CurrentCompletionPresenterSession.SelectedItem)
Assert.Equal(description, itemDescription.Text)
End If
End Function
diff --git a/src/EditorFeatures/Test2/IntelliSense/VisualBasicCompletionCommandHandlerTests.vb b/src/EditorFeatures/Test2/IntelliSense/VisualBasicCompletionCommandHandlerTests.vb
index 5b0c179b839f6a0d3af575848d0573d1cb80ce0a..2ec76a9be78f2fae3c1f21cea9f8fefcfe8b4ab0 100644
--- a/src/EditorFeatures/Test2/IntelliSense/VisualBasicCompletionCommandHandlerTests.vb
+++ b/src/EditorFeatures/Test2/IntelliSense/VisualBasicCompletionCommandHandlerTests.vb
@@ -345,7 +345,7 @@ End Class
)
state.SendTypeChars(".A")
Await state.AssertCompletionSession()
- Assert.Equal(3, state.CurrentCompletionPresenterSession.PresentationItems.Count)
+ Assert.Equal(3, state.CurrentCompletionPresenterSession.CompletionItems.Count)
End Using
End Function
@@ -371,10 +371,10 @@ End Class
)
state.SendTypeChars(".A")
Await state.WaitForAsynchronousOperationsAsync()
- Assert.Equal(4, state.CurrentCompletionPresenterSession.PresentationItems.Count)
+ Assert.Equal(4, state.CurrentCompletionPresenterSession.CompletionItems.Count)
state.SendTypeChars("A")
Await state.WaitForAsynchronousOperationsAsync()
- Assert.Equal(2, state.CurrentCompletionPresenterSession.PresentationItems.Count)
+ Assert.Equal(2, state.CurrentCompletionPresenterSession.CompletionItems.Count)
End Using
End Function
@@ -565,8 +565,8 @@ End Class
Await state.AssertCompletionSession()
Await state.AssertSelectedCompletionItem(displayText:="A", isHardSelected:=True)
Await state.WaitForAsynchronousOperationsAsync()
- state.SendSelectCompletionItemThroughPresenterSession(state.CurrentCompletionPresenterSession.PresentationItems.First(
- Function(i) i.Item.DisplayText = "B"))
+ state.SendSelectCompletionItemThroughPresenterSession(state.CurrentCompletionPresenterSession.CompletionItems.First(
+ Function(i) i.DisplayText = "B"))
state.SendTab()
Assert.Contains(".B", state.GetLineTextFromCaretPosition(), StringComparison.Ordinal)
End Using
@@ -1012,10 +1012,10 @@ End Class
state.SendTypeChars("s")
Await state.AssertCompletionSession()
- Assert.True(state.CurrentCompletionPresenterSession.PresentationItems.Any(Function(i) i.Item.DisplayText = "string:="))
+ Assert.True(state.CurrentCompletionPresenterSession.CompletionItems.Any(Function(i) i.DisplayText = "string:="))
state.SendTypeChars("t")
Await state.WaitForAsynchronousOperationsAsync()
- Assert.True(state.CurrentCompletionPresenterSession.PresentationItems.Any(Function(i) i.Item.DisplayText = "string:="))
+ Assert.True(state.CurrentCompletionPresenterSession.CompletionItems.Any(Function(i) i.DisplayText = "string:="))
End Using
End Function
@@ -1039,8 +1039,8 @@ End Class
state.SendTypeChars(" ")
Await state.AssertCompletionSession()
- Assert.Equal(1, state.CurrentCompletionPresenterSession.PresentationItems.Count)
- Assert.True(state.CurrentCompletionPresenterSession.PresentationItems.Any(Function(i) i.Item.DisplayText = "str:="))
+ Assert.Equal(1, state.CurrentCompletionPresenterSession.CompletionItems.Count)
+ Assert.True(state.CurrentCompletionPresenterSession.CompletionItems.Any(Function(i) i.DisplayText = "str:="))
End Using
End Function
@@ -1068,11 +1068,11 @@ End Class
state.SendTypeChars(" ")
Await state.AssertCompletionSession()
- Assert.Equal(3, state.CurrentCompletionPresenterSession.PresentationItems.Count)
- Assert.True(state.CurrentCompletionPresenterSession.PresentationItems.Any(Function(i) i.Item.DisplayText = "b:="))
- Assert.True(state.CurrentCompletionPresenterSession.PresentationItems.Any(Function(i) i.Item.DisplayText = "num:="))
- Assert.True(state.CurrentCompletionPresenterSession.PresentationItems.Any(Function(i) i.Item.DisplayText = "str:="))
- Assert.False(state.CurrentCompletionPresenterSession.PresentationItems.Any(Function(i) i.Item.DisplayText = "dbl:="))
+ Assert.Equal(3, state.CurrentCompletionPresenterSession.CompletionItems.Count)
+ Assert.True(state.CurrentCompletionPresenterSession.CompletionItems.Any(Function(i) i.DisplayText = "b:="))
+ Assert.True(state.CurrentCompletionPresenterSession.CompletionItems.Any(Function(i) i.DisplayText = "num:="))
+ Assert.True(state.CurrentCompletionPresenterSession.CompletionItems.Any(Function(i) i.DisplayText = "str:="))
+ Assert.False(state.CurrentCompletionPresenterSession.CompletionItems.Any(Function(i) i.DisplayText = "dbl:="))
End Using
End Function
@@ -1615,10 +1615,10 @@ End Class
]]>)
state.SendBackspace()
Await state.AssertCompletionSession()
- Assert.True(state.CurrentCompletionPresenterSession.PresentationItems.Any(Function(c) c.Item.DisplayText = "AccessViolationException"))
+ Assert.True(state.CurrentCompletionPresenterSession.CompletionItems.Any(Function(c) c.DisplayText = "AccessViolationException"))
state.SendBackspace()
Await state.AssertCompletionSession()
- Assert.True(state.CurrentCompletionPresenterSession.PresentationItems.Any(Function(c) c.Item.DisplayText = "AccessViolationException"))
+ Assert.True(state.CurrentCompletionPresenterSession.CompletionItems.Any(Function(c) c.DisplayText = "AccessViolationException"))
End Using
End Function
@@ -1675,7 +1675,7 @@ End Class
]]>)
state.SendTypeChars("selec")
Await state.WaitForAsynchronousOperationsAsync()
- Assert.Equal(state.CurrentCompletionPresenterSession.PresentationItems.Count, 2)
+ Assert.Equal(state.CurrentCompletionPresenterSession.CompletionItems.Count, 2)
End Using
End Function
@@ -2049,9 +2049,9 @@ End Class)
state.SendTypeChars("(")
Await state.AssertCompletionSession()
' DayOfWeek.Monday should immediately follow DayOfWeek.Friday
- Dim friday = state.CurrentCompletionPresenterSession.PresentationItems.First(Function(i) i.Item.DisplayText = "DayOfWeek.Friday")
- Dim monday = state.CurrentCompletionPresenterSession.PresentationItems.First(Function(i) i.Item.DisplayText = "DayOfWeek.Monday")
- Assert.True(state.CurrentCompletionPresenterSession.PresentationItems.IndexOf(friday) = state.CurrentCompletionPresenterSession.PresentationItems.IndexOf(monday) - 1)
+ Dim friday = state.CurrentCompletionPresenterSession.CompletionItems.First(Function(i) i.DisplayText = "DayOfWeek.Friday")
+ Dim monday = state.CurrentCompletionPresenterSession.CompletionItems.First(Function(i) i.DisplayText = "DayOfWeek.Monday")
+ Assert.True(state.CurrentCompletionPresenterSession.CompletionItems.IndexOf(friday) = state.CurrentCompletionPresenterSession.CompletionItems.IndexOf(monday) - 1)
End Using
End Function
@@ -2140,8 +2140,8 @@ End Class
state.SendInvokeCompletionList()
Await state.WaitForAsynchronousOperationsAsync()
' Should only have one item called 'Double' and it should have a keyword glyph
- Dim doubleItem = state.CurrentCompletionPresenterSession.PresentationItems.Single(Function(c) c.Item.DisplayText = "Double")
- Assert.True(doubleItem.Item.Tags.Contains(CompletionTags.Keyword))
+ Dim doubleItem = state.CurrentCompletionPresenterSession.CompletionItems.Single(Function(c) c.DisplayText = "Double")
+ Assert.True(doubleItem.Tags.Contains(CompletionTags.Keyword))
End Using
End Function
@@ -2160,10 +2160,10 @@ End Class
state.SendInvokeCompletionList()
Await state.WaitForAsynchronousOperationsAsync()
' We should have gotten the item corresponding to [Double] and the item for the Double keyword
- Dim doubleItems = state.CurrentCompletionPresenterSession.PresentationItems.Where(Function(c) c.Item.DisplayText = "Double")
+ Dim doubleItems = state.CurrentCompletionPresenterSession.CompletionItems.Where(Function(c) c.DisplayText = "Double")
Assert.Equal(2, doubleItems.Count())
- Assert.True(doubleItems.Any(Function(c) c.Item.Tags.Contains(CompletionTags.Keyword)))
- Assert.True(doubleItems.Any(Function(c) c.Item.Tags.Contains(CompletionTags.Class) AndAlso c.Item.Tags.Contains(CompletionTags.Internal)))
+ Assert.True(doubleItems.Any(Function(c) c.Tags.Contains(CompletionTags.Keyword)))
+ Assert.True(doubleItems.Any(Function(c) c.Tags.Contains(CompletionTags.Class) AndAlso c.Tags.Contains(CompletionTags.Internal)))
End Using
End Function
diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/AttributeNamedParameterCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/AttributeNamedParameterCompletionProvider.cs
index dc240b880c8de9bb252590de0a2ba34d7441ad9a..77cda7299defbad2b26be45098edcbf82c42b453 100644
--- a/src/Features/CSharp/Portable/Completion/CompletionProviders/AttributeNamedParameterCompletionProvider.cs
+++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/AttributeNamedParameterCompletionProvider.cs
@@ -174,10 +174,8 @@ private bool IsAfterNameEqualsArgument(SyntaxToken token)
rules: CompletionItemRules.Default);
}
- public override Task GetDescriptionAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
- {
- return SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
- }
+ protected override Task GetDescriptionWorkerAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
+ => SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
private bool IsValid(ImmutableArray parameterList, ISet existingNamedParameters)
{
diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/CrefCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/CrefCompletionProvider.cs
index a272f71e97d9576d4c561e672c2fd2263ffabf6a..4ba11bf50ab6563c37b307bd1f9cad80c4aaf307 100644
--- a/src/Features/CSharp/Portable/Completion/CompletionProviders/CrefCompletionProvider.cs
+++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/CrefCompletionProvider.cs
@@ -312,10 +312,8 @@ private static TextSpan GetCompletionItemSpan(SourceText text, int position)
rules: GetRules(insertionText));
}
- public override Task GetDescriptionAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
- {
- return SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
- }
+ protected override Task GetDescriptionWorkerAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
+ => SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
private static readonly CharacterSetModificationRule s_WithoutOpenBrace = CharacterSetModificationRule.Create(CharacterSetModificationKind.Remove, '{');
private static readonly CharacterSetModificationRule s_WithoutOpenParen = CharacterSetModificationRule.Create(CharacterSetModificationKind.Remove, '(');
diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/EnumAndCompletionListTagCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/EnumAndCompletionListTagCompletionProvider.cs
index 0f5342a9b2b5afc1c79a7a8244fc4c9479845658..6df94a6f6e53d80b8f61d7541c28bf2f147ebbba 100644
--- a/src/Features/CSharp/Portable/Completion/CompletionProviders/EnumAndCompletionListTagCompletionProvider.cs
+++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/EnumAndCompletionListTagCompletionProvider.cs
@@ -127,10 +127,8 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
}
}
- public override Task GetDescriptionAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
- {
- return SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
- }
+ protected override Task GetDescriptionWorkerAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
+ => SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
private static readonly CompletionItemRules s_rules =
CompletionItemRules.Default.WithCommitCharacterRules(ImmutableArray.Create(CharacterSetModificationRule.Create(CharacterSetModificationKind.Replace, '.')))
diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/ExplicitInterfaceCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/ExplicitInterfaceCompletionProvider.cs
index 9cedf6bc2f3535c3f6e17796ee7ef7a6caba44af..e3f6485843e1db26d8644029ea0e06384a6a3580 100644
--- a/src/Features/CSharp/Portable/Completion/CompletionProviders/ExplicitInterfaceCompletionProvider.cs
+++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/ExplicitInterfaceCompletionProvider.cs
@@ -108,11 +108,8 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
}
}
- public override Task GetDescriptionAsync(
- Document document, CompletionItem item, CancellationToken cancellationToken)
- {
- return SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
- }
+ protected override Task GetDescriptionWorkerAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
+ => SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
public override Task GetTextChangeAsync(
Document document, CompletionItem selectedItem, char? ch, CancellationToken cancellationToken)
diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/NamedParameterCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/NamedParameterCompletionProvider.cs
index c20cc663c3621416741f5d4cff89bed172bd8705..5e53cfd429e62a09619461e15e691fbc3183ed8a 100644
--- a/src/Features/CSharp/Portable/Completion/CompletionProviders/NamedParameterCompletionProvider.cs
+++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/NamedParameterCompletionProvider.cs
@@ -106,10 +106,8 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
}
}
- public override Task GetDescriptionAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
- {
- return SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
- }
+ protected override Task GetDescriptionWorkerAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
+ => SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
private bool IsValid(ImmutableArray parameterList, ISet existingNamedParameters)
{
diff --git a/src/Features/Core/Portable/Completion/CommonCompletionProvider.cs b/src/Features/Core/Portable/Completion/CommonCompletionProvider.cs
index f2f702c49a492e03804647838aeddc25ab4ecdfb..85c301e7c28e352ee052796f90eadb73655bd4dc 100644
--- a/src/Features/Core/Portable/Completion/CommonCompletionProvider.cs
+++ b/src/Features/Core/Portable/Completion/CommonCompletionProvider.cs
@@ -1,9 +1,13 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Options;
+using Microsoft.CodeAnalysis.Snippets;
using Microsoft.CodeAnalysis.Text;
-using System.Threading;
namespace Microsoft.CodeAnalysis.Completion
{
@@ -27,18 +31,55 @@ internal virtual bool IsInsertionTrigger(SourceText text, int insertedCharacterP
return false;
}
- public override Task GetDescriptionAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
+ public sealed override async Task GetDescriptionAsync(
+ Document document, CompletionItem item, CancellationToken cancellationToken)
{
- if (CommonCompletionItem.HasDescription(item))
- {
- return Task.FromResult(CommonCompletionItem.GetDescription(item));
- }
- else
+ // Get the actual description provided by whatever subclass we are.
+ // Then, if we would commit text that could be expanded as a snippet,
+ // put that information in the description so that the user knows.
+ var description = await this.GetDescriptionWorkerAsync(document, item, cancellationToken).ConfigureAwait(false);
+ var parts = await TryAddSnippetInvocationPart(document, item, description.TaggedParts, cancellationToken).ConfigureAwait(false);
+
+ return description.WithTaggedParts(parts);
+ }
+
+ private async Task> TryAddSnippetInvocationPart(
+ Document document, CompletionItem item,
+ ImmutableArray parts, CancellationToken cancellationToken)
+ {
+ var languageServices = document.Project.LanguageServices;
+ var snippetService = languageServices.GetService();
+ if (snippetService != null)
{
- return Task.FromResult(CompletionDescription.Empty);
+ var change = await GetTextChangeAsync(document, item, ch: '\t', cancellationToken: cancellationToken).ConfigureAwait(false) ??
+ new TextChange(item.Span, item.DisplayText);
+ var insertionText = change.NewText;
+
+ if (snippetService != null && snippetService.SnippetShortcutExists_NonBlocking(insertionText))
+ {
+ var note = string.Format(FeaturesResources.Note_colon_Tab_twice_to_insert_the_0_snippet, insertionText);
+
+ if (parts.Any())
+ {
+ parts = parts.Add(new TaggedText(TextTags.LineBreak, Environment.NewLine));
+ }
+
+ parts = parts.Add(new TaggedText(TextTags.Text, note));
+ }
}
+
+ return parts;
}
+ protected virtual Task GetDescriptionWorkerAsync(
+ Document document, CompletionItem item, CancellationToken cancellationToken)
+ {
+ return CommonCompletionItem.HasDescription(item)
+ ? Task.FromResult(CommonCompletionItem.GetDescription(item))
+ : Task.FromResult(CompletionDescription.Empty);
+ }
+
+
public override async Task GetChangeAsync(Document document, CompletionItem item, char? commitKey = null, CancellationToken cancellationToken = default(CancellationToken))
{
var change = (await GetTextChangeAsync(document, item, commitKey, cancellationToken).ConfigureAwait(false))
diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs
index 87f3fcbaf1f46236de6731d8580ab997e437aad2..98c75f7cd1eadc522379de1233cd334c80850eef 100644
--- a/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs
+++ b/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs
@@ -253,9 +253,7 @@ internal virtual CompletionItemRules GetRules()
return s_defaultRules;
}
- public override Task GetDescriptionAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
- {
- return MemberInsertionCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
- }
+ protected override Task GetDescriptionWorkerAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
+ => MemberInsertionCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
}
}
\ No newline at end of file
diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractObjectInitializerCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractObjectInitializerCompletionProvider.cs
index 6c5b6c560503b52d0da4dff63a1c0858d0ac60c0..2a84fecbca0d3a2b53fa90245798d1fcf853cd55 100644
--- a/src/Features/Core/Portable/Completion/Providers/AbstractObjectInitializerCompletionProvider.cs
+++ b/src/Features/Core/Portable/Completion/Providers/AbstractObjectInitializerCompletionProvider.cs
@@ -70,10 +70,8 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
}
}
- public override Task GetDescriptionAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
- {
- return SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
- }
+ protected override Task GetDescriptionWorkerAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
+ => SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
protected abstract Task IsExclusiveAsync(Document document, int position, CancellationToken cancellationToken);
diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractPartialTypeCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractPartialTypeCompletionProvider.cs
index 1c0cf668cbb29a6bc565ae2685f778405f002640..07397767a56d7d93335042337e0e286178f57758 100644
--- a/src/Features/Core/Portable/Completion/Providers/AbstractPartialTypeCompletionProvider.cs
+++ b/src/Features/Core/Portable/Completion/Providers/AbstractPartialTypeCompletionProvider.cs
@@ -110,10 +110,8 @@ private static bool NotNewDeclaredMember(INamedTypeSymbol symbol, SyntaxContext
.Any(node => !(node.SyntaxTree == context.SyntaxTree && node.Span.IntersectsWith(context.Position)));
}
- public override Task GetDescriptionAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
- {
- return SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
- }
+ protected override Task GetDescriptionWorkerAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
+ => SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
public override Task GetTextChangeAsync(Document document, CompletionItem selectedItem, char? ch, CancellationToken cancellationToken)
{
diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractSymbolCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractSymbolCompletionProvider.cs
index fde766e94b134c790ce02bf3038e7815318eb4ef..61cca6a0a848d5fbe64804ec3ff17586aa2a9e1b 100644
--- a/src/Features/Core/Portable/Completion/Providers/AbstractSymbolCompletionProvider.cs
+++ b/src/Features/Core/Portable/Completion/Providers/AbstractSymbolCompletionProvider.cs
@@ -132,10 +132,8 @@ protected AbstractSymbolCompletionProvider()
return null;
}
- public override Task GetDescriptionAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
- {
- return SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
- }
+ protected override Task GetDescriptionWorkerAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
+ => SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
protected virtual string GetFilterText(ISymbol symbol, string displayText, SyntaxContext context)
{
diff --git a/src/Features/VisualBasic/Portable/Completion/CompletionProviders/CrefCompletionProvider.vb b/src/Features/VisualBasic/Portable/Completion/CompletionProviders/CrefCompletionProvider.vb
index 1b63795548067cd55435cce0f7cdb186e5a2a404..f7e3269fa8322c8dcfdc79143f36504fc64a48b6 100644
--- a/src/Features/VisualBasic/Portable/Completion/CompletionProviders/CrefCompletionProvider.vb
+++ b/src/Features/VisualBasic/Portable/Completion/CompletionProviders/CrefCompletionProvider.vb
@@ -205,7 +205,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
rules:=GetRules(displayString))
End Function
- Public Overrides Function GetDescriptionAsync(document As Document, item As CompletionItem, cancellationToken As CancellationToken) As Task(Of CompletionDescription)
+ Protected Overrides Function GetDescriptionWorkerAsync(document As Document, item As CompletionItem, cancellationToken As CancellationToken) As Task(Of CompletionDescription)
If CommonCompletionItem.HasDescription(item) Then
Return Task.FromResult(CommonCompletionItem.GetDescription(item))
Else
diff --git a/src/Features/VisualBasic/Portable/Completion/CompletionProviders/NamedParameterCompletionProvider.vb b/src/Features/VisualBasic/Portable/Completion/CompletionProviders/NamedParameterCompletionProvider.vb
index b74047650ed4faf05946f1e69b7e11cda14a1a0a..b2032578794369ff0b06613ac3d5565974d49390 100644
--- a/src/Features/VisualBasic/Portable/Completion/CompletionProviders/NamedParameterCompletionProvider.vb
+++ b/src/Features/VisualBasic/Portable/Completion/CompletionProviders/NamedParameterCompletionProvider.vb
@@ -80,7 +80,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
WithFilterCharacterRule(CharacterSetModificationRule.Create(CharacterSetModificationKind.Remove, ":"c, "="c)).
WithCommitCharacterRule(CharacterSetModificationRule.Create(CharacterSetModificationKind.Add, ":"c, "="c))
- Public Overrides Function GetDescriptionAsync(document As Document, item As CompletionItem, cancellationToken As CancellationToken) As Task(Of CompletionDescription)
+ Protected Overrides Function GetDescriptionWorkerAsync(document As Document, item As CompletionItem, cancellationToken As CancellationToken) As Task(Of CompletionDescription)
Return SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken)
End Function
diff --git a/src/VisualStudio/Core/Test/Completion/CSharpCompletionSnippetNoteTests.vb b/src/VisualStudio/Core/Test/Completion/CSharpCompletionSnippetNoteTests.vb
index e1014a0b24dbb581bbe28bc88ed6c0d02ebf971e..5e0f0e38200c7b167d8880603fa35375e88345ae 100644
--- a/src/VisualStudio/Core/Test/Completion/CSharpCompletionSnippetNoteTests.vb
+++ b/src/VisualStudio/Core/Test/Completion/CSharpCompletionSnippetNoteTests.vb
@@ -121,7 +121,9 @@ class C
state.SendTypeChars("for")
Await state.AssertCompletionSession()
- Await state.AssertSelectedCompletionItem(description:=String.Format(FeaturesResources._0_Keyword, "for"))
+ Await state.AssertSelectedCompletionItem(
+ description:=String.Format(FeaturesResources._0_Keyword, "for") & vbCrLf &
+ String.Format(FeaturesResources.Note_colon_Tab_twice_to_insert_the_0_snippet, "for"))
End Using
End Function
diff --git a/src/VisualStudio/Core/Test/DebuggerIntelliSense/TestState.vb b/src/VisualStudio/Core/Test/DebuggerIntelliSense/TestState.vb
index 45d219ab7e09fa7a8df7cbf20e35d2a6d421ab69..239eeced6aa3f760bed24dd1eb2f5494f9c3aacd 100644
--- a/src/VisualStudio/Core/Test/DebuggerIntelliSense/TestState.vb
+++ b/src/VisualStudio/Core/Test/DebuggerIntelliSense/TestState.vb
@@ -193,7 +193,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.DebuggerIntelliSense
MyBase.SendCommitUniqueCompletionListItem(Sub(a, n) handler.ExecuteCommand(a, n), Sub() Return)
End Sub
- Public Overloads Sub SendSelectCompletionItemThroughPresenterSession(item As PresentationItem)
+ Public Overloads Sub SendSelectCompletionItemThroughPresenterSession(item As CompletionItem)
AssertNoAsynchronousOperationsRunning()
CurrentCompletionPresenterSession.SetSelectedItem(item)
End Sub
@@ -219,7 +219,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.DebuggerIntelliSense
End If
For Each displayText In displayTexts
- If Not CurrentCompletionPresenterSession.PresentationItems.Any(Function(i) i.Item.DisplayText = displayText) Then
+ If Not CurrentCompletionPresenterSession.CompletionItems.Any(Function(i) i.DisplayText = displayText) Then
Assert.False(True, "Didn't find '" & displayText & "' in completion.")
End If
Next
@@ -233,7 +233,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.DebuggerIntelliSense
End If
For Each displayText In displayTexts
- If CurrentCompletionPresenterSession.PresentationItems.Any(Function(i) i.Item.DisplayText = displayText) Then
+ If CurrentCompletionPresenterSession.CompletionItems.Any(Function(i) i.DisplayText = displayText) Then
Assert.False(True, "Found '" & displayText & "' in completion.")
End If
Next
@@ -256,7 +256,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.DebuggerIntelliSense
End If
If displayText IsNot Nothing Then
- Assert.Equal(displayText, Me.CurrentCompletionPresenterSession.SelectedItem.Item.DisplayText)
+ Assert.Equal(displayText, Me.CurrentCompletionPresenterSession.SelectedItem.DisplayText)
End If
#If False Then
@@ -267,7 +267,8 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.DebuggerIntelliSense
If description IsNot Nothing Then
Dim document = Me.Workspace.CurrentSolution.Projects.First().Documents.First()
- Dim itemDescription = Await Me.CurrentCompletionPresenterSession.SelectedItem.GetDescriptionAsync(document, CancellationToken.None)
+ Dim service = CompletionService.GetService(document)
+ Dim itemDescription = Await service.GetDescriptionAsync(document, Me.CurrentCompletionPresenterSession.SelectedItem)
Assert.Equal(description, itemDescription.Text)
End If
End Function
diff --git a/src/VisualStudio/Core/Test/Snippets/SnippetCompletionProviderTests.vb b/src/VisualStudio/Core/Test/Snippets/SnippetCompletionProviderTests.vb
index 1ba253e3cd4bf5eb615d8136ef875d81504722b0..cd97454a6aac6a071c881882c4cdea12cc15c477 100644
--- a/src/VisualStudio/Core/Test/Snippets/SnippetCompletionProviderTests.vb
+++ b/src/VisualStudio/Core/Test/Snippets/SnippetCompletionProviderTests.vb
@@ -23,12 +23,12 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Snippets
Assert.Equal(testState.GetDocumentText(), "a")
Await testState.WaitForAsynchronousOperationsAsync()
- Assert.Equal(testState.CurrentCompletionPresenterSession.SelectedItem.Item.DisplayText, "Shortcut")
+ Assert.Equal(testState.CurrentCompletionPresenterSession.SelectedItem.DisplayText, "Shortcut")
Dim document = testState.Workspace.CurrentSolution.Projects.First().Documents.First()
Dim service = document.Project.LanguageServices.GetService(Of CompletionService)
- Dim itemDescription = Await service.GetDescriptionAsync(document, testState.CurrentCompletionPresenterSession.SelectedItem.Item)
- Assert.Equal("Description", itemDescription.Text)
+ Dim itemDescription = Await service.GetDescriptionAsync(document, testState.CurrentCompletionPresenterSession.SelectedItem)
+ Assert.True(itemDescription.Text.StartsWith("Description"))
testState.SendTabToCompletion()
@@ -43,11 +43,11 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Snippets
Using testState
testState.SendTabToCompletion()
Await testState.WaitForAsynchronousOperationsAsync()
- Assert.Equal(testState.CurrentCompletionPresenterSession.SelectedItem.Item.DisplayText, "Shortcut")
+ Assert.Equal(testState.CurrentCompletionPresenterSession.SelectedItem.DisplayText, "Shortcut")
testState.SendBackspace()
Await testState.WaitForAsynchronousOperationsAsync()
- Assert.Equal(testState.CurrentCompletionPresenterSession.SelectedItem.Item.DisplayText, "Shortcut")
+ Assert.Equal(testState.CurrentCompletionPresenterSession.SelectedItem.DisplayText, "Shortcut")
testState.SendTabToCompletion()