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

Side by Side Diff: pkg/compiler/lib/src/kernel/kernel_visitor.dart

Issue 2664513003: Fix Rasta to correctly identify added break targets in switch statements. (Closed)
Patch Set: 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
« no previous file with comments | « no previous file | no next file » | 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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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.md file. 3 // BSD-style license that can be found in the LICENSE.md file.
4 4
5 import 'package:kernel/ast.dart' as ir; 5 import 'package:kernel/ast.dart' as ir;
6 import 'package:kernel/frontend/accessors.dart' 6 import 'package:kernel/frontend/accessors.dart'
7 show 7 show
8 Accessor, 8 Accessor,
9 IndexAccessor, 9 IndexAccessor,
10 NullAwarePropertyAccessor, 10 NullAwarePropertyAccessor,
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 393
394 ir.LabeledStatement getContinueTarget(JumpTarget target) { 394 ir.LabeledStatement getContinueTarget(JumpTarget target) {
395 return continueTargets.putIfAbsent( 395 return continueTargets.putIfAbsent(
396 target, () => new ir.LabeledStatement(null)); 396 target, () => new ir.LabeledStatement(null));
397 } 397 }
398 398
399 ir.SwitchCase getContinueSwitchTarget(JumpTarget target) { 399 ir.SwitchCase getContinueSwitchTarget(JumpTarget target) {
400 return continueSwitchTargets[target]; 400 return continueSwitchTargets[target];
401 } 401 }
402 402
403 /// The optional positional parameter isBreakTarget can be added in cases
404 /// where a break statement was added but the element model and underlying
405 /// JumpTargets don't know about it.
403 ir.Statement buildBreakTarget( 406 ir.Statement buildBreakTarget(
404 ir.Statement statement, Node node, JumpTarget jumpTarget) { 407 ir.Statement statement, Node node, JumpTarget jumpTarget,
408 [bool isBreakTarget]) {
405 assert(node.isValidBreakTarget()); 409 assert(node.isValidBreakTarget());
406 assert(jumpTarget == elements.getTargetDefinition(node)); 410 assert(jumpTarget == elements.getTargetDefinition(node));
407 associateNode(statement, node); 411 associateNode(statement, node);
408 if (jumpTarget != null && jumpTarget.isBreakTarget) { 412 if (jumpTarget != null && (jumpTarget.isBreakTarget || isBreakTarget)) {
409 ir.LabeledStatement breakTarget = getBreakTarget(jumpTarget); 413 ir.LabeledStatement breakTarget = getBreakTarget(jumpTarget);
410 breakTarget.body = statement; 414 breakTarget.body = statement;
411 statement.parent = breakTarget; 415 statement.parent = breakTarget;
412 return breakTarget; 416 return breakTarget;
413 } else { 417 } else {
414 return statement; 418 return statement;
415 } 419 }
416 } 420 }
417 421
418 ir.Statement buildContinueTarget( 422 ir.Statement buildContinueTarget(
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 return !(node is ir.BreakStatement || 1008 return !(node is ir.BreakStatement ||
1005 node is ir.ReturnStatement || 1009 node is ir.ReturnStatement ||
1006 node is ir.ContinueSwitchStatement || 1010 node is ir.ContinueSwitchStatement ||
1007 (node is ir.ExpressionStatement && node.expression is ir.Throw)); 1011 (node is ir.ExpressionStatement && node.expression is ir.Throw));
1008 } 1012 }
1009 1013
1010 @override 1014 @override
1011 ir.Statement visitSwitchStatement(SwitchStatement node) { 1015 ir.Statement visitSwitchStatement(SwitchStatement node) {
1012 ir.Expression expression = visitForValue(node.expression); 1016 ir.Expression expression = visitForValue(node.expression);
1013 List<ir.SwitchCase> cases = <ir.SwitchCase>[]; 1017 List<ir.SwitchCase> cases = <ir.SwitchCase>[];
1018 bool switchIsBreakTarget = elements.getTargetDefinition(node).isBreakTarget;
1014 for (SwitchCase caseNode in node.cases.nodes) { 1019 for (SwitchCase caseNode in node.cases.nodes) {
1015 cases.add(caseNode.accept(this)); 1020 cases.add(caseNode.accept(this));
1016 JumpTarget jumpTarget = elements.getTargetDefinition(caseNode); 1021 JumpTarget jumpTarget = elements.getTargetDefinition(caseNode);
1017 if (jumpTarget != null) { 1022 if (jumpTarget != null) {
1018 assert(jumpTarget.isContinueTarget); 1023 assert(jumpTarget.isContinueTarget);
1019 assert(!continueSwitchTargets.containsKey(jumpTarget)); 1024 assert(!continueSwitchTargets.containsKey(jumpTarget));
1020 continueSwitchTargets[jumpTarget] = cases.last; 1025 continueSwitchTargets[jumpTarget] = cases.last;
1021 } 1026 }
1022 } 1027 }
1023 1028
(...skipping 12 matching lines...) Expand all
1036 for (Statement statement in caseNode.statements.nodes) { 1041 for (Statement statement in caseNode.statements.nodes) {
1037 if (buildStatement(statement, statements)) { 1042 if (buildStatement(statement, statements)) {
1038 hasVariableDeclaration = true; 1043 hasVariableDeclaration = true;
1039 } 1044 }
1040 } 1045 }
1041 if (statements.isEmpty || fallsThrough(statements.last)) { 1046 if (statements.isEmpty || fallsThrough(statements.last)) {
1042 if (isLastCase) { 1047 if (isLastCase) {
1043 if (!caseNode.isDefaultCase) { 1048 if (!caseNode.isDefaultCase) {
1044 statements.add(new ir.BreakStatement( 1049 statements.add(new ir.BreakStatement(
1045 getBreakTarget(elements.getTargetDefinition(node)))); 1050 getBreakTarget(elements.getTargetDefinition(node))));
1051 // Because we "helpfully" add a break here, in the underlying
1052 // element model the jump target doesn't actually know it's a break
1053 // target, so we have to pass that information.
1054 switchIsBreakTarget = true;
1046 } 1055 }
1047 } else { 1056 } else {
1048 statements.add(new ir.ExpressionStatement(new ir.Throw( 1057 statements.add(new ir.ExpressionStatement(new ir.Throw(
1049 new ir.ConstructorInvocation( 1058 new ir.ConstructorInvocation(
1050 kernel.getFallThroughErrorConstructor(), 1059 kernel.getFallThroughErrorConstructor(),
1051 new ir.Arguments.empty())))); 1060 new ir.Arguments.empty()))));
1052 } 1061 }
1053 } 1062 }
1054 ir.Statement body = new ir.Block(statements); 1063 ir.Statement body = new ir.Block(statements);
1055 irCase.body = body; 1064 irCase.body = body;
1056 body.parent = irCase; 1065 body.parent = irCase;
1057 } 1066 }
1058 assert(!casesIterator.moveNext()); 1067 assert(!casesIterator.moveNext());
1059 1068
1060 return buildBreakTarget(new ir.SwitchStatement(expression, cases), node, 1069 return buildBreakTarget(new ir.SwitchStatement(expression, cases), node,
1061 elements.getTargetDefinition(node)); 1070 elements.getTargetDefinition(node), switchIsBreakTarget);
1062 } 1071 }
1063 1072
1064 @override 1073 @override
1065 ir.Statement visitSyncForIn(SyncForIn node) { 1074 ir.Statement visitSyncForIn(SyncForIn node) {
1066 return buildForIn(node, isAsync: false); 1075 return buildForIn(node, isAsync: false);
1067 } 1076 }
1068 1077
1069 @override 1078 @override
1070 ir.Throw visitThrow(Throw node) { 1079 ir.Throw visitThrow(Throw node) {
1071 return new ir.Throw(visitForValue(node?.expression)); 1080 return new ir.Throw(visitForValue(node?.expression));
(...skipping 1785 matching lines...) Expand 10 before | Expand all | Expand 10 after
2857 : this(null, true, node, initializers); 2866 : this(null, true, node, initializers);
2858 2867
2859 accept(ir.Visitor v) => throw "unsupported"; 2868 accept(ir.Visitor v) => throw "unsupported";
2860 2869
2861 visitChildren(ir.Visitor v) => throw "unsupported"; 2870 visitChildren(ir.Visitor v) => throw "unsupported";
2862 2871
2863 String toString() { 2872 String toString() {
2864 return "IrFunction($kind, $isConstructor, $node, $initializers)"; 2873 return "IrFunction($kind, $isConstructor, $node, $initializers)";
2865 } 2874 }
2866 } 2875 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698