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

List patterns: main IDE scenarios and AddRequiredParens #53850

Merged
merged 15 commits into from
Oct 23, 2021

Conversation

jcouv
Copy link
Member

@jcouv jcouv commented Jun 3, 2021

Basic scenarios (first commit):

  • completion
  • QuickInfo
  • formatting
  • classification

More advanced scenarios (second commit):
- AddRequiredParens
- RemoveUnecessaryParens

Test plan #51289

FYI @alrz

@jcouv jcouv added this to the C# 10 milestone Jun 3, 2021
@jcouv jcouv self-assigned this Jun 3, 2021
@@ -27,6 +27,7 @@ internal enum OperatorPrecedence
Multiplicative,
Switch,
Range,
Slice,
Copy link
Member Author

@jcouv jcouv Jun 3, 2021

Choose a reason for hiding this comment

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

Slice,


📝 I don't know what is the correct precedence order in this list. #Resolved

Copy link
Member

Choose a reason for hiding this comment

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

it feels like this shoudl be higher up right? i.e. if i have .. y or z then it's parsed a .. (y or z) not (..y) or z. So .. has lower precedence than than all the binaries. so i would expect this to at least be above ConditionalOr. We should probably note that .. as a range and .. as a slice are very different wrt precedence.

@jcouv jcouv added Area-IDE PR For Personal Review Only The PR doesn’t require anyone other than the developer to review it. and removed Area-Compilers labels Jun 3, 2021
@jcouv jcouv force-pushed the list-patterns branch 4 times, most recently from f05a6c5 to dc68306 Compare June 29, 2021 17:50
{
void M()
{
_ = this is [ 1, 2, >= 3 ];
Copy link
Member

@CyrusNajmabadi CyrusNajmabadi Jun 29, 2021

Choose a reason for hiding this comment

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

_ = this is [1, 2, >= 3] #Resolved

Copy link
Member

Choose a reason for hiding this comment

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

i think this will be like parens. and we'll want to have no spaces around them. similar to foo[1, 2, 3] as well.

{
// is [ > 0$$]
return CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpacesIfOnSingleLine);
}
Copy link
Member

@CyrusNajmabadi CyrusNajmabadi Jun 29, 2021

Choose a reason for hiding this comment

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

definitely not sure about this. #Resolved

@jcouv jcouv removed the PR For Personal Review Only The PR doesn’t require anyone other than the developer to review it. label Jul 13, 2021
@jcouv jcouv marked this pull request as ready for review July 13, 2021 23:49
@jcouv jcouv requested review from a team as code owners July 13, 2021 23:49
@jcouv
Copy link
Member Author

jcouv commented Oct 19, 2021

@CyrusNajmabadi I've removed the AddParens change from this PR.
Now, it just covers completion, QuickInfo and formatting. I'll add a classification test as well.

@CyrusNajmabadi
Copy link
Member

CyrusNajmabadi commented Oct 19, 2021

Can you add at least 1-2 indentation tests?


In reply to: 947044345


In reply to: 947044345

@@ -520,6 +520,39 @@ private static bool NeedsSeparatorForPositionalPattern(SyntaxToken token, Syntax
return false;
}

private static bool NeedsSeparatorForListPattern(SyntaxToken token, SyntaxToken next)
{
ListPatternSyntax? listPattern;
Copy link
Member

@CyrusNajmabadi CyrusNajmabadi Oct 19, 2021

Choose a reason for hiding this comment

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

Suggested change
ListPatternSyntax? listPattern;
ListPatternSyntax listPattern;

Copy link
Member

Choose a reason for hiding this comment

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

@jcouv your edit to this comment was breaking markdown syntax so I reverted it

Comment on lines 540 to 541
var nextIsOpenBracket = next.IsKind(SyntaxKind.OpenBracketToken);
if (nextIsOpenBracket)
Copy link
Member

@CyrusNajmabadi CyrusNajmabadi Oct 19, 2021

Choose a reason for hiding this comment

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

Suggested change
var nextIsOpenBracket = next.IsKind(SyntaxKind.OpenBracketToken);
if (nextIsOpenBracket)
if (next.IsKind(SyntaxKind.OpenBracketToken))

Copy link
Member

Choose a reason for hiding this comment

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

@jcouv your edit to this comment was breaking markdown syntax so I reverted it

Comment on lines 547 to 548
var tokenIsOpenBracket = token.IsKind(SyntaxKind.OpenBracketToken);
if (tokenIsOpenBracket)
Copy link
Member

@CyrusNajmabadi CyrusNajmabadi Oct 19, 2021

Choose a reason for hiding this comment

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

Suggested change
var tokenIsOpenBracket = token.IsKind(SyntaxKind.OpenBracketToken);
if (tokenIsOpenBracket)
if (token.IsKind(SyntaxKind.OpenBracketToken))

Copy link
Member

Choose a reason for hiding this comment

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

@jcouv your edit to this comment was breaking markdown syntax so I reverted it

{
void M()
{
_ = this is [0, .. var rest];
Copy link
Member

@CyrusNajmabadi CyrusNajmabadi Oct 19, 2021

Choose a reason for hiding this comment

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

add test where ..var is the starting state, to ensure a space is added. #Resolved

if (token.IsKind(SyntaxKind.DotDotToken)
&& token.Parent.IsKind(SyntaxKind.SlicePattern))
{
return true;
Copy link
Member

@CyrusNajmabadi CyrusNajmabadi Oct 19, 2021

Choose a reason for hiding this comment

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

this seems odd. what sort of expressions are legal here? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

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

Constants for example

Copy link
Member

Choose a reason for hiding this comment

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

how woudl that work? .. SomeConstant. How would that work? you've got a list there, so how would that list match against a constant?

Put another way, this is not a question if this is legal. It's a question of if the user has a genuine need to be able to write this. If not, then i would say: this is not an expr context as we don't want expr completion items to clutter things up here.

Copy link
Member Author

Choose a reason for hiding this comment

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

The slice method can return any type. The type could be int (then you can apply a constant pattern to it) or int[] (then you can apply a constant null pattern to it).
Those are technically correct, but not really useful... I'm okay to remove if you think that's better.

Copy link
Member

Choose a reason for hiding this comment

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

yes. please remove for now. i'm highly doubtful this will be an issue in practice. we can add back in the future if someone has a genuinely reasonable case they're running into (and in that case, i think we'd likely do a semantic check for them, rather than muddy teh completion space for everyone else).

@jcouv
Copy link
Member Author

jcouv commented Oct 19, 2021

this seems... not good :)

It's not crashing ;-P
Also seems to be the same behavior as newline in other brackets (which is already not great):

        [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)]
        public void Array_TODO2()
        {
            var code = @"class C
{
    int [] i = new int $$
}";

            var expected = @"class C
{
    int [] i = new int [
]
}";

            using var session = CreateSession(code);
            Assert.NotNull(session);

            CheckStart(session.Session);
            CheckReturn(session.Session, 0, expected);
        }

In reply to: 947125569

@jcouv
Copy link
Member Author

jcouv commented Oct 19, 2021

this seems... not good :)

Spent some time trying to figure out indentation when a newline is introduced. Couldn't figure it out.
Given that we don't do it for other constructs with brackets (ie. arrays), I'd propose to handle later. This syntax will typically be on a single line. Let me know if that's okay.
Filled #57244 to track


In reply to: 947146285

@CyrusNajmabadi
Copy link
Member

CyrusNajmabadi commented Oct 19, 2021

Yup. t hat's fine.


In reply to: 947151263

@jcouv
Copy link
Member Author

jcouv commented Oct 21, 2021

Doing some more manual validation, there's still a problem with completing .. var x. I'll investigate and like push a fix this afternoon.

Never mind. I was testing stale bits...

@jcouv jcouv mentioned this pull request Oct 22, 2021
91 tasks
Comment on lines 525 to 537
ListPatternSyntax listPattern;
if (token.Parent.IsKind(SyntaxKind.ListPattern))
{
listPattern = (ListPatternSyntax)token.Parent;
}
else if (next.Parent.IsKind(SyntaxKind.ListPattern))
{
listPattern = (ListPatternSyntax)next.Parent;
}
else
{
return false;
}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
ListPatternSyntax listPattern;
if (token.Parent.IsKind(SyntaxKind.ListPattern))
{
listPattern = (ListPatternSyntax)token.Parent;
}
else if (next.Parent.IsKind(SyntaxKind.ListPattern))
{
listPattern = (ListPatternSyntax)next.Parent;
}
else
{
return false;
}
var listPattern = token.Parent as ListPatternSyntax ?? next.Parent as ListPatternSyntax;
if (listPattern == null)
return false;

Copy link
Member

Choose a reason for hiding this comment

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

nit, you can ignore this if you want.

Comment on lines 847 to 848
}
if (NeedsSeparatorForListPattern(token, next))
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
}
if (NeedsSeparatorForListPattern(token, next))
}
if (NeedsSeparatorForListPattern(token, next))

i'm surpirsed there was no warning on this.

@@ -436,6 +443,13 @@ public override AbstractFormattingRule WithOptions(AnalyzerConfigOptions options
return CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpacesIfOnSingleLine);
}

// Slice pattern:
// ..var x
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// ..var x
// .. var x

@jcouv jcouv enabled auto-merge (squash) October 22, 2021 23:38
@jcouv jcouv merged commit 2259e13 into dotnet:features/list-patterns Oct 23, 2021
@jcouv jcouv deleted the list-patterns branch October 23, 2021 05:46
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.

4 participants