blob: fcee4184a61e73ed4ea246f5a0a45d283df50401 [file] [log] [blame]
// Copyright (c) 2020, 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.
// @dart = 2.9
// Test that an assignment on the right hand side of `&&` defeats promotion
// after the entire `&&` expression, not just in the right hand side.
class A {}
class B extends A {
// An invocation of the form `x.checkB()` verifies that the static type of `x`
// is `B`, since this method is not defined anywhere else.
dynamic checkB() => null;
}
class C extends A {}
class D extends B {}
// An invocation of the form `checkNotB(x)` verifies that the static type of `x`
// is not `B`, since `B` is not assignable to `C`.
dynamic checkNotB(C c) => null;
// An invocation of the form `alwaysTrue(x)` always returns `true` regardless of
// `x`.
bool alwaysTrue(dynamic x) => true;
ifSimple([A a]) {
if (a is B && alwaysTrue(a = null)) {
checkNotB(a);
}
}
ifChainedAndsUnparenthesizedUnrelated([A a, Object x]) {
if (a is B && alwaysTrue(a = null) && x is int) {
checkNotB(a);
}
}
ifChainedAndsUnparenthesizedRePromote([A a]) {
if (a is B && alwaysTrue(a = null) && a is B) {
a.checkB();
}
}
ifChainedAndsUnparenthesizedAssignLast([A a, Object x]) {
if (a is B && x is int && alwaysTrue(a = null)) {
checkNotB(a);
}
}
ifChainedAndsUnparenthesizedDeeperPromote([A a]) {
if (a is B && a is D && alwaysTrue(a = null)) {
checkNotB(a);
}
}
ifChainedAndsParenLeftUnrelated([A a, Object x]) {
if ((a is B && alwaysTrue(a = null)) && x is int) {
checkNotB(a);
}
}
ifChainedAndsParenLeftRePromote([A a]) {
if ((a is B && alwaysTrue(a = null)) && a is B) {
a.checkB();
}
}
ifChainedAndsParenLeftAssignLast([A a, Object x]) {
if ((a is B && x is int) && alwaysTrue(a = null)) {
checkNotB(a);
}
}
ifChainedAndsParenLeftDeeperPromote([A a]) {
if ((a is B && a is D) && alwaysTrue(a = null)) {
checkNotB(a);
}
}
ifChainedAndsParenRightUnrelated([A a, Object x]) {
if (a is B && (alwaysTrue(a = null) && x is int)) {
checkNotB(a);
}
}
ifChainedAndsParenRightRePromote([A a]) {
if (a is B && (alwaysTrue(a = null) && a is B)) {
checkNotB(a);
}
}
ifChainedAndsParenRightAssignLast([A a, Object x]) {
if (a is B && (x is int && alwaysTrue(a = null))) {
checkNotB(a);
}
}
ifChainedAndsParenRightDeeperPromote([A a]) {
if (a is B && (a is D && alwaysTrue(a = null))) {
checkNotB(a);
}
}
conditionalSimple([A a]) {
a is B && alwaysTrue(a = null) ? checkNotB(a) : null;
}
conditionalChainedAndsUnparenthesizedUnrelated([A a, Object x]) {
a is B && alwaysTrue(a = null) && x is int ? checkNotB(a) : null;
}
conditionalChainedAndsUnparenthesizedRePromote([A a]) {
a is B && alwaysTrue(a = null) && a is B ? a.checkB() : null;
}
conditionalChainedAndsUnparenthesizedAssignLast([A a, Object x]) {
a is B && x is int && alwaysTrue(a = null) ? checkNotB(a) : null;
}
conditionalChainedAndsUnparenthesizedDeeperPromote([A a]) {
a is B && a is D && alwaysTrue(a = null) ? checkNotB(a) : null;
}
conditionalChainedAndsParenLeftUnrelated([A a, Object x]) {
(a is B && alwaysTrue(a = null)) && x is int ? checkNotB(a) : null;
}
conditionalChainedAndsParenLeftRePromote([A a]) {
(a is B && alwaysTrue(a = null)) && a is B ? a.checkB() : null;
}
conditionalChainedAndsParenLeftAssignLast([A a, Object x]) {
(a is B && x is int) && alwaysTrue(a = null) ? checkNotB(a) : null;
}
conditionalChainedAndsParenLeftDeeperPromote([A a]) {
(a is B && a is D) && alwaysTrue(a = null) ? checkNotB(a) : null;
}
conditionalChainedAndsParenRightUnrelated([A a, Object x]) {
a is B && (alwaysTrue(a = null) && x is int) ? checkNotB(a) : null;
}
conditionalChainedAndsParenRightRePromote([A a]) {
a is B && (alwaysTrue(a = null) && a is B) ? checkNotB(a) : null;
}
conditionalChainedAndsParenRightAssignLast([A a, Object x]) {
a is B && (x is int && alwaysTrue(a = null)) ? checkNotB(a) : null;
}
conditionalChainedAndsParenRightDeeperPromote([A a]) {
a is B && (a is D && alwaysTrue(a = null)) ? checkNotB(a) : null;
}
andSimple([A a]) {
a is B && alwaysTrue(a = null) && checkNotB(a);
}
andChainedAndsUnparenthesizedUnrelated([A a, Object x]) {
a is B && alwaysTrue(a = null) && x is int && checkNotB(a);
}
andChainedAndsUnparenthesizedAssignLast([A a, Object x]) {
a is B && x is int && alwaysTrue(a = null) && checkNotB(a);
}
andChainedAndsUnparenthesizedDeeperPromote([A a]) {
a is B && a is D && alwaysTrue(a = null) && checkNotB(a);
}
andChainedAndsParenLeftUnrelated([A a, Object x]) {
(a is B && alwaysTrue(a = null)) && x is int && checkNotB(a);
}
andChainedAndsParenLeftAssignLast([A a, Object x]) {
(a is B && x is int) && alwaysTrue(a = null) && checkNotB(a);
}
andChainedAndsParenLeftDeeperPromote([A a]) {
(a is B && a is D) && alwaysTrue(a = null) && checkNotB(a);
}
andChainedAndsParenRightUnrelated([A a, Object x]) {
a is B && (alwaysTrue(a = null) && x is int) && checkNotB(a);
}
andChainedAndsParenRightRePromote([A a]) {
a is B && (alwaysTrue(a = null) && a is B) && checkNotB(a);
}
andChainedAndsParenRightAssignLast([A a, Object x]) {
a is B && (x is int && alwaysTrue(a = null)) && checkNotB(a);
}
andChainedAndsParenRightDeeperPromote([A a]) {
a is B && (a is D && alwaysTrue(a = null)) && checkNotB(a);
}
main() {
ifSimple();
ifChainedAndsUnparenthesizedUnrelated();
ifChainedAndsUnparenthesizedRePromote();
ifChainedAndsUnparenthesizedAssignLast();
ifChainedAndsUnparenthesizedDeeperPromote();
ifChainedAndsParenLeftUnrelated();
ifChainedAndsParenLeftRePromote();
ifChainedAndsParenLeftAssignLast();
ifChainedAndsParenLeftDeeperPromote();
ifChainedAndsParenRightUnrelated();
ifChainedAndsParenRightRePromote();
ifChainedAndsParenRightAssignLast();
ifChainedAndsParenRightDeeperPromote();
conditionalSimple();
conditionalChainedAndsUnparenthesizedUnrelated();
conditionalChainedAndsUnparenthesizedRePromote();
conditionalChainedAndsUnparenthesizedAssignLast();
conditionalChainedAndsUnparenthesizedDeeperPromote();
conditionalChainedAndsParenLeftUnrelated();
conditionalChainedAndsParenLeftRePromote();
conditionalChainedAndsParenLeftAssignLast();
conditionalChainedAndsParenLeftDeeperPromote();
conditionalChainedAndsParenRightUnrelated();
conditionalChainedAndsParenRightRePromote();
conditionalChainedAndsParenRightAssignLast();
conditionalChainedAndsParenRightDeeperPromote();
andSimple();
andChainedAndsUnparenthesizedUnrelated();
andChainedAndsUnparenthesizedAssignLast();
andChainedAndsUnparenthesizedDeeperPromote();
andChainedAndsParenLeftUnrelated();
andChainedAndsParenLeftAssignLast();
andChainedAndsParenLeftDeeperPromote();
andChainedAndsParenRightUnrelated();
andChainedAndsParenRightRePromote();
andChainedAndsParenRightAssignLast();
andChainedAndsParenRightDeeperPromote();
}