提交 76248c5b 编写于 作者: M Matt Warren

Merge pull request #2719 from mattwar/Bug2650

Add support for explicit interface members in DocumentCommentId
...@@ -265,6 +265,39 @@ private static string EncodeName(string name) ...@@ -265,6 +265,39 @@ private static string EncodeName(string name)
return 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 class DeclarationGenerator : SymbolVisitor
{ {
private readonly StringBuilder _builder; private readonly StringBuilder _builder;
...@@ -371,14 +404,10 @@ public override bool VisitProperty(IPropertySymbol symbol) ...@@ -371,14 +404,10 @@ public override bool VisitProperty(IPropertySymbol symbol)
_builder.Append("."); _builder.Append(".");
} }
if (symbol.Name == "this[]") var name = EncodePropertyName(symbol.Name);
{ _builder.Append(EncodeName(name));
_builder.Append("Item");
} AppendParameters(symbol.Parameters);
else
{
_builder.Append(EncodeName(symbol.Name));
}
return true; return true;
} }
...@@ -397,19 +426,32 @@ public override bool VisitMethod(IMethodSymbol symbol) ...@@ -397,19 +426,32 @@ public override bool VisitMethod(IMethodSymbol symbol)
_builder.Append(symbol.TypeParameters.Length); _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<IParameterSymbol> parameters)
{
if (parameters.Length > 0)
{ {
_builder.Append("("); _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) if (i > 0)
{ {
_builder.Append(","); _builder.Append(",");
} }
var p = symbol.Parameters[i]; var p = parameters[i];
this.GetReferenceGenerator(symbol).Visit(p.Type); this.GetReferenceGenerator(p.ContainingSymbol).Visit(p.Type);
if (p.RefKind != RefKind.None) if (p.RefKind != RefKind.None)
{ {
_builder.Append("@"); _builder.Append("@");
...@@ -418,14 +460,6 @@ public override bool VisitMethod(IMethodSymbol symbol) ...@@ -418,14 +460,6 @@ public override bool VisitMethod(IMethodSymbol symbol)
_builder.Append(")"); _builder.Append(")");
} }
if (!symbol.ReturnsVoid)
{
_builder.Append("~");
this.GetReferenceGenerator(symbol).Visit(symbol.ReturnType);
}
return true;
} }
public override bool VisitNamespace(INamespaceSymbol symbol) public override bool VisitNamespace(INamespaceSymbol symbol)
...@@ -1218,13 +1252,7 @@ private static void GetMatchingProperties(string id, ref int index, List<INamesp ...@@ -1218,13 +1252,7 @@ private static void GetMatchingProperties(string id, ref int index, List<INamesp
{ {
for (int i = 0, n = containers.Count; i < n; i++) for (int i = 0, n = containers.Count; i < n; i++)
{ {
// special case, csharp names indexers 'this[]', not 'Item' memberName = DecodePropertyName(memberName, compilation.Language);
if (memberName == "Item"
&& compilation.Language == LanguageNames.CSharp)
{
memberName = "this[]";
}
var members = containers[i].GetMembers(memberName); var members = containers[i].GetMembers(memberName);
foreach (var symbol in members) foreach (var symbol in members)
......
...@@ -196,8 +196,8 @@ public string Name ...@@ -196,8 +196,8 @@ public string Name
VerifyCSharpFix(code, expectedFixedCode); VerifyCSharpFix(code, expectedFixedCode);
} }
[WorkItem(2650, "https://github.com/dotnet/roslyn/issues/2650")] [WorkItem(2616, "https://github.com/dotnet/roslyn/issues/2616")]
[Fact(Skip = "2650"), Trait(Traits.Feature, Traits.Features.Diagnostics)] [Fact(Skip ="2616"), Trait(Traits.Feature, Traits.Features.Diagnostics)]
public void CA1033SimpleDiagnosticCasesCSharp_Indexer() public void CA1033SimpleDiagnosticCasesCSharp_Indexer()
{ {
var code = @" var code = @"
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Formatting;
...@@ -999,5 +1001,46 @@ public void TestSetBaseType_Null_UnknownBase() ...@@ -999,5 +1001,46 @@ public void TestSetBaseType_Null_UnknownBase()
var actual = GetActual(editor.GetChangedDocuments().First()); var actual = GetActual(editor.GetChangedDocuments().First());
Assert.Equal(expected, actual); Assert.Equal(expected, actual);
} }
[Fact]
[WorkItem(2650, "https://github.com/dotnet/roslyn/issues/2650")]
public void TestEditExplicitInterfaceIndexer()
{
var code =
@"public interface I
{
int this[int item] { get; }
}
public class C : I
{
int I.this[int item]
{
get
{
return item;
}
}
}";
var solution = GetSolution(code);
var typeC = (INamedTypeSymbol)GetSymbols(solution, "C").First();
var property = typeC.GetMembers().First(m => m.Kind == SymbolKind.Property);
var editor = SymbolEditor.Create(solution);
var newProperty = editor.EditOneDeclarationAsync(property, (e, d) =>
{
// nothing
});
var typeI = (INamedTypeSymbol)GetSymbols(solution, "I").First();
var iproperty = typeI.GetMembers().First(m => m.Kind == SymbolKind.Property);
var newIProperty = editor.EditOneDeclarationAsync(iproperty, (e, d) =>
{
// nothing;
});
}
} }
} }
...@@ -28,12 +28,23 @@ private void CheckDeclarationId(string expectedId, INamespaceOrTypeSymbol symbol ...@@ -28,12 +28,23 @@ private void CheckDeclarationId(string expectedId, INamespaceOrTypeSymbol symbol
Assert.Equal(symbol, sym); Assert.Equal(symbol, sym);
} }
private void CheckDeclarationId<TSymbol>(string expectedId, Compilation compilation, Func<TSymbol, bool> test) private TSymbol CheckDeclarationId<TSymbol>(string expectedId, Compilation compilation, Func<TSymbol, bool> test)
where TSymbol : ISymbol where TSymbol : ISymbol
{ {
var symbol = DocumentationCommentId.GetFirstSymbolForDeclarationId(expectedId, compilation); var symbol = DocumentationCommentId.GetFirstSymbolForDeclarationId(expectedId, compilation);
Assert.Equal(true, symbol is TSymbol); Assert.Equal(true, symbol is TSymbol);
Assert.Equal(true, test((TSymbol)symbol)); Assert.Equal(true, test((TSymbol)symbol));
return (TSymbol)symbol;
}
private void CheckDeclarationIdExact<TSymbol>(string expectedId, Compilation compilation, Func<TSymbol, bool> 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) private void CheckReferenceId(string expectedId, INamespaceOrTypeSymbol symbol, Compilation compilation)
...@@ -232,9 +243,9 @@ class Widget : IProcess ...@@ -232,9 +243,9 @@ class Widget : IProcess
} }
"); ");
CheckDeclarationId<IPropertySymbol>("P:Acme.Widget.Width", compilation, p => p.Name == "Width"); CheckDeclarationIdExact<IPropertySymbol>("P:Acme.Widget.Width", compilation, p => p.Name == "Width");
CheckDeclarationId<IPropertySymbol>("P:Acme.Widget.Item(System.Int32)", compilation, p => p.Parameters.Length == 1); CheckDeclarationIdExact<IPropertySymbol>("P:Acme.Widget.Item(System.Int32)", compilation, p => p.Parameters.Length == 1);
CheckDeclarationId<IPropertySymbol>("P:Acme.Widget.Item(System.String,System.Int32)", compilation, p => p.Parameters.Length == 2); CheckDeclarationIdExact<IPropertySymbol>("P:Acme.Widget.Item(System.String,System.Int32)", compilation, p => p.Parameters.Length == 2);
} }
[Fact] [Fact]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册