diff --git a/LanguageFeatures/Declaring-constructors/static_processing_A11_t01.dart b/LanguageFeatures/Declaring-constructors/static_processing_A11_t01.dart index 4c7ff91680..e55c993f70 100644 --- a/LanguageFeatures/Declaring-constructors/static_processing_A11_t01.dart +++ b/LanguageFeatures/Declaring-constructors/static_processing_A11_t01.dart @@ -15,12 +15,15 @@ /// Where no processing is mentioned below, `D2` is identical to `D`. Changes /// occur as follows: /// -/// Assume that `p` is an formal parameter in `D` which has the modifier `var` -/// or the modifier `final` (that is, p is a declaring parameter). +/// Let `p` be a formal parameter in `k` which has the modifier `var` or the +/// modifier `final` (that is, `p` is a declaring parameter). /// -/// Assume that the combined member signature for a getter with the same name as -/// `p` from the superinterfaces of `D` exists, and has return type `T`. In that -/// case the parameter `p` has declared type `T` as well. +/// Consider the situation where `p` has no type annotation: +/// - if combined member signature for a getter with the same name as `p` from +/// the superinterfaces of `D` exists and has return type `T`, the parameter +/// `p` has declared type `T`. If no such getter exists, but a setter with the +/// same basename exists, with a formal parameter whose type is `T`, the +/// parameter `p` has declared type `T`. /// /// @description Check that if the combined member signature for a getter with /// the same name as `p` from the superinterfaces of `D` exists, and has return @@ -58,6 +61,10 @@ class C5(var x, {var y = 2}) extends A2; class C6(final x, {final y = 3}) extends A3; +class C7(var x, {required var y}) extends A1; + +class C8(final x, {required final y}) extends A2; + main() { C1(1).x.expectStaticType>(); C1(1).y.expectStaticType>(); @@ -71,4 +78,8 @@ main() { C5(5).y.expectStaticType>(); C6(6).x.expectStaticType>(); C6(6).y.expectStaticType>(); + C7(7, y: 7).x.expectStaticType>(); + C7(7, y: 7).y.expectStaticType>(); + C8(8, y: 8).x.expectStaticType>(); + C8(8, y: 8).y.expectStaticType>(); } diff --git a/LanguageFeatures/Declaring-constructors/static_processing_A11_t02.dart b/LanguageFeatures/Declaring-constructors/static_processing_A11_t02.dart new file mode 100644 index 0000000000..6abdd2fb77 --- /dev/null +++ b/LanguageFeatures/Declaring-constructors/static_processing_A11_t02.dart @@ -0,0 +1,68 @@ +// 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 The following applies to both the header and the body form of +/// declaring constructors. +/// +/// The semantics of the declaring constructor is found in the following steps, +/// where `D` is the class, extension type, or enum declaration in the program +/// that includes a declaring constructor, and `D2` is the result of the +/// derivation of the semantics of `D`. The derivation step will delete elements +/// that amount to the declaring constructor; it will add a new constructor `k`; +/// and it will add zero or more instance variable declarations. +/// +/// Where no processing is mentioned below, `D2` is identical to `D`. Changes +/// occur as follows: +/// +/// Let `p` be a formal parameter in `k` which has the modifier `var` or the +/// modifier `final` (that is, `p` is a declaring parameter). +/// +/// Consider the situation where `p` has no type annotation: +/// - if combined member signature for a getter with the same name as `p` from +/// the superinterfaces of `D` exists and has return type `T`, the parameter +/// `p` has declared type `T`. If no such getter exists, but a setter with the +/// same basename exists, with a formal parameter whose type is `T`, the +/// parameter `p` has declared type `T`. +/// +/// @description Check that if the combined member signature for a setter with +/// the same basename as `p` from the superinterfaces of `D` exists, and has a +/// formal parameter type `T` then the parameter `p` has declared type `T` as +/// well. +/// @author sgrekhov22@gmail.com + +// SharedOptions=--enable-experiment=declaring-constructors + +import '../../Utils/static_type_helper.dart'; + +class A { + void set x(num x) {} + void set y(num x) {} +} + +class C1(var x, [var y = 1]) extends A; + +class C2(final x, [final y = 2]) extends A; + +class C3(final x, {final y = 1}) extends A; + +class C4(var x, {var y = 2}) extends A; + +class C5(final x, {required final y}) extends A; + +class C6(var x, {required var y}) extends A; + +main() { + C1(1).x.expectStaticType>(); + C1(1).y.expectStaticType>(); + C2(2).x.expectStaticType>(); + C2(2).y.expectStaticType>(); + C3(3).x.expectStaticType>(); + C3(3).y.expectStaticType>(); + C4(4).x.expectStaticType>(); + C4(4).y.expectStaticType>(); + C5(5, y: 5).x.expectStaticType>(); + C5(5, y: 5).y.expectStaticType>(); + C6(6, y: 6).x.expectStaticType>(); + C6(6, y: 6).y.expectStaticType>(); +} diff --git a/LanguageFeatures/Declaring-constructors/static_processing_A12_t01.dart b/LanguageFeatures/Declaring-constructors/static_processing_A12_t01.dart index 5b93dc5323..4187b7e20a 100644 --- a/LanguageFeatures/Declaring-constructors/static_processing_A12_t01.dart +++ b/LanguageFeatures/Declaring-constructors/static_processing_A12_t01.dart @@ -15,15 +15,14 @@ /// Where no processing is mentioned below, `D2` is identical to `D`. Changes /// occur as follows: /// -/// Assume that `p` is an formal parameter in `D` which has the modifier `var` -/// or the modifier `final` (that is, p is a declaring parameter). +/// Let `p` be a formal parameter in `k` which has the modifier `var` or the +/// modifier `final` (that is, `p` is a declaring parameter). +/// +/// Consider the situation where `p` has no type annotation: /// ... -/// Otherwise, assume that `p` does not have a declared type, but it does have a -/// default value whose static type in the empty context is a type (not a type -/// schema) `T` which is not `Null`. In that case `p` is considered to have the -/// declared type `T`. When `T` is `Null`, `p` is considered to have the -/// declared type `Object?`. If `p` does not have a declared type nor a default -/// value then `p` is considered to have the declared type `Object?`. +/// - otherwise, if `p` is optional and has a default value whose static type in +/// the empty context is a type `T` which is not `Null` then `p` has declared +/// type `T`. When `T` is `Null`, `p` has declared type `Object?`. /// /// @description Check that if `p` does not have a declared type, but it does /// have a default value whose static type is `T` which is not `Null` then `p` diff --git a/LanguageFeatures/Declaring-constructors/static_processing_A12_t02.dart b/LanguageFeatures/Declaring-constructors/static_processing_A12_t02.dart index b3e1257c1a..baadae7a16 100644 --- a/LanguageFeatures/Declaring-constructors/static_processing_A12_t02.dart +++ b/LanguageFeatures/Declaring-constructors/static_processing_A12_t02.dart @@ -15,15 +15,14 @@ /// Where no processing is mentioned below, `D2` is identical to `D`. Changes /// occur as follows: /// -/// Assume that `p` is an formal parameter in `D` which has the modifier `var` -/// or the modifier `final` (that is, p is a declaring parameter). +/// Let `p` be a formal parameter in `k` which has the modifier `var` or the +/// modifier `final` (that is, `p` is a declaring parameter). +/// +/// Consider the situation where `p` has no type annotation: /// ... -/// Otherwise, assume that `p` does not have a declared type, but it does have a -/// default value whose static type in the empty context is a type (not a type -/// schema) `T` which is not `Null`. In that case `p` is considered to have the -/// declared type `T`. When `T` is `Null`, `p` is considered to have the -/// declared type `Object?`. If `p` does not have a declared type nor a default -/// value then `p` is considered to have the declared type `Object?`. +/// - otherwise, if `p` is optional and has a default value whose static type in +/// the empty context is a type `T` which is not `Null` then `p` has declared +/// type `T`. When `T` is `Null`, `p` has declared type `Object?`. /// /// @description Check that if `p` does not have a declared type, but it does /// have a default value whose static type is `Null` then `p` has the declared diff --git a/LanguageFeatures/Declaring-constructors/static_processing_A12_t03.dart b/LanguageFeatures/Declaring-constructors/static_processing_A12_t03.dart index 251ef35656..c5d1aa08fb 100644 --- a/LanguageFeatures/Declaring-constructors/static_processing_A12_t03.dart +++ b/LanguageFeatures/Declaring-constructors/static_processing_A12_t03.dart @@ -15,15 +15,13 @@ /// Where no processing is mentioned below, `D2` is identical to `D`. Changes /// occur as follows: /// -/// Assume that `p` is an formal parameter in `D` which has the modifier `var` -/// or the modifier `final` (that is, p is a declaring parameter). +/// Let `p` be a formal parameter in `k` which has the modifier `var` or the +/// modifier `final` (that is, `p` is a declaring parameter). +/// +/// Consider the situation where `p` has no type annotation: /// ... -/// Otherwise, assume that `p` does not have a declared type, but it does have a -/// default value whose static type in the empty context is a type (not a type -/// schema) `T` which is not `Null`. In that case `p` is considered to have the -/// declared type `T`. When `T` is `Null`, `p` is considered to have the -/// declared type `Object?`. If `p` does not have a declared type nor a default -/// value then `p` is considered to have the declared type `Object?`. +/// - otherwise, if `p` does not have a default value then `p` has declared type +/// `Object?`. /// /// @description Check that if `p` does not have a declared type nor a default /// value then `p` is considered to have the declared type `Object?`. @@ -41,6 +39,10 @@ class C3(final x, {final y}); class C4(var x, {var x}); +class C5(final x, {required final y}); + +class C6(var x, {required var x}); + main() { C1(1).x.expectStaticType>(); C1(1).y.expectStaticType>(); @@ -50,4 +52,8 @@ main() { C3(3).y.expectStaticType>(); C4(4).x.expectStaticType>(); C4(4).y.expectStaticType>(); + C5(5, y: 5).x.expectStaticType>(); + C5(5, y: 5).y.expectStaticType>(); + C6(6, y: 6).x.expectStaticType>(); + C6(6, y: 6).y.expectStaticType>(); } diff --git a/LanguageFeatures/Declaring-constructors/static_processing_A12_t04.dart b/LanguageFeatures/Declaring-constructors/static_processing_A12_t04.dart index 3e4c7dbb6d..0e4afb6b63 100644 --- a/LanguageFeatures/Declaring-constructors/static_processing_A12_t04.dart +++ b/LanguageFeatures/Declaring-constructors/static_processing_A12_t04.dart @@ -15,15 +15,13 @@ /// Where no processing is mentioned below, `D2` is identical to `D`. Changes /// occur as follows: /// -/// Assume that `p` is an optional formal parameter in `D` which has the -/// modifier `var` or the modifier `final` (that is, p is a declaring parameter). +/// Let `p` be a formal parameter in `k` which has the modifier `var` or the +/// modifier `final` (that is, `p` is a declaring parameter). +/// +/// Consider the situation where `p` has no type annotation: /// ... -/// Otherwise, assume that `p` does not have a declared type, but it does have a -/// default value whose static type in the empty context is a type (not a type -/// schema) `T` which is not `Null`. In that case `p` is considered to have the -/// declared type `T`. When `T` is `Null`, `p` is considered to have the -/// declared type `Object?`. If `p` does not have a declared type nor a default -/// value then `p` is considered to have the declared type `Object?`. +/// - otherwise, if `p` does not have a default value then `p` has declared type +/// `Object?`. /// /// @description Check that if `p` does not have a declared type and its default /// value is `Null` or absent then the declared type of `p` is `Object?` not