-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
IObjectCreationExpression API Change #19278
Conversation
There are couple of changes here: 1. API change: `ImmutableArray<ISymbolInitializer> MemberInitializers` is changed to `ImmutableArray<IOperation> Initializers`. 2. Implementation changes: 1. Instead of returning the member initializers as synthesized ISymbolInitializer nodes, we now return member intializers as IAssignmentExpression nodes. This ensures completeness of IOperation tree. 2. Now we also return the collection intializer expressions within an object creation expression. Fixes dotnet#18115 There are 2 bugs still affecting this area: 1. dotnet#18781: IOperation API shape for collection initializer expressions 2. dotnet#19276: Missing Field/Property reference expression nodes in object creation initializer node
Tagging @dotnet/analyzer-ioperation for review. |
Also tagging @AlekseyTs and @cston |
@@ -238,33 +238,48 @@ Friend Class [Class] | |||
Public Property C As [Class] | |||
|
|||
Public Sub M(x As Integer, y As Integer, z As Integer) | |||
Dim c = New [Class]() With {'BIND:"New [Class]() With {" | |||
Dim c = New [Class]() With {'BIND:"New [Class]() With {"'BIND:"New [Class]() With {'BIND:"New [Class]() With {"" |
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.
What are the extra 'BIND ...
comments for? #Pending
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.
Seems like they got left behind accidentally when I copied another existing test and modified it. There are few more tests with extra bind comments, I will clean them separately. #Closed
LGTM |
…s. I have filed dotnet#19300 to track the skipped tests
@dotnet-bot retest windows_debug_unit64_prtest please |
@AlekseyTs Can you take a look? Thanks. |
Member Initializers(1): IPropertyInitializer (Property: Property [Class].X As System.Int32) (OperationKind.PropertyInitializerInCreation) (Syntax: '.X = z') | ||
IParameterReferenceExpression: z (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'z') | ||
Initializers(4): IAssignmentExpression (OperationKind.AssignmentExpression, Type: System.Void) (Syntax: '.X = x') | ||
Left: IIndexedPropertyReferenceExpression: Property [Class].X As System.Int32 (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: '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.
Left: IIndexedPropertyReferenceExpression: Property [Class].X As System.Int32 (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'X') [](start = 6, length = 155)
It doesn't look like the property is an indexed property. The same issue is with other properties.
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, this is a bug that is already fixed in features/ioperation branch. I also updated the test in that branch accordingly: https://github.com/dotnet/roslyn/blob/features/ioperation/src/Compilers/VisualBasic/Test/Semantic/IOperation/IOperationTests_IParameterReferenceExpression.vb#L94
Initializers(4): IAssignmentExpression (OperationKind.AssignmentExpression, Type: System.Int32) (Syntax: 'X = x') | ||
Left: IOperation: (OperationKind.None) (Syntax: 'X') | ||
Right: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x') | ||
IAssignmentExpression (OperationKind.AssignmentExpression, Type: System.Collections.Generic.List<System.Int32>) (Syntax: 'Y = { x, y, 3 }') |
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.
IAssignmentExpression (OperationKind.AssignmentExpression, Type: System.Collections.Generic.List<System.Int32>) (Syntax: 'Y = { x, y, 3 }') [](start = 4, length = 139)
This feels surprising. Does the assignment really happen in this scenario?
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.
Would you like me to file an issue or are you suggesting we not expose the IAssignmentExpression in the operation tree?
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 think opening an issue should be fine at this point.
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.
Filed #19375
|
||
namespace Microsoft.CodeAnalysis.CSharp.UnitTests | ||
{ | ||
public partial class IOperationTests : SemanticModelTestBase |
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.
IOperationTests [](start = 25, length = 15)
It looks like there are no tests for an initializer target in the form of an argument list.
initializer_target
: identifier
| '[' argument_list ']'
;
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, this PR is not meant to add complete set of tests for IObjectCreationExpression. I will add them later as part of unit testing effort #17588
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.
LGTM
Tagging @MattGertz for ask mode approval. |
…or an IOperation API change merged yesterday (dotnet#19278).
Customer scenario
All IOperation based analyzers will generate large number of false positives OR not analyze code within object and collection initializers. Given that such a code pattern is very common, this can be a dogfood blocker for IOperation analyzers (FXCop).
Bugs this fixes:
Fixes #18115
There are still 2 remaining bugs affecting this area:
Workarounds, if any
The analyzer users will have to either suppress all IOperation analyzers on methods containing object/collection initializers or disable these analyzers.
Risk
Low. We are just returning the operation nodes as they are in the bound tree rather than synthesizing new symbol initializer nodes.
Performance impact
None
Is this a regression from a previous update?
No, this was the original IOperation API implementation
Root cause analysis:
The underlying reason is that the current API shape of IObjectCreationExpression only exposes member initializers, not collection initializers.
There are couple of changes in this PR:
ImmutableArray<ISymbolInitializer> MemberInitializers
is changed toImmutableArray<IOperation> Initializers
as per design time decision.How was the bug found?
Dogfooding.