Skip to content

Commit

Permalink
Fix issue with nameof(MemberGroup) caused us to consider all members …
Browse files Browse the repository at this point in the history
…used (#76335)
  • Loading branch information
CyrusNajmabadi authored Dec 9, 2024
2 parents b437126 + 32e6565 commit ad54ee4
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1295,15 +1295,16 @@ class MyClass<T>
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31581")]
public async Task MethodInNameOf()
{
var code = """
class MyClass
{
private void M() { }
private string _goo = nameof(M);
}
""";

await VerifyCS.VerifyCodeFixAsync(code, code);
await new VerifyCS.Test
{
TestCode = """
class MyClass
{
private void M() { }
public string _goo = nameof(M);
}
""",
}.RunAsync();
}

[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33765")]
Expand Down Expand Up @@ -3368,4 +3369,85 @@ struct S
ReferenceAssemblies = ReferenceAssemblies.Net.Net90,
}.RunAsync();
}

[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/54972")]
public async Task TestNameof1()
{
await new VerifyCS.Test
{
TestCode = """
using System;
class Program
{
private int [|unused|];
static void Main(string[] args)
{
Console.WriteLine(nameof(Main));
}
}
""",
FixedCode = """
using System;
class Program
{
static void Main(string[] args)
{
Console.WriteLine(nameof(Main));
}
}
""",
LanguageVersion = LanguageVersion.CSharp13,
ReferenceAssemblies = ReferenceAssemblies.Net.Net90,
}.RunAsync();
}

[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/54972")]
public async Task TestNameof2()
{
await new VerifyCS.Test
{
TestCode = """
using System;
class Program
{
private int used;
static void Main(string[] args)
{
Console.WriteLine(nameof(used));
}
}
""",
LanguageVersion = LanguageVersion.CSharp13,
ReferenceAssemblies = ReferenceAssemblies.Net.Net90,
}.RunAsync();
}

[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/54972")]
public async Task TestNameof3()
{
await new VerifyCS.Test
{
TestCode = """
using System;
class Program
{
private void M() { }
private void M(int i) { }
static void Main(string[] args)
{
Console.WriteLine(nameof(M));
}
}
""",
LanguageVersion = LanguageVersion.CSharp13,
ReferenceAssemblies = ReferenceAssemblies.Net.Net90,
}.RunAsync();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,26 @@ private void RegisterActions(CompilationStartAnalysisContext compilationStartCon

var hasUnsupportedOperation = false;
symbolStartContext.RegisterOperationAction(
_ => hasUnsupportedOperation = true,
OperationKind.Invalid, OperationKind.None, OperationKind.DynamicIndexerAccess, OperationKind.DynamicInvocation, OperationKind.DynamicMemberReference, OperationKind.DynamicObjectCreation);
context =>
{
var operation = context.Operation;

// 'nameof(argument)' currently returns a 'None' operation for its argument. We don't want this
// to cause us to bail out of processing. Instead, we'll handle this case explicitly in AnalyzeNameOfOperation.
if (operation is { Kind: OperationKind.None, Parent: INameOfOperation { Argument: var nameofArgument } } &&
nameofArgument == operation)
{
return;
}

hasUnsupportedOperation = true;
},
OperationKind.Invalid,
OperationKind.None,
OperationKind.DynamicIndexerAccess,
OperationKind.DynamicInvocation,
OperationKind.DynamicMemberReference,
OperationKind.DynamicObjectCreation);

symbolStartContext.RegisterSymbolEndAction(symbolEndContext => OnSymbolEnd(symbolEndContext, hasUnsupportedOperation));

Expand Down Expand Up @@ -429,17 +447,7 @@ private void AnalyzeNameOfOperation(OperationAnalysisContext operationContext)
// a bound method group/property group.
var symbolInfo = nameofArgument.SemanticModel!.GetSymbolInfo(nameofArgument.Syntax, operationContext.CancellationToken);
foreach (var symbol in symbolInfo.GetAllSymbols())
{
switch (symbol.Kind)
{
// Handle potential references to methods/properties from missing IOperation
// for method group/property group.
case SymbolKind.Method:
case SymbolKind.Property:
OnSymbolUsage(symbol.OriginalDefinition, ValueUsageInfo.ReadWrite);
break;
}
}
OnSymbolUsage(symbol.OriginalDefinition, ValueUsageInfo.ReadWrite);
}

private void AnalyzeObjectCreationOperation(OperationAnalysisContext operationContext)
Expand Down

0 comments on commit ad54ee4

Please sign in to comment.