Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#2976. Add more tests for nullable and FutureOr types #3050

Merged
merged 3 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/// declaration S when looked up on D.
/// ...
/// - An expression of the form `.<identifier>` is a constant expression if S
/// declares a constant getter.
/// declares a corresponding static constant getter.
///
/// @description Checks that expressions of the form `'.' <identifier>` is a
/// constant expression if the appropriate declaration declares a constant
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,46 @@
/// declaration S when looked up on D.
/// ...
/// - An expression of the form `.<identifier>` is a constant expression if S
/// declares a constant getter.
/// declares a corresponding static constant getter.
///
/// @description Checks that it is a compile-time error to use an expressions of
eernstg marked this conversation as resolved.
Show resolved Hide resolved
/// the form `'.' <identifier>` in a constant context if `<identifier>` is an
/// explicit getter declaration.
/// explicit or implicit getter declaration.
eernstg marked this conversation as resolved.
Show resolved Hide resolved
/// @author sgrekhov22@gmail.com

// SharedOptions=--enable-experiment=enum-shorthands

class C {
final String value;
static C get instance => const C("C instance");
static C get instance1 => const C("C instance1");
static final C instance2 = const C("C instance2");

const C(this.value);
}

extension type const ET(String value) {
static ET get instance => const ET("ET instance");
static ET get instance1 => const ET("ET instance1");
static final ET instance2 = const ET("ET instance2");
}

main() {
const C c = .instance;
// ^
const C c1 = .instance1;
eernstg marked this conversation as resolved.
Show resolved Hide resolved
// ^
// [analyzer] unspecified
// [cfe] unspecified

const ET et = .instance;
// ^
const C c2 = .instance2;
// ^
// [analyzer] unspecified
// [cfe] unspecified

const ET et1 = .instance1;
// ^
// [analyzer] unspecified
// [cfe] unspecified

const ET et2 = .instance2;
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
/// ...
/// - An expression of `.id(arguments)` or `.new(arguments)` is a constant
/// expression if (and only if) it occurs in a constant context, S declares a
/// constant constructor, every expression in arguments (which then occurs in
/// a constant context too) is a constant expression, and inferred type
/// arguments, if any, are all constant types.
/// corresponding constant constructor, every expression in arguments (which
eernstg marked this conversation as resolved.
Show resolved Hide resolved
/// then occurs in a constant context too) is a constant expression, and
/// inferred type arguments to the target class, if any, are all constant
/// types.
///
/// @description Checks that an expression of the form `'.' id(arguments)` or
/// `'.' new(arguments)` is not a constant expression if inferred type arguments
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) 2025, 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.

/// @assertion It is a conspicuous special-casing to allow `int?` to denote a
/// static namespace, but it’s special casing of a type that we otherwise
/// special-case all the time.
///
/// It allows `int? v = .tryParse(42);` to work. That’s a pretty good reason. It
/// also allows `int x = .tryParse(input) ?? 0;` to work, which it wouldn’t
/// otherwise because the context type of `.tryParse(input)` is `int?`.
///
/// @description Checks that static access shorthand can be used with nullable
eernstg marked this conversation as resolved.
Show resolved Hide resolved
/// types. Test a class.
/// @author sgrekhov22@gmail.com

// SharedOptions=--enable-experiment=enum-shorthands

import '../../Utils/expect.dart';

class C<T> {
T value;
C(this.value);
C.id(this.value);
factory C.f(T t) = C;

static C<int> get staticGetter => C(4);
static C<X> staticMethod<X>(X x) => C<X>(x);
static List<C<String>> instances = [C("one")];
}

main() {
C? c1 = .new(1);
Expect.equals(1, c1.value);

C? c2 = .id(2);
Expect.equals(2, c2.value);

C? c3 = .f(3);
Expect.equals(3, c3.value);

C<int>? c4 = .staticGetter;
Expect.equals(4, c4.value);

C<int>? c5 = .staticMethod<int>(5);
Expect.equals(5, c5.value);

List<C<String>?> c6 = .instances;
Expect.equals("one", c6[0]?.value);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) 2025, 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.

