Skip to content

Fix IntroduceVariable when the textSpan is whitespace#28983

Merged
JoeRobich merged 1 commit intodotnet:masterfrom
JoeRobich:fix-introduce-variable-empty-span
Aug 2, 2018
Merged

Fix IntroduceVariable when the textSpan is whitespace#28983
JoeRobich merged 1 commit intodotnet:masterfrom
JoeRobich:fix-introduce-variable-empty-span

Conversation

@JoeRobich
Copy link
Copy Markdown
Member

@JoeRobich JoeRobich commented Jul 31, 2018

If the textSpan is a span of whitespace that is itself surrounded by
whitespace, trying to recover by getting the next token and creating a
new textSpan will result in a gold bar. This change prevents the gold bar by
checking the proposed newStart position and returning if it is past
the end position.

This fixes #27949 and fixes #28665.

@JoeRobich JoeRobich requested a review from a team as a code owner July 31, 2018 23:49
@dnfclas
Copy link
Copy Markdown

dnfclas commented Jul 31, 2018

CLA assistant check
All CLA requirements met.

Copy link
Copy Markdown
Contributor

@sharwell sharwell left a comment

Choose a reason for hiding this comment

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

Looks good but note the specific comments before merge

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Explanation of the scenario would be helpful

Additional trivia exists between 'textSpan' and the start of the next token, ...

Then, the ... might be replaced with something indicating why it's important:

... so the two are not considered adjacent

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done. thanks

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

❔ Out of curiosity, many of the new tests failed prior to the change?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

All four added tests were failing before the fix.

@dpoeschl
Copy link
Copy Markdown
Contributor

dpoeschl commented Aug 1, 2018

windows_debug_vs-integration_prtest failure is tracked by #29001, and the failing tests have no relation to this change whatsoever. I don't think we need to rerun the tests.

@JoeRobich JoeRobich force-pushed the fix-introduce-variable-empty-span branch 2 times, most recently from 697d176 to 13d2889 Compare August 1, 2018 22:46
Copy link
Copy Markdown
Contributor

@dpoeschl dpoeschl left a comment

Choose a reason for hiding this comment

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

In the description of the PR/commit, it says it causes a "crash", but it should just be showing the gold bar and letting VS continue, right? This verbiage can mislead management when deciding whether to accept a fix for a particular release (though in this case you're targeting master, which is open now, so it doesn't matter as much).

Overall, I believe this PR makes the world a better place with a targeted fix for the reported scenarios. I can't actually make the product crash or show the gold bar, so I wasn't able to try out other scenarios that may have been missed here and just haven't been reported yet (what if everything is in leading trivia instead of trailing trivia? etc.). @JoeRobich can you help me repro the failure?

I thought there might be a regression introduced in the service, but I've tested it and for some reason there's no regression there. I'm fine accepting a fix with this general approach.

But, I've played with this feature in the IDE, and I personally find it difficult to understand. It working or not depends on the details of where the span starts and ends, and whether they're exactly touching tokens, or if they're just a position versus a span, etc. This was written before we really discussed general guidelines for refactorings back in May (though I also don't think we ever published that document), and it takes the stricter approach (in an attempt to avoid light bulb pollution) instead of the guidelines more lenient approach (of making the refactoring Just Work as best as possible when even remotely reasonable). (Try various positions and spans in int x = 8 * 8 + 7 * 5; to see what I mean.) As a side effect, I find the existing code in this method hard to follow (at least in its current form without good comments).

We discussed the possibility of opportunistically fixing these up as we went along and encountered them. If that's what we want to do to chip away at the problem, this could be our chance.

@jinujoseph @kuhlenh What do you think?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If the textSpan.End and the newStart are equal, then there isn't trivia between the selection and the next token (so the comment isn't correct). I was worried this would introduce a regression in that case (non-empty selection that starts in whitespace and ends at the start of the next token), but that doesn't appear to work in the IDE currently either (I suspect due to some of the logic below that I don't immediately understand). I'll comment more on this in my overall review feedback.

Copy link
Copy Markdown
Contributor

@dpoeschl dpoeschl Aug 2, 2018

Choose a reason for hiding this comment

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

