Skip to content

Commit f75a982

Browse files
Dmitry Stefantsovcommit-bot@chromium.org
Dmitry Stefantsov
authored andcommitted
[cfe] Complete support for statements in text serialization.
This CL adds round-trip serialization support for FunctionDeclarations and the remining kinds of VariableDeclarations, completing the support for statements. Additionally, the CL fixes a variable scope issue in Catch clauses, namely that the exception and the stack trace variables should be visible in the body. Change-Id: I3843d491b85a65c4953d6fc10a59ecbde5017029 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/153611 Reviewed-by: Johnni Winther <[email protected]>
1 parent 27446b4 commit f75a982

File tree

3 files changed

+71
-95
lines changed

3 files changed

+71
-95
lines changed

pkg/front_end/test/spell_checking_list_code.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ field1
406406
field1a
407407
field1b
408408
field2
409+
fieldformal
409410
file's
410411
filenames
411412
finv

pkg/kernel/lib/text/text_serialization_verifier.dart

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -322,18 +322,9 @@ class VerificationState {
322322
}
323323
}
324324

325-
static bool isStatementSupported(Statement node) =>
326-
!isStatementNotSupported(node);
327-
328-
static bool isStatementNotSupported(Statement node) =>
329-
node is VariableDeclaration &&
330-
(node.parent is! Block || node.name == null) ||
331-
node is FunctionDeclaration;
332-
333325
static bool isSupported(Node node) => !isNotSupported(node);
334326

335327
static bool isNotSupported(Node node) =>
336-
node is Statement && isStatementNotSupported(node) ||
337328
node is FunctionNode && node.body == null ||
338329
node is Procedure &&
339330
(!node.isStatic || node.kind != ProcedureKind.Method) ||

pkg/kernel/lib/text/text_serializer.dart

Lines changed: 70 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -803,82 +803,71 @@ class VariableDeclarationTagger implements Tagger<VariableDeclaration> {
803803
const VariableDeclarationTagger();
804804

805805
String tag(VariableDeclaration decl) {
806-
if (decl.isCovariant) throw UnimplementedError("Covariant declaration.");
807-
if (decl.isFieldFormal) throw UnimplementedError("Initializing formal.");
806+
String prefix = "";
807+
if (decl.isCovariant) {
808+
prefix = "${prefix}covariant-";
809+
if (decl.isFieldFormal) {
810+
// Field formals can only be used in constructors,
811+
// and "covariant" keyword doesn't make sense for them.
812+
throw StateError("Encountered covariant field formal.");
813+
}
814+
}
815+
if (decl.isFieldFormal) {
816+
prefix = "${prefix}fieldformal-";
817+
}
818+
808819
if (decl.isConst) {
809820
// It's not clear what invariants we assume about const/final. For now
810821
// throw if we have both.
811-
if (decl.isFinal) throw UnimplementedError("const and final");
812-
return "const";
822+
if (decl.isFinal) {
823+
throw UnimplementedError(
824+
"Encountered a variable that is both const and final.");
825+
}
826+
return "${prefix}const";
813827
}
814828
if (decl.isFinal) {
815-
return "final";
829+
return "${prefix}final";
816830
}
817-
return "var";
818-
}
819-
}
820-
821-
TextSerializer<VariableDeclaration> varDeclarationSerializer = new Wrapped(
822-
unwrapVariableDeclaration,
823-
wrapVarDeclaration,
824-
Tuple3Serializer(dartTypeSerializer, new Optional(expressionSerializer),
825-
new ListSerializer(expressionSerializer)));
826-
827-
Tuple3<DartType, Expression, List<Expression>> unwrapVariableDeclaration(
828-
VariableDeclaration declaration) {
829-
return new Tuple3(
830-
declaration.type, declaration.initializer, declaration.annotations);
831-
}
832-
833-
VariableDeclaration wrapVarDeclaration(
834-
Tuple3<DartType, Expression, List<Expression>> tuple) {
835-
var result = new VariableDeclaration(null,
836-
initializer: tuple.second, type: tuple.first);
837-
for (int i = 0; i < tuple.third.length; ++i) {
838-
result.addAnnotation(tuple.third[i]);
839-
}
840-
return result;
841-
}
842-
843-
TextSerializer<VariableDeclaration> finalDeclarationSerializer = new Wrapped(
844-
unwrapVariableDeclaration,
845-
wrapFinalDeclaration,
846-
Tuple3Serializer(dartTypeSerializer, new Optional(expressionSerializer),
847-
new ListSerializer(expressionSerializer)));
848-
849-
VariableDeclaration wrapFinalDeclaration(
850-
Tuple3<DartType, Expression, List<Expression>> tuple) {
851-
var result = new VariableDeclaration(null,
852-
initializer: tuple.second, type: tuple.first, isFinal: true);
853-
for (int i = 0; i < tuple.third.length; ++i) {
854-
result.addAnnotation(tuple.third[i]);
831+
return "${prefix}var";
855832
}
856-
return result;
857833
}
858834

