| Index: pkg/compiler/lib/src/kernel/kernel_visitor.dart
|
| diff --git a/pkg/compiler/lib/src/kernel/kernel_visitor.dart b/pkg/compiler/lib/src/kernel/kernel_visitor.dart
|
| index ef34ee96f2a400d291e3c200e49588a839c024bc..e6ed1e475a1b2cc5d6d200fa58713f8de56e429d 100644
|
| --- a/pkg/compiler/lib/src/kernel/kernel_visitor.dart
|
| +++ b/pkg/compiler/lib/src/kernel/kernel_visitor.dart
|
| @@ -22,6 +22,7 @@ import 'package:kernel/frontend/accessors.dart'
|
| import 'package:kernel/transformations/flags.dart';
|
|
|
| import '../common.dart';
|
| +import '../common/names.dart';
|
| import '../constants/expressions.dart'
|
| show
|
| BoolFromEnvironmentConstantExpression,
|
| @@ -145,7 +146,6 @@ import '../universe/call_structure.dart' show CallStructure;
|
| import '../universe/selector.dart' show Selector;
|
| import '../util/util.dart' show Link;
|
| import 'error.dart' show KernelError;
|
| -import 'fall_through_visitor.dart' show fallsThrough;
|
| import 'kernel.dart' show ConstructorTarget, Kernel;
|
| import 'unavailable.dart' show UnavailableVisitor;
|
| import 'unresolved.dart' show UnresolvedVisitor;
|
| @@ -995,6 +995,15 @@ class KernelVisitor extends Object
|
| return new ir.SwitchCase(expressions, null, isDefault: node.isDefaultCase);
|
| }
|
|
|
| + /// Returns true if [node] would let execution reach the next node (aka
|
| + /// fall-through in switch cases).
|
| + bool fallsThrough(ir.Statement node) {
|
| + return !(node is ir.BreakStatement ||
|
| + node is ir.ReturnStatement ||
|
| + node is ir.ContinueSwitchStatement ||
|
| + (node is ir.ExpressionStatement && node.expression is ir.Throw));
|
| + }
|
| +
|
| @override
|
| ir.Statement visitSwitchStatement(SwitchStatement node) {
|
| ir.Expression expression = visitForValue(node.expression);
|
| @@ -1026,18 +1035,18 @@ class KernelVisitor extends Object
|
| hasVariableDeclaration = true;
|
| }
|
| }
|
| - if (!isLastCase &&
|
| - (statements.isEmpty || fallsThrough(statements.last))) {
|
| - statements.add(new ir.ExpressionStatement(new ir.Throw(
|
| - new ir.StaticInvocation(kernel.getFallThroughErrorBuilder(),
|
| - new ir.Arguments.empty()))));
|
| - }
|
| - ir.Statement body;
|
| - if (!hasVariableDeclaration && statements.length == 1) {
|
| - body = statements.single;
|
| - } else {
|
| - body = new ir.Block(statements);
|
| + if (statements.isEmpty || fallsThrough(statements.last)) {
|
| + if (isLastCase) {
|
| + statements.add(new ir.BreakStatement(
|
| + getBreakTarget(elements.getTargetDefinition(node))));
|
| + } else {
|
| + statements.add(new ir.ExpressionStatement(new ir.Throw(
|
| + new ir.ConstructorInvocation(
|
| + kernel.getFallThroughErrorConstructor(),
|
| + new ir.Arguments.empty()))));
|
| + }
|
| }
|
| + ir.Statement body = new ir.Block(statements);
|
| irCase.body = body;
|
| body.parent = irCase;
|
| }
|
| @@ -2042,13 +2051,23 @@ class KernelVisitor extends Object
|
| } else if (function.isConstructor) {
|
| // TODO(johnniwinther): Clean this up pending kernel issue #28.
|
| ConstructorElement constructor = function;
|
| - if (constructor.isDefaultConstructor) {
|
| + if (bodyNode == null || bodyNode.asEmptyStatement() != null) {
|
| body = new ir.EmptyStatement();
|
| - } else if (bodyNode != null && bodyNode.asEmptyStatement() == null) {
|
| + } else {
|
| body = buildStatementInBlock(bodyNode);
|
| }
|
| } else if (bodyNode != null) {
|
| - body = buildStatementInBlock(bodyNode);
|
| + Return returnStatement = bodyNode.asReturn();
|
| + if ((function.isSetter || function.name == Names.INDEX_SET_NAME.text) &&
|
| + returnStatement != null) {
|
| + // Avoid encoding the implicit return of setters with arrow body:
|
| + // set setter(value) => this.value = value;
|
| + // operator []=(index, value) => this[index] = value;
|
| + body = new ir.ExpressionStatement(
|
| + visitForEffect(returnStatement.expression));
|
| + } else {
|
| + body = buildStatementInBlock(bodyNode);
|
| + }
|
| }
|
| return associateElement(
|
| new ir.FunctionNode(body,
|
|
|