/// @assertion It is a conspicuous special-casing to allow `int?` to denote a
/// static namespace, but it’s special casing of a type that we otherwise
/// special-case all the time.
///
/// It allows `int? v = .tryParse(42);` to work. That’s a pretty good reason. It
/// also allows `int x = .tryParse(input) ?? 0;` to work, which it wouldn’t
/// otherwise because the context type of `.tryParse(input)` is `int?`.
///
/// @description Checks that static access shorthand can be used with nullable
eernstg marked this conversation as resolved.
Show resolved Hide resolved
/// union types. Test a class.
/// @author sgrekhov22@gmail.com

// SharedOptions=--enable-experiment=enum-shorthands

import 'dart:async';
import '../../Utils/expect.dart';

class C<T> {
T value;
C(this.value);
C.id(this.value);
factory C.f(T t) = C;

static C<int> get staticGetter => C(4);
static C<X> staticMethod<X>(X x) => C<X>(x);
static List<C<String>> instances = [C("one")];
}

main() async {
FutureOr<C?>? c1 = .new(1);
Expect.equals(1, (await c1)?.value);

FutureOr<C?>? c2 = .id(2);
Expect.equals(2, (await c2)?.value);

FutureOr<C?>? c3 = .f(3);
Expect.equals(3, (await c3)?.value);

FutureOr<C<int>?>? c4 = .staticGetter;
Expect.equals(4, (await c4)?.value);

FutureOr<C<int>?>? c5 = .staticMethod<int>(5);
Expect.equals(5, (await c5)?.value);

FutureOr<List<C<String>?>?>? c6 = .instances;
eernstg marked this conversation as resolved.
Show resolved Hide resolved
Expect.equals("one", (await c6)![0]?.value);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) 2025, 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.

/// @assertion It is a conspicuous special-casing to allow `int?` to denote a
/// static namespace, but it’s special casing of a type that we otherwise
/// special-case all the time.
///
/// It allows `int? v = .tryParse(42);` to work. That’s a pretty good reason. It
/// also allows `int x = .tryParse(input) ?? 0;` to work, which it wouldn’t
/// otherwise because the context type of `.tryParse(input)` is `int?`.
///
/// @description Checks that static access shorthand can be used with nullable
eernstg marked this conversation as resolved.
Show resolved Hide resolved
/// types. Test a mixin.
/// @author sgrekhov22@gmail.com

// SharedOptions=--enable-experiment=enum-shorthands

import '../../Utils/expect.dart';

class C<T> {
T value;
C(this.value);
}

mixin M<T> on C<T> {
static M<int> get staticGetter => MC(1);
static M<X> staticMethod<X>(X x) => MC<X>(x);
static List<M<String>> instances = [MC("one")];

@override
bool operator ==(Object other) {
if (other is C) {
return value == other.value;
}
return false;
}
}

class MC<T> = C<T> with M<T>;

main() {
M<int>? m1 = .staticGetter;
Expect.equals(MC(1), m1);

M<int>? m2 = .staticMethod<int>(2);
Expect.equals(MC(2), m2);

List<M<String>?> m3 = .instances;
eernstg marked this conversation as resolved.
Show resolved Hide resolved
Expect.equals(MC("one"), m3[0]);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) 2025, 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.

/// @assertion It is a conspicuous special-casing to allow `int?` to denote a
/// static namespace, but it’s special casing of a type that we otherwise
/// special-case all the time.
///
/// It allows `int? v = .tryParse(42);` to work. That’s a pretty good reason. It
/// also allows `int x = .tryParse(input) ?? 0;` to work, which it wouldn’t
/// otherwise because the context type of `.tryParse(input)` is `int?`.
eernstg marked this conversation as resolved.
Show resolved Hide resolved
///
/// @description Checks that static access shorthand can be used with nullable
eernstg marked this conversation as resolved.
Show resolved Hide resolved
/// union types. Test a mixin.
/// @author sgrekhov22@gmail.com

