diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/XmlDocumentationCommentCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/XmlDocumentationCommentCompletionProviderTests.cs index 14e9986f91084448781d948a25549c32fe9a8218..438e90ec52c62932a1512778a100207a229b6700 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/XmlDocumentationCommentCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/XmlDocumentationCommentCompletionProviderTests.cs @@ -327,13 +327,16 @@ public class goo [Fact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task MethodParamTypeParam() { - await VerifyItemsExistAsync(@" -public class goo + var text = @" +public class goo { /// $$ - public int bar(T green) { } -}", "typeparam name=\"T\"", "param name=\"green\""); + public int bar(TBar green) { } +}"; + + await VerifyItemsExistAsync(text, "typeparam name=\"TBar\"", "param name=\"green\""); + await VerifyItemsAbsentAsync(text, "typeparam name=\"TGoo\""); } [Fact, Trait(Traits.Feature, Traits.Features.Completion)] @@ -348,18 +351,27 @@ public class goo }", "param name=\"green\""); } + [WorkItem(17872, "https://github.com/dotnet/roslyn/issues/17872")] [Fact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task MethodParamRefName() { - await VerifyItemsExistAsync(@" -public class goo + var text = @" +public class Outer { - - /// - /// $$ - /// - public int bar(T green) { } -}", "typeparamref name=\"T\"", "paramref name=\"green\""); + public class Inner + { + /// + /// $$ + /// + public int Method(T green) { } + } +}"; + await VerifyItemsExistAsync( + text, + "typeparamref name=\"TOuter\"", + "typeparamref name=\"TInner\"", + "typeparamref name=\"TMethod\"", + "paramref name=\"green\""); } [Fact, Trait(Traits.Feature, Traits.Features.Completion)] @@ -1172,28 +1184,42 @@ static void Goo(string str) ", "str"); } + [WorkItem(17872, "https://github.com/dotnet/roslyn/issues/17872")] [Fact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task TypeParamRefNames() { - await VerifyItemExistsAsync(@" -/// -/// -/// -static void Goo() + var text = @" +public class Outer { -} -", "T"); + public class Inner + { + /// + /// + /// + public int Method(T green) { } + } +}"; + + await VerifyItemsExistAsync(text, "TOuter", "TInner", "TMethod"); } - [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task TypeParamNames() { - await VerifyItemExistsAsync(@" -/// -static void Goo() + var text = @" +public class Outer { -} -", "T"); + public class Inner + { + /// + /// + /// + public int Method(T green) { } + } +}"; + + await VerifyItemsExistAsync(text, "TMethod"); + await VerifyItemsAbsentAsync(text, "TOuter", "TInner"); } [WorkItem(8322, "https://github.com/dotnet/roslyn/issues/8322")] diff --git a/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/XmlDocCommentCompletionProviderTests.vb b/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/XmlDocCommentCompletionProviderTests.vb index 3b802c35d4b8099714199d2ae2ca4a16a047e6c7..8d89cf8b4983708ff590ca68f35f3c69fdb3e7a6 100644 --- a/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/XmlDocCommentCompletionProviderTests.vb +++ b/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/XmlDocCommentCompletionProviderTests.vb @@ -112,19 +112,27 @@ End Class Await VerifyItemsExistAsync(text, "code", "list", "para") End Function + Public Async Function TestRepeatableNestedParamRefAndTypeParamRefTagsOnMethod() As Task Dim text = " -Class C - ''' - ''' <$$ - ''' - Sub Goo(Of T)(i as Integer) - End Sub +Class Outer(Of TOuter) + Class Inner(Of TInner) + ''' + ''' $$ + ''' + Sub Goo(Of TMethod)(i as Integer) + End Sub + End Class End Class " - Await VerifyItemsExistAsync(text, "paramref name=""i""", "typeparamref name=""T""") + Await VerifyItemsExistAsync( + text, + "paramref name=""i""", + "typeparamref name=""TOuter""", + "typeparamref name=""TInner""", + "typeparamref name=""TMethod""") End Function @@ -239,14 +247,15 @@ End Class Public Async Function TestMethodParamTypeParam() As Task Dim text = " -Class C(Of T) +Class C(Of TClass) ''' <$$ - Sub Goo(Of T)(bar as T) + Sub Goo(Of TMethod)(bar as TMethod) End Sub End Class " - Await VerifyItemsExistAsync(text, "param name=""bar""", "typeparam name=""T""") + Await VerifyItemsExistAsync(text, "param name=""bar""", "typeparam name=""TMethod""") + Await VerifyItemsAbsentAsync(text, "typeparam name=""TClass""") End Function @@ -799,28 +808,31 @@ End Class Public Async Function TestTypeParamNames() As Task Dim text = " -Class C +Class C(Of TClass) ''' Public Async Function TestTypeParamRefNames() As Task Dim text = " -Class C - ''' - ''' - Sub Goo(Of T)(i as Integer) - End Sub +Class Outer(Of TOuter) + Class Inner(Of TInner) + ''' + ''' + Sub Goo(Of TMethod)(i as Integer) + End Sub + End Class End Class " - Await VerifyItemsExistAsync(text, "T") + Await VerifyItemsExistAsync(text, "TOuter", "TInner", "TMethod") Await VerifyItemsAbsentAsync(text, "i") End Function diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractDocCommentCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractDocCommentCompletionProvider.cs index f251422753ca44ebd297a481d0b402ac64935d41..9a42d5994fa235cc2e7594df1412ad4ee60ff334 100644 --- a/src/Features/Core/Portable/Completion/Providers/AbstractDocCommentCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/AbstractDocCommentCompletionProvider.cs @@ -149,7 +149,7 @@ private IEnumerable GetParamRefItems(ISymbol symbol) private IEnumerable GetTypeParamRefItems(ISymbol symbol) { - var names = symbol.GetTypeParameters().Select(t => t.Name); + var names = symbol.GetAllTypeParameters().Select(t => t.Name); return names.Select(t => CreateCompletionItem( displayText: FormatParameter(TypeParameterReferenceElementName, t), @@ -166,11 +166,16 @@ protected IEnumerable GetAttributeValueItems(ISymbol symbol, str return symbol.GetParameters() .Select(parameter => CreateCompletionItem(parameter.Name)); } - else if (tagName == TypeParameterElementName || tagName == TypeParameterReferenceElementName) + else if (tagName == TypeParameterElementName) { return symbol.GetTypeParameters() .Select(typeParameter => CreateCompletionItem(typeParameter.Name)); } + else if (tagName == TypeParameterReferenceElementName) + { + return symbol.GetAllTypeParameters() + .Select(typeParameter => CreateCompletionItem(typeParameter.Name)); + } } else if (attributeName == LangwordAttributeName && tagName == SeeElementName) { diff --git a/src/Workspaces/Core/Portable/Shared/Extensions/ISymbolExtensions.cs b/src/Workspaces/Core/Portable/Shared/Extensions/ISymbolExtensions.cs index 99bbb66edd86443eda9ba951d3570f44dfa37656..9748383023ec4aced51cfbfedea0c3d8275cc540 100644 --- a/src/Workspaces/Core/Portable/Shared/Extensions/ISymbolExtensions.cs +++ b/src/Workspaces/Core/Portable/Shared/Extensions/ISymbolExtensions.cs @@ -425,6 +425,19 @@ public static ImmutableArray GetTypeParameters(this ISymbo } } + public static ImmutableArray GetAllTypeParameters(this ISymbol symbol) + { + var results = ArrayBuilder.GetInstance(); + + while (symbol != null) + { + results.AddRange(symbol.GetTypeParameters()); + symbol = symbol.ContainingType; + } + + return results.ToImmutableAndFree(); + } + public static ImmutableArray GetTypeArguments(this ISymbol symbol) { switch (symbol)