blob: 9b0699cbe5a30634153847a3815ff97b354a77e2 [file] [log] [blame]
// Copyright (c) 2023, 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.
// Tests that field promotion distinguishes `this` accesses from `super`
// accesses when they resolve to different fields.
// In this test, the fields in question have generic types. This is an important
// special case to test because the analyzer uses special "Member" data
// structures to track accesses to fields with generic types.
// Most of the functionality is tested in
// `super_this_distinction_generic_test.dart`. This "error" test exists solely
// to verify that the implementation properly tracks promotions when determining
// whether it's legal to invoke a member whose type is a nullable function type.
class Base<T> {
final T Function()? _f;
Base(this._f);
}
// In this class, `_f` overrides the declaration of `_f` in `super`, so their
// promotions should be tracked separately.
class DerivedClassThatOverridesBaseMembers<T> extends Base<T> {
final T Function()? _f;
DerivedClassThatOverridesBaseMembers(this._f, T Function()? superF)
: super(superF);
void invokedVariableGet() {
_f();
// ^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
// ^
// [cfe] Can't use an expression of type 'T Function()?' as a function because it's potentially null.
this._f();
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
// ^
// [cfe] Can't use an expression of type 'T Function()?' as a function because it's potentially null.
super._f();
// ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
// ^
// [cfe] Can't use an expression of type 'T Function()?' as a function because it's potentially null.
if (_f != null) {
_f();
this._f();
super._f();
// ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
// ^
// [cfe] Can't use an expression of type 'T Function()?' as a function because it's potentially null.
}
if (this._f != null) {
_f();
this._f();
super._f();
// ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
// ^
// [cfe] Can't use an expression of type 'T Function()?' as a function because it's potentially null.
}
if (super._f != null) {
_f();
// ^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
// ^
// [cfe] Can't use an expression of type 'T Function()?' as a function because it's potentially null.
this._f();
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
// ^
// [cfe] Can't use an expression of type 'T Function()?' as a function because it's potentially null.
super._f();
}
}
}
/// In this class, `this._f` and `super._f` refer to the same field. However,
/// they still promote independently, since this is simpler to implement, has no
/// soundness problems, and is unlikely to cause problems in real-world code.
class DerivedClassThatOverridesNothing<T> extends Base<T> {
DerivedClassThatOverridesNothing(super._f);
void invokedVariableGet() {
_f();
// ^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
// ^
// [cfe] Can't use an expression of type 'T Function()?' as a function because it's potentially null.
this._f();
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
// ^
// [cfe] Can't use an expression of type 'T Function()?' as a function because it's potentially null.
super._f();
// ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
// ^
// [cfe] Can't use an expression of type 'T Function()?' as a function because it's potentially null.
if (_f != null) {
_f();
this._f();
super._f();
// ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
// ^
// [cfe] Can't use an expression of type 'T Function()?' as a function because it's potentially null.
}
if (this._f != null) {
_f();
this._f();
super._f();
// ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
// ^
// [cfe] Can't use an expression of type 'T Function()?' as a function because it's potentially null.
}
if (super._f != null) {
_f();
// ^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
// ^
// [cfe] Can't use an expression of type 'T Function()?' as a function because it's potentially null.
this._f();
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
// ^
// [cfe] Can't use an expression of type 'T Function()?' as a function because it's potentially null.
super._f();
}
}
}
main() {}