-
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
Support long chains of else if
statements
#74317
Conversation
/azp run roslyn-CI |
Azure Pipelines successfully started running 1 pipeline(s). |
@@ -654,6 +654,30 @@ private void CheckDeclared(LocalSymbol local) | |||
return null; | |||
} | |||
|
|||
public override BoundNode? VisitIfStatement(BoundIfStatement node) |
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.
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.
Sounds good.
@@ -1045,5 +1045,32 @@ public override BoundNode VisitCollectionExpression(BoundCollectionExpression no | |||
|
|||
return base.VisitCollectionExpression(node); | |||
} | |||
|
|||
public override BoundNode VisitIfStatement(BoundIfStatement node) |
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.
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.
Consider deriving
DiagnosticsPass
fromBoundTreeWalkerWithStackGuardWithoutRecursionOnTheLeftOfBinaryOperator
. That should allow removing this override and simplifyingVisitBinaryOperator
.
I'll open a follow-up issue for this refactoring. There is another PR coming about binary patterns. Will take care of all of them together.
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.
Opened #75319.
Is Refers to: src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_IfStatement.cs:123 in 487db6e. [](commit_id = 487db6e, deletion_comment = False) |
// if (condition) | ||
// consequence; | ||
// else | ||
// alternative |
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.
return (StatementSyntax)this.EatNode(); | ||
} | ||
|
||
return null; | ||
|
||
bool canReuseStatement(SyntaxList<AttributeListSyntax> attributes, bool isGlobal) |
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.
@dotnet/roslyn-compiler Please review |
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 couple of minor comments
@@ -2180,7 +2180,7 @@ private static bool IsEmptyRewritePossible(BoundNode node) | |||
} | |||
} | |||
|
|||
private sealed class EmptyRewriter : BoundTreeRewriterWithStackGuard | |||
private sealed class EmptyRewriter : BoundTreeRewriterWithStackGuardWithoutRecursionOnTheLeftOfBinaryOperator |
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 thought about making this change for my BinaryPatterns change, but I don't think it's actually desirable; rather, this is why I updated StackGuard to handle binary patterns as well as expressions, so that it would throw a CancelledByStackGuard
exception and enter the catch above. #Resolved
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.
This visitor and its usage were added in #65398. It looks there was no specific motivation around verifying stack guard behavior. Rather it looks like it was about asserting that Update
implementations are working for all possible nodes. The purpose is still preserved, in my opinion.
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.
By the way, the change made to BoundTreeRewriterWithStackGuard
around binary patterns probably makes sense since they are used in expression context. However, it is probably not that useful because patterns do not survive the very first rewrite phase (lowering).
@@ -1143,6 +1143,17 @@ private CompoundUseSiteInfo<AssemblySymbol> GetNewCompoundUseSiteInfo() | |||
/// </summary> | |||
private sealed class LocalRewritingValidator : BoundTreeWalkerWithStackGuardWithoutRecursionOnTheLeftOfBinaryOperator | |||
{ | |||
public override BoundNode? Visit(BoundNode? node) | |||
{ | |||
if (node is BoundIfStatement) |
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 what this changes. What does this get us? #Resolved
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 what this changes. What does this get us?
It gets us a validation that we don't have BoundIfStatement
s post lowering. We no longer can enforce that by overriding VisitIfStatement
because it is now sealed in base. I don't think it makes sense to "unseal" it for the purpose of debug-only visitor.
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 no longer can enforce that by overriding VisitIfStatement because it is now sealed in base.
Ah, that's what I was missing. Thanks.
var alternative = boundIfStatement.AlternativeOpt; | ||
if (alternative is null) | ||
{ | ||
whenFalse = null; | ||
break; | ||
} | ||
|
||
if (alternative is BoundIfStatement elseIfStatement) | ||
{ | ||
boundIfStatement = elseIfStatement; | ||
} | ||
else | ||
{ | ||
whenFalse = Create(alternative); | ||
break; | ||
} |
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.
Nit: Create
is null-resileint. Consider simplifying this to just check if alternative
is a BoundIfStatement
, and unconditionally calling Create
and break in the else. #Resolved
LGTM, although it looks like I cannot approve the PR, perhaps because I created the PR. |
Chuck reviewed my changes, and, I reviewed his initial changes. In my opinion, that should count for a second sign-off. Merging. |
…terns * upstream/main: (267 commits) Support long chains of `else if` statements (dotnet#74317) Update dependencies from https://github.com/dotnet/source-build-externals build 20240930.2 Fix the path to the proposal (dotnet#75302) Fix TSA tooling (dotnet#75307) Clarify the bug template to request a code snippet (dotnet#75306) Bump razor for serialization changes (dotnet#75282) Disallow declaration of indexers in absence of proper DefaultMemberAttribute. (dotnet#75099) stoub use ref Simpler Simplify Switch to a threadlocal storage to prevent locks add comment don't mess with user caret in smart rename Update LanguageServer references Localized file check-in by OneLocBuild Task: Build definition ID 327: Build ID 2548898 Use common helper method Localized file check-in by OneLocBuild Task: Build definition ID 327: Build ID 2548278 Field-backed properties: additional tests (dotnet#75283) Revert "Updates content exclusion for on-the-fly-docs (dotnet#75172)" (dotnet#75279) (dotnet#75284) ...
This is a follow up on #74317
Avoid recursion when visiting nested
else if
statements.See #72393.