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

IObjectCreationExpression API Change #19278

Merged
merged 2 commits into from
May 9, 2017

Conversation

mavasani
Copy link
Contributor

@mavasani mavasani commented May 4, 2017

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:

  1. IOperation API shape for object and collection initializer expressions #18781: IOperation API shape for collection initializer expressions
  2. Missing Field/Property reference expression nodes in object creation initializer node #19276: Missing Field/Property reference expression nodes in object creation initializer node

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:

  1. API change: ImmutableArray<ISymbolInitializer> MemberInitializers is changed to ImmutableArray<IOperation> Initializers as per design time decision.
  2. Implementation changes:
    1. Instead of returning the member initializers as synthesized ISymbolInitializer nodes, we now return member initializers as IAssignmentExpression nodes. This ensures completeness of IOperation tree.
    2. Now we also return the collection initializer expressions within an object creation expression.

How was the bug found?

Dogfooding.

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
@mavasani
Copy link
Contributor Author

mavasani commented May 4, 2017

Tagging @dotnet/analyzer-ioperation for review.

@mavasani
Copy link
Contributor Author

mavasani commented May 4, 2017

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 {""
Copy link
Member

@cston cston May 5, 2017

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

Copy link
Contributor Author

@mavasani mavasani May 5, 2017

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

@cston
Copy link
Member

cston commented May 5, 2017

LGTM

@mavasani
Copy link
Contributor Author

mavasani commented May 5, 2017

@dotnet-bot retest windows_debug_unit64_prtest please

@mavasani
Copy link
Contributor Author

mavasani commented May 8, 2017

@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')
Copy link
Contributor

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.

Copy link
Contributor Author

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 }')
Copy link
Contributor

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?

Copy link
Contributor Author

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?

Copy link
Contributor

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.

Copy link
Contributor Author

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
Copy link
Contributor

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 ']'
;

Copy link
Contributor Author

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

Copy link
Contributor

@AlekseyTs AlekseyTs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@mavasani
Copy link
Contributor Author

mavasani commented May 9, 2017

Tagging @MattGertz for ask mode approval.

@mavasani mavasani merged commit c16e998 into dotnet:master May 9, 2017
mavasani added a commit to mavasani/roslyn that referenced this pull request May 10, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

IObjectCreationExpression API shape
6 participants