Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async completion bug fixes #28219

Closed
wants to merge 24 commits into from
Closed
26 changes: 13 additions & 13 deletions build/Targets/Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -80,23 +80,23 @@
<MicrosoftVisualStudioDebuggerEngineVersion>15.0.27309-vsucorediag</MicrosoftVisualStudioDebuggerEngineVersion>
<MicrosoftVisualStudioDebuggerMetadataVersion>15.0.27309-vsucorediag</MicrosoftVisualStudioDebuggerMetadataVersion>
<MicrosoftVisualStudioDebuggerUIInterfacesVersion>15.0.27309-vsucorediag</MicrosoftVisualStudioDebuggerUIInterfacesVersion>
<MicrosoftVisualStudioCoreUtilityVersion>15.8.386-preview-g596ac9ac8e</MicrosoftVisualStudioCoreUtilityVersion>
<MicrosoftVisualStudioCoreUtilityVersion>15.8.501</MicrosoftVisualStudioCoreUtilityVersion>
<MicrosoftVisualStudioDebuggerInterop100Version>10.0.30319</MicrosoftVisualStudioDebuggerInterop100Version>
<MicrosoftVisualStudioDesignerInterfacesVersion>1.1.4322</MicrosoftVisualStudioDesignerInterfacesVersion>
<MicrosoftVisualStudioDiagnosticsPerformanceProviderVersion>15.0.26730-alpha</MicrosoftVisualStudioDiagnosticsPerformanceProviderVersion>
<MicrosoftVisualStudioEditorVersion>15.8.238-preview</MicrosoftVisualStudioEditorVersion>
<MicrosoftVisualStudioEditorVersion>15.8.501</MicrosoftVisualStudioEditorVersion>
<MicrosoftVisualStudioGraphModelVersion>15.0.26730-alpha</MicrosoftVisualStudioGraphModelVersion>
<MicrosoftVisualStudioImageCatalogVersion>15.0.26730-alpha</MicrosoftVisualStudioImageCatalogVersion>
<MicrosoftVisualStudioImageCatalogVersion>15.8.27731</MicrosoftVisualStudioImageCatalogVersion>
<MicrosoftVisualStudioImagingVersion>15.0.26730-alpha</MicrosoftVisualStudioImagingVersion>
<MicrosoftVisualStudioImagingInterop140DesignTimeVersion>15.0.25726-Preview5</MicrosoftVisualStudioImagingInterop140DesignTimeVersion>
<MicrosoftVisualStudioInteractiveWindowVersion>2.0.0-rc3-61304-01</MicrosoftVisualStudioInteractiveWindowVersion>
<MicrosoftVisualStudioLanguageCallHierarchyVersion>15.3.1710.203</MicrosoftVisualStudioLanguageCallHierarchyVersion>
<MicrosoftVisualStudioLanguageVersion>15.8.386-preview-g596ac9ac8e</MicrosoftVisualStudioLanguageVersion>
<MicrosoftVisualStudioLanguageIntellisenseVersion>15.8.386-preview-g596ac9ac8e</MicrosoftVisualStudioLanguageIntellisenseVersion>
<MicrosoftVisualStudioLanguageVersion>15.8.501</MicrosoftVisualStudioLanguageVersion>
<MicrosoftVisualStudioLanguageIntellisenseVersion>15.8.501</MicrosoftVisualStudioLanguageIntellisenseVersion>
<MicrosoftVisualStudioLanguageNavigateToInterfacesVersion>15.7.153-preview-g7d0635149a</MicrosoftVisualStudioLanguageNavigateToInterfacesVersion>
<MicrosoftVisualStudioLanguageStandardClassificationVersion>15.8.386-preview-g596ac9ac8e</MicrosoftVisualStudioLanguageStandardClassificationVersion>
<MicrosoftVisualStudioLanguageStandardClassificationVersion>15.8.501</MicrosoftVisualStudioLanguageStandardClassificationVersion>
<MicrosoftVisualStudioOLEInteropVersion>7.10.6070</MicrosoftVisualStudioOLEInteropVersion>
<MicrosoftVisualStudioPlatformVSEditorVersion>15.8.386-preview-g596ac9ac8e</MicrosoftVisualStudioPlatformVSEditorVersion>
<MicrosoftVisualStudioPlatformVSEditorVersion>15.8.501</MicrosoftVisualStudioPlatformVSEditorVersion>
<MicrosoftVisualStudioProgressionCodeSchemaVersion>15.0.26730-alpha</MicrosoftVisualStudioProgressionCodeSchemaVersion>
<MicrosoftVisualStudioProgressionCommonVersion>15.0.26730-alpha</MicrosoftVisualStudioProgressionCommonVersion>
<MicrosoftVisualStudioProgressionInterfacesVersion>15.0.26730-alpha</MicrosoftVisualStudioProgressionInterfacesVersion>
Expand All @@ -123,11 +123,11 @@
<MicrosoftVisualStudioShellInterop90Version>9.0.30729</MicrosoftVisualStudioShellInterop90Version>
<MicrosoftVisualStudioTelemetryVersion>15.0.26730-alpha</MicrosoftVisualStudioTelemetryVersion>
<MicrosoftVisualStudioTemplateWizardInterfaceVersion>8.0.0.0-alpha</MicrosoftVisualStudioTemplateWizardInterfaceVersion>
<MicrosoftVisualStudioTextDataVersion>15.8.386-preview-g596ac9ac8e</MicrosoftVisualStudioTextDataVersion>
<MicrosoftVisualStudioTextInternalVersion>15.8.386-preview-g596ac9ac8e</MicrosoftVisualStudioTextInternalVersion>
<MicrosoftVisualStudioTextLogicVersion>15.8.386-preview-g596ac9ac8e</MicrosoftVisualStudioTextLogicVersion>
<MicrosoftVisualStudioTextUIVersion>15.8.386-preview-g596ac9ac8e</MicrosoftVisualStudioTextUIVersion>
<MicrosoftVisualStudioTextUIWpfVersion>15.8.386-preview-g596ac9ac8e</MicrosoftVisualStudioTextUIWpfVersion>
<MicrosoftVisualStudioTextDataVersion>15.8.501</MicrosoftVisualStudioTextDataVersion>
<MicrosoftVisualStudioTextInternalVersion>15.8.501</MicrosoftVisualStudioTextInternalVersion>
<MicrosoftVisualStudioTextLogicVersion>15.8.501</MicrosoftVisualStudioTextLogicVersion>
<MicrosoftVisualStudioTextUIVersion>15.8.501</MicrosoftVisualStudioTextUIVersion>
<MicrosoftVisualStudioTextUIWpfVersion>15.8.501</MicrosoftVisualStudioTextUIWpfVersion>
<MicrosoftVisualStudioTextManagerInteropVersion>7.10.6070</MicrosoftVisualStudioTextManagerInteropVersion>
<MicrosoftVisualStudioTextManagerInterop100Version>10.0.30319</MicrosoftVisualStudioTextManagerInterop100Version>
<MicrosoftVisualStudioTextManagerInterop120Version>12.0.30110</MicrosoftVisualStudioTextManagerInterop120Version>
Expand Down Expand Up @@ -158,7 +158,7 @@
<RoslynToolsReferenceAssembliesVersion>0.1.3</RoslynToolsReferenceAssembliesVersion>
<RoslynToolsSignToolVersion>1.0.0-beta2-dev3</RoslynToolsSignToolVersion>
<RoslynMicrosoftVisualStudioExtensionManagerVersion>0.0.4</RoslynMicrosoftVisualStudioExtensionManagerVersion>
<StreamJsonRpcVersion>1.1.92</StreamJsonRpcVersion>
<StreamJsonRpcVersion>1.3.6</StreamJsonRpcVersion>
<SystemAppContextVersion>4.3.0</SystemAppContextVersion>
<SystemCollectionsVersion>4.3.0</SystemCollectionsVersion>
<SystemCollectionsConcurrentVersion>4.3.0</SystemCollectionsConcurrentVersion>
Expand Down
18 changes: 18 additions & 0 deletions src/EditorFeatures/Core/EditorFeaturesResources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/EditorFeatures/Core/EditorFeaturesResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -815,4 +815,10 @@ Do you want to proceed?</value>
<data name="Do_not_show_this_message_again" xml:space="preserve">
<value>Do not show this message again</value>
</data>
<data name="Filter" xml:space="preserve">
<value>Filter</value>
</data>
<data name="Warning" xml:space="preserve">
<value>Warning</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,18 @@ public EditorCompletion.CommitResult TryCommit(ITextView view, ITextBuffer buffe
var needsCustomCommit = ((CompletionServiceWithProviders)completionService).GetProvider(roslynItem) is IFeaturesCustomCommitCompletionProvider;
if (needsCustomCommit)
{
CustomCommit(view, buffer, roslynItem, applicableSpan, typeChar, token);
return new EditorCompletion.CommitResult(isHandled: true, EditorCompletion.CommitBehavior.SuppressFurtherTypeCharCommandHandlers);
var commitBehavior = CustomCommit(view, buffer, roslynItem, applicableSpan, typeChar, token);
return new EditorCompletion.CommitResult(isHandled: true, commitBehavior);
}

if (!IsCommitCharacter(typeChar, roslynItem.Rules.CommitCharacterRules))
{
return new EditorCompletion.CommitResult(isHandled: true, EditorCompletion.CommitBehavior.CancelCommit);
}

if (document.Project.Language == LanguageNames.VisualBasic && typeChar == '\n')
{
return new EditorCompletion.CommitResult(isHandled: false, EditorCompletion.CommitBehavior.SuppressFurtherTypeCharCommandHandlers);
return new EditorCompletion.CommitResult(isHandled: false, EditorCompletion.CommitBehavior.RaiseFurtherReturnKeyAndTabKeyCommandHandlers);
}

if (item.InsertText.EndsWith(":") && typeChar == ':')
Expand All @@ -66,6 +71,46 @@ public EditorCompletion.CommitResult TryCommit(ITextView view, ITextBuffer buffe
return new EditorCompletion.CommitResult(isHandled: false, EditorCompletion.CommitBehavior.None);
}

/// <summary>
/// This method needs to support custom procesing of commit characters to be on par with the old completion implementation.
/// TODO we should consider removign this method and arrange better processing of commit characters.
/// </summary>
private bool IsCommitCharacter(char typeChar, ImmutableArray<CharacterSetModificationRule> rules)
{
// Tab, Enter and Null (call invoke commit) are always a commit character
if (typeChar == '\t' || typeChar == '\n' || typeChar == '\0')
{
return true;
}

foreach (var rule in rules)
{
switch (rule.Kind)
{
case CharacterSetModificationKind.Add:
if (rule.Characters.Contains(typeChar))
{
return true;
}

break;

case CharacterSetModificationKind.Remove:
if (rule.Characters.Contains(typeChar))
{
return false;
}

break;

case CharacterSetModificationKind.Replace:
return rule.Characters.Contains(typeChar);
}
}

return CommitChars.Contains(typeChar);
}

private EditorCompletion.CommitBehavior CustomCommit(
ITextView view,
ITextBuffer buffer,
Expand All @@ -78,7 +123,17 @@ private EditorCompletion.CommitBehavior CustomCommit(
var document = buffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
var service = (CompletionServiceWithProviders)document.GetLanguageService<CompletionService>();

// TODO: Better error handling https://github.com/dotnet/roslyn/issues/27412
bool includesCommitCharacter;
if (!buffer.CheckEditAccess())
{
// We are on the wrong thread.
return EditorCompletion.CommitBehavior.None;
}

if (buffer.EditInProgress)
{
return EditorCompletion.CommitBehavior.None;
}

using (var edit = buffer.CreateEdit())
{
Expand All @@ -100,9 +155,11 @@ private EditorCompletion.CommitBehavior CustomCommit(
{
view.TryMoveCaretToAndEnsureVisible(new SnapshotPoint(buffer.CurrentSnapshot, change.NewPosition.Value));
}

includesCommitCharacter = change.IncludesCommitCharacter;
}

return EditorCompletion.CommitBehavior.SuppressFurtherTypeCharCommandHandlers;
return includesCommitCharacter ? EditorCompletion.CommitBehavior.SuppressFurtherTypeCharCommandHandlers : EditorCompletion.CommitBehavior.None;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ private static RoslynTrigger GetRoslynTrigger(EditorCompletion.InitialTrigger tr
case EditorCompletion.InitialTriggerReason.Deletion:
return RoslynTrigger.CreateDeletionTrigger(trigger.Character);
case EditorCompletion.InitialTriggerReason.Snippets:
// TODO: Exclusive snippet mode isn't currently supported https://github.com/dotnet/roslyn/issues/27423
return default;
return new RoslynTrigger(CompletionTriggerKind.Snippets);
default:
return default;
}
Expand Down Expand Up @@ -120,13 +119,13 @@ private EditorCompletion.CompletionItem Convert(
attributeImages = ImmutableArray.Create(
new ImageElement(
warningImage,
"Temporary Automation Name")); // TODO: Get automation names, here and below https://github.com/dotnet/roslyn/issues/27430
EditorFeaturesResources.Warning));
}

var item = new EditorCompletion.CompletionItem(
roslynItem.DisplayText,
this,
new ImageElement(new ImageId(imageId.Guid, imageId.Id), "Temporary Automation Name"),
new ImageElement(new ImageId(imageId.Guid, imageId.Id), roslynItem.DisplayText),
filters,
suffix: string.Empty,
insertionText,
Expand Down Expand Up @@ -157,7 +156,7 @@ private EditorCompletion.CompletionItem Convert(
var itemFilter = new EditorCompletion.CompletionFilter(
filter.DisplayText,
filter.AccessKey.ToString(),
new ImageElement(new ImageId(imageId.Guid, imageId.Id), "Temporary Automation Name"));
new ImageElement(new ImageId(imageId.Guid, imageId.Id),EditorFeaturesResources.Filter));
filterCache[filter.DisplayText] = itemFilter;
listBuilder.Add(itemFilter);
}
Expand All @@ -169,29 +168,27 @@ private EditorCompletion.CompletionItem Convert(

public async Task<object> GetDescriptionAsync(EditorCompletion.CompletionItem item, CancellationToken cancellationToken)
{
// TODO: Should string.Empty returns here be null to avoid an empty popup? https://github.com/dotnet/roslyn/issues/27420

if (!item.Properties.TryGetProperty<RoslynCompletionItem>(RoslynItem, out var roslynItem) ||
!item.Properties.TryGetProperty<ITextBuffer>(TriggerBuffer, out var triggerBuffer))
{
return string.Empty;
return null;
}

if (!Workspace.TryGetWorkspace(triggerBuffer.AsTextContainer(), out var workspace))
{
return string.Empty;
return null;
}

var documentId = workspace.GetDocumentIdInCurrentContext(triggerBuffer.AsTextContainer());
if (documentId == null)
{
return string.Empty;
return null;
}

var document = workspace.CurrentSolution.GetDocument(documentId);
if (document == null)
{
return string.Empty;
return null;
}

var service = (CompletionServiceWithProviders)document.GetLanguageService<CompletionService>();
Expand Down Expand Up @@ -230,25 +227,34 @@ public bool TryGetApplicableToSpan(char typeChar, SnapshotPoint triggerLocation,
return false;
}

// TODO: Use GetTextSynchronously https://github.com/dotnet/roslyn/issues/27425
if (!document.TryGetText(out var sourceText))
{
applicableSpan = default;
return false;
}
var sourceText = document.GetTextSynchronously(cancellationToken);

// TODO: TypeChar of 0 means Invoke or InvokeAndCommitIfUnique. An API update will make this better. https://github.com/dotnet/roslyn/issues/27426
if (typeChar != 0 && !service.ShouldTriggerCompletion(sourceText, triggerLocation.Position, RoslynTrigger.CreateInsertionTrigger(typeChar)))
if (!ShouldTriggerCompletion(typeChar, triggerLocation, sourceText, service))
{
applicableSpan = default;
return false;
}

// TODO: Check CompletionOptions.TriggerOnTyping https://github.com/dotnet/roslyn/issues/27427
// TODO: Check CompletionOptions.TriggerOnDeletion

applicableSpan = new SnapshotSpan(triggerLocation.Snapshot, service.GetDefaultCompletionListSpan(sourceText, triggerLocation.Position).ToSpan());
return true;
}

// TODO: TypeChar of 0 means Invoke or InvokeAndCommitIfUnique. An API update will make this better. https://github.com/dotnet/roslyn/issues/27426
private static bool ShouldTriggerCompletion(char typeChar, SnapshotPoint triggerLocation, SourceText sourceText, CompletionServiceWithProviders service)
{
// TODO: Check CompletionOptions.TriggerOnTyping https://github.com/dotnet/roslyn/issues/27427
// Both Backspace and Delete.
if (typeChar == '\b')
{
return triggerLocation.Position >= 0 &&
triggerLocation.Position < triggerLocation.Snapshot.Length &&
service.ShouldTriggerCompletion(sourceText, triggerLocation.Position, RoslynTrigger.CreateDeletionTrigger(triggerLocation.GetChar()));
}

return typeChar == 0 || service.ShouldTriggerCompletion(
sourceText,
triggerLocation.Position,
RoslynTrigger.CreateInsertionTrigger(typeChar));
}
}
}
Loading