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

Introduce local variable supporting target-type new syntax #76342

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

MartyIX
Copy link
Contributor

@MartyIX MartyIX commented Dec 9, 2024

Our project uses target-type new syntax. Whenever, I have a line like this one:

int sum = Sum([|new Numbers()|]);

and I want to extract a new variable from the marked expression, I get

Numbers numbers = new Numbers();
int sum = Sum(numbers);

but I would like to get

Numbers numbers = new(); // i.e. `new()` here and not `new Numbers()`.
int sum = Sum(numbers);

That's why I created this PR. Are you interested in such feature?1 Could you give me some pointers how to finish this PR (as it does not work at the moment)?

Footnotes

  1. I sure am as I hit this daily. :)

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead labels Dec 9, 2024
@dotnet-policy-service dotnet-policy-service bot added Community The pull request was submitted by a contributor who is not a Microsoft employee. VSCode labels Dec 9, 2024
@@ -54,7 +55,7 @@ protected override Document IntroduceLocal(
[VariableDeclarator(
newLocalNameToken.WithAdditionalAnnotations(RenameAnnotation.Create()),
argumentList: null,
EqualsValueClause(expression.WithoutTrivia()))]));
EqualsValueClause(expression.WithAdditionalAnnotations(Simplifier.Annotation)).WithoutTrivia())]));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there any chance that this might work? It does not but I'm not exactly sure why it doesn't. I thought it might.

Copy link
Member

Choose a reason for hiding this comment

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

i would not use the simplifier annotation. I would just generate the right expected results based ont he user's options specified.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I took the time to debug TestIntroduceLocalInExpressionBodiedIndexer. It is my understanding that var in that test (instead of explicit type name) is added in a postprocessing step. However, that postprocessing is not able to convert it to "target-type form".

So then your suggestion is a reasonably easy solution here.

@CyrusNajmabadi
Copy link
Member

Happy to help with this. And we would accept a PR for this as logn as the the following holds:

  1. if the user has 'prefer var when apparent/elsewhere' we should generate var numbers = new Numbers();
  2. if the user does not have those options on, but does have csharp_style_implicit_object_creation_when_type_is_apparent, then we should do Numbers numbers = new();
  3. otherwise, we should generate Numbers numbers = new Numbers();

If you can confirm this is the logic the PR maintains,a nd you have tests for this, i can review asap. I can also review any questions blocking you if you call them out. Thanks!

@CyrusNajmabadi CyrusNajmabadi self-assigned this Dec 9, 2024
@MartyIX
Copy link
Contributor Author

MartyIX commented Dec 9, 2024

Yes, that's I would like to achieve.

I added a few comments to specific lines of code where some help would be great

@MartyIX MartyIX force-pushed the feature/2024-12-09-TargetTypeNew-for-IntroduceLocalVariable branch from b01eca3 to 12a96b8 Compare December 22, 2024 20:13
@MartyIX MartyIX changed the title [wip] Introduce local variable supporting target-type new syntax Introduce local variable supporting target-type new syntax Dec 22, 2024
@MartyIX MartyIX marked this pull request as ready for review December 22, 2024 20:16
@MartyIX MartyIX requested a review from a team as a code owner December 22, 2024 20:16
@CyrusNajmabadi
Copy link
Member

FYI, it's vacation time. So things may be slow to respond. Feel free to ping me on jan2 if you haven't heard from anyone else!

@MartyIX MartyIX force-pushed the feature/2024-12-09-TargetTypeNew-for-IntroduceLocalVariable branch from 12a96b8 to 42634bd Compare December 22, 2024 20:38
@MartyIX
Copy link
Contributor Author

MartyIX commented Dec 22, 2024

FYI, it's vacation time. So things may be slow to respond. Feel free to ping me on jan2 if you haven't heard from anyone else!

Thank you for the heads up. It would be great if at least tests could be run for the PR, I would get some feedback. If not, no problem, I can wait.

Merry Christmas!

@CyrusNajmabadi
Copy link
Member

It would be great if at least tests could be run for the PR

Tears will automatically run for you pr as long as it builds successfully :-)

@MartyIX
Copy link
Contributor Author

MartyIX commented Dec 23, 2024

Hm, I'm not too sure what that CI error

Caught exception querying ADO for test runs: System.InvalidOperationException: Sequence contains more than one matching element
   at System.Linq.ThrowHelper.ThrowMoreThanOneMatchException()
   at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source, Func`2 predicate, Boolean& found)
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at RunTests.TestHistoryManager.GetRunForStageAsync(Build build, String phaseName, TestResultsHttpClient testClient, CancellationToken cancellationToken) in /_/src/Tools/Source/RunTests/TestHistoryManager.cs:line 177
Unable to get a run with name Test_Windows_CoreClr_Debug from build https://dev.azure.com/dnceng-public/cbb18261-c48f-4abb-8651-8cdcb5474649/_apis/build/Builds/900968.

is about.

var updatedExpression = expression.WithoutTrivia();

if (options.SimplifierOptions is CSharpSimplifierOptions csOptions && csOptions.ImplicitObjectCreationWhenTypeIsApparent.Value
&& csOptions.GetUseVarPreference() == UseVarPreference.None)
Copy link
Member

Choose a reason for hiding this comment

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

needs docs explaining what is going on.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I documented my approach. It is a really conservative one (either target-type new syntax is used exclusively, or codebase opts into using "var" in any case). My reasoning is as follows:

  • It's a very conservative change, so it should not introduce some unwanted behavior.
  • It's hard for me to tell what codebases in the wild actually use and want (i.e., how complex the implementation should be), so I basically wanted to cover my use-case because I understand it well (and hopefully, it's what other customers will like).
  • With my PR, it should be easy to add missing cases, if people actually want it.

That being said, I'm certainly open to modify it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it is what #76342 (comment) mentions.

@CyrusNajmabadi
Copy link
Member

@dotnet/roslyn-infrastructure can someone help this community member with their PR? something has gone wonky with the test machines. Thanks!

@MartyIX
Copy link
Contributor Author

MartyIX commented Dec 23, 2024

@dotnet/roslyn-infrastructure can someone help this community member with their PR? something has gone wonky with the test machines. Thanks!

Perhaps it was my fault. I fixed a few failing tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-IDE Community The pull request was submitted by a contributor who is not a Microsoft employee. untriaged Issues and PRs which have not yet been triaged by a lead VSCode
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants