[tests] Declaring constructors - Tests for covariant modifier. Tests the following: - A compile-time error occurs if the formal parameter contains a term of the form `this.v`, or `super.v` where `v` is an identifier, and the parameter has the modifier `covariant`. - We allow formal parameters of a declaring constructor to have the `covariant` modifier with `var`. - It is an error for a formal parameter of a declaring constructor to be both `covariant` and `final`. - It is an error for a formal parameter of a declaring constructor to have the `covariant` modifier but not the `var` modifier. Bug: https://github.com/dart-lang/sdk/issues/61687 Change-Id: I6c2a258a3a5d02c9ec33ef944c3655917a4899fb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/454980 Commit-Queue: Kallen Tu <kallentu@google.com> Reviewed-by: Erik Ernst <eernst@google.com>
diff --git a/tests/language/declaring_constructors/syntax/covariant_super_this_error_test.dart b/tests/language/declaring_constructors/syntax/covariant_super_this_error_test.dart new file mode 100644 index 0000000..73ec92f --- /dev/null +++ b/tests/language/declaring_constructors/syntax/covariant_super_this_error_test.dart
@@ -0,0 +1,128 @@ +// 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. + +// A compile-time error occurs if the formal parameter contains a term of the +// form `this.v`, or `super.v` where `v` is an identifier, and the parameter has +// the modifier `covariant`. + +// SharedOptions=--enable-experiment=declaring-constructors + +// `covariant` with `this.x` + +// In-header declaring constructor +class C1(covariant this.x) { + // ^ + // [analyzer] unspecified + // [cfe] unspecified + int x; +} + + +class C2({covariant this.x}) { + // ^ + // [analyzer] unspecified + // [cfe] unspecified + int? x; +} + +class C3({required covariant this.x}) { + // ^ + // [analyzer] unspecified + // [cfe] unspecified + int x; +} + +class C4([covariant this.x]) { + // ^ + // [analyzer] unspecified + // [cfe] unspecified + int? x; +} + +// In-body declaring constructor +class C5 { + int? x; + this(covariant this.x); + // ^ + // [analyzer] unspecified + // [cfe] unspecified +} + +class C6 { + int x; + this({covariant this.x}); + // ^ + // [analyzer] unspecified + // [cfe] unspecified +} + +class C7 { + int x; + this({required covariant this.x}); + // ^ + // [analyzer] unspecified + // [cfe] unspecified +} + +class C8 { + int? x; + this([covariant this.x]); + // ^ + // [analyzer] unspecified + // [cfe] unspecified +} + +// `covariant` with `super.x` + +class A(final int? x); + +// In-header declaring constructor +class C9(covariant super.x) extends A; +// ^ +// [analyzer] unspecified +// [cfe] unspecified + +class C10({covariant super.x}) extends A; +// ^ +// [analyzer] unspecified +// [cfe] unspecified + +class C11({required covariant super.x}) extends A; +// ^ +// [analyzer] unspecified +// [cfe] unspecified + +class C12([covariant super.x]) extends A; +// ^ +// [analyzer] unspecified +// [cfe] unspecified + +// In-body declaring constructor +class C13 extends A { + this(covariant super.x); + // ^ + // [analyzer] unspecified + // [cfe] unspecified +} + +class C14 extends A { + this({covariant super.x}); + // ^ + // [analyzer] unspecified + // [cfe] unspecified +} + +class C15 extends A { + this({required covariant super.x}); + // ^ + // [analyzer] unspecified + // [cfe] unspecified +} + +class C16 extends A { + this([covariant super.x]); + // ^ + // [analyzer] unspecified + // [cfe] unspecified +}
diff --git a/tests/language/declaring_constructors/syntax/covariant_var_test.dart b/tests/language/declaring_constructors/syntax/covariant_var_test.dart new file mode 100644 index 0000000..7365064 --- /dev/null +++ b/tests/language/declaring_constructors/syntax/covariant_var_test.dart
@@ -0,0 +1,83 @@ +// 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. + +// Allow the modifier `covariant` in declaring parameters. + +// SharedOptions=--enable-experiment=declaring-constructors + +import 'package:expect/expect.dart'; + +class A {} +class B extends A {} + +class C1(covariant var A x); +class D1(var B x) implements C1; + +class C2({covariant var A? x}); +class D2({var B? x}) implements C2; + +class C3({required covariant var A x}); +class D3({required var B x}) implements C2; + +class C4([covariant var A? x]); +class D4([var B? x]) implements C2; + +class C5 { + this(covariant var A x); +} +class D5 implements C5 { + this(var B x); +} + +class C6 { + this({covariant var A? x}); +} +class D6 { + this({var B? x}); +} + +class C7 { + this({required covariant var A x}); +} +class D7 { + this({required var B x}); +} + +class C8 { + this([covariant var A? x]); +} +class D8 { + this([var B? x]); +} + +void main() { + A a = A(); + B b = B(); + + // In-header + Expect.equals(a, C1(a).x); + Expect.equals(b, D1(b).x); + + Expect.equals(a, C2(x: a).x); + Expect.equals(b, D2(x: b).x); + + Expect.equals(a, C3(x: a).x); + Expect.equals(b, D3(x: b).x); + + Expect.equals(a, C4(a).x); + Expect.equals(b, D4(b).x); + + // In-body + Expect.equals(a, C5(a).x); + Expect.equals(b, D5(b).x); + + Expect.equals(a, C6(x: a).x); + Expect.equals(b, D6(x: b).x); + + Expect.equals(a, C7(x: a).x); + Expect.equals(b, D7(x: b).x); + + Expect.equals(a, C8(a).x); + Expect.equals(b, D8(b).x); +}
diff --git a/tests/language/declaring_constructors/syntax/covariant_with_final_error_test.dart b/tests/language/declaring_constructors/syntax/covariant_with_final_error_test.dart new file mode 100644 index 0000000..268162e --- /dev/null +++ b/tests/language/declaring_constructors/syntax/covariant_with_final_error_test.dart
@@ -0,0 +1,65 @@ +// 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. + +// It is an error for a formal parameter to be both `covariant` and `final`. + +// SharedOptions=--enable-experiment=declaring-constructors + +class C1(covariant final int x); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + +class C2({covariant final int? x = 1}); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + +class C3({required covariant final int x}); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + +class C4([covariant final int? x]); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + +class C5 { + this(covariant final int x); + // ^ + // [analyzer] unspecified + // [cfe] unspecified +} + +class C6 { + this({covariant final int? x}); + // ^ + // [analyzer] unspecified + // [cfe] unspecified +} + +class C7 { + this({required covariant final int x}); + // ^ + // [analyzer] unspecified + // [cfe] unspecified +} + +class C8 { + this([covariant final int? x]); + // ^ + // [analyzer] unspecified + // [cfe] unspecified +} + +extension type E1(covariant final int x); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + +extension type E2(covariant int x); +// ^ +// [analyzer] unspecified +// [cfe] unspecified
diff --git a/tests/language/declaring_constructors/syntax/covariant_without_var_error_test.dart b/tests/language/declaring_constructors/syntax/covariant_without_var_error_test.dart new file mode 100644 index 0000000..b141b5c --- /dev/null +++ b/tests/language/declaring_constructors/syntax/covariant_without_var_error_test.dart
@@ -0,0 +1,57 @@ +// 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. + +// It is an error for a formal parameter to have the `covariant` modifier +// but not the `var` modifier. + +// SharedOptions=--enable-experiment=declaring-constructors + +class C1(covariant int x); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + +class C2({covariant int? x}); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + +class C3({required covariant int x}); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + +class C4([covariant int? x]); +// ^ +// [analyzer] unspecified +// [cfe] unspecified + + +class C5 { + this(covariant int x); + // ^ + // [analyzer] unspecified + // [cfe] unspecified +} + +class C6 { + this({covariant int? x}); + // ^ + // [analyzer] unspecified + // [cfe] unspecified +} + +class C7 { + this({required covariant int x}); + // ^ + // [analyzer] unspecified + // [cfe] unspecified +} + +class C8 { + this([covariant int? x]); + // ^ + // [analyzer] unspecified + // [cfe] unspecified +}