blob: e376b7e70f002af2182974e2448bea5b0960bf54 [file] [log] [blame]
// Copyright (c) 2019, 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.
const bool constTrue = const bool.fromEnvironment('test.define.isTrue');
const bool constFalse = const bool.fromEnvironment('test.define.isFalse');
const bool constTrue2 = !constFalse;
const bool constFalse2 = const bool.fromEnvironment('test.define.notDefined');
bool? foo() => null;
Never throws() => throw 'oops';
void testSimpleConditions() {
if (constTrue) {
print('1_yes');
}
if (constFalse) {
print('2_no');
}
if (constTrue2) {
print('3_yes');
if (constFalse2) {
print('4_no');
}
}
}
void testAndConditions() {
// LHS and operator should only be dropped with sound null safety.
if (constTrue && foo()!) {
print('1_yes');
}
if (constFalse && foo()!) {
print('2_no');
}
if (constTrue && constFalse) {
print('3_no');
}
if (constTrue && constTrue && constFalse) {
print('4_no');
}
if (throws() && constTrue) {
print('5_calls_throw');
}
if (throws() && constFalse) {
print('6_calls_throw');
}
}
void testOrConditions() {
if (constTrue || foo()!) {
print('1_yes');
}
// LHS and operator should only be dropped with sound null safety.
if (constFalse || foo()!) {
print('2_yes');
}
if (constFalse || constFalse2) {
print('3_no');
}
if (constFalse || !constTrue || constTrue2) {
print('4_yes');
}
if (throws() || constTrue) {
print('5_calls_throw');
}
if (throws() || constFalse) {
print('6_calls_throw');
}
}
void testNotConditions() {
if (!constTrue) {
print('1_no');
}
if (!constFalse) {
print('2_yes');
}
if (!(!(!constTrue && foo()!) || foo()!)) {
print('3_no');
}
}
testConditionalExpressions() {
print(!constFalse && constTrue ? '1_yes' : '2_no');
print(constFalse && foo()! ? '3_no' : '4_yes ${foo()}');
}
void testAsserts() {
assert(foo()!);
assert(!foo()!, "oops!");
}
class TestAssertInitializer {
TestAssertInitializer() : assert(foo()!) {}
}
testRemovalOfStatementBodies() {
if (foo()!) assert(foo()!);
while (foo()!) assert(foo()!);
do assert(foo()!); while (foo()!);
for (;;) assert(foo()!);
for (var i in [1, 2]) assert(foo()!);
try {
assert(foo()!);
} finally {
assert(foo()!);
}
try {
assert(foo()!);
} catch (e) {
assert(foo()!);
}
try {
assert(foo()!);
} catch (e) {
assert(foo()!);
rethrow;
}
switch (42) {
case 10:
assert(foo()!);
}
switch (42) {
default:
assert(foo()!);
}
}
enum TestPlatform {
linux,
macos,
windows,
}
const switchTestString = "noMatch";
const switchTestInt = 23;
testConstantSwitches() {
switch (constTrue) {
case true:
print('1_yes');
break;
case false:
print('2_no');
break;
}
switch (constFalse) {
case true:
print('3_yes');
break;
default:
print('4_not_yes');
}
switch (TestPlatform.windows) {
case TestPlatform.linux:
print("5_linux");
break;
case TestPlatform.macos:
print("6_macos");
break;
case TestPlatform.windows:
print("7_windows");
break;
}
switch (TestPlatform.macos) {
case TestPlatform.linux:
case TestPlatform.macos:
print("8_not_windows");
break;
case TestPlatform.windows:
print("9_windows");
break;
}
switch (TestPlatform.linux) {
case TestPlatform.linux:
continue L1_macos;
L1_macos:
case TestPlatform.macos:
print("10_not_windows");
break;
case TestPlatform.windows:
print("11_windows");
break;
}
switch (TestPlatform.windows) {
case TestPlatform.linux:
print("12_linux");
break;
case TestPlatform.macos:
print("13_macos");
break;
default:
print("14_default");
}
switch (TestPlatform.windows) {
case TestPlatform.linux:
print("15_linux");
break;
case TestPlatform.macos:
print("16_macos");
break;
case TestPlatform.windows:
continue L2_default;
L2_default:
default:
print("17_default");
}
// Not explicitly exhaustive as is because there's a default, but once UCE
// is run, the resulting switch should be explicitly exhaustive, as the
// default is removed but we're still guaranteed that a case will be matched.
switch (TestPlatform.macos) {
L3_linux:
case TestPlatform.linux:
print("18_notwindows");
break;
case TestPlatform.macos:
continue L3_linux;
case TestPlatform.windows:
print("19_windows");
break;
default:
print("20_default");
}
// Also should be explicitly exhaustive post-UCE, for the reason above.
switch (TestPlatform.macos) {
L4_linux:
case TestPlatform.linux:
print("21_notwindows");
break;
case TestPlatform.macos:
if (foo()!) {
continue L4_linux;
}
break;
case TestPlatform.windows:
print("22_windows");
break;
default:
print("23_default");
}
switch (switchTestString) {
case "isMatch":
print("24_isMatch");
break;
case "isNotMatch":
print("25_isNotMatch");
break;
default:
print("26_default");
}
switch (switchTestString) {
case "isMatch":
print("27_isMatch");
break;
L5_isNotMatch:
case "isNotMatch":
print("28_isNotMatch");
break;
default:
continue L5_isNotMatch;
}
switch (switchTestInt) {
case 0:
print("29_zero");
break;
case 1:
print("30_one");
break;
default:
print("31_default");
}
switch (switchTestInt) {
case 0:
print("32_zero");
break;
case 23:
print("33_twentythree");
break;
default:
print("34_default");
}
switch (switchTestString) {
case "foo":
switch (switchTestInt) {
case 0:
print("35_foo_zero");
break;
default:
print("36_foo_nonzero");
}
break;
default:
switch (switchTestInt) {
case 1:
print("37_default_one");
break;
default:
print("38_default_default");
}
}
switch (switchTestString) {
L6_foo:
case "foo":
switch (switchTestInt) {
case 0:
print("39_foo_zero");
break;
default:
print("40_foo_nonzero");
}
break;
default:
switch (switchTestInt) {
case 1:
print("41_default_one");
break;
default:
continue L6_foo;
}
}
switch (switchTestString) {
case "foo":
switch (switchTestInt) {
case 0:
continue L7_default;
default:
print("42_foo_nonzero");
}
break;
L7_default:
default:
switch (switchTestInt) {
case 23:
print("43_default_twentythree");
break;
default:
print("44_default_default");
}
}
switch (switchTestString) {
L8_foo:
case "foo":
switch (switchTestInt) {
case 23:
continue L9_default;
default:
print("45_foo_nontwentythree");
}
break;
L9_default:
default:
switch (switchTestInt) {
case 23:
print("46_default_twentythree");
break;
default:
continue L8_foo;
}
}
switch (switchTestString) {
L10_foo:
case "foo":
switch (switchTestInt) {
case 23:
continue L11_default;
default:
print("47_foo_nontwentythree");
}
break;
L11_default:
default:
switch (switchTestInt) {
case 0:
print("48_default_zero");
break;
default:
continue L10_foo;
}
}
switch (switchTestInt) {
case 23:
print("49_twentythree");
}
switch (switchTestInt) {
case 0:
print("50_zero");
}
switch (switchTestInt) {
case 0:
print("51_zero");
break;
case 23:
default:
print("52_23_and_default");
}
// Should not be marked as isExplicitlyExhaustive, as the case that has the
// matching constant is also the default.
switch (switchTestInt) {
L12_zero:
case 0:
print("51_zero");
break;
case 23:
default:
print("52_23_and_default");
continue L12_zero;
}
}
main(List<String> args) {
testSimpleConditions();
testAndConditions();
testOrConditions();
testNotConditions();
testConditionalExpressions();
testAsserts();
new TestAssertInitializer();
testRemovalOfStatementBodies();
}