// SharedOptions=--enable-experiment=enum-shorthands

import 'dart:async';
import '../../Utils/expect.dart';

class C<T> {
T value;
C(this.value);
}

mixin M<T> on C<T> {
static M<int> get staticGetter => MC(1);
static M<X> staticMethod<X>(X x) => MC<X>(x);
static List<M<String>> instances = [MC("one")];

@override
bool operator ==(Object other) {
if (other is C) {
return value == other.value;
}
return false;
}
}

class MC<T> = C<T> with M<T>;

main() async {
FutureOr<M<int>?>? m1 = .staticGetter;
Expect.equals(MC(1), await m1);

FutureOr<M<int>?>? m2 = .staticMethod<int>(2);
Expect.equals(MC(2), await m2);

FutureOr<List<M<String>?>?>? m3 = .instances;
Expect.equals(MC("one"), (await m3)![0]);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) 2025, 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.

/// @assertion It is a conspicuous special-casing to allow `int?` to denote a
/// static namespace, but it’s special casing of a type that we otherwise
/// special-case all the time.
///
/// It allows `int? v = .tryParse(42);` to work. That’s a pretty good reason. It
/// also allows `int x = .tryParse(input) ?? 0;` to work, which it wouldn’t
/// otherwise because the context type of `.tryParse(input)` is `int?`.
///
/// @description Checks that static access shorthand can be used with nullable
eernstg marked this conversation as resolved.
Show resolved Hide resolved
/// types. Test an enum.
/// @author sgrekhov22@gmail.com

// SharedOptions=--enable-experiment=enum-shorthands

import '../../Utils/expect.dart';

enum E<T> {
e1(1), e2(2), e3("3"), e4("4");
final T value;
const E(this.value);

static E<int> get staticGetter => E.e1;
static E staticMethod() => E.e2;
static List<E<String>> instances = [E.e3];
}

main() {
E<int>? e1 = .staticGetter;
Expect.equals(E.e1, e1);

E? e2 = .staticMethod();
Expect.equals(E.e2, e2);

List<E<String>?> e3 = .instances;
Expect.equals(E.e3, e3[0]);

E<String>? e4 = .e4;
Expect.equals(E.e4, e4);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) 2025, 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.

/// @assertion It is a conspicuous special-casing to allow `int?` to denote a
/// static namespace, but it’s special casing of a type that we otherwise
/// special-case all the time.
///
/// It allows `int? v = .tryParse(42);` to work. That’s a pretty good reason. It
/// also allows `int x = .tryParse(input) ?? 0;` to work, which it wouldn’t
/// otherwise because the context type of `.tryParse(input)` is `int?`.
///
/// @description Checks that static access shorthand can be used with nullable
eernstg marked this conversation as resolved.
Show resolved Hide resolved
/// union types. Test an enum.
/// @author sgrekhov22@gmail.com

// SharedOptions=--enable-experiment=enum-shorthands

import 'dart:async';
import '../../Utils/expect.dart';

enum E<T> {
e1(1), e2(2), e3("3"), e4("4");
final T value;
const E(this.value);

static E<int> get staticGetter => E.e1;
static E staticMethod() => E.e2;
static List<E<String>> instances = [E.e3];
}

main() async {
FutureOr<E<int>?>? e1 = .staticGetter;
Expect.equals(E.e1, await e1);

FutureOr<E?>? e2 = .staticMethod();
Expect.equals(E.e2, await e2);

FutureOr<List<E<String>?>?>? e3 = .instances;
Expect.equals(E.e3, (await e3)![0]);

FutureOr<E<String>?>? e4 = .e4;
Expect.equals(E.e4, await e4);
}
Loading
Loading