-
Notifications
You must be signed in to change notification settings - Fork 4k
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 reference finding for tuple fields and anonymous type properties #69804
base: main
Are you sure you want to change the base?
Conversation
...s/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SemanticFacts/CSharpSemanticFacts.cs
Outdated
Show resolved
Hide resolved
...s/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SemanticFacts/CSharpSemanticFacts.cs
Outdated
Show resolved
Hide resolved
...s/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SemanticFacts/CSharpSemanticFacts.cs
Outdated
Show resolved
Hide resolved
...s/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SemanticFacts/CSharpSemanticFacts.cs
Outdated
Show resolved
Hide resolved
void M(int x, int y) | ||
{ | ||
var t = ($$[|{|Definition:x|}|]: x, y: y); | ||
t = ([|x|]: y, y: x); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test of x:x
as well please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
x: x
is included above, it's the definition, do you also want a test that doesn't involve the definition itself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add test where there is also an implicit name. i.e. (x, ...)
...s/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SemanticFacts/CSharpSemanticFacts.cs
Outdated
Show resolved
Hide resolved
{ | ||
int length = [|a|].Length; | ||
var r = new { [|a|], Length = 1 }; | ||
r = new { $$[|a|], [|a|].Length }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add an example where there is a named-arg for 'a'. like new { a = "", ...}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add test where the $$ is on the defintion. add test where $$ is on the a
in new { a = "", ...
src/EditorFeatures/Test2/FindReferences/FindReferencesTests.AnonymousTypeSymbols.vb
Outdated
Show resolved
Hide resolved
src/EditorFeatures/Test2/FindReferences/FindReferencesTests.Tuples.vb
Outdated
Show resolved
Hide resolved
} | ||
]]> | ||
</Document> | ||
</Project> | ||
</Workspace> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm finding the tests hard to totally understand because they don't show both implicit and explicit named-props in anonymous-types, and implicit and explicit arguments for tuples.
...s/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SemanticFacts/CSharpSemanticFacts.cs
Outdated
Show resolved
Hide resolved
// Skip the tuple expression if the identifier is part of the simple identifier expression inside a tuple, | ||
// but not the identifier of the field | ||
// For example, we are evaluating `x` in `(x, y)`, or the expression after the colon in `(x: x, y: y)` | ||
// but not the name of the field |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this doesn't explain the 'why' this is important.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added comment ptal
case IPropertySymbol { ContainingType: ITypeSymbol { IsAnonymousType: true } }: | ||
{ | ||
// If the span is part of the property's assignment expression, it's not our target result | ||
// For example, we are evaluating `a.Length` in `new { a.Length }`, or in `new { Length = a.Length }` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this doesn't say 'why' though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added comment ptal
@CyrusNajmabadi ptal, I'll check the failing checks soon |
protected static async ValueTask DiscoverImpliedSymbolsAsync( | ||
TSymbol symbol, Solution solution, ArrayBuilder<ISymbol> symbolBuilder, CancellationToken cancellationToken) | ||
{ | ||
var name = symbol.Name; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this whole method needs comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added comments ptal
Fixes #24268
Fixes #52621
Related issues:
#20115
Summary
The symbol that is bound to an expression that implies the decared tuple field is always the expression itself.
See the tests and the linked issues for examples.
Also discovered a bad case with anonymous type properties, where assigning an expression accessing a name equal to the property of the anonymous type would result in binding to that anonymous type property. For example:
Hovering over
Length
would show the propertyLength
of the anonymous type ofq
, and not that of the typestring
.Related
Rename is not tested currently.