859-
TextSerializer<VariableDeclaration> constDeclarationSerializer = new Wrapped(
860-
unwrapVariableDeclaration,
861-
wrapConstDeclaration,
862-
Tuple3Serializer(dartTypeSerializer, new Optional(expressionSerializer),
863-
new ListSerializer(expressionSerializer)));
864-
865-
VariableDeclaration wrapConstDeclaration(
866-
Tuple3<DartType, Expression, List<Expression>> tuple) {
867-
var result = new VariableDeclaration(null,
868-
initializer: tuple.second, type: tuple.first, isConst: true);
869-
for (int i = 0; i < tuple.third.length; ++i) {
870-
result.addAnnotation(tuple.third[i]);
871-
}
872-
return result;
873-
}
835+
TextSerializer<VariableDeclaration> makeVariableDeclarationSerializer(
836+
{bool isFinal = false,
837+
bool isConst = false,
838+
bool isCovariant = false,
839+
bool isFieldFormal = false}) =>
840+
new Wrapped(
841+
(w) => Tuple3(w.type, w.initializer, w.annotations),
842+
(u) => u.third.fold(
843+
VariableDeclaration(null,
844+
type: u.first,
845+
initializer: u.second,
846+
isFinal: isFinal,
847+
isConst: isConst,
848+
isCovariant: isCovariant,
849+
isFieldFormal: isFieldFormal),
850+
(v, a) => v..addAnnotation(a)),
851+
Tuple3Serializer(dartTypeSerializer, new Optional(expressionSerializer),
852+
new ListSerializer(expressionSerializer)));
874853

875854
TextSerializer<VariableDeclaration> variableDeclarationSerializer = Wrapped(
876855
(v) => Tuple2(v.name, v),
877856
(t) => t.second..name = t.first,
878857
Binder(Case(VariableDeclarationTagger(), {
879-
"var": varDeclarationSerializer,
880-
"final": finalDeclarationSerializer,
881-
"const": constDeclarationSerializer,
858+
"var": makeVariableDeclarationSerializer(),
859+
"final": makeVariableDeclarationSerializer(isFinal: true),
860+
"const": makeVariableDeclarationSerializer(isConst: true),
861+
"covariant-var": makeVariableDeclarationSerializer(isCovariant: true),
862+
"covariant-final":
863+
makeVariableDeclarationSerializer(isCovariant: true, isFinal: true),
864+
"covariant-const":
865+
makeVariableDeclarationSerializer(isCovariant: true, isConst: true),
866+
"fieldformal-var": makeVariableDeclarationSerializer(isFieldFormal: true),
867+
"fieldformal-final":
868+
makeVariableDeclarationSerializer(isFieldFormal: true, isFinal: true),
869+
"fieldformal-const":
870+
makeVariableDeclarationSerializer(isFieldFormal: true, isConst: true),
882871
})));
883872

884873
TextSerializer<TypeParameter> typeParameterSerializer = Wrapped(
@@ -1108,6 +1097,7 @@ class StatementTagger extends StatementVisitor<String>
11081097
String visitSwitchStatement(SwitchStatement node) => "switch";
11091098
String visitContinueSwitchStatement(ContinueSwitchStatement node) =>
11101099
"continue";
1100+
String visitFunctionDeclaration(FunctionDeclaration node) => "local-fun";
11111101
}
11121102

