-
Notifications
You must be signed in to change notification settings - Fork 4k
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
IDE0083: add support for binary is-expressions and constant is-patterns #54870
Conversation
…tern analyzer and code fix
Operand: ParenthesizedExpressionSyntax | ||
{ | ||
Expression: BinaryExpressionSyntax | ||
{ | ||
Right: TypeSyntax | ||
} isExpression, | ||
}, | ||
} notIsExpression && isExpression.IsKind(SyntaxKind.IsExpression)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Operand: ParenthesizedExpressionSyntax | |
{ | |
Expression: BinaryExpressionSyntax | |
{ | |
Right: TypeSyntax | |
} isExpression, | |
}, | |
} notIsExpression && isExpression.IsKind(SyntaxKind.IsExpression)) | |
Operand: ParenthesizedExpressionSyntax { Expression: BinaryExpressionSyntax(SyntaxKind.IsExpression) }, | |
}) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/Analyzers/CSharp/Analyzers/UsePatternMatching/CSharpUseNotPatternDiagnosticAnalyzer.cs
Show resolved
Hide resolved
{ | ||
Right: TypeSyntax type | ||
} binaryIsExpression => IsPatternExpression(binaryIsExpression.Left, UnaryPattern(Token(SyntaxKind.NotKeyword), TypePattern(type))), | ||
_ => null |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
BinaryExpressionSyntax | ||
{ | ||
Right: TypeSyntax type | ||
} binaryIsExpression => IsPatternExpression(binaryIsExpression.Left, UnaryPattern(Token(SyntaxKind.NotKeyword), TypePattern(type))), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this 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!
Thanks! Yes, I'd like to get this done. |
Awesome! |
}, | ||
} notExpression)) | ||
Operand: ParenthesizedExpressionSyntax parenthesizedExpression | ||
} notExpression) | ||
{ |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_ => throw ExceptionUtilities.Unreachable | |
_ => throw ExceptionUtilities.UnexpectedValue(oldExpression) |
There was a problem hiding this 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.
Awesome. Thanks! |
Fixes #50690.