Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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 @@ -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
Expand Down Expand Up @@ -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<Exactly<num>>();
C1(1).y.expectStaticType<Exactly<num>>();
Expand All @@ -71,4 +78,8 @@ main() {
C5(5).y.expectStaticType<Exactly<num>>();
C6(6).x.expectStaticType<Exactly<num>>();
C6(6).y.expectStaticType<Exactly<num>>();
C7(7, y: 7).x.expectStaticType<Exactly<num>>();
C7(7, y: 7).y.expectStaticType<Exactly<num>>();
C8(8, y: 8).x.expectStaticType<Exactly<num>>();
C8(8, y: 8).y.expectStaticType<Exactly<num>>();
}
Original file line number Diff line number Diff line change
@@ -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<Exactly<num>>();
C1(1).y.expectStaticType<Exactly<num>>();
C2(2).x.expectStaticType<Exactly<num>>();
C2(2).y.expectStaticType<Exactly<num>>();
C3(3).x.expectStaticType<Exactly<num>>();
C3(3).y.expectStaticType<Exactly<num>>();
C4(4).x.expectStaticType<Exactly<num>>();
C4(4).y.expectStaticType<Exactly<num>>();
C5(5, y: 5).x.expectStaticType<Exactly<num>>();
C5(5, y: 5).y.expectStaticType<Exactly<num>>();
C6(6, y: 6).x.expectStaticType<Exactly<num>>();
C6(6, y: 6).y.expectStaticType<Exactly<num>>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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?`.
Expand All @@ -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<Exactly<Object?>>();
C1(1).y.expectStaticType<Exactly<Object?>>();
Expand All @@ -50,4 +52,8 @@ main() {
C3(3).y.expectStaticType<Exactly<Object?>>();
C4(4).x.expectStaticType<Exactly<Object?>>();
C4(4).y.expectStaticType<Exactly<Object?>>();
C5(5, y: 5).x.expectStaticType<Exactly<Object?>>();
C5(5, y: 5).y.expectStaticType<Exactly<Object?>>();
C6(6, y: 6).x.expectStaticType<Exactly<Object?>>();
C6(6, y: 6).y.expectStaticType<Exactly<Object?>>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down