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

IInvocationExpression and IArgument refinement and testing #11450

Closed
wants to merge 24 commits into from

Conversation

msJohnHamby
Copy link
Contributor

This change set removes syntactic concerns from IInvocationExpression and IArgument. Specifically, the ArgumentsInSourceOrder property of IInvocationExpression has been replaced with ArgumentsInEvaluationOrder, and the ArgumentKind property of IArgument has been removed.

Those interested only in the API surface are can confine their attention to changes to the IExpression.cs file.

This change set also includes new tests to cover the surface areas of these interfaces for a variety of circumstances, along with a set of bug fixes to make the tests pass.

This change set does not includes fixes for all previously-reported issues related to invocations. For example, there are still some problems with matching array arguments to paramarray parameters, and the reported issues remain open for the time being.

@dotnet/roslyn-compiler @dotnet/roslyn-analysis @AlekseyTs @jcouv @genlu @jaredpar @DustinCampbell @nguerrera @srivatsn @gafter @mattwar @CyrusNajmabadi @mavasani @ManishJayaswal and anyone else eager to read 1600 lines of new tests are requested to review.

/// </summary>
ImmutableArray<IArgument> ArgumentsInSourceOrder { get; }
ImmutableArray<IArgument> ArgumentsInEvaluationOrder { get; }
Copy link
Contributor

Choose a reason for hiding this comment

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

Why isn't this on IHasArgumentsExpression?

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 should be.

@nguerrera
Copy link
Contributor

API change looks good. (I didn't review the tests.)

Now that you have the hood up on argument handling, it might be a good time to look into vararg (__arglist) handling. See #8394.

@msJohnHamby
Copy link
Contributor Author

I have pushed a commit that moves ArgumentsInEvaluationOrder from IInvocationExpresion to IHasArgumentsExpression. Tests for the additional cases in other interfaces derived from IHasArgumentsExpression will be added later in the test wave when those interfaces receive exhaustive testing.

@msJohnHamby
Copy link
Contributor Author

retest windows_debug_unit32_prtest please

@msJohnHamby
Copy link
Contributor Author

retest windows_debug_unit64_prtest please

@msJohnHamby
Copy link
Contributor Author

retest windows_debug_unit32_prtest please
retest windows_debug_unit64_prtest please
retest windows_eta_open_prtest please

@msJohnHamby
Copy link
Contributor Author

Adding @VSadov @cston in hopes of attracting compiler team members.

@genlu
Copy link
Member

genlu commented May 20, 2016

    private abstract class ArgumentBase : IArgument

I think ArgumentBase is not used anywhere else, maybe merge Argument and ArgumentBase into one concrete type instead.


Refers to: src/Compilers/CSharp/Portable/BoundTree/Expression.cs:240 in 4e5617e. [](commit_id = 4e5617e, deletion_comment = False)

@msJohnHamby
Copy link
Contributor Author

I've pushed a new commit that removes the ArgumentBase class.

@@ -83,7 +67,7 @@ public override void Accept(OperationVisitor visitor)
return visitor.VisitInvocationExpression(this, argument);
}

internal static ImmutableArray<IArgument> DeriveArguments(ImmutableArray<BoundExpression> boundArguments, ImmutableArray<string> argumentNames, ImmutableArray<int> argumentsToParameters, ImmutableArray<RefKind> argumentRefKinds, ImmutableArray<Symbols.ParameterSymbol> parameters, SyntaxNode invocationSyntax)
internal static ImmutableArray<IArgument> DeriveArgumentsInParameterOrder(ImmutableArray<BoundExpression> boundArguments, ImmutableArray<string> argumentNames, ImmutableArray<int> argumentsToParameters, ImmutableArray<RefKind> argumentRefKinds, ImmutableArray<Symbols.ParameterSymbol> parameters, SyntaxNode invocationSyntax)
Copy link
Member

@genlu genlu May 20, 2016

Choose a reason for hiding this comment

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

Consider moving DeriveArgumentsInParameterOrder and DeriveArgumentsInEvaluationOrder both to Expression class at the end of this file, since they are called by indexer and object creation as well.

