Skip to content

Commit

Permalink
[tests] Additional tests for ?? with enum shorthands.
Browse files Browse the repository at this point in the history
Tests for `??` where context is from LHS and warnings when LHS is not nullable.

Context: https://dart-review.googlesource.com/c/sdk/+/399520/comments/ee1b4e32_2a0ed6e7

Bug: #57038
Change-Id: I563d54b447e90f97fbea1a972f2e06c2cc23c8fe
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/401140
Commit-Queue: Kallen Tu <kallentu@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
  • Loading branch information
kallentu authored and Commit Queue committed Dec 17, 2024
1 parent e1be04c commit b67f61a
Show file tree
Hide file tree
Showing 7 changed files with 205 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);

Expand All @@ -36,4 +49,7 @@ void main() {

Expect.isNotNull(ctorExtRegularTest(null));
Expect.equals(ctorExtRegularTest(ctorExtDefault), ctorExtDefault);

noContextLHSContextExt(null);
noContextLHSContextExt(ctorExtDefault);
}
7 changes: 7 additions & 0 deletions tests/language/enum_shorthands/enum_shorthand_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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);
}
Expand Down Expand Up @@ -68,13 +71,17 @@ extension type ConstructorExt(int? x) {

class StaticMember<T> {
static StaticMember<int> member() => StaticMember(1);
static StaticMember<int>? memberNullable() => null;
static StaticMember<U> memberType<U, V>(U u) => StaticMember(u);
static StaticMember<U>? memberTypeNullable<U, V>(U u) => null;

final T t;
StaticMember(this.t);
}

extension type StaticMemberExt<T>(T x) {
static StaticMemberExt<int> member() => StaticMemberExt(1);
static StaticMemberExt<int>? memberNullable() => null;
static StaticMemberExt<U> memberType<U, V>(U u) => StaticMemberExt(u);
static StaticMemberExt<U>? memberTypeNullable<U, V>(U u) => null;
}
Original file line number Diff line number Diff line change
@@ -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<String, int>("s") ?? member;
// ^
// [analyzer] unspecified
// [cfe] unspecified
}

void memberExtTest() {
StaticMemberExt<int> member = StaticMemberExt.member();

// Warning when LHS is not able to be `null`.
StaticMemberExt memberLocal = .member() ?? member;
// ^
// [analyzer] unspecified
// [cfe] unspecified

StaticMemberExt memberType = .memberType<String, int>("s") ?? member;
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,20 @@ StaticMember memberTest(StaticMember? member) => member ?? .member();

StaticMember memberTypeTest(StaticMember? member) => member ?? .memberType<String, int>("s");

void noContextLHSContext(StaticMember? member) {
member ?? .member();
member ?? .memberType<String, int>("s");
}

StaticMemberExt memberExtTest(StaticMemberExt? member) => member ?? .member();

StaticMemberExt memberExtTypeTest(StaticMemberExt? member) => member ?? .memberType<String, int>("s");

void noContextLHSContextExt(StaticMemberExt? member) {
member ?? .member();
member ?? .memberType<String, int>("s");
}

void main() {
// Class
var memberDefault = StaticMember.memberType<int, int>(100);
Expand All @@ -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<String, int>("s") ?? memberDefault;

// Extension type
var memberExtDefault = StaticMemberExt.memberType(100);

Expand All @@ -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<String, int>("s") ?? memberExtDefault;
}
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

0 comments on commit b67f61a

Please sign in to comment.