blob: 2268dc5ab055f236b955d7fc6e6a26149e3d9b0c [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.
/// This test verifies that `is` and `==` tests performed on a property get of a
/// variable do not lead to code being considered unreachable. (In principle,
/// we could soundly mark some such code as unreachable, but we have decided not
/// to do so at this time).
///
/// Exception: when the static type of the property access is guaranteed to be
/// Null, and we are performing an `== null` test, then we do mark the non-null
/// branch as unreachable.
import '../../static_type_helper.dart';
class C {
Null get nullProperty => null;
Object? get objectQProperty => null;
}
void equalitySimple(int? x, int? y, C c) {
if (x == null || y == null) return;
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int>>();
if (c.nullProperty == null) {
x = null;
} else {
y = null;
}
// Since the assignment to x was reachable, it should have static type
// `int?` now. But y should still have static type `int`.
x.expectStaticType<Exactly<int?>>();
y.expectStaticType<Exactly<int>>();
}
void equalityWithBogusPromotion(int? x, int? y, C c) {
if (x == null || y == null) return;
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int>>();
if (c.objectQProperty is Null) {
if (c.objectQProperty == null) {
x = null;
} else {
y = null;
}
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
y.expectStaticType<Exactly<int?>>();
}
void isSimple(int? x, int? y, C c) {
if (x == null || y == null) return;
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int>>();
if (c.nullProperty is Never) {
x = null;
} else {
y = null;
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
y.expectStaticType<Exactly<int?>>();
}
void isWithBogusPromotion(int? x, int? y, C c) {
if (x == null || y == null) return;
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int>>();
if (c.objectQProperty is Null) {
if (c.objectQProperty is Never) {
x = null;
} else {
y = null;
}
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
y.expectStaticType<Exactly<int?>>();
}
class _C {
final Null _nullField = null;
final Object? _objectQField = null;
}
void equalitySimplePrivate(int? x, int? y, _C c) {
if (x == null || y == null) return;
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int>>();
if (c._nullField == null) {
x = null;
} else {
y = null;
}
// Since the assignment to x was reachable, it should have static type
// `int?` now. But y should still have static type `int`.
x.expectStaticType<Exactly<int?>>();
y.expectStaticType<Exactly<int>>();
}
void equalityWithBogusPromotionPrivate(int? x, int? y, _C c) {
if (x == null || y == null) return;
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int>>();
if (c._objectQField is Null) {
if (c._objectQField == null) {
x = null;
} else {
y = null;
}
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
y.expectStaticType<Exactly<int?>>();
}
void isSimplePrivate(int? x, int? y, _C c) {
if (x == null || y == null) return;
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int>>();
if (c._nullField is Never) {
x = null;
} else {
y = null;
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
y.expectStaticType<Exactly<int?>>();
}
void isWithBogusPromotionPrivate(int? x, int? y, _C c) {
if (x == null || y == null) return;
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int>>();
if (c._objectQField is Null) {
if (c._objectQField is Never) {
x = null;
} else {
y = null;
}
}
// Since the assignments to x and y were both reachable, they should have
// static type `int?` now.
x.expectStaticType<Exactly<int?>>();
y.expectStaticType<Exactly<int?>>();
}
main() {
equalitySimple(1, 1, C());
equalityWithBogusPromotion(1, 1, C());
isSimple(1, 1, C());
isWithBogusPromotion(1, 1, C());
equalitySimplePrivate(1, 1, _C());
equalityWithBogusPromotionPrivate(1, 1, _C());
isSimplePrivate(1, 1, _C());
isWithBogusPromotionPrivate(1, 1, _C());
}