@@ -125,18 +125,19 @@ Map<String, List<bool>> string2listOfBool = Map.fromString([]);
125
125
126
126
The grammar remains unchanged.
127
127
128
- However, it is no longer an error to declare a factory constructor in an
129
- extension declaration that has an on-class, be it redirecting or not,
130
- constant or not. * Such declarations may of course give rise to errors as
131
- usual, e.g., if a redirecting factory constructor redirects to a
132
- constructor that does not exist, or there is a redirection cycle.*
128
+ However, it is no longer an error to declare a factory constructor
129
+ (redirecting or not) or a redirecting generative constructor in an
130
+ extension declaration that has an on-class, possibly constant. * Such
131
+ declarations may of course give rise to errors as usual, e.g., if a
132
+ redirecting factory constructor redirects to a constructor that does not
133
+ exist, or there is a redirection cycle.*
133
134
134
135
In an extension declaration of the form ` extension E on C {...} ` where ` C `
135
136
is an identifier or an identifier with an import prefix that denotes a
136
137
class, mixin, enum, or extension type declaration, we say that the
137
138
_ on-class_ of the extension is ` C ` . If ` C ` denotes a non-generic class,
138
- mixin, mixin class, or extension type then we say that the _ constructor return
139
- type_ of the extension is ` C ` .
139
+ mixin, mixin class, or extension type then we say that the _ constructor
140
+ return type_ of the extension is ` C ` .
140
141
141
142
If ` C ` denotes a generic class then ` E ` is treated as
142
143
` extension E on C<T1 .. Tk> {...} ` where ` T1 .. Tk ` are obtained by
@@ -193,44 +194,79 @@ on-class. The warning above is aimed at static members and constructors,
193
194
but a similar warning would probably be useful for instance members as
194
195
well.*
195
196
196
- #### Invocation of a static member of an extension
197
+ #### Invocation of a static member
197
198
198
- An _ explicitly resolved invocation_ of a static member of an extension
199
- named ` E ` is an expression of the form ` E.m() ` (or any other member access,
200
- * e.g., ` E.m ` , ` E.m = e ` , etc* ), where ` m ` is a static member declared by
201
- ` E ` .
199
+ * The language specification defines the notion of a _ member invocation_ in
200
+ the section [ Member Invocations] [ ] , which is used below. This concept
201
+ includes method invocations like ` e.aMethod<int>(24) ` , property extractions
202
+ like ` e.aGetter ` or ` e.aMethod ` (tear-offs), operator invocations like
203
+ ` e1 + e2 ` or ` aListOrNull?[1] = e ` , function invocations like ` f() ` . Each
204
+ of these expressions has a _ syntactic receiver_ and an _ associated member
205
+ name_ . With ` e.aMethod<int>(24) ` , the receiver is ` e ` and the associated
206
+ member name is ` aMethod ` , with ` e1 + e2 ` the receiver is ` e1 ` and the
207
+ member name is ` + ` , and with ` f() ` the receiver is ` f ` and the member name
208
+ is ` call ` . Note that the syntactic receiver is a type literal in the case
209
+ where the member invocation invokes a static member. In the following we
210
+ will specify invocations of static members using this concept.*
211
+
212
+ [ Member Invocations ] : https://github.com/dart-lang/language/blob/94194cee07d7deadf098b1f1e0475cb424f3d4be/specification/dartLangSpec.tex#L13903
213
+
214
+ Consider an expression ` e ` which is a member invocation with syntactic
215
+ receiver ` E ` and associated member name ` m ` , where ` E ` denotes an extension
216
+ and ` m ` is a static member declared by ` E ` . We say that ` e ` is an
217
+ _ explicitly resolved invocation_ of said static member of ` E ` .
202
218
203
219
* This can be used to invoke a static member of a specific extension in
204
- order to manually resolve a name clash. At the same time, in current Dart
205
- (without the feature which is specified in this document), this is the only
206
- way we can invoke a static member of an extension, so it may be useful for
207
- backward compatibility reasons.*
208
-
209
- A static member invocation on a class ` C ` , of the form ` C.m() ` (or any
210
- other member access), is resolved by looking up static members in ` C ` named
211
- ` m ` and looking up static members of every accessible extension with
212
- on-class ` C ` and a static member named ` m ` .
213
-
214
- If ` C ` contains such a declaration then the expression is an invocation of
215
- that static member of ` C ` , with the same static analysis and dynamic
216
- semantics as before the introduction of this feature.
217
-
218
- Otherwise, if ` C ` declares a constructor named ` C.m ` then the given
219
- expression is not a static member invocation. It is then handled with the
220
- same static analysis and dynamic semantics as before the introduction of
221
- this feature * (it may be an error, or it may be an instance creation
222
- expression; in any case, declarations in ` C ` are given a higher priority
223
- than declarations in extensions)* .
224
-
225
- Otherwise, an error occurs if no declarations named ` m ` or more than one
226
- declaration named ` m ` were found, or if both static members named ` m ` and
227
- constructors named ` C.m ` were found. * They would necessarily be declared in
228
- extensions.*
229
-
230
- Otherwise, the invocation is resolved to the given static member
231
- declaration in an extension named ` Ej ` , and the invocation is treated
232
- as ` Ej.m() ` * (this is an explicitly resolved invocation, which is specified
233
- above)* .
220
+ order to manually resolve a name clash. At the same time, in Dart without
221
+ the feature which is specified in this document, this is the only way we
222
+ can invoke a static member of an extension (except when it is in scope, see
223
+ below), so it may be useful for backward compatibility.*
224
+
225
+ Consider an expression ` e ` which is a member invocation with syntactic
226
+ receiver ` C ` and an associated member name ` m ` , where ` C ` denotes a class
227
+ and ` m ` is a static member declared by ` C ` . The static analysis and dynamic
228
+ semantics of this expression is the same as in Dart before the introduction
229
+ of this feature.
230
+
231
+ When ` C ` declares a static member whose basename is the basename of ` m ` ,
232
+ but ` C ` does not declare a static member named ` m ` or a constructor named
233
+ ` C.m ` , a compile-time error occurs. * This is the same behavior as in
234
+ pre-feature Dart.*
235
+
236
+ In the case where ` C ` does not declare any static members whose basename is
237
+ the basename of ` m ` , and ` C ` does not declare any constructors named ` C.m2 `
238
+ where ` m2 ` is the basename of ` m ` , let _ M_ be the set of each accessible
239
+ extension whose on-class is ` C ` , and whose static members include one with
240
+ the name ` m ` , or which declares a constructor named ` C.m ` .
241
+
242
+ * If ` C ` does declare a constructor with such a name ` C.m2 ` then the given
243
+ expression is not a static member invocation. This case is described in a
244
+ section below.*
245
+
246
+ Otherwise, an error occurs if _ M_ is empty or _ M_ contains more than one
247
+ member.
248
+
249
+ Otherwise, assume that _ M_ contains exactly one element which is an
250
+ extension ` E ` that declares a static member named ` m ` . The invocation is
251
+ then treated as ` E.m() ` * (this is an explicitly resolved invocation, which
252
+ is specified above)* .
253
+
254
+ Otherwise, _ M_ will contain exactly one element which is a constructor
255
+ named ` C.m ` . This is not a static member invocation, and it is specified in
256
+ a section below.
257
+
258
+ In addition to these rules for invocations of static members of a class or
259
+ an extension, a corresponding set of rules exist for the following: An
260
+ enumerated declaration * (` enum ... ` )* , a mixin class, a mixin, and an
261
+ extension type. They only differ by being concerned with a different kind
262
+ of declaration.
263
+
264
+ In addition to the member invocations specified above, it is also possible
265
+ to invoke a static member of the enclosing declaration based on lexical
266
+ lookup. This case is applicable when an expression in a class, enum, mixin
267
+ or extension type resolves to an invocation of a static member of the
268
+ enclosing declaration. It will never invoke a static member of an extension
269
+ which is not the enclosing declaration.
234
270
235
271
#### The instantiated constructor return type of an extension
236
272
@@ -255,11 +291,11 @@ and it has a constructor return type of the form `C<S1 .. Sk>`. In this
255
291
case the instantiated constructor return type of _ D_ is ` C<S1 .. Sk> ` ,
256
292
which is a ground type, and it is the same for all call sites.*
257
293
258
- #### Explicit invocation of a constructor in an extension
294
+ #### Invocation of a constructor in an extension
259
295
260
- Explicit constructor invocations are similar to static member invocations,
261
- but they need more detailed rules because they can use the formal type
262
- parameters declared by an extension.
296
+ Explicit constructor invocations are similar to explicitly resolved static
297
+ member invocations, but they need more detailed rules because they can use
298
+ the formal type parameters declared by an extension.
263
299
264
300
An _ explicitly resolved invocation_ of a constructor named ` C.name ` in a
265
301
extension declaration _ D_ named ` E ` with ` s ` type parameters and on-class
@@ -269,10 +305,10 @@ similarly for a constructor named `C` using `E<S1 .. Ss>.C(args)`, etc).
269
305
270
306
A compile-time error occurs if the type arguments passed to ` E ` violate the
271
307
declared bounds. A compile-time error occurs if no type arguments are
272
- passed to ` E ` , and type arguments ` U1 .. Uk ` are passed to ` C ` , but no list
273
- of actual type arguments for the type variables of ` E ` can be found such
274
- that the instantiated constructor return type of ` E ` with said type
275
- arguments is ` C<U1 .. Uk> ` .
308
+ passed to ` E ` , and type arguments ` U1 .. Uk ` are passed to ` C ` , but no
309
+ actual type arguments for the type variables of ` E ` can be found such that
310
+ the instantiated constructor return type of ` E ` with said type arguments is
311
+ ` C<U1 .. Uk> ` .
276
312
277
313
* Note that we must be able to choose the values of the type parameters
278
314
` X1 .. Xs ` such that the instantiated constructor return type is
@@ -288,7 +324,7 @@ normalization occurs. *In other words, the types must be equal, not
288
324
just mutual subtypes.*
289
325
290
326
* Note that explicitly resolved invocations of constructors declared in
291
- extensions are an exception in real code, usable in the case where a
327
+ extensions are a rare exception in real code, usable in the case where a
292
328
name clash prevents an implicitly resolved invocation. However, implicitly
293
329
resolved invocations are specified in the rest of this section by reducing
294
330
them to explicitly resolved ones.*
@@ -303,16 +339,26 @@ If a constructor in `C` with the requested name was found, the pre-feature
303
339
static analysis and dynamic semantics apply. * That is, the class always
304
340
wins.*
305
341
306
- Otherwise, the invocation is partially resolved to a set of candidate
307
- constructors found in extensions. Each of the candidates _ kj_ is
308
- vetted as follows:
342
+ Otherwise, if ` m ` is zero * (which means that the invocation is
343
+ ` C.name(args) ` )* , and ` C ` declares a static member whose basename is the
344
+ basename of ` name ` , the invocation is a static member invocation * (which is
345
+ specified in an earlier section)* .
346
+
347
+ Otherwise, the invocation is partially resolved to a set _ M_ of candidate
348
+ constructors and static members found in extensions. Each of the candidates
349
+ _ kj_ is vetted as follows:
350
+
351
+ If ` m ` is zero and ` E ` is an accessible extension with on-class ` C `
352
+ that declares a static member whose basename is ` name ` then the invocation
353
+ is a static member invocation * (which is specified in an earlier section)* .
309
354
310
- Assume that _ kj_ is a constructor declared by an extension _ D_ named
311
- ` E ` with type parameters ` X1 extends B1 .. Xs extends Bs ` and on-type
312
- ` C<S1 .. Sm> ` . Find actual values ` U1 .. Us ` for ` X1 .. Xs ` satisfying the
313
- bounds ` B1 .. Bs ` , such that ` ([U1/X1 .. Us/Xs]C<S1 .. Sm>) == C<T1 .. Tm> ` .
314
- If this fails then remove _ kj_ from the set of candidate constructors.
315
- Otherwise note that _ kj_ uses actual type arguments ` U1 .. Us ` .
355
+ Otherwise, assume that _ kj_ is a constructor declared by an extension _ D_
356
+ named ` E ` with type parameters ` X1 extends B1 .. Xs extends Bs ` , on-class
357
+ ` C ` , and on-type ` C<S1 .. Sm> ` . Find actual values ` U1 .. Us ` for
358
+ ` X1 .. Xs ` satisfying the bounds ` B1 .. Bs ` , such that
359
+ ` ([U1/X1 .. Us/Xs]C<S1 .. Sm>) == C<T1 .. Tm> ` . If this fails then remove
360
+ _ kj_ from the set of candidate constructors. Otherwise note that _ kj_
361
+ uses actual type arguments ` U1 .. Us ` .
316
362
317
363
If all candidate constructors have been removed, or more than one candidate
318
364
remains, a compile-time error occurs. Otherwise, the invocation is
@@ -338,13 +384,19 @@ In the case where the invocation resolves to exactly one constructor
338
384
` C.name ` (or ` C ` ) declared by an extension named ` E ` , the invocation
339
385
is treated as ` E.C.name(args) ` (respectively ` E.C(args) ` ).
340
386
341
- Otherwise, when there are two or more candidates from extensions,
342
- an error occurs. * We do not wish to specify an approach whereby ` args ` is
343
- subject to type inference multiple times, and hence we do not support type
344
- inference for ` C.name(args) ` in the case where there are multiple distinct
387
+ Otherwise, when there are two or more candidates from extensions, an error
388
+ occurs. * We do not wish to specify an approach whereby ` args ` is subject to
389
+ type inference multiple times, and hence we do not support type inference
390
+ for ` C.name(args) ` in the case where there are multiple distinct
345
391
declarations whose signature could be used during the static analysis of
346
392
that expression.*
347
393
394
+ In addition to these rules for invocations of constructors of a class or an
395
+ extension, a corresponding set of rules exist for the following: An
396
+ enumerated declaration * (` enum ... ` )* , a mixin class, a mixin, and an
397
+ extension type. They only differ by being concerned with a different kind
398
+ of declaration.
399
+
348
400
### Dynamic Semantics
349
401
350
402
The dynamic semantics of static members of an extension is the same
@@ -362,6 +414,10 @@ This fully determines the dynamic semantics of this feature.
362
414
363
415
### Changelog
364
416
417
+ 1.1 - Aug 21, 2024
418
+
419
+ * Extensive revision of this document based on thorough review.
420
+
365
421
1.0 - May 31, 2024
366
422
367
423
* First version of this document released.
0 commit comments