Skip to content

Commit 9f594ce

Browse files
authored
Update specification for generative constructors (#4192)
This is a paired down version of #4164. It contains only the changes to the proposal we had previously discussed, making augmented have no special meaning in generative constructor bodies. It does not change rules around initializing formals or super parameters (these must be consistent across the introductory and any augmenting declarations still). I wanted to separate out this change from the much more complicated explanation of how these constructors should be evaluated.
1 parent 1b0e339 commit 9f594ce

File tree

1 file changed

+34
-55
lines changed

1 file changed

+34
-55
lines changed

working/augmentation-libraries/feature-specification.md

Lines changed: 34 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -239,14 +239,14 @@ An augmentation that replaces the body of a function may also want to
239239
preserve and run the code of the augmented declaration (hence the name
240240
"augmentation"). It may want to run its own code before the augmented
241241
code, after it, or both. To support that, we allow a new expression syntax
242-
inside the "bodies" of augmenting declarations (function bodies,
243-
constructor bodies, and variable initializers). Inside an expression in an
244-
augmenting member declaration, the identifier `augmented` can be used to
245-
refer to the augmented function, getter, or setter body, or variable
246-
initializer. This is a contextual reserved word within `augment`
247-
declarations, and has no special meaning outside of that context. See the
248-
next section for a full specification of what `augmented` means, and how it
249-
must be used, in the various contexts.
242+
inside the "bodies" of augmenting declarations (some function bodies and
243+
variable initializers). Inside an expression in an augmenting member
244+
declaration, the identifier `augmented` can be used to refer to the augmented
245+
function, getter, or setter body, or variable initializer. This is a contextual
246+
reserved word within `augment` declarations, and has no special meaning outside
247+
of that context. See the [augmented expression](#augmented-expression) section
248+
for a full specification of what `augmented` means, and how it must be used, in
249+
the various contexts.
250250

251251
*Note that within an augmenting member declaration, a reference to a member
252252
by the same name refers to the final version of the member (and not the one
@@ -343,9 +343,20 @@ augmented, but it generally follows the same rules as any normal identifier:
343343
variable's initializer if the member being augmented is not a variable
344344
declaration with an initializing expression.
345345

346-
* **Augmenting functions**: When augmenting a function, `augmented`
347-
refers to the augmented function. Tear offs are not allowed, so this
348-
function must immediately be invoked.
346+
* **Augmenting functions**: Inside an augmenting function body (including
347+
factory constructors but not generative constructors) `augmented` refers to
348+
the augmented function. Tear-offs are not allowed, and this function must
349+
immediately be invoked.
350+
351+
* **Augmenting non-redirecting generative constructors**: Unlike other
352+
functions, `augmented` has no special meaning in non-redirecting generative
353+
constructors. It is still a reserved word inside the body of these
354+
constructors, since they are within the scope of an augmenting declaration.
355+
356+
There is instead an implicit order in which these augmented constructors are
357+
invoked, and they all receive the same arguments. See
358+
[this section](#non-redirecting-generative-constructors) for more
359+
information.
349360

350361
* **Augmenting operators**: When augmenting an operator, `augmented`
351362
refers to the augmented operator method, which must be immediately
@@ -867,51 +878,15 @@ It is a compile-time error if:
867878

868879
#### Non-redirecting generative constructors
869880

870-
These are probably the most complex constructor, but also the most common.
871-
872-
A non-redirecting generative constructor marked `augment` may:
873-
874-
* Add or replace the body of the augmented constructor with a new body.
875-
876-
* If the augmenting constructor has an explicit block body, then that body
877-
replaces any existing constructor body.
881+
These are probably the most complex constructors, but also the most common.
878882

879-
* In the augmenting constructor's body, an `augmented()` call executes the
880-
augmented constructor's body in the same parameter scope that the
881-
augmenting body is executing in. The expression has type `void` and
882-
evaluates to `null`. **(TODO: This is slightly under-specified. We can
883-
use the current bindings of the parameters of the augmenting constructor
884-
as the initial binding of parameter variables in the augmented body, or
885-
we can execute the body in the current *scope*, using the same variables
886-
as the current body. The latter is not what we do with functions
887-
elsewhere, and allows the `augmented()` expression to modify local
888-
variables, but the former introduces different variables than the ones
889-
that existed when evaluating the initializer list. If the initializer
890-
list captures variables in closures, that body may not work.)**
883+
At a high level, a non-redirecting generative constructor marked `augment` may:
891884

892-
* Initializer lists _are not_ re-run, they have already executed and
893-
shouldn't be executed twice. The same goes for initializing formals and
894-
super parameters.
885+
* Augment the constructor with an _additional_ constructor body (bodies are
886+
invoked in augmentation order, starting at the introductory declaration).
895887

896-
* If a parameter variable is overwritten prior to calling `augmented()`,
897-
the augmented body will see the updated value, because the parameter
898-
scope is identical.
899-
900-
* Local variables in scope where `augmented()` is evaluated are not in
901-
scope for the execution of the augmented constructor's body.
902-
903-
* Add initializers to the initializer list. If the augmenting constructor has
904-
an initializer list then:
905-
906-
* It's a compile-time error if the augmented constructor has
907-
super-initializer, and the augmenting constructor's initializer list
908-
also contains a super-initializer.
909-
910-
* Otherwise the result of applying the augmenting constructor has an
911-
initializer list containing first the assertions and field initializers
912-
of the augmented constructor, if any, then the assertions and field
913-
initializers of the augmenting constructor, and finally any
914-
super-initializer of either the augmeted or augmenting constructor.
888+
* Add initializers (and/or asserts) to the initializer list, as well as a
889+
`super` call at the end of the initializer list.
915890

916891
#### Non-redirecting factory constructors
917892

@@ -932,8 +907,12 @@ potentially non-redirecting property of the constructor.
932907

933908
It is a compile-time error if:
934909

935-
* The augmented constructor has an initializer list or a body, or it has a
936-
redirection.
910+
* The augmented constructor has any initializers.
911+
* The augmented constructor has a body.
912+
* The augmented constructor has a redirection.
913+
914+
This redirecting generative constructor now behaves exactly like any other
915+
redirecting generative constructor when it is invoked.
937916

938917
#### Redirecting factory constructors
939918

0 commit comments

Comments
 (0)