Skip to content

Commit dcadf0b

Browse files
committed
Store expression function closures summaries when needed for type inference.
R=scheglov@google.com Review URL: https://codereview.chromium.org/2012263002 .
1 parent 48637d1 commit dcadf0b

File tree

2 files changed

+42
-6
lines changed

2 files changed

+42
-6
lines changed

pkg/analyzer/lib/src/summary/summarize_ast.dart

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,13 @@ class _SummarizeAstVisitor extends RecursiveAstVisitor {
345345
*/
346346
Map<int, int> _localClosureIndexMap;
347347

348+
/**
349+
* Indicates whether closure function bodies should be serialized. This flag
350+
* is set while visiting the bodies of initializer expressions that will be
351+
* needed by type inference.
352+
*/
353+
bool _serializeClosureBodyExprs = false;
354+
348355
/**
349356
* Create a slot id for storing a propagated or inferred type or const cycle
350357
* info.
@@ -580,6 +587,9 @@ class _SummarizeAstVisitor extends RecursiveAstVisitor {
580587
/**
581588
* Serialize a [FunctionDeclaration] or [MethodDeclaration] into an
582589
* [UnlinkedExecutable].
590+
*
591+
* If [serializeBodyExpr] is `true`, then the function definition is stored
592+
* in [UnlinkedExecutableBuilder.bodyExpr].
583593
*/
584594
UnlinkedExecutableBuilder serializeExecutable(
585595
AstNode node,
@@ -595,7 +605,8 @@ class _SummarizeAstVisitor extends RecursiveAstVisitor {
595605
Comment documentationComment,
596606
NodeList<Annotation> annotations,
597607
TypeParameterList typeParameters,
598-
bool isExternal) {
608+
bool isExternal,
609+
bool serializeBodyExpr) {
599610
int oldScopesLength = scopes.length;
600611
_TypeParameterScope typeParameterScope = new _TypeParameterScope();
601612
scopes.add(typeParameterScope);
@@ -643,7 +654,7 @@ class _SummarizeAstVisitor extends RecursiveAstVisitor {
643654
}
644655
b.visibleOffset = enclosingBlock?.offset;
645656
b.visibleLength = enclosingBlock?.length;
646-
serializeFunctionBody(b, null, body, false);
657+
serializeFunctionBody(b, null, body, serializeBodyExpr);
647658
scopes.removeLast();
648659
assert(scopes.length == oldScopesLength);
649660
return b;
@@ -658,7 +669,8 @@ class _SummarizeAstVisitor extends RecursiveAstVisitor {
658669
* are serialized first.
659670
*
660671
* If [serializeBodyExpr] is `true`, then the function definition is stored
661-
* in [UnlinkedExecutableBuilder.bodyExpr].
672+
* in [UnlinkedExecutableBuilder.bodyExpr], and closures occurring inside
673+
* [initializers] and [body] have their function bodies serialized as well.
662674
*
663675
* The return value is a map whose keys are the offsets of local function
664676
* nodes representing closures inside [initializers] and [body], and whose
@@ -679,10 +691,12 @@ class _SummarizeAstVisitor extends RecursiveAstVisitor {
679691
List<UnlinkedLabelBuilder> oldLabels = labels;
680692
List<UnlinkedVariableBuilder> oldVariables = variables;
681693
Map<int, int> oldLocalClosureIndexMap = _localClosureIndexMap;
694+
bool oldSerializeClosureBodyExprs = _serializeClosureBodyExprs;
682695
executables = <UnlinkedExecutableBuilder>[];
683696
labels = <UnlinkedLabelBuilder>[];
684697
variables = <UnlinkedVariableBuilder>[];
685698
_localClosureIndexMap = <int, int>{};
699+
_serializeClosureBodyExprs = serializeBodyExpr;
686700
if (initializers != null) {
687701
for (ConstructorInitializer initializer in initializers) {
688702
initializer.accept(this);
@@ -692,6 +706,8 @@ class _SummarizeAstVisitor extends RecursiveAstVisitor {
692706
if (serializeBodyExpr) {
693707
if (body is Expression) {
694708
b.bodyExpr = serializeConstExpr(_localClosureIndexMap, body);
709+
} else if (body is ExpressionFunctionBody) {
710+
b.bodyExpr = serializeConstExpr(_localClosureIndexMap, body.expression);
695711
} else {
696712
// TODO(paulberry): serialize other types of function bodies.
697713
}
@@ -704,6 +720,7 @@ class _SummarizeAstVisitor extends RecursiveAstVisitor {
704720
labels = oldLabels;
705721
variables = oldVariables;
706722
_localClosureIndexMap = oldLocalClosureIndexMap;
723+
_serializeClosureBodyExprs = oldSerializeClosureBodyExprs;
707724
return localClosureIndexMap;
708725
}
709726

@@ -1158,7 +1175,8 @@ class _SummarizeAstVisitor extends RecursiveAstVisitor {
11581175
node.documentationComment,
11591176
node.metadata,
11601177
node.functionExpression.typeParameters,
1161-
node.externalKeyword != null));
1178+
node.externalKeyword != null,
1179+
false));
11621180
}
11631181

11641182
@override
@@ -1181,7 +1199,8 @@ class _SummarizeAstVisitor extends RecursiveAstVisitor {
11811199
null,
11821200
null,
11831201
node.typeParameters,
1184-
false));
1202+
false,
1203+
_serializeClosureBodyExprs));
11851204
}
11861205
}
11871206

@@ -1280,7 +1299,8 @@ class _SummarizeAstVisitor extends RecursiveAstVisitor {
12801299
node.documentationComment,
12811300
node.metadata,
12821301
node.typeParameters,
1283-
node.externalKeyword != null));
1302+
node.externalKeyword != null,
1303+
false));
12841304
}
12851305

12861306
@override

pkg/analyzer/test/src/summary/summary_common.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7067,6 +7067,22 @@ final v = ((a, b) => 42)(1, 2);
70677067
isValidConst: false, operators: [UnlinkedConstOperation.pushNull]);
70687068
}
70697069

7070+
test_expr_inClosure() {
7071+
if (skipNonConstInitializers) {
7072+
return;
7073+
}
7074+
UnlinkedVariable variable = serializeVariableText('var v = () => 1;');
7075+
_assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
7076+
operators: [UnlinkedConstOperation.pushInt], ints: [1]);
7077+
}
7078+
7079+
test_expr_inClosure_noTypeInferenceNeeded() {
7080+
// We don't serialize closure body expressions for closures that don't need
7081+
// to participate in type inference.
7082+
UnlinkedVariable variable = serializeVariableText('Object v = () => 1;');
7083+
expect(variable.initializer.localFunctions[0].bodyExpr, isNull);
7084+
}
7085+
70707086
test_expr_invokeMethod_instance() {
70717087
if (skipNonConstInitializers) {
70727088
return;

0 commit comments

Comments
 (0)