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

Add IOperation support for tuple expressions #20749

Merged
merged 10 commits into from
Jul 17, 2017

Conversation

mavasani
Copy link
Contributor

Fixes #10856

    public interface ITupleExpression : IOperation
    {
        /// <summary>
        /// Elements for tuple expression.
        /// </summary>
        ImmutableArray<IOperation> Elements { get; }
    }

mavasani added 3 commits May 18, 2017 15:05
Fixes dotnet#10856

```
    public interface ITupleExpression : IOperation
    {
        /// <summary>
        /// Elements for tuple expression.
        /// </summary>
        ImmutableArray<IOperation> Elements { get; }
    }
```
mavasani added 2 commits July 10, 2017 12:37
…e expression and parenting variable declaration so we test the operation tree for tuple conversions.
@mavasani
Copy link
Contributor Author

mavasani commented Jul 10, 2017

This PR is revival of #19636, with following extra changes:

  1. Added additional unit tests recommended by @AlekseyTs to test the IOperation tree binding for both the tuple expressions and its parent declaration so we test the tuple conversions.
  2. There seem to be lot of redundant IConversionExpression nodes generated for tuple conversions. I have opened a separate bug to track analyzing and fixing these: Do not expose redundant implicit identity conversion on top of tuple expressions and foreach collection #20756 #Resolved

@mavasani mavasani requested review from cston, jcouv and a team July 10, 2017 19:43
bool isInvalid = boundTupleExpression.HasErrors;
SyntaxNode syntax = boundTupleExpression.Syntax;
ITypeSymbol type = boundTupleExpression.Type;
Optional<object> constantValue = ConvertToOptional(boundTupleExpression.ConstantValue);
Copy link
Member

@jcouv jcouv Jul 11, 2017

Choose a reason for hiding this comment

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

Re-opening question from previous PR: tuples don't have constant values.
@CyrusNajmabadi prefered to keep as-is. But I don't see the benefit. #Resolved

Copy link
Member

@CyrusNajmabadi CyrusNajmabadi Jul 13, 2017

Choose a reason for hiding this comment

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

I'm fine making them not having constant values.

Copy link
Member

Choose a reason for hiding this comment

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

I'd still remove this logic. Tuples don't have constant values.


In reply to: 126766304 [](ancestors = 126766304)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, I have changed this to be initialized to default(Optional<object>)

