Skip to content

Adding missing completion for switch when clause#25133

Merged
jinujoseph merged 30 commits intodotnet:masterfrom
Neme12:whenRecommender
Apr 4, 2018
Merged

Adding missing completion for switch when clause#25133
jinujoseph merged 30 commits intodotnet:masterfrom
Neme12:whenRecommender

Conversation

@Neme12
Copy link
Copy Markdown
Contributor

@Neme12 Neme12 commented Feb 28, 2018

fixes #25084
fixes #25293

@Neme12 Neme12 requested a review from a team as a code owner February 28, 2018 21:49
@"switch (1) { case int i $$ }"));
await VerifyKeywordAsync(AddInsideMethod(@"switch (1) { case int i $$ }"));
await VerifyKeywordAsync(AddInsideMethod(@"switch (1) { case int i $$: }"));
await VerifyKeywordAsync(AddInsideMethod(@"switch (1) { case int i $$ break; }"));
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.

note: in practice we prefer one test per test method. That way if something fails, you don't have to fix it, only to find the next line then fails.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

hmm.. i actually thought about making a helper for this to test the same code all these cases... I think it would clutter up the tests to have 3 versions for each one. And when working on this, it never happened to me that 1 version would actually fail while another one didn't. I just added this as a precaution.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

VerifyKeywordAsync itself actually does like 5 different tests for variations such as a partially written keyword, and it's all in 1 method

Copy link
Copy Markdown
Contributor Author

@Neme12 Neme12 Feb 28, 2018

Choose a reason for hiding this comment

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

my point is... I don't think it's very likely that these variations would fail independently (as opposed to the tests hidden inside VerifyKeywordAsync, which often do)

class C
{
const Color Color = null;
void M() { switch (new object()) { case int $$ } }
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 don't understnd why there is "const Color Colon" in these tests.

Copy link
Copy Markdown
Contributor Author

@Neme12 Neme12 Feb 28, 2018

Choose a reason for hiding this comment

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

Because I wanted to have the same environment in this set of tests and just do different things inside the switch statement... but you're right maybe it's not a good idea after all. It really doesn't help readability.

}

private static bool IsIdentifierInCasePattern(SyntaxNode node)
private static T GetAncestorUntilStatement<T>(SyntaxToken token) where T : SyntaxNode
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.

Don't we already have a GetAncestor or FindAncestor call that could already be used?

Copy link
Copy Markdown
Contributor Author

@Neme12 Neme12 Feb 28, 2018

Choose a reason for hiding this comment

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

Yes but it always goes all the way up to the root, I thought that was unnecessary.. but I guess it wouldn't be a performance right? so maybe this is kinda useless

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.

Usually teh root is no more than 8 items high. So this is a microoptimization that i can't imagine ever being worth it :)

Copy link
Copy Markdown
Contributor Author

@Neme12 Neme12 Feb 28, 2018

Choose a reason for hiding this comment

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

i didn't think of this that much as an optimization as just... I just want this to be as local search as possible, I don't really care what's outside.

}

[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task ExceptionFilter1_NotBeforeOpenParen()
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

just a precaution to make sure this never gets mixed up with when inside switch where there's no parentheses required


return false;

bool NotATypeName(SyntaxNode node)
Copy link
Copy Markdown
Contributor Author

@Neme12 Neme12 Feb 28, 2018

Choose a reason for hiding this comment

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

Naming is hard, especially with negatives... After 10 minutes of pondering and constantly changing the name, I settled on this. Even adding 'Is' makes this slightly less readable, not more. My conclusion was that a longer name wouldn't be an improvement here.

return false;
}

// If the last token missing, the expression is incomplete - possibly because of missing parentheses,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

note to myself: last token is missing


[WorkItem(25084, "https://github.com/dotnet/roslyn/issues/25084")]
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task SwitchPatternCaseWhenClause()
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

note to myself: they're all pattern cases if they have 'when'... wording doesn't make sense


