提交 2456162e 编写于 作者: C CyrusNajmabadi

Merge branch 'master' into completionRazorMaster

......@@ -392,8 +392,11 @@
Inputs="@(IntermediateAssembly)"
Outputs="@(IntermediateAssembly);$(PostCompileBinaryModificationSentinelFile)">
<Message Text="Adding optimization data to @(IntermediateAssembly)"/>
<Exec Command="&quot;$(IbcMergePath)&quot; -q -f -partialNGEN -minify -mo &quot;@(IntermediateAssembly)&quot; -incremental &quot;$(OptimizationDataFile)&quot;" />
<!-- SKIPPING: https://github.com/dotnet/roslyn/issues/12508
<Message Text="Adding optimization data to @(IntermediateAssembly)"/>
<Exec Command="&quot;$(IbcMergePath)&quot; -q -f -partialNGEN -minify -mo &quot;@(IntermediateAssembly)&quot; -incremental &quot;$(OptimizationDataFile)&quot;" />
-->
</Target>
......
......@@ -9,9 +9,9 @@ internal partial class SpecializedCollections
{
private partial class Empty
{
internal class Dictionary<TKey, TValue> : Collection<KeyValuePair<TKey, TValue>>, IDictionary<TKey, TValue>
internal class Dictionary<TKey, TValue> : Collection<KeyValuePair<TKey, TValue>>, IDictionary<TKey, TValue>, IReadOnlyDictionary<TKey, TValue>
{
public static readonly new IDictionary<TKey, TValue> Instance = new Dictionary<TKey, TValue>();
public static readonly new Dictionary<TKey, TValue> Instance = new Dictionary<TKey, TValue>();
private Dictionary()
{
......@@ -35,6 +35,9 @@ public ICollection<TKey> Keys
}
}
IEnumerable<TKey> IReadOnlyDictionary<TKey, TValue>.Keys => Keys;
IEnumerable<TValue> IReadOnlyDictionary<TKey, TValue>.Values => Values;
public bool Remove(TKey key)
{
throw new NotSupportedException();
......
......@@ -49,6 +49,11 @@ public static ISet<T> EmptySet<T>()
return Empty.Dictionary<TKey, TValue>.Instance;
}
public static IReadOnlyDictionary<TKey, TValue> EmptyReadOnlyDictionary<TKey, TValue>()
{
return Empty.Dictionary<TKey, TValue>.Instance;
}
public static IEnumerable<T> SingletonEnumerable<T>(T value)
{
return new Singleton.Collection<T>(value);
......
......@@ -272,8 +272,6 @@
<Compile Include="Implementation\GoToImplementation\AbstractGoToImplementationService.cs" />
<Compile Include="Implementation\GoToImplementation\IGoToImplementationService.cs" />
<Compile Include="Implementation\Intellisense\Completion\BraceCompletionMetadata.cs" />
<Compile Include="Extensibility\Completion\CompletionHelper.cs" />
<Compile Include="Extensibility\Completion\CompletionHelperFactory.cs" />
<Compile Include="Implementation\Intellisense\Completion\OptionSetExtensions.cs" />
<Compile Include="Implementation\Intellisense\Completion\Presentation\ClassificationTags.cs" />
<Compile Include="Implementation\Intellisense\Completion\Presentation\ImageMonikers.cs" />
......
// 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;
using Microsoft.CodeAnalysis.Host;
namespace Microsoft.CodeAnalysis.Editor
{
internal abstract class CompletionHelperFactory : ILanguageService
{
public abstract CompletionHelper CreateCompletionHelper();
}
}
\ No newline at end of file
......@@ -14,7 +14,7 @@ internal interface ICompletionPresenterSession : IIntelliSensePresenterSession
ITrackingSpan triggerSpan, IList<PresentationItem> items, PresentationItem selectedItem,
PresentationItem suggestionModeItem, bool suggestionMode, bool isSoftSelected,
ImmutableArray<CompletionItemFilter> completionItemFilters,
IReadOnlyDictionary<CompletionItem, string> completionItemToFilterText);
string filterText);
void SelectPreviousItem();
void SelectNextItem();
......
......@@ -107,4 +107,4 @@ private void OnPresenterSessionItemSelected(object sender, PresentationItemEvent
}
}
}
}
}
\ No newline at end of file
......@@ -132,7 +132,7 @@ internal override void OnModelUpdated(Model modelOpt)
sessionOpt.PresenterSession.PresentItems(
triggerSpan, modelOpt.FilteredItems, selectedItem, modelOpt.SuggestionModeItem,
this.SubjectBuffer.GetOption(EditorCompletionOptions.UseSuggestionMode),
modelOpt.IsSoftSelection, modelOpt.CompletionItemFilters, modelOpt.CompletionItemToFilterText);
modelOpt.IsSoftSelection, modelOpt.CompletionItemFilters, modelOpt.FilterText);
}
}
......@@ -183,7 +183,9 @@ internal override void OnModelUpdated(Model modelOpt)
var filterReason = trigger.Kind == CompletionTriggerKind.Deletion
? CompletionFilterReason.BackspaceOrDelete
: CompletionFilterReason.TypeChar;
: trigger.Kind == CompletionTriggerKind.Other
? CompletionFilterReason.Other
: CompletionFilterReason.TypeChar;
if (filterItems)
{
......@@ -280,4 +282,4 @@ public ImmutableArray<string> GetRecentItems()
return _recentItems;
}
}
}
}
\ No newline at end of file
......@@ -115,7 +115,7 @@ private bool CaretHasLeftDefaultTrackingSpan(int caretPoint, Document document)
// We haven't finished computing the model, but we may need to dismiss.
// Get the context span and see if we're outside it.
var text = document.GetTextAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None);
var contextSpan = GetCompletionService().GetDefaultItemSpan(text, caretPoint);
var contextSpan = GetCompletionService().GetDefaultCompletionListSpan(text, caretPoint);
var newCaretPoint = GetCaretPointInViewBuffer();
return !contextSpan.IntersectsWith(new TextSpan(newCaretPoint, 0));
}
......@@ -164,4 +164,4 @@ internal bool AllFilterTextsEmpty(Model model, SnapshotPoint caretPoint)
return currentText.Length == 0;
}
}
}
}
\ No newline at end of file
......@@ -56,4 +56,4 @@ CommandState ICommandHandler<CommitUniqueCompletionListItemCommandArgs>.GetComma
}
}
}
}
}
\ No newline at end of file
......@@ -40,4 +40,4 @@ void ICommandHandler<InvokeCompletionListCommandArgs>.ExecuteCommand(InvokeCompl
completionService, filterItems: false, dismissIfEmptyAllowed: false);
}
}
}
}
\ No newline at end of file
......@@ -178,4 +178,4 @@ private void CommitOnTab(out bool committed)
committed = true;
}
}
}
}
\ No newline at end of file
......@@ -295,9 +295,14 @@ private static bool IsPotentialFilterCharacter(TypeCharCommandArgs args)
|| args.TypedChar == '_';
}
private Document GetDocument()
{
return this.SubjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
}
private CompletionHelper GetCompletionHelper()
{
var document = this.SubjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
var document = GetDocument();
if (document != null)
{
return CompletionHelper.GetHelper(document);
......
......@@ -71,17 +71,17 @@ public ImmutableArray<CompletionItem> GetItems(string pathSoFar, string document
private CompletionItem CreateCurrentDirectoryItem()
{
return CommonCompletionItem.Create(".", _textChangeSpan, rules: _itemRules);
return CommonCompletionItem.Create(".", rules: _itemRules);
}
private CompletionItem CreateParentDirectoryItem()
{
return CommonCompletionItem.Create("..", _textChangeSpan, rules: _itemRules);
return CommonCompletionItem.Create("..", rules: _itemRules);
}
private CompletionItem CreateNetworkRoot(TextSpan textChangeSpan)
{
return CommonCompletionItem.Create("\\\\", textChangeSpan, rules: _itemRules);
return CommonCompletionItem.Create("\\\\", rules: _itemRules);
}
private ImmutableArray<CompletionItem> GetFilesAndDirectories(string path, string basePath)
......@@ -194,7 +194,6 @@ private CompletionItem CreateCompletion(FileSystemInfo child)
{
return CommonCompletionItem.Create(
child.Name,
_textChangeSpan,
glyph: child is DirectoryInfo ? _folderGlyph : _fileGlyph,
description: child.FullName.ToSymbolDisplayParts(),
rules: _itemRules);
......@@ -275,7 +274,7 @@ private IEnumerable<CompletionItem> GetLogicalDrives()
return from d in _lazyGetDrives.Value
where d.Length > 0 && (d.Last() == Path.DirectorySeparatorChar || d.Last() == Path.AltDirectorySeparatorChar)
let text = d.Substring(0, d.Length - 1)
select CommonCompletionItem.Create(text, _textChangeSpan, glyph: _folderGlyph, rules: _itemRules);
select CommonCompletionItem.Create(text, glyph: _folderGlyph, rules: _itemRules);
}
private static FileSystemInfo[] GetFileSystemInfos(DirectoryInfo directoryInfo)
......
......@@ -27,7 +27,7 @@ internal class Model
public ImmutableArray<CompletionItemFilter> CompletionItemFilters { get; }
public ImmutableDictionary<CompletionItemFilter, bool> FilterState { get; }
public IReadOnlyDictionary<CompletionItem, string> CompletionItemToFilterText { get; }
public string FilterText { get; } = "";
public bool IsHardSelection { get; }
public bool IsUnique { get; }
......@@ -55,7 +55,7 @@ internal class Model
PresentationItem selectedItem,
ImmutableArray<CompletionItemFilter> completionItemFilters,
ImmutableDictionary<CompletionItemFilter, bool> filterState,
IReadOnlyDictionary<CompletionItem, string> completionItemToFilterText,
string filterText,
bool isHardSelection,
bool isUnique,
bool useSuggestionMode,
......@@ -75,7 +75,7 @@ internal class Model
this.FilterState = filterState;
this.SelectedItem = selectedItem;
this.CompletionItemFilters = completionItemFilters;
this.CompletionItemToFilterText = completionItemToFilterText;
this.FilterText = filterText;
this.IsHardSelection = isHardSelection;
this.IsUnique = isUnique;
this.UseSuggestionMode = useSuggestionMode;
......@@ -145,20 +145,19 @@ internal class Model
}
totalItems = totalItemsBuilder.AsImmutable();
defaultSuggestionModePresentationItem = new DescriptionModifyingPresentationItem(CreateDefaultSuggestionModeItem(originalList.DefaultSpan), completionService, isSuggestionModeItem: true);
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<PresentationItem>();
defaultSuggestionModePresentationItem = new SimplePresentationItem(CreateDefaultSuggestionModeItem(originalList.DefaultSpan), completionService, isSuggestionModeItem: true);
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);
var completionItemToFilterText = new Dictionary<CompletionItem, string>();
return new Model(
triggerDocument,
disconnectedBufferGraph,
......@@ -168,14 +167,14 @@ internal class Model
selectedPresentationItem,
actualItemFilters,
filterState,
completionItemToFilterText,
"",
isHardSelection,
isUnique,
useSuggestionMode,
suggestionModePresentationItem,
defaultSuggestionModePresentationItem,
trigger,
GetDefaultTrackingSpanEnd(originalList.DefaultSpan, disconnectedBufferGraph),
GetDefaultTrackingSpanEnd(originalList.Span, disconnectedBufferGraph),
originalList.Rules.DismissIfEmpty);
}
......@@ -189,9 +188,9 @@ internal class Model
PointTrackingMode.Positive);
}
private static CompletionItem CreateDefaultSuggestionModeItem(TextSpan defaultTrackingSpanInSubjectBuffer)
private static CompletionItem CreateDefaultSuggestionModeItem()
{
return CompletionItem.Create(displayText: "", span: defaultTrackingSpanInSubjectBuffer);
return CompletionItem.Create(displayText: "");
}
public bool IsSoftSelection
......@@ -206,7 +205,7 @@ public bool IsSoftSelection
Optional<ImmutableArray<PresentationItem>> filteredItems = default(Optional<ImmutableArray<PresentationItem>>),
Optional<PresentationItem> selectedItem = default(Optional<PresentationItem>),
Optional<ImmutableDictionary<CompletionItemFilter, bool>> filterState = default(Optional<ImmutableDictionary<CompletionItemFilter, bool>>),
Optional<IReadOnlyDictionary<CompletionItem, string>> completionItemToFilterText = default(Optional<IReadOnlyDictionary<CompletionItem, string>>),
Optional<string> filterText = default(Optional<string>),
Optional<bool> isHardSelection = default(Optional<bool>),
Optional<bool> isUnique = default(Optional<bool>),
Optional<bool> useSuggestionMode = default(Optional<bool>),
......@@ -216,7 +215,7 @@ public bool IsSoftSelection
var newFilteredItems = filteredItems.HasValue ? filteredItems.Value : FilteredItems;
var newSelectedItem = selectedItem.HasValue ? selectedItem.Value : SelectedItem;
var newFilterState = filterState.HasValue ? filterState.Value : FilterState;
var newCompletionItemToFilterText = completionItemToFilterText.HasValue ? completionItemToFilterText.Value : CompletionItemToFilterText;
var newFilterText = filterText.HasValue ? filterText.Value : FilterText;
var newIsHardSelection = isHardSelection.HasValue ? isHardSelection.Value : IsHardSelection;
var newIsUnique = isUnique.HasValue ? isUnique.Value : IsUnique;
var newUseSuggestionMode = useSuggestionMode.HasValue ? useSuggestionMode.Value : UseSuggestionMode;
......@@ -225,7 +224,7 @@ public bool IsSoftSelection
if (newFilteredItems == FilteredItems &&
newSelectedItem == SelectedItem &&
newFilterState == FilterState &&
newFilterText == FilterText &&
newCompletionItemToFilterText == CompletionItemToFilterText &&
newIsHardSelection == IsHardSelection &&
newIsUnique == IsUnique &&
......@@ -238,7 +237,7 @@ public bool IsSoftSelection
return new Model(
TriggerDocument, _disconnectedBufferGraph, OriginalList, TotalItems, newFilteredItems,
newSelectedItem, CompletionItemFilters, newFilterState, newCompletionItemToFilterText,
newSelectedItem, CompletionItemFilters, newFilterState, newFilterText,
newIsHardSelection, newIsUnique, newUseSuggestionMode, newSuggestionModeItem,
DefaultSuggestionModeItem, Trigger, newCommitTrackingSpanEndPoint, DismissIfEmpty);
}
......@@ -283,9 +282,9 @@ internal Model WithFilterState(ImmutableDictionary<CompletionItemFilter, bool> f
return With(filterState: filterState);
}
internal Model WithCompletionItemToFilterText(IReadOnlyDictionary<CompletionItem, string> completionItemToFilterText)
internal Model WithFilterText(string filterText)
{
return With(completionItemToFilterText: new Optional<IReadOnlyDictionary<CompletionItem, string>>(completionItemToFilterText));
return With(filterText: filterText);
}
internal SnapshotSpan GetCurrentSpanInSnapshot(ViewTextSpan originalSpan, ITextSnapshot textSnapshot)
......
......@@ -67,7 +67,7 @@ public ITextBuffer SubjectBuffer
bool suggestionMode,
bool isSoftSelected,
ImmutableArray<CompletionItemFilter> completionItemFilters,
IReadOnlyDictionary<CompletionItem, string> completionItemToFilterText)
string filterText)
{
AssertIsForeground();
......@@ -87,7 +87,7 @@ public ITextBuffer SubjectBuffer
{
_completionSet.SetCompletionItems(
completionItems, selectedItem, suggestionModeItem, suggestionMode,
isSoftSelected, completionItemFilters, completionItemToFilterText);
isSoftSelected, completionItemFilters, filterText);
}
finally
{
......
......@@ -22,7 +22,7 @@ internal interface ICompletionSet
bool suggestionMode,
bool isSoftSelected,
ImmutableArray<CompletionItemFilter> completionItemFilters,
IReadOnlyDictionary<CompletionItem, string> completionItemToFilterText);
string filterText);
PresentationItem GetPresentationItem(VSCompletion completion);
}
}
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
......@@ -34,7 +33,7 @@ internal class Roslyn14CompletionSet : ForegroundThreadAffinitizedObject
protected readonly CompletionPresenterSession CompletionPresenterSession;
protected Dictionary<PresentationItem, VSCompletion> PresentationItemMap;
protected IReadOnlyDictionary<CompletionItem, string> CompletionItemToFilterText;
protected string FilterText;
public Roslyn14CompletionSet(
IVisualStudioCompletionSet vsCompletionSet,
......@@ -64,7 +63,7 @@ public void SetTrackingSpan(ITrackingSpan trackingSpan)
bool suggestionMode,
bool isSoftSelected,
ImmutableArray<CompletionItemFilter> completionItemFilters,
IReadOnlyDictionary<CompletionItem, string> completionItemToFilterText)
string filterText)
{
this.AssertIsForeground();
......@@ -72,7 +71,7 @@ public void SetTrackingSpan(ITrackingSpan trackingSpan)
// Initialize the completion map to a reasonable default initial size (+1 for the builder)
PresentationItemMap = PresentationItemMap ?? new Dictionary<PresentationItem, VSCompletion>(completionItems.Count + 1);
CompletionItemToFilterText = completionItemToFilterText;
FilterText = filterText;
try
{
......@@ -87,11 +86,12 @@ public void SetTrackingSpan(ITrackingSpan trackingSpan)
SimplePresentationItem filteredSuggestionModeItem = null;
if (selectedItem != null)
{
var completionItem = CompletionItem.Create(displayText: applicableToText);
completionItem.Span = VsCompletionSet.ApplicableTo.GetSpan(
VsCompletionSet.ApplicableTo.TextBuffer.CurrentSnapshot).Span.ToTextSpan();
filteredSuggestionModeItem = new SimplePresentationItem(
CompletionItem.Create(
displayText: applicableToText,
span: VsCompletionSet.ApplicableTo.GetSpan(
VsCompletionSet.ApplicableTo.TextBuffer.CurrentSnapshot).Span.ToTextSpan()),
completionItem,
selectedItem.CompletionService,
isSuggestionModeItem: true);
}
......
......@@ -51,9 +51,9 @@ void ICompletionSet.SetTrackingSpan(ITrackingSpan trackingSpan)
_roslynCompletionSet.SetTrackingSpan(trackingSpan);
}
void ICompletionSet.SetCompletionItems(IList<PresentationItem> completionItems, PresentationItem selectedItem, PresentationItem presetBuilder, bool suggestionMode, bool isSoftSelected, ImmutableArray<CompletionItemFilter> completionItemFilters, IReadOnlyDictionary<CompletionItem, string> completionItemToFilterText)
void ICompletionSet.SetCompletionItems(IList<PresentationItem> completionItems, PresentationItem selectedItem, PresentationItem presetBuilder, bool suggestionMode, bool isSoftSelected, ImmutableArray<CompletionItemFilter> completionItemFilters, string filterText)
{
_roslynCompletionSet.SetCompletionItems(completionItems, selectedItem, presetBuilder, suggestionMode, isSoftSelected, completionItemFilters, completionItemToFilterText);
_roslynCompletionSet.SetCompletionItems(completionItems, selectedItem, presetBuilder, suggestionMode, isSoftSelected, completionItemFilters, filterText);
}
PresentationItem ICompletionSet.GetPresentationItem(VSCompletion completion)
......
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.Linq;
using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.Text.Shared.Extensions;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Text;
......@@ -71,7 +71,7 @@ private CompletionHelper GetCompletionHelper()
public IReadOnlyList<Span> GetHighlightedSpansInDisplayText(string displayText)
{
if (_highlightMatchingPortions && CompletionItemToFilterText != null)
if (_highlightMatchingPortions && !string.IsNullOrWhiteSpace(FilterText))
{
var completionHelper = this.GetCompletionHelper();
if (completionHelper != null)
......@@ -80,14 +80,11 @@ public IReadOnlyList<Span> GetHighlightedSpansInDisplayText(string displayText)
if (presentationItem != null && !presentationItem.IsSuggestionModeItem)
{
string filterText;
if (CompletionItemToFilterText.TryGetValue(presentationItem.Item, out filterText))
var highlightedSpans = completionHelper.GetHighlightedSpans(
presentationItem.Item, FilterText, CultureInfo.CurrentCulture);
if (highlightedSpans != null)
{
var highlightedSpans = completionHelper.GetHighlightedSpans(presentationItem.Item, filterText);
if (highlightedSpans != null)
{
return highlightedSpans.Select(s => s.ToSpan()).ToArray();
}
return highlightedSpans.Select(s => s.ToSpan()).ToArray();
}
}
}
......
......@@ -77,9 +77,9 @@ void ICompletionSet.SetTrackingSpan(ITrackingSpan trackingSpan)
_roslynCompletionSet.SetTrackingSpan(trackingSpan);
}
void ICompletionSet.SetCompletionItems(IList<PresentationItem> completionItems, PresentationItem selectedItem, PresentationItem presetBuilder, bool suggestionMode, bool isSoftSelected, ImmutableArray<CompletionItemFilter> completionItemFilters, IReadOnlyDictionary<CompletionItem, string> completionItemToFilterText)
void ICompletionSet.SetCompletionItems(IList<PresentationItem> completionItems, PresentationItem selectedItem, PresentationItem presetBuilder, bool suggestionMode, bool isSoftSelected, ImmutableArray<CompletionItemFilter> completionItemFilters, string filterText)
{
_roslynCompletionSet.SetCompletionItems(completionItems, selectedItem, presetBuilder, suggestionMode, isSoftSelected, completionItemFilters, completionItemToFilterText);
_roslynCompletionSet.SetCompletionItems(completionItems, selectedItem, presetBuilder, suggestionMode, isSoftSelected, completionItemFilters, filterText);
}
PresentationItem ICompletionSet.GetPresentationItem(VSCompletion completion)
......
......@@ -72,22 +72,6 @@ internal static CompletionHelper GetCompletionHelper(Document document)
return CompletionHelper.GetHelper(document);
}
internal static async Task<CompletionContext> GetCompletionListContextAsync(
CompletionProvider provider,
Document document,
int position,
CompletionTrigger triggerInfo,
OptionSet options = null)
{
options = options ?? document.Options;
var service = document.Project.LanguageServices.GetService<CompletionService>();
var text = await document.GetTextAsync();
var span = service.GetDefaultItemSpan(text, position);
var context = new CompletionContext(provider, document, position, span, triggerInfo, options, CancellationToken.None);
await provider.ProvideCompletionsAsync(context);
return context;
}
internal Task<CompletionList> GetCompletionListAsync(
CompletionService service,
Document document, int position, CompletionTrigger triggerInfo, OptionSet options = null)
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Globalization
Imports System.Threading
Imports System.Threading.Tasks
Imports Microsoft.CodeAnalysis.Completion
Imports Microsoft.CodeAnalysis.Editor.Commands
......@@ -10,7 +8,6 @@ Imports Microsoft.CodeAnalysis.Editor.UnitTests.Extensions
Imports Microsoft.CodeAnalysis.Options
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.VisualStudio.Text
Imports Microsoft.VisualStudio.Text.Differencing
Imports Microsoft.VisualStudio.Text.Editor
Imports Microsoft.VisualStudio.Text.Operations
Imports Microsoft.VisualStudio.Text.Projection
......
......@@ -2,7 +2,6 @@
Imports System.Globalization
Imports Microsoft.CodeAnalysis.Completion
Imports Microsoft.CodeAnalysis.CSharp.Completion
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
......@@ -46,26 +45,24 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
End Sub
Private Sub TestMatches(v As String, wordsToMatch() As String)
Using New CultureContext("tr-TR")
Dim workspace = New TestWorkspace
Dim helper = CompletionHelper.GetHelper(workspace, LanguageNames.CSharp)
For Each word In wordsToMatch
Dim item = CompletionItem.Create(word)
Assert.True(helper.MatchesFilterText(item, v, CompletionTrigger.Default, Nothing), $"Expected item {word} does not match {v}")
Next
End Using
Dim culture = New CultureInfo("tr-TR", useUserOverride:=False)
Dim workspace = New TestWorkspace
Dim helper = CompletionHelper.GetHelper(workspace, LanguageNames.CSharp)
For Each word In wordsToMatch
Dim item = CompletionItem.Create(word)
Assert.True(helper.MatchesFilterText(item, v, culture), $"Expected item {word} does not match {v}")
Next
End Sub
Private Sub TestNotMatches(v As String, wordsToNotMatch() As String)
Using New CultureContext("tr-TR")
Dim workspace = New TestWorkspace
Dim helper = CompletionHelper.GetHelper(workspace, LanguageNames.CSharp)
For Each word In wordsToNotMatch
Dim item = CompletionItem.Create(word)
Assert.False(helper.MatchesFilterText(item, v, CompletionTrigger.Default, Nothing), $"Unexpected item {word} matches {v}")
Next
End Using
Dim culture = New CultureInfo("tr-TR", useUserOverride:=False)
Dim workspace = New TestWorkspace
Dim helper = CompletionHelper.GetHelper(workspace, LanguageNames.CSharp)
For Each word In wordsToNotMatch
Dim item = CompletionItem.Create(word)
Assert.False(helper.MatchesFilterText(item, v, culture), $"Unexpected item {word} matches {v}")
Next
End Sub
End Class
End Namespace
End Namespace
\ No newline at end of file
......@@ -39,7 +39,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
suggestionMode As Boolean,
isSoftSelected As Boolean,
completionItemFilters As ImmutableArray(Of CompletionItemFilter),
completionItemToFilterText As IReadOnlyDictionary(Of CompletionItem, String)) Implements ICompletionPresenterSession.PresentItems
filterText As String) Implements ICompletionPresenterSession.PresentItems
_testState.CurrentCompletionPresenterSession = Me
Me.TriggerSpan = triggerSpan
Me.PresentationItems = presentationItems
......
......@@ -59,7 +59,7 @@ protected override ImmutableArray<CompletionProvider> GetBuiltInProviders()
return _defaultCompletionProviders;
}
public override TextSpan GetDefaultItemSpan(SourceText text, int caretPosition)
public override TextSpan GetDefaultCompletionListSpan(SourceText text, int caretPosition)
{
return CompletionUtilities.GetCompletionItemSpan(text, caretPosition);
}
......
......@@ -147,7 +147,6 @@ private bool IsAfterNameEqualsArgument(SyntaxToken token)
select SymbolCompletionItem.Create(
displayText: p.Name.ToIdentifierToken().ToString() + SpaceEqualsString,
insertionText: null,
span: context.DefaultItemSpan,
symbol: p,
descriptionPosition: token.SpanStart,
sortText: p.Name,
......@@ -167,7 +166,6 @@ private bool IsAfterNameEqualsArgument(SyntaxToken token)
select SymbolCompletionItem.Create(
displayText: p.Name.ToIdentifierToken().ToString() + ColonString,
insertionText: null,
span: context.DefaultItemSpan,
symbol: p,
descriptionPosition: token.SpanStart,
sortText: p.Name,
......
......@@ -228,7 +228,7 @@ private static TextSpan GetCompletionItemSpan(SourceText text, int position)
foreach (var symbol in symbols)
{
builder.Clear();
yield return CreateItem(workspace, semanticModel, symbol, token, itemSpan, builder);
yield return CreateItem(workspace, semanticModel, symbol, token, builder);
}
}
finally
......@@ -238,7 +238,7 @@ private static TextSpan GetCompletionItemSpan(SourceText text, int position)
}
private CompletionItem CreateItem(
Workspace workspace, SemanticModel semanticModel, ISymbol symbol, SyntaxToken token, TextSpan span, StringBuilder builder)
Workspace workspace, SemanticModel semanticModel, ISymbol symbol, SyntaxToken token, StringBuilder builder)
{
int position = token.SpanStart;
......@@ -296,7 +296,6 @@ private static TextSpan GetCompletionItemSpan(SourceText text, int position)
return SymbolCompletionItem.Create(
displayText: insertionText,
insertionText: insertionText,
span: span,
symbol: symbol,
descriptionPosition: position,
sortText: symbolText,
......
......@@ -114,7 +114,6 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
var item = SymbolCompletionItem.Create(
displayText: displayText,
insertionText: null,
span: context.DefaultItemSpan,
symbol: alias ?? type,
descriptionPosition: position,
matchPriority: MatchPriority.Preselect,
......
......@@ -96,7 +96,6 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
context.AddItem(SymbolCompletionItem.Create(
displayText,
insertionText: insertionText,
span: context.DefaultItemSpan,
symbol: member,
contextPosition: position,
descriptionPosition: position,
......
......@@ -55,10 +55,10 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
foreach (var alias in aliases)
{
context.AddItem(CommonCompletionItem.Create(alias, context.DefaultItemSpan, glyph: Glyph.Namespace));
context.AddItem(CommonCompletionItem.Create(alias, glyph: Glyph.Namespace));
}
}
}
}
}
}
}
\ No newline at end of file
......@@ -168,11 +168,10 @@ protected override async Task<CSharpSyntaxContext> CreateContextAsync(Document d
return CSharpSyntaxContext.CreateContext(document.Project.Solution.Workspace, semanticModel, position, cancellationToken);
}
protected override CompletionItem CreateItem(RecommendedKeyword keyword, TextSpan span)
protected override CompletionItem CreateItem(RecommendedKeyword keyword)
{
return CommonCompletionItem.Create(
displayText: keyword.Keyword,
span: span,
description: keyword.DescriptionFactory(CancellationToken.None),
glyph: Glyph.Keyword,
shouldFormatOnCommit: keyword.ShouldFormatOnCommit,
......
......@@ -93,7 +93,6 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
context.AddItem(SymbolCompletionItem.Create(
displayText: escapedName + ColonString,
insertionText: null,
span: context.DefaultItemSpan,
symbol: parameter,
descriptionPosition: token.SpanStart,
filterText: escapedName,
......
......@@ -56,14 +56,15 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
var snippetCompletionItems = await document.GetUnionItemsFromDocumentAndLinkedDocumentsAsync(
UnionCompletionItemComparer.Instance,
(d, c) => GetSnippetsForDocumentAsync(d, position, context.DefaultItemSpan, workspace, c),
(d, c) => GetSnippetsForDocumentAsync(d, position, workspace, c),
cancellationToken).ConfigureAwait(false);
context.AddItems(snippetCompletionItems);
}
}
private async Task<IEnumerable<CompletionItem>> GetSnippetsForDocumentAsync(Document document, int position, TextSpan itemSpan, Workspace workspace, CancellationToken cancellationToken)
private async Task<IEnumerable<CompletionItem>> GetSnippetsForDocumentAsync(
Document document, int position, Workspace workspace, CancellationToken cancellationToken)
{
var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
var syntaxFacts = document.GetLanguageService<ISyntaxFactsService>();
......@@ -97,7 +98,7 @@ private async Task<IEnumerable<CompletionItem>> GetSnippetsForDocumentAsync(Docu
return SpecializedCollections.EmptyEnumerable<CompletionItem>();
}
return await GetSnippetCompletionItemsAsync(workspace, semanticModel, itemSpan, isPreProcessorContext: true, cancellationToken: cancellationToken).ConfigureAwait(false);
return await GetSnippetCompletionItemsAsync(workspace, semanticModel, isPreProcessorContext: true, cancellationToken: cancellationToken).ConfigureAwait(false);
}
if (semanticFacts.IsGlobalStatementContext(semanticModel, position, cancellationToken) ||
......@@ -110,13 +111,14 @@ private async Task<IEnumerable<CompletionItem>> GetSnippetsForDocumentAsync(Docu
semanticFacts.IsMemberDeclarationContext(semanticModel, position, cancellationToken) ||
semanticFacts.IsLabelContext(semanticModel, position, cancellationToken))
{
return await GetSnippetCompletionItemsAsync(workspace, semanticModel, itemSpan, isPreProcessorContext: false, cancellationToken: cancellationToken).ConfigureAwait(false);
return await GetSnippetCompletionItemsAsync(workspace, semanticModel, isPreProcessorContext: false, cancellationToken: cancellationToken).ConfigureAwait(false);
}
return SpecializedCollections.EmptyEnumerable<CompletionItem>();
}
private async Task<IEnumerable<CompletionItem>> GetSnippetCompletionItemsAsync(Workspace workspace, SemanticModel semanticModel, TextSpan itemSpan, bool isPreProcessorContext, CancellationToken cancellationToken)
private async Task<IEnumerable<CompletionItem>> GetSnippetCompletionItemsAsync(
Workspace workspace, SemanticModel semanticModel, bool isPreProcessorContext, CancellationToken cancellationToken)
{
var service = _snippetInfoService ?? workspace.Services.GetLanguageServices(semanticModel.Language).GetService<ISnippetInfoService>();
if (service == null)
......@@ -135,9 +137,8 @@ private async Task<IEnumerable<CompletionItem>> GetSnippetCompletionItemsAsync(W
displayText: isPreProcessorContext ? snippet.Shortcut.Substring(1) : snippet.Shortcut,
sortText: isPreProcessorContext ? snippet.Shortcut.Substring(1) : snippet.Shortcut,
description: (snippet.Title + Environment.NewLine + snippet.Description).ToSymbolDisplayParts(),
span: itemSpan,
glyph: Glyph.Snippet,
shouldFormatOnCommit: service.ShouldFormatSnippet(snippet))).ToList();
}
}
}
}
\ No newline at end of file
......@@ -35,7 +35,7 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
const string T = nameof(T);
context.AddItem(CommonCompletionItem.Create(T, context.DefaultItemSpan, glyph: Glyph.TypeParameter));
context.AddItem(CommonCompletionItem.Create(T, glyph: Glyph.TypeParameter));
}
}
......
......@@ -75,7 +75,7 @@ internal override bool IsInsertionTrigger(SourceText text, int characterPosition
// The user is typing inside an XmlElement
if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement)
{
items.AddRange(GetNestedTags(span, declaredSymbol));
items.AddRange(GetNestedTags(declaredSymbol));
}
if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement && ((XmlElementSyntax)token.Parent.Parent).StartTag.Name.LocalName.ValueText == ListTagName)
......@@ -94,13 +94,13 @@ internal override bool IsInsertionTrigger(SourceText text, int characterPosition
if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement && ((XmlElementSyntax)token.Parent.Parent).StartTag.Name.LocalName.ValueText == ListHeaderTagName)
{
items.AddRange(GetListHeaderItems(span));
items.AddRange(GetListHeaderItems());
}
if (token.Parent.Parent is DocumentationCommentTriviaSyntax)
{
items.AddRange(GetTopLevelSingleUseNames(parentTrivia, span));
items.AddRange(GetTopLevelRepeatableItems(span));
items.AddRange(GetTopLevelRepeatableItems());
}
}
......@@ -115,11 +115,11 @@ internal override bool IsInsertionTrigger(SourceText text, int characterPosition
if (token == startTag.GreaterThanToken && startTag.Name.LocalName.ValueText == ListHeaderTagName)
{
items.AddRange(GetListHeaderItems(span));
items.AddRange(GetListHeaderItems());
}
}
items.AddRange(GetAlwaysVisibleItems(span));
items.AddRange(GetAlwaysVisibleItems());
return items;
}
......@@ -129,7 +129,7 @@ private IEnumerable<CompletionItem> GetTopLevelSingleUseNames(DocumentationComme
RemoveExistingTags(parentTrivia, names, (x) => x.StartTag.Name.LocalName.ValueText);
return names.Select(n => GetItem(n, span));
return names.Select(GetItem);
}
private void RemoveExistingTags(DocumentationCommentTriviaSyntax parentTrivia, ISet<string> names, Func<XmlElementSyntax, string> selector)
......@@ -151,23 +151,23 @@ private IEnumerable<CompletionItem> GetTagsForSymbol(ISymbol symbol, TextSpan it
{
if (symbol is IMethodSymbol)
{
return GetTagsForMethod((IMethodSymbol)symbol, itemSpan, trivia, token);
return GetTagsForMethod((IMethodSymbol)symbol, trivia, token);
}
if (symbol is IPropertySymbol)
{
return GetTagsForProperty((IPropertySymbol)symbol, itemSpan, trivia, token);
return GetTagsForProperty((IPropertySymbol)symbol, trivia, token);
}
if (symbol is INamedTypeSymbol)
{
return GetTagsForType((INamedTypeSymbol)symbol, itemSpan, trivia);
return GetTagsForType((INamedTypeSymbol)symbol, trivia);
}
return SpecializedCollections.EmptyEnumerable<CompletionItem>();
}
private IEnumerable<CompletionItem> GetTagsForType(INamedTypeSymbol symbol, TextSpan itemSpan, DocumentationCommentTriviaSyntax trivia)
private IEnumerable<CompletionItem> GetTagsForType(INamedTypeSymbol symbol, DocumentationCommentTriviaSyntax trivia)
{
var items = new List<CompletionItem>();
......@@ -175,7 +175,7 @@ private IEnumerable<CompletionItem> GetTagsForType(INamedTypeSymbol symbol, Text
RemoveExistingTags(trivia, typeParameters, x => AttributeSelector(x, TypeParamTagName));
items.AddRange(typeParameters.Select(t => CreateCompletionItem(itemSpan, FormatParameter(TypeParamTagName, t))));
items.AddRange(typeParameters.Select(t => CreateCompletionItem(FormatParameter(TypeParamTagName, t))));
return items;
}
......@@ -197,7 +197,8 @@ private string AttributeSelector(XmlElementSyntax element, string attribute)
return null;
}
private IEnumerable<CompletionItem> GetTagsForProperty(IPropertySymbol symbol, TextSpan itemSpan, DocumentationCommentTriviaSyntax trivia, SyntaxToken token)
private IEnumerable<CompletionItem> GetTagsForProperty(
IPropertySymbol symbol, DocumentationCommentTriviaSyntax trivia, SyntaxToken token)
{
var items = new List<CompletionItem>();
......@@ -220,23 +221,24 @@ private IEnumerable<CompletionItem> GetTagsForProperty(IPropertySymbol symbol, T
// We're writing the name of a paramref
if (parentElementName == ParamRefTagName)
{
items.AddRange(parameters.Select(p => CreateCompletionItem(itemSpan, p)));
items.AddRange(parameters.Select(CreateCompletionItem));
}
return items;
}
RemoveExistingTags(trivia, parameters, x => AttributeSelector(x, ParamTagName));
items.AddRange(parameters.Select(p => CreateCompletionItem(itemSpan, FormatParameter(ParamTagName, p))));
items.AddRange(parameters.Select(p => CreateCompletionItem(FormatParameter(ParamTagName, p))));
}
var typeParameters = symbol.GetTypeArguments().Select(p => p.Name).ToSet();
items.AddRange(typeParameters.Select(t => CreateCompletionItem(itemSpan, TypeParamTagName, NameAttributeName, t)));
items.Add(CreateCompletionItem(itemSpan, "value"));
items.AddRange(typeParameters.Select(t => CreateCompletionItem(TypeParamTagName, NameAttributeName, t)));
items.Add(CreateCompletionItem("value"));
return items;
}
private IEnumerable<CompletionItem> GetTagsForMethod(IMethodSymbol symbol, TextSpan itemSpan, DocumentationCommentTriviaSyntax trivia, SyntaxToken token)
private IEnumerable<CompletionItem> GetTagsForMethod(
IMethodSymbol symbol, DocumentationCommentTriviaSyntax trivia, SyntaxToken token)
{
var items = new List<CompletionItem>();
......@@ -258,11 +260,11 @@ private IEnumerable<CompletionItem> GetTagsForMethod(IMethodSymbol symbol, TextS
// We're writing the name of a paramref or typeparamref
if (parentElementName == ParamRefTagName)
{
items.AddRange(parameters.Select(p => CreateCompletionItem(itemSpan, p)));
items.AddRange(parameters.Select(CreateCompletionItem));
}
else if (parentElementName == TypeParamRefTagName)
{
items.AddRange(typeParameters.Select(t => CreateCompletionItem(itemSpan, t)));
items.AddRange(typeParameters.Select(CreateCompletionItem));
}
return items;
......@@ -271,8 +273,8 @@ private IEnumerable<CompletionItem> GetTagsForMethod(IMethodSymbol symbol, TextS
RemoveExistingTags(trivia, parameters, x => AttributeSelector(x, ParamTagName));
RemoveExistingTags(trivia, typeParameters, x => AttributeSelector(x, TypeParamTagName));
items.AddRange(parameters.Select(p => CreateCompletionItem(itemSpan, FormatParameter(ParamTagName, p))));
items.AddRange(typeParameters.Select(t => CreateCompletionItem(itemSpan, FormatParameter(TypeParamTagName, t))));
items.AddRange(parameters.Select(p => CreateCompletionItem(FormatParameter(ParamTagName, p))));
items.AddRange(typeParameters.Select(t => CreateCompletionItem(FormatParameter(TypeParamTagName, t))));
// Provide a return completion item in case the function returns something
var returns = true;
......@@ -294,7 +296,7 @@ private IEnumerable<CompletionItem> GetTagsForMethod(IMethodSymbol symbol, TextS
if (returns && !symbol.ReturnsVoid)
{
items.Add(CreateCompletionItem(itemSpan, ReturnsTagName));
items.Add(CreateCompletionItem(ReturnsTagName));
}
return items;
......
......@@ -20,7 +20,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.SuggestionMode
{
internal class CSharpSuggestionModeCompletionProvider : SuggestionModeCompletionProvider
{
protected override async Task<CompletionItem> GetSuggestionModeItemAsync(Document document, int position, TextSpan itemSpan, CompletionTrigger trigger, CancellationToken cancellationToken = default(CancellationToken))
protected override async Task<CompletionItem> GetSuggestionModeItemAsync(
Document document, int position, TextSpan itemSpan, CompletionTrigger trigger, CancellationToken cancellationToken = default(CancellationToken))
{
if (trigger.Kind == CompletionTriggerKind.Insertion)
{
......@@ -41,27 +42,27 @@ protected override async Task<CompletionItem> GetSuggestionModeItemAsync(Documen
if (IsLambdaExpression(semanticModel, position, token, typeInferrer, cancellationToken))
{
return CreateSuggestionModeItem(CSharpFeaturesResources.LambdaExpression, itemSpan, CSharpFeaturesResources.AutoselectDisabledDueToPotentialLambdaDeclaration);
return CreateSuggestionModeItem(CSharpFeaturesResources.LambdaExpression, CSharpFeaturesResources.AutoselectDisabledDueToPotentialLambdaDeclaration);
}
else if (IsAnonymousObjectCreation(token) || IsPossibleTupleExpression(token))
{
return CreateSuggestionModeItem(CSharpFeaturesResources.MemberName, itemSpan, CSharpFeaturesResources.AutoselectDisabledDueToPossibleExplicitlyNamesAnonTypeMemCreation);
return CreateSuggestionModeItem(CSharpFeaturesResources.MemberName, CSharpFeaturesResources.AutoselectDisabledDueToPossibleExplicitlyNamesAnonTypeMemCreation);
}
else if (token.IsPreProcessorExpressionContext())
{
return CreateEmptySuggestionModeItem(itemSpan);
return CreateEmptySuggestionModeItem();
}
else if (IsImplicitArrayCreation(semanticModel, token, position, typeInferrer, cancellationToken))
{
return CreateSuggestionModeItem(CSharpFeaturesResources.ImplicitArrayCreation, itemSpan, CSharpFeaturesResources.AutoselectDisabledDueToPotentialImplicitArray);
return CreateSuggestionModeItem(CSharpFeaturesResources.ImplicitArrayCreation, CSharpFeaturesResources.AutoselectDisabledDueToPotentialImplicitArray);
}
else if (token.IsKindOrHasMatchingText(SyntaxKind.FromKeyword) || token.IsKindOrHasMatchingText(SyntaxKind.JoinKeyword))
{
return CreateSuggestionModeItem(CSharpFeaturesResources.RangeVariable, itemSpan, CSharpFeaturesResources.AutoselectDisabledDueToPotentialRangeVariableDecl);
return CreateSuggestionModeItem(CSharpFeaturesResources.RangeVariable, CSharpFeaturesResources.AutoselectDisabledDueToPotentialRangeVariableDecl);
}
else if (tree.IsNamespaceDeclarationNameContext(position, cancellationToken))
{
return CreateSuggestionModeItem(CSharpFeaturesResources.NamespaceName, itemSpan, CSharpFeaturesResources.AutoselectDisabledDueToNamespaceDeclaration);
return CreateSuggestionModeItem(CSharpFeaturesResources.NamespaceName, CSharpFeaturesResources.AutoselectDisabledDueToNamespaceDeclaration);
}
}
......
......@@ -16,7 +16,6 @@ internal static class CommonCompletionItem
{
public static CompletionItem Create(
string displayText,
TextSpan span,
Glyph? glyph = null,
ImmutableArray<SymbolDisplayPart> description = default(ImmutableArray<SymbolDisplayPart>),
string sortText = null,
......@@ -55,7 +54,6 @@ internal static class CommonCompletionItem
displayText: displayText,
filterText: filterText,
sortText: sortText,
span: span,
properties: properties,
tags: tags,
rules: rules);
......
......@@ -2,7 +2,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Text;
......@@ -39,8 +38,21 @@ internal IReadOnlyList<CompletionItem> Items
/// This is the most common value used for <see cref="CompletionItem.Span"/> and will
/// be automatically assigned to any <see cref="CompletionItem"/> that has no <see cref="CompletionItem.Span"/> specified.
/// </summary>
[Obsolete("Not used anymore. Use CompletionListSpan instead.")]
public TextSpan DefaultItemSpan { get; }
/// <summary>
/// The span of the document the completion list corresponds to. It will be set initially to
/// the result of <see cref="CompletionService.GetDefaultCompletionListSpan"/>, but it can
/// be overwritten bduring <see cref="CompletionService.GetCompletionsAsync"/>. The purpose
/// of the span is to:
/// 1. Signify where the completions should be presented.
/// 2. Designate any existing text in the document that should be used for filtering.
/// 3. Specify, by default, what portion of the text should be replaced when a completion
/// item is committed.
/// </summary>
public TextSpan CompletionListSpan { get; set; }
/// <summary>
/// The triggering action that caused completion to be started.
/// </summary>
......@@ -91,7 +103,10 @@ internal IReadOnlyList<CompletionItem> Items
this.Provider = provider;
this.Document = document;
this.Position = position;
#pragma warning disable CS0618 // Type or member is obsolete
this.DefaultItemSpan = defaultSpan;
#pragma warning restore CS0618 // Type or member is obsolete
this.CompletionListSpan = defaultSpan;
this.Trigger = trigger;
this.Options = options;
this.CancellationToken = cancellationToken;
......@@ -157,13 +172,9 @@ private CompletionItem FixItem(CompletionItem item)
// remember provider so we can find it again later
item = item.AddProperty("Provider", this.Provider.Name);
// assign the default span if not set by provider
if (item.Span == default(TextSpan) && this.DefaultItemSpan != default(TextSpan))
{
item = item.WithSpan(this.DefaultItemSpan);
}
item.Span = this.CompletionListSpan;
return item;
}
}
}
}
\ No newline at end of file
......@@ -10,6 +10,7 @@ namespace Microsoft.CodeAnalysis.Completion
{
internal enum CompletionFilterReason
{
Other,
TypeChar,
BackspaceOrDelete,
ItemFiltersChanged
......
......@@ -3,45 +3,44 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Globalization;
using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.Utilities;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.Editor
namespace Microsoft.CodeAnalysis.Completion
{
internal class CompletionHelper
internal sealed class CompletionHelper
{
private static readonly CompletionHelper CaseSensitiveInstance = new CompletionHelper(isCaseSensitive: true);
private static readonly CompletionHelper CaseInsensitiveInstance = new CompletionHelper(isCaseSensitive: false);
private readonly object _gate = new object();
private readonly Dictionary<string, PatternMatcher> _patternMatcherMap = new Dictionary<string, PatternMatcher>();
private readonly Dictionary<string, PatternMatcher> _fallbackPatternMatcherMap = new Dictionary<string, PatternMatcher>();
private readonly Dictionary<CultureInfo, Dictionary<string, PatternMatcher>> _patternMatcherMap =
new Dictionary<CultureInfo, Dictionary<string, PatternMatcher>>();
private readonly Dictionary<CultureInfo, Dictionary<string, PatternMatcher>> _fallbackPatternMatcherMap =
new Dictionary<CultureInfo, Dictionary<string, PatternMatcher>>();
private static readonly CultureInfo EnUSCultureInfo = new CultureInfo("en-US");
private readonly bool _isCaseSensitive;
protected CompletionHelper(bool isCaseSensitive)
private CompletionHelper(bool isCaseSensitive)
{
_isCaseSensitive = isCaseSensitive;
}
public static CompletionHelper GetHelper(Workspace workspace, string language)
{
var isCaseSensitive = true;
var ls = workspace.Services.GetLanguageServices(language);
if (ls != null)
{
var factory = ls.GetService<CompletionHelperFactory>();
if (factory != null)
{
return factory.CreateCompletionHelper();
}
var syntaxFacts = ls.GetService<ISyntaxFactsService>();
return new CompletionHelper(syntaxFacts?.IsCaseSensitive ?? true);
isCaseSensitive = syntaxFacts?.IsCaseSensitive ?? true;
}
return null;
return isCaseSensitive ? CaseSensitiveInstance : CaseInsensitiveInstance;
}
public static CompletionHelper GetHelper(Document document)
......@@ -49,9 +48,10 @@ public static CompletionHelper GetHelper(Document document)
return GetHelper(document.Project.Solution.Workspace, document.Project.Language);
}
public IReadOnlyList<TextSpan> GetHighlightedSpans(CompletionItem completionItem, string filterText)
public IReadOnlyList<TextSpan> GetHighlightedSpans(
CompletionItem completionItem, string filterText, CultureInfo culture)
{
var match = GetMatch(completionItem, filterText, includeMatchSpans: true);
var match = GetMatch(completionItem, filterText, includeMatchSpans: true, culture: culture);
return match?.MatchedSpans;
}
......@@ -60,55 +60,19 @@ public IReadOnlyList<TextSpan> GetHighlightedSpans(CompletionItem completionItem
/// iff the completion item matches and should be included in the filtered completion
/// results, or false if it should not be.
/// </summary>
public virtual bool MatchesFilterText(
CompletionItem item, string filterText,
CompletionTrigger trigger, ImmutableArray<string> recentItems)
{
// If the user hasn't typed anything, and this item was preselected, or was in the
// MRU list, then we definitely want to include it.
if (filterText.Length == 0)
{
if (item.Rules.MatchPriority > MatchPriority.Default || (!recentItems.IsDefault && GetRecentItemIndex(recentItems, item) < 0))
{
return true;
}
}
if (filterText.Length > 0 && IsAllDigits(filterText))
{
// The user is just typing a number. We never want this to match against
// anything we would put in a completion list.
return false;
}
return GetMatch(item, filterText) != null;
}
private static int GetRecentItemIndex(ImmutableArray<string> recentItems, CompletionItem item)
{
var index = recentItems.IndexOf(item.DisplayText);
return -index;
}
private static bool IsAllDigits(string filterText)
public bool MatchesFilterText(CompletionItem item, string filterText, CultureInfo culture)
{
for (int i = 0; i < filterText.Length; i++)
{
if (filterText[i] < '0' || filterText[i] > '9')
{
return false;
}
}
return true;
return GetMatch(item, filterText, culture) != null;
}
private PatternMatch? GetMatch(CompletionItem item, string filterText)
private PatternMatch? GetMatch(CompletionItem item, string filterText, CultureInfo culture)
{
return GetMatch(item, filterText, includeMatchSpans: false);
return GetMatch(item, filterText, includeMatchSpans: false, culture: culture);
}
private PatternMatch? GetMatch(CompletionItem item, string filterText, bool includeMatchSpans)
private PatternMatch? GetMatch(
CompletionItem item, string filterText,
bool includeMatchSpans, CultureInfo culture)
{
// If the item has a dot in it (i.e. for something like enum completion), then attempt
// to match what the user wrote against the last portion of the name. That way if they
......@@ -120,7 +84,7 @@ private static bool IsAllDigits(string filterText)
if (lastDotIndex >= 0)
{
var textAfterLastDot = item.FilterText.Substring(lastDotIndex + 1);
var match = GetMatchWorker(textAfterLastDot, filterText, includeMatchSpans);
var match = GetMatchWorker(textAfterLastDot, filterText, includeMatchSpans, culture);
if (match != null)
{
return match;
......@@ -129,12 +93,14 @@ private static bool IsAllDigits(string filterText)
// Didn't have a dot, or the user text didn't match the portion after the dot.
// Just do a normal check against the entire completion item.
return GetMatchWorker(item.FilterText, filterText, includeMatchSpans);
return GetMatchWorker(item.FilterText, filterText, includeMatchSpans, culture);
}
private PatternMatch? GetMatchWorker(string completionItemText, string filterText, bool includeMatchSpans)
private PatternMatch? GetMatchWorker(
string completionItemText, string filterText,
bool includeMatchSpans, CultureInfo culture)
{
var patternMatcher = this.GetPatternMatcher(filterText, CultureInfo.CurrentCulture);
var patternMatcher = this.GetPatternMatcher(filterText, culture);
var match = patternMatcher.GetFirstMatch(completionItemText, includeMatchSpans);
if (match != null)
......@@ -143,7 +109,7 @@ private static bool IsAllDigits(string filterText)
}
// Start with the culture-specific comparison, and fall back to en-US.
if (!CultureInfo.CurrentCulture.Equals(EnUSCultureInfo))
if (!culture.Equals(EnUSCultureInfo))
{
patternMatcher = this.GetEnUSPatternMatcher(filterText);
match = patternMatcher.GetFirstMatch(completionItemText);
......@@ -157,17 +123,24 @@ private static bool IsAllDigits(string filterText)
}
private PatternMatcher GetPatternMatcher(
string value, CultureInfo culture, Dictionary<string, PatternMatcher> map)
string value, CultureInfo culture, Dictionary<CultureInfo, Dictionary<string, PatternMatcher>> map)
{
lock (_gate)
{
Dictionary<string, PatternMatcher> innerMap;
if (!map.TryGetValue(culture, out innerMap))
{
innerMap = new Dictionary<string, PatternMatcher>();
map[culture] = innerMap;
}
PatternMatcher patternMatcher;
if (!map.TryGetValue(value, out patternMatcher))
if (!innerMap.TryGetValue(value, out patternMatcher))
{
patternMatcher = new PatternMatcher(value, culture,
verbatimIdentifierPrefixIsWordCharacter: true,
allowFuzzyMatching: false);
map.Add(value, patternMatcher);
innerMap.Add(value, patternMatcher);
}
return patternMatcher;
......@@ -188,59 +161,43 @@ private PatternMatcher GetEnUSPatternMatcher(string value)
/// Returns true if item1 is a better completion item than item2 given the provided filter
/// text, or false if it is not better.
/// </summary>
public virtual bool IsBetterFilterMatch(CompletionItem item1, CompletionItem item2, string filterText, CompletionTrigger trigger, ImmutableArray<string> recentItems)
public int CompareItems(CompletionItem item1, CompletionItem item2, string filterText, CultureInfo culture)
{
return IsBetterFilterMatchWorker(item1, item2, filterText, recentItems);
}
protected bool IsBetterFilterMatchWorker(CompletionItem item1, CompletionItem item2, string filterText, ImmutableArray<string> recentItems)
{
var match1 = GetMatch(item1, filterText);
var match2 = GetMatch(item2, filterText);
var match1 = GetMatch(item1, filterText, culture);
var match2 = GetMatch(item2, filterText, culture);
if (match1 != null && match2 != null)
{
var result = CompareMatches(match1.Value, match2.Value, item1, item2);
if (result != 0)
{
return result < 0;
return result;
}
}
else if (match1 != null)
{
return true;
return -1;
}
else if (match2 != null)
{
return false;
return 1;
}
// If they both seemed just as good, but they differ on preselection, then
// item1 is better if it is preselected, otherwise it is worse.
if (item1.Rules.MatchPriority != item2.Rules.MatchPriority)
var diff = item1.Rules.MatchPriority - item2.Rules.MatchPriority;
if (diff != 0)
{
return item1.Rules.MatchPriority > item2.Rules.MatchPriority;
return -diff;
}
// Prefer things with a keyword tag, if the filter texts are the same.
if (!TagsEqual(item1, item2) && item1.FilterText == item2.FilterText)
{
return IsKeywordItem(item1);
}
// They matched on everything, including preselection values. Item1 is better if it
// has a lower MRU index.
if (!recentItems.IsDefault)
{
var item1MRUIndex = GetRecentItemIndex(recentItems, item1);
var item2MRUIndex = GetRecentItemIndex(recentItems, item2);
// The one with the lower index is the better one.
return item1MRUIndex < item2MRUIndex;
return IsKeywordItem(item1) ? -1 : IsKeywordItem(item2) ? 1 : 0;
}
return false;
return 0;
}
private static bool TagsEqual(CompletionItem item1, CompletionItem item2)
......
......@@ -36,7 +36,7 @@ public sealed class CompletionItem : IComparable<CompletionItem>
/// The span identifies the text in the document that is used to filter the initial list presented to the user,
/// and typically represents the region of the document that will be changed if this item is committed.
/// </summary>
public TextSpan Span { get; }
public TextSpan Span { get; internal set; }
/// <summary>
/// Additional information attached to a completion item by it creator.
......@@ -72,6 +72,26 @@ public sealed class CompletionItem : IComparable<CompletionItem>
this.Rules = rules ?? CompletionItemRules.Default;
}
#pragma warning disable RS0027 // Public API with optional parameter(s) should have the most parameters amongst its public overloads.
public static CompletionItem Create(
#pragma warning restore RS0027 // Public API with optional parameter(s) should have the most parameters amongst its public overloads.
string displayText,
string filterText = null,
string sortText = null,
ImmutableDictionary<string, string> properties = null,
ImmutableArray<string> tags = default(ImmutableArray<string>),
CompletionItemRules rules = null)
{
return new CompletionItem(
span: default(TextSpan),
displayText: displayText,
filterText: filterText,
sortText: sortText,
properties: properties,
tags: tags,
rules: rules);
}
/// <summary>
/// Creates a new <see cref="CompletionItem"/>
/// </summary>
......@@ -83,14 +103,15 @@ public sealed class CompletionItem : IComparable<CompletionItem>
/// <param name="tags">Descriptive tags that may influence how the item is displayed.</param>
/// <param name="rules">The rules that declare how this item should behave.</param>
/// <returns></returns>
[Obsolete("Use the Create overload that does not take a span")]
public static CompletionItem Create(
string displayText,
string filterText = null,
string sortText = null,
TextSpan span = default(TextSpan),
ImmutableDictionary<string, string> properties = null,
ImmutableArray<string> tags = default(ImmutableArray<string>),
CompletionItemRules rules = null)
string filterText,
string sortText,
TextSpan span,
ImmutableDictionary<string, string> properties,
ImmutableArray<string> tags,
CompletionItemRules rules)
{
return new CompletionItem(
span: span,
......@@ -107,7 +128,7 @@ public sealed class CompletionItem : IComparable<CompletionItem>
Optional<string> displayText = default(Optional<string>),
Optional<string> filterText = default(Optional<string>),
Optional<string> sortText = default(Optional<string>),
Optional<ImmutableDictionary<string, string>> properties = default(Optional<ImmutableDictionary<string,string>>),
Optional<ImmutableDictionary<string, string>> properties = default(Optional<ImmutableDictionary<string, string>>),
Optional<ImmutableArray<string>> tags = default(Optional<ImmutableArray<string>>),
Optional<CompletionItemRules> rules = default(Optional<CompletionItemRules>))
{
......@@ -119,18 +140,18 @@ public sealed class CompletionItem : IComparable<CompletionItem>
var newTags = tags.HasValue ? tags.Value : this.Tags;
var newRules = rules.HasValue ? rules.Value : this.Rules;
if (newSpan == this.Span
&& newDisplayText == this.DisplayText
&& newFilterText == this.FilterText
&& newSortText == this.SortText
&& newProperties == this.Properties
&& newTags == this.Tags
&& newRules == this.Rules)
if (newSpan == this.Span &&
newDisplayText == this.DisplayText &&
newFilterText == this.FilterText &&
newSortText == this.SortText &&
newProperties == this.Properties &&
newTags == this.Tags &&
newRules == this.Rules)
{
return this;
}
return Create(
return new CompletionItem(
displayText: newDisplayText,
filterText: newFilterText,
span: newSpan,
......@@ -143,9 +164,10 @@ public sealed class CompletionItem : IComparable<CompletionItem>
/// <summary>
/// Creates a copy of this <see cref="CompletionItem"/> with the <see cref="Span"/> property changed.
/// </summary>
[Obsolete("Not used anymore. CompletionList.Span is used to control the span used for filtering.")]
public CompletionItem WithSpan(TextSpan span)
{
return With(span: span);
return this;
}
/// <summary>
......@@ -240,4 +262,4 @@ public override string ToString()
return DisplayText;
}
}
}
}
\ No newline at end of file
// 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 Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.Completion
......@@ -20,8 +20,19 @@ public sealed class CompletionList
/// The span of the syntax element at the caret position when the <see cref="CompletionList"/> was created.
/// Individual <see cref="CompletionItem"/> spans may vary.
/// </summary>
[Obsolete("Not used anymore. CompletionList.Span is used instead.")]
public TextSpan DefaultSpan { get; }
/// <summary>
/// The span of the syntax element at the caret position when the <see cref="CompletionList"/>
/// was created.
///
/// The span identifies the text in the document that is used to filter the initial list
/// presented to the user, and typically represents the region of the document that will
/// be changed if this item is committed.
/// </summary>
public TextSpan Span { get; }
/// <summary>
/// The rules used to control behavior of the completion list shown to the user during typing.
/// </summary>
......@@ -48,11 +59,20 @@ public sealed class CompletionList
CompletionItem suggestionModeItem,
bool isExclusive)
{
this.DefaultSpan = defaultSpan;
this.Items = items.IsDefault ? ImmutableArray<CompletionItem>.Empty : items;
this.Rules = rules ?? CompletionRules.Default;
this.SuggestionModeItem = suggestionModeItem;
this.IsExclusive = isExclusive;
#pragma warning disable CS0618 // Type or member is obsolete
DefaultSpan = defaultSpan;
#pragma warning restore CS0618 // Type or member is obsolete
Span = defaultSpan;
Items = items.IsDefault ? ImmutableArray<CompletionItem>.Empty : items;
Rules = rules ?? CompletionRules.Default;
SuggestionModeItem = suggestionModeItem;
IsExclusive = isExclusive;
foreach (var item in Items)
{
item.Span = defaultSpan;
}
}
/// <summary>
......@@ -79,18 +99,7 @@ public sealed class CompletionList
CompletionItem suggestionModeItem,
bool isExclusive)
{
return new CompletionList(
defaultSpan, FixItemSpans(items, defaultSpan), rules, suggestionModeItem, isExclusive);
}
private static ImmutableArray<CompletionItem> FixItemSpans(ImmutableArray<CompletionItem> items, TextSpan defaultSpan)
{
if (defaultSpan != default(TextSpan) && items.Any(i => i.Span == default(TextSpan)))
{
items = items.Select(i => i.Span == default(TextSpan) ? i.WithSpan(defaultSpan) : i).ToImmutableArray();
}
return items;
return new CompletionList(defaultSpan, items, rules, suggestionModeItem, isExclusive);
}
private CompletionList With(
......@@ -99,15 +108,15 @@ private static ImmutableArray<CompletionItem> FixItemSpans(ImmutableArray<Comple
Optional<CompletionRules> rules = default(Optional<CompletionRules>),
Optional<CompletionItem> suggestionModeItem = default(Optional<CompletionItem>))
{
var newSpan = span.HasValue ? span.Value : this.DefaultSpan;
var newSpan = span.HasValue ? span.Value : this.Span;
var newItems = items.HasValue ? items.Value : this.Items;
var newRules = rules.HasValue ? rules.Value : this.Rules;
var newSuggestionModeItem = suggestionModeItem.HasValue ? suggestionModeItem.Value : this.SuggestionModeItem;
if (newSpan == this.DefaultSpan
&& newItems == this.Items
&& newRules == this.Rules
&& newSuggestionModeItem == this.SuggestionModeItem)
if (newSpan == this.Span &&
newItems == this.Items &&
newRules == this.Rules &&
newSuggestionModeItem == this.SuggestionModeItem)
{
return this;
}
......@@ -120,11 +129,17 @@ private static ImmutableArray<CompletionItem> FixItemSpans(ImmutableArray<Comple
/// <summary>
/// Creates a copy of this <see cref="CompletionList"/> with the <see cref="DefaultSpan"/> property changed.
/// </summary>
[Obsolete("Not used anymore. Use WithSpan instead.")]
public CompletionList WithDefaultSpan(TextSpan span)
{
return With(span: span);
}
public CompletionList WithSpan(TextSpan span)
{
return With(span: span);
}
/// <summary>
/// Creates a copy of this <see cref="CompletionList"/> with the <see cref="Items"/> property changed.
/// </summary>
......@@ -156,4 +171,4 @@ public CompletionList WithSuggestionModeItem(CompletionItem suggestionModeItem)
default(TextSpan), default(ImmutableArray<CompletionItem>), CompletionRules.Default,
suggestionModeItem: null, isExclusive: false);
}
}
}
\ No newline at end of file
// 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.Collections.Immutable;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Text;
using System.Collections.Immutable;
using System.Threading;
namespace Microsoft.CodeAnalysis.Completion
{
......@@ -52,7 +52,8 @@ public virtual Task<CompletionDescription> GetDescriptionAsync(Document document
/// <param name="item">The item to be committed.</param>
/// <param name="commitKey">The optional key character that caused the commit.</param>
/// <param name="cancellationToken"></param>
public virtual Task<CompletionChange> GetChangeAsync(Document document, CompletionItem item, char? commitKey, CancellationToken cancellationToken)
public virtual Task<CompletionChange> GetChangeAsync(
Document document, CompletionItem item, char? commitKey, CancellationToken cancellationToken)
{
return Task.FromResult(CompletionChange.Create(new TextChange(item.Span, item.DisplayText)));
}
......@@ -60,9 +61,6 @@ public virtual Task<CompletionChange> GetChangeAsync(Document document, Completi
/// <summary>
/// True if the provider produces snippet items.
/// </summary>
internal virtual bool IsSnippetProvider
{
get { return false; }
}
internal virtual bool IsSnippetProvider => false;
}
}
}
\ No newline at end of file
// 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.Collections.Immutable;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Host;
......@@ -64,9 +67,16 @@ public virtual CompletionRules GetRules()
/// </summary>
/// <param name="text">The document text that completion is occurring within.</param>
/// <param name="caretPosition">The position of the caret within the text.</param>
[Obsolete("Not used anymore. CompletionService.GetDefaultCompletionListSpan is used instead.")]
public virtual TextSpan GetDefaultItemSpan(SourceText text, int caretPosition)
{
return CommonCompletionUtilities.GetWordSpan(text, caretPosition, c => char.IsLetter(c), c => char.IsLetterOrDigit(c));
return GetDefaultCompletionListSpan(text, caretPosition);
}
public virtual TextSpan GetDefaultCompletionListSpan(SourceText text, int caretPosition)
{
return CommonCompletionUtilities.GetWordSpan(
text, caretPosition, c => char.IsLetter(c), c => char.IsLetterOrDigit(c));
}
/// <summary>
......@@ -117,5 +127,52 @@ public virtual TextSpan GetDefaultItemSpan(SourceText text, int caretPosition)
{
return Task.FromResult(CompletionChange.Create(new TextChange(item.Span, item.DisplayText)));
}
/// <summary>
/// Given a list of completion items that match the current code typed by the user,
/// returns the item that is considered the best match, and whether or not that
/// item should be selected or not.
///
/// itemToFilterText provides the values that each individual completion item should
/// be filtered against.
/// </summary>
public virtual ImmutableArray<CompletionItem> ChooseBestItems(
Document document,
ImmutableArray<CompletionItem> filteredItems,
string filterText)
{
var helper = CompletionHelper.GetHelper(document);
var bestItems = ImmutableArray.CreateBuilder<CompletionItem>();
foreach (var item in filteredItems)
{
if (bestItems.Count == 0)
{
// We've found no good items yet. So this is the best item currently.
bestItems.Add(item);
}
else
{
var comparison = helper.CompareItems(item, bestItems.First(), filterText, CultureInfo.CurrentCulture);
if (comparison < 0)
{
// This item is strictly better than the best items we've found so far.
bestItems.Clear();
bestItems.Add(item);
}
else if (comparison == 0)
{
// This item is as good as the items we've been collecting. We'll return
// it and let the controller decide what to do. (For example, it will
// pick the one that has the best MRU index).
bestItems.Add(item);
}
// otherwise, this item is strictly worse than the ones we've been collecting.
// We can just ignore it.
}
}
return bestItems.ToImmutable();
}
}
}
\ No newline at end of file
......@@ -191,7 +191,7 @@ internal protected CompletionProvider GetProvider(CompletionItem item)
CancellationToken cancellationToken)
{
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
var defaultItemSpan = this.GetDefaultItemSpan(text, caretPosition);
var defaultItemSpan = this.GetDefaultCompletionListSpan(text, caretPosition);
options = options ?? document.Options;
var providers = GetProviders(roles, trigger);
......@@ -397,7 +397,7 @@ protected virtual CompletionItem GetBetterItem(CompletionItem item, CompletionIt
if (defaultSpan == null)
{
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
defaultSpan = this.GetDefaultItemSpan(text, position);
defaultSpan = this.GetDefaultCompletionListSpan(text, position);
}
var context = new CompletionContext(provider, document, position, defaultSpan.Value, triggerInfo, options, cancellationToken);
......
......@@ -85,8 +85,8 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
}
var items = await GetItemsWorkerAsync(
context.Document, context.Position, context.DefaultItemSpan,
context.Trigger, context.CancellationToken).ConfigureAwait(false);
context.Document, context.Position, context.CompletionListSpan, context.Trigger, context.CancellationToken).ConfigureAwait(false);
if (items != null)
{
context.AddItems(items);
......@@ -95,28 +95,27 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
protected abstract Task<IEnumerable<CompletionItem>> GetItemsWorkerAsync(Document document, int position, TextSpan span, CompletionTrigger trigger, CancellationToken cancellationToken);
protected CompletionItem GetItem(string n, TextSpan span)
protected CompletionItem GetItem(string n)
{
if (_tagMap.ContainsKey(n))
{
var value = _tagMap[n];
return CreateCompletionItem(span, n, value[0], value[1]);
return CreateCompletionItem(n, value[0], value[1]);
}
return CreateCompletionItem(span, n);
return CreateCompletionItem(n);
}
protected IEnumerable<CompletionItem> GetAttributeItem(string n, TextSpan span)
protected IEnumerable<CompletionItem> GetAttributeItem(string n)
{
var items = _attributeMap.Where(x => x[0] == n).Select(x => CreateCompletionItem(span, x[1], x[2], x[3]));
var items = _attributeMap.Where(x => x[0] == n).Select(x => CreateCompletionItem(x[1], x[2], x[3]));
return items.Any() ? items : SpecializedCollections.SingletonEnumerable(CreateCompletionItem(span, n));
return items.Any() ? items : SpecializedCollections.SingletonEnumerable(CreateCompletionItem(n));
}
protected IEnumerable<CompletionItem> GetAlwaysVisibleItems(TextSpan itemSpan)
protected IEnumerable<CompletionItem> GetAlwaysVisibleItems()
{
return new[] { SeeTagName, SeeAlsoTagName, CDataPrefixTagName, CommentPrefixTagName }
.Select(t => GetItem(t, itemSpan));
return new[] { SeeTagName, SeeAlsoTagName, CDataPrefixTagName, CommentPrefixTagName }.Select(GetItem);
}
protected IEnumerable<string> NestedTagNames
......@@ -124,14 +123,14 @@ protected IEnumerable<string> NestedTagNames
get { return new[] { CTagName, CodeTagName, ParaTagName, ListTagName }; }
}
protected IEnumerable<CompletionItem> GetNestedTags(TextSpan itemSpan, ISymbol declaredSymbol)
protected IEnumerable<CompletionItem> GetNestedTags(ISymbol declaredSymbol)
{
return NestedTagNames.Select(t => GetItem(t, itemSpan))
.Concat(GetParamRefItems(itemSpan, declaredSymbol))
.Concat(GetTypeParamRefItems(itemSpan, declaredSymbol));
return NestedTagNames.Select(GetItem)
.Concat(GetParamRefItems(declaredSymbol))
.Concat(GetTypeParamRefItems(declaredSymbol));
}
private IEnumerable<CompletionItem> GetParamRefItems(TextSpan itemSpan, ISymbol declaredSymbol)
private IEnumerable<CompletionItem> GetParamRefItems(ISymbol declaredSymbol)
{
var parameters = declaredSymbol?.GetParameters().Select(p => p.Name).ToSet();
......@@ -141,13 +140,12 @@ private IEnumerable<CompletionItem> GetParamRefItems(TextSpan itemSpan, ISymbol
}
return parameters.Select(p => CreateCompletionItem(
span: itemSpan,
displayText: FormatParameter(ParamRefTagName, p),
beforeCaretText: FormatParameterRefTag(ParamRefTagName, p),
afterCaretText: string.Empty));
}
private IEnumerable<CompletionItem> GetTypeParamRefItems(TextSpan itemSpan, ISymbol declaredSymbol)
private IEnumerable<CompletionItem> GetTypeParamRefItems(ISymbol declaredSymbol)
{
var typeParameters = declaredSymbol?.GetTypeParameters().Select(t => t.Name).ToSet();
......@@ -157,28 +155,24 @@ private IEnumerable<CompletionItem> GetTypeParamRefItems(TextSpan itemSpan, ISym
}
return typeParameters.Select(t => CreateCompletionItem(
span: itemSpan,
displayText: FormatParameter(TypeParamRefTagName, t),
beforeCaretText: FormatParameterRefTag(TypeParamRefTagName, t),
afterCaretText: string.Empty));
}
protected IEnumerable<CompletionItem> GetTopLevelRepeatableItems(TextSpan itemSpan)
protected IEnumerable<CompletionItem> GetTopLevelRepeatableItems()
{
return new[] { ExceptionTagName, IncludeTagName, PermissionTagName }
.Select(t => GetItem(t, itemSpan));
return new[] { ExceptionTagName, IncludeTagName, PermissionTagName }.Select(GetItem);
}
protected IEnumerable<CompletionItem> GetListItems(TextSpan span)
{
return new[] { ListHeaderTagName, TermTagName, ItemTagName, DescriptionTagName }
.Select(t => GetItem(t, span));
return new[] { ListHeaderTagName, TermTagName, ItemTagName, DescriptionTagName }.Select(GetItem);
}
protected IEnumerable<CompletionItem> GetListHeaderItems(TextSpan span)
protected IEnumerable<CompletionItem> GetListHeaderItems()
{
return new[] { TermTagName, DescriptionTagName }
.Select(t => GetItem(t, span));
return new[] { TermTagName, DescriptionTagName }.Select(GetItem);
}
protected string FormatParameter(string kind, string name)
......@@ -227,15 +221,15 @@ private TextSpan ComputeReplacementSpan(CompletionItem completionItem, SourceTex
return TextSpan.FromBounds(text[currentSpan.Start - 1] == '<' && beforeCaretText[0] == '<' ? currentSpan.Start - 1 : currentSpan.Start, currentSpan.End);
}
protected CompletionItem CreateCompletionItem(TextSpan span, string displayText)
protected CompletionItem CreateCompletionItem(string displayText)
{
return CreateCompletionItem(span, displayText, displayText, string.Empty);
return CreateCompletionItem(displayText, displayText, string.Empty);
}
protected CompletionItem CreateCompletionItem(TextSpan span, string displayText, string beforeCaretText, string afterCaretText)
protected CompletionItem CreateCompletionItem(string displayText, string beforeCaretText, string afterCaretText)
{
return XmlDocCommentCompletionItem.Create(
span, displayText, beforeCaretText, afterCaretText,
displayText, beforeCaretText, afterCaretText,
rules: GetCompletionItemRules(displayText));
}
......
......@@ -57,18 +57,17 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
foreach (var keyword in keywords)
{
context.AddItem(CreateItem(keyword, context.DefaultItemSpan));
context.AddItem(CreateItem(keyword));
}
}
}
private static ImmutableArray<string> s_Tags = ImmutableArray.Create(CompletionTags.Intrinsic);
protected virtual CompletionItem CreateItem(RecommendedKeyword keyword, TextSpan span)
protected virtual CompletionItem CreateItem(RecommendedKeyword keyword)
{
return CommonCompletionItem.Create(
displayText: keyword.Keyword,
span: span,
description: keyword.DescriptionFactory(CancellationToken.None),
glyph: Glyph.Keyword,
tags: s_Tags,
......
......@@ -25,13 +25,15 @@ internal abstract class AbstractObjectCreationCompletionProvider : AbstractSymbo
private static readonly ImmutableArray<string> s_Tags = ImmutableArray.Create(CompletionTags.ObjectCreation);
protected override CompletionItem CreateItem(string displayText, string insertionText, int position, List<ISymbol> symbols, AbstractSyntaxContext context, TextSpan span, bool preselect, SupportedPlatformData supportedPlatformData)
protected override CompletionItem CreateItem(
string displayText, string insertionText, int position, List<ISymbol> symbols,
AbstractSyntaxContext context, bool preselect,
SupportedPlatformData supportedPlatformData)
{
return SymbolCompletionItem.Create(
displayText: displayText,
insertionText: insertionText,
filterText: GetFilterText(symbols[0], displayText, context),
span: span,
contextPosition: context.Position,
descriptionPosition: position,
symbols: symbols,
......
......@@ -65,11 +65,9 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
context.AddItem(SymbolCompletionItem.Create(
displayText: uninitializedMember.Name,
insertionText: null,
span: context.DefaultItemSpan,
symbol: uninitializedMember,
descriptionPosition: initializerLocation.SourceSpan.Start,
rules: s_rules
));
rules: s_rules));
}
}
......
......@@ -18,7 +18,6 @@ private partial class ItemGetter
{
private readonly CancellationToken _cancellationToken;
private readonly int _position;
private readonly TextSpan _span;
private readonly AbstractOverrideCompletionProvider _provider;
private readonly SymbolDisplayFormat _overrideNameFormat = SymbolDisplayFormats.NameFormat.WithParameterOptions(
SymbolDisplayParameterOptions.IncludeDefaultValue |
......@@ -37,7 +36,6 @@ private partial class ItemGetter
AbstractOverrideCompletionProvider overrideCompletionProvider,
Document document,
int position,
TextSpan span,
SourceText text,
SyntaxTree syntaxTree,
int startLineNumber,
......@@ -47,7 +45,6 @@ private partial class ItemGetter
_provider = overrideCompletionProvider;
_document = document;
_position = position;
_span = span;
_text = text;
_syntaxTree = syntaxTree;
_startLineNumber = startLineNumber;
......@@ -59,14 +56,13 @@ private partial class ItemGetter
AbstractOverrideCompletionProvider overrideCompletionProvider,
Document document,
int position,
TextSpan span,
CancellationToken cancellationToken)
{
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
var startLineNumber = text.Lines.IndexOf(position);
var startLine = text.Lines[startLineNumber];
return new ItemGetter(overrideCompletionProvider, document, position, span, text, syntaxTree, startLineNumber, startLine, cancellationToken);
return new ItemGetter(overrideCompletionProvider, document, position, text, syntaxTree, startLineNumber, startLine, cancellationToken);
}
internal async Task<IEnumerable<CompletionItem>> GetItemsAsync()
......@@ -101,11 +97,11 @@ internal async Task<IEnumerable<CompletionItem>> GetItemsAsync()
var symbolDisplayService = _document.GetLanguageService<ISymbolDisplayService>();
return overridableMembers.Select(m => CreateItem(
m, _span, symbolDisplayService, semanticModel, startToken, modifiers)).ToList();
m, symbolDisplayService, semanticModel, startToken, modifiers)).ToList();
}
private CompletionItem CreateItem(
ISymbol symbol, TextSpan textChangeSpan, ISymbolDisplayService symbolDisplayService,
ISymbol symbol, ISymbolDisplayService symbolDisplayService,
SemanticModel semanticModel, SyntaxToken startToken, DeclarationModifiers modifiers)
{
var position = startToken.SpanStart;
......@@ -114,7 +110,6 @@ internal async Task<IEnumerable<CompletionItem>> GetItemsAsync()
return MemberInsertionCompletionItem.Create(
displayString,
textChangeSpan,
symbol.GetGlyph(),
modifiers,
_startLineNumber,
......
......@@ -26,7 +26,7 @@ public AbstractOverrideCompletionProvider()
public override async Task ProvideCompletionsAsync(CompletionContext context)
{
var state = await ItemGetter.CreateAsync(this, context.Document, context.Position, context.DefaultItemSpan, context.CancellationToken).ConfigureAwait(false);
var state = await ItemGetter.CreateAsync(this, context.Document, context.Position, context.CancellationToken).ConfigureAwait(false);
var items = await state.GetItemsAsync().ConfigureAwait(false);
if (items?.Any() == true)
......
......@@ -50,7 +50,8 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
return;
}
var items = await CreatePartialItemsAsync(document, position, context.DefaultItemSpan, modifiers, token, cancellationToken).ConfigureAwait(false);
var items = await CreatePartialItemsAsync(
document, position, context.CompletionListSpan, modifiers, token, cancellationToken).ConfigureAwait(false);
if (items?.Any() == true)
{
......@@ -75,7 +76,8 @@ protected override async Task<ISymbol> GenerateMemberAsync(ISymbol member, IName
statements: syntaxFactory.CreateThrowNotImplementedStatementBlock(semanticModel.Compilation));
}
protected async Task<IEnumerable<CompletionItem>> CreatePartialItemsAsync(Document document, int position, TextSpan span, DeclarationModifiers modifiers, SyntaxToken token, CancellationToken cancellationToken)
protected async Task<IEnumerable<CompletionItem>> CreatePartialItemsAsync(
Document document, int position, TextSpan span, DeclarationModifiers modifiers, SyntaxToken token, CancellationToken cancellationToken)
{
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var enclosingSymbol = semanticModel.GetEnclosingSymbol(position, cancellationToken) as INamedTypeSymbol;
......@@ -103,7 +105,6 @@ private CompletionItem CreateItem(IMethodSymbol method, int line, TextSpan lineS
return MemberInsertionCompletionItem.Create(
displayText,
span,
Glyph.MethodPrivate,
modifiers,
line,
......
......@@ -57,7 +57,7 @@ private ITypeSymbol GetSymbolType(ISymbol symbol)
return symbol.GetSymbolType();
}
protected override CompletionItem CreateItem(string displayText, string insertionText, int position, List<ISymbol> symbols, AbstractSyntaxContext context, TextSpan span, bool preselect, SupportedPlatformData supportedPlatformData)
protected override CompletionItem CreateItem(string displayText, string insertionText, int position, List<ISymbol> symbols, AbstractSyntaxContext context, bool preselect, SupportedPlatformData supportedPlatformData)
{
var matchPriority = preselect ? ComputeSymbolMatchPriority(symbols[0]) : MatchPriority.Default;
var rules = GetCompletionItemRules(symbols, context, preselect);
......@@ -70,7 +70,6 @@ protected override CompletionItem CreateItem(string displayText, string insertio
displayText: displayText,
insertionText: insertionText,
filterText: GetFilterText(symbols[0], displayText, context),
span: span,
contextPosition: context.Position,
descriptionPosition: position,
symbols: symbols,
......
......@@ -41,7 +41,6 @@ protected AbstractSymbolCompletionProvider()
protected IEnumerable<CompletionItem> CreateItems(
int position,
IEnumerable<ISymbol> symbols,
TextSpan span,
AbstractSyntaxContext context,
Dictionary<ISymbol, List<ProjectId>> invalidProjectMap,
List<ProjectId> totalProjects,
......@@ -52,7 +51,7 @@ protected AbstractSymbolCompletionProvider()
var q = from symbol in symbols
let texts = GetDisplayAndInsertionText(symbol, context)
group symbol by texts into g
select this.CreateItem(g.Key.Item1, g.Key.Item2, position, g.ToList(), context, span, invalidProjectMap, totalProjects, preselect);
select this.CreateItem(g.Key.Item1, g.Key.Item2, position, g.ToList(), context, invalidProjectMap, totalProjects, preselect);
return q.ToList();
}
......@@ -63,7 +62,6 @@ protected AbstractSymbolCompletionProvider()
protected IEnumerable<CompletionItem> CreateItems(
int position,
IEnumerable<ISymbol> symbols,
TextSpan span,
Dictionary<ISymbol, AbstractSyntaxContext> originatingContextMap,
Dictionary<ISymbol, List<ProjectId>> invalidProjectMap,
List<ProjectId> totalProjects,
......@@ -72,7 +70,7 @@ protected AbstractSymbolCompletionProvider()
var q = from symbol in symbols
let texts = GetDisplayAndInsertionText(symbol, originatingContextMap[symbol])
group symbol by texts into g
select this.CreateItem(g.Key.Item1, g.Key.Item2, position, g.ToList(), originatingContextMap[g.First()], span, invalidProjectMap, totalProjects, preselect);
select this.CreateItem(g.Key.Item1, g.Key.Item2, position, g.ToList(), originatingContextMap[g.First()], invalidProjectMap, totalProjects, preselect);
return q.ToList();
}
......@@ -86,7 +84,6 @@ protected AbstractSymbolCompletionProvider()
int position,
List<ISymbol> symbols,
AbstractSyntaxContext context,
TextSpan span,
Dictionary<ISymbol, List<ProjectId>> invalidProjectMap,
List<ProjectId> totalProjects,
bool preselect)
......@@ -111,16 +108,19 @@ protected AbstractSymbolCompletionProvider()
}
}
return CreateItem(displayText, insertionText, position, symbols, context, span, preselect, supportedPlatformData);
return CreateItem(displayText, insertionText, position, symbols, context, preselect, supportedPlatformData);
}
protected virtual CompletionItem CreateItem(string displayText, string insertionText, int position, List<ISymbol> symbols, AbstractSyntaxContext context, TextSpan span, bool preselect, SupportedPlatformData supportedPlatformData)
protected virtual CompletionItem CreateItem(
string displayText, string insertionText,
int position, List<ISymbol> symbols,
AbstractSyntaxContext context, bool preselect,
SupportedPlatformData supportedPlatformData)
{
return SymbolCompletionItem.Create(
displayText: displayText,
insertionText: insertionText,
filterText: GetFilterText(symbols[0], displayText, context),
span: span,
contextPosition: context.Position,
descriptionPosition: position,
symbols: symbols,
......@@ -154,7 +154,6 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
{
var document = context.Document;
var position = context.Position;
var span = context.DefaultItemSpan;
var options = context.Options;
var cancellationToken = context.CancellationToken;
......@@ -173,15 +172,15 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
using (Logger.LogBlock(FunctionId.Completion_SymbolCompletionProvider_GetItemsWorker, cancellationToken))
{
var regularItems = await GetItemsWorkerAsync(document, position, span, options, preselect: false, cancellationToken: cancellationToken).ConfigureAwait(false);
var regularItems = await GetItemsWorkerAsync(document, position, options, preselect: false, cancellationToken: cancellationToken).ConfigureAwait(false);
context.AddItems(regularItems);
var preselectedItems = await GetItemsWorkerAsync(document, position, span, options, preselect: true, cancellationToken: cancellationToken).ConfigureAwait(false);
var preselectedItems = await GetItemsWorkerAsync(document, position, options, preselect: true, cancellationToken: cancellationToken).ConfigureAwait(false);
context.AddItems(preselectedItems);
}
}
private async Task<IEnumerable<CompletionItem>> GetItemsWorkerAsync(Document document, int position, TextSpan span, OptionSet options, bool preselect, CancellationToken cancellationToken)
private async Task<IEnumerable<CompletionItem>> GetItemsWorkerAsync(Document document, int position, OptionSet options, bool preselect, CancellationToken cancellationToken)
{
var relatedDocumentIds = document.GetLinkedDocumentIds();
var relatedDocuments = relatedDocumentIds.Concat(document.Id).Select(document.Project.Solution.GetDocument);
......@@ -210,7 +209,7 @@ private async Task<IEnumerable<CompletionItem>> GetItemsWorkerAsync(Document doc
IEnumerable<ISymbol> itemsForCurrentDocument = await GetSymbolsWorker(position, preselect, context, options, cancellationToken).ConfigureAwait(false);
itemsForCurrentDocument = itemsForCurrentDocument ?? SpecializedCollections.EmptyEnumerable<ISymbol>();
return CreateItems(position, itemsForCurrentDocument, span, context, null, null, preselect);
return CreateItems(position, itemsForCurrentDocument, context, null, null, preselect);
}
var contextAndSymbolLists = await GetPerContextSymbols(document, position, options, new[] { document.Id }.Concat(relatedDocumentIds), preselect, cancellationToken).ConfigureAwait(false);
......@@ -220,7 +219,7 @@ private async Task<IEnumerable<CompletionItem>> GetItemsWorkerAsync(Document doc
var missingSymbolsMap = FindSymbolsMissingInLinkedContexts(unionedSymbolsList, contextAndSymbolLists);
var totalProjects = contextAndSymbolLists.Select(t => t.Item1.ProjectId).ToList();
return CreateItems(position, unionedSymbolsList, span, originatingContextMap, missingSymbolsMap, totalProjects, preselect);
return CreateItems(position, unionedSymbolsList, originatingContextMap, missingSymbolsMap, totalProjects, preselect);
}
protected virtual bool IsExclusive()
......
......@@ -13,7 +13,6 @@ internal class MemberInsertionCompletionItem
{
public static CompletionItem Create(
string displayText,
TextSpan span,
Glyph? glyph,
DeclarationModifiers modifiers,
int line,
......@@ -29,7 +28,6 @@ internal class MemberInsertionCompletionItem
return SymbolCompletionItem.Create(
displayText: displayText,
span: span,
symbol: symbol,
glyph: glyph,
descriptionPosition: descriptionPosition,
......
......@@ -18,7 +18,6 @@ internal static class SymbolCompletionItem
{
public static CompletionItem Create(
string displayText,
TextSpan span,
IReadOnlyList<ISymbol> symbols,
int contextPosition = -1,
int descriptionPosition = -1,
......@@ -54,7 +53,6 @@ internal static class SymbolCompletionItem
var item = CommonCompletionItem.Create(
displayText: displayText,
span: span,
filterText: filterText ?? (displayText.Length > 0 && displayText[0] == '@' ? displayText : symbols[0].Name),
sortText: sortText ?? symbols[0].Name,
glyph: glyph ?? symbols[0].GetGlyph(),
......@@ -69,7 +67,6 @@ internal static class SymbolCompletionItem
public static CompletionItem Create(
string displayText,
TextSpan span,
ISymbol symbol,
int contextPosition = -1,
int descriptionPosition = -1,
......@@ -85,7 +82,6 @@ internal static class SymbolCompletionItem
{
return Create(
displayText: displayText,
span: span,
symbols: ImmutableArray.Create(symbol),
contextPosition: contextPosition,
descriptionPosition: descriptionPosition,
......
// 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 Microsoft.CodeAnalysis.Text;
using System.Collections.Immutable;
namespace Microsoft.CodeAnalysis.Completion.Providers
......@@ -8,7 +7,6 @@ namespace Microsoft.CodeAnalysis.Completion.Providers
internal static class XmlDocCommentCompletionItem
{
public static CompletionItem Create(
TextSpan span,
string displayText,
string beforeCaretText,
string afterCaretText,
......@@ -20,8 +18,7 @@ internal static class XmlDocCommentCompletionItem
return CommonCompletionItem.Create(
displayText: displayText,
span: span,
glyph: CodeAnalysis.Glyph.Keyword,
glyph: Glyph.Keyword,
properties: props,
rules: rules);
}
......@@ -40,4 +37,4 @@ public static string GetAfterCaretText(CompletionItem item)
return afterCaretText;
}
}
}
}
\ No newline at end of file
......@@ -18,26 +18,26 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
if (context.Options.GetOption(CompletionControllerOptions.AlwaysShowBuilder))
{
var text = await context.Document.GetTextAsync(context.CancellationToken).ConfigureAwait(false);
context.SuggestionModeItem = this.CreateEmptySuggestionModeItem(context.DefaultItemSpan);
context.SuggestionModeItem = this.CreateEmptySuggestionModeItem();
}
else
{
context.SuggestionModeItem = await this.GetSuggestionModeItemAsync(context.Document, context.Position, context.DefaultItemSpan, context.Trigger, context.CancellationToken).ConfigureAwait(false);
context.SuggestionModeItem = await this.GetSuggestionModeItemAsync(
context.Document, context.Position, context.CompletionListSpan, context.Trigger, context.CancellationToken).ConfigureAwait(false);
}
}
protected CompletionItem CreateEmptySuggestionModeItem(TextSpan span)
protected CompletionItem CreateEmptySuggestionModeItem()
{
return CreateSuggestionModeItem(displayText: null, span: span, description: null);
return CreateSuggestionModeItem(displayText: null, description: null);
}
private static CompletionItemRules s_rules = CompletionItemRules.Create(enterKeyRule: EnterKeyRule.Never);
protected CompletionItem CreateSuggestionModeItem(string displayText, TextSpan span, string description)
protected CompletionItem CreateSuggestionModeItem(string displayText, string description)
{
return CommonCompletionItem.Create(
displayText: displayText ?? string.Empty,
span: span,
description: description != null ? description.ToSymbolDisplayParts() : default(ImmutableArray<SymbolDisplayPart>),
rules: s_rules);
}
......
......@@ -168,6 +168,7 @@
<Compile Include="Completion\CommonCompletionUtilities.cs" />
<Compile Include="Completion\CompletionDescription.cs" />
<Compile Include="Completion\CompletionFilterReason.cs" />
<Compile Include="Completion\CompletionHelper.cs" />
<Compile Include="Completion\CompletionItem.cs" />
<Compile Include="Completion\CompletionItemFilter.cs" />
<Compile Include="Completion\CompletionItemRules.cs" />
......
*REMOVED*static Microsoft.CodeAnalysis.Completion.CompletionItem.Create(string displayText, string filterText = null, string sortText = null, Microsoft.CodeAnalysis.Text.TextSpan span = default(Microsoft.CodeAnalysis.Text.TextSpan), System.Collections.Immutable.ImmutableDictionary<string, string> properties = null, System.Collections.Immutable.ImmutableArray<string> tags = default(System.Collections.Immutable.ImmutableArray<string>), Microsoft.CodeAnalysis.Completion.CompletionItemRules rules = null) -> Microsoft.CodeAnalysis.Completion.CompletionItem
Microsoft.CodeAnalysis.Completion.CompletionContext.CompletionListSpan.get -> Microsoft.CodeAnalysis.Text.TextSpan
Microsoft.CodeAnalysis.Completion.CompletionContext.CompletionListSpan.set -> void
Microsoft.CodeAnalysis.Completion.CompletionChange.TextChange.get -> Microsoft.CodeAnalysis.Text.TextChange
Microsoft.CodeAnalysis.Completion.CompletionChange.WithTextChange(Microsoft.CodeAnalysis.Text.TextChange textChange) -> Microsoft.CodeAnalysis.Completion.CompletionChange
Microsoft.CodeAnalysis.Completion.CompletionItemRules.SelectionBehavior.get -> Microsoft.CodeAnalysis.Completion.CompletionItemSelectionBehavior
......@@ -6,6 +9,8 @@ Microsoft.CodeAnalysis.Completion.CompletionItemSelectionBehavior
Microsoft.CodeAnalysis.Completion.CompletionItemSelectionBehavior.Default = 0 -> Microsoft.CodeAnalysis.Completion.CompletionItemSelectionBehavior
Microsoft.CodeAnalysis.Completion.CompletionItemSelectionBehavior.HardSelection = 2 -> Microsoft.CodeAnalysis.Completion.CompletionItemSelectionBehavior
Microsoft.CodeAnalysis.Completion.CompletionItemSelectionBehavior.SoftSelection = 1 -> Microsoft.CodeAnalysis.Completion.CompletionItemSelectionBehavior
Microsoft.CodeAnalysis.Completion.CompletionList.Span.get -> Microsoft.CodeAnalysis.Text.TextSpan
Microsoft.CodeAnalysis.Completion.CompletionList.WithSpan(Microsoft.CodeAnalysis.Text.TextSpan span) -> Microsoft.CodeAnalysis.Completion.CompletionList
Microsoft.CodeAnalysis.Completion.CompletionRules.SnippetsRule.get -> Microsoft.CodeAnalysis.Completion.SnippetsRule
Microsoft.CodeAnalysis.Completion.CompletionRules.WithSnippetsRule(Microsoft.CodeAnalysis.Completion.SnippetsRule snippetsRule) -> Microsoft.CodeAnalysis.Completion.CompletionRules
Microsoft.CodeAnalysis.Completion.SnippetsRule
......@@ -14,5 +19,9 @@ Microsoft.CodeAnalysis.Completion.SnippetsRule.Default = 0 -> Microsoft.CodeAnal
Microsoft.CodeAnalysis.Completion.SnippetsRule.IncludeAfterTypingIdentifierQuestionTab = 3 -> Microsoft.CodeAnalysis.Completion.SnippetsRule
Microsoft.CodeAnalysis.Completion.SnippetsRule.NeverInclude = 1 -> Microsoft.CodeAnalysis.Completion.SnippetsRule
static Microsoft.CodeAnalysis.Completion.CompletionChange.Create(Microsoft.CodeAnalysis.Text.TextChange textChange, int? newPosition = null, bool includesCommitCharacter = false) -> Microsoft.CodeAnalysis.Completion.CompletionChange
static Microsoft.CodeAnalysis.Completion.CompletionItem.Create(string displayText, string filterText = null, string sortText = null, System.Collections.Immutable.ImmutableDictionary<string, string> properties = null, System.Collections.Immutable.ImmutableArray<string> tags = default(System.Collections.Immutable.ImmutableArray<string>), Microsoft.CodeAnalysis.Completion.CompletionItemRules rules = null) -> Microsoft.CodeAnalysis.Completion.CompletionItem
static Microsoft.CodeAnalysis.Completion.CompletionItem.Create(string displayText, string filterText, string sortText, Microsoft.CodeAnalysis.Text.TextSpan span, System.Collections.Immutable.ImmutableDictionary<string, string> properties, System.Collections.Immutable.ImmutableArray<string> tags, Microsoft.CodeAnalysis.Completion.CompletionItemRules rules) -> Microsoft.CodeAnalysis.Completion.CompletionItem
static Microsoft.CodeAnalysis.Completion.CompletionItemRules.Create(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Completion.CharacterSetModificationRule> filterCharacterRules = default(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Completion.CharacterSetModificationRule>), System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Completion.CharacterSetModificationRule> commitCharacterRules = default(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Completion.CharacterSetModificationRule>), Microsoft.CodeAnalysis.Completion.EnterKeyRule enterKeyRule = Microsoft.CodeAnalysis.Completion.EnterKeyRule.Default, bool formatOnCommit = false, int? matchPriority = null, Microsoft.CodeAnalysis.Completion.CompletionItemSelectionBehavior selectionBehavior = Microsoft.CodeAnalysis.Completion.CompletionItemSelectionBehavior.Default) -> Microsoft.CodeAnalysis.Completion.CompletionItemRules
static Microsoft.CodeAnalysis.Completion.CompletionRules.Create(bool dismissIfEmpty = false, bool dismissIfLastCharacterDeleted = false, System.Collections.Immutable.ImmutableArray<char> defaultCommitCharacters = default(System.Collections.Immutable.ImmutableArray<char>), Microsoft.CodeAnalysis.Completion.EnterKeyRule defaultEnterKeyRule = Microsoft.CodeAnalysis.Completion.EnterKeyRule.Default, Microsoft.CodeAnalysis.Completion.SnippetsRule snippetsRule = Microsoft.CodeAnalysis.Completion.SnippetsRule.Default) -> Microsoft.CodeAnalysis.Completion.CompletionRules
\ No newline at end of file
static Microsoft.CodeAnalysis.Completion.CompletionRules.Create(bool dismissIfEmpty = false, bool dismissIfLastCharacterDeleted = false, System.Collections.Immutable.ImmutableArray<char> defaultCommitCharacters = default(System.Collections.Immutable.ImmutableArray<char>), Microsoft.CodeAnalysis.Completion.EnterKeyRule defaultEnterKeyRule = Microsoft.CodeAnalysis.Completion.EnterKeyRule.Default, Microsoft.CodeAnalysis.Completion.SnippetsRule snippetsRule = Microsoft.CodeAnalysis.Completion.SnippetsRule.Default) -> Microsoft.CodeAnalysis.Completion.CompletionRules
virtual Microsoft.CodeAnalysis.Completion.CompletionService.ChooseBestItems(Microsoft.CodeAnalysis.Document document, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Completion.CompletionItem> filteredItems, string filterText) -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Completion.CompletionItem>
virtual Microsoft.CodeAnalysis.Completion.CompletionService.GetDefaultCompletionListSpan(Microsoft.CodeAnalysis.Text.SourceText text, int caretPosition) -> Microsoft.CodeAnalysis.Text.TextSpan
\ No newline at end of file
......@@ -66,12 +66,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
Return ValueTuple.Create(text, text)
End Function
Protected Overrides Function CreateItem(displayText As String, insertionText As String, position As Integer, symbols As List(Of ISymbol), context As AbstractSyntaxContext, textChangeSpan As TextSpan, preselect As Boolean, supportedPlatformData As SupportedPlatformData) As CompletionItem
Protected Overrides Function CreateItem(displayText As String, insertionText As String, position As Integer, symbols As List(Of ISymbol), context As AbstractSyntaxContext, preselect As Boolean, supportedPlatformData As SupportedPlatformData) As CompletionItem
Return SymbolCompletionItem.Create(
displayText:=displayText,
insertionText:=insertionText,
filterText:=GetFilterText(symbols(0), displayText, context),
span:=textChangeSpan,
symbols:=symbols,
contextPosition:=context.Position,
descriptionPosition:=position,
......
......@@ -56,12 +56,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
Dim text = Await document.GetTextAsync(cancellationToken).ConfigureAwait(False)
Dim items = CreateCompletionItems(workspace, semanticModel, symbols, token.SpanStart, context.DefaultItemSpan)
Dim items = CreateCompletionItems(workspace, semanticModel, symbols, token.SpanStart)
context.AddItems(items)
If IsFirstCrefParameterContext(token) Then
' Include Of in case they're typing a type parameter
context.AddItem(CreateOfCompletionItem(context.DefaultItemSpan))
context.AddItem(CreateOfCompletionItem())
End If
context.IsExclusive = True
......@@ -140,19 +140,25 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
End If
End Function
Private Iterator Function CreateCompletionItems(workspace As Workspace, semanticModel As SemanticModel, symbols As IEnumerable(Of ISymbol), position As Integer, span As TextSpan) As IEnumerable(Of CompletionItem)
Private Iterator Function CreateCompletionItems(
workspace As Workspace, semanticModel As SemanticModel,
symbols As IEnumerable(Of ISymbol), position As Integer) As IEnumerable(Of CompletionItem)
Dim builder = SharedPools.Default(Of StringBuilder).Allocate()
Try
For Each symbol In symbols
builder.Clear()
Yield CreateCompletionItem(workspace, semanticModel, symbol, position, span, builder)
Yield CreateCompletionItem(workspace, semanticModel, symbol, position, builder)
Next
Finally
SharedPools.Default(Of StringBuilder).ClearAndFree(builder)
End Try
End Function
Private Function CreateCompletionItem(workspace As Workspace, semanticModel As SemanticModel, symbol As ISymbol, position As Integer, span As TextSpan, builder As StringBuilder) As CompletionItem
Private Function CreateCompletionItem(
workspace As Workspace, semanticModel As SemanticModel,
symbol As ISymbol, position As Integer, builder As StringBuilder) As CompletionItem
If symbol.IsUserDefinedOperator() Then
builder.Append("Operator ")
End If
......@@ -187,7 +193,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
Return SymbolCompletionItem.Create(displayText:=displayString,
insertionText:=Nothing,
span:=span,
symbol:=symbol,
descriptionPosition:=position,
rules:=GetRules(displayString))
......@@ -201,8 +206,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
End If
End Function
Private Function CreateOfCompletionItem(span As TextSpan) As CompletionItem
Return CommonCompletionItem.Create("Of", span, glyph:=Glyph.Keyword,
Private Function CreateOfCompletionItem() As CompletionItem
Return CommonCompletionItem.Create("Of", glyph:=Glyph.Keyword,
description:=RecommendedKeyword.CreateDisplayParts("Of", VBFeaturesResources.OfKeywordToolTip))
End Function
......
......@@ -111,12 +111,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
Return Await VisualBasicSyntaxContext.CreateContextAsync(document.Project.Solution.Workspace, semanticModel, position, cancellationToken).ConfigureAwait(False)
End Function
Protected Overrides Function CreateItem(displayText As String, insertionText As String, position As Integer, symbols As List(Of ISymbol), context As AbstractSyntaxContext, span As TextSpan, preselect As Boolean, supportedPlatformData As SupportedPlatformData) As CompletionItem
Protected Overrides Function CreateItem(displayText As String, insertionText As String, position As Integer, symbols As List(Of ISymbol), context As AbstractSyntaxContext, preselect As Boolean, supportedPlatformData As SupportedPlatformData) As CompletionItem
Return SymbolCompletionItem.Create(
displayText:=displayText,
insertionText:=insertionText,
filterText:=GetFilterText(symbols(0), displayText, context),
span:=span,
symbols:=symbols,
contextPosition:=context.Position,
descriptionPosition:=position,
......
......@@ -111,7 +111,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
Private Function CreateCompletionItem(position As Integer,
symbol As ISymbol,
span As TextSpan,
context As VisualBasicSyntaxContext) As CompletionItem
Dim displayAndInsertionText = CompletionUtilities.GetDisplayAndInsertionText(
......@@ -120,7 +119,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
Return SymbolCompletionItem.Create(
displayText:=displayAndInsertionText.Item1,
insertionText:=displayAndInsertionText.Item2,
span:=span,
symbol:=symbol,
contextPosition:=context.Position,
descriptionPosition:=position,
......
......@@ -70,7 +70,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
SymbolCompletionItem.Create(
displayText:=parameter.Name & s_colonEquals,
insertionText:=parameter.Name.ToIdentifierToken().ToString() & s_colonEquals,
span:=context.DefaultItemSpan,
symbol:=parameter,
descriptionPosition:=position,
contextPosition:=position,
......
......@@ -48,7 +48,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
token.IsChildToken(Of ModuleStatementSyntax)(Function(stmt) stmt.DeclarationKeyword) Then
If token.GetAncestor(Of TypeStatementSyntax).Modifiers.Any(SyntaxKind.PartialKeyword) Then
Dim items = Await CreateItemsAsync(document, position, context.DefaultItemSpan, token, cancellationToken).ConfigureAwait(False)
Dim items = Await CreateItemsAsync(document, position, context.CompletionListSpan, token, cancellationToken).ConfigureAwait(False)
If items?.Any() Then
context.AddItems(items)
......@@ -79,7 +79,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
.OfType(Of INamedTypeSymbol)() _
.Where(Function(s) NotNewDeclaredMember(s, token)) _
.Where(Function(s) MatchesTypeKind(s, token) AndAlso InSameProject(s, compilation)) _
.Select(Function(s) CreateCompletionItem(s, span, displayService, token.SpanStart, context))
.Select(Function(s) CreateCompletionItem(s, displayService, token.SpanStart, context))
End Function
Private Function MatchesTypeKind(symbol As INamedTypeSymbol, token As SyntaxToken) As Boolean
......@@ -108,7 +108,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
End Function
Private Function CreateCompletionItem(symbol As INamedTypeSymbol,
textSpan As TextSpan,
displayService As ISymbolDisplayService,
position As Integer,
context As VisualBasicSyntaxContext) As CompletionItem
......@@ -127,7 +126,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
Return SymbolCompletionItem.Create(
displayText:=displayText,
insertionText:=insertionText,
span:=textSpan,
symbol:=symbol,
contextPosition:=context.Position,
descriptionPosition:=position,
......
......@@ -81,7 +81,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
Return items
End If
items.AddRange(GetAlwaysVisibleItems(span))
items.AddRange(GetAlwaysVisibleItems())
If declaration IsNot Nothing Then
items.AddRange(GetTagsForDeclaration(semanticModel, declaration, span, parent, cancellationToken))
......@@ -97,28 +97,28 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
Dim symbol = semanticModel.GetDeclaredSymbol(declaration, cancellationToken)
If grandParent.IsKind(SyntaxKind.XmlElement) Then
items.AddRange(GetNestedTags(span, symbol))
items.AddRange(GetNestedTags(symbol))
If GetStartTagName(grandParent) = ListTagName Then
items.AddRange(GetListItems(span))
End If
If GetStartTagName(grandParent) = ListHeaderTagName Then
items.AddRange(GetListHeaderItems(span))
items.AddRange(GetListHeaderItems())
End If
ElseIf token.Parent.IsKind(SyntaxKind.XmlText) AndAlso token.Parent.Parent.IsKind(SyntaxKind.XmlElement) Then
items.AddRange(GetNestedTags(span, symbol))
items.AddRange(GetNestedTags(symbol))
If GetStartTagName(token.Parent.Parent) = ListTagName Then
items.AddRange(GetListItems(span))
End If
If GetStartTagName(token.Parent.Parent) = ListHeaderTagName Then
items.AddRange(GetListHeaderItems(span))
items.AddRange(GetListHeaderItems())
End If
ElseIf grandParent.IsKind(SyntaxKind.DocumentationCommentTrivia) Then
items.AddRange(GetSingleUseTopLevelItems(parent, span))
items.AddRange(GetTopLevelRepeatableItems(span))
items.AddRange(GetTopLevelRepeatableItems())
End If
If token.Parent.IsKind(SyntaxKind.XmlElementStartTag, SyntaxKind.XmlName) Then
......@@ -128,7 +128,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
End If
If GetStartTagName(parentElement.Parent) = ListHeaderTagName Then
items.AddRange(GetListHeaderItems(span))
items.AddRange(GetListHeaderItems())
End If
End If
End If
......@@ -155,7 +155,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
Dim nameToken = name.LocalName
If Not nameToken.IsMissing AndAlso nameToken.ValueText.Length > 0 Then
Return SpecializedCollections.SingletonEnumerable(Of CompletionItem)(CreateCompletionItem(span, nameToken.ValueText, nameToken.ValueText & ">", String.Empty))
Return SpecializedCollections.SingletonEnumerable(CreateCompletionItem(nameToken.ValueText, nameToken.ValueText & ">", String.Empty))
End If
Return Nothing
......@@ -211,11 +211,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
If attributeName = NameAttributeName Then
If tagName = ParamTagName Then
items.AddRange(symbol.GetParameters().Select(Function(s) CreateCompletionItem(span, s.Name)))
items.AddRange(symbol.GetParameters().Select(Function(s) CreateCompletionItem(s.Name)))
End If
If tagName = TypeParamTagName Then
items.AddRange(symbol.GetTypeArguments().Select(Function(s) CreateCompletionItem(span, s.Name)))
items.AddRange(symbol.GetTypeArguments().Select(Function(s) CreateCompletionItem(s.Name)))
End If
End If
End If
......@@ -258,7 +258,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
Dim typeParameters = type.GetTypeArguments().Select(Function(t) t.Name).ToSet()
RemoveExistingTags(parent, typeParameters, Function(e) FindName(TypeParamTagName, e))
items.AddRange(typeParameters.Select(Function(p) CreateCompletionItem(span, FormatParameter(TypeParamTagName, p))))
items.AddRange(typeParameters.Select(Function(p) CreateCompletionItem(FormatParameter(TypeParamTagName, p))))
Return items
End Function
......@@ -285,13 +285,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
If [property].IsIndexer Then
Dim parameters = [property].Parameters.Select(Function(p) p.Name).ToSet()
RemoveExistingTags(parent, parameters, Function(e) FindName(ParamTagName, e))
items.AddRange(parameters.Select(Function(p) CreateCompletionItem(span, FormatParameter(ParamTagName, p))))
items.AddRange(parameters.Select(Function(p) CreateCompletionItem(FormatParameter(ParamTagName, p))))
End If
items.AddRange(typeParameters.Select(Function(p) CreateCompletionItem(span, FormatParameter(TypeParamTagName, p))))
items.AddRange(typeParameters.Select(Function(p) CreateCompletionItem(FormatParameter(TypeParamTagName, p))))
If value Then
items.Add(GetItem(ValueTagName, span))
items.Add(GetItem(ValueTagName))
End If
Return items
......@@ -318,11 +318,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
End If
Next
items.AddRange(parameters.Select(Function(p) CreateCompletionItem(span, FormatParameter(ParamTagName, p))))
items.AddRange(typeParameters.Select(Function(p) CreateCompletionItem(span, FormatParameter(TypeParamTagName, p))))
items.AddRange(parameters.Select(Function(p) CreateCompletionItem(FormatParameter(ParamTagName, p))))
items.AddRange(typeParameters.Select(Function(p) CreateCompletionItem(FormatParameter(TypeParamTagName, p))))
If returns Then
items.Add(GetItem(ReturnsTagName, span))
items.Add(GetItem(ReturnsTagName))
End If
Return items
......@@ -347,7 +347,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
RemoveExistingTags(parentTrivia, names, Function(x) DirectCast(x.StartTag.Name, XmlNameSyntax).LocalName.ValueText)
Return names.Select(Function(n) GetItem(n, span))
Return names.Select(AddressOf GetItem)
End Function
Private Sub RemoveExistingTags(parentTrivia As DocumentationCommentTriviaSyntax, names As ISet(Of String), selector As Func(Of XmlElementSyntax, String))
......@@ -364,7 +364,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
If nameSyntax IsNot Nothing Then
Dim name = nameSyntax.LocalName.ValueText
Dim existingAttributeNames = startTag.Attributes.OfType(Of XmlAttributeSyntax).Select(Function(a) DirectCast(a.Name, XmlNameSyntax).LocalName.ValueText)
Return GetAttributeItem(name, span).Where(Function(i) Not existingAttributeNames.Contains(i.DisplayText))
Return GetAttributeItem(name).Where(Function(i) Not existingAttributeNames.Contains(i.DisplayText))
End If
Return Nothing
......
......@@ -24,7 +24,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.SuggestionMode
Dim targetToken = syntaxTree.GetTargetToken(position, cancellationToken)
If semanticModel.OptionExplicit = False AndAlso (syntaxTree.IsExpressionContext(position, targetToken, cancellationToken) OrElse syntaxTree.IsSingleLineStatementContext(position, targetToken, cancellationToken)) Then
Return CreateSuggestionModeItem(VBFeaturesResources.EmptyString1, itemSpan, VBFeaturesResources.EmptyString1)
Return CreateSuggestionModeItem(VBFeaturesResources.EmptyString1, VBFeaturesResources.EmptyString1)
End If
' Builder if we're typing a field
......@@ -32,7 +32,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.SuggestionMode
VBFeaturesResources.NoteSpaceCompletionIsDisa
If syntaxTree.IsFieldNameDeclarationContext(position, targetToken, cancellationToken) Then
Return CreateSuggestionModeItem(VBFeaturesResources.NewField, itemSpan, description)
Return CreateSuggestionModeItem(VBFeaturesResources.NewField, description)
End If
If targetToken.Kind = SyntaxKind.None OrElse targetToken.FollowsEndOfStatement(position) Then
......@@ -60,7 +60,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.SuggestionMode
' Otherwise just return a builder. It won't show up unless other modifiers are
' recommended, which is what we want.
Return CreateSuggestionModeItem(VBFeaturesResources.ParameterName, itemSpan, description)
Return CreateSuggestionModeItem(VBFeaturesResources.ParameterName, description)
End If
' Builder in select clause: after Select, after comma
......@@ -69,7 +69,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.SuggestionMode
description = VBFeaturesResources.TypeANewNameForTheColumn & vbCrLf &
VBFeaturesResources.NoteUseTabForAutomaticCo
Return CreateSuggestionModeItem(VBFeaturesResources.ResultAlias, itemSpan, description)
Return CreateSuggestionModeItem(VBFeaturesResources.ResultAlias, description)
End If
End If
......@@ -80,7 +80,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.SuggestionMode
description = VBFeaturesResources.TypeANewVariableName & vbCrLf &
VBFeaturesResources.NoteSpaceAndCompletion
Return CreateSuggestionModeItem(VBFeaturesResources.NewVariable, itemSpan, description)
Return CreateSuggestionModeItem(VBFeaturesResources.NewVariable, description)
End If
' Build after Using
......@@ -90,7 +90,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.SuggestionMode
description = VBFeaturesResources.TypeANewVariableName & vbCrLf &
VBFeaturesResources.NoteSpaceAndCompletion
Return CreateSuggestionModeItem(VBFeaturesResources.NewResource, itemSpan, description)
Return CreateSuggestionModeItem(VBFeaturesResources.NewResource, description)
End If
' Builder at Namespace declaration name
......@@ -99,7 +99,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.SuggestionMode
description = VBFeaturesResources.TypeANameHereToDeclareANamespace & vbCrLf &
VBFeaturesResources.NoteSpaceAndCompletion
Return CreateSuggestionModeItem(VBFeaturesResources.NamespaceName, itemSpan, description)
Return CreateSuggestionModeItem(VBFeaturesResources.NamespaceName, description)
End If
Return Nothing
......
......@@ -139,7 +139,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion
Return item.DisplayText
End Function
Public Overrides Function GetDefaultItemSpan(text As SourceText, caretPosition As Integer) As TextSpan
Public Overrides Function GetDefaultCompletionListSpan(text As SourceText, caretPosition As Integer) As TextSpan
Return CompletionUtilities.GetCompletionItemSpan(text, caretPosition)
End Function
......
......@@ -44,7 +44,7 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
{
string completion = GetCompletionString(commandName);
context.AddItem(CommonCompletionItem.Create(
completion, context.DefaultItemSpan, description: command.Description.ToSymbolDisplayParts(), glyph: Glyph.Intrinsic));
completion, description: command.Description.ToSymbolDisplayParts(), glyph: Glyph.Intrinsic));
}
}
}
......
......@@ -51,13 +51,13 @@ private IEnumerable<CompletionItem> GetCompletionsWorker(string pathSoFar)
var path = pathSoFar.Substring(0, comma);
return from identity in GetAssemblyIdentities(path)
let text = identity.GetDisplayName()
select CommonCompletionItem.Create(text, _textChangeSpan, glyph: Glyph.Assembly, rules: _itemRules);
select CommonCompletionItem.Create(text, glyph: Glyph.Assembly, rules: _itemRules);
}
else
{
return from displayName in s_lazyAssemblySimpleNames.Value
select CommonCompletionItem.Create(
displayName, _textChangeSpan,
displayName,
description: GlobalAssemblyCache.Instance.ResolvePartialName(displayName).GetDisplayName().ToSymbolDisplayParts(),
glyph: Glyph.Assembly,
rules: _itemRules);
......
......@@ -87,7 +87,7 @@ class C
Using state = TestState.CreateTestStateFromWorkspace(
workspaceXml,
New CompletionProvider() {New MockCompletionProvider(New TextSpan(31, 10))},
New CompletionProvider() {New MockCompletionProvider()},
Nothing,
New List(Of Type) From {GetType(TestCSharpSnippetInfoService)},
WorkspaceKind.Interactive)
......@@ -106,7 +106,7 @@ class C
Private Function CreateCSharpSnippetExpansionNoteTestState(xElement As XElement, ParamArray snippetShortcuts As String()) As TestState
Dim state = TestState.CreateCSharpTestState(
xElement,
New CompletionProvider() {New MockCompletionProvider(New TextSpan(31, 10))},
New CompletionProvider() {New MockCompletionProvider()},
Nothing,
New List(Of Type) From {GetType(TestCSharpSnippetInfoService)})
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Collections.Immutable
Imports System.Threading
Imports System.Threading.Tasks
Imports Microsoft.CodeAnalysis
......@@ -13,14 +12,8 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Completion
Friend Class MockCompletionProvider
Inherits CommonCompletionProvider
Private ReadOnly _span As TextSpan
Public Sub New(span As TextSpan)
Me._span = span
End Sub
Public Overrides Function ProvideCompletionsAsync(context As CompletionContext) As Task
Dim item = CommonCompletionItem.Create("DisplayText", _span, rules:=CompletionItemRules.Default)
Dim item = CommonCompletionItem.Create("DisplayText", rules:=CompletionItemRules.Default)
context.AddItem(item)
Return SpecializedTasks.EmptyTask
......@@ -34,4 +27,4 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Completion
Return Task.FromResult(Of TextChange?)(New TextChange(selectedItem.Span, "InsertionText"))
End Function
End Class
End Namespace
End Namespace
\ No newline at end of file
......@@ -82,7 +82,7 @@ End Class]]></document>
Private Function CreateVisualBasicSnippetExpansionNoteTestState(xElement As XElement, ParamArray snippetShortcuts As String()) As TestState
Dim state = TestState.CreateVisualBasicTestState(
xElement,
New CompletionProvider() {New MockCompletionProvider(New TextSpan(31, 10))},
New CompletionProvider() {New MockCompletionProvider()},
Nothing,
New List(Of Type) From {GetType(TestVisualBasicSnippetInfoService)})
......
......@@ -47,14 +47,8 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Snippets
Dim snippets = snippetInfoService.GetSnippetsIfAvailable()
Dim itemSpan = CommonCompletionUtilities.GetWordSpan(
document.GetTextAsync(cancellationToken).WaitAndGetResult(cancellationToken),
position,
AddressOf Char.IsLetterOrDigit,
AddressOf Char.IsLetterOrDigit)
context.IsExclusive = True
context.AddItems(CreateCompletionItems(snippets, itemSpan))
context.AddItems(CreateCompletionItems(snippets))
Return SpecializedTasks.EmptyTask
End Function
......@@ -63,14 +57,13 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Snippets
Private Shared ReadOnly s_rules As CompletionItemRules = CompletionItemRules.Create(
commitCharacterRules:=ImmutableArray.Create(CharacterSetModificationRule.Create(CharacterSetModificationKind.Replace, s_commitChars)))
Private Function CreateCompletionItems(snippets As IEnumerable(Of SnippetInfo), span As TextSpan) As IEnumerable(Of CompletionItem)
Private Function CreateCompletionItems(snippets As IEnumerable(Of SnippetInfo)) As IEnumerable(Of CompletionItem)
Return snippets.Select(Function(s) CommonCompletionItem.Create(
s.Shortcut,
span,
description:=s.Description.ToSymbolDisplayParts(),
glyph:=Glyph.Snippet,
rules:=s_rules))
s.Shortcut,
description:=s.Description.ToSymbolDisplayParts(),
glyph:=Glyph.Snippet,
rules:=s_rules))
End Function
Friend Overrides Function IsInsertionTrigger(text As SourceText, characterPosition As Integer, options As OptionSet) As Boolean
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册