diff --git a/src/Compilers/Core/Portable/DocumentationCommentId.cs b/src/Compilers/Core/Portable/DocumentationCommentId.cs index d55c826c4331b40140c506e5faa751ad6cd312c1..2c065e706ebfb6770e4547bf559a8b34d702c378 100644 --- a/src/Compilers/Core/Portable/DocumentationCommentId.cs +++ b/src/Compilers/Core/Portable/DocumentationCommentId.cs @@ -265,6 +265,39 @@ private static string EncodeName(string name) return name; } + private static string EncodePropertyName(string name) + { + // convert C# indexer names to 'Item' + if (name == "this[]") + { + name = "Item"; + } + else if (name.EndsWith(".this[]")) + { + name = name.Substring(0, name.Length - 6) + "Item"; + } + + return name; + } + + private static string DecodePropertyName(string name, string language) + { + // special case, csharp names indexers 'this[]', not 'Item' + if (language == LanguageNames.CSharp) + { + if (name == "Item") + { + name = "this[]"; + } + else if (name.EndsWith(".Item")) + { + name = name.Substring(0, name.Length - 4) + "this[]"; + } + } + + return name; + } + private class DeclarationGenerator : SymbolVisitor { private readonly StringBuilder _builder; @@ -371,14 +404,10 @@ public override bool VisitProperty(IPropertySymbol symbol) _builder.Append("."); } - if (symbol.Name == "this[]") - { - _builder.Append("Item"); - } - else - { - _builder.Append(EncodeName(symbol.Name)); - } + var name = EncodePropertyName(symbol.Name); + _builder.Append(EncodeName(name)); + + AppendParameters(symbol.Parameters); return true; } @@ -397,19 +426,32 @@ public override bool VisitMethod(IMethodSymbol symbol) _builder.Append(symbol.TypeParameters.Length); } - if (symbol.Parameters.Length > 0) + AppendParameters(symbol.Parameters); + + if (!symbol.ReturnsVoid) + { + _builder.Append("~"); + this.GetReferenceGenerator(symbol).Visit(symbol.ReturnType); + } + + return true; + } + + private void AppendParameters(ImmutableArray parameters) + { + if (parameters.Length > 0) { _builder.Append("("); - for (int i = 0, n = symbol.Parameters.Length; i < n; i++) + for (int i = 0, n = parameters.Length; i < n; i++) { if (i > 0) { _builder.Append(","); } - var p = symbol.Parameters[i]; - this.GetReferenceGenerator(symbol).Visit(p.Type); + var p = parameters[i]; + this.GetReferenceGenerator(p.ContainingSymbol).Visit(p.Type); if (p.RefKind != RefKind.None) { _builder.Append("@"); @@ -418,14 +460,6 @@ public override bool VisitMethod(IMethodSymbol symbol) _builder.Append(")"); } - - if (!symbol.ReturnsVoid) - { - _builder.Append("~"); - this.GetReferenceGenerator(symbol).Visit(symbol.ReturnType); - } - - return true; } public override bool VisitNamespace(INamespaceSymbol symbol) @@ -1218,13 +1252,7 @@ private static void GetMatchingProperties(string id, ref int index, List m.Kind == SymbolKind.Method); + var property = typeC.GetMembers().First(m => m.Kind == SymbolKind.Property); var editor = SymbolEditor.Create(solution); - var newMethod = editor.EditOneDeclarationAsync(method, (e, d) => + var newProperty = editor.EditOneDeclarationAsync(property, (e, d) => { // nothing }); var typeI = (INamedTypeSymbol)GetSymbols(solution, "I").First(); - var imethod = typeI.GetMembers().First(m => m.Kind == SymbolKind.Method); + var iproperty = typeI.GetMembers().First(m => m.Kind == SymbolKind.Property); - var newIMethod = editor.EditOneDeclarationAsync(imethod, (e, d) => + var newIProperty = editor.EditOneDeclarationAsync(iproperty, (e, d) => { // nothing; }); diff --git a/src/Workspaces/CoreTest/UtilityTest/DocumentationCommentIdTests.cs b/src/Workspaces/CoreTest/UtilityTest/DocumentationCommentIdTests.cs index 25b8384ff4da65f7946d04d696e9f76cbb1bc8b0..cd3f2256141be9625d84543eb15713743b8c8be3 100644 --- a/src/Workspaces/CoreTest/UtilityTest/DocumentationCommentIdTests.cs +++ b/src/Workspaces/CoreTest/UtilityTest/DocumentationCommentIdTests.cs @@ -28,12 +28,23 @@ private void CheckDeclarationId(string expectedId, INamespaceOrTypeSymbol symbol Assert.Equal(symbol, sym); } - private void CheckDeclarationId(string expectedId, Compilation compilation, Func test) + private TSymbol CheckDeclarationId(string expectedId, Compilation compilation, Func test) where TSymbol : ISymbol { var symbol = DocumentationCommentId.GetFirstSymbolForDeclarationId(expectedId, compilation); Assert.Equal(true, symbol is TSymbol); Assert.Equal(true, test((TSymbol)symbol)); + + return (TSymbol)symbol; + } + + private void CheckDeclarationIdExact(string expectedId, Compilation compilation, Func test) + where TSymbol : ISymbol + { + var symbol = CheckDeclarationId(expectedId, compilation, test); + + var id = DocumentationCommentId.CreateDeclarationId(symbol); + Assert.Equal(expectedId, id); } private void CheckReferenceId(string expectedId, INamespaceOrTypeSymbol symbol, Compilation compilation) @@ -232,9 +243,9 @@ class Widget : IProcess } "); - CheckDeclarationId("P:Acme.Widget.Width", compilation, p => p.Name == "Width"); - CheckDeclarationId("P:Acme.Widget.Item(System.Int32)", compilation, p => p.Parameters.Length == 1); - CheckDeclarationId("P:Acme.Widget.Item(System.String,System.Int32)", compilation, p => p.Parameters.Length == 2); + CheckDeclarationIdExact("P:Acme.Widget.Width", compilation, p => p.Name == "Width"); + CheckDeclarationIdExact("P:Acme.Widget.Item(System.Int32)", compilation, p => p.Parameters.Length == 1); + CheckDeclarationIdExact("P:Acme.Widget.Item(System.String,System.Int32)", compilation, p => p.Parameters.Length == 2); } [Fact]