blob: 747cb36836f55477befab15650e13e14a7cfab75 [file] [log] [blame]
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(
FunctionReferenceResolution_genericFunctionInstantiationTest);
defineReflectiveTests(FunctionReferenceResolutionTest);
defineReflectiveTests(
FunctionReferenceResolutionWithoutConstructorTearoffsTest);
});
}
@reflectiveTest
class FunctionReferenceResolution_genericFunctionInstantiationTest
extends PubPackageResolutionTest {
test_asExpression() async {
await assertNoErrorsInCode('''
void Function(int) foo(void Function<T>(T) f) {
return (f as dynamic) as void Function<T>(T);
}
''');
assertResolvedNodeText(
findNode.functionReference('as void Function<T>(T);'), r'''
FunctionReference
function: AsExpression
expression: ParenthesizedExpression
leftParenthesis: (
expression: AsExpression
expression: SimpleIdentifier
token: f
staticElement: f@43
staticType: void Function<T>(T)
asOperator: as
type: NamedType
name: SimpleIdentifier
token: dynamic
staticElement: dynamic@-1
staticType: null
type: dynamic
staticType: dynamic
rightParenthesis: )
staticType: dynamic
asOperator: as
type: GenericFunctionType
returnType: NamedType
name: SimpleIdentifier
token: void
staticElement: <null>
staticType: null
type: void
functionKeyword: Function
typeParameters: TypeParameterList
leftBracket: <
typeParameters
TypeParameter
name: SimpleIdentifier
token: T
staticElement: T@89
staticType: null
declaredElement: T@89
rightBracket: >
parameters: FormalParameterList
leftParenthesis: (
parameter: SimpleFormalParameter
type: NamedType
name: SimpleIdentifier
token: T
staticElement: T@89
staticType: null
type: T
declaredElement: @-1
declaredElementType: T
rightParenthesis: )
declaredElement: GenericFunctionTypeElement
parameters
<empty>
kind: required positional
type: T
returnType: void
type: void Function<T>(T)
type: void Function<T>(T)
staticType: void Function<T>(T)
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_assignmentExpression() async {
await assertNoErrorsInCode('''
late void Function<T>(T) g;
void Function(int) foo(void Function<T>(T) f) {
return g = f;
}
''');
assertResolvedNodeText(findNode.functionReference('g = f;'), r'''
FunctionReference
function: AssignmentExpression
leftHandSide: SimpleIdentifier
token: g
staticElement: <null>
staticType: null
operator: =
rightHandSide: SimpleIdentifier
token: f
staticElement: f@71
staticType: void Function<T>(T)
readElement: <null>
readType: null
writeElement: self::@setter::g
writeType: void Function<T>(T)
staticElement: <null>
staticType: void Function<T>(T)
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_assignmentExpression_compound() async {
await assertNoErrorsInCode('''
extension on void Function<T>(T) {
void Function<T>(T) operator +(int i) {
return this;
}
}
void Function(int) foo(void Function<T>(T) f) {
return f += 1;
}
''');
assertResolvedNodeText(findNode.functionReference('f += 1'), r'''
FunctionReference
function: AssignmentExpression
leftHandSide: SimpleIdentifier
token: f
staticElement: f@144
staticType: null
operator: +=
rightHandSide: IntegerLiteral
literal: 1
staticType: int
readElement: f@144
readType: void Function<T>(T)
writeElement: f@144
writeType: void Function<T>(T)
staticElement: self::@extension::0::@method::+
staticType: void Function<T>(T)
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_awaitExpression() async {
await assertNoErrorsInCode('''
Future<void Function(int)> foo(Future<void Function<T>(T)> f) async {
return await f;
}
''');
assertResolvedNodeText(findNode.functionReference('await f'), r'''
FunctionReference
function: AwaitExpression
awaitKeyword: await
expression: SimpleIdentifier
token: f
staticElement: f@59
staticType: Future<void Function<T>(T)>
staticType: void Function<T>(T)
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_binaryExpression() async {
await assertNoErrorsInCode('''
class C {
void Function<T>(T) operator +(int i) {
return <T>(T a) {};
}
}
void Function(int) foo(C c) {
return c + 1;
}
''');
assertResolvedNodeText(findNode.functionReference('c + 1'), r'''
FunctionReference
function: BinaryExpression
leftOperand: SimpleIdentifier
token: c
staticElement: c@108
staticType: C
operator: +
rightOperand: IntegerLiteral
literal: 1
staticType: int
staticElement: self::@class::C::@method::+
staticInvokeType: void Function<T>(T) Function(int)
staticType: void Function<T>(T)
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_cascadeExpression() async {
await assertNoErrorsInCode('''
void Function(int) foo(void Function<T>(T) f) {
return f..toString();
}
''');
assertResolvedNodeText(findNode.functionReference('f..toString()'), r'''
FunctionReference
function: SimpleIdentifier
token: f
staticElement: f@43
staticType: void Function<T>(T)
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_constructorReference() async {
await assertNoErrorsInCode('''
class C<T> {
C(T a);
}
C<int> Function(int) foo() {
return C.new;
}
''');
// TODO(srawlins): Leave the constructor reference uninstantiated, then
// perform generic function instantiation as a wrapping node.
assertResolvedNodeText(findNode.constructorReference('C.new'), r'''
ConstructorReference
constructorName: ConstructorName
type: NamedType
name: SimpleIdentifier
token: C
staticElement: self::@class::C
staticType: null
type: null
period: .
name: SimpleIdentifier
token: new
staticElement: self::@class::C::@constructor::•
staticType: null
tearOffTypeArgumentTypes
int
staticElement: self::@class::C::@constructor::•
staticType: C<int> Function(int)
''');
}
test_functionExpression() async {
await assertNoErrorsInCode('''
Null Function(int) foo() {
return <T>(T a) {};
}
''');
assertResolvedNodeText(findNode.functionReference('<T>(T a) {};'), r'''
FunctionReference
function: FunctionExpression
typeParameters: TypeParameterList
leftBracket: <
typeParameters
TypeParameter
name: SimpleIdentifier
token: T
staticElement: T@37
staticType: null
declaredElement: T@37
rightBracket: >
parameters: FormalParameterList
leftParenthesis: (
parameter: SimpleFormalParameter
type: NamedType
name: SimpleIdentifier
token: T
staticElement: T@37
staticType: null
type: T
identifier: SimpleIdentifier
token: a
staticElement: a@42
staticType: null
declaredElement: a@42
declaredElementType: T
rightParenthesis: )
body: BlockFunctionBody
block: Block
leftBracket: {
rightBracket: }
declaredElement: @36
staticType: Null Function<T>(T)
staticType: Null Function(int)
typeArgumentTypes
int
''');
}
test_functionExpressionInvocation() async {
await assertNoErrorsInCode('''
void Function(int) foo(void Function<T>(T) Function() f) {
return (f)();
}
''');
assertResolvedNodeText(findNode.functionReference('(f)()'), r'''
FunctionReference
function: FunctionExpressionInvocation
function: ParenthesizedExpression
leftParenthesis: (
expression: SimpleIdentifier
token: f
staticElement: f@54
staticType: void Function<T>(T) Function()
rightParenthesis: )
staticType: void Function<T>(T) Function()
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
staticElement: <null>
staticInvokeType: void Function<T>(T) Function()
staticType: void Function<T>(T)
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_functionReference() async {
await assertNoErrorsInCode('''
typedef Fn = void Function<U>(U);
void Function(int) foo(Fn f) {
return f;
}
''');
assertResolvedNodeText(findNode.functionReference('f;'), r'''
FunctionReference
function: SimpleIdentifier
token: f
staticElement: f@61
staticType: void Function<U>(U)
alias: self::@typeAlias::Fn
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_implicitCallReference() async {
await assertNoErrorsInCode('''
class C {
void call<T>(T a) {}
}
void Function(int) foo(C c) {
return c;
}
''');
assertImplicitCallReference(findNode.implicitCallReference('c;'),
findElement.method('call'), 'void Function(int)');
}
test_indexExpression() async {
await assertNoErrorsInCode('''
void Function(int) foo(List<void Function<T>(T)> f) {
return f[0];
}
''');
assertResolvedNodeText(findNode.functionReference('f[0];'), r'''
FunctionReference
function: IndexExpression
target: SimpleIdentifier
token: f
staticElement: f@49
staticType: List<void Function<T>(T)>
leftBracket: [
index: IntegerLiteral
literal: 0
staticType: int
rightBracket: ]
staticElement: MethodMember
base: dart:core::@class::List::@method::[]
substitution: {E: void Function<T>(T)}
staticType: void Function<T>(T)
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_methodInvocation() async {
await assertNoErrorsInCode('''
class C {
late void Function<T>(T) f;
void Function<T>(T) m() => f;
}
void Function(int) foo(C c) {
return c.m();
}
''');
assertResolvedNodeText(findNode.functionReference('c.m();'), r'''
FunctionReference
function: MethodInvocation
target: SimpleIdentifier
token: c
staticElement: c@100
staticType: C
operator: .
methodName: SimpleIdentifier
token: m
staticElement: self::@class::C::@method::m
staticType: void Function<T>(T) Function()
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
staticInvokeType: void Function<T>(T) Function()
staticType: void Function<T>(T)
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_postfixExpression_compound() async {
await assertNoErrorsInCode('''
extension on void Function<T>(T) {
void Function<T>(T) operator +(int i) {
return this;
}
}
void Function(int) foo(void Function<T>(T) f) {
return f++;
}
''');
assertResolvedNodeText(findNode.functionReference('f++'), r'''
FunctionReference
function: PostfixExpression
operand: SimpleIdentifier
token: f
staticElement: f@144
staticType: null
operator: ++
readElement: f@144
readType: void Function<T>(T)
writeElement: f@144
writeType: void Function<T>(T)
staticElement: self::@extension::0::@method::+
staticType: void Function<T>(T)
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_prefixedIdentifier() async {
await assertNoErrorsInCode('''
class C {
late void Function<T>(T) f;
}
void Function(int) foo(C c) {
return c.f;
}
''');
assertResolvedNodeText(findNode.functionReference('c.f;'), r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: c
staticElement: c@68
staticType: C
period: .
identifier: SimpleIdentifier
token: f
staticElement: self::@class::C::@getter::f
staticType: void Function<T>(T)
staticElement: self::@class::C::@getter::f
staticType: void Function<T>(T)
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_prefixExpression_compound() async {
await assertNoErrorsInCode('''
extension on void Function<T>(T) {
void Function<T>(T) operator +(int i) {
return this;
}
}
void Function(int) foo(void Function<T>(T) f) {
return ++f;
}
''');
assertResolvedNodeText(findNode.functionReference('++f'), r'''
FunctionReference
function: PrefixExpression
operator: ++
operand: SimpleIdentifier
token: f
staticElement: f@144
staticType: null
readElement: f@144
readType: void Function<T>(T)
writeElement: f@144
writeType: void Function<T>(T)
staticElement: self::@extension::0::@method::+
staticType: void Function<T>(T)
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_propertyAccess() async {
await assertNoErrorsInCode('''
class C {
late void Function<T>(T) f;
}
void Function(int) foo(C c) {
return (c).f;
}
''');
assertResolvedNodeText(findNode.functionReference('(c).f;'), r'''
FunctionReference
function: PropertyAccess
target: ParenthesizedExpression
leftParenthesis: (
expression: SimpleIdentifier
token: c
staticElement: c@68
staticType: C
rightParenthesis: )
staticType: C
operator: .
propertyName: SimpleIdentifier
token: f
staticElement: self::@class::C::@getter::f
staticType: void Function<T>(T)
staticType: void Function<T>(T)
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_simpleIdentifier() async {
await assertNoErrorsInCode('''
void Function(int) foo(void Function<T>(T) f) {
return f;
}
''');
assertResolvedNodeText(findNode.functionReference('f;'), r'''
FunctionReference
function: SimpleIdentifier
token: f
staticElement: f@43
staticType: void Function<T>(T)
staticType: void Function(int)
typeArgumentTypes
int
''');
}
}
@reflectiveTest
class FunctionReferenceResolutionTest extends PubPackageResolutionTest {
test_constructorFunction_named() async {
await assertNoErrorsInCode('''
class A<T> {
A.foo() {}
}
var x = (A.foo)<int>;
''');
assertResolvedNodeText(findNode.functionReference('(A.foo)<int>;'), r'''
FunctionReference
function: ParenthesizedExpression
leftParenthesis: (
expression: ConstructorReference
constructorName: ConstructorName
type: NamedType
name: SimpleIdentifier
token: A
staticElement: self::@class::A
staticType: null
type: null
period: .
name: SimpleIdentifier
token: foo
staticElement: self::@class::A::@constructor::foo
staticType: null
staticElement: self::@class::A::@constructor::foo
staticType: A<T> Function<T>()
rightParenthesis: )
staticType: A<T> Function<T>()
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: A<int> Function()
typeArgumentTypes
int
''');
}
test_constructorFunction_unnamed() async {
await assertNoErrorsInCode('''
class A<T> {
A();
}
var x = (A.new)<int>;
''');
assertResolvedNodeText(findNode.functionReference('(A.new)<int>;'), r'''
FunctionReference
function: ParenthesizedExpression
leftParenthesis: (
expression: ConstructorReference
constructorName: ConstructorName
type: NamedType
name: SimpleIdentifier
token: A
staticElement: self::@class::A
staticType: null
type: null
period: .
name: SimpleIdentifier
token: new
staticElement: self::@class::A::@constructor::•
staticType: null
staticElement: self::@class::A::@constructor::•
staticType: A<T> Function<T>()
rightParenthesis: )
staticType: A<T> Function<T>()
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: A<int> Function()
typeArgumentTypes
int
''');
}
test_constructorReference() async {
await assertErrorsInCode('''
class A<T> {
A.foo() {}
}
var x = A.foo<int>;
''', [
error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR, 42,
5,
messageContains: ["'A.foo'"]),
]);
assertResolvedNodeText(findNode.functionReference('A.foo<int>;'), r'''
FunctionReference
function: ConstructorReference
constructorName: ConstructorName
type: NamedType
name: SimpleIdentifier
token: A
staticElement: self::@class::A
staticType: null
type: null
period: .
name: SimpleIdentifier
token: foo
staticElement: self::@class::A::@constructor::foo
staticType: null
staticElement: self::@class::A::@constructor::foo
staticType: A<T> Function<T>()
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_constructorReference_prefixed() async {
await assertErrorsInCode('''
import 'dart:async' as a;
var x = a.Future.delayed<int>;
''', [
error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR, 50,
5,
messageContains: ["'a.Future.delayed'"]),
]);
assertResolvedNodeText(
findNode.functionReference('a.Future.delayed<int>;'), r'''
FunctionReference
function: ConstructorReference
constructorName: ConstructorName
type: NamedType
name: PrefixedIdentifier
prefix: SimpleIdentifier
token: a
staticElement: self::@prefix::a
staticType: null
period: .
identifier: SimpleIdentifier
token: Future
staticElement: dart:async::@class::Future
staticType: null
staticElement: dart:async::@class::Future
staticType: null
type: null
period: .
name: SimpleIdentifier
token: delayed
staticElement: dart:async::@class::Future::@constructor::delayed
staticType: null
staticElement: dart:async::@class::Future::@constructor::delayed
staticType: Future<T> Function<T>(Duration, [FutureOr<T> Function()?])
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_dynamicTyped() async {
await assertErrorsInCode('''
dynamic i = 1;
void bar() {
i<int>;
}
''', [
error(
CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 31, 1),
]);
assertResolvedNodeText(findNode.functionReference('i<int>;'), r'''
FunctionReference
function: SimpleIdentifier
token: i
staticElement: self::@getter::i
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_dynamicTyped_targetOfMethodCall() async {
await assertErrorsInCode('''
dynamic i = 1;
void bar() {
i<int>.foo();
}
''', [
error(
CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 31, 1),
]);
assertResolvedNodeText(findNode.functionReference('i<int>.foo();'), r'''
FunctionReference
function: SimpleIdentifier
token: i
staticElement: self::@getter::i
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_explicitReceiver_dynamicTyped() async {
await assertErrorsInCode('''
dynamic f() => 1;
foo() {
f().instanceMethod<int>;
}
''', [
error(CompileTimeErrorCode.GENERIC_METHOD_TYPE_INSTANTIATION_ON_DYNAMIC,
29, 23),
]);
assertResolvedNodeText(
findNode.functionReference('f().instanceMethod<int>;'), r'''
FunctionReference
function: PropertyAccess
target: MethodInvocation
methodName: SimpleIdentifier
token: f
staticElement: self::@function::f
staticType: dynamic Function()
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
staticInvokeType: dynamic Function()
staticType: dynamic
operator: .
propertyName: SimpleIdentifier
token: instanceMethod
staticElement: <null>
staticType: dynamic
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_explicitReceiver_unknown() async {
await assertErrorsInCode('''
bar() {
a.foo<int>;
}
''', [
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 10, 1),
]);
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: a
staticElement: <null>
staticType: null
period: .
identifier: SimpleIdentifier
token: foo
staticElement: <null>
staticType: null
staticElement: <null>
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_explicitReceiver_unknown_multipleProperties() async {
await assertErrorsInCode('''
bar() {
a.b.foo<int>;
}
''', [
// TODO(srawlins): Get the information to [FunctionReferenceResolve] that
// [PropertyElementResolver] encountered an error, to avoid double reporting.
error(CompileTimeErrorCode.GENERIC_METHOD_TYPE_INSTANTIATION_ON_DYNAMIC,
10, 12),
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 10, 1),
]);
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: PropertyAccess
target: PrefixedIdentifier
prefix: SimpleIdentifier
token: a
staticElement: <null>
staticType: dynamic
period: .
identifier: SimpleIdentifier
token: b
staticElement: <null>
staticType: dynamic
staticElement: <null>
staticType: dynamic
operator: .
propertyName: SimpleIdentifier
token: foo
staticElement: <null>
staticType: dynamic
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_extension() async {
await assertErrorsInCode('''
extension E<T> on String {}
void foo() {
E<int>;
}
''', [
error(
CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 44, 1),
]);
var reference = findNode.functionReference('E<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: SimpleIdentifier
token: E
staticElement: self::@extension::E
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_extension_prefixed() async {
newFile('$testPackageLibPath/a.dart', content: '''
extension E<T> on String {}
''');
await assertErrorsInCode('''
import 'a.dart' as a;
void foo() {
a.E<int>;
}
''', [
error(
CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 38, 3),
]);
assertImportPrefix(findNode.simple('a.E'), findElement.prefix('a'));
var reference = findNode.functionReference('E<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: a
staticElement: self::@prefix::a
staticType: null
period: .
identifier: SimpleIdentifier
token: E
staticElement: package:test/a.dart::@extension::E
staticType: dynamic
staticElement: package:test/a.dart::@extension::E
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_extensionGetter_extensionOverride() async {
await assertErrorsInCode('''
class A {}
extension E on A {
int get foo => 0;
}
bar(A a) {
E(a).foo<int>;
}
''', [
error(
CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 67, 8),
]);
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: PropertyAccess
target: ExtensionOverride
extensionName: SimpleIdentifier
token: E
staticElement: self::@extension::E
staticType: null
argumentList: ArgumentList
leftParenthesis: (
arguments
SimpleIdentifier
token: a
staticElement: a@60
staticType: A
rightParenthesis: )
extendedType: A
staticType: null
operator: .
propertyName: SimpleIdentifier
token: foo
staticElement: self::@extension::E::@getter::foo
staticType: int
staticType: int
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_extensionMethod() async {
await assertNoErrorsInCode('''
class A {}
extension E on A {
void foo<T>(T a) {}
bar() {
foo<int>;
}
}
''');
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: self::@extension::E::@method::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_extensionMethod_explicitReceiver_this() async {
await assertNoErrorsInCode('''
class A {}
extension E on A {
void foo<T>(T a) {}
bar() {
this.foo<int>;
}
}
''');
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PropertyAccess
target: ThisExpression
thisKeyword: this
staticType: A
operator: .
propertyName: SimpleIdentifier
token: foo
staticElement: self::@extension::E::@method::foo
staticType: void Function<T>(T)
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_extensionMethod_extensionOverride() async {
await assertNoErrorsInCode('''
class A {
int foo = 0;
}
extension E on A {
void foo<T>(T a) {}
}
bar(A a) {
E(a).foo<int>;
}
''');
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PropertyAccess
target: ExtensionOverride
extensionName: SimpleIdentifier
token: E
staticElement: self::@extension::E
staticType: null
argumentList: ArgumentList
leftParenthesis: (
arguments
SimpleIdentifier
token: a
staticElement: a@78
staticType: A
rightParenthesis: )
extendedType: A
staticType: null
operator: .
propertyName: SimpleIdentifier
token: foo
staticElement: self::@extension::E::@method::foo
staticType: void Function<T>(T)
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_extensionMethod_extensionOverride_cascade() async {
await assertErrorsInCode('''
class A {
int foo = 0;
}
extension E on A {
void foo<T>(T a) {}
}
bar(A a) {
E(a)..foo<int>;
}
''', [
error(CompileTimeErrorCode.EXTENSION_OVERRIDE_WITH_CASCADE, 85, 1),
]);
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PropertyAccess
operator: ..
propertyName: SimpleIdentifier
token: foo
staticElement: self::@extension::E::@method::foo
staticType: void Function<T>(T)
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_extensionMethod_extensionOverride_static() async {
await assertErrorsInCode('''
class A {}
extension E on A {
static void foo<T>(T a) {}
}
bar(A a) {
E(a).foo<int>;
}
''', [
error(CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER, 81,
3),
]);
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PropertyAccess
target: ExtensionOverride
extensionName: SimpleIdentifier
token: E
staticElement: self::@extension::E
staticType: null
argumentList: ArgumentList
leftParenthesis: (
arguments
SimpleIdentifier
token: a
staticElement: a@69
staticType: A
rightParenthesis: )
extendedType: A
staticType: null
operator: .
propertyName: SimpleIdentifier
token: foo
staticElement: self::@extension::E::@method::foo
staticType: void Function<T>(T)
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_extensionMethod_extensionOverride_unknown() async {
await assertErrorsInCode('''
class A {}
extension E on A {}
bar(A a) {
E(a).foo<int>;
}
''', [
error(CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER, 51, 3),
]);
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: PropertyAccess
target: ExtensionOverride
extensionName: SimpleIdentifier
token: E
staticElement: self::@extension::E
staticType: null
argumentList: ArgumentList
leftParenthesis: (
arguments
SimpleIdentifier
token: a
staticElement: a@39
staticType: A
rightParenthesis: )
extendedType: A
staticType: null
operator: .
propertyName: SimpleIdentifier
token: foo
staticElement: <null>
staticType: dynamic
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_extensionMethod_fromClassDeclaration() async {
await assertNoErrorsInCode('''
class A {
bar() {
foo<int>;
}
}
extension E on A {
void foo<T>(T a) {}
}
''');
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: self::@extension::E::@method::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_extensionMethod_unknown() async {
await assertErrorsInCode('''
extension on double {
bar() {
foo<int>;
}
}
''', [
error(HintCode.UNUSED_ELEMENT, 24, 3),
error(CompileTimeErrorCode.UNDEFINED_METHOD, 36, 3,
messageContains: ["for the type 'double'"]),
]);
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: <null>
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_function_call() async {
await assertNoErrorsInCode('''
void foo<T>(T a) {}
void bar() {
foo.call<int>;
}
''');
assertResolvedNodeText(findNode.functionReference('foo.call<int>;'), r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: foo
staticElement: self::@function::foo
staticType: void Function<T>(T)
period: .
identifier: SimpleIdentifier
token: call
staticElement: <null>
staticType: null
staticElement: <null>
staticType: null
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_function_call_tooFewTypeArgs() async {
await assertErrorsInCode('''
void foo<T, U>(T a, U b) {}
void bar() {
foo.call<int>;
}
''', [
error(
CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_FUNCTION, 52, 5),
]);
assertResolvedNodeText(findNode.functionReference('foo.call<int>;'), r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: foo
staticElement: self::@function::foo
staticType: void Function<T, U>(T, U)
period: .
identifier: SimpleIdentifier
token: call
staticElement: <null>
staticType: null
staticElement: <null>
staticType: null
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(dynamic, dynamic)
typeArgumentTypes
dynamic
dynamic
''');
}
test_function_call_tooManyTypeArgs() async {
await assertErrorsInCode('''
void foo(String a) {}
void bar() {
foo.call<int>;
}
''', [
error(
CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_FUNCTION, 46, 5),
]);
assertResolvedNodeText(findNode.functionReference('foo.call<int>;'), r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: foo
staticElement: self::@function::foo
staticType: void Function(String)
period: .
identifier: SimpleIdentifier
token: call
staticElement: <null>
staticType: null
staticElement: <null>
staticType: null
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(String)
''');
}
test_function_call_typeArgNotMatchingBound() async {
await assertNoErrorsInCode('''
void foo<T extends num>(T a) {}
void bar() {
foo.call<String>;
}
''');
assertResolvedNodeText(findNode.functionReference('foo.call<String>;'), r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: foo
staticElement: self::@function::foo
staticType: void Function<T extends num>(T)
period: .
identifier: SimpleIdentifier
token: call
staticElement: <null>
staticType: null
staticElement: <null>
staticType: null
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: String
staticElement: dart:core::@class::String
staticType: null
type: String
rightBracket: >
staticType: void Function(String)
typeArgumentTypes
String
''');
}
test_function_extensionOnFunction() async {
// TODO(srawlins): Test extension on function type, like
// `extension on void Function<T>(T)`.
await assertNoErrorsInCode('''
void foo<T>(T a) {}
void bar() {
foo.m<int>;
}
extension on Function {
void m<T>(T t) {}
}
''');
assertResolvedNodeText(findNode.functionReference('foo.m<int>;'), r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: foo
staticElement: self::@function::foo
staticType: void Function<T>(T)
period: .
identifier: SimpleIdentifier
token: m
staticElement: self::@extension::0::@method::m
staticType: null
staticElement: self::@extension::0::@method::m
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_function_extensionOnFunction_static() async {
await assertErrorsInCode('''
void foo<T>(T a) {}
void bar() {
foo.m<int>;
}
extension on Function {
static void m<T>(T t) {}
}
''', [
error(
CompileTimeErrorCode
.INSTANCE_ACCESS_TO_STATIC_MEMBER_OF_UNNAMED_EXTENSION,
40,
1),
]);
assertResolvedNodeText(findNode.functionReference('foo.m<int>;'), r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: foo
staticElement: self::@function::foo
staticType: void Function<T>(T)
period: .
identifier: SimpleIdentifier
token: m
staticElement: self::@extension::0::@method::m
staticType: null
staticElement: self::@extension::0::@method::m
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_implicitCallTearoff() async {
await assertNoErrorsInCode('''
class C {
T call<T>(T t) => t;
}
foo() {
C()<int>;
}
''');
assertImplicitCallReference(findNode.implicitCallReference('C()<int>;'),
findElement.method('call'), 'int Function(int)');
}
test_implicitCallTearoff_class_staticGetter() async {
await assertNoErrorsInCode('''
class C {
static const v = C();
const C();
T call<T>(T t) => t;
}
void f() {
C.v<int>;
}
''');
var node = findNode.implicitCallReference('C.v<int>');
assertResolvedNodeText(node, r'''
ImplicitCallReference
expression: PrefixedIdentifier
prefix: SimpleIdentifier
token: C
staticElement: self::@class::C
staticType: null
period: .
identifier: SimpleIdentifier
token: v
staticElement: self::@class::C::@getter::v
staticType: null
staticElement: self::@class::C::@getter::v
staticType: null
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticElement: self::@class::C::@method::call
staticType: int Function(int)
typeArgumentTypes
int
''');
}
test_implicitCallTearoff_extensionOnNullable() async {
await assertNoErrorsInCode('''
Object? v = null;
extension E on Object? {
void call<R, S>(R r, S s) {}
}
void foo() {
v<int, String>;
}
''');
assertImplicitCallReference(
findNode.implicitCallReference('v<int, String>;'),
findElement.method('call'),
'void Function(int, String)');
}
test_implicitCallTearoff_prefix_class_staticGetter() async {
newFile('$testPackageLibPath/a.dart', content: r'''
class C {
static const v = C();
const C();
T call<T>(T t) => t;
}
''');
await assertNoErrorsInCode('''
import 'a.dart' as prefix;
void f() {
prefix.C.v<int>;
}
''');
var node = findNode.implicitCallReference('C.v<int>');
assertResolvedNodeText(node, r'''
ImplicitCallReference
expression: PropertyAccess
target: PrefixedIdentifier
prefix: SimpleIdentifier
token: prefix
staticElement: self::@prefix::prefix
staticType: null
period: .
identifier: SimpleIdentifier
token: C
staticElement: package:test/a.dart::@class::C
staticType: null
staticElement: package:test/a.dart::@class::C
staticType: null
operator: .
propertyName: SimpleIdentifier
token: v
staticElement: package:test/a.dart::@class::C::@getter::v
staticType: C
staticType: C
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticElement: package:test/a.dart::@class::C::@method::call
staticType: int Function(int)
typeArgumentTypes
int
''');
}
test_implicitCallTearoff_prefixed() async {
newFile('$testPackageLibPath/a.dart', content: '''
class C {
T call<T>(T t) => t;
}
C c = C();
''');
await assertNoErrorsInCode('''
import 'a.dart' as prefix;
bar() {
prefix.c<int>;
}
''');
assertImportPrefix(
findNode.simple('prefix.'), findElement.prefix('prefix'));
assertImplicitCallReference(
findNode.implicitCallReference('c<int>;'),
findElement.importFind('package:test/a.dart').method('call'),
'int Function(int)');
}
test_implicitCallTearoff_tooFewTypeArguments() async {
await assertErrorsInCode('''
class C {
void call<T, U>(T t, U u) {}
}
foo() {
C()<int>;
}
''', [
error(
CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_FUNCTION, 57, 5),
]);
assertImplicitCallReference(findNode.implicitCallReference('C()<int>;'),
findElement.method('call'), 'void Function(dynamic, dynamic)');
}
test_implicitCallTearoff_tooManyTypeArguments() async {
await assertErrorsInCode('''
class C {
int call(int t) => t;
}
foo() {
C()<int>;
}
''', [
error(
CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_FUNCTION, 50, 5),
]);
assertImplicitCallReference(findNode.implicitCallReference('C()<int>;'),
findElement.method('call'), 'int Function(int)');
}
test_instanceGetter_explicitReceiver() async {
await assertNoErrorsInCode('''
class A {
late void Function<T>(T) foo;
}
bar(A a) {
a.foo<int>;
}
''');
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: a
staticElement: a@51
staticType: A
period: .
identifier: SimpleIdentifier
token: foo
staticElement: self::@class::A::@getter::foo
staticType: null
staticElement: self::@class::A::@getter::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_instanceGetter_functionTyped() async {
await assertNoErrorsInCode('''
abstract class A {
late void Function<T>(T) foo;
bar() {
foo<int>;
}
}
''');
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: self::@class::A::@getter::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_instanceGetter_functionTyped_inherited() async {
await assertNoErrorsInCode('''
abstract class A {
late void Function<T>(T) foo;
}
abstract class B extends A {
bar() {
foo<int>;
}
}
''');
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: self::@class::A::@getter::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_instanceMethod() async {
await assertNoErrorsInCode('''
class A {
void foo<T>(T a) {}
bar() {
foo<int>;
}
}
''');
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: self::@class::A::@method::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_instanceMethod_call() async {
await assertNoErrorsInCode('''
class C {
void foo<T>(T a) {}
void bar() {
foo.call<int>;
}
}
''');
var reference = findNode.functionReference('foo.call<int>;');
// TODO(srawlins): PropertyElementResolver does not return an element for
// `.call`. If we want `findElement.method('foo')` here, we must change the
// policy over there.
assertResolvedNodeText(reference, r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: foo
staticElement: self::@class::C::@method::foo
staticType: void Function<T>(T)
period: .
identifier: SimpleIdentifier
token: call
staticElement: <null>
staticType: null
staticElement: <null>
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_instanceMethod_explicitReceiver_call() async {
await assertNoErrorsInCode('''
class C {
void foo<T>(T a) {}
}
void bar(C c) {
c.foo.call<int>;
}
''');
var reference = findNode.functionReference('foo.call<int>;');
// TODO(srawlins): PropertyElementResolver does not return an element for
// `.call`. If we want `findElement.method('foo')` here, we must change the
// policy over there.
assertResolvedNodeText(reference, r'''
FunctionReference
function: PropertyAccess
target: PrefixedIdentifier
prefix: SimpleIdentifier
token: c
staticElement: c@46
staticType: C
period: .
identifier: SimpleIdentifier
token: foo
staticElement: self::@class::C::@method::foo
staticType: void Function<T>(T)
staticElement: self::@class::C::@method::foo
staticType: void Function<T>(T)
operator: .
propertyName: SimpleIdentifier
token: call
staticElement: <null>
staticType: void Function<T>(T)
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_instanceMethod_explicitReceiver_field() async {
await assertNoErrorsInCode('''
class A {
void foo<T>(T a) {}
}
class B {
A a;
B(this.a);
bar() {
a.foo<int>;
}
}
''');
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: a
staticElement: self::@class::B::@getter::a
staticType: A
period: .
identifier: SimpleIdentifier
token: foo
staticElement: self::@class::A::@method::foo
staticType: null
staticElement: self::@class::A::@method::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_instanceMethod_explicitReceiver_getter_wrongNumberOfTypeArguments() async {
await assertNoErrorsInCode(r'''
class A {
int get foo => 0;
}
void f(A a) {
// Extra `()` to force reading the type.
((a).foo<double>);
}
''');
var reference = findNode.functionReference('foo<double>');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PropertyAccess
target: ParenthesizedExpression
leftParenthesis: (
expression: SimpleIdentifier
token: a
staticElement: a@42
staticType: A
rightParenthesis: )
staticType: A
operator: .
propertyName: SimpleIdentifier
token: foo
staticElement: self::@class::A::@getter::foo
staticType: int
staticType: int
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: double
staticElement: dart:core::@class::double
staticType: null
type: double
rightBracket: >
staticType: dynamic
''');
}
test_instanceMethod_explicitReceiver_otherExpression() async {
await assertNoErrorsInCode('''
class A {
void foo<T>(T a) {}
}
void f(A? a, A b) {
(a ?? b).foo<int>;
}
''');
assertResolvedNodeText(
findNode.functionReference('(a ?? b).foo<int>;'), r'''
FunctionReference
function: PropertyAccess
target: ParenthesizedExpression
leftParenthesis: (
expression: BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: a@45
staticType: A?
operator: ??
rightOperand: SimpleIdentifier
token: b
staticElement: b@50
staticType: A
staticElement: <null>
staticInvokeType: null
staticType: A
rightParenthesis: )
staticType: A
operator: .
propertyName: SimpleIdentifier
token: foo
staticElement: self::@class::A::@method::foo
staticType: void Function<T>(T)
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_instanceMethod_explicitReceiver_receiverIsNotIdentifier_call() async {
await assertNoErrorsInCode('''
extension on List<Object?> {
void foo<T>(T a) {}
}
var a = [].foo.call<int>;
''');
var reference = findNode.functionReference('foo.call<int>;');
// TODO(srawlins): PropertyElementResolver does not return an element for
// `.call`. If we want `findElement.method('foo')` here, we must change the
// policy over there.
assertResolvedNodeText(reference, r'''
FunctionReference
function: PropertyAccess
target: PropertyAccess
target: ListLiteral
leftBracket: [
rightBracket: ]
staticType: List<dynamic>
operator: .
propertyName: SimpleIdentifier
token: foo
staticElement: self::@extension::0::@method::foo
staticType: void Function<T>(T)
staticType: void Function<T>(T)
operator: .
propertyName: SimpleIdentifier
token: call
staticElement: <null>
staticType: void Function<T>(T)
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_instanceMethod_explicitReceiver_super() async {
await assertNoErrorsInCode('''
class A {
void foo<T>(T a) {}
}
class B extends A {
bar() {
super.foo<int>;
}
}
''');
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PropertyAccess
target: SuperExpression
superKeyword: super
staticType: B
operator: .
propertyName: SimpleIdentifier
token: foo
staticElement: self::@class::A::@method::foo
staticType: void Function<T>(T)
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_instanceMethod_explicitReceiver_super_noMethod() async {
await assertErrorsInCode('''
class A {
bar() {
super.foo<int>;
}
}
''', [
error(
CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 24, 9),
error(CompileTimeErrorCode.UNDEFINED_SUPER_GETTER, 30, 3),
]);
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: PropertyAccess
target: SuperExpression
superKeyword: super
staticType: A
operator: .
propertyName: SimpleIdentifier
token: foo
staticElement: <null>
staticType: dynamic
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_instanceMethod_explicitReceiver_super_noSuper() async {
await assertErrorsInCode('''
bar() {
super.foo<int>;
}
''', [
error(
CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 10, 9),
error(CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT, 10, 5),
]);
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: PropertyAccess
target: SuperExpression
superKeyword: super
staticType: dynamic
operator: .
propertyName: SimpleIdentifier
token: foo
staticElement: <null>
staticType: dynamic
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_instanceMethod_explicitReceiver_targetOfFunctionCall() async {
await assertNoErrorsInCode('''
extension on Function {
void m() {}
}
class A {
void foo<T>(T a) {}
}
bar(A a) {
a.foo<int>.m();
}
''');
var reference = findNode.functionReference('foo<int>');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: a
staticElement: a@81
staticType: A
period: .
identifier: SimpleIdentifier
token: foo
staticElement: self::@class::A::@method::foo
staticType: null
staticElement: self::@class::A::@method::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_instanceMethod_explicitReceiver_this() async {
await assertNoErrorsInCode('''
class A {
void foo<T>(T a) {}
bar() {
this.foo<int>;
}
}
''');
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PropertyAccess
target: ThisExpression
thisKeyword: this
staticType: A
operator: .
propertyName: SimpleIdentifier
token: foo
staticElement: self::@class::A::@method::foo
staticType: void Function<T>(T)
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_instanceMethod_explicitReceiver_topLevelVariable() async {
await assertNoErrorsInCode('''
class A {
void foo<T>(T a) {}
}
var a = A();
void bar() {
a.foo<int>;
}
''');
assertIdentifierTopGetRef(findNode.simple('a.'), 'a');
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: a
staticElement: self::@getter::a
staticType: A
period: .
identifier: SimpleIdentifier
token: foo
staticElement: self::@class::A::@method::foo
staticType: null
staticElement: self::@class::A::@method::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_instanceMethod_explicitReceiver_topLevelVariable_prefix() async {
newFile('$testPackageLibPath/a.dart', content: '''
class A {
void foo<T>(T a) {}
}
var a = A();
''');
await assertNoErrorsInCode('''
import 'a.dart' as prefix;
bar() {
prefix.a.foo<int>;
}
''');
assertImportPrefix(
findNode.simple('prefix.'), findElement.prefix('prefix'));
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PropertyAccess
target: PrefixedIdentifier
prefix: SimpleIdentifier
token: prefix
staticElement: self::@prefix::prefix
staticType: null
period: .
identifier: SimpleIdentifier
token: a
staticElement: package:test/a.dart::@getter::a
staticType: A
staticElement: package:test/a.dart::@getter::a
staticType: A
operator: .
propertyName: SimpleIdentifier
token: foo
staticElement: package:test/a.dart::@class::A::@method::foo
staticType: void Function<T>(T)
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_instanceMethod_explicitReceiver_topLevelVariable_prefix_unknown() async {
newFile('$testPackageLibPath/a.dart', content: '''
class A {}
var a = A();
''');
await assertErrorsInCode('''
import 'a.dart' as prefix;
bar() {
prefix.a.foo<int>;
}
''', [
error(CompileTimeErrorCode.UNDEFINED_GETTER, 47, 3),
]);
assertImportPrefix(
findNode.simple('prefix.'), findElement.prefix('prefix'));
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: PropertyAccess
target: PrefixedIdentifier
prefix: SimpleIdentifier
token: prefix
staticElement: self::@prefix::prefix
staticType: null
period: .
identifier: SimpleIdentifier
token: a
staticElement: package:test/a.dart::@getter::a
staticType: A
staticElement: package:test/a.dart::@getter::a
staticType: A
operator: .
propertyName: SimpleIdentifier
token: foo
staticElement: <null>
staticType: dynamic
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_instanceMethod_explicitReceiver_typeParameter() async {
await assertErrorsInCode('''
bar<T>() {
T.foo<int>;
}
''', [
error(CompileTimeErrorCode.UNDEFINED_GETTER, 15, 3),
]);
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: T
staticElement: T@4
staticType: Type
period: .
identifier: SimpleIdentifier
token: foo
staticElement: <null>
staticType: dynamic
staticElement: <null>
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_instanceMethod_explicitReceiver_variable() async {
await assertNoErrorsInCode('''
class A {
void foo<T>(T a) {}
}
bar(A a) {
a.foo<int>;
}
''');
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: a
staticElement: a@41
staticType: A
period: .
identifier: SimpleIdentifier
token: foo
staticElement: self::@class::A::@method::foo
staticType: null
staticElement: self::@class::A::@method::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_instanceMethod_explicitReceiver_variable_cascade() async {
await assertNoErrorsInCode('''
class A {
void foo<T>(T a) {}
}
bar(A a) {
a..foo<int>;
}
''');
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PropertyAccess
operator: ..
propertyName: SimpleIdentifier
token: foo
staticElement: self::@class::A::@method::foo
staticType: void Function<T>(T)
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_instanceMethod_inherited() async {
await assertNoErrorsInCode('''
class A {
void foo<T>(T a) {}
}
class B extends A {
bar() {
foo<int>;
}
}
''');
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: self::@class::A::@method::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_instanceMethod_targetOfFunctionCall() async {
await assertNoErrorsInCode('''
extension on Function {
void m() {}
}
class A {
void foo<T>(T a) {}
bar() {
foo<int>.m();
}
}
''');
var reference = findNode.functionReference('foo<int>');
assertResolvedNodeText(reference, r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: self::@class::A::@method::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_instanceMethod_unknown() async {
await assertErrorsInCode('''
class A {
bar() {
foo<int>;
}
}
''', [
error(CompileTimeErrorCode.UNDEFINED_METHOD, 24, 3,
messageContains: ["for the type 'A'"]),
]);
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: <null>
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_localFunction() async {
await assertNoErrorsInCode('''
void bar() {
void foo<T>(T a) {}
foo<int>;
}
''');
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: foo@20
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_localVariable() async {
await assertNoErrorsInCode('''
void bar(void Function<T>(T a) foo) {
foo<int>;
}
''');
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: foo@31
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_localVariable_call() async {
await assertNoErrorsInCode('''
void foo<T>(T a) {}
void bar() {
var fn = foo;
fn.call<int>;
}
''');
var reference = findNode.functionReference('fn.call<int>;');
// TODO(srawlins): PropertyElementResolver does not return an element for
// `.call`. If we want `findElement.method('foo')` here, we must change the
// policy over there.
assertResolvedNodeText(reference, r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: fn
staticElement: fn@40
staticType: void Function<T>(T)
period: .
identifier: SimpleIdentifier
token: call
staticElement: <null>
staticType: null
staticElement: <null>
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_localVariable_call_tooManyTypeArgs() async {
await assertErrorsInCode('''
void foo<T>(T a) {}
void bar() {
void Function(int) fn = foo;
fn.call<int>;
}
''', [
error(
CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_FUNCTION, 74, 5),
]);
var reference = findNode.functionReference('fn.call<int>;');
// TODO(srawlins): PropertyElementResolver does not return an element for
// `.call`. If we want `findElement.method('fn')` here, we must change the
// policy over there.
assertResolvedNodeText(reference, r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: fn
staticElement: fn@55
staticType: void Function(int)
period: .
identifier: SimpleIdentifier
token: call
staticElement: <null>
staticType: null
staticElement: <null>
staticType: void Function(int)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
''');
}
test_localVariable_typeVariable_boundToFunction() async {
await assertErrorsInCode('''
void bar<T extends Function>(T foo) {
foo<int>;
}
''', [
error(
CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 40, 3),
]);
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: foo@31
staticType: T
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_localVariable_typeVariable_functionTyped() async {
await assertNoErrorsInCode('''
void bar<T extends void Function<U>(U)>(T foo) {
foo<int>;
}
''');
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: foo@42
staticType: T
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_localVariable_typeVariable_nonFunction() async {
await assertErrorsInCode('''
void bar<T>(T foo) {
foo<int>;
}
''', [
error(
CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 23, 3),
]);
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: foo@14
staticType: T
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_neverTyped() async {
await assertErrorsInCode('''
external Never get i;
void bar() {
i<int>;
}
''', [
error(
CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 38, 1),
]);
assertResolvedNodeText(findNode.functionReference('i<int>;'), r'''
FunctionReference
function: SimpleIdentifier
token: i
staticElement: self::@getter::i
staticType: Never
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_nonGenericFunction() async {
await assertErrorsInCode('''
class A {
void foo() {}
bar() {
foo<int>;
}
}
''', [
error(
CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_FUNCTION, 44, 5),
]);
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: self::@class::A::@method::foo
staticType: void Function()
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function()
''');
}
test_otherExpression() async {
await assertNoErrorsInCode('''
void f(void Function<T>(T a) foo, void Function<T>(T a) bar) {
(1 == 2 ? foo : bar)<int>;
}
''');
var reference = findNode.functionReference('(1 == 2 ? foo : bar)<int>;');
assertType(reference, 'void Function(int)');
// A ParenthesizedExpression has no element to assert on.
}
test_otherExpression_wrongNumberOfTypeArguments() async {
await assertErrorsInCode('''
void f(void Function<T>(T a) foo, void Function<T>(T a) bar) {
(1 == 2 ? foo : bar)<int, String>;
}
''', [
error(
CompileTimeErrorCode
.WRONG_NUMBER_OF_TYPE_ARGUMENTS_ANONYMOUS_FUNCTION,
85,
13),
]);
var reference =
findNode.functionReference('(1 == 2 ? foo : bar)<int, String>;');
assertType(reference, 'void Function(dynamic)');
// A ParenthesizedExpression has no element to assert on.
}
test_receiverIsDynamic() async {
await assertErrorsInCode('''
bar(dynamic a) {
a.foo<int>;
}
''', [
error(CompileTimeErrorCode.GENERIC_METHOD_TYPE_INSTANTIATION_ON_DYNAMIC,
19, 5),
]);
assertResolvedNodeText(findNode.functionReference('a.foo<int>;'), r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: a
staticElement: a@12
staticType: dynamic
period: .
identifier: SimpleIdentifier
token: foo
staticElement: <null>
staticType: null
staticElement: <null>
staticType: null
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_staticMethod() async {
await assertNoErrorsInCode('''
class A {
static void foo<T>(T a) {}
bar() {
foo<int>;
}
}
''');
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: self::@class::A::@method::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_staticMethod_explicitReceiver() async {
await assertNoErrorsInCode('''
class A {
static void foo<T>(T a) {}
}
bar() {
A.foo<int>;
}
''');
assertClassRef(findNode.simple('A.'), findElement.class_('A'));
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: A
staticElement: self::@class::A
staticType: null
period: .
identifier: SimpleIdentifier
token: foo
staticElement: self::@class::A::@method::foo
staticType: null
staticElement: self::@class::A::@method::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_staticMethod_explicitReceiver_importPrefix() async {
newFile('$testPackageLibPath/a.dart', content: '''
class A {
static void foo<T>(T a) {}
}
''');
await assertNoErrorsInCode('''
import 'a.dart' as a;
bar() {
a.A.foo<int>;
}
''');
assertImportPrefix(findNode.simple('a.A'), findElement.prefix('a'));
assertClassRef(findNode.simple('A.'),
findElement.importFind('package:test/a.dart').class_('A'));
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PropertyAccess
target: PrefixedIdentifier
prefix: SimpleIdentifier
token: a
staticElement: self::@prefix::a
staticType: null
period: .
identifier: SimpleIdentifier
token: A
staticElement: package:test/a.dart::@class::A
staticType: null
staticElement: package:test/a.dart::@class::A
staticType: null
operator: .
propertyName: SimpleIdentifier
token: foo
staticElement: package:test/a.dart::@class::A::@method::foo
staticType: void Function<T>(T)
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_staticMethod_explicitReceiver_prefix_typeAlias() async {
newFile('$testPackageLibPath/a.dart', content: '''
class A {
static void foo<T>(T a) {}
}
typedef TA = A;
''');
await assertNoErrorsInCode('''
import 'a.dart' as prefix;
bar() {
prefix.TA.foo<int>;
}
''');
assertImportPrefix(
findNode.simple('prefix.'), findElement.prefix('prefix'));
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PropertyAccess
target: PrefixedIdentifier
prefix: SimpleIdentifier
token: prefix
staticElement: self::@prefix::prefix
staticType: null
period: .
identifier: SimpleIdentifier
token: TA
staticElement: package:test/a.dart::@typeAlias::TA
staticType: Type
staticElement: package:test/a.dart::@typeAlias::TA
staticType: Type
operator: .
propertyName: SimpleIdentifier
token: foo
staticElement: package:test/a.dart::@class::A::@method::foo
staticType: void Function<T>(T)
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_staticMethod_explicitReceiver_typeAlias() async {
await assertNoErrorsInCode('''
class A {
static void foo<T>(T a) {}
}
typedef TA = A;
bar() {
TA.foo<int>;
}
''');
assertTypeAliasRef(findNode.simple('TA.'), findElement.typeAlias('TA'));
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: TA
staticElement: self::@typeAlias::TA
staticType: null
period: .
identifier: SimpleIdentifier
token: foo
staticElement: self::@class::A::@method::foo
staticType: null
staticElement: self::@class::A::@method::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_staticMethod_explicitReciver_prefix() async {
newFile('$testPackageLibPath/a.dart', content: '''
class A {
static void foo<T>(T a) {}
}
''');
await assertNoErrorsInCode('''
import 'a.dart' as prefix;
bar() {
prefix.A.foo<int>;
}
''');
assertImportPrefix(
findNode.simple('prefix.'), findElement.prefix('prefix'));
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PropertyAccess
target: PrefixedIdentifier
prefix: SimpleIdentifier
token: prefix
staticElement: self::@prefix::prefix
staticType: null
period: .
identifier: SimpleIdentifier
token: A
staticElement: package:test/a.dart::@class::A
staticType: null
staticElement: package:test/a.dart::@class::A
staticType: null
operator: .
propertyName: SimpleIdentifier
token: foo
staticElement: package:test/a.dart::@class::A::@method::foo
staticType: void Function<T>(T)
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_tooFewTypeArguments() async {
await assertErrorsInCode('''
class A {
void foo<T, U>(T a, U b) {}
bar() {
foo<int>;
}
}
''', [
error(
CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_FUNCTION, 58, 5),
]);
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: self::@class::A::@method::foo
staticType: void Function<T, U>(T, U)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(dynamic, dynamic)
typeArgumentTypes
dynamic
dynamic
''');
}
test_tooManyTypeArguments() async {
await assertErrorsInCode('''
class A {
void foo<T>(T a) {}
bar() {
foo<int, int>;
}
}
''', [
error(
CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_FUNCTION, 50, 10),
]);
var reference = findNode.functionReference('foo<int, int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: self::@class::A::@method::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(dynamic)
typeArgumentTypes
dynamic
''');
}
test_topLevelFunction() async {
await assertNoErrorsInCode('''
void foo<T>(T a) {}
void bar() {
foo<int>;
}
''');
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: self::@function::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_topLevelFunction_importPrefix() async {
newFile('$testPackageLibPath/a.dart', content: '''
void foo<T>(T arg) {}
''');
await assertNoErrorsInCode('''
import 'a.dart' as a;
void bar() {
a.foo<int>;
}
''');
assertImportPrefix(findNode.simple('a.f'), findElement.prefix('a'));
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: a
staticElement: self::@prefix::a
staticType: null
period: .
identifier: SimpleIdentifier
token: foo
staticElement: package:test/a.dart::@function::foo
staticType: void Function<T>(T)
staticElement: package:test/a.dart::@function::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_topLevelFunction_importPrefix_asTargetOfFunctionCall() async {
newFile('$testPackageLibPath/a.dart', content: '''
void foo<T>(T arg) {}
''');
await assertNoErrorsInCode('''
import 'a.dart' as a;
extension on Function {
void m() {}
}
void bar() {
a.foo<int>.m();
}
''');
assertImportPrefix(findNode.simple('a.f'), findElement.prefix('a'));
var reference = findNode.functionReference('foo<int>');
assertResolvedNodeText(reference, r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: a
staticElement: self::@prefix::a
staticType: null
period: .
identifier: SimpleIdentifier
token: foo
staticElement: package:test/a.dart::@function::foo
staticType: void Function<T>(T)
staticElement: package:test/a.dart::@function::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_topLevelFunction_prefix_unknownPrefix() async {
await assertErrorsInCode('''
bar() {
prefix.foo<int>;
}
''', [
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 10, 6),
]);
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: prefix
staticElement: <null>
staticType: null
period: .
identifier: SimpleIdentifier
token: foo
staticElement: <null>
staticType: null
staticElement: <null>
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_topLevelFunction_targetOfCall() async {
await assertNoErrorsInCode('''
void foo<T>(T a) {}
void bar() {
foo<int>.call;
}
''');
assertResolvedNodeText(findNode.functionReference('foo<int>.call;'), r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: self::@function::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
assertSimpleIdentifier(findNode.simple('call;'),
element: null, type: 'void Function(int)');
}
test_topLevelFunction_targetOfFunctionCall() async {
await assertNoErrorsInCode('''
void foo<T>(T arg) {}
extension on Function {
void m() {}
}
void bar() {
foo<int>.m();
}
''');
assertResolvedNodeText(findNode.functionReference('foo<int>'), r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: self::@function::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_topLevelVariable_prefix() async {
newFile('$testPackageLibPath/a.dart', content: '''
void Function<T>(T) foo = <T>(T arg) {}
''');
await assertNoErrorsInCode('''
import 'a.dart' as prefix;
bar() {
prefix.foo<int>;
}
''');
assertImportPrefix(
findNode.simple('prefix.'), findElement.prefix('prefix'));
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: prefix
staticElement: self::@prefix::prefix
staticType: null
period: .
identifier: SimpleIdentifier
token: foo
staticElement: package:test/a.dart::@getter::foo
staticType: void Function<T>(T)
staticElement: package:test/a.dart::@getter::foo
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
test_topLevelVariable_prefix_unknownIdentifier() async {
newFile('$testPackageLibPath/a.dart', content: '');
await assertErrorsInCode('''
import 'a.dart' as prefix;
bar() {
prefix.a.foo<int>;
}
''', [
error(CompileTimeErrorCode.GENERIC_METHOD_TYPE_INSTANTIATION_ON_DYNAMIC,
38, 17),
error(CompileTimeErrorCode.UNDEFINED_PREFIXED_NAME, 45, 1),
]);
assertImportPrefix(
findNode.simple('prefix.'), findElement.prefix('prefix'));
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: PropertyAccess
target: PrefixedIdentifier
prefix: SimpleIdentifier
token: prefix
staticElement: self::@prefix::prefix
staticType: null
period: .
identifier: SimpleIdentifier
token: a
staticElement: <null>
staticType: dynamic
staticElement: <null>
staticType: dynamic
operator: .
propertyName: SimpleIdentifier
token: foo
staticElement: <null>
staticType: dynamic
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_typeAlias_function_unknownProperty() async {
await assertErrorsInCode('''
typedef Cb = void Function();
var a = Cb.foo<int>;
''', [
error(CompileTimeErrorCode.UNDEFINED_GETTER, 42, 3),
]);
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: Cb
staticElement: self::@typeAlias::Cb
staticType: Type
period: .
identifier: SimpleIdentifier
token: foo
staticElement: <null>
staticType: dynamic
staticElement: <null>
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_typeAlias_typeVariable_unknownProperty() async {
await assertErrorsInCode('''
typedef T<E> = E;
var a = T.foo<int>;
''', [
error(CompileTimeErrorCode.UNDEFINED_GETTER, 29, 3),
]);
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: T
staticElement: self::@typeAlias::T
staticType: Type
period: .
identifier: SimpleIdentifier
token: foo
staticElement: <null>
staticType: dynamic
staticElement: <null>
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_unknownIdentifier() async {
await assertErrorsInCode('''
void bar() {
foo<int>;
}
''', [
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 15, 3),
]);
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: <null>
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_unknownIdentifier_explicitReceiver() async {
await assertErrorsInCode('''
class A {}
class B {
bar(A a) {
a.foo<int>;
}
}
''', [
error(CompileTimeErrorCode.UNDEFINED_GETTER, 41, 3),
]);
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: a
staticElement: a@30
staticType: A
period: .
identifier: SimpleIdentifier
token: foo
staticElement: <null>
staticType: dynamic
staticElement: <null>
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
test_unknownIdentifier_importPrefix() async {
newFile('$testPackageLibPath/a.dart', content: '');
await assertErrorsInCode('''
import 'a.dart' as a;
void bar() {
a.foo<int>;
}
''', [
error(CompileTimeErrorCode.UNDEFINED_PREFIXED_NAME, 40, 3),
]);
assertResolvedNodeText(findNode.functionReference('foo<int>;'), r'''
FunctionReference
function: PrefixedIdentifier
prefix: SimpleIdentifier
token: a
staticElement: self::@prefix::a
staticType: null
period: .
identifier: SimpleIdentifier
token: foo
staticElement: <null>
staticType: null
staticElement: <null>
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: dynamic
''');
}
}
@reflectiveTest
class FunctionReferenceResolutionWithoutConstructorTearoffsTest
extends PubPackageResolutionTest with WithoutConstructorTearoffsMixin {
test_localVariable() async {
// This code includes a disallowed type instantiation (local variable),
// but in the case that the experiment is not enabled, we suppress the
// associated error.
await assertErrorsInCode('''
void bar(void Function<T>(T a) foo) {
foo<int>;
}
''', [
error(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 43, 5),
]);
var reference = findNode.functionReference('foo<int>;');
assertResolvedNodeText(reference, r'''
FunctionReference
function: SimpleIdentifier
token: foo
staticElement: foo@31
staticType: void Function<T>(T)
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
rightBracket: >
staticType: void Function(int)
typeArgumentTypes
int
''');
}
}