From d33d2072ae417521beca3de2b7dc937326050ce9 Mon Sep 17 00:00:00 2001 From: CyrusNajmabadi Date: Fri, 15 Jul 2016 16:38:50 -0700 Subject: [PATCH] Don't resolve symbols at insertion time for Partial-Type-Completion. --- .../PartialTypeCompletionProvider.cs | 24 ++++++++++++------- .../AbstractPartialTypeCompletionProvider.cs | 14 +++++++---- .../PartialTypeCompletionProvider.vb | 17 +++++++------ 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/PartialTypeCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/PartialTypeCompletionProvider.cs index 3615d50d1bc..3385fe5fa80 100644 --- a/src/Features/CSharp/Portable/Completion/CompletionProviders/PartialTypeCompletionProvider.cs +++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/PartialTypeCompletionProvider.cs @@ -1,5 +1,6 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -18,6 +19,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.Providers { internal partial class PartialTypeCompletionProvider : AbstractPartialTypeCompletionProvider { + private const string InsertionTextOnLessThan = nameof(InsertionTextOnLessThan); + private static readonly SymbolDisplayFormat _symbolFormatWithGenerics = new SymbolDisplayFormat( globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Omitted, @@ -51,7 +54,8 @@ protected override Task CreateSyntaxContextAsync(Document return Task.FromResult(CSharpSyntaxContext.CreateContext(document.Project.Solution.Workspace, semanticModel, position, cancellationToken)); } - protected override ValueTuple GetDisplayAndInsertionText(INamedTypeSymbol symbol, AbstractSyntaxContext context) + protected override ValueTuple GetDisplayAndInsertionText( + INamedTypeSymbol symbol, AbstractSyntaxContext context) { var displayAndInsertionText = symbol.ToMinimalDisplayString(context.SemanticModel, context.Position, _symbolFormatWithGenerics); return ValueTuple.Create(displayAndInsertionText, displayAndInsertionText); @@ -68,19 +72,23 @@ protected override IEnumerable LookupCandidateSymbols(Abstract private static bool IsPartialTypeDeclaration(SyntaxNode syntax) { - var declarationSyntax = syntax as BaseTypeDeclarationSyntax; + var declarationSyntax = syntax as BaseTypeDeclarationSyntax; return declarationSyntax != null && declarationSyntax.Modifiers.Any(modifier => modifier.IsKind(SyntaxKind.PartialKeyword)); } - public async override Task GetTextChangeAsync(Document document, CompletionItem selectedItem, char? ch, CancellationToken cancellationToken) + protected override CompletionItem AddAdditionalProperties(CompletionItem item, INamedTypeSymbol symbol, AbstractSyntaxContext context) + { + return item.AddProperty(InsertionTextOnLessThan, symbol.Name.EscapeIdentifier()); + } + + public async override Task GetTextChangeAsync( + Document document, CompletionItem selectedItem, char? ch, CancellationToken cancellationToken) { if (ch == '<') { - var symbols = await SymbolCompletionItem.GetSymbolsAsync(selectedItem, document, cancellationToken).ConfigureAwait(false); - - if (symbols.Length > 0) + string insertionText; + if (selectedItem.Properties.TryGetValue(InsertionTextOnLessThan, out insertionText)) { - var insertionText = symbols[0].Name.EscapeIdentifier(); return new TextChange(selectedItem.Span, insertionText); } } @@ -88,4 +96,4 @@ private static bool IsPartialTypeDeclaration(SyntaxNode syntax) return await base.GetTextChangeAsync(document, selectedItem, ch, cancellationToken).ConfigureAwait(false); } } -} +} \ No newline at end of file diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractPartialTypeCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractPartialTypeCompletionProvider.cs index 6f0df4cfbab..ae69b79fdbe 100644 --- a/src/Features/Core/Portable/Completion/Providers/AbstractPartialTypeCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/AbstractPartialTypeCompletionProvider.cs @@ -37,7 +37,7 @@ public async sealed override Task ProvideCompletionsAsync(CompletionContext comp if (declaredSymbol != null) { var symbols = LookupCandidateSymbols(syntaxContext, declaredSymbol, cancellationToken); - var items = symbols?.Select(symbol => CreateCompletionItem(symbol, completionContext.CompletionListSpan, position, syntaxContext)); + var items = symbols?.Select(s => CreateCompletionItem(s, syntaxContext)); if (items != null) { @@ -47,19 +47,25 @@ public async sealed override Task ProvideCompletionsAsync(CompletionContext comp } } - private CompletionItem CreateCompletionItem(INamedTypeSymbol symbol, TextSpan textSpan, int position, AbstractSyntaxContext context) + private CompletionItem CreateCompletionItem( + INamedTypeSymbol symbol, AbstractSyntaxContext context) { var displayAndInsertionText = GetDisplayAndInsertionText(symbol, context); - return SymbolCompletionItem.Create( + var item = SymbolCompletionItem.Create( displayText: displayAndInsertionText.Item1, insertionText: displayAndInsertionText.Item2, symbol: symbol, contextPosition: context.Position, - descriptionPosition: position, + descriptionPosition: context.Position, rules: CompletionItemRules.Default); + + item = AddAdditionalProperties(item, symbol, context); + return item; } + protected abstract CompletionItem AddAdditionalProperties( + CompletionItem item, INamedTypeSymbol symbol, AbstractSyntaxContext context); protected abstract Task CreateSyntaxContextAsync( Document document, SemanticModel semanticModel, diff --git a/src/Features/VisualBasic/Portable/Completion/CompletionProviders/PartialTypeCompletionProvider.vb b/src/Features/VisualBasic/Portable/Completion/CompletionProviders/PartialTypeCompletionProvider.vb index cbedd7ab7f6..e632d616101 100644 --- a/src/Features/VisualBasic/Portable/Completion/CompletionProviders/PartialTypeCompletionProvider.vb +++ b/src/Features/VisualBasic/Portable/Completion/CompletionProviders/PartialTypeCompletionProvider.vb @@ -13,6 +13,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers Partial Friend Class PartialTypeCompletionProvider Inherits AbstractPartialTypeCompletionProvider + Private Const InsertionTextOnOpenParen As String = NameOf(InsertionTextOnOpenParen) + Private Shared ReadOnly _insertionTextFormatWithGenerics As SymbolDisplayFormat = New SymbolDisplayFormat( globalNamespaceStyle:=SymbolDisplayGlobalNamespaceStyle.Omitted, @@ -25,9 +27,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers SymbolDisplayGenericsOptions.IncludeVariance Or SymbolDisplayGenericsOptions.IncludeTypeConstraints) - Private Shared ReadOnly _insertionTextFormatWithoutGenerics As SymbolDisplayFormat = - _insertionTextFormatWithGenerics.WithGenericsOptions(SymbolDisplayGenericsOptions.None) - Private Shared ReadOnly _displayTextFormat As SymbolDisplayFormat = _insertionTextFormatWithGenerics.RemoveMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers) @@ -50,19 +49,19 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers Return ValueTuple.Create(displayText, insertionText) End Function + Protected Overrides Function AddAdditionalProperties(item As CompletionItem, symbol As INamedTypeSymbol, context As AbstractSyntaxContext) As CompletionItem + Return item.AddProperty(InsertionTextOnOpenParen, symbol.Name.EscapeIdentifier()) + End Function + Public Overrides Async Function GetTextChangeAsync(document As Document, selectedItem As CompletionItem, ch As Char?, cancellationToken As CancellationToken) As Task(Of TextChange?) If ch = "("c Then - Dim symbols = Await SymbolCompletionItem.GetSymbolsAsync(selectedItem, document, cancellationToken).ConfigureAwait(False) - If symbols.Length > 0 Then - Dim position = SymbolCompletionItem.GetContextPosition(selectedItem) - Dim semanticModel = Await document.GetSemanticModelForSpanAsync(New TextSpan(position, 0), cancellationToken).ConfigureAwait(False) - Dim insertionText = symbols(0).ToMinimalDisplayString(semanticModel, position, format:=_insertionTextFormatWithoutGenerics) + Dim insertionText As String = Nothing + If selectedItem.Properties.TryGetValue(InsertionTextOnOpenParen, insertionText) Then Return New TextChange(selectedItem.Span, insertionText) End If End If Return Await MyBase.GetTextChangeAsync(document, selectedItem, ch, cancellationToken).ConfigureAwait(False) End Function - End Class End Namespace \ No newline at end of file -- GitLab