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

Side by Side Diff: pkg/compiler/lib/src/js_model/closure_visitors.dart

Issue 3009903002: Pass in `this` as a free variable to the closure class (Closed)
Patch Set: merge with master Created 3 years, 3 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
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import 'package:kernel/ast.dart' as ir; 5 import 'package:kernel/ast.dart' as ir;
6 6
7 import '../closure.dart'; 7 import '../closure.dart';
8 import 'closure.dart'; 8 import 'closure.dart';
9 9
10 /// This builder walks the code to determine what variables are captured/free at 10 /// This builder walks the code to determine what variables are captured/free at
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 // parameters, and type parameters are declared in the class, not 171 // parameters, and type parameters are declared in the class, not
172 // the factory. 172 // the factory.
173 _currentScopeInfo.freeVariables.add(variable); 173 _currentScopeInfo.freeVariables.add(variable);
174 } 174 }
175 if (_inTry) { 175 if (_inTry) {
176 _currentScopeInfo.localsUsedInTryOrSync.add(variable); 176 _currentScopeInfo.localsUsedInTryOrSync.add(variable);
177 } 177 }
178 } 178 }
179 179
180 @override 180 @override
181 void visitThisExpression(ir.ThisExpression thisExpression) {
182 if (_hasThisLocal) _registerNeedsThis();
183 }
184
185 @override
186 void visitTypeParameter(ir.TypeParameter typeParameter) {
187 ir.TreeNode context = _executableContext;
188 if (_isInsideClosure && context is ir.Procedure && context.isFactory) {
189 // This is a closure in a factory constructor. Since there is no
190 // [:this:], we have to mark the type arguments as free variables to
191 // capture them in the closure.
192 // TODO(efortuna): Implement for in the case of RTI.
193 // useTypeVariableAsLocal(typeParameter.bound);
194 }
195
196 if (_executableContext is ir.Member &&
197 _executableContext is! ir.Field &&
198 _hasThisLocal) {
199 // In checked mode, using a type variable in a type annotation may lead
200 // to a runtime type check that needs to access the type argument and
201 // therefore the closure needs a this-element, if it is not in a field
202 // initializer; field initializers are evaluated in a context where
203 // the type arguments are available in locals.
204 _registerNeedsThis();
205 }
206 }
207
208 /// Add `this` as a variable that needs to be accessed (and thus may become a
209 /// free/captured variable.
210 void _registerNeedsThis() {
211 if (_isInsideClosure) {
212 _currentScopeInfo.thisUsedAsFreeVariable = true;
213 }
214 }
215
216 @override
181 void visitForStatement(ir.ForStatement node) { 217 void visitForStatement(ir.ForStatement node) {
182 List<ir.VariableDeclaration> boxedLoopVariables = 218 List<ir.VariableDeclaration> boxedLoopVariables =
183 <ir.VariableDeclaration>[]; 219 <ir.VariableDeclaration>[];
184 enterNewScope(node, () { 220 enterNewScope(node, () {
185 // First visit initialized variables and update steps so we can easily 221 // First visit initialized variables and update steps so we can easily
186 // check if a loop variable was captured in one of these subexpressions. 222 // check if a loop variable was captured in one of these subexpressions.
187 node.variables 223 node.variables
188 .forEach((ir.VariableDeclaration variable) => variable.accept(this)); 224 .forEach((ir.VariableDeclaration variable) => variable.accept(this));
189 node.updates 225 node.updates
190 .forEach((ir.Expression expression) => expression.accept(this)); 226 .forEach((ir.Expression expression) => expression.accept(this));
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 @override 332 @override
297 void visitFunctionExpression(ir.FunctionExpression functionExpression) { 333 void visitFunctionExpression(ir.FunctionExpression functionExpression) {
298 visitInvokable(functionExpression); 334 visitInvokable(functionExpression);
299 } 335 }
300 336
301 @override 337 @override
302 void visitFunctionDeclaration(ir.FunctionDeclaration functionDeclaration) { 338 void visitFunctionDeclaration(ir.FunctionDeclaration functionDeclaration) {
303 visitInvokable(functionDeclaration); 339 visitInvokable(functionDeclaration);
304 } 340 }
305 } 341 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698