51bc6c6479
The current implementation still falls back on if-else-if dispatch if the case expressions are not compile-time constants. It also falls back if the expressions fail to follow the specification for any other reason. The specification requires that case expressions: - Are compile-time constants. - All have the same type and are instances of the same class. - Do not override Object.operator==. For the last one, I've made exceptions for int/double/String. Function constants are rejected due to overriding operator==. I'm not sure they do yet, but they will eventually. Map and List are accepted. All constant Map/List instances are expected to be instances of the same class. If we later decide to make them override operator==, we'll have to reject them too. If we decide to have a special class for some List/Map constants, we'll let it override runtimeType to hide it. Type equality is only checked as far as the constants know their type. Type parameters are not included in the test since I don't think they are recorded in the compile-time constant (I could be wrong). The new switch semantics are still on "hold", so this change retains the old version too (which accepted any expression). When we want to remove that, it's a matter of making the warnings into errors and remove the fallback (the current content of visitSwitchStatement after the call to tryBuildConstantSwitch). The validation of switch cases should really happen during resolution if possible. I'll try to figure out how to move it there in a later CL. Review URL: https://chromiumcodereview.appspot.com//10916002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@12189 260f80e4-7a28-3924-810f-c04153c831b5
126 lines
2.4 KiB
Dart
126 lines
2.4 KiB
Dart
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
// Test switch statement.
|
|
|
|
class Switcher {
|
|
|
|
Switcher() { }
|
|
|
|
test1 (val) {
|
|
var x = 0;
|
|
switch (val) {
|
|
case 1:
|
|
x = 100; break;
|
|
case 2:
|
|
case 3:
|
|
x = 200; break;
|
|
case 4:
|
|
default: {
|
|
x = 400; break;
|
|
}
|
|
}
|
|
return x;
|
|
}
|
|
|
|
test2 (val) {
|
|
switch (val) {
|
|
case 1: return 200;
|
|
default: return 400;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
class SwitchTest {
|
|
static testMain() {
|
|
Switcher s = new Switcher();
|
|
Expect.equals(100, s.test1(1));
|
|
Expect.equals(200, s.test1(2));
|
|
Expect.equals(200, s.test1(3));
|
|
Expect.equals(400, s.test1(4));
|
|
Expect.equals(400, s.test1(5));
|
|
|
|
Expect.equals(200, s.test2(1));
|
|
Expect.equals(400, s.test2(2));
|
|
}
|
|
}
|
|
|
|
|
|
class Enum {
|
|
static const Enum e1 = const Enum(1);
|
|
static const Enum e2 = const Enum(2);
|
|
static const Enum e3 = const Enum(3);
|
|
final int id;
|
|
const Enum(this.id);
|
|
}
|
|
|
|
void testSwitchEnum(Enum input, int expect) {
|
|
int result = null;
|
|
switch (input) {
|
|
case Enum.e1:
|
|
result = 10;
|
|
break;
|
|
case Enum.e2:
|
|
result = 20;
|
|
break;
|
|
case Enum.e3:
|
|
result = 30;
|
|
break;
|
|
default:
|
|
result = 40;
|
|
}
|
|
Expect.equals(expect, result);
|
|
}
|
|
|
|
const int ic1 = 1;
|
|
const int ic2 = 2;
|
|
void testSwitchIntExpression(int input, int expect) {
|
|
int result = null;
|
|
switch (input) {
|
|
case 1 + 1: // 2
|
|
case ic1 + 2: // 3
|
|
result = 11;
|
|
break;
|
|
case ic2 * 2: // 4
|
|
case 1 * 5: // 5
|
|
result = 21;
|
|
break;
|
|
case ic1 % ic2 + 5: // 6
|
|
result = 31;
|
|
break;
|
|
}
|
|
Expect.equals(expect, result);
|
|
}
|
|
|
|
void testSwitchBool(bool input, int expect) {
|
|
int result = null;
|
|
switch (input) {
|
|
case true:
|
|
result = 12;
|
|
break;
|
|
case false:
|
|
result = 22;
|
|
}
|
|
Expect.equals(expect, result);
|
|
}
|
|
|
|
main() {
|
|
SwitchTest.testMain();
|
|
|
|
testSwitchEnum(Enum.e1, 10);
|
|
testSwitchEnum(Enum.e2, 20);
|
|
testSwitchEnum(Enum.e3, 30);
|
|
testSwitchEnum(null, 40);
|
|
|
|
testSwitchIntExpression(2, 11);
|
|
testSwitchIntExpression(3, 11);
|
|
testSwitchIntExpression(4, 21);
|
|
testSwitchIntExpression(5, 21);
|
|
testSwitchIntExpression(6, 31);
|
|
testSwitchIntExpression(7, null);
|
|
|
|
testSwitchBool(true, 12);
|
|
testSwitchBool(false, 22);
|
|
}
|