{
static void Main()
{
/*<bind>*/(int A, int B) t = (1, 2)/*</bind>*/;
Copy link
Member

@jcouv jcouv Jul 11, 2017

Choose a reason for hiding this comment

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

All the tests involve literals (which get individually converted). I'd suggest also testing with typed expressions.

int a = 1;
int b = 2;
(long, long) t = (a, b);

I expect to see a tuple with type (int, int), which is converted to (long, long). I'm not sure how such tuple conversion is represented in IOperation. #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, will add tests.

ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1')
";
var expectedDiagnostics = new DiagnosticDescription[] {
// CS0266: Cannot implicitly convert type 'int' to 'uint'. An explicit conversion exists (are you missing a cast?)
Copy link
Member

@jcouv jcouv Jul 11, 2017

Choose a reason for hiding this comment

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

I don't think the diagnostics are interesting here. Consider x = 0; y = 0; in Deconstruct. Or simply throw null;. #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, done.

/// <summary>
/// Elements for tuple expression.
/// </summary>
ImmutableArray<IOperation> Elements { get; }
Copy link
Member

@jcouv jcouv Jul 11, 2017

Choose a reason for hiding this comment

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

This is a general comment beyond this PR, but I'm concerned about materializing more data structures to represent existing information. I would have expected IOperation to be much more "view-like". #Resolved

Copy link
Member

@CyrusNajmabadi CyrusNajmabadi Jul 13, 2017

Choose a reason for hiding this comment

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

It wsa an early decision we consciously made. There are negatives to the materialization approach, but it puts us in a good space in terms of defining the tree and getting a good test infrastructure in place for it. We can then optimize it later as necessary as an implementation detail. #Resolved

string expectedOperationTree = @"
IOperation: (OperationKind.None) (Syntax: '(uint x, ui ... Point(0, 1)')
Children(2): ITupleExpression (OperationKind.TupleExpression, Type: (System.UInt32 x, System.UInt32 y)) (Syntax: '(uint x, uint y)')
Elements(2): ILocalReferenceExpression: x (OperationKind.LocalReferenceExpression, Type: System.UInt32) (Syntax: 'uint x')
Copy link
Member

@jcouv jcouv Jul 11, 2017

Choose a reason for hiding this comment

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

Was there a discussion about how to represent declaration expressions in IOperation? I think the bound nodes have a flag to signify that those aren't just references to locals, but actually declaring locals. #Resolved

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 #20798 to bring this up in the next design meeting.

IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'C t = (0, n ... *</bind>*/;')
Variables: Local_1: C t
Initializer: IConversionExpression (ConversionKind.OperatorMethod, Implicit) (OperatorMethod: C C.op_Implicit((System.Int32, System.String) x)) (OperationKind.ConversionExpression, Type: C) (Syntax: '(0, null)')
IConversionExpression (ConversionKind.CSharp, Implicit) (OperationKind.ConversionExpression, Type: (System.Int32, System.String)) (Syntax: '(0, null)')
Copy link
Member

Choose a reason for hiding this comment

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

@VSadov, do we expect a conversion here?

}

[Fact, WorkItem(10856, "https://github.com/dotnet/roslyn/issues/10856")]
public void TupleExpression_Deconstruction()
Copy link
Member

@jcouv jcouv Jul 11, 2017

Choose a reason for hiding this comment

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

TupleExpression_Deconstruction [](start = 20, length = 30)

Consider adding a test for deconstruction-foreach: foreach (var (x, y) in new Point[] { new Point(0, 1) }) { ... } #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It seems like no IOperation is exposed for the deconstruction inside foreach, we just expose the IArrayCreationExpression on the right. I will file an issue to track this bug.

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 #20889

@jcouv
Copy link
Member

jcouv commented Jul 11, 2017

It would have been preferable to continue on the old PR, to maintain comment history.


In reply to: 314213234 [](ancestors = 314213234)

@mavasani
Copy link
Contributor Author

It would have been preferable to continue on the old PR, to maintain comment history.

Yes, but I had accidentally created my base branch for that PR on the dotnet upstream, instead of my own fork and GitHub didn't allow me to change the base fork on an existing PR.

}

/// <summary>
/// Represents a C# try or a VB Try statement.
Copy link
Member

Choose a reason for hiding this comment

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

tuple rather than try.

}

[Fact, WorkItem(10856, "https://github.com/dotnet/roslyn/issues/10856")]
public void TupleExpression_NamedElementsInTupleType_ParentVariableDeclaration()
Copy link
Member

@cston cston Jul 13, 2017

Choose a reason for hiding this comment

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

Do we need separate tests for initializer and _ParentVariableDeclaration in each case? Would one _ParentVariableDeclaration test be sufficient for declarations?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was explicitly requested by Aleksey in the original PR so that we test conversions.

End Sub

<Fact, WorkItem(10856, "https://github.com/dotnet/roslyn/issues/10856")>
Public Sub TupleExpression_ImplicitConversionFromNull_ParentVaraibleDeclaration()
Copy link
Member

Choose a reason for hiding this comment

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

Variable

@mavasani
Copy link
Contributor Author

@jcouv @cston addressed your feedback

@cston
Copy link
Member

cston commented Jul 14, 2017

LGTM

@mavasani
Copy link
Contributor Author

Ping any further feedback @jcouv?

I am going to resolve the merge conflicts and fix all the added unit tests due to dumper test change.

Copy link
Member

@jcouv jcouv 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 mavasani merged commit bd297ad into dotnet:features/ioperation Jul 17, 2017
@mavasani mavasani deleted the Tuples2 branch July 17, 2017 19:04
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.

6 participants