11131103
TextSerializer<ExpressionStatement> expressionStatementSerializer = new Wrapped(
@@ -1282,28 +1272,14 @@ DoStatement wrapDoStatement(Tuple2<Statement, Expression> tuple) {
12821272
}
12831273

12841274
TextSerializer<ForStatement> forStatementSerializer = new Wrapped(
1285-
unwrapForStatement,
1286-
wrapForStatement,
1275+
(w) => Tuple2(w.variables, Tuple3(w.condition, w.updates, w.body)),
1276+
(u) =>
1277+
ForStatement(u.first, u.second.first, u.second.second, u.second.third),
12871278
new Bind(
12881279
ListSerializer(variableDeclarationSerializer),
1289-
new Tuple3Serializer(expressionSerializer,
1280+
new Tuple3Serializer(Optional(expressionSerializer),
12901281
new ListSerializer(expressionSerializer), statementSerializer)));
12911282

1292-
Tuple2<List<VariableDeclaration>,
1293-
Tuple3<Expression, List<Expression>, Statement>>
1294-
unwrapForStatement(ForStatement node) {
1295-
return new Tuple2(
1296-
node.variables, new Tuple3(node.condition, node.updates, node.body));
1297-
}
1298-
1299-
ForStatement wrapForStatement(
1300-
Tuple2<List<VariableDeclaration>,
1301-
Tuple3<Expression, List<Expression>, Statement>>
1302-
tuple) {
1303-
return new ForStatement(
1304-
tuple.first, tuple.second.first, tuple.second.second, tuple.second.third);
1305-
}
1306-
13071283
TextSerializer<ForInStatement> forInStatementSerializer = new Wrapped(
13081284
unwrapForInStatement,
13091285
wrapForInStatement,
@@ -1370,13 +1346,15 @@ TextSerializer<TryCatch> tryCatchSerializer = Wrapped(
13701346
Tuple2Serializer(statementSerializer, ListSerializer(catchSerializer)));
13711347

13721348
TextSerializer<Catch> catchSerializer = Wrapped(
1373-
(w) => Tuple4(w.guard, w.exception, w.stackTrace, w.body),
1374-
(u) => Catch(u.second, u.fourth, stackTrace: u.third, guard: u.first),
1375-
Tuple4Serializer(
1349+
(w) => Tuple2(w.guard, Tuple2(Tuple2(w.exception, w.stackTrace), w.body)),
1350+
(u) => Catch(u.second.first.first, u.second.second,
1351+
stackTrace: u.second.first.second, guard: u.first),
1352+
Tuple2Serializer(
13761353
dartTypeSerializer,
1377-
Optional(variableDeclarationSerializer),
1378-
Optional(variableDeclarationSerializer),
1379-
statementSerializer));
1354+
Bind(
1355+
Tuple2Serializer(Optional(variableDeclarationSerializer),
1356+
Optional(variableDeclarationSerializer)),
1357+
statementSerializer)));
13801358

13811359
TextSerializer<SwitchStatement> switchStatementSerializer = Wrapped(
13821360
(w) => Tuple2(w.expression, w.cases),
@@ -1417,6 +1395,11 @@ TextSerializer<SwitchCase> switchCaseSerializer = Case(SwitchCaseTagger(), {
14171395
TextSerializer<ContinueSwitchStatement> continueSwitchStatementSerializer =
14181396
Wrapped((w) => w.target, (u) => ContinueSwitchStatement(u), ScopedUse());
14191397

1398+
TextSerializer<FunctionDeclaration> functionDeclarationSerializer = Wrapped(
1399+
(w) => Tuple2(w.variable, w.function),
1400+
(u) => FunctionDeclaration(u.first, u.second),
1401+
Bind(variableDeclarationSerializer, functionNodeSerializer));
1402+
14201403
Case<Statement> statementSerializer =
14211404
new Case.uninitialized(const StatementTagger());
14221405

@@ -1889,6 +1872,7 @@ void initializeSerializers() {
18891872
"try-catch": tryCatchSerializer,
18901873
"switch": switchStatementSerializer,
18911874
"continue": continueSwitchStatementSerializer,
1875+
"local-fun": functionDeclarationSerializer,
18921876
});
18931877
functionNodeSerializer.registerTags({
18941878
"sync": syncFunctionNodeSerializer,

0 commit comments

Comments
 (0)