{
int x = 10;
int y;
F(ref x, out y);
Copy link
Member

Choose a reason for hiding this comment

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

It seems this is also valid:

F(yy: out y, xx: ref x);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added tests for named out and reference arguments.

@AlekseyTs
Copy link
Contributor

AlekseyTs commented May 23, 2016

                ' Apparently the VB bound trees don't encode named arguments, which seems unnecesarily lossy.

Consider removing this comment as argument names in VB do not affect the order of evaluation. Evaluation is performed in parameter declaration order.


Refers to: src/Compilers/VisualBasic/Portable/BoundTree/Expression.vb:375 in 4a94d83. [](commit_id = 4a94d83, deletion_comment = False)

@@ -379,9 +377,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
argument,
Function(argumentValue)
If index >= parameters.Length - 1 AndAlso parameters.Length > 0 AndAlso parameters(parameters.Length - 1).IsParamArray Then
Copy link
Contributor

Choose a reason for hiding this comment

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

I do not understand why this conditional logic is needed.

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 logic probably isn't needed. It's left over from before I discovered that the VB bound trees already include paramarray matching. I deleted the If statement and no tests failed.

@msJohnHamby
Copy link
Contributor Author

I will take care of fixing up TestOperationWalker.

@msJohnHamby
Copy link
Contributor Author

The commit just pushed is for purposes of backing up work in progress. The change set is not yet ready for further review.

@CyrusNajmabadi
Copy link
Member

Why was ArgumentKind removed? It seems super useful.

@msJohnHamby
Copy link
Contributor Author

ArgumentKind is removed because:

  1. It's a syntactic concept, not a semantic concept.
  2. The VB implementation would have been difficult to make correct, because the VB compiler does not presently preserve information like named arguments and paramarray arguments in the bound trees. Rummaging through the syntax trees to try to reconstruct the original form wasn't appealing.

@CyrusNajmabadi
Copy link
Member

It's a syntactic concept, not a semantic concept.

This is unfortunate. Right now it's a bit hard for me to tell what the design around IOperation should be. Right now it seems very oriented at exposing bound nodes. And that's def a good thing. However, at the same time it serves as a great way of providing a language neutral way of viewing C# and VB code.

For many IDE features we'd like to use IOperation as a mechanism to allow us to write features without having to have duplicated logic for VB and C# to perform the same syntactic check. IOperation has provided us with that neutral introspection API. For example, PopulateSwitch is written without any C# of VB specific code at all: https://github.com/dotnet/roslyn/blob/master/src/Features/Core/Portable/PopulateSwitch/PopulateSwitchCodeFixProvider.cs

These two designs end up causing tension though. There are things that VB and C# syntactically share which IOperation still does not necessarily represent. While i see the benefit of just exposing the BoundNode data, i would still very much like it if we can push things further and allow this to be the language neutral way of operating over VB and C#.

So, for something like IArgument, having hte ArgumentKind is very nice. It's true that it's a syntactic concept. But, at the same time, it's common to C# and VB and otherwise requires duplicated code in a feature to ask the exact same for each language.

@msJohnHamby
Copy link
Contributor Author

Wow. I love the PopulateSwitch example, and would very much like to make more things like this possible.

Certainly I think ArgumentKind would be useful, else it wouldn't have been part of the original concept. If VB made supporting it easy I probably wouldn't be pushing to remove it.

Having a part of the API that is not supported correctly in VB is not tenable, and getting the VB implementation correct would require time that I don't have. (Anyone else want to take a whack at it?) The whole IOperation feature is under severe time pressure to meet correctness requirements. We can restore ArgumentKind to the API when there is time to implement it correctly in all supported languages.

@CyrusNajmabadi
Copy link
Member

The whole IOperation feature is under severe time pressure to meet correctness requirements.

Is it an option to spend more time on this, and release as a more stable API later? I'd rather spend more up front time on this than rush something through.

@msJohnHamby
Copy link
Contributor Author

The commit I just pushed will cause this PR to fail to build--I pushed the commit to save some work in progress.

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.

9 participants