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

IDE0083: add support for binary is-expressions and constant is-patterns #54870

Merged
merged 11 commits into from
Jul 29, 2021

Conversation

reacheight
Copy link
Contributor

Fixes #50690.

Comment on lines 91 to 98
Operand: ParenthesizedExpressionSyntax
{
Expression: BinaryExpressionSyntax
{
Right: TypeSyntax
} isExpression,
},
} notIsExpression && isExpression.IsKind(SyntaxKind.IsExpression))
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
Operand: ParenthesizedExpressionSyntax
{
Expression: BinaryExpressionSyntax
{
Right: TypeSyntax
} isExpression,
},
} notIsExpression && isExpression.IsKind(SyntaxKind.IsExpression))
Operand: ParenthesizedExpressionSyntax { Expression: BinaryExpressionSyntax(SyntaxKind.IsExpression) },
})

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 don't understand how Expression: BinaryExpressionSyntax(SyntaxKind.IsExpression) is supposed to work.

The only way to check if it's an is-expression using pattern matching I came up with is

Expression: BinaryExpressionSyntax { RawKind: (int)SyntaxKind.IsExpression }

but I'm not sure how it looks.

Copy link
Member

Choose a reason for hiding this comment

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

We should have a deconstruct member here to allow a positional pattern to match type and kind. I'm not in front of the computer, but I can try to find later.

Or maybe @alrz or @Youssef1313 know where it is?

Copy link
Member

@Youssef1313 Youssef1313 Jul 17, 2021

Choose a reason for hiding this comment

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

public static void Deconstruct(this SyntaxNode node, out SyntaxKind kind)
{
kind = node.Kind();
}

Related PR: #53663

{
Right: TypeSyntax type
} binaryIsExpression => IsPatternExpression(binaryIsExpression.Left, UnaryPattern(Token(SyntaxKind.NotKeyword), TypePattern(type))),
_ => null
Copy link
Member

Choose a reason for hiding this comment

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

how does this case get hit?

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's required for successful CI build.

Copy link
Member

Choose a reason for hiding this comment

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

@reacheight You can use throw ExceptionUtilities.Unreachable; instead.

Comment on lines 73 to 76
BinaryExpressionSyntax
{
Right: TypeSyntax type
} binaryIsExpression => IsPatternExpression(binaryIsExpression.Left, UnaryPattern(Token(SyntaxKind.NotKeyword), TypePattern(type))),
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
BinaryExpressionSyntax
{
Right: TypeSyntax type
} binaryIsExpression => IsPatternExpression(binaryIsExpression.Left, UnaryPattern(Token(SyntaxKind.NotKeyword), TypePattern(type))),
BinaryExpressionSyntax { Right: TypeSyntax type } binaryIsExpression
=> IsPatternExpression(binaryIsExpression.Left, UnaryPattern(Token(SyntaxKind.NotKeyword), TypePattern(type))),

// Look for the form: !(x is Y y)
if (!(node is PrefixUnaryExpressionSyntax
// Look for the form: !(x is Y y) and !(x is const)
if (node is PrefixUnaryExpressionSyntax
Copy link
Member

Choose a reason for hiding this comment

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

i'm not a huge fan of all the redundancy here. i would just make this a simple first check that checks for a !(...) and bails otherwise. then we can just have the simple dedicated code that checks the inner expression.

Copy link
Member

@CyrusNajmabadi CyrusNajmabadi left a comment

Choose a reason for hiding this comment

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

A few changes to make. Let us know if you'd like to do this. if you don't have time, we're happy to take over this PR for you. Thanks!

@reacheight
Copy link
Contributor Author

Thanks! Yes, I'd like to get this done.

@CyrusNajmabadi
Copy link
Member

Awesome!

},
} notExpression))
Operand: ParenthesizedExpressionSyntax parenthesizedExpression
} notExpression)
{
Copy link
Member

Choose a reason for hiding this comment

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

we also need to check that this is actually a ! expression. There are other prefix-unary expressions in the alngauge as well.

Copy link
Member

Choose a reason for hiding this comment

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

it doesn't look like you use 'notExpression'. can you remove if so?

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 use it in ReportDiagnostic call at the end.

Copy link
Member

Choose a reason for hiding this comment

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

I use it in ReportDiagnostic call at the end.

I think you can use node for that.

IsPatternExpressionSyntax isPattern => isPattern.WithPattern(UnaryPattern(Token(SyntaxKind.NotKeyword), isPattern.Pattern)),
BinaryExpressionSyntax { Right: TypeSyntax type } binaryIsExpression
=> IsPatternExpression(binaryIsExpression.Left, UnaryPattern(Token(SyntaxKind.NotKeyword), TypePattern(type))),
_ => throw ExceptionUtilities.Unreachable
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
_ => throw ExceptionUtilities.Unreachable
_ => throw ExceptionUtilities.UnexpectedValue(oldExpression)

Copy link
Member

@CyrusNajmabadi CyrusNajmabadi left a comment

Choose a reason for hiding this comment

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

lgtm with the suggestions made.

@CyrusNajmabadi
Copy link
Member

Awesome. Thanks!

@CyrusNajmabadi CyrusNajmabadi merged commit 8f8f95e into dotnet:main Jul 29, 2021
@ghost ghost added this to the Next milestone Jul 29, 2021
@jinujoseph jinujoseph added the Community The pull request was submitted by a contributor who is not a Microsoft employee. label Jul 29, 2021
@dibarbet dibarbet modified the milestones: Next, 17.0.P4 Aug 31, 2021
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.

IDE0083 looks only for declaration patterns
5 participants