提交 65d4fca1 编写于 作者: D David Poeschl

Don't allow rename on the well-known ValueTuple types

Fixes #14159

The well-known ValueTuple types are very special in that you can ask for
the SymbolInfo on the ValueTuple token and not get back the ValueTuple
type. This means that the token we invoke rename on has no locations,
which Rename Tracking mistakenly interpreted as being okay to rename.
This has been fixed, and also the RenameUtilities.GetTokenRenameInfo
method has been updated to return NoSymbolsTokenInfo when it finds an
ITypeSymbol with IsTupleType.
上级 54fdc858
......@@ -194,7 +194,7 @@ private async Task<TriggerIdentifierKind> DetermineIfRenamableSymbolsAsync(IEnum
// Get the source symbol if possible
var sourceSymbol = await SymbolFinder.FindSourceDefinitionAsync(symbol, document.Project.Solution, _cancellationToken).ConfigureAwait(false) ?? symbol;
if (!sourceSymbol.Locations.All(loc => loc.IsInSource))
if (!sourceSymbol.IsFromSource())
{
return TriggerIdentifierKind.NotRenamable;
}
......@@ -217,7 +217,7 @@ private async Task<TriggerIdentifierKind> DetermineIfRenamableSymbolAsync(ISymbo
return TriggerIdentifierKind.NotRenamable;
}
if (!sourceSymbol.Locations.All(loc => loc.IsInSource))
if (!sourceSymbol.IsFromSource())
{
return TriggerIdentifierKind.NotRenamable;
}
......
......@@ -1478,5 +1478,72 @@ End Sub
await state.AssertNoTag();
}
}
[WpfFact]
[Trait(Traits.Feature, Traits.Features.RenameTracking)]
[WorkItem(14159, "https://github.com/dotnet/roslyn/issues/14159")]
public async Task RenameTrackingNotOnWellKnownValueTupleType()
{
var workspaceXml = @"
<Workspace>
<Project Language=""C#"" CommonReferences=""true"" LanguageVersion=""7"">
<Document>
using System;
class C
{
void M()
{
var x = new ValueTuple$$&lt;int&gt;();
}
}
namespace System
{
public struct ValueTuple&lt;T1&gt;
{
public T1 Item1;
}
}
</Document>
</Project>
</Workspace>";
using (var state = await RenameTrackingTestState.CreateFromWorkspaceXmlAsync(workspaceXml, LanguageNames.CSharp))
{
state.EditorOperations.InsertText("2");
await state.AssertNoTag();
}
}
[WpfFact]
[Trait(Traits.Feature, Traits.Features.RenameTracking)]
[WorkItem(14159, "https://github.com/dotnet/roslyn/issues/14159")]
public async Task RenameTrackingOnThingsCalledValueTupleThatAreNotTheWellKnownType()
{
var workspaceXml = @"
<Workspace>
<Project Language=""C#"" CommonReferences=""true"" LanguageVersion=""7"">
<Document>
class C
{
void M()
{
var x = new ValueTuple$$&lt;int&gt;();
}
}
public struct ValueTuple&lt;T1&gt;
{
public T1 Item1;
}
</Document>
</Project>
</Workspace>";
using (var state = await RenameTrackingTestState.CreateFromWorkspaceXmlAsync(workspaceXml, LanguageNames.CSharp))
{
state.EditorOperations.InsertText("2");
await state.AssertTag("ValueTuple", "ValueTuple2");
}
}
}
}
......@@ -60,6 +60,19 @@ internal sealed class RenameTrackingTestState : IDisposable
return new RenameTrackingTestState(workspace, languageName, onBeforeGlobalSymbolRenamedReturnValue, onAfterGlobalSymbolRenamedReturnValue);
}
public static async Task<RenameTrackingTestState> CreateFromWorkspaceXmlAsync(
string workspaceXml,
string languageName,
bool onBeforeGlobalSymbolRenamedReturnValue = true,
bool onAfterGlobalSymbolRenamedReturnValue = true)
{
var workspace = await TestWorkspace.CreateAsync(
workspaceXml,
exportProvider: TestExportProvider.CreateExportProviderWithCSharpAndVisualBasic());
return new RenameTrackingTestState(workspace, languageName, onBeforeGlobalSymbolRenamedReturnValue, onAfterGlobalSymbolRenamedReturnValue);
}
public RenameTrackingTestState(
TestWorkspace workspace,
string languageName,
......
......@@ -122,6 +122,11 @@ private static bool ShouldRenameOnlyAffectDeclaringProject(ISymbol symbol)
var symbolInfo = semanticModel.GetSymbolInfo(token, cancellationToken);
if (symbolInfo.Symbol != null)
{
if (symbolInfo.Symbol.IsTupleType())
{
return TokenRenameInfo.NoSymbolsTokenInfo;
}
return TokenRenameInfo.CreateSingleSymbolTokenInfo(symbolInfo.Symbol);
}
......
......@@ -168,6 +168,11 @@ public static bool IsArrayType(this ISymbol symbol)
return symbol?.Kind == SymbolKind.ArrayType;
}
public static bool IsTupleType(this ISymbol symbol)
{
return (symbol as ITypeSymbol)?.IsTupleType ?? false;
}
public static bool IsAnonymousFunction(this ISymbol symbol)
{
return (symbol as IMethodSymbol)?.MethodKind == MethodKind.AnonymousFunction;
......@@ -819,6 +824,11 @@ public static bool IsEventAccessor(this ISymbol symbol)
method.MethodKind == MethodKind.EventRemove);
}
public static bool IsFromSource(this ISymbol symbol)
{
return symbol.Locations.Any() && symbol.Locations.All(location => location.IsInSource);
}
public static DeclarationModifiers GetSymbolModifiers(this ISymbol symbol)
{
return new DeclarationModifiers(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册