This comment only makes sense if you understand the first comment on line 200, track through how the tokens are discovered and mutated, and convince yourself that this is when the span is entirely in the trivia between two tokens (and not starting/ending in two different trivias) (unless there's any non-whitespace trivia in there for some reason??).

I actually like the explanation in your commit/PR description better since it's trying to describe the full thing (whitespace span surrounded by whitespace).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I haven't read the 9000 lines of pre-existing tests, but are there any with spans like this that also end touching the next token? e.g. x = [| |]0; I mentioned this case elsewhere, and I'm not sure if the behavior (no refactoring offered) is intentional or not.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also, are there test cases similar to this one where the span is in whitespace (just like this) but the leading token contains, additionally, a /**/ so that the check for all trivia being whitespace on line 198 of the service goes the opposite way?

@dpoeschl
Copy link
Copy Markdown
Contributor

dpoeschl commented Aug 2, 2018

Preserving the unit test failure URL in case tests get restarted: https://ci.dot.net/job/dotnet_roslyn/job/master/job/windows_debug_unit64_prtest/15567/
@JoeRobich Can you take a look? (I can help tomorrow if you'd like.)

@JoeRobich
Copy link
Copy Markdown
Member Author

@dpoeschl The failing unit test is the same one identified in this issue as being flaky. #28062

If the textSpan is a span of whitespace that is itself surrounded by
whitespace, trying to recover by getting the next token and creating a
new textSpan will result in a gold bar. This change prevents the gold
bar by checking the proposed newStart position and returning if it is
past the end position.

This fixes dotnet#27949 and fixes dotnet#28665.
@JoeRobich JoeRobich force-pushed the fix-introduce-variable-empty-span branch from 13d2889 to a4ba814 Compare August 2, 2018 19:38
Copy link
Copy Markdown
Contributor

@dpoeschl dpoeschl left a comment

Choose a reason for hiding this comment

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

Lgtm! We can consider the overall feature design separately.

@JoeRobich
Copy link
Copy Markdown
Member Author

retest windows_release_unit32_prtest

@sheinv
Copy link
Copy Markdown

sheinv commented Oct 5, 2018

From time to time I still get the same error.

image

image
System.ArgumentOutOfRangeException : 'end' must not be less than 'start' Parameter name: end at Microsoft.CodeAnalysis.Text.TextSpan.FromBounds(Int32 start,Int32 end) at Microsoft.CodeAnalysis.IntroduceVariable.AbstractIntroduceVariableService6.State.GetExpressionUnderSpan(SyntaxTree tree,TextSpan textSpan,CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.IntroduceVariable.AbstractIntroduceVariableService6.State.TryInitialize(TextSpan textSpan,CancellationToken cancellationToken) at Microsoft.CodeAnalysis.IntroduceVariable.AbstractIntroduceVariableService6.State.Generate(TService service,SemanticDocument document,TextSpan textSpan,CancellationToken cancellationToken)
at async Microsoft.CodeAnalysis.IntroduceVariable.AbstractIntroduceVariableService6.IntroduceVariableAsync[TService,TExpressionSyntax,TTypeSyntax,TTypeDeclarationSyntax,TQueryExpressionSyntax,TNameSyntax](<Unknown Parameters>) at async Microsoft.CodeAnalysis.CodeRefactorings.IntroduceVariable.IntroduceVariableCodeRefactoringProvider.ComputeRefactoringsAsync(<Unknown Parameters>) at async Microsoft.CodeAnalysis.CodeRefactorings.CodeRefactoringService.GetRefactoringFromProviderAsync(<Unknown Parameters>)

@Neme12
Copy link
Copy Markdown
Contributor

Neme12 commented Oct 5, 2018

@sheinv I think this fix will only be present in VS 2019, unfortunately (milestone is 16.0).

@StingyJack
Copy link
Copy Markdown

In the description of the PR/commit, it says it causes a "crash", but it should just be showing the gold bar and letting VS continue, right? This verbiage can mislead management when deciding whether to accept a fix for a particular release (though in this case you're targeting master, which is open now, so it doesn't matter as much).

@dpoeschl - as a user, getting a gold bar signifies that VS has become unstable and needs to be closed and reopened or I'm just going to get more gold bars (especially editor related ones, I left VS running after the first one today only to be smacked by this one a few minutes later).

I'm not sure there is any difference in productivity loss between restarting to avoid additional problems and restarting because vs crashed. This impact to productivity should be getting management's attention regardless of the verbiage.

@CyrusNajmabadi
Copy link
Copy Markdown
Contributor

I'm not sure there is any difference in productivity loss between restarting to avoid additional problems and restarting because vs crashed.

One is data loss, one is productivity here. These are different things, and people should be aware of which is happening to make the most informed decision possible.

The position is not that this is not important, or should not be taken. It's simply that the impact needs to be accurately described so that people who are considering what to do can properly assess things.

@StingyJack
Copy link
Copy Markdown

If you want accurate then the description should be in a less subjective measure than can be had from personal assumptions of the differences between terms, triggering words, and votes (the worst measure possible).

@jinujoseph jinujoseph modified the milestones: 16.0, 16.1.P1 Jan 7, 2019
@JoeRobich JoeRobich deleted the fix-introduce-variable-empty-span branch January 16, 2019 18:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

9 participants