@@ -643,7 +643,7 @@ class _SummarizeAstVisitor extends RecursiveAstVisitor {
643643 }
644644 b.visibleOffset = enclosingBlock? .offset;
645645 b.visibleLength = enclosingBlock? .length;
646- serializeFunctionBody (b, null , body);
646+ serializeFunctionBody (b, null , body, false );
647647 scopes.removeLast ();
648648 assert (scopes.length == oldScopesLength);
649649 return b;
@@ -656,9 +656,19 @@ class _SummarizeAstVisitor extends RecursiveAstVisitor {
656656 *
657657 * If [initializers] is non-`null` , closures occurring inside the initializers
658658 * are serialized first.
659+ *
660+ * If [serializeBodyExpr] is `true` , then the function definition is stored
661+ * in [UnlinkedExecutableBuilder.bodyExpr] .
662+ *
663+ * The return value is a map whose keys are the offsets of local function
664+ * nodes representing closures inside [initializers] and [body] , and whose
665+ * values are the indices of those local functions relative to their siblings.
659666 */
660- void serializeFunctionBody (UnlinkedExecutableBuilder b,
661- List <ConstructorInitializer > initializers, AstNode body) {
667+ Map <int , int > serializeFunctionBody (
668+ UnlinkedExecutableBuilder b,
669+ List <ConstructorInitializer > initializers,
670+ AstNode body,
671+ bool serializeBodyExpr) {
662672 if (body is BlockFunctionBody || body is ExpressionFunctionBody ) {
663673 for (UnlinkedParamBuilder parameter in b.parameters) {
664674 parameter.visibleOffset = body.offset;
@@ -668,21 +678,33 @@ class _SummarizeAstVisitor extends RecursiveAstVisitor {
668678 List <UnlinkedExecutableBuilder > oldExecutables = executables;
669679 List <UnlinkedLabelBuilder > oldLabels = labels;
670680 List <UnlinkedVariableBuilder > oldVariables = variables;
681+ Map <int , int > oldLocalClosureIndexMap = _localClosureIndexMap;
671682 executables = < UnlinkedExecutableBuilder > [];
672683 labels = < UnlinkedLabelBuilder > [];
673684 variables = < UnlinkedVariableBuilder > [];
685+ _localClosureIndexMap = < int , int > {};
674686 if (initializers != null ) {
675687 for (ConstructorInitializer initializer in initializers) {
676688 initializer.accept (this );
677689 }
678690 }
679691 body.accept (this );
692+ if (serializeBodyExpr) {
693+ if (body is Expression ) {
694+ b.bodyExpr = serializeConstExpr (_localClosureIndexMap, body);
695+ } else {
696+ // TODO(paulberry): serialize other types of function bodies.
697+ }
698+ }
680699 b.localFunctions = executables;
681700 b.localLabels = labels;
682701 b.localVariables = variables;
702+ Map <int , int > localClosureIndexMap = _localClosureIndexMap;
683703 executables = oldExecutables;
684704 labels = oldLabels;
685705 variables = oldVariables;
706+ _localClosureIndexMap = oldLocalClosureIndexMap;
707+ return localClosureIndexMap;
686708 }
687709
688710 /**
@@ -703,15 +725,18 @@ class _SummarizeAstVisitor extends RecursiveAstVisitor {
703725 /**
704726 * If the given [expression] is not `null` , serialize it as an
705727 * [UnlinkedExecutableBuilder] , otherwise return `null` .
728+ *
729+ * If [serializeBodyExpr] is `true` , then the initializer expression is stored
730+ * in [UnlinkedExecutableBuilder.bodyExpr] .
706731 */
707732 UnlinkedExecutableBuilder serializeInitializerFunction (
708- Expression expression) {
733+ Expression expression, bool serializeBodyExpr ) {
709734 if (expression == null ) {
710735 return null ;
711736 }
712737 UnlinkedExecutableBuilder initializer =
713738 new UnlinkedExecutableBuilder (nameOffset: expression.offset);
714- serializeFunctionBody (initializer, null , expression);
739+ serializeFunctionBody (initializer, null , expression, serializeBodyExpr );
715740 initializer.inferredReturnTypeSlot = assignSlot ();
716741 return initializer;
717742 }
@@ -893,18 +918,11 @@ class _SummarizeAstVisitor extends RecursiveAstVisitor {
893918 b.documentationComment = serializeDocumentation (documentationComment);
894919 b.annotations = serializeAnnotations (annotations);
895920 b.codeRange = serializeCodeRange (variables.parent);
896- Map <int , int > localClosureIndexMap = _withLocalClosureIndexMap (() {
897- b.initializer = serializeInitializerFunction (variable.initializer);
898- });
899- if (variable.isConst ||
921+ bool serializeBodyExpr = variable.isConst ||
900922 variable.isFinal && isField && ! isDeclaredStatic ||
901- variables.type == null ) {
902- Expression initializer = variable.initializer;
903- if (initializer != null ) {
904- b.initializer.bodyExpr =
905- serializeConstExpr (localClosureIndexMap, initializer);
906- }
907- }
923+ variables.type == null ;
924+ b.initializer =
925+ serializeInitializerFunction (variable.initializer, serializeBodyExpr);
908926 if (variable.initializer != null &&
909927 (variables.isFinal || variables.isConst)) {
910928 b.propagatedTypeSlot = assignSlot ();
@@ -1023,9 +1041,8 @@ class _SummarizeAstVisitor extends RecursiveAstVisitor {
10231041 b.documentationComment = serializeDocumentation (node.documentationComment);
10241042 b.annotations = serializeAnnotations (node.metadata);
10251043 b.codeRange = serializeCodeRange (node);
1026- Map <int , int > localClosureIndexMap = _withLocalClosureIndexMap (() {
1027- serializeFunctionBody (b, node.initializers, node.body);
1028- });
1044+ Map <int , int > localClosureIndexMap = serializeFunctionBody (
1045+ b, node.initializers, node.body, node.constKeyword != null );
10291046 if (node.constKeyword != null ) {
10301047 Set <String > constructorParameterNames =
10311048 node.parameters.parameters.map ((p) => p.identifier.name).toSet ();
@@ -1044,13 +1061,8 @@ class _SummarizeAstVisitor extends RecursiveAstVisitor {
10441061 UnlinkedParamBuilder visitDefaultFormalParameter (
10451062 DefaultFormalParameter node) {
10461063 UnlinkedParamBuilder b = node.parameter.accept (this );
1047- b.initializer = serializeInitializerFunction (node.defaultValue);
1064+ b.initializer = serializeInitializerFunction (node.defaultValue, true );
10481065 if (node.defaultValue != null ) {
1049- // Closures can't appear inside default values, so we don't need a
1050- // localClosureIndexMap.
1051- Map <int , int > localClosureIndexMap = null ;
1052- b.initializer? .bodyExpr =
1053- serializeConstExpr (localClosureIndexMap, node.defaultValue);
10541066 b.defaultValueCode = node.defaultValue.toSource ();
10551067 }
10561068 b.codeRange = serializeCodeRange (node);
@@ -1316,21 +1328,6 @@ class _SummarizeAstVisitor extends RecursiveAstVisitor {
13161328 enclosingBlock, node.variables, false , null , null , false );
13171329 }
13181330
1319- /**
1320- * Execute [callback] , gathering any local closures in
1321- * [_localClosureIndexMap] , and return the resulting map.
1322- *
1323- * Properly handles cases where one closure is nested within another.
1324- */
1325- Map <int , int > _withLocalClosureIndexMap (void callback ()) {
1326- Map <int , int > prevLocalClosureIndexMap = _localClosureIndexMap;
1327- _localClosureIndexMap = < int , int > {};
1328- callback ();
1329- Map <int , int > localClosureIndexMap = _localClosureIndexMap;
1330- _localClosureIndexMap = prevLocalClosureIndexMap;
1331- return localClosureIndexMap;
1332- }
1333-
13341331 /**
13351332 * Helper method to determine if a given [typeName] refers to `dynamic` .
13361333 */
0 commit comments