From cf911f2fa7a331f82fcddd1bb958350c96ef5c9a Mon Sep 17 00:00:00 2001 From: Gen Lu Date: Fri, 25 Oct 2019 10:44:13 -0700 Subject: [PATCH] Support having multiple identical aliases as ext methods' target type --- ...sionMethodImportCompletionProviderTests.cs | 4 +- .../SyntaxTree/SyntaxTreeIndex_Create.cs | 40 +++++++++++++++---- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ExtensionMethodImportCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ExtensionMethodImportCompletionProviderTests.cs index 2aaa99d35f0..0982751607f 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ExtensionMethodImportCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ExtensionMethodImportCompletionProviderTests.cs @@ -1096,9 +1096,9 @@ public void M(int x) } [InlineData("int", "Int32Method", "Foo")] - [InlineData("string", "StringMethod", "Bar", Skip = "Currently can't handle aliases with idencical name")] + [InlineData("string", "StringMethod", "Bar")] [Theory, Trait(Traits.Feature, Traits.Features.Completion)] - public async Task TestIdenticalAlias_UseOuterOne(string type, string expectedMethodname, string expectedNamespace) + public async Task TestIdenticalAliases(string type, string expectedMethodname, string expectedNamespace) { var file1 = @" using X = System.String; diff --git a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs index 7bb5e148226..afd67dc5de9 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs @@ -120,12 +120,26 @@ internal sealed partial class SyntaxTreeIndex { foreach (var (aliasName, name) in aliases) { - // TODO: - // we currently don't handle using aliases with same name declared - // in different containers in the document (only allowed in C#) - // e.g. see test CSharpReferenceHighlightingTests.TestAlias4 - // Debug.Assert(!usingAliases.ContainsKey(aliasName)); - usingAliases[aliasName] = name; + // In C#, it's valid to declare two alias with identical name, + // as long as they are in different containers. + // + // e.g. + // using X = System.String; + // namespace N + // { + // using X = System.Int32; + // } + // + // If we detect this, we will simply treat extension methods whose + // target type is this alais as complex method. + if (usingAliases.ContainsKey(aliasName)) + { + usingAliases[aliasName] = null; + } + else + { + usingAliases[aliasName] = name; + } } } @@ -288,19 +302,29 @@ internal sealed partial class SyntaxTreeIndex return; } - // complex type + // complex method if (targetTypeName == null) { complexInfoBuilder.Add(declaredSymbolInfoIndex); return; } + // Target type is an alias if (aliases.TryGetValue(targetTypeName, out var originalName)) { + // it is an alias of multiple with identical name, + // simply treat it as a complex method. + if (originalName == null) + { + complexInfoBuilder.Add(declaredSymbolInfoIndex); + return; + } + + // replace the alias with its original name. targetTypeName = originalName; } - // simple type + // So we've got a simple method. if (!simpleInfoBuilder.TryGetValue(targetTypeName, out var arrayBuilder)) { arrayBuilder = ArrayBuilder.GetInstance(); -- GitLab