@@ -49,7 +49,8 @@ void main() {
49
49
```
50
50
51
51
In the case where the on-type of an extension declaration satisfies some
52
- constraints, we say that it is the _ on-class_ of the extension.
52
+ constraints, we say that the class/mixin/etc. which is referred in the
53
+ on-type is the _ on-class_ of the extension.
53
54
54
55
The enhancements specified for ` extension ` declarations in this document
55
56
are only applicable to extensions that have an on-class, all other
@@ -60,7 +61,7 @@ For example:
60
61
61
62
``` dart
62
63
// Static members must ignore the type parameters. It may be useful
63
- // to omit the type parameters in the case where every member is
64
+ // to omit the type parameters in the case where every member is
64
65
// static.
65
66
extension E2 on Map {
66
67
static Map<K2, V> castFromKey<K, V, K2>(Map<K, V> source) =>
@@ -69,12 +70,14 @@ extension E2 on Map {
69
70
70
71
// Type parameters are used by constructors.
71
72
extension E3<K extends String, V> on Map<K, V> {
72
- factory Map.fromJson(Map<String, Object?> source) => Map.from(source);
73
+ factory Map.fromJson(Map<String, Object?> source) =>
74
+ Map.from(source);
73
75
}
74
76
75
77
var jsonMap = <String, Object?>{"key": 42};
76
78
var typedMap = Map<String, int>.fromJson(jsonMap);
77
- // `Map<int, int>.fromJson(...)` is an error: Violates the bound of `K`.
79
+ // `Map<int, int>.fromJson(...)` is an error: It violates the
80
+ // bound of `K`.
78
81
```
79
82
80
83
Another motivation for this mechanism is that it supports constructors of
@@ -152,7 +155,7 @@ of `E` is `C`, and the _constructor return type_ of `E` is `C<T1 .. Tk>`.
152
155
In an extension of the form ` extension E on F<T1 .. Tk> {...} ` where ` F ` is
153
156
a type alias whose transitive alias expansion denotes a class, mixin, enum,
154
157
or extension type ` C ` , we say that the _ on-class_ of ` E ` is ` C ` , and the
155
- _ constructor return type_ of ` E ` is the transitive alias expansion of
158
+ _ constructor return type_ of ` E ` is the transitive alias expansion of
156
159
` F<T1 .. Tk> ` .
157
160
158
161
In all other cases, an extension declaration does not have an on-class nor a
@@ -271,6 +274,8 @@ or extension type resolves to an invocation of a static member of the
271
274
enclosing declaration. It will never invoke a static member of an extension
272
275
which is not the enclosing declaration.
273
276
277
+ * In other words, there is nothing new in this case.*
278
+
274
279
#### The instantiated constructor return type of an extension
275
280
276
281
Assume that _ D_ is a generic extension declaration named ` E ` with formal
@@ -283,11 +288,27 @@ _instantiated constructor return type_ of _D_ _with actual type arguments_
283
288
non-generic class ` C ` . In this case, the instantiated constructor return
284
289
type is ` C ` , for any list of actual type arguments.*
285
290
286
- * It is not very useful to declare a type parameter of an extension which
287
- isn't used in the on-type (and hence in the constructor return type, if it
288
- exists), because it can only be passed in an explicitly resolved
289
- invocation, e.g., ` E<int>.C(42) ` . In all other invocations, the value of
290
- such type variables is determined by instantiation to bound.*
291
+ * Note that such type arguments can be useful, in spite of the fact that
292
+ they do not occur in the type of the newly created object. For example:*
293
+
294
+ ``` dart
295
+ class A {
296
+ final int i;
297
+ A(this.i);
298
+ }
299
+
300
+ static extension E<X> on A {
301
+ A.computed(X x, int Function(X) fun): this(fun(x));
302
+ }
303
+
304
+ void main() {
305
+ // We can create an `A` "directly".
306
+ A a = A(42);
307
+
308
+ // We can also use a function to compute the `int`.
309
+ a = A.computed('Hello!', (s) => s.length);
310
+ }
311
+ ```
291
312
292
313
* As another special case, assume that _ D_ has no formal type parameters,
293
314
and it has a constructor return type of the form ` C<S1 .. Sk> ` . In this
@@ -302,7 +323,7 @@ the formal type parameters declared by an extension.
302
323
303
324
An _ explicitly resolved invocation_ of a constructor named ` C.name ` in a
304
325
extension declaration _ D_ named ` E ` with ` s ` type parameters and on-class
305
- ` C ` can be expressed as ` E<S1 .. Ss>.C.name(args) ` ,
326
+ ` C ` can be expressed as ` E<S1 .. Ss>.C.name(args) ` ,
306
327
` E.C<U1 .. Uk>.name(args) ` , or ` E<S1 .. Ss>.C<U1 .. Uk>.name(args) ` (and
307
328
similarly for a constructor named ` C ` using ` E<S1 .. Ss>.C(args) ` , etc).
308
329
@@ -342,11 +363,6 @@ If a constructor in `C` with the requested name was found, the pre-feature
342
363
static analysis and dynamic semantics apply. * That is, the class always
343
364
wins.*
344
365
345
- Otherwise, if ` m ` is zero * (which means that the invocation is
346
- ` C.name(args) ` )* , and ` C ` declares a static member whose basename is the
347
- basename of ` name ` , the invocation is a static member invocation * (which is
348
- specified in an earlier section)* .
349
-
350
366
Otherwise, the invocation is partially resolved to a set _ M_ of candidate
351
367
constructors and static members found in extensions. Each of the candidates
352
368
_ kj_ is vetted as follows:
@@ -357,11 +373,16 @@ is a static member invocation *(which is specified in an earlier section)*.
357
373
358
374
Otherwise, assume that _ kj_ is a constructor declared by an extension _ D_
359
375
named ` E ` with type parameters ` X1 extends B1 .. Xs extends Bs ` , on-class
360
- ` C ` , and on-type ` C<S1 .. Sm> ` . Find actual values ` U1 .. Us ` for
376
+ ` C ` , and on-type ` C<S1 .. Sm> ` . Find actual values ` U1 .. Us ` for
361
377
` X1 .. Xs ` satisfying the bounds ` B1 .. Bs ` , such that
362
- ` ([U1/X1 .. Us/Xs]C<S1 .. Sm>) == C<T1 .. Tm> ` . If this fails then remove
363
- _ kj_ from the set of candidate constructors. Otherwise note that _ kj_
364
- uses actual type arguments ` U1 .. Us ` .
378
+ ` ([U1/X1 .. Us/Xs]C<S1 .. Sm>) == C<T1 .. Tm> ` . This may determine the
379
+ value of some of the actual type arguments ` U1 .. Us ` , and others may be
380
+ unconstrained (because they do not occur in ` C<T1 .. Tm> ` ). Actual type
381
+ arguments corresponding to unconstrained type parameters are given as ` _ `
382
+ (and they are subject to inference later on, where the types of the actual
383
+ arguments ` args ` may influence their value). If this inference fails
384
+ then remove _ kj_ from the set of candidate constructors. Otherwise note
385
+ that _ kj_ uses actual type arguments ` U1 .. Us ` .
365
386
366
387
If all candidate constructors have been removed, or more than one candidate
367
388
remains, a compile-time error occurs. Otherwise, the invocation is
@@ -371,18 +392,18 @@ constructor invocation, which is specified above.*
371
392
372
393
A constructor invocation of the form ` C.name(args) ` (respectively
373
394
` C(args) ` ) where ` C ` denotes a non-generic class is resolved in the
374
- same manner, with ` m == 0 ` . * In this case, type parameters declared by ` E `
375
- will be bound to values selected by instantiation to bound.*
395
+ same manner, with ` m == 0 ` .
376
396
377
397
Consider a constructor invocation of the form ` C.name(args) ` (and similarly
378
398
for ` C(args) ` ) where ` C ` denotes a generic class. As usual, the
379
399
invocation is treated as in the pre-feature language when it denotes a
380
400
constructor declared by the class ` C ` .
381
401
382
- In the case where the context type schema for this invocation fully
383
- determines the actual type arguments of ` C ` , the expression is changed to
384
- receive said actual type arguments, ` C<T1 .. Tm>.name(args) ` , and treated
385
- as described above.
402
+ In the case where the context type schema for this invocation
403
+ determines some actual type arguments of ` C ` , the expression is changed to
404
+ receive said actual type arguments, ` C<T1 .. Tm>.name(args) ` (where the
405
+ unconstrained actual type arguments are given as ` _ ` and inferred later).
406
+ The expression is then treated as described above.
386
407
387
408
Next, we construct a set _ M_ containing all accessible extensions with
388
409
on-class ` C ` that declare a constructor named ` C.name ` (respectively ` C ` ).
0 commit comments