[cfe] Add support for Switch statements to text serialization

Also handle TryCatch and TryFinally.

Change-Id: I68e64161500c036bc0e1d39723baf2a88f7a3cc1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/153603
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
This commit is contained in:
Dmitry Stefantsov 2020-07-08 09:46:54 +00:00 committed by commit-bot@chromium.org
parent ddb97247f7
commit 2e5e03fe8d
2 changed files with 72 additions and 7 deletions

View file

@ -328,11 +328,7 @@ class VerificationState {
static bool isStatementNotSupported(Statement node) =>
node is VariableDeclaration &&
(node.parent is! Block || node.name == null) ||
node is SwitchStatement ||
node is TryFinally ||
node is TryCatch ||
node is FunctionDeclaration ||
node is ContinueSwitchStatement;
node is FunctionDeclaration;
static bool isSupported(Node node) => !isNotSupported(node);
@ -342,7 +338,6 @@ class VerificationState {
node is Procedure &&
(!node.isStatic || node.kind != ProcedureKind.Method) ||
node is AssertInitializer ||
node is Catch ||
node is Class ||
node is Component ||
node is Constructor ||
@ -359,7 +354,6 @@ class VerificationState {
node is RedirectingInitializer ||
node is SuperInitializer ||
node is Supertype ||
node is SwitchCase ||
node is Typedef;
}
@ -501,6 +495,10 @@ class TextSerializationVerifier extends RecursiveVisitor<void> {
makeRoundTrip<Combinator>(node, showHideSerializer);
} else if (node is LibraryDependency) {
makeRoundTrip<LibraryDependency>(node, libraryDependencySerializer);
} else if (node is Catch) {
makeRoundTrip<Catch>(node, catchSerializer);
} else if (node is SwitchCase) {
makeRoundTrip<SwitchCase>(node, switchCaseSerializer);
} else {
throw new StateError(
"Don't know how to make a round trip for a supported node "

View file

@ -1103,6 +1103,11 @@ class StatementTagger extends StatementVisitor<String>
String visitAssertBlock(AssertBlock node) => "assert-block";
String visitLabeledStatement(LabeledStatement node) => "label";
String visitBreakStatement(BreakStatement node) => "break";
String visitTryFinally(TryFinally node) => "try-finally";
String visitTryCatch(TryCatch node) => "try-catch";
String visitSwitchStatement(SwitchStatement node) => "switch";
String visitContinueSwitchStatement(ContinueSwitchStatement node) =>
"continue";
}
TextSerializer<ExpressionStatement> expressionStatementSerializer = new Wrapped(
@ -1354,6 +1359,64 @@ BreakStatement wrapBreakStatement(LabeledStatement node) {
return new BreakStatement(node);
}
TextSerializer<TryFinally> tryFinallySerializer = Wrapped(
(w) => Tuple2(w.body, w.finalizer),
(u) => TryFinally(u.first, u.second),
Tuple2Serializer(statementSerializer, statementSerializer));
TextSerializer<TryCatch> tryCatchSerializer = Wrapped(
(w) => Tuple2(w.body, w.catches),
(u) => TryCatch(u.first, u.second),
Tuple2Serializer(statementSerializer, ListSerializer(catchSerializer)));
TextSerializer<Catch> catchSerializer = Wrapped(
(w) => Tuple4(w.guard, w.exception, w.stackTrace, w.body),
(u) => Catch(u.second, u.fourth, stackTrace: u.third, guard: u.first),
Tuple4Serializer(
dartTypeSerializer,
Optional(variableDeclarationSerializer),
Optional(variableDeclarationSerializer),
statementSerializer));
TextSerializer<SwitchStatement> switchStatementSerializer = Wrapped(
(w) => Tuple2(w.expression, w.cases),
(u) => SwitchStatement(u.first, u.second),
Tuple2Serializer(
expressionSerializer,
Zip(
Bind(ListSerializer<SwitchCase>(switchCaseSerializer),
ListSerializer(statementSerializer)),
(SwitchCase c, Statement b) => c..body = b,
(SwitchCase z) => Tuple2(z, z.body))));
class SwitchCaseTagger implements Tagger<SwitchCase> {
String tag(SwitchCase node) {
return node.isDefault ? "default" : "case";
}
}
TextSerializer<SwitchCase> switchCaseCaseSerializer = Wrapped(
(w) => Tuple2("L", w),
(u) => u.second,
Binder(Wrapped(
(w) => w.expressions,
(u) => SwitchCase(u, List.filled(u.length, 0), null),
ListSerializer(expressionSerializer))));
TextSerializer<SwitchCase> switchCaseDefaultSerializer = Wrapped(
(w) => Tuple2("L", w),
(u) => u.second,
Binder(
Wrapped((w) => null, (u) => SwitchCase.defaultCase(null), Nothing())));
TextSerializer<SwitchCase> switchCaseSerializer = Case(SwitchCaseTagger(), {
"case": switchCaseCaseSerializer,
"default": switchCaseDefaultSerializer,
});
TextSerializer<ContinueSwitchStatement> continueSwitchStatementSerializer =
Wrapped((w) => w.target, (u) => ContinueSwitchStatement(u), ScopedUse());
Case<Statement> statementSerializer =
new Case.uninitialized(const StatementTagger());
@ -1822,6 +1885,10 @@ void initializeSerializers() {
"assert-block": assertBlockSerializer,
"label": labeledStatementSerializer,
"break": breakSerializer,
"try-finally": tryFinallySerializer,
"try-catch": tryCatchSerializer,
"switch": switchStatementSerializer,
"continue": continueSwitchStatementSerializer,
});
functionNodeSerializer.registerTags({
"sync": syncFunctionNodeSerializer,