Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue with nameof(MemberGroup) caused us to consider all members used #76335

Merged
merged 1 commit into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading