From 691bf5fede8234a2e36c18ca97387b4f21b8419c Mon Sep 17 00:00:00 2001 From: Erik Ernst Date: Wed, 28 May 2025 16:18:03 +0200 Subject: [PATCH 1/6] Add rules to allow omission of certain default values --- .../feature-specification.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/working/augmentation-libraries/feature-specification.md b/working/augmentation-libraries/feature-specification.md index 17d4c5863..12e519f87 100644 --- a/working/augmentation-libraries/feature-specification.md +++ b/working/augmentation-libraries/feature-specification.md @@ -774,7 +774,8 @@ It's a **compile-time** error if: matching] the signature of the augmented function. * The augmenting function specifies any default values. *Default values are - defined solely by the introductory function.* + defined solely by the introductory function. Note that constructors are + treated differently from other functions in this respect.* * A function is not complete after all augmentations are applied, unless it's an instance member and the surrounding class is abstract. *Every function @@ -845,13 +846,21 @@ Augmenting constructors works similar to augmenting a function, with some extra rules to handle features unique to constructors like redirections and initializer lists. +It is **not** a compile-time error for an incomplete factory constructor to +omit default values. *That is, they are treated similarly to abstract +instance methods in this respect. This allows the augmenting declaration to +implement the constructor by adding a redirection or a body.* + It's a **compile-time error** if: * The signature of the augmenting function does not [match][signature matching] the signature of the augmented function. -* The augmenting constructor parameters specify any default values. - *Default values are defined solely by the introductory constructor.* +* The augmenting constructor parameters specify any default values, + and the constructor is a non-redirecting factory. *Default values are + defined by the introductory constructor, except when this precludes the + augmentation from choosing whether or not the constructor should be + redirecting.* * The introductory constructor is `const` and the augmenting constructor is not or vice versa. *An augmentation can't change whether or not a From 6104287f709d11abfd0caffbe9689a066f1ae859 Mon Sep 17 00:00:00 2001 From: Erik Ernst Date: Wed, 28 May 2025 18:33:06 +0200 Subject: [PATCH 2/6] Typo --- working/augmentation-libraries/feature-specification.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/working/augmentation-libraries/feature-specification.md b/working/augmentation-libraries/feature-specification.md index 12e519f87..8574cd8d8 100644 --- a/working/augmentation-libraries/feature-specification.md +++ b/working/augmentation-libraries/feature-specification.md @@ -856,8 +856,8 @@ It's a **compile-time error** if: * The signature of the augmenting function does not [match][signature matching] the signature of the augmented function. -* The augmenting constructor parameters specify any default values, - and the constructor is a non-redirecting factory. *Default values are +* The augmenting constructor parameters specify any default values, and + the constructor is not a non-redirecting factory. *Default values are defined by the introductory constructor, except when this precludes the augmentation from choosing whether or not the constructor should be redirecting.* From 660edcb59d2aa81f511a1be15bf184e8ce3ffb50 Mon Sep 17 00:00:00 2001 From: Erik Ernst Date: Wed, 28 May 2025 18:39:03 +0200 Subject: [PATCH 3/6] WIP --- working/augmentation-libraries/feature-specification.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/working/augmentation-libraries/feature-specification.md b/working/augmentation-libraries/feature-specification.md index 8574cd8d8..fb43f9184 100644 --- a/working/augmentation-libraries/feature-specification.md +++ b/working/augmentation-libraries/feature-specification.md @@ -871,6 +871,9 @@ It's a **compile-time error** if: constructor is not, or vice versa. *An augmentation can't change whether or not a constructor is generative because that affects whether users are allowed to call the constructor in a subclass's initializer list.* + +* More than one constructor declaration in an augmentation chain specifies + a default value for the same parameter. An incomplete constructor can be completed by adding an initializer list and/or a body, or by adding a redirection: From 2a0a47db2c23f34d0b13be42ab31b891a3695479 Mon Sep 17 00:00:00 2001 From: Erik Ernst Date: Wed, 28 May 2025 18:45:55 +0200 Subject: [PATCH 4/6] WIP --- working/augmentation-libraries/feature-specification.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/working/augmentation-libraries/feature-specification.md b/working/augmentation-libraries/feature-specification.md index fb43f9184..b9913f2ad 100644 --- a/working/augmentation-libraries/feature-specification.md +++ b/working/augmentation-libraries/feature-specification.md @@ -871,10 +871,14 @@ It's a **compile-time error** if: constructor is not, or vice versa. *An augmentation can't change whether or not a constructor is generative because that affects whether users are allowed to call the constructor in a subclass's initializer list.* - + * More than one constructor declaration in an augmentation chain specifies a default value for the same parameter. +* A constructor declaration in an augmentation chain is a redirecting + factory, and some declaration in the chain specifies a default value + for one or more parameters. + An incomplete constructor can be completed by adding an initializer list and/or a body, or by adding a redirection: From e636087babd2dea9d5b5bc061ea97e189cbb2e25 Mon Sep 17 00:00:00 2001 From: Erik Ernst Date: Tue, 10 Jun 2025 15:36:58 +0200 Subject: [PATCH 5/6] Specify that default values can be specified at most once in an augmentation chain --- .../feature-specification.md | 36 ++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/working/augmentation-libraries/feature-specification.md b/working/augmentation-libraries/feature-specification.md index b9913f2ad..eeffe51ff 100644 --- a/working/augmentation-libraries/feature-specification.md +++ b/working/augmentation-libraries/feature-specification.md @@ -450,7 +450,7 @@ scope. *We could say that it attaches itself to the existing name.* Augmentations aren't allowed to *replace* code, so they mostly add entirely new declarations to the surrounding type. However, function and constructor -augmentations can fill in a body for an augmented declaration that is lacks one. +augmentations can fill in a body for an augmented declaration that lacks one. More precisely, a function or constructor declaration (introductory or augmenting) is *incomplete* if all of: @@ -768,14 +768,42 @@ augment class Person { } ``` +A top-level function, static method, or instance method may be augmented to +provide default values for optional parameters: + +```dart +class C { + void m1([int i]); + void m2({String name}); +} + +augment class C { + augment m1([i = 1]) {} + augment m2({name = "Smith"}) {} +} +``` + +An optional formal parameter has the default value _d_ if exactly one +declaration of that formal parameter in the augmentation chain specifies a +default value, and it is _d_. An optional formal parameter does not have an +explicitly specified default value if none of its declarations in the +augmentation chain specifies a default value; the default value is introduced +implicitly with the value null in the case where the parameter has a nullable +declared type, and no default values are specified in the augmentation chain. + It's a **compile-time** error if: * The signature of the augmenting function does not [match][signature matching] the signature of the augmented function. -* The augmenting function specifies any default values. *Default values are - defined solely by the introductory function. Note that constructors are - treated differently from other functions in this respect.* +* The augmentation chain has two or more specifications of a default + value, even in the case where they are all identical. *Default values are + defined by the introductory function or an augmentation, but at most + once.* + +* The augmentation chain has no specifications of a default value for an + optional parameter whose declared type is potentially non-nullable. *In + this case the specification must be explicit.* * A function is not complete after all augmentations are applied, unless it's an instance member and the surrounding class is abstract. *Every function From ae929b86456087ffa4e62fb3791aa62a5bd2c894 Mon Sep 17 00:00:00 2001 From: Erik Ernst Date: Tue, 10 Jun 2025 16:19:16 +0200 Subject: [PATCH 6/6] Adjust the rules about augmenting constructors wrt default values --- .../feature-specification.md | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/working/augmentation-libraries/feature-specification.md b/working/augmentation-libraries/feature-specification.md index eeffe51ff..0beb2dd1a 100644 --- a/working/augmentation-libraries/feature-specification.md +++ b/working/augmentation-libraries/feature-specification.md @@ -775,11 +775,13 @@ provide default values for optional parameters: class C { void m1([int i]); void m2({String name}); + void m3({String otherName = "Smith"}); // OK, too. } augment class C { augment m1([i = 1]) {} - augment m2({name = "Smith"}) {} + augment m2({name = "John"}) {} + augment m3({otherName}) {} } ``` @@ -787,23 +789,24 @@ An optional formal parameter has the default value _d_ if exactly one declaration of that formal parameter in the augmentation chain specifies a default value, and it is _d_. An optional formal parameter does not have an explicitly specified default value if none of its declarations in the -augmentation chain specifies a default value; the default value is introduced -implicitly with the value null in the case where the parameter has a nullable -declared type, and no default values are specified in the augmentation chain. +augmentation chain specifies a default value; in this case, the default value +is introduced implicitly with the value null in the case where the parameter +has a nullable declared type, and no default values for that parameter are +specified in the augmentation chain. It's a **compile-time** error if: * The signature of the augmenting function does not [match][signature matching] the signature of the augmented function. -* The augmentation chain has two or more specifications of a default - value, even in the case where they are all identical. *Default values are - defined by the introductory function or an augmentation, but at most - once.* +* The augmentation chain has two or more specifications of a default value + for the same optional parameter. This is an error even in the case where + all of them are identical. *Default values are defined by the introductory + function or an augmentation, but at most once.* * The augmentation chain has no specifications of a default value for an - optional parameter whose declared type is potentially non-nullable. *In - this case the specification must be explicit.* + optional parameter whose declared type is potentially non-nullable, and + the declared function is not abstract. * A function is not complete after all augmentations are applied, unless it's an instance member and the surrounding class is abstract. *Every function @@ -884,11 +887,17 @@ It's a **compile-time error** if: * The signature of the augmenting function does not [match][signature matching] the signature of the augmented function. -* The augmenting constructor parameters specify any default values, and - the constructor is not a non-redirecting factory. *Default values are - defined by the introductory constructor, except when this precludes the - augmentation from choosing whether or not the constructor should be - redirecting.* +* The augmentation chain has two or more specifications of a default value + for the same optional parameter. This is an error even in the case where + all of them are identical. *Default values are defined by the introductory + declaration or an augmentation, but at most once.* + +* The augmentation chain has exactly one specification of a default value + for an optional parameter, and the constructor is a redirecting factory. + +* The augmentation chain has no specifications of a default value for an + optional parameter whose declared type is potentially non-nullable, and + the constructor is not a redirecting factory. * The introductory constructor is `const` and the augmenting constructor is not or vice versa. *An augmentation can't change whether or not a