if (lastToken == context.TargetToken)
{
return NotATypeName(expressionOrPattern);
Copy link
Copy Markdown
Contributor Author

@Neme12 Neme12 Mar 1, 2018

Choose a reason for hiding this comment

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

note: consider TypeSyntax inside a constant pattern & whether that's relevant here

@Neme12
Copy link
Copy Markdown
Contributor Author

Neme12 commented Mar 1, 2018

Question:

case 1 | when

offer when before an existing one? Usually completion ignores this sort of thing and provides completion based on what's to the left, so I would think yes. This would be an easy check though.

But I think I could see myself clicking after the 1 to type a new when clause (expecting that completion would provide it based on what's to the left) before deleting the other one, or more likely just experimenting/trying to see what I can type there. I would expect it to show up personally, because I'm used to it working this way in all other places.

@CyrusNajmabadi
Copy link
Copy Markdown
Contributor

offer when before an existing one? Usually completion ignores this sort of thing and provides completion based on what's to the left, so I would think yes.

Yes. completion should care only what is to the left 99% of the time (unless there is a VERY good reason to do otherwise). This is because sometimes people jsut want to restart a thought, and we shouldn't penalize them for what's coming after where they currently are.

@Neme12
Copy link
Copy Markdown
Contributor Author

Neme12 commented Mar 1, 2018

Then I need to fix the code. It is indeed offered now, but it bypasses the semantic check for whether the expression is actually a type.

case SyntaxNode | when

it will currently offer 'when' even if SyntaxNode is known to be a type. (Without the 'when', it won't be offered. This is because I check for TypeSyntax but not inside a constant pattern, as would happen if the 'when' clause is added)

@Neme12
Copy link
Copy Markdown
Contributor Author

Neme12 commented Mar 2, 2018

With var it's still not great:
image

@Neme12
Copy link
Copy Markdown
Contributor Author

Neme12 commented Mar 2, 2018

Actually with var it's especially bad because for some reason var doesn't trigger suggestion mode:
image

Copy link
Copy Markdown
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 Thanks!

@jcouv
Copy link
Copy Markdown
Member

jcouv commented Mar 20, 2018

@dotnet/roslyn-ide for review and merging of a community PR. Thanks

@jcouv
Copy link
Copy Markdown
Member

jcouv commented Mar 27, 2018

@dotnet/roslyn-ide for review and merging of a community PR for 15.7. Thanks


[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestForSwitchCase_NotAfterIncompleteMemberAccess() =>
await VerifyAbsenceAsync(AddInsideMethod(@"switch (1) { case int.$$ }"));
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

well... now I have an urge to change this to use the same pattern as I did in #25703 (use a theory called 'NotAfterIncompleteExpression' with all these cases as inline data)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

even though here there wouldn't be as big of a benefit since all these tests are just one line

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I quickly made the change, I hope it's fine

@Neme12
Copy link
Copy Markdown
Contributor Author

Neme12 commented Mar 27, 2018

@jcouv Do we need to ask @Pilchie or someone if this is wanted for 15.7 or not? Isn't it too late for that?

@Neme12
Copy link
Copy Markdown
Contributor Author

Neme12 commented Mar 27, 2018

I see the build failure is the same as #25689 due to some moving of test helpers to a different namespace that happened on master recently (#25643) - I haven't done a merge since then. But that is only present on master so if this were to go to 15.7, I shouldn't port that change in. I was wrong, I see it was merged to 15.7.

@jinujoseph
Copy link
Copy Markdown
Contributor

@Neme12 not late for 15.7 , @dpoeschl to review

@Neme12
Copy link
Copy Markdown
Contributor Author

Neme12 commented Mar 28, 2018

@dotnet-bot retest windows_debug_vs-integration_prtest please

@jcouv
Copy link
Copy Markdown
Member

jcouv commented Mar 28, 2018

@Neme12 I don't generally worry about the integration tests much, as they are fairly noisy and don't block merging. IDE team can correct me if that's wrong.

@Neme12
Copy link
Copy Markdown
Contributor Author

Neme12 commented Mar 29, 2018

retest windows_debug_vs-integration_prtest please

@Neme12
Copy link
Copy Markdown
Contributor Author

Neme12 commented Mar 29, 2018

retest windows_release_vs-integration_prtest please

@Neme12
Copy link
Copy Markdown
Contributor Author

Neme12 commented Mar 30, 2018

retest windows_debug_es_unit32_prtest please

@jcouv
Copy link
Copy Markdown
Member

jcouv commented Apr 3, 2018

@dpoeschl @dotnet/roslyn-ide This community PR is waiting for a last review. It would be great to merge in time for 15.7. Thanks

@jinujoseph
Copy link
Copy Markdown
Contributor

Sorry for the delay @Neme12 , we will get this reviewed and make a call on which release today

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. Thanks @Neme12!

@dpoeschl
Copy link
Copy Markdown
Contributor

dpoeschl commented Apr 3, 2018

FYI @jinujoseph

@dpoeschl
Copy link
Copy Markdown
Contributor

dpoeschl commented Apr 3, 2018

And don't worry about windows_debug_es_unit32_prtest failing. It's not required and a work in progress.

@jcouv
Copy link
Copy Markdown
Member

jcouv commented Apr 3, 2018

retest this please

@jcouv
Copy link
Copy Markdown
Member

jcouv commented Apr 3, 2018

I re-triggered a CI run as the PR last passed a week ago, but the branch changed since.
@jinujoseph for ask-mode approval. Thanks

@jinujoseph jinujoseph modified the milestones: 15.7, 15.8 Apr 4, 2018
@jinujoseph
Copy link
Copy Markdown
Contributor

@jcouv Lets take this for 15.8
@Neme12 thanks for the PR !!

@jinujoseph jinujoseph merged commit 0882a48 into dotnet:master Apr 4, 2018
@Neme12
Copy link
Copy Markdown
Contributor Author

Neme12 commented Apr 4, 2018

Awesome, thanks!

@Neme12 Neme12 deleted the whenRecommender branch April 4, 2018 23:47
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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Annoying completion when adding pattern conditional in front of expression Missing completion in switch 'when' clause

6 participants