You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Dart allows you to tear off (aka. closurize) methods instead of just calling them. It does not allow you to tear off *constructors*, even though they are just as callable as methods (and for factory methods, the distinction is mainly philosophical).
6
6
@@ -171,6 +171,10 @@ Type intList = List<int>; // In-line instantiated type literal.
171
171
172
172
These grammar changes allows *type parameters* without following parenthesized arguments in places where we previously did not allow them. For example, this means that `<typeArguments>` becomes a *selector* by itself, not just followed by arguments.
173
173
174
+
It applies to instance methods as well as local, static and top-level function declarations. For instance methods, it applies to references of the form
175
+
176
+
`instanceMethod<int>` (with implicit `this`), `object.instanceMethod<int>` (including `this`) and `super.instanceMethod<int>`.
177
+
174
178
The static type of the explicitly instantiated tear-offs are the same as if the type parameter had been inferred, but no longer depends on the context type.
175
179
176
180
The static type of the instantiated type literal is `Type`. This also satisfies issue [#123](https://github.com/dart-lang/language/issues/123).
@@ -259,19 +263,60 @@ T top<T>(T value) => value;
259
263
class C {
260
264
static T stat<T>(T value) => value;
261
265
T inst<T>(T value) => value;
266
+
void method() {
267
+
var f1 = stat<int>;
268
+
var f1TypeName = stat<int>.runtimeType.toString();
269
+
var f2 = inst<int>;
270
+
var f2TypeName = inst<int>.runtimeType.toString();
271
+
var f3 = this.inst<int>;
272
+
var f3TypeName = this.inst<int>.runtimeType.toString();
273
+
}
274
+
}
275
+
mixin M on C {
276
+
static T mstat<T>(T value) => value;
277
+
T minst<T>(T value) => value;
278
+
void mmethod() {
279
+
var f1 = mstat<int>;
280
+
var f1TypeName = mstat<int>.runtimeType.toString();
281
+
var f2 = minst<int>;
282
+
var f2TypeName = minst<int>.runtimeType.toString();
283
+
var f3 = this.minst<int>;
284
+
var f3TypeName = this.minst<int>.runtimeType.toString();
285
+
}
286
+
}
287
+
extension Ext on C {
288
+
static T estat<T>(T value) => value;
289
+
T einst<T>(T value) => value;
290
+
void emethod() {
291
+
var f1 = estat<int>; // works like (int $) => Ext.estat<int>($)
292
+
var f1TypeName = estat<int>.runtimeType.toString();
293
+
var f2 = einst<int>; // works like (int $) => Ext(this).einst<int>($)
294
+
var f2TypeName = einst<int>.runtimeType.toString();
295
+
var f3 = this.einst<int>; // works like (int $) => Ext(this).einst<int>($)
296
+
var f3TypeName = this.einst<int>.runtimeType.toString();
297
+
}
298
+
}
299
+
class D extends C with M {
300
+
void method() {
301
+
var f4 = super.inst<int>; // works like (int $) => super.inst<int>($)
302
+
var f4TypeName = super.inst<int>.runtimeType.toString();
303
+
}
262
304
}
263
305
void main() {
264
306
// Type literals.
265
307
var t1 = List<int>; // Type object for `List<int>`.
266
308
var t2 = ListList<int>; // Type object for `List<List<int>>`.
267
-
// Tear-offs.
309
+
310
+
// Instantiated function tear-offs.
268
311
T local<T>(T value) => value;
269
312
270
313
const f1 = top<int>; // int Function(int), works like (int $) => top<int>($);
271
314
const f2 = C.stat<int>; // int Function(int), works like (int $) => C.stat<int>($);
272
-
var c = C();
273
-
var f3 = C().inst<int>; // int Function(int), works like (int $) => c.inst<int>($);
274
-
var f4 = local<int>; // int Function(int), works like (int $) => local<int>($);
315
+
var f3 = local<int>; // int Function(int), works like (int $) => local<int>($);
316
+
var d = D();
317
+
var f4 = d.inst<int>; // int Function(int), works like (int $) => c.inst<int>($);
318
+
var f5 = d.minst<int>; // int Function(int), works like (int $) => c.minst<int>($);
319
+
var f6 = d.einst<int>; // int Function(int), works like (int $) => Ext(c).einst<int>($);
275
320
276
321
var typeName = List<int>.toString();
277
322
var functionTypeName = local<int>.runtimeType.toString();
@@ -283,7 +328,7 @@ Finally, we formalize the current behavior disallowing instantiated tear-off of
283
328
```dart
284
329
T func<T>(T value) => value;
285
330
var funcValue = func;
286
-
int Function(int) f = funcValue.call; // Disallow!
331
+
int Function(int) f = funcValue.call; // Disallowed!
287
332
```
288
333
289
334
We can detect these statically, and they always throw at run-time, so we can special case them.
@@ -322,3 +367,4 @@ In this case, most of the parameters are *unnecessary*, and a tear-off expressio
0 commit comments