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

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

Issue 3009463002: Handle labelled continue statements (Closed)
Patch Set: Updated cf. comments 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
« no previous file with comments | « pkg/compiler/lib/src/elements/modelx.dart ('k') | pkg/compiler/lib/src/resolution/members.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 library dart2js.js_model.locals; 5 library dart2js.js_model.locals;
6 6
7 import 'package:kernel/ast.dart' as ir; 7 import 'package:kernel/ast.dart' as ir;
8 8
9 import '../closure.dart'; 9 import '../closure.dart';
10 import '../common.dart'; 10 import '../common.dart';
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 final Set<ir.BreakStatement> breaksAsContinue = new Set<ir.BreakStatement>(); 164 final Set<ir.BreakStatement> breaksAsContinue = new Set<ir.BreakStatement>();
165 165
166 JumpVisitor(this.member); 166 JumpVisitor(this.member);
167 167
168 JJumpTarget _getJumpTarget(ir.TreeNode node) { 168 JJumpTarget _getJumpTarget(ir.TreeNode node) {
169 return jumpTargetMap.putIfAbsent(node, () { 169 return jumpTargetMap.putIfAbsent(node, () {
170 return new JJumpTarget(member, jumpIndex++); 170 return new JJumpTarget(member, jumpIndex++);
171 }); 171 });
172 } 172 }
173 173
174 JLabelDefinition _getOrCreateLabel(JJumpTarget target, ir.Node node) {
175 if (target.labels.isEmpty) {
176 return target.addLabel(node, 'label${labelIndex++}');
177 } else {
178 return target.labels.single;
179 }
180 }
181
174 @override 182 @override
175 defaultNode(ir.Node node) => node.visitChildren(this); 183 defaultNode(ir.Node node) => node.visitChildren(this);
176 184
177 bool _canBeBreakTarget(ir.TreeNode node) { 185 bool _canBeBreakTarget(ir.TreeNode node) {
178 return node is ir.ForStatement || 186 return node is ir.ForStatement ||
179 node is ir.ForInStatement || 187 node is ir.ForInStatement ||
180 node is ir.WhileStatement || 188 node is ir.WhileStatement ||
181 node is ir.DoStatement || 189 node is ir.DoStatement ||
182 node is ir.SwitchStatement; 190 node is ir.SwitchStatement;
183 } 191 }
(...skipping 26 matching lines...) Expand all
210 ir.TreeNode search = node; 218 ir.TreeNode search = node;
211 bool needsLabel = false; 219 bool needsLabel = false;
212 while (search != node.target) { 220 while (search != node.target) {
213 if (_canBeBreakTarget(search)) { 221 if (_canBeBreakTarget(search)) {
214 needsLabel = search != body; 222 needsLabel = search != body;
215 break; 223 break;
216 } 224 }
217 search = search.parent; 225 search = search.parent;
218 } 226 }
219 if (needsLabel) { 227 if (needsLabel) {
220 target.addLabel(node.target, 'label${labelIndex++}', 228 JLabelDefinition label = _getOrCreateLabel(target, node.target);
221 isBreakTarget: true); 229 label.isBreakTarget = true;
222 } 230 }
223 } else if (_canBeContinueTarget(parent)) { 231 } else if (_canBeContinueTarget(parent)) {
224 // We have code like 232 // We have code like
225 // 233 //
226 // for (int i = 0; i < 10; i++) l1: { 234 // for (int i = 0; i < 10; i++) l1: {
227 // break l1: 235 // break l1:
228 // } 236 // }
229 // 237 //
230 // and can therefore use the for loop as a continue target. 238 // and can therefore use the for loop as a continue target.
231 target = _getJumpTarget(parent); 239 target = _getJumpTarget(parent);
232 target.isContinueTarget = true; 240 target.isContinueTarget = true;
233 breaksAsContinue.add(node); 241 breaksAsContinue.add(node);
242 ir.TreeNode search = node;
243 bool needsLabel = false;
244 while (search != node.target) {
245 if (_canBeContinueTarget(search)) {
246 needsLabel = search != body;
247 break;
248 }
249 search = search.parent;
250 }
251 if (needsLabel) {
252 JLabelDefinition label = _getOrCreateLabel(target, node.target);
253 label.isContinueTarget = true;
254 }
234 } else { 255 } else {
235 target = _getJumpTarget(node.target); 256 target = _getJumpTarget(node.target);
236 target.isBreakTarget = true; 257 target.isBreakTarget = true;
237 } 258 }
238 jumpTargetMap[node] = target; 259 jumpTargetMap[node] = target;
239 super.visitBreakStatement(node); 260 super.visitBreakStatement(node);
240 } 261 }
241 } 262 }
242 263
243 class JJumpTarget extends JumpTarget<ir.Node> { 264 class JJumpTarget extends JumpTarget<ir.Node> {
244 final MemberEntity memberContext; 265 final MemberEntity memberContext;
245 final int nestingLevel; 266 final int nestingLevel;
246 List<LabelDefinition<ir.Node>> _labels; 267 List<LabelDefinition<ir.Node>> _labels;
268 final bool isSwitch;
269 final bool isSwitchCase;
247 270
248 JJumpTarget(this.memberContext, this.nestingLevel); 271 JJumpTarget(this.memberContext, this.nestingLevel,
272 {this.isSwitch: false, this.isSwitchCase: false});
249 273
250 bool isBreakTarget = false; 274 bool isBreakTarget = false;
251 bool isContinueTarget = false; 275 bool isContinueTarget = false;
252 bool isSwitch = false;
253 276
254 @override 277 @override
255 Entity get executableContext => memberContext; 278 Entity get executableContext => memberContext;
256 279
257 @override 280 @override
258 LabelDefinition<ir.Node> addLabel(ir.Node label, String labelName, 281 LabelDefinition<ir.Node> addLabel(ir.Node label, String labelName,
259 {bool isBreakTarget: false}) { 282 {bool isBreakTarget: false, bool isContinueTarget: false}) {
260 _labels ??= <LabelDefinition<ir.Node>>[]; 283 _labels ??= <LabelDefinition<ir.Node>>[];
261 LabelDefinition<ir.Node> labelDefinition = new JLabelDefinition( 284 LabelDefinition<ir.Node> labelDefinition = new JLabelDefinition(
262 this, label, labelName, 285 this, labelName,
263 isBreakTarget: isBreakTarget); 286 isBreakTarget: isBreakTarget, isContinueTarget: isContinueTarget);
264 _labels.add(labelDefinition); 287 _labels.add(labelDefinition);
265 return labelDefinition; 288 return labelDefinition;
266 } 289 }
267 290
268 @override 291 @override
269 List<LabelDefinition<ir.Node>> get labels { 292 List<LabelDefinition<ir.Node>> get labels {
270 return _labels ?? const <LabelDefinition<ir.Node>>[]; 293 return _labels ?? const <LabelDefinition<ir.Node>>[];
271 } 294 }
272 295
273 @override 296 @override
(...skipping 16 matching lines...) Expand all
290 sb.write(',labels='); 313 sb.write(',labels=');
291 sb.write(_labels); 314 sb.write(_labels);
292 } 315 }
293 sb.write(')'); 316 sb.write(')');
294 return sb.toString(); 317 return sb.toString();
295 } 318 }
296 } 319 }
297 320
298 class JLabelDefinition extends LabelDefinition<ir.Node> { 321 class JLabelDefinition extends LabelDefinition<ir.Node> {
299 final JumpTarget<ir.Node> target; 322 final JumpTarget<ir.Node> target;
300 final ir.Node label;
301 final String labelName; 323 final String labelName;
302 final bool isBreakTarget; 324 bool isBreakTarget;
303 final bool isContinueTarget; 325 bool isContinueTarget;
304 326
305 JLabelDefinition(this.target, this.label, this.labelName, 327 JLabelDefinition(this.target, this.labelName,
306 {this.isBreakTarget: false, this.isContinueTarget: false}); 328 {this.isBreakTarget: false, this.isContinueTarget: false});
307 329
308 @override 330 @override
309 String get name => labelName; 331 String get name => labelName;
310 String toString() { 332 String toString() {
311 StringBuffer sb = new StringBuffer(); 333 StringBuffer sb = new StringBuffer();
312 sb.write('JLabelDefinition('); 334 sb.write('JLabelDefinition(');
313 sb.write('label=');
314 sb.write(label);
315 sb.write(',labelName='); 335 sb.write(',labelName=');
316 sb.write(labelName); 336 sb.write(labelName);
317 sb.write(',isBreakTarget='); 337 sb.write(',isBreakTarget=');
318 sb.write(isBreakTarget); 338 sb.write(isBreakTarget);
319 sb.write(',isContinueTarget='); 339 sb.write(',isContinueTarget=');
320 sb.write(isContinueTarget); 340 sb.write(isContinueTarget);
321 sb.write(')'); 341 sb.write(')');
322 return sb.toString(); 342 return sb.toString();
323 } 343 }
324 } 344 }
(...skipping 18 matching lines...) Expand all
343 sb.write(memberContext.enclosingClass.name); 363 sb.write(memberContext.enclosingClass.name);
344 sb.write('.'); 364 sb.write('.');
345 } 365 }
346 sb.write(memberContext.name); 366 sb.write(memberContext.name);
347 sb.write('#'); 367 sb.write('#');
348 sb.write(name); 368 sb.write(name);
349 sb.write(')'); 369 sb.write(')');
350 return sb.toString(); 370 return sb.toString();
351 } 371 }
352 } 372 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/elements/modelx.dart ('k') | pkg/compiler/lib/src/resolution/members.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698