diff --git a/tests/language/enum_shorthands/constructor/constructor_if_null_error_test.dart b/tests/language/enum_shorthands/constructor/constructor_if_null_error_test.dart new file mode 100644 index 000000000000..f721f34b2865 --- /dev/null +++ b/tests/language/enum_shorthands/constructor/constructor_if_null_error_test.dart @@ -0,0 +1,59 @@ +// Copyright (c) 2024, 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. + +// Errors with `??` and enum shorthands with constructors. + +// SharedOptions=--enable-experiment=enum-shorthands + +import '../enum_shorthand_helper.dart'; + +void constructorClassTest() { + ConstructorClass ctor = ConstructorClass(1); + + // Warning when LHS is not able to be `null`. + ConstructorClass notNullable = .new(1) ?? ctor; + // ^ + // [analyzer] unspecified + // [cfe] unspecified + + ConstructorClass notNullableRegular = .regular(1) ?? ctor; + // ^ + // [analyzer] unspecified + // [cfe] unspecified + + ConstructorClass notNullableNamed = .named(x: 1) ?? ctor; + // ^ + // [analyzer] unspecified + // [cfe] unspecified + + ConstructorClass notNullableOptional = .optional(1) ?? ctor; + // ^ + // [analyzer] unspecified + // [cfe] unspecified +} + +void constructorExtTest() { + ConstructorExt ctorExt = ConstructorExt(1); + + // Warning when LHS is not able to be `null`. + ConstructorExt notNullableExt = .new(1) ?? ctorExt; + // ^ + // [analyzer] unspecified + // [cfe] unspecified + + ConstructorExt notNullableRegularExt = .regular(1) ?? ctorExt; + // ^ + // [analyzer] unspecified + // [cfe] unspecified + + ConstructorExt notNullableNamedExt = .named(x: 1) ?? ctorExt; + // ^ + // [analyzer] unspecified + // [cfe] unspecified + + ConstructorExt notNullableOptionalExt = .optional(1) ?? ctorExt; + // ^ + // [analyzer] unspecified + // [cfe] unspecified +} diff --git a/tests/language/enum_shorthands/constructor/constructor_if_null_test.dart b/tests/language/enum_shorthands/constructor/constructor_if_null_test.dart index 9f4dfc293dd9..697829297043 100644 --- a/tests/language/enum_shorthands/constructor/constructor_if_null_test.dart +++ b/tests/language/enum_shorthands/constructor/constructor_if_null_test.dart @@ -14,10 +14,20 @@ ConstructorClass ctorTest(ConstructorClass? ctor) => ctor ?? .new(1); ConstructorClass ctorRegularTest(ConstructorClass? ctor) => ctor ?? .regular(1); +void noContextLHSContext(ConstructorClass? ctor) { + ctor ?? .new(1); + ctor ?? .regular(1); +} + ConstructorExt ctorExtTest(ConstructorExt? ctor) => ctor ?? .new(1); ConstructorExt ctorExtRegularTest(ConstructorExt? ctor) => ctor ?? .regular(1); +void noContextLHSContextExt(ConstructorExt? ctor) { + ctor ?? .new(1); + ctor ?? .regular(1); +} + void main() { // Class var ctorDefault = ConstructorClass(2); @@ -28,6 +38,9 @@ void main() { Expect.isNotNull(ctorRegularTest(null)); Expect.equals(ctorRegularTest(ctorDefault), ctorDefault); + noContextLHSContext(null); + noContextLHSContext(ctorDefault); + // Extension type var ctorExtDefault = ConstructorExt(2); @@ -36,4 +49,7 @@ void main() { Expect.isNotNull(ctorExtRegularTest(null)); Expect.equals(ctorExtRegularTest(ctorExtDefault), ctorExtDefault); + + noContextLHSContextExt(null); + noContextLHSContextExt(ctorExtDefault); } diff --git a/tests/language/enum_shorthands/enum_shorthand_helper.dart b/tests/language/enum_shorthands/enum_shorthand_helper.dart index 308e41a7a643..97f969f25753 100644 --- a/tests/language/enum_shorthands/enum_shorthand_helper.dart +++ b/tests/language/enum_shorthands/enum_shorthand_helper.dart @@ -11,6 +11,7 @@ enum Color { red, green, blue } class Integer { static Integer get one => Integer(1); static Integer get two => Integer(2); + static Integer? get nullable => null; static const Integer constOne = const Integer._(1); static const Integer constTwo = const Integer._(2); final int integer; @@ -21,6 +22,7 @@ class Integer { extension type IntegerExt(int integer) { static IntegerExt get one => IntegerExt(1); static IntegerExt get two => IntegerExt(2); + static IntegerExt? get nullable => null; static const IntegerExt constOne = const IntegerExt._(1); static const IntegerExt constTwo = const IntegerExt._(2); const IntegerExt._(this.integer); @@ -29,6 +31,7 @@ extension type IntegerExt(int integer) { mixin IntegerMixin on Integer { static IntegerMixin get mixinOne => _IntegerWithMixin(1); static IntegerMixin get mixinTwo => _IntegerWithMixin(2); + static IntegerMixin? get mixinNullable => null; static const IntegerMixin mixinConstOne = const _IntegerWithMixin._(1); static const IntegerMixin mixinConstTwo = const _IntegerWithMixin._(2); } @@ -68,7 +71,9 @@ extension type ConstructorExt(int? x) { class StaticMember { static StaticMember member() => StaticMember(1); + static StaticMember? memberNullable() => null; static StaticMember memberType(U u) => StaticMember(u); + static StaticMember? memberTypeNullable(U u) => null; final T t; StaticMember(this.t); @@ -76,5 +81,7 @@ class StaticMember { extension type StaticMemberExt(T x) { static StaticMemberExt member() => StaticMemberExt(1); + static StaticMemberExt? memberNullable() => null; static StaticMemberExt memberType(U u) => StaticMemberExt(u); + static StaticMemberExt? memberTypeNullable(U u) => null; } diff --git a/tests/language/enum_shorthands/member/static_method_if_null_error_test.dart b/tests/language/enum_shorthands/member/static_method_if_null_error_test.dart new file mode 100644 index 000000000000..98be551df0b9 --- /dev/null +++ b/tests/language/enum_shorthands/member/static_method_if_null_error_test.dart @@ -0,0 +1,39 @@ +// Copyright (c) 2024, 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. + +// Errors with `??` and enum shorthands with static members. + +// SharedOptions=--enable-experiment=enum-shorthands + +import '../enum_shorthand_helper.dart'; + +void memberTest() { + StaticMember member = StaticMember.member(); + + // Warning when LHS is not able to be `null`. + StaticMember memberLocal = .member() ?? member; + // ^ + // [analyzer] unspecified + // [cfe] unspecified + + StaticMember memberType = .memberType("s") ?? member; + // ^ + // [analyzer] unspecified + // [cfe] unspecified +} + +void memberExtTest() { + StaticMemberExt member = StaticMemberExt.member(); + + // Warning when LHS is not able to be `null`. + StaticMemberExt memberLocal = .member() ?? member; + // ^ + // [analyzer] unspecified + // [cfe] unspecified + + StaticMemberExt memberType = .memberType("s") ?? member; + // ^ + // [analyzer] unspecified + // [cfe] unspecified +} diff --git a/tests/language/enum_shorthands/member/static_method_if_null_test.dart b/tests/language/enum_shorthands/member/static_method_if_null_test.dart index b4a98fd58d37..324d4a5a10ee 100644 --- a/tests/language/enum_shorthands/member/static_method_if_null_test.dart +++ b/tests/language/enum_shorthands/member/static_method_if_null_test.dart @@ -14,10 +14,20 @@ StaticMember memberTest(StaticMember? member) => member ?? .member(); StaticMember memberTypeTest(StaticMember? member) => member ?? .memberType("s"); +void noContextLHSContext(StaticMember? member) { + member ?? .member(); + member ?? .memberType("s"); +} + StaticMemberExt memberExtTest(StaticMemberExt? member) => member ?? .member(); StaticMemberExt memberExtTypeTest(StaticMemberExt? member) => member ?? .memberType("s"); +void noContextLHSContextExt(StaticMemberExt? member) { + member ?? .member(); + member ?? .memberType("s"); +} + void main() { // Class var memberDefault = StaticMember.memberType(100); @@ -28,6 +38,12 @@ void main() { Expect.isNotNull(memberTypeTest(null)); Expect.equals(memberTypeTest(memberDefault), memberDefault); + noContextLHSContext(null); + noContextLHSContext(memberDefault); + + StaticMember possiblyNullable = .memberNullable() ?? memberDefault; + StaticMember possiblyNullableWithType = .memberTypeNullable("s") ?? memberDefault; + // Extension type var memberExtDefault = StaticMemberExt.memberType(100); @@ -36,4 +52,10 @@ void main() { Expect.isNotNull(memberExtTypeTest(null)); Expect.equals(memberExtTypeTest(memberExtDefault), memberExtDefault); + + noContextLHSContextExt(null); + noContextLHSContextExt(memberExtDefault); + + StaticMemberExt possiblyNullableExt = .memberNullable() ?? memberExtDefault; + StaticMemberExt possiblyNullableExtWithType = .memberTypeNullable("s") ?? memberExtDefault; } diff --git a/tests/language/enum_shorthands/simple/simple_identifier_if_null_error_test.dart b/tests/language/enum_shorthands/simple/simple_identifier_if_null_error_test.dart new file mode 100644 index 000000000000..fe8ef8313a59 --- /dev/null +++ b/tests/language/enum_shorthands/simple/simple_identifier_if_null_error_test.dart @@ -0,0 +1,27 @@ +// Copyright (c) 2024, 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. + +// Errors with `??` and enum shorthands with static properties or enums. + +// SharedOptions=--enable-experiment=enum-shorthands + +import '../enum_shorthand_helper.dart'; + +void test() { + // Warning when LHS is not able to be `null`. + Color colorLocal = .blue ?? Color.red; + // ^ + // [analyzer] unspecified + // [cfe] unspecified + + Integer integerLocal = .one ?? Integer.two; + // ^ + // [analyzer] unspecified + // [cfe] unspecified + + IntegerMixin integerMixinLocal = .mixinOne ?? IntegerMixin.mixinTwo; + // ^ + // [analyzer] unspecified + // [cfe] unspecified +} diff --git a/tests/language/enum_shorthands/simple/simple_identifier_if_null_test.dart b/tests/language/enum_shorthands/simple/simple_identifier_if_null_test.dart index db28813e2034..488ee6a00e75 100644 --- a/tests/language/enum_shorthands/simple/simple_identifier_if_null_test.dart +++ b/tests/language/enum_shorthands/simple/simple_identifier_if_null_test.dart @@ -11,27 +11,62 @@ import 'package:expect/expect.dart'; Color colorTest(Color? color) => color ?? .blue; +void noContextLHSContextColor(Color? color) { + color ?? .blue; +} + Integer integerTest(Integer? integer) => integer ?? .one; +void noContextLHSContextInteger(Integer? integer) { + integer ?? .one; +} + IntegerExt integerExtTest(IntegerExt? integer) => integer ?? .one; +void noContextLHSContextIntegerExt(IntegerExt? integer) { + integer ?? .one; +} + IntegerMixin integerMixinTest(IntegerMixin? integer) => integer ?? .mixinOne; +void noContextLHSContextIntegerMixin(IntegerMixin? integer) { + integer ?? .mixinOne; +} + void main() { // Enum Expect.equals(colorTest(null), Color.blue); Expect.equals(colorTest(Color.red), Color.red); + noContextLHSContextColor(null); + noContextLHSContextColor(Color.red); + // Class Expect.equals(integerTest(null), Integer.one); Expect.equals(integerTest(Integer.two), Integer.two); + noContextLHSContextInteger(null); + noContextLHSContextInteger(Integer.one); + + Integer possiblyNullableInteger = .nullable ?? Integer.one; + // Extension type Expect.equals(integerExtTest(null), IntegerExt.one); Expect.equals(integerExtTest(IntegerExt.two), IntegerExt.two); + noContextLHSContextIntegerExt(null); + noContextLHSContextIntegerExt(IntegerExt.one); + + IntegerExt possiblyNullableIntegerExt = .nullable ?? IntegerExt.one; + IntegerExt possiblyNullableIntegerExt2 = .one ?? IntegerExt.one; + // Mixin Expect.equals(integerMixinTest(null), IntegerMixin.mixinOne); Expect.equals(integerMixinTest(IntegerMixin.mixinTwo), IntegerMixin.mixinTwo); + + noContextLHSContextIntegerMixin(null); + noContextLHSContextIntegerMixin(IntegerMixin.mixinOne); + + IntegerMixin possiblyNullableIntegerMixin = .mixinNullable ?? IntegerMixin.mixinOne; }