@@ -475,7 +475,11 @@ class CodeGenerator extends GeneralizingAstVisitor
475
475
}
476
476
477
477
@override
478
- JS .Expression visitTypeName (TypeName node) => _emitTypeName (node.type);
478
+ JS .Expression visitTypeName (TypeName node) {
479
+ // TODO(jmesserly): should only happen for erroneous code.
480
+ if (node.type == null ) return js.call ('dart.dynamic' );
481
+ return _emitTypeName (node.type);
482
+ }
479
483
480
484
@override
481
485
JS .Statement visitClassTypeAlias (ClassTypeAlias node) {
@@ -1479,7 +1483,7 @@ class CodeGenerator extends GeneralizingAstVisitor
1479
1483
for (var p in ctor.parameters.parameters) {
1480
1484
var element = p.element;
1481
1485
if (element is FieldFormalParameterElement ) {
1482
- fields[element.field] = visitSimpleIdentifier (p.identifier);
1486
+ fields[element.field] = _emitSimpleIdentifier (p.identifier);
1483
1487
}
1484
1488
}
1485
1489
@@ -1542,7 +1546,7 @@ class CodeGenerator extends GeneralizingAstVisitor
1542
1546
1543
1547
var body = < JS .Statement > [];
1544
1548
for (var param in parameters.parameters) {
1545
- var jsParam = visitSimpleIdentifier (param.identifier);
1549
+ var jsParam = _emitSimpleIdentifier (param.identifier);
1546
1550
1547
1551
if (! options.destructureNamedParams) {
1548
1552
if (param.kind == ParameterKind .NAMED ) {
@@ -1978,10 +1982,18 @@ class CodeGenerator extends GeneralizingAstVisitor
1978
1982
]);
1979
1983
}
1980
1984
1981
- /// Writes a simple identifier. This can handle implicit `this` as well as
1982
- /// going through the qualified library name if necessary .
1985
+ /// Emits a simple identifier, including handling an inferred generic
1986
+ /// function instantiation .
1983
1987
@override
1984
1988
JS .Expression visitSimpleIdentifier (SimpleIdentifier node) {
1989
+ return _applyFunctionTypeArguments (
1990
+ _emitSimpleIdentifier (node), node.staticElement, node.staticType);
1991
+ }
1992
+
1993
+ /// Emits a simple identifier, handling implicit `this` as well as
1994
+ /// going through the qualified library name if necessary, but *not* handling
1995
+ /// inferred generic function instantiation.
1996
+ JS .Expression _emitSimpleIdentifier (SimpleIdentifier node) {
1985
1997
var accessor = node.staticElement;
1986
1998
if (accessor == null ) {
1987
1999
return js.commentExpression (
@@ -2334,8 +2346,8 @@ class CodeGenerator extends GeneralizingAstVisitor
2334
2346
List <JS .Expression > args = _visit (node.argumentList);
2335
2347
if (DynamicInvoke .get (target)) {
2336
2348
if (typeArgs != null ) {
2337
- return js.call ('dart.dgsend(#, [#] , #, #)' ,
2338
- [jsTarget, typeArgs, memberName, args]);
2349
+ return js.call ('dart.dgsend(#, # , #, #)' ,
2350
+ [jsTarget, new JS . ArrayInitializer ( typeArgs) , memberName, args]);
2339
2351
} else {
2340
2352
return js.call ('dart.dsend(#, #, #)' , [jsTarget, memberName, args]);
2341
2353
}
@@ -2367,7 +2379,8 @@ class CodeGenerator extends GeneralizingAstVisitor
2367
2379
if (DynamicInvoke .get (node.function)) {
2368
2380
var typeArgs = _emitInvokeTypeArguments (node);
2369
2381
if (typeArgs != null ) {
2370
- return js.call ('dart.dgcall(#, [#], #)' , [fn, typeArgs, args]);
2382
+ return js.call ('dart.dgcall(#, #, #)' ,
2383
+ [fn, new JS .ArrayInitializer (typeArgs), args]);
2371
2384
} else {
2372
2385
return js.call ('dart.dcall(#, #)' , [fn, args]);
2373
2386
}
@@ -2385,19 +2398,26 @@ class CodeGenerator extends GeneralizingAstVisitor
2385
2398
2386
2399
List <JS .Expression > _emitInvokeTypeArguments (InvocationExpression node) {
2387
2400
return _emitFunctionTypeArguments (
2388
- node.function.staticType, node.staticInvokeType);
2401
+ node.function.staticType, node.staticInvokeType, node.typeArguments );
2389
2402
}
2390
2403
2391
2404
/// If `g` is a generic function type, and `f` is an instantiation of it,
2392
2405
/// then this will return the type arguments to apply, otherwise null.
2393
- List <JS .Expression > _emitFunctionTypeArguments (DartType g, DartType f) {
2406
+ List <JS .Expression > _emitFunctionTypeArguments (DartType g, DartType f,
2407
+ [TypeArgumentList typeArgs]) {
2394
2408
if (g is FunctionType &&
2395
2409
g.typeFormals.isNotEmpty &&
2396
2410
f is FunctionType &&
2397
2411
f.typeFormals.isEmpty) {
2398
2412
return _recoverTypeArguments (g, f)
2399
2413
.map (_emitTypeName)
2400
2414
.toList (growable: false );
2415
+ } else if (typeArgs != null ) {
2416
+ // Dynamic calls may have type arguments, even though the function types
2417
+ // are not known.
2418
+ // TODO(jmesserly): seems to be mostly broken in Analyzer at the moment:
2419
+ // https://github.com/dart-lang/sdk/issues/26368
2420
+ return typeArgs.arguments.map (visitTypeName).toList (growable: false );
2401
2421
}
2402
2422
return null ;
2403
2423
}
@@ -3365,7 +3385,7 @@ class CodeGenerator extends GeneralizingAstVisitor
3365
3385
if (isLibraryPrefix (node.prefix)) {
3366
3386
return _visit (node.identifier);
3367
3387
} else {
3368
- return _emitAccess (node.prefix, node.identifier);
3388
+ return _emitAccess (node.prefix, node.identifier, node.staticType );
3369
3389
}
3370
3390
}
3371
3391
@@ -3374,7 +3394,7 @@ class CodeGenerator extends GeneralizingAstVisitor
3374
3394
if (node.operator .lexeme == '?.' ) {
3375
3395
return _emitNullSafe (node);
3376
3396
}
3377
- return _emitAccess (_getTarget (node), node.propertyName);
3397
+ return _emitAccess (_getTarget (node), node.propertyName, node.staticType );
3378
3398
}
3379
3399
3380
3400
JS .Expression _emitNullSafe (Expression node) {
@@ -3451,8 +3471,9 @@ class CodeGenerator extends GeneralizingAstVisitor
3451
3471
}
3452
3472
3453
3473
/// Shared code for [PrefixedIdentifier] and [PropertyAccess] .
3454
- JS .Expression _emitAccess (Expression target, SimpleIdentifier memberId) {
3455
- var member = memberId.staticElement;
3474
+ JS .Expression _emitAccess (
3475
+ Expression target, SimpleIdentifier memberId, DartType resultType) {
3476
+ Element member = memberId.staticElement;
3456
3477
if (member is PropertyAccessorElement ) {
3457
3478
member = (member as PropertyAccessorElement ).variable;
3458
3479
}
@@ -3463,30 +3484,49 @@ class CodeGenerator extends GeneralizingAstVisitor
3463
3484
return js.call ('dart.dload(#, #)' , [_visit (target), name]);
3464
3485
}
3465
3486
3466
- if (target is SuperExpression &&
3467
- member is FieldElement &&
3468
- ! member.isSynthetic) {
3487
+ var jsTarget = _visit (target);
3488
+ bool isSuper = jsTarget is JS .Super ;
3489
+
3490
+ if (isSuper && member is FieldElement && ! member.isSynthetic) {
3469
3491
// If super.x is actually a field, then x is an instance property since
3470
3492
// subclasses cannot override x.
3471
- return js. call ( 'this.#' , [name] );
3493
+ jsTarget = new JS . This ( );
3472
3494
}
3473
3495
3474
- String code ;
3496
+ JS . Expression result ;
3475
3497
if (member != null && member is MethodElement && ! isStatic) {
3476
3498
// Tear-off methods: explicitly bind it.
3477
- if (target is SuperExpression ) {
3478
- return js.call ('dart.bind(this, #, #.#)' , [name, _visit (target) , name]);
3499
+ if (isSuper ) {
3500
+ result = js.call ('dart.bind(this, #, #.#)' , [name, jsTarget , name]);
3479
3501
} else if (_isObjectMemberCall (target, memberId.name)) {
3480
- return js.call ('dart.bind(#, #, dart.#)' , [_visit (target), name, name]);
3502
+ result = js.call ('dart.bind(#, #, dart.#)' , [jsTarget, name, name]);
3503
+ } else {
3504
+ result = js.call ('dart.bind(#, #)' , [jsTarget, name]);
3481
3505
}
3482
- code = 'dart.bind(#, #)' ;
3483
3506
} else if (_isObjectMemberCall (target, memberId.name)) {
3484
- return js.call ('dart.#(#)' , [name, _visit (target) ]);
3507
+ result = js.call ('dart.#(#)' , [name, jsTarget ]);
3485
3508
} else {
3486
- code = '#.#' ;
3509
+ result = js.call ('#.#' , [jsTarget, name]);
3510
+ }
3511
+ return _applyFunctionTypeArguments (result, member, resultType);
3512
+ }
3513
+
3514
+ /// If this is an inferred instantiation of a generic function/method, this
3515
+ /// will add the inferred type arguments.
3516
+ JS .Expression _applyFunctionTypeArguments (
3517
+ JS .Expression result, Element member, DartType instantiated) {
3518
+ DartType type;
3519
+ if (member is ExecutableElement ) {
3520
+ type = member.type;
3521
+ } else if (member is VariableElement ) {
3522
+ type = member.type;
3487
3523
}
3488
3524
3489
- return js.call (code, [_visit (target), name]);
3525
+ // TODO(jmesserly): handle explicitly passed type args.
3526
+ if (type == null ) return result;
3527
+ var typeArgs = _emitFunctionTypeArguments (type, instantiated);
3528
+ if (typeArgs == null ) return result;
3529
+ return js.call ('dart.gbind(#, #)' , [result, typeArgs]);
3490
3530
}
3491
3531
3492
3532
/// Emits a generic send, like an operator method.
0 commit comments