提交 6b7e67f6 编写于 作者: G Gen Lu

Address review comments

上级 85db98f3
' 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 Microsoft.CodeAnalysis.Completion
Imports Microsoft.CodeAnalysis.Completion.Providers
Imports Microsoft.CodeAnalysis.Editor.UnitTests
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
Imports Microsoft.CodeAnalysis.Experiments
Imports Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
Imports Microsoft.VisualStudio.Composition
......@@ -207,5 +205,75 @@ End Class]]></Text>.Value
Await VerifyItemIsAbsentAsync(markup, "ExtensionMethod1", inlineDescription:="Foo")
Await VerifyItemIsAbsentAsync(markup, "ExtensionMethod2", inlineDescription:="Foo")
End Function
<InlineData(ReferenceType.None)>
<InlineData(ReferenceType.Project)>
<Theory, Trait(Traits.Feature, Traits.Features.Completion)>
Public Async Function TestImplicitTarget1(refType As ReferenceType) As Task
Dim file1 = <Text><![CDATA[
Imports System
Imports System.Runtime.CompilerServices
Namespace NS
Public Module Foo
<Extension>
Public Function ExtentionMethod(x As Bar) As Boolean
Return True
End Function
End Module
Public Class Bar
Public X As Boolean
End Class
End Namespace]]></Text>.Value
Dim file2 = <Text><![CDATA[
Imports System
Public Class Baz
Sub M()
Dim x = New Bar() {.$$}
End Sub
End Class]]></Text>.Value
Dim markup = GetMarkup(file2, file1, refType)
Await VerifyItemIsAbsentAsync(markup, "ExtentionMethod", inlineDescription:="NS")
End Function
<InlineData(ReferenceType.None)>
<InlineData(ReferenceType.Project)>
<Theory, Trait(Traits.Feature, Traits.Features.Completion)>
Public Async Function TestImplicitTarget2(refType As ReferenceType) As Task
Dim file1 = <Text><![CDATA[
Imports System
Imports System.Runtime.CompilerServices
Namespace NS
Public Module Foo
<Extension>
Public Function ExtentionMethod(x As Bar) As Boolean
Return True
End Function
End Module
Public Class Bar
Public X As Boolean
End Class
End Namespace]]></Text>.Value
Dim file2 = <Text><![CDATA[
Imports System
Public Class Baz
Sub M()
Dim x = New Bar() {.X = .$$}
End Sub
End Class]]></Text>.Value
Dim markup = GetMarkup(file2, file1, refType)
Await VerifyItemIsAbsentAsync(markup, "ExtentionMethod", inlineDescription:="NS")
End Function
End Class
End Namespace
......@@ -27,8 +27,5 @@ internal override bool IsInsertionTrigger(SourceText text, int characterPosition
protected override Task<SyntaxContext> CreateContextAsync(Document document, int position, CancellationToken cancellationToken)
=> ImportCompletionProviderHelper.CreateContextAsync(document, position, cancellationToken);
protected override Task<bool> IsInImportsDirectiveAsync(Document document, int position, CancellationToken cancellationToken)
=> ImportCompletionProviderHelper.IsInImportsDirectiveAsync(document, position, cancellationToken);
}
}
......@@ -30,12 +30,5 @@ public static async Task<SyntaxContext> CreateContextAsync(Document document, in
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
return CSharpSyntaxContext.CreateContext(document.Project.Solution.Workspace, semanticModel, position, cancellationToken);
}
public static async Task<bool> IsInImportsDirectiveAsync(Document document, int position, CancellationToken cancellationToken)
{
var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
var leftToken = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken, includeDirectives: true);
return leftToken.GetAncestor<UsingDirectiveSyntax>() != null;
}
}
}
......@@ -25,8 +25,5 @@ internal override bool IsInsertionTrigger(SourceText text, int characterPosition
protected override Task<SyntaxContext> CreateContextAsync(Document document, int position, CancellationToken cancellationToken)
=> ImportCompletionProviderHelper.CreateContextAsync(document, position, cancellationToken);
protected override Task<bool> IsInImportsDirectiveAsync(Document document, int position, CancellationToken cancellationToken)
=> ImportCompletionProviderHelper.IsInImportsDirectiveAsync(document, position, cancellationToken);
}
}
......@@ -33,15 +33,15 @@ protected override bool ShouldProvideCompletion(Document document, SyntaxContext
var syntaxFacts = completionContext.Document.GetRequiredLanguageService<ISyntaxFactsService>();
if (TryGetReceiverTypeSymbol(syntaxContext, syntaxFacts, out var receiverTypeSymbol))
{
var items = await ExtensionMethodImportCompletionHelper.GetUnimportExtensionMethodsAsync(
var items = await ExtensionMethodImportCompletionHelper.GetUnimportedExtensionMethodsAsync(
completionContext.Document,
completionContext.Position,
receiverTypeSymbol,
namespaceInScope,
isExpandedCompletion,
forceIndexCreation: isExpandedCompletion,
cancellationToken).ConfigureAwait(false);
completionContext.AddItems(items.Select(Convert));
completionContext.AddItems(items.Select(i => Convert(i)));
}
}
}
......@@ -49,7 +49,11 @@ protected override bool ShouldProvideCompletion(Document document, SyntaxContext
private static bool TryGetReceiverTypeSymbol(SyntaxContext syntaxContext, ISyntaxFactsService syntaxFacts, [NotNullWhen(true)] out ITypeSymbol? receiverTypeSymbol)
{
var parentNode = syntaxContext.TargetToken.Parent;
var expressionNode = syntaxFacts.GetLeftSideOfDot(parentNode, allowImplicitTarget: true);
// Even though implicit access to extension method is allowed, we decide not support it for simplicity
// e.g. we will not provide completion for unimport extension method in this case
// New Bar() {.X = .$$ }
var expressionNode = syntaxFacts.GetLeftSideOfDot(parentNode, allowImplicitTarget: false);
if (expressionNode == null)
{
......
......@@ -24,7 +24,6 @@ internal abstract class AbstractImportCompletionProvider : CommonCompletionProvi
{
protected abstract Task<SyntaxContext> CreateContextAsync(Document document, int position, CancellationToken cancellationToken);
protected abstract ImmutableArray<string> GetImportedNamespaces(SyntaxNode location, SemanticModel semanticModel, CancellationToken cancellationToken);
protected abstract Task<bool> IsInImportsDirectiveAsync(Document document, int position, CancellationToken cancellationToken);
protected abstract bool ShouldProvideCompletion(Document document, SyntaxContext syntaxContext);
protected abstract Task AddCompletionItemsAsync(CompletionContext completionContext, SyntaxContext syntaxContext, HashSet<string> namespacesInScope, bool isExpandedCompletion, CancellationToken cancellationToken);
......@@ -84,7 +83,7 @@ private HashSet<string> GetNamespacesInScope(Document document, SyntaxContext sy
var importedNamespaces = GetImportedNamespaces(syntaxContext.LeftToken.Parent, semanticModel, cancellationToken);
// This hashset will be used to match namespace names, so it must have the same case-sensitivity as the source language.
var syntaxFacts = document.GetLanguageService<ISyntaxFactsService>()!;
var syntaxFacts = document.GetRequiredLanguageService<ISyntaxFactsService>();
var namespacesInScope = new HashSet<string>(importedNamespaces, syntaxFacts.StringComparer);
// Get containing namespaces.
......@@ -111,15 +110,15 @@ internal override async Task<CompletionChange> GetChangeAsync(Document document,
}
// Find context node so we can use it to decide where to insert using/imports.
var tree = (await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false))!;
var tree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
var root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false);
var addImportContextNode = root.FindToken(completionListSpan.Start, findInsideTrivia: true).Parent;
// Add required using/imports directive.
var addImportService = document.GetLanguageService<IAddImportsService>()!;
var addImportService = document.GetRequiredLanguageService<IAddImportsService>();
var optionSet = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);
var placeSystemNamespaceFirst = optionSet.GetOption(GenerationOptions.PlaceSystemNamespaceFirst, document.Project.Language);
var compilation = (await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false))!;
var compilation = await document.Project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false);
var importNode = CreateImport(document, containingNamespace);
var rootWithImport = addImportService.AddImport(compilation, root, addImportContextNode, importNode, placeSystemNamespaceFirst, cancellationToken);
......@@ -185,6 +184,14 @@ async Task<bool> ShouldCompleteWithFullyQualifyTypeName()
}
}
private static async Task<bool> IsInImportsDirectiveAsync(Document document, int position, CancellationToken cancellationToken)
{
var syntaxFacts = document.GetRequiredLanguageService<ISyntaxFactsService>();
var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
var leftToken = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken, includeDirectives: true);
return leftToken.GetAncestor(syntaxFacts.IsUsingOrImport) != null;
}
protected static bool IsAddingImportsSupported(Document document)
{
var workspace = document.Project.Solution.Workspace;
......
......@@ -141,10 +141,6 @@ public void Dispose()
[ExportWorkspaceServiceFactory(typeof(IImportCompletionCacheService<CacheEntry, CacheEntry>), ServiceLayer.Editor), Shared]
private sealed class CacheServiceFactory : AbstractImportCompletionCacheServiceFactory<CacheEntry, CacheEntry>
{
[ImportingConstructor]
public CacheServiceFactory()
{
}
}
}
}
......@@ -9,6 +9,7 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.Extensions.ContextQuery;
namespace Microsoft.CodeAnalysis.Completion.Providers.ImportCompletion
......@@ -37,7 +38,7 @@ internal AbstractTypeImportCompletionService(Workspace workspace)
throw new ArgumentException(nameof(project));
}
var compilation = (await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false))!;
var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false);
// Since we only need top level types from source, therefore we only care if source symbol checksum changes.
var checksum = await SymbolTreeInfo.GetSourceSymbolsChecksumAsync(project, cancellationToken).ConfigureAwait(false);
......
......@@ -97,10 +97,6 @@ public void Dispose()
[ExportWorkspaceServiceFactory(typeof(IImportCompletionCacheService<CacheEntry, object>), ServiceLayer.Editor), Shared]
private sealed class CacheServiceFactory : AbstractImportCompletionCacheServiceFactory<CacheEntry, object>
{
[ImportingConstructor]
public CacheServiceFactory()
{
}
}
private static IImportCompletionCacheService<CacheEntry, object> GetCacheService(Workspace workspace)
......
......@@ -30,12 +30,12 @@ internal static partial class ExtensionMethodImportCompletionHelper
private static readonly object s_gate = new object();
private static Task s_indexingTask = Task.CompletedTask;
public static async Task<ImmutableArray<SerializableImportCompletionItem>> GetUnimportExtensionMethodsAsync(
public static async Task<ImmutableArray<SerializableImportCompletionItem>> GetUnimportedExtensionMethodsAsync(
Document document,
int position,
ITypeSymbol receiverTypeSymbol,
ISet<string> namespaceInScope,
bool isExpandedCompletion,
bool forceIndexCreation,
CancellationToken cancellationToken)
{
var ticks = Environment.TickCount;
......@@ -47,8 +47,8 @@ internal static partial class ExtensionMethodImportCompletionHelper
: null;
var (serializableItems, counter) = client == null
? await GetUnimportExtensionMethodsInCurrentProcessAsync(document, position, receiverTypeSymbol, namespaceInScope, isExpandedCompletion, cancellationToken).ConfigureAwait(false)
: await GetUnimportExtensionMethodsInRemoteProcessAsync(client, document, position, receiverTypeSymbol, namespaceInScope, isExpandedCompletion, cancellationToken).ConfigureAwait(false);
? await GetUnimportedExtensionMethodsInCurrentProcessAsync(document, position, receiverTypeSymbol, namespaceInScope, forceIndexCreation, cancellationToken).ConfigureAwait(false)
: await GetUnimportedExtensionMethodsInRemoteProcessAsync(client, document, position, receiverTypeSymbol, namespaceInScope, forceIndexCreation, cancellationToken).ConfigureAwait(false);
counter.TotalTicks = Environment.TickCount - ticks;
counter.TotalExtensionMethodsProvided = serializableItems.Length;
......@@ -57,31 +57,31 @@ internal static partial class ExtensionMethodImportCompletionHelper
return serializableItems;
}
public static async Task<(ImmutableArray<SerializableImportCompletionItem>, StatisticCounter)> GetUnimportExtensionMethodsInRemoteProcessAsync(
public static async Task<(ImmutableArray<SerializableImportCompletionItem>, StatisticCounter)> GetUnimportedExtensionMethodsInRemoteProcessAsync(
RemoteHostClient client,
Document document,
int position,
ITypeSymbol receiverTypeSymbol,
ISet<string> namespaceInScope,
bool isExpandedCompletion,
bool forceIndexCreation,
CancellationToken cancellationToken)
{
var project = document.Project;
var (serializableItems, counter) = await client.TryRunCodeAnalysisRemoteAsync<(IList<SerializableImportCompletionItem>, StatisticCounter)>(
project.Solution,
nameof(IRemoteExtensionMethodImportCompletionService.GetUnimportedExtensionMethodsAsync),
new object[] { document.Id, position, SymbolKey.CreateString(receiverTypeSymbol), namespaceInScope.ToArray(), isExpandedCompletion },
new object[] { document.Id, position, SymbolKey.CreateString(receiverTypeSymbol), namespaceInScope.ToArray(), forceIndexCreation },
cancellationToken).ConfigureAwait(false);
return (serializableItems.ToImmutableArray(), counter);
}
public static async Task<(ImmutableArray<SerializableImportCompletionItem>, StatisticCounter)> GetUnimportExtensionMethodsInCurrentProcessAsync(
public static async Task<(ImmutableArray<SerializableImportCompletionItem>, StatisticCounter)> GetUnimportedExtensionMethodsInCurrentProcessAsync(
Document document,
int position,
ITypeSymbol receiverTypeSymbol,
ISet<string> namespaceInScope,
bool isExpandedCompletion,
bool forceIndexCreation,
CancellationToken cancellationToken)
{
var counter = new StatisticCounter();
......@@ -104,7 +104,7 @@ internal static partial class ExtensionMethodImportCompletionHelper
var allTypeNames = allTypeNamesBuilder.ToImmutableArray();
var matchedMethods = await GetPossibleExtensionMethodMatchesAsync(
project, allTypeNames, isExpandedCompletion, isPrecalculation: false, cancellationToken).ConfigureAwait(false);
project, allTypeNames, forceIndexCreation, isPrecalculation: false, cancellationToken).ConfigureAwait(false);
counter.GetFilterTicks = Environment.TickCount - ticks;
counter.NoFilter = matchedMethods == null;
......@@ -119,7 +119,7 @@ internal static partial class ExtensionMethodImportCompletionHelper
{
if (s_indexingTask.IsCompleted)
{
s_indexingTask = Task.Run(() => GetPossibleExtensionMethodMatchesAsync(project, allTypeNames, isExpandedCompletion: false, isPrecalculation: true, CancellationToken.None));
s_indexingTask = Task.Run(() => GetPossibleExtensionMethodMatchesAsync(project, allTypeNames, forceIndexCreation: false, isPrecalculation: true, CancellationToken.None));
}
}
......@@ -140,7 +140,7 @@ internal static partial class ExtensionMethodImportCompletionHelper
private static async Task<MultiDictionary<string, string>?> GetPossibleExtensionMethodMatchesAsync(
Project currentProject,
ImmutableArray<string> targetTypeNames,
bool isExpandedCompletion,
bool forceIndexCreation,
bool isPrecalculation,
CancellationToken cancellationToken)
{
......@@ -155,9 +155,9 @@ internal static partial class ExtensionMethodImportCompletionHelper
var peReferences = PooledHashSet<PortableExecutableReference>.GetInstance();
// We will only create missing indices in the following cases, neither would block completion.
// 1. User explicitly asked for them using expander.
// 1. We are asked explicitly to create missing indices (e.g. via expander)
// 2. We are trying to populate the data in background.
var shouldCreateIndex = isExpandedCompletion || isPrecalculation;
var shouldCreateIndex = forceIndexCreation || isPrecalculation;
try
{
......
......@@ -15,7 +15,7 @@ internal interface IRemoteExtensionMethodImportCompletionService
int position,
string receiverTypeSymbolKeyData,
string[] namespaceInScope,
bool isExpandedCompletion,
bool forceIndexCreation,
CancellationToken cancellationToken);
}
}
......@@ -129,7 +129,8 @@ private static string GetFullyQualifiedName(string namespaceName, string typeNam
return SymbolKey.ResolveString(symbolId, compilation).GetAnySymbol();
}
// Otherwise, this is a type item, so we should have all the data to constrcut its metadata name
// Otherwise, this is a type item, so we don't have SymbolKey data. But we should still have all
// the data to construct its full metadata name
var containingNamespace = GetContainingNamespace(item);
var typeName = item.Properties.TryGetValue(AttributeFullName, out var attributeFullName) ? attributeFullName : item.DisplayText;
var fullyQualifiedName = GetFullyQualifiedName(containingNamespace, typeName);
......
......@@ -28,9 +28,5 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
Protected Overrides Function GetImportedNamespaces(location As SyntaxNode, semanticModel As SemanticModel, cancellationToken As CancellationToken) As ImmutableArray(Of String)
Return ImportCompletionProviderHelper.GetImportedNamespaces(location, semanticModel, cancellationToken)
End Function
Protected Overrides Function IsInImportsDirectiveAsync(document As Document, position As Integer, cancellationToken As CancellationToken) As Task(Of Boolean)
Return ImportCompletionProviderHelper.IsInImportsDirectiveAsync(document, position, cancellationToken)
End Function
End Class
End Namespace
......@@ -35,11 +35,5 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
Dim semanticModel = Await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(False)
Return Await VisualBasicSyntaxContext.CreateContextAsync(document.Project.Solution.Workspace, semanticModel, position, cancellationToken).ConfigureAwait(False)
End Function
Public Shared Async Function IsInImportsDirectiveAsync(document As Document, position As Integer, cancellationToken As CancellationToken) As Task(Of Boolean)
Dim syntaxTree = Await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(False)
Dim leftToken = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken, includeDirectives:=True, includeDocumentationComments:=True)
Return leftToken.GetAncestor(Of ImportsStatementSyntax)() IsNot Nothing
End Function
End Class
End Namespace
......@@ -24,9 +24,5 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
Protected Overrides Function GetImportedNamespaces(location As SyntaxNode, semanticModel As SemanticModel, cancellationToken As CancellationToken) As ImmutableArray(Of String)
Return ImportCompletionProviderHelper.GetImportedNamespaces(location, semanticModel, cancellationToken)
End Function
Protected Overrides Function IsInImportsDirectiveAsync(document As Document, position As Integer, cancellationToken As CancellationToken) As Task(Of Boolean)
Return ImportCompletionProviderHelper.IsInImportsDirectiveAsync(document, position, cancellationToken)
End Function
End Class
End Namespace
......@@ -558,6 +558,8 @@ private static bool TryGetSimpleTypeName(SyntaxNode node, ImmutableArray<string>
return TryGetSimpleTypeName(qualifiedNameNode.Right, typeParameterNames: null, out simpleTypeName);
case NullableTypeSyntax nullableNode:
// Ignore nullability, becase nullable reference type might not be enabled universally.
// In the worst case we just include more methods to check in out filter.
return TryGetSimpleTypeName(nullableNode.ElementType, typeParameterNames, out simpleTypeName);
}
}
......
......@@ -1371,6 +1371,11 @@ public bool IsUsingOrExternOrImport(SyntaxNode node)
node.IsKind(SyntaxKind.ExternAliasDirective);
}
public bool IsUsingOrImport(SyntaxNode node)
{
return node.IsKind(SyntaxKind.UsingDirective);
}
public bool IsGlobalAttribute(SyntaxNode node)
{
return node.IsKind(SyntaxKind.Attribute) && node.Parent.IsKind(SyntaxKind.AttributeList) &&
......
......@@ -19,6 +19,8 @@ namespace Microsoft.CodeAnalysis.FindSymbols
{
internal interface IDeclaredSymbolInfoFactoryService : ILanguageService
{
// `rootNamespace` is required for VB projects that has non-global namespace as root namespace,
// otherwise we would not be able to get correct data from syntax.
bool TryGetDeclaredSymbolInfo(StringTable stringTable, SyntaxNode node, string rootNamespace, out DeclaredSymbolInfo declaredSymbolInfo);
bool TryGetTargetTypeName(SyntaxNode node, out string instanceTypeName);
......
......@@ -89,6 +89,8 @@ internal interface ISyntaxFactsService : ILanguageService
bool IsTypeNamedVarInVariableOrFieldDeclaration(SyntaxToken token, SyntaxNode parent);
bool IsTypeNamedDynamic(SyntaxToken token, SyntaxNode parent);
bool IsUsingOrExternOrImport(SyntaxNode node);
bool IsUsingOrImport(SyntaxNode node);
bool IsUsingAliasDirective(SyntaxNode node);
bool IsGlobalAttribute(SyntaxNode node);
bool IsDeclaration(SyntaxNode node);
bool IsTypeDeclaration(SyntaxNode node);
......@@ -266,7 +268,6 @@ internal interface ISyntaxFactsService : ILanguageService
bool IsIdentifierName(SyntaxNode node);
bool IsGenericName(SyntaxNode node);
bool IsQualifiedName(SyntaxNode node);
bool IsUsingAliasDirective(SyntaxNode node);
bool IsAttribute(SyntaxNode node);
bool IsAttributeName(SyntaxNode node);
......
......@@ -23,13 +23,24 @@ namespace Microsoft.CodeAnalysis.Shared.Extensions
{
internal static partial class DocumentExtensions
{
// ⚠ Verify IVTs do not use this method before removing it.
// ⚠ Verify IVTs do not use this method before removing it.314104
public static TLanguageService? GetLanguageService<TLanguageService>(this Document? document) where TLanguageService : class, ILanguageService
=> document?.Project?.LanguageServices?.GetService<TLanguageService>();
public static TLanguageService GetRequiredLanguageService<TLanguageService>(this Document document) where TLanguageService : class, ILanguageService
=> document.Project.LanguageServices.GetRequiredService<TLanguageService>();
public static async Task<SyntaxTree> GetRequiredSyntaxTreeAsync(this Document document, CancellationToken cancellationToken)
{
var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
if (syntaxTree == null)
{
throw new InvalidOperationException(string.Format(WorkspacesResources.SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0, document.Name));
}
return syntaxTree;
}
public static bool IsOpen(this Document document)
{
var workspace = document.Project.Solution.Workspace as Workspace;
......
......@@ -3384,6 +3384,15 @@ internal class WorkspacesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Syntax tree is required to accomplish the task but is not supported by document {0}..
/// </summary>
internal static string SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0 {
get {
return ResourceManager.GetString("SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Temporary storage cannot be written more than once..
/// </summary>
......
......@@ -1482,4 +1482,7 @@ Zero-width positive lookbehind assertions are typically used at the beginning of
<data name="Compilation_is_required_to_accomplish_the_task_but_is_not_supported_by_project_0" xml:space="preserve">
<value>Compilation is required to accomplish the task but is not supported by project {0}.</value>
</data>
<data name="SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0" xml:space="preserve">
<value>Syntax tree is required to accomplish the task but is not supported by document {0}.</value>
</data>
</root>
\ No newline at end of file
......@@ -1317,6 +1317,11 @@ Pozitivní kontrolní výrazy zpětného vyhledávání s nulovou šířkou se o
<target state="translated">Specifikace symbolů</target>
<note />
</trans-unit>
<trans-unit id="SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0">
<source>Syntax tree is required to accomplish the task but is not supported by document {0}.</source>
<target state="new">Syntax tree is required to accomplish the task but is not supported by document {0}.</target>
<note />
</trans-unit>
<trans-unit id="Visual_Basic_files">
<source>Visual Basic files</source>
<target state="translated">Soubory jazyka Visual Basic</target>
......
......@@ -1317,6 +1317,11 @@ Positive Lookbehindassertionen mit Nullbreite werden normalerweise am Anfang reg
<target state="translated">Symbolspezifikationen</target>
<note />
</trans-unit>
<trans-unit id="SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0">
<source>Syntax tree is required to accomplish the task but is not supported by document {0}.</source>
<target state="new">Syntax tree is required to accomplish the task but is not supported by document {0}.</target>
<note />
</trans-unit>
<trans-unit id="Visual_Basic_files">
<source>Visual Basic files</source>
<target state="translated">Visual Basic-Dateien</target>
......
......@@ -1317,6 +1317,11 @@ Las aserciones posteriores positivas de ancho cero se usan normalmente al princi
<target state="translated">Especificaciones de símbolos</target>
<note />
</trans-unit>
<trans-unit id="SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0">
<source>Syntax tree is required to accomplish the task but is not supported by document {0}.</source>
<target state="new">Syntax tree is required to accomplish the task but is not supported by document {0}.</target>
<note />
</trans-unit>
<trans-unit id="Visual_Basic_files">
<source>Visual Basic files</source>
<target state="translated">Archivos de Visual Basic</target>
......
......@@ -1317,6 +1317,11 @@ Les assertions de postanalyse positives de largeur nulle sont généralement uti
<target state="translated">Spécifications de symboles</target>
<note />
</trans-unit>
<trans-unit id="SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0">
<source>Syntax tree is required to accomplish the task but is not supported by document {0}.</source>
<target state="new">Syntax tree is required to accomplish the task but is not supported by document {0}.</target>
<note />
</trans-unit>
<trans-unit id="Visual_Basic_files">
<source>Visual Basic files</source>
<target state="translated">Fichiers Visual Basic</target>
......
......@@ -1317,6 +1317,11 @@ Le asserzioni lookbehind positive di larghezza zero vengono usate in genere all'
<target state="translated">Specifiche dei simboli</target>
<note />
</trans-unit>
<trans-unit id="SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0">
<source>Syntax tree is required to accomplish the task but is not supported by document {0}.</source>
<target state="new">Syntax tree is required to accomplish the task but is not supported by document {0}.</target>
<note />
</trans-unit>
<trans-unit id="Visual_Basic_files">
<source>Visual Basic files</source>
<target state="translated">File Visual Basic</target>
......
......@@ -1317,6 +1317,11 @@ Zero-width positive lookbehind assertions are typically used at the beginning of
<target state="translated">記号の仕様</target>
<note />
</trans-unit>
<trans-unit id="SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0">
<source>Syntax tree is required to accomplish the task but is not supported by document {0}.</source>
<target state="new">Syntax tree is required to accomplish the task but is not supported by document {0}.</target>
<note />
</trans-unit>
<trans-unit id="Visual_Basic_files">
<source>Visual Basic files</source>
<target state="translated">Visual Basic ファイル</target>
......
......@@ -1317,6 +1317,11 @@ Zero-width positive lookbehind assertions are typically used at the beginning of
<target state="translated">기호 사양</target>
<note />
</trans-unit>
<trans-unit id="SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0">
<source>Syntax tree is required to accomplish the task but is not supported by document {0}.</source>
<target state="new">Syntax tree is required to accomplish the task but is not supported by document {0}.</target>
<note />
</trans-unit>
<trans-unit id="Visual_Basic_files">
<source>Visual Basic files</source>
<target state="translated">Visual Basic 파일</target>
......
......@@ -1317,6 +1317,11 @@ Pozytywne asercje wsteczne o zerowej szerokości są zwykle używane na początk
<target state="translated">Specyfikacje symboli</target>
<note />
</trans-unit>
<trans-unit id="SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0">
<source>Syntax tree is required to accomplish the task but is not supported by document {0}.</source>
<target state="new">Syntax tree is required to accomplish the task but is not supported by document {0}.</target>
<note />
</trans-unit>
<trans-unit id="Visual_Basic_files">
<source>Visual Basic files</source>
<target state="translated">Pliki języka Visual Basic</target>
......
......@@ -1317,6 +1317,11 @@ As declarações de lookbehind positivas de largura zero normalmente são usadas
<target state="translated">Especificações de símbolo</target>
<note />
</trans-unit>
<trans-unit id="SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0">
<source>Syntax tree is required to accomplish the task but is not supported by document {0}.</source>
<target state="new">Syntax tree is required to accomplish the task but is not supported by document {0}.</target>
<note />
</trans-unit>
<trans-unit id="Visual_Basic_files">
<source>Visual Basic files</source>
<target state="translated">Arquivos do Visual Basic</target>
......
......@@ -1317,6 +1317,11 @@ Zero-width positive lookbehind assertions are typically used at the beginning of
<target state="translated">Спецификации символов</target>
<note />
</trans-unit>
<trans-unit id="SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0">
<source>Syntax tree is required to accomplish the task but is not supported by document {0}.</source>
<target state="new">Syntax tree is required to accomplish the task but is not supported by document {0}.</target>
<note />
</trans-unit>
<trans-unit id="Visual_Basic_files">
<source>Visual Basic files</source>
<target state="translated">Файлы Visual Basic</target>
......
......@@ -1317,6 +1317,11 @@ Sıfır genişlikli pozitif geri yönlü onaylamalar genellikle normal ifadeleri
<target state="translated">Sembol belirtimleri</target>
<note />
</trans-unit>
<trans-unit id="SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0">
<source>Syntax tree is required to accomplish the task but is not supported by document {0}.</source>
<target state="new">Syntax tree is required to accomplish the task but is not supported by document {0}.</target>
<note />
</trans-unit>
<trans-unit id="Visual_Basic_files">
<source>Visual Basic files</source>
<target state="translated">Visual Basic dosyaları</target>
......
......@@ -1317,6 +1317,11 @@ Zero-width positive lookbehind assertions are typically used at the beginning of
<target state="translated">符号规范</target>
<note />
</trans-unit>
<trans-unit id="SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0">
<source>Syntax tree is required to accomplish the task but is not supported by document {0}.</source>
<target state="new">Syntax tree is required to accomplish the task but is not supported by document {0}.</target>
<note />
</trans-unit>
<trans-unit id="Visual_Basic_files">
<source>Visual Basic files</source>
<target state="translated">visual basic 文件</target>
......
......@@ -1317,6 +1317,11 @@ Zero-width positive lookbehind assertions are typically used at the beginning of
<target state="translated">符號規格</target>
<note />
</trans-unit>
<trans-unit id="SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0">
<source>Syntax tree is required to accomplish the task but is not supported by document {0}.</source>
<target state="new">Syntax tree is required to accomplish the task but is not supported by document {0}.</target>
<note />
</trans-unit>
<trans-unit id="Visual_Basic_files">
<source>Visual Basic files</source>
<target state="translated">Visual Basic 檔案</target>
......
......@@ -19,7 +19,7 @@ internal partial class CodeAnalysisService : IRemoteExtensionMethodImportComplet
int position,
string receiverTypeSymbolKeyData,
string[] namespaceInScope,
bool isExpandedCompletion,
bool forceIndexCreation,
CancellationToken cancellationToken)
{
return RunServiceAsync(async () =>
......@@ -36,8 +36,8 @@ internal partial class CodeAnalysisService : IRemoteExtensionMethodImportComplet
var syntaxFacts = document.GetRequiredLanguageService<ISyntaxFactsService>();
var namespaceInScopeSet = new HashSet<string>(namespaceInScope, syntaxFacts.StringComparer);
var (items, counter) = await ExtensionMethodImportCompletionHelper.GetUnimportExtensionMethodsInCurrentProcessAsync(
document, position, receiverTypeSymbol, namespaceInScopeSet, isExpandedCompletion, cancellationToken).ConfigureAwait(false);
var (items, counter) = await ExtensionMethodImportCompletionHelper.GetUnimportedExtensionMethodsInCurrentProcessAsync(
document, position, receiverTypeSymbol, namespaceInScopeSet, forceIndexCreation, cancellationToken).ConfigureAwait(false);
return ((IList<SerializableImportCompletionItem>)items, counter);
}
......
......@@ -1402,6 +1402,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Function
Public Function IsUsingOrExternOrImport(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsUsingOrExternOrImport
Return IsUsingOrImport(node)
End Function
Public Function IsUsingOrImport(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsUsingOrImport
Return node.IsKind(SyntaxKind.ImportsStatement)
End Function
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册