[ddc] Fixing switch label finder.

Our previous visitor was manually implemented. Extending the recursive visitor instead helps us be more robust to future CFE updates.

Fixes #51802

Change-Id: I9efebdf28fdf9146c2d1f948e01363a77807aa16
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/290280
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
This commit is contained in:
Mark Zhou 2023-03-22 16:35:18 +00:00 committed by Commit Queue
parent 5d6e499c0d
commit 6872707aa6
3 changed files with 83 additions and 39 deletions

View file

@ -277,54 +277,16 @@ bool hasLabeledContinue(SwitchStatement node) {
return visitor.found;
}
class LabelContinueFinder extends StatementVisitor<void> {
class LabelContinueFinder extends RecursiveVisitor<void> {
var found = false;
void visit(Statement? s) {
if (!found && s != null) s.accept(this);
}
@override
void visitBlock(Block node) => node.statements.forEach(visit);
@override
void visitAssertBlock(AssertBlock node) => node.statements.forEach(visit);
@override
void visitWhileStatement(WhileStatement node) => visit(node.body);
@override
void visitDoStatement(DoStatement node) => visit(node.body);
@override
void visitForStatement(ForStatement node) => visit(node.body);
@override
void visitForInStatement(ForInStatement node) => visit(node.body);
@override
void visitContinueSwitchStatement(ContinueSwitchStatement node) =>
found = true;
@override
void visitSwitchStatement(SwitchStatement node) {
node.cases.forEach((c) => visit(c.body));
}
@override
void visitIfStatement(IfStatement node) {
visit(node.then);
visit(node.otherwise);
}
@override
void visitTryCatch(TryCatch node) {
visit(node.body);
node.catches.forEach((c) => visit(c.body));
}
@override
void visitTryFinally(TryFinally node) {
visit(node.body);
visit(node.finalizer);
}
@override
void defaultStatement(Statement node) {}
}
/// Ensures that all of the known DartType implementors are handled.

View file

@ -0,0 +1,40 @@
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:expect/expect.dart';
enum Color { red, green, blue }
enum Taste { sweet, sour, salty, bitter, umami }
void main() {
Expect.equals(getValue(Taste.sweet, Color.blue), 1);
Expect.equals(getValue(Taste.bitter, Color.blue), 1);
Expect.equals(getValue(Taste.salty, Color.red), 2);
Expect.equals(getValue(Taste.salty, Color.blue), 4);
Expect.equals(getValue(Taste.salty, Color.green), 3);
Expect.equals(getValue(Taste.umami, Color.red), 4);
}
int getValue(Taste taste, Color color) {
switch (taste) {
case Taste.sweet:
case Taste.sour:
case Taste.bitter:
return 1;
case Taste.salty:
switch (color) {
case Color.red:
return 2;
case Color.blue:
continue LABEL;
case Color.green:
return 3;
}
throw Exception('Invalid state.');
LABEL:
case Taste.umami:
return 4;
}
}

View file

@ -0,0 +1,42 @@
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// @dart = 2.9
import 'package:expect/expect.dart';
enum Color { red, green, blue }
enum Taste { sweet, sour, salty, bitter, umami }
void main() {
Expect.equals(getValue(Taste.sweet, Color.blue), 1);
Expect.equals(getValue(Taste.bitter, Color.blue), 1);
Expect.equals(getValue(Taste.salty, Color.red), 2);
Expect.equals(getValue(Taste.salty, Color.blue), 4);
Expect.equals(getValue(Taste.salty, Color.green), 3);
Expect.equals(getValue(Taste.umami, Color.red), 4);
}
int getValue(Taste taste, Color color) {
switch (taste) {
case Taste.sweet:
case Taste.sour:
case Taste.bitter:
return 1;
case Taste.salty:
switch (color) {
case Color.red:
return 2;
case Color.blue:
continue LABEL;
case Color.green:
return 3;
}
throw Exception('Invalid state.');
LABEL:
case Taste.umami:
return 4;
}
}