提交 d33d2072 编写于 作者: C CyrusNajmabadi

Don't resolve symbols at insertion time for Partial-Type-Completion.

上级 249ef344
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
...@@ -18,6 +19,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.Providers ...@@ -18,6 +19,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.Providers
{ {
internal partial class PartialTypeCompletionProvider : AbstractPartialTypeCompletionProvider internal partial class PartialTypeCompletionProvider : AbstractPartialTypeCompletionProvider
{ {
private const string InsertionTextOnLessThan = nameof(InsertionTextOnLessThan);
private static readonly SymbolDisplayFormat _symbolFormatWithGenerics = private static readonly SymbolDisplayFormat _symbolFormatWithGenerics =
new SymbolDisplayFormat( new SymbolDisplayFormat(
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Omitted, globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Omitted,
...@@ -51,7 +54,8 @@ protected override Task<AbstractSyntaxContext> CreateSyntaxContextAsync(Document ...@@ -51,7 +54,8 @@ protected override Task<AbstractSyntaxContext> CreateSyntaxContextAsync(Document
return Task.FromResult<AbstractSyntaxContext>(CSharpSyntaxContext.CreateContext(document.Project.Solution.Workspace, semanticModel, position, cancellationToken)); return Task.FromResult<AbstractSyntaxContext>(CSharpSyntaxContext.CreateContext(document.Project.Solution.Workspace, semanticModel, position, cancellationToken));
} }
protected override ValueTuple<string, string> GetDisplayAndInsertionText(INamedTypeSymbol symbol, AbstractSyntaxContext context) protected override ValueTuple<string, string> GetDisplayAndInsertionText(
INamedTypeSymbol symbol, AbstractSyntaxContext context)
{ {
var displayAndInsertionText = symbol.ToMinimalDisplayString(context.SemanticModel, context.Position, _symbolFormatWithGenerics); var displayAndInsertionText = symbol.ToMinimalDisplayString(context.SemanticModel, context.Position, _symbolFormatWithGenerics);
return ValueTuple.Create(displayAndInsertionText, displayAndInsertionText); return ValueTuple.Create(displayAndInsertionText, displayAndInsertionText);
...@@ -68,19 +72,23 @@ protected override IEnumerable<INamedTypeSymbol> LookupCandidateSymbols(Abstract ...@@ -68,19 +72,23 @@ protected override IEnumerable<INamedTypeSymbol> LookupCandidateSymbols(Abstract
private static bool IsPartialTypeDeclaration(SyntaxNode syntax) 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)); return declarationSyntax != null && declarationSyntax.Modifiers.Any(modifier => modifier.IsKind(SyntaxKind.PartialKeyword));
} }
public async override Task<TextChange?> 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<TextChange?> GetTextChangeAsync(
Document document, CompletionItem selectedItem, char? ch, CancellationToken cancellationToken)
{ {
if (ch == '<') if (ch == '<')
{ {
var symbols = await SymbolCompletionItem.GetSymbolsAsync(selectedItem, document, cancellationToken).ConfigureAwait(false); string insertionText;
if (selectedItem.Properties.TryGetValue(InsertionTextOnLessThan, out insertionText))
if (symbols.Length > 0)
{ {
var insertionText = symbols[0].Name.EscapeIdentifier();
return new TextChange(selectedItem.Span, insertionText); return new TextChange(selectedItem.Span, insertionText);
} }
} }
...@@ -88,4 +96,4 @@ private static bool IsPartialTypeDeclaration(SyntaxNode syntax) ...@@ -88,4 +96,4 @@ private static bool IsPartialTypeDeclaration(SyntaxNode syntax)
return await base.GetTextChangeAsync(document, selectedItem, ch, cancellationToken).ConfigureAwait(false); return await base.GetTextChangeAsync(document, selectedItem, ch, cancellationToken).ConfigureAwait(false);
} }
} }
} }
\ No newline at end of file
...@@ -37,7 +37,7 @@ public async sealed override Task ProvideCompletionsAsync(CompletionContext comp ...@@ -37,7 +37,7 @@ public async sealed override Task ProvideCompletionsAsync(CompletionContext comp
if (declaredSymbol != null) if (declaredSymbol != null)
{ {
var symbols = LookupCandidateSymbols(syntaxContext, declaredSymbol, cancellationToken); 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) if (items != null)
{ {
...@@ -47,19 +47,25 @@ public async sealed override Task ProvideCompletionsAsync(CompletionContext comp ...@@ -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); var displayAndInsertionText = GetDisplayAndInsertionText(symbol, context);
return SymbolCompletionItem.Create( var item = SymbolCompletionItem.Create(
displayText: displayAndInsertionText.Item1, displayText: displayAndInsertionText.Item1,
insertionText: displayAndInsertionText.Item2, insertionText: displayAndInsertionText.Item2,
symbol: symbol, symbol: symbol,
contextPosition: context.Position, contextPosition: context.Position,
descriptionPosition: position, descriptionPosition: context.Position,
rules: CompletionItemRules.Default); rules: CompletionItemRules.Default);
item = AddAdditionalProperties(item, symbol, context);
return item;
} }
protected abstract CompletionItem AddAdditionalProperties(
CompletionItem item, INamedTypeSymbol symbol, AbstractSyntaxContext context);
protected abstract Task<AbstractSyntaxContext> CreateSyntaxContextAsync( protected abstract Task<AbstractSyntaxContext> CreateSyntaxContextAsync(
Document document, Document document,
SemanticModel semanticModel, SemanticModel semanticModel,
......
...@@ -13,6 +13,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers ...@@ -13,6 +13,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
Partial Friend Class PartialTypeCompletionProvider Partial Friend Class PartialTypeCompletionProvider
Inherits AbstractPartialTypeCompletionProvider Inherits AbstractPartialTypeCompletionProvider
Private Const InsertionTextOnOpenParen As String = NameOf(InsertionTextOnOpenParen)
Private Shared ReadOnly _insertionTextFormatWithGenerics As SymbolDisplayFormat = Private Shared ReadOnly _insertionTextFormatWithGenerics As SymbolDisplayFormat =
New SymbolDisplayFormat( New SymbolDisplayFormat(
globalNamespaceStyle:=SymbolDisplayGlobalNamespaceStyle.Omitted, globalNamespaceStyle:=SymbolDisplayGlobalNamespaceStyle.Omitted,
...@@ -25,9 +27,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers ...@@ -25,9 +27,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
SymbolDisplayGenericsOptions.IncludeVariance Or SymbolDisplayGenericsOptions.IncludeVariance Or
SymbolDisplayGenericsOptions.IncludeTypeConstraints) SymbolDisplayGenericsOptions.IncludeTypeConstraints)
Private Shared ReadOnly _insertionTextFormatWithoutGenerics As SymbolDisplayFormat =
_insertionTextFormatWithGenerics.WithGenericsOptions(SymbolDisplayGenericsOptions.None)
Private Shared ReadOnly _displayTextFormat As SymbolDisplayFormat = Private Shared ReadOnly _displayTextFormat As SymbolDisplayFormat =
_insertionTextFormatWithGenerics.RemoveMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers) _insertionTextFormatWithGenerics.RemoveMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers)
...@@ -50,19 +49,19 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers ...@@ -50,19 +49,19 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
Return ValueTuple.Create(displayText, insertionText) Return ValueTuple.Create(displayText, insertionText)
End Function 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?) 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 If ch = "("c Then
Dim symbols = Await SymbolCompletionItem.GetSymbolsAsync(selectedItem, document, cancellationToken).ConfigureAwait(False) Dim insertionText As String = Nothing
If symbols.Length > 0 Then If selectedItem.Properties.TryGetValue(InsertionTextOnOpenParen, insertionText) 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)
Return New TextChange(selectedItem.Span, insertionText) Return New TextChange(selectedItem.Span, insertionText)
End If End If
End If End If
Return Await MyBase.GetTextChangeAsync(document, selectedItem, ch, cancellationToken).ConfigureAwait(False) Return Await MyBase.GetTextChangeAsync(document, selectedItem, ch, cancellationToken).ConfigureAwait(False)
End Function End Function
End Class End Class
End Namespace End Namespace
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册