diff --git a/LanguageFeatures/Static-access-shorthand/constant_expression_A01_t01.dart b/LanguageFeatures/Static-access-shorthand/constant_expression_A01_t01.dart new file mode 100644 index 0000000000..363f7a4c67 --- /dev/null +++ b/LanguageFeatures/Static-access-shorthand/constant_expression_A01_t01.dart @@ -0,0 +1,54 @@ +// 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. + +/// @assertion Given an expression that is a prefix of +/// ` *`, whose assigned shorthand context +/// denotes a declaration D, and where the identifier or `new` of the +/// `` denotes a static declaration or constructor +/// declaration S when looked up on D. +/// - An expression of the form `const .id(arguments)` or +/// `const .new(arguments)` is a constant expression. It's a compile-time +/// error if S does not declare a constant constructor, and if any expression +/// in `arguments`, which are all in a constant context, is not a constant +/// expression. +/// +/// @description Checks that expressions of the form `const '.' id(arguments)` +/// and `const '.' new(arguments)` are constant expressions. +/// @author sgrekhov22@gmail.com + +// SharedOptions=--enable-experiment=enum-shorthands + +import '../../Utils/expect.dart'; + +class C { + final String value; + const C(this.value); + const C.id(this.value); + const factory C.f(String value) = C; +} + +extension type const ET(String value) { + const ET.id(this.value); + const factory ET.f(String value) = ET; +} + +main() { + const C c1 = const .new("one"); + Expect.equals("one", c1.value); + + const C c2 = const .id("two"); + Expect.equals("two", c2.value); + + const C c3 = const .f("three"); + Expect.equals("three", c3.value); + + const ET et1 = const .new("new"); + Expect.equals("new", et1.value); + + const ET et2 = const .id("id"); + Expect.equals("id", et2.value); + + const ET et3 = const .f("f"); + Expect.equals("f", et3.value); +} diff --git a/LanguageFeatures/Static-access-shorthand/constant_expression_A01_t02.dart b/LanguageFeatures/Static-access-shorthand/constant_expression_A01_t02.dart new file mode 100644 index 0000000000..130d0e5a08 --- /dev/null +++ b/LanguageFeatures/Static-access-shorthand/constant_expression_A01_t02.dart @@ -0,0 +1,65 @@ +// 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. + +/// @assertion Given an expression that is a prefix of +/// ` *`, whose assigned shorthand context +/// denotes a declaration D, and where the identifier or `new` of the +/// `` denotes a static declaration or constructor +/// declaration S when looked up on D. +/// - An expression of the form `const .id(arguments)` or +/// `const .new(arguments)` is a constant expression. It's a compile-time +/// error if S does not declare a constant constructor, and if any expression +/// in `arguments`, which are all in a constant context, is not a constant +/// expression. +/// +/// @description Checks that it's a compile-time error to use expressions of the +/// form `const '.' id(arguments)` or `const '.' new(arguments)` if constructors +/// in an appropriate declaration are not constant constructors. +/// @author sgrekhov22@gmail.com + +// SharedOptions=--enable-experiment=enum-shorthands + +class C { + final String value; + C(this.value); + C.id(this.value); + factory C.f(String value) = C; +} + +extension type ET(String value) { + ET.id(this.value); + factory ET.f(String value) = ET; +} + +main() { + const C c1 = const .new("one"); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + + const C c2 = const .id("two"); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + + const C c3 = const .f("three"); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + + const ET et1 = const .new("new"); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + + const ET et2 = const .id("id"); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + + const ET et3 = const .f("f"); +// ^ +// [analyzer] unspecified +// [cfe] unspecified +} diff --git a/LanguageFeatures/Static-access-shorthand/constant_expression_A01_t03.dart b/LanguageFeatures/Static-access-shorthand/constant_expression_A01_t03.dart new file mode 100644 index 0000000000..39c4dfb065 --- /dev/null +++ b/LanguageFeatures/Static-access-shorthand/constant_expression_A01_t03.dart @@ -0,0 +1,96 @@ +// 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. + +/// @assertion Given an expression that is a prefix of +/// ` *`, whose assigned shorthand context +/// denotes a declaration D, and where the identifier or `new` of the +/// `` denotes a static declaration or constructor +/// declaration S when looked up on D. +/// - An expression of the form `const .id(arguments)` or +/// `const .new(arguments)` is a constant expression. It's a compile-time +/// error if S does not declare a constant constructor, and if any expression +/// in `arguments`, which are all in a constant context, is not a constant +/// expression. +/// +/// @description Checks that it's a compile-time error to use expressions of the +/// form `const '.' id(arguments)` or `const '.' new(arguments)` if any +/// expression in `arguments` is not a constant expression. +/// @author sgrekhov22@gmail.com + +// SharedOptions=--enable-experiment=enum-shorthands + +class C { + final String value; + const C(this.value, [String s = ""]); + const C.id(this.value, {String s = ""}); + const factory C.f(String value) = C; +} + +extension type const ET(String value) { + const ET.id(this.value, [String s = ""]); + const factory ET.f(String value, {String s = ""}) = ET; +} + +main() { + String s = "Not a constant"; + const C c1 = const .new(s); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + + const C c2 = const .new("one", s); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + + const C c3 = const .id(s); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + + const C c4 = const .id("two", s: s); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + + const C c5 = const .f(s); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + + const C c6 = const .f("three", s: s); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + + const ET et1 = const .new(s); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + + const ET et2 = const .new("new", s); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + + const ET et3 = const .id(s); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + + const ET et4 = const .id("id", s); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + + const ET et5 = const .f(s); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + + const ET et6 = const .f("f", s: s); +// ^ +// [analyzer] unspecified +// [cfe] unspecified +} diff --git a/LanguageFeatures/Static-access-shorthand/constant_expression_A02_t01.dart b/LanguageFeatures/Static-access-shorthand/constant_expression_A02_t01.dart new file mode 100644 index 0000000000..0a12a6d4d5 --- /dev/null +++ b/LanguageFeatures/Static-access-shorthand/constant_expression_A02_t01.dart @@ -0,0 +1,47 @@ +// 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. + +/// @assertion Given an expression that is a prefix of +/// ` *`, whose assigned shorthand context +/// denotes a declaration D, and where the identifier or `new` of the +/// `` denotes a static declaration or constructor +/// declaration S when looked up on D. +/// ... +/// - An expression of the form `.` is a constant expression if S +/// declares a constant getter. +/// +/// @description Checks that expressions of the form `'.' ` is a +/// constant expression if the appropriate declaration declares a constant +/// getter with the name ``. +/// @author sgrekhov22@gmail.com + +// SharedOptions=--enable-experiment=enum-shorthands + +import '../../Utils/expect.dart'; + +class C { + final String value; + static const C instance = C("C instance"); + + const C(this.value); +} + +mixin M { + final String value; + static const M instance = MO("M instance"); +} + +class MO = Object with M; + +extension type const ET(String value) { + static const instance = ET("ET instance"); +} + +main() { + const C c = .instance; + Expect.equals("C instance", c.value); + + const ET et = .instance; + Expect.equals("ET instance", et.value); +} diff --git a/LanguageFeatures/Static-access-shorthand/constant_expression_A02_t02.dart b/LanguageFeatures/Static-access-shorthand/constant_expression_A02_t02.dart new file mode 100644 index 0000000000..c40988e628 --- /dev/null +++ b/LanguageFeatures/Static-access-shorthand/constant_expression_A02_t02.dart @@ -0,0 +1,42 @@ +// 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. + +/// @assertion Given an expression that is a prefix of +/// ` *`, whose assigned shorthand context +/// denotes a declaration D, and where the identifier or `new` of the +/// `` denotes a static declaration or constructor +/// declaration S when looked up on D. +/// ... +/// - An expression of the form `.` is a constant expression if S +/// declares a constant getter. +/// +/// @description Checks that it is a compile-time error to use an expressions of +/// the form `'.' ` in a constant context if `` is an +/// explicit getter declaration. +/// @author sgrekhov22@gmail.com + +// SharedOptions=--enable-experiment=enum-shorthands + +class C { + final String value; + static C get instance => const C("C instance"); + + const C(this.value); +} + +extension type const ET(String value) { + static ET get instance => const ET("ET instance"); +} + +main() { + const C c = .instance; +// ^ +// [analyzer] unspecified +// [cfe] unspecified + + const ET et = .instance; +// ^ +// [analyzer] unspecified +// [cfe] unspecified +} diff --git a/LanguageFeatures/Static-access-shorthand/constant_expression_A06_t01.dart b/LanguageFeatures/Static-access-shorthand/constant_expression_A06_t01.dart new file mode 100644 index 0000000000..86d4393d0a --- /dev/null +++ b/LanguageFeatures/Static-access-shorthand/constant_expression_A06_t01.dart @@ -0,0 +1,36 @@ +// 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. + +/// @assertion Given an expression that is a prefix of +/// ` *`, whose assigned shorthand context +/// denotes a declaration D, and where the identifier or `new` of the +/// `` denotes a static declaration or constructor +/// declaration S when looked up on D. +/// ... +/// - (An expression of the form `.new` followed by a `` is still +/// a compile-time error.) +/// +/// @description Checks that an expression of the form `'.' new` followed by a +/// `` is still a compile-time error. +/// @author sgrekhov22@gmail.com + +// SharedOptions=--enable-experiment=enum-shorthands + +class C { + const C(); +} + +extension type const ET(T _) {} + +main() { + const C c = const .new(); +// ^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + + const ET et = const .new(0); +// ^^^^^ +// [analyzer] unspecified +// [cfe] unspecified +} diff --git a/LanguageFeatures/Static-access-shorthand/constant_expression_A07_t01.dart b/LanguageFeatures/Static-access-shorthand/constant_expression_A07_t01.dart new file mode 100644 index 0000000000..48e13b9477 --- /dev/null +++ b/LanguageFeatures/Static-access-shorthand/constant_expression_A07_t01.dart @@ -0,0 +1,54 @@ +// 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. + +/// @assertion Given an expression that is a prefix of +/// ` *`, whose assigned shorthand context +/// denotes a declaration D, and where the identifier or `new` of the +/// `` denotes a static declaration or constructor +/// declaration S when looked up on D. +/// ... +/// - 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. +/// +/// @description Checks that an expression of the form `'.' id(arguments)` or +/// `'.' new(arguments)` is not a constant expression if inferred type arguments +/// are not constant types. +/// @author sgrekhov22@gmail.com + +// SharedOptions=--enable-experiment=enum-shorthands + +class C { + const C(); + const C.id(); +} + +extension type const ET(int _) { + const ET.id(this._); +} + +void foo() { + C()> c1 = const .new(); +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified + C(), int> c2 = const .id(); +// ^^^ +// [analyzer] unspecified +// [cfe] unspecified + ET()> et1 = const .new(0); +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified + ET(), int> et2 = const .id(0); +// ^^^ +// [analyzer] unspecified +// [cfe] unspecified +} + +main() { + foo(); +} diff --git a/LanguageFeatures/Static-access-shorthand/constant_expression_A08_t01.dart b/LanguageFeatures/Static-access-shorthand/constant_expression_A08_t01.dart new file mode 100644 index 0000000000..b879cd230f --- /dev/null +++ b/LanguageFeatures/Static-access-shorthand/constant_expression_A08_t01.dart @@ -0,0 +1,72 @@ +// 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. + +/// @assertion Given an expression that is a prefix of +/// ` *`, whose assigned shorthand context +/// denotes a declaration D, and where the identifier or `new` of the +/// `` denotes a static declaration or constructor +/// declaration S when looked up on D. +/// ... +/// - An expression of `.id(arguments)` or `.id(arguments)` where +/// S declares a getter or static function is never a constant expression. +/// There are no static functions whose invocation is constant, the only +/// non-instance function which can be invoked as a constant expression is +/// identical, which is not inside a static namespace. +/// +/// @description Checks that an expression of the form `'.' id(arguments)` is +/// not a constant expression if `id` is a getter or static function declaration +/// @author sgrekhov22@gmail.com + +// SharedOptions=--enable-experiment=enum-shorthands + +class C { + const C(); + static C get id1 => const C(); + static C id2() => const C(); + + C call() => const C(); +} + +extension type const ET(int _) { + static ET get id1 => const ET(0); + static ET id2() => const ET(0); +} + +main() { + C nc1 = .id1; // Ok + const C c1 = .id1; +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified + + C nc2 = .id1(); + const C c2 = .id1(); +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified + + C nc3 = .id2(); + const C c3 = .id2(); +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified + + ET net1 = .id1; + const ET et1 = .id1; +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified + + ET net2 = .id1(); + const ET et2 = .id1(); +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified + + ET net3 = .id2(); + const ET et3 = .id2(); +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified +} diff --git a/LanguageFeatures/Static-access-shorthand/constant_expression_A08_t02.dart b/LanguageFeatures/Static-access-shorthand/constant_expression_A08_t02.dart new file mode 100644 index 0000000000..5eb4eeacfd --- /dev/null +++ b/LanguageFeatures/Static-access-shorthand/constant_expression_A08_t02.dart @@ -0,0 +1,45 @@ +// 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. + +/// @assertion Given an expression that is a prefix of +/// ` *`, whose assigned shorthand context +/// denotes a declaration D, and where the identifier or `new` of the +/// `` denotes a static declaration or constructor +/// declaration S when looked up on D. +/// ... +/// - An expression of `.id(arguments)` or `.id(arguments)` where +/// S declares a getter or static function is never a constant expression. +/// There are no static functions whose invocation is constant, the only +/// non-instance function which can be invoked as a constant expression is +/// identical, which is not inside a static namespace. +/// +/// @description Checks that an expression of the form +/// `'.' id(arguments)` is not a constant expression if `id` is a +/// static function declaration. +/// @author sgrekhov22@gmail.com + +// SharedOptions=--enable-experiment=enum-shorthands + +class C { + const C(); + static C id() => const C(); +} + +extension type const ET(int _) { + static ET id() => const ET(0); +} + +main() { + C nc = .id(); // Ok + const C c = .id(); +// ^^^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + + ET net = .id(); + const ET et = .id(); +// ^^^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified +}