Files
sdk/tests/language/switch_test.dart
T
lrn@google.com 51bc6c6479 Change switch to give warnings when cases don't follow the newest syntax.
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
2012-09-11 12:26:41 +00:00

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);
}