@@ -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
875854TextSerializer <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
884873TextSerializer <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
11131103TextSerializer <ExpressionStatement > expressionStatementSerializer = new Wrapped (
@@ -1282,28 +1272,14 @@ DoStatement wrapDoStatement(Tuple2<Statement, Expression> tuple) {
12821272}
12831273
12841274TextSerializer <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-
13071283TextSerializer <ForInStatement > forInStatementSerializer = new Wrapped (
13081284 unwrapForInStatement,
13091285 wrapForInStatement,
@@ -1370,13 +1346,15 @@ TextSerializer<TryCatch> tryCatchSerializer = Wrapped(
13701346 Tuple2Serializer (statementSerializer, ListSerializer (catchSerializer)));
13711347
13721348TextSerializer <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
13811359TextSerializer <SwitchStatement > switchStatementSerializer = Wrapped (
13821360 (w) => Tuple2 (w.expression, w.cases),
@@ -1417,6 +1395,11 @@ TextSerializer<SwitchCase> switchCaseSerializer = Case(SwitchCaseTagger(), {
14171395TextSerializer <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+
14201403Case <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