@@ -89,7 +89,6 @@ class FunctionReferenceResolver {
89
89
prefixType = prefixElement.returnType;
90
90
}
91
91
92
- function.prefix.staticType = prefixType;
93
92
if (prefixType != null && prefixType.isDynamic) {
94
93
_errorReporter.reportErrorForNode (
95
94
CompileTimeErrorCode .GENERIC_METHOD_TYPE_INSTANTIATION_ON_DYNAMIC ,
@@ -301,19 +300,15 @@ class FunctionReferenceResolver {
301
300
/// There are three possible valid cases: tearing off the `call` method of a
302
301
/// function element, tearing off an extension element declared on [Function] ,
303
302
/// and tearing off an extension element declared on a function type.
304
- ExecutableElement ? _resolveFunctionElementFunction (
303
+ Element ? _resolveFunctionTypeFunction (
305
304
Expression receiver,
306
305
SimpleIdentifier methodName,
307
- FunctionElement receiverElement ,
306
+ FunctionType receiverType ,
308
307
) {
309
- if (methodName.name == FunctionElement .CALL_METHOD_NAME ) {
310
- return receiverElement;
311
- }
312
-
313
308
var methodElement = _resolver.typePropertyResolver
314
309
.resolve (
315
310
receiver: receiver,
316
- receiverType: receiverElement.type ,
311
+ receiverType: receiverType ,
317
312
name: methodName.name,
318
313
propertyErrorEntity: methodName,
319
314
nameErrorEntity: methodName,
@@ -342,6 +337,7 @@ class FunctionReferenceResolver {
342
337
}
343
338
344
339
function.prefix.staticElement = prefixElement;
340
+ function.prefix.staticType = prefixElement.referenceType;
345
341
var functionName = function.identifier.name;
346
342
347
343
if (prefixElement is PrefixElement ) {
@@ -376,28 +372,22 @@ class FunctionReferenceResolver {
376
372
return ;
377
373
}
378
374
379
- var methodElement = _resolveTypeProperty (
375
+ var functionType = _resolveTypeProperty (
380
376
receiver: function.prefix,
381
- receiverElement: prefixElement,
382
377
name: function.identifier,
383
378
nameErrorEntity: function,
384
379
);
385
380
386
- if (methodElement is MethodElement ) {
387
- function.identifier.staticElement = methodElement;
388
- function.staticType = methodElement.type;
389
- _resolve (
390
- node: node,
391
- rawType: methodElement.type,
392
- name: functionName,
393
- );
394
- return ;
395
- }
396
-
397
- if (methodElement is PropertyAccessorElement ) {
398
- function.accept (_resolver);
399
- _resolveDisallowedExpression (node, methodElement.returnType);
400
- return ;
381
+ if (functionType != null ) {
382
+ if (functionType is FunctionType ) {
383
+ function.staticType = functionType;
384
+ _resolve (
385
+ node: node,
386
+ rawType: functionType,
387
+ name: functionName,
388
+ );
389
+ return ;
390
+ }
401
391
}
402
392
403
393
function.accept (_resolver);
@@ -425,39 +415,12 @@ class FunctionReferenceResolver {
425
415
node.staticType = DynamicTypeImpl .instance;
426
416
return ;
427
417
}
428
- } else if (target is PrefixedIdentifierImpl ) {
429
- var prefixElement = target.prefix.scopeLookupResult! .getter;
430
- if (prefixElement is PrefixElement ) {
431
- var prefixName = target.identifier.name;
432
- var targetElement = prefixElement.scope.lookup (prefixName).getter;
433
-
434
- var methodElement = _resolveTypeProperty (
435
- receiver: target,
436
- receiverElement: targetElement,
437
- name: function.propertyName,
438
- nameErrorEntity: function,
439
- );
440
-
441
- if (methodElement == null ) {
442
- // The target is known, but the method is not; [UNDEFINED_GETTER] is
443
- // reported elsewhere.
444
- node.staticType = DynamicTypeImpl .instance;
445
- return ;
446
- } else {
447
- _resolveReceiverPrefix (node, prefixElement, target, methodElement);
448
- return ;
449
- }
450
- } else {
451
- // The prefix is unknown; [UNDEFINED_IDENTIFIER] is reported elsewhere.
452
- node.staticType = DynamicTypeImpl .instance;
453
- return ;
454
- }
455
418
} else if (target is ExtensionOverrideImpl ) {
456
419
_resolveExtensionOverride (node, function, target);
457
420
return ;
458
421
} else {
459
- targetType = target.typeOrThrow ;
460
- if (targetType.isDynamic) {
422
+ var targetType = target.staticType ;
423
+ if (targetType != null && targetType .isDynamic) {
461
424
_errorReporter.reportErrorForNode (
462
425
CompileTimeErrorCode .GENERIC_METHOD_TYPE_INSTANTIATION_ON_DYNAMIC ,
463
426
node,
@@ -466,6 +429,29 @@ class FunctionReferenceResolver {
466
429
node.staticType = DynamicTypeImpl .instance;
467
430
return ;
468
431
}
432
+ var functionType = _resolveTypeProperty (
433
+ receiver: target,
434
+ name: function.propertyName,
435
+ nameErrorEntity: function,
436
+ );
437
+
438
+ if (functionType == null ) {
439
+ // The target is known, but the method is not; [UNDEFINED_GETTER] is
440
+ // reported elsewhere.
441
+ node.staticType = DynamicTypeImpl .instance;
442
+ return ;
443
+ } else {
444
+ if (functionType is FunctionType ) {
445
+ function.staticType = functionType;
446
+ _resolve (
447
+ node: node,
448
+ rawType: functionType,
449
+ name: function.propertyName.name,
450
+ );
451
+ }
452
+
453
+ return ;
454
+ }
469
455
}
470
456
471
457
var propertyElement = _resolver.typePropertyResolver
@@ -719,47 +705,52 @@ class FunctionReferenceResolver {
719
705
NodeReplacer .replace (node, typeLiteral);
720
706
}
721
707
722
- /// Resolves [name] as a property on [receiver] (with element
723
- /// [receiverElement] ).
708
+ /// Resolves [name] as a property on [receiver] .
724
709
///
725
- /// Returns `null` if [receiverElement] is `null` , a [TypeParameterElement ] ,
726
- /// or a [TypeAliasElement] for a non-interface type.
727
- ExecutableElement ? _resolveTypeProperty ({
710
+ /// Returns `null` if [receiver] 's type is `null` , a [TypeParameterType ] ,
711
+ /// or a type alias for a non-interface type.
712
+ DartType ? _resolveTypeProperty ({
728
713
required Expression receiver,
729
- required Element ? receiverElement,
730
- required SimpleIdentifier name,
714
+ required SimpleIdentifierImpl name,
731
715
required SyntacticEntity nameErrorEntity,
732
716
}) {
733
- if (receiverElement == null ) {
734
- return null ;
735
- }
736
- if (receiverElement is TypeParameterElement ) {
737
- return null ;
738
- }
739
- if (receiverElement is ClassElement ) {
740
- return _resolveStaticElement (receiverElement, name);
741
- } else if (receiverElement is FunctionElement ) {
742
- return _resolveFunctionElementFunction (receiver, name, receiverElement);
743
- } else if (receiverElement is TypeAliasElement ) {
744
- var aliasedType = receiverElement.aliasedType;
745
- if (aliasedType is InterfaceType ) {
746
- return _resolveStaticElement (aliasedType.element, name);
747
- } else {
748
- return null ;
717
+ if (receiver is Identifier ) {
718
+ var receiverElement = receiver.staticElement;
719
+ if (receiverElement is ClassElement ) {
720
+ var element = _resolveStaticElement (receiverElement, name);
721
+ name.staticElement = element;
722
+ // TODO(srawlins): Should this use referenceType? E.g. if `element`
723
+ // is a function-typed static getter.
724
+ return element? .type;
725
+ } else if (receiverElement is TypeAliasElement ) {
726
+ var aliasedType = receiverElement.aliasedType;
727
+ if (aliasedType is InterfaceType ) {
728
+ var element = _resolveStaticElement (aliasedType.element, name);
729
+ name.staticElement = element;
730
+ // TODO(srawlins): Should this use referenceType? E.g. if `element`
731
+ // is a function-typed static getter.
732
+ return element? .type;
733
+ } else {
734
+ return null ;
735
+ }
749
736
}
750
737
}
751
738
752
- DartType receiverType;
753
- if (receiverElement is VariableElement ) {
754
- receiverType = receiverElement.type;
755
- } else if (receiverElement is PropertyAccessorElement ) {
756
- receiverType = receiverElement.returnType;
757
- } else {
758
- assert (false ,
759
- 'Unexpected receiverElement type: ${receiverElement .runtimeType }' );
739
+ var receiverType = receiver.staticType;
740
+ if (receiverType == null ) {
760
741
return null ;
742
+ } else if (receiverType is TypeParameterType ) {
743
+ return null ;
744
+ } else if (receiverType is FunctionType ) {
745
+ if (name.name == FunctionElement .CALL_METHOD_NAME ) {
746
+ return receiverType;
747
+ }
748
+ var element = _resolveFunctionTypeFunction (receiver, name, receiverType);
749
+ name.staticElement = element;
750
+ return element? .referenceType;
761
751
}
762
- var methodElement = _resolver.typePropertyResolver
752
+
753
+ var element = _resolver.typePropertyResolver
763
754
.resolve (
764
755
receiver: receiver,
765
756
receiverType: receiverType,
@@ -768,10 +759,35 @@ class FunctionReferenceResolver {
768
759
nameErrorEntity: nameErrorEntity,
769
760
)
770
761
.getter;
771
- if (methodElement != null && methodElement.isStatic) {
772
- _reportInvalidAccessToStaticMember (name, methodElement,
762
+ name.staticElement = element;
763
+ if (element != null && element.isStatic) {
764
+ _reportInvalidAccessToStaticMember (name, element,
773
765
implicitReceiver: false );
774
766
}
775
- return methodElement;
767
+ return element? .referenceType;
768
+ }
769
+ }
770
+
771
+ extension on Element {
772
+ /// Returns the 'type' of `this` , when accessed as a "reference", not
773
+ /// immediately followed by parentheses and arguments.
774
+ ///
775
+ /// For all elements that don't have a type (for example, [ExportElement] ),
776
+ /// `null` is returned. For [PropertyAccessorElement] , the return value is
777
+ /// returned. For all other elements, their `type` property is returned.
778
+ DartType ? get referenceType {
779
+ if (this is ConstructorElement ) {
780
+ return (this as ConstructorElement ).type;
781
+ } else if (this is FunctionElement ) {
782
+ return (this as FunctionElement ).type;
783
+ } else if (this is PropertyAccessorElement ) {
784
+ return (this as PropertyAccessorElement ).returnType;
785
+ } else if (this is MethodElement ) {
786
+ return (this as MethodElement ).type;
787
+ } else if (this is VariableElement ) {
788
+ return (this as VariableElement ).type;
789
+ } else {
790
+ return null ;
791
+ }
776
792
}
777
793
}
0 commit comments