Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(475)

Side by Side Diff: pkg/kernel/lib/transformations/closure/rewriter.dart

Issue 2712473003: closure conversion: Support closures in initializers (Closed)
Patch Set: Remove parameter Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library kernel.transformations.closure.rewriter;
6
7 import '../../ast.dart';
8 import 'converter.dart' show ClosureConverter;
9
10 /// Used by the [Context] to initialize and update the context variable
11 /// used to capture the variables closed over by functions.
12 abstract class AstRewriter {
13 /// The declared variable that holds the context.
14 VariableDeclaration contextDeclaration;
15
16 /// The expression used to initialize the size of the context stored in
17 /// [contextDeclaration]. This expression is modified when the context is
18 /// extended.
19 IntLiteral contextSize;
20
21 /// Creates a new [AstRewriter] for a (nested) [Block].
22 BlockRewriter forNestedBlock(Block block);
23
24 /// Inserts an allocation of a context and initializes [contextDeclaration]
25 /// and [contextSize].
26 void insertContextDeclaration(Class contextClass, Expression accessParent);
27
28 /// Inserts an expression or statement that extends the context, where
29 /// [arguments] holds a pair of the new index and the initial value.
30 void insertExtendContext(Expression accessContext, Arguments arguments);
31
32 void _createDeclaration(Class contextClass) {
33 assert(contextDeclaration == null && contextSize == null);
34
35 contextSize = new IntLiteral(0);
36 contextDeclaration = new VariableDeclaration.forValue(
37 new ConstructorInvocation(contextClass.constructors.first,
38 new Arguments(<Expression>[contextSize])),
39 type: new InterfaceType(contextClass));
40 contextDeclaration.name = "#context";
41 }
42 }
43
44 /// Adds a local variable for the context and adds update [Statement]s to the
45 /// current block.
46 class BlockRewriter extends AstRewriter {
47 BlockRewriter(this._currentBlock) : _insertionIndex = 0;
48
49 BlockRewriter forNestedBlock(Block block) {
50 return _currentBlock != block ? new BlockRewriter(block) : this;
51 }
52
53 void transformStatements(Block block, ClosureConverter converter) {
54 while (_insertionIndex < _currentBlock.statements.length) {
55 var original = _currentBlock.statements[_insertionIndex];
56 var transformed = original.accept(converter);
57 assert(_currentBlock.statements[_insertionIndex] == original);
58 if (transformed == null) {
59 _currentBlock.statements.removeAt(_insertionIndex);
60 } else {
61 _currentBlock.statements[_insertionIndex++] = transformed;
62 transformed.parent = _currentBlock;
63 }
64 }
65 }
66
67 void _insertStatement(Statement statement) {
68 _currentBlock.statements.insert(_insertionIndex++, statement);
69 statement.parent = _currentBlock;
70 }
71
72 void insertContextDeclaration(Class contextClass, Expression accessParent) {
73 _createDeclaration(contextClass);
74 _insertStatement(contextDeclaration);
75 _insertStatement(new ExpressionStatement(new PropertySet(
76 new VariableGet(contextDeclaration),
77 new Name('parent'),
78 accessParent)));
79 }
80
81 void insertExtendContext(Expression accessContext, Arguments arguments) {
82 _insertStatement(new ExpressionStatement(
83 new MethodInvocation(accessContext, new Name('[]='), arguments)));
84 }
85
86 Block _currentBlock;
87 int _insertionIndex;
ahe 2017/02/27 07:36:06 Move to beginning of class declaration.
karlklose 2017/02/28 11:45:15 Done.
88 }
89
90 /// Creates and updates the context as [Let] bindings around the initializer
91 /// expression.
92 class InitializerRewriter extends AstRewriter {
93 final Expression initializingExpression;
94
95 InitializerRewriter(this.initializingExpression) {
96 assert(initializingExpression.parent is FieldInitializer);
97 }
98
99 @override
100 BlockRewriter forNestedBlock(Block block) {
101 return new BlockRewriter(block);
102 }
103
104 @override
105 void insertContextDeclaration(Class contextClass, Expression accessParent) {
106 _createDeclaration(contextClass);
107 FieldInitializer parent = initializingExpression.parent;
108 Let binding = new Let(contextDeclaration, initializingExpression);
109 initializingExpression.parent = binding;
110 parent.value = binding;
111 binding.parent = parent;
112 }
113
114 @override
115 void insertExtendContext(Expression accessContext, Arguments arguments) {
116 Expression extendContext =
117 new MethodInvocation(accessContext, new Name('[]='), arguments);
118 Let parent = initializingExpression.parent;
119 Let binding = new Let(
120 new VariableDeclaration(null, initializer: extendContext),
121 initializingExpression);
122 parent.body = binding;
123 binding.parent = parent;
124 }
125 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698