blob: 042926b7b03d062320701eabb445bf4ffdb4ac49 [file]
// Copyright (c) 2019, 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:test_reflective_loader/test_reflective_loader.dart';
import 'context_collection_resolution.dart';
import 'node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(CallInvocationTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@reflectiveTest
class CallInvocationTest extends PubPackageResolutionTest {
test_call_infer_fromArguments() async {
var result = await resolveTestCodeWithDiagnostics(r'''
class A {
void call<T>(T t) {}
}
void f(A a) {
a(0);
}
''');
var node = result.findNode.callInvocation('a(0)');
assertResolvedNodeText(node, r'''
CallInvocation
receiver: UnqualifiedNameExpression
name: a
resolution: VariableReadResolution
element: <testLibrary>::@function::f::@formalParameter::a
type: A
staticType: A
argumentList: ArgumentList
leftParenthesis: (
arguments2
IntegerLiteral
literal: 0
correspondingParameter: SubstitutedFormalParameterElementImpl
baseElement: <testLibrary>::@class::A::@method::call::@formalParameter::t
substitution: {T: int}
staticType: int
rightParenthesis: )
resolution: ExecutableInvocationResolution
element: <testLibrary>::@class::A::@method::call
invokeType: void Function(int)
type: void
staticType: void
typeArgumentTypes
int
V1: FunctionExpressionInvocation
function: SimpleIdentifier
token: a
element: <testLibrary>::@function::f::@formalParameter::a
staticType: A
argumentList: ArgumentList
leftParenthesis: (
arguments
IntegerLiteral
literal: 0
correspondingParameter: SubstitutedFormalParameterElementImpl
baseElement: <testLibrary>::@class::A::@method::call::@formalParameter::t
substitution: {T: int}
staticType: int
rightParenthesis: )
element: <testLibrary>::@class::A::@method::call
staticInvokeType: void Function(int)
staticType: void
typeArgumentTypes
int
''');
}
test_call_infer_fromArguments_listLiteral() async {
var result = await resolveTestCodeWithDiagnostics(r'''
class A {
List<T> call<T>(List<T> _) {
throw 42;
}
}
main(A a) {
// ^
// [diag.mainFirstPositionalParameterType] The type of the first positional parameter of the 'main' function must be a supertype of 'List<String>'.
a([0]);
}
''');
var node = result.findNode.callInvocation('a([');
assertResolvedNodeText(node, r'''
CallInvocation
receiver: UnqualifiedNameExpression
name: a
resolution: VariableReadResolution
element: <testLibrary>::@function::main::@formalParameter::a
type: A
staticType: A
argumentList: ArgumentList
leftParenthesis: (
arguments2
ListLiteral
leftBracket: [
elements2
IntegerLiteral
literal: 0
staticType: int
rightBracket: ]
correspondingParameter: SubstitutedFormalParameterElementImpl
baseElement: <testLibrary>::@class::A::@method::call::@formalParameter::_
substitution: {T: int}
staticType: List<int>
rightParenthesis: )
resolution: ExecutableInvocationResolution
element: <testLibrary>::@class::A::@method::call
invokeType: List<int> Function(List<int>)
type: List<int>
staticType: List<int>
typeArgumentTypes
int
V1: FunctionExpressionInvocation
function: SimpleIdentifier
token: a
element: <testLibrary>::@function::main::@formalParameter::a
staticType: A
argumentList: ArgumentList
leftParenthesis: (
arguments
ListLiteral
leftBracket: [
elements
IntegerLiteral
literal: 0
staticType: int
rightBracket: ]
correspondingParameter: SubstitutedFormalParameterElementImpl
baseElement: <testLibrary>::@class::A::@method::call::@formalParameter::_
substitution: {T: int}
staticType: List<int>
rightParenthesis: )
element: <testLibrary>::@class::A::@method::call
staticInvokeType: List<int> Function(List<int>)
staticType: List<int>
typeArgumentTypes
int
''');
}
test_call_infer_fromContext() async {
var result = await resolveTestCodeWithDiagnostics(r'''
class A {
T call<T>() {
throw 42;
}
}
void f(A a, int context) {
context = a();
}
''');
var node = result.findNode.callInvocation('a()');
assertResolvedNodeText(node, r'''
CallInvocation
receiver: UnqualifiedNameExpression
name: a
resolution: VariableReadResolution
element: <testLibrary>::@function::f::@formalParameter::a
type: A
staticType: A
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
resolution: ExecutableInvocationResolution
element: <testLibrary>::@class::A::@method::call
invokeType: int Function()
type: int
correspondingParameter: <null>
staticType: int
typeArgumentTypes
int
V1: FunctionExpressionInvocation
function: SimpleIdentifier
token: a
element: <testLibrary>::@function::f::@formalParameter::a
staticType: A
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
element: <testLibrary>::@class::A::@method::call
staticInvokeType: int Function()
staticType: int
typeArgumentTypes
int
''');
}
test_call_typeArguments() async {
var result = await resolveTestCodeWithDiagnostics(r'''
class A {
T call<T>() {
throw 42;
}
}
void f(A a) {
a<int>();
}
''');
var node = result.findNode.callInvocation('a<int>()');
assertResolvedNodeText(node, r'''
CallInvocation
receiver: UnqualifiedNameExpression
name: a
resolution: VariableReadResolution
element: <testLibrary>::@function::f::@formalParameter::a
type: A
staticType: A
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: int
element: dart:core::@class::int
type: int
rightBracket: >
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
resolution: ExecutableInvocationResolution
element: <testLibrary>::@class::A::@method::call
invokeType: int Function()
type: int
staticType: int
typeArgumentTypes
int
V1: FunctionExpressionInvocation
function: SimpleIdentifier
token: a
element: <testLibrary>::@function::f::@formalParameter::a
staticType: A
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: int
element: dart:core::@class::int
type: int
rightBracket: >
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
element: <testLibrary>::@class::A::@method::call
staticInvokeType: int Function()
staticType: int
typeArgumentTypes
int
''');
}
test_dynamic_withoutTypeArguments() async {
var result = await resolveTestCodeWithDiagnostics(r'''
main() {
(main as dynamic)(0);
}
''');
var node = result.findNode.callInvocation('(0)');
assertResolvedNodeText(node, r'''
CallInvocation
receiver: ParenthesizedExpression
leftParenthesis: (
expression2: AsExpression
expression2: UnqualifiedNameExpression
name: main
resolution: ExecutableTearOffResolution
element: <testLibrary>::@function::main
type: dynamic Function()
staticType: dynamic Function()
asOperator: as
type: NamedType
name: dynamic
element: dynamic
type: dynamic
staticType: dynamic
rightParenthesis: )
staticType: dynamic
argumentList: ArgumentList
leftParenthesis: (
arguments2
IntegerLiteral
literal: 0
correspondingParameter: <null>
staticType: int
rightParenthesis: )
resolution: DynamicInvocationResolution
type: dynamic
staticType: dynamic
V1: FunctionExpressionInvocation
function: ParenthesizedExpression
leftParenthesis: (
expression: AsExpression
expression: SimpleIdentifier
token: main
element: <testLibrary>::@function::main
staticType: dynamic Function()
asOperator: as
type: NamedType
name: dynamic
element: dynamic
type: dynamic
staticType: dynamic
rightParenthesis: )
staticType: dynamic
argumentList: ArgumentList
leftParenthesis: (
arguments
IntegerLiteral
literal: 0
correspondingParameter: <null>
staticType: int
rightParenthesis: )
element: <null>
staticInvokeType: dynamic
staticType: dynamic
''');
}
test_dynamic_withTypeArguments() async {
var result = await resolveTestCodeWithDiagnostics(r'''
main() {
(main as dynamic)<bool, int>(0);
}
''');
var node = result.findNode.callInvocation('(0)');
assertResolvedNodeText(node, r'''
CallInvocation
receiver: ParenthesizedExpression
leftParenthesis: (
expression2: AsExpression
expression2: UnqualifiedNameExpression
name: main
resolution: ExecutableTearOffResolution
element: <testLibrary>::@function::main
type: dynamic Function()
staticType: dynamic Function()
asOperator: as
type: NamedType
name: dynamic
element: dynamic
type: dynamic
staticType: dynamic
rightParenthesis: )
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: bool
element: dart:core::@class::bool
type: bool
NamedType
name: int
element: dart:core::@class::int
type: int
rightBracket: >
argumentList: ArgumentList
leftParenthesis: (
arguments2
IntegerLiteral
literal: 0
correspondingParameter: <null>
staticType: int
rightParenthesis: )
resolution: DynamicInvocationResolution
type: dynamic
staticType: dynamic
typeArgumentTypes
bool
int
V1: FunctionExpressionInvocation
function: ParenthesizedExpression
leftParenthesis: (
expression: AsExpression
expression: SimpleIdentifier
token: main
element: <testLibrary>::@function::main
staticType: dynamic Function()
asOperator: as
type: NamedType
name: dynamic
element: dynamic
type: dynamic
staticType: dynamic
rightParenthesis: )
staticType: dynamic
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: bool
element: dart:core::@class::bool
type: bool
NamedType
name: int
element: dart:core::@class::int
type: int
rightBracket: >
argumentList: ArgumentList
leftParenthesis: (
arguments
IntegerLiteral
literal: 0
correspondingParameter: <null>
staticType: int
rightParenthesis: )
element: <null>
staticInvokeType: dynamic
staticType: dynamic
typeArgumentTypes
bool
int
''');
}
test_expression_interfaceType_nullable_hasCall() async {
var result = await resolveTestCodeWithDiagnostics(r'''
void f(int? a) {
a();
}
extension on int? {
int call() => 0;
}
''');
var node = result.findNode.callInvocation('();');
assertResolvedNodeText(node, r'''
CallInvocation
receiver: UnqualifiedNameExpression
name: a
resolution: VariableReadResolution
element: <testLibrary>::@function::f::@formalParameter::a
type: int?
staticType: int?
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
resolution: ExecutableInvocationResolution
element: <testLibrary>::@extension::#0::@method::call
invokeType: int Function()
type: int
staticType: int
V1: FunctionExpressionInvocation
function: SimpleIdentifier
token: a
element: <testLibrary>::@function::f::@formalParameter::a
staticType: int?
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
element: <testLibrary>::@extension::#0::@method::call
staticInvokeType: int Function()
staticType: int
''');
}
test_expression_recordType_hasCall_extensionMethod() async {
var result = await resolveTestCodeWithDiagnostics(r'''
void f((String,) a) {
a();
}
extension on (String,) {
int call() => 0;
}
''');
var node = result.findNode.callInvocation('();');
assertResolvedNodeText(node, r'''
CallInvocation
receiver: UnqualifiedNameExpression
name: a
resolution: VariableReadResolution
element: <testLibrary>::@function::f::@formalParameter::a
type: (String,)
staticType: (String,)
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
resolution: ExecutableInvocationResolution
element: <testLibrary>::@extension::#0::@method::call
invokeType: int Function()
type: int
staticType: int
V1: FunctionExpressionInvocation
function: SimpleIdentifier
token: a
element: <testLibrary>::@function::f::@formalParameter::a
staticType: (String,)
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
element: <testLibrary>::@extension::#0::@method::call
staticInvokeType: int Function()
staticType: int
''');
}
test_expression_recordType_hasCall_namedField() async {
var result = await resolveTestCodeWithDiagnostics(r'''
void f() {
var r = (call: () => 0);
r();
//^
// [diag.invocationOfNonFunctionExpression] The expression doesn't evaluate to a function, so it can't be invoked.
}
''');
var node = result.findNode.singleCallInvocation;
assertResolvedNodeText(node, r'''
CallInvocation
receiver: UnqualifiedNameExpression
name: r
resolution: VariableReadResolution
element: r@17
type: ({int Function() call})
staticType: ({int Function() call})
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
resolution: InvalidInvocationResolution
type: InvalidType
recovery: <null>
staticType: InvalidType
V1: FunctionExpressionInvocation
function: SimpleIdentifier
token: r
element: r@17
staticType: ({int Function() call})
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
element: <null>
staticInvokeType: InvalidType
staticType: InvalidType
''');
}
test_expression_recordType_noCall() async {
var result = await resolveTestCodeWithDiagnostics(r'''
void f((String,) a) {
a();
//^
// [diag.invocationOfNonFunctionExpression] The expression doesn't evaluate to a function, so it can't be invoked.
}
''');
var node = result.findNode.callInvocation('();');
assertResolvedNodeText(node, r'''
CallInvocation
receiver: UnqualifiedNameExpression
name: a
resolution: VariableReadResolution
element: <testLibrary>::@function::f::@formalParameter::a
type: (String,)
staticType: (String,)
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
resolution: InvalidInvocationResolution
type: InvalidType
recovery: <null>
staticType: InvalidType
V1: FunctionExpressionInvocation
function: SimpleIdentifier
token: a
element: <testLibrary>::@function::f::@formalParameter::a
staticType: (String,)
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
element: <null>
staticInvokeType: InvalidType
staticType: InvalidType
''');
}
test_formalParameter_generic() async {
var result = await resolveTestCodeWithDiagnostics(r'''
void f(T Function<T>(T a) g) {
g(0);
}
''');
var node = result.findNode.singleCallInvocation;
assertResolvedNodeText(node, r'''
CallInvocation
receiver: UnqualifiedNameExpression
name: g
resolution: VariableReadResolution
element: <testLibrary>::@function::f::@formalParameter::g
type: T Function<T>(T)
staticType: T Function<T>(T)
argumentList: ArgumentList
leftParenthesis: (
arguments2
IntegerLiteral
literal: 0
correspondingParameter: SubstitutedFormalParameterElementImpl
baseElement: a@23
substitution: {T: int}
staticType: int
rightParenthesis: )
resolution: FunctionTypeInvocationResolution
invokeType: int Function(int)
type: int
staticType: int
typeArgumentTypes
int
V1: FunctionExpressionInvocation
function: SimpleIdentifier
token: g
element: <testLibrary>::@function::f::@formalParameter::g
staticType: T Function<T>(T)
argumentList: ArgumentList
leftParenthesis: (
arguments
IntegerLiteral
literal: 0
correspondingParameter: SubstitutedFormalParameterElementImpl
baseElement: a@23
substitution: {T: int}
staticType: int
rightParenthesis: )
element: <null>
staticInvokeType: int Function(int)
staticType: int
typeArgumentTypes
int
''');
}
test_formalParameter_generic_withTypeArguments() async {
var result = await resolveTestCodeWithDiagnostics(r'''
typedef F<S> = S Function<T>(T x);
void f(F<int> a) {
a<String>('hello');
}
''');
var node = result.findNode.singleCallInvocation;
assertResolvedNodeText(node, r'''
CallInvocation
receiver: UnqualifiedNameExpression
name: a
resolution: VariableReadResolution
element: <testLibrary>::@function::f::@formalParameter::a
type: int Function<T>(T)
alias: <testLibrary>::@typeAlias::F
typeArguments
int
staticType: int Function<T>(T)
alias: <testLibrary>::@typeAlias::F
typeArguments
int
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: String
element: dart:core::@class::String
type: String
rightBracket: >
argumentList: ArgumentList
leftParenthesis: (
arguments2
SimpleStringLiteral
literal: 'hello'
rightParenthesis: )
resolution: FunctionTypeInvocationResolution
invokeType: int Function(String)
type: int
staticType: int
typeArgumentTypes
String
V1: FunctionExpressionInvocation
function: SimpleIdentifier
token: a
element: <testLibrary>::@function::f::@formalParameter::a
staticType: int Function<T>(T)
alias: <testLibrary>::@typeAlias::F
typeArguments
int
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: String
element: dart:core::@class::String
type: String
rightBracket: >
argumentList: ArgumentList
leftParenthesis: (
arguments
SimpleStringLiteral
literal: 'hello'
rightParenthesis: )
element: <null>
staticInvokeType: int Function(String)
staticType: int
typeArgumentTypes
String
''');
}
test_formalParameter_tooManyArguments() async {
var result = await resolveTestCodeWithDiagnostics(r'''
void f(int Function() g, int a) {
g(a);
// ^
// [diag.extraPositionalArguments] Too many positional arguments: 0 expected, but 1 found.
}
''');
var node = result.findNode.singleCallInvocation;
assertResolvedNodeText(node, r'''
CallInvocation
receiver: UnqualifiedNameExpression
name: g
resolution: VariableReadResolution
element: <testLibrary>::@function::f::@formalParameter::g
type: int Function()
staticType: int Function()
argumentList: ArgumentList
leftParenthesis: (
arguments2
UnqualifiedNameExpression
name: a
resolution: VariableReadResolution
element: <testLibrary>::@function::f::@formalParameter::a
type: int
correspondingParameter: <null>
staticType: int
rightParenthesis: )
resolution: FunctionTypeInvocationResolution
invokeType: int Function()
type: int
staticType: int
V1: FunctionExpressionInvocation
function: SimpleIdentifier
token: g
element: <testLibrary>::@function::f::@formalParameter::g
staticType: int Function()
argumentList: ArgumentList
leftParenthesis: (
arguments
SimpleIdentifier
token: a
correspondingParameter: <null>
element: <testLibrary>::@function::f::@formalParameter::a
staticType: int
rightParenthesis: )
element: <null>
staticInvokeType: int Function()
staticType: int
''');
}
test_getter_functionTyped() async {
var result = await resolveTestCodeWithDiagnostics(r'''
typedef F = String Function(int a, {int b});
class A {
F get foo => throw 0;
void f() {
foo(1, b: 2);
}
}
''');
var node = result.findNode.singleCallInvocation;
assertResolvedNodeText(node, r'''
CallInvocation
receiver: UnqualifiedNameExpression
name: foo
resolution: GetterInvocationResolution
element: <testLibrary>::@class::A::@getter::foo
invokeType: String Function(int, {int b}) Function()
type: String Function(int, {int b})
alias: <testLibrary>::@typeAlias::F
staticType: String Function(int, {int b})
alias: <testLibrary>::@typeAlias::F
argumentList: ArgumentList
leftParenthesis: (
arguments2
IntegerLiteral
literal: 1
correspondingParameter: a@null
staticType: int
NamedArgument
name: b
colon: :
argumentExpression2: IntegerLiteral
literal: 2
staticType: int
correspondingParameter: b@null
rightParenthesis: )
resolution: FunctionTypeInvocationResolution
invokeType: String Function(int, {int b})
alias: <testLibrary>::@typeAlias::F
type: String
staticType: String
V1: FunctionExpressionInvocation
function: SimpleIdentifier
token: foo
element: <testLibrary>::@class::A::@getter::foo
staticType: String Function(int, {int b})
alias: <testLibrary>::@typeAlias::F
argumentList: ArgumentList
leftParenthesis: (
arguments
IntegerLiteral
literal: 1
correspondingParameter: a@null
staticType: int
NamedArgument
name: b
colon: :
argumentExpression: IntegerLiteral
literal: 2
staticType: int
correspondingParameter: b@null
rightParenthesis: )
element: <null>
staticInvokeType: String Function(int, {int b})
alias: <testLibrary>::@typeAlias::F
staticType: String
''');
}
test_getter_functionTyped_withSetterDeclaredLocally() async {
var result = await resolveTestCodeWithDiagnostics('''
class A {
Function get foo => () {};
}
class B extends A {
set foo(Function _) {}
void f() {
foo();
}
}
''');
var node = result.findNode.singleCallInvocation;
assertResolvedNodeText(node, r'''
CallInvocation
receiver: UnqualifiedNameExpression
name: foo
resolution: GetterInvocationResolution
element: <testLibrary>::@class::A::@getter::foo
invokeType: Function Function()
type: Function
staticType: Function
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
resolution: FunctionInterfaceInvocationResolution
type: dynamic
staticType: dynamic
V1: FunctionExpressionInvocation
function: SimpleIdentifier
token: foo
element: <testLibrary>::@class::A::@getter::foo
staticType: Function
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
element: <null>
staticInvokeType: dynamic
staticType: dynamic
''');
}
test_invalidConst_topLevelVariable() async {
var result = await resolveTestCodeWithDiagnostics(r'''
const id = identical;
const a = 0;
const b = 0;
const c = id(a, b);
// ^^^^^^^^
// [diag.constInitializedWithNonConstantValue] Const variables must be initialized with a constant value.
''');
var node = result.findNode.singleCallInvocation;
assertResolvedNodeText(node, r'''
CallInvocation
receiver: UnqualifiedNameExpression
name: id
resolution: GetterInvocationResolution
element: <testLibrary>::@getter::id
invokeType: bool Function(Object?, Object?) Function()
type: bool Function(Object?, Object?)
staticType: bool Function(Object?, Object?)
argumentList: ArgumentList
leftParenthesis: (
arguments2
UnqualifiedNameExpression
name: a
resolution: GetterInvocationResolution
element: <testLibrary>::@getter::a
invokeType: int Function()
type: int
correspondingParameter: dart:core::@function::identical::@formalParameter::a
staticType: int
UnqualifiedNameExpression
name: b
resolution: GetterInvocationResolution
element: <testLibrary>::@getter::b
invokeType: int Function()
type: int
correspondingParameter: dart:core::@function::identical::@formalParameter::b
staticType: int
rightParenthesis: )
resolution: FunctionTypeInvocationResolution
invokeType: bool Function(Object?, Object?)
type: bool
staticType: bool
V1: FunctionExpressionInvocation
function: SimpleIdentifier
token: id
element: <testLibrary>::@getter::id
staticType: bool Function(Object?, Object?)
argumentList: ArgumentList
leftParenthesis: (
arguments
SimpleIdentifier
token: a
correspondingParameter: dart:core::@function::identical::@formalParameter::a
element: <testLibrary>::@getter::a
staticType: int
SimpleIdentifier
token: b
correspondingParameter: dart:core::@function::identical::@formalParameter::b
element: <testLibrary>::@getter::b
staticType: int
rightParenthesis: )
element: <null>
staticInvokeType: bool Function(Object?, Object?)
staticType: bool
''');
}
test_never() async {
var result = await resolveTestCodeWithDiagnostics(r'''
void f(Never x) {
x<int>(1 + 2);
//^
// [diag.receiverOfTypeNever] The receiver is of type 'Never', and will never complete with a value.
// ^^^^^^^^
// [diag.deadCode] Dead code.
}
''');
var node = result.findNode.callInvocation('x<int>(1 + 2)');
assertResolvedNodeText(node, r'''
CallInvocation
receiver: UnqualifiedNameExpression
name: x
resolution: VariableReadResolution
element: <testLibrary>::@function::f::@formalParameter::x
type: Never
staticType: Never
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: int
element: dart:core::@class::int
type: int
rightBracket: >
argumentList: ArgumentList
leftParenthesis: (
arguments2
BinaryOperatorInvocation
leftOperand: IntegerLiteral
literal: 1
staticType: int
operator: +
rightOperand: IntegerLiteral
literal: 2
correspondingParameter: dart:core::@class::num::@method::+::@formalParameter::other
staticType: int
correspondingParameter: <null>
binaryOperator: add
element: dart:core::@class::num::@method::+
staticType: int
rightParenthesis: )
resolution: <null>
staticType: Never
typeArgumentTypes
int
V1: FunctionExpressionInvocation
function: SimpleIdentifier
token: x
element: <testLibrary>::@function::f::@formalParameter::x
staticType: Never
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: int
element: dart:core::@class::int
type: int
rightBracket: >
argumentList: ArgumentList
leftParenthesis: (
arguments
BinaryExpression
leftOperand: IntegerLiteral
literal: 1
staticType: int
operator: +
rightOperand: IntegerLiteral
literal: 2
correspondingParameter: dart:core::@class::num::@method::+::@formalParameter::other
staticType: int
correspondingParameter: <null>
element: dart:core::@class::num::@method::+
staticInvokeType: num Function(num)
staticType: int
rightParenthesis: )
element: <null>
staticInvokeType: Never
staticType: Never
typeArgumentTypes
int
''');
}
test_neverQ() async {
var result = await resolveTestCodeWithDiagnostics(r'''
void f(Never? x) {
x<int>(1 + 2);
//^
// [diag.uncheckedInvocationOfNullableValue] The function can't be unconditionally invoked because it can be 'null'.
}
''');
var node = result.findNode.callInvocation('x<int>(1 + 2)');
assertResolvedNodeText(node, r'''
CallInvocation
receiver: UnqualifiedNameExpression
name: x
resolution: VariableReadResolution
element: <testLibrary>::@function::f::@formalParameter::x
type: Never?
staticType: Never?
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: int
element: dart:core::@class::int
type: int
rightBracket: >
argumentList: ArgumentList
leftParenthesis: (
arguments2
BinaryOperatorInvocation
leftOperand: IntegerLiteral
literal: 1
staticType: int
operator: +
rightOperand: IntegerLiteral
literal: 2
correspondingParameter: dart:core::@class::num::@method::+::@formalParameter::other
staticType: int
correspondingParameter: <null>
binaryOperator: add
element: dart:core::@class::num::@method::+
staticType: int
rightParenthesis: )
resolution: InvalidInvocationResolution
type: InvalidType
recovery: <null>
staticType: InvalidType
typeArgumentTypes
int
V1: FunctionExpressionInvocation
function: SimpleIdentifier
token: x
element: <testLibrary>::@function::f::@formalParameter::x
staticType: Never?
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: int
element: dart:core::@class::int
type: int
rightBracket: >
argumentList: ArgumentList
leftParenthesis: (
arguments
BinaryExpression
leftOperand: IntegerLiteral
literal: 1
staticType: int
operator: +
rightOperand: IntegerLiteral
literal: 2
correspondingParameter: dart:core::@class::num::@method::+::@formalParameter::other
staticType: int
correspondingParameter: <null>
element: dart:core::@class::num::@method::+
staticInvokeType: num Function(num)
staticType: int
rightParenthesis: )
element: <null>
staticInvokeType: InvalidType
staticType: InvalidType
typeArgumentTypes
int
''');
}
test_nullShorting() async {
var result = await resolveTestCodeWithDiagnostics(r'''
abstract class A {
int Function() get foo;
}
class B {
void bar(A? a) {
a?.foo();
}
}
''');
var node = result.findNode.callInvocation('a?.foo()');
assertResolvedNodeText(node, r'''
CallInvocation
receiver: ReceiverPropertyExtraction
receiver: UnqualifiedNameExpression
name: a
resolution: VariableReadResolution
element: <testLibrary>::@class::B::@method::bar::@formalParameter::a
type: A?
staticType: A?
operator: ?.
name: foo
resolution: GetterInvocationResolution
element: <testLibrary>::@class::A::@getter::foo
invokeType: int Function() Function()
type: int Function()
staticType: int Function()
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
resolution: FunctionTypeInvocationResolution
invokeType: int Function()
type: int
staticType: int?
V1: FunctionExpressionInvocation
function: PropertyAccess
target: SimpleIdentifier
token: a
element: <testLibrary>::@class::B::@method::bar::@formalParameter::a
staticType: A?
operator: ?.
propertyName: SimpleIdentifier
token: foo
element: <testLibrary>::@class::A::@getter::foo
staticType: int Function()
staticType: int Function()
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
element: <null>
staticInvokeType: int Function()
staticType: int?
''');
}
test_nullShorting_extended() async {
var result = await resolveTestCodeWithDiagnostics('''
abstract class A {
int Function() f();
}
test(A? a) => a?.f()();
''');
var node = result.findNode.callInvocation('a?.f()()');
assertResolvedNodeText(node, r'''
CallInvocation
receiver: ReceiverMethodInvocation
receiver: UnqualifiedNameExpression
name: a
resolution: VariableReadResolution
element: <testLibrary>::@function::test::@formalParameter::a
type: A?
staticType: A?
operator: ?.
name: f
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
resolution: ExecutableInvocationResolution
element: <testLibrary>::@class::A::@method::f
invokeType: int Function() Function()
type: int Function()
staticType: int Function()
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
resolution: FunctionTypeInvocationResolution
invokeType: int Function()
type: int
staticType: int?
V1: FunctionExpressionInvocation
function: MethodInvocation
target: SimpleIdentifier
token: a
element: <testLibrary>::@function::test::@formalParameter::a
staticType: A?
operator: ?.
methodName: SimpleIdentifier
token: f
element: <testLibrary>::@class::A::@method::f
staticType: int Function() Function()
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
staticInvokeType: int Function() Function()
staticType: int Function()
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
element: <null>
staticInvokeType: int Function()
staticType: int?
''');
}
test_nullShorting_extends() async {
var result = await resolveTestCodeWithDiagnostics(r'''
abstract class A {
int Function() get foo;
}
class B {
void bar(A? a) {
a?.foo().isEven;
}
}
''');
var node = result.findNode.receiverPropertyExtraction('isEven');
assertResolvedNodeText(node, r'''
ReceiverPropertyExtraction
receiver: CallInvocation
receiver: ReceiverPropertyExtraction
receiver: UnqualifiedNameExpression
name: a
resolution: VariableReadResolution
element: <testLibrary>::@class::B::@method::bar::@formalParameter::a
type: A?
staticType: A?
operator: ?.
name: foo
resolution: GetterInvocationResolution
element: <testLibrary>::@class::A::@getter::foo
invokeType: int Function() Function()
type: int Function()
staticType: int Function()
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
resolution: FunctionTypeInvocationResolution
invokeType: int Function()
type: int
staticType: int
operator: .
name: isEven
resolution: GetterInvocationResolution
element: dart:core::@class::int::@getter::isEven
invokeType: bool Function()
type: bool
staticType: bool?
V1: PropertyAccess
target: FunctionExpressionInvocation
function: PropertyAccess
target: SimpleIdentifier
token: a
element: <testLibrary>::@class::B::@method::bar::@formalParameter::a
staticType: A?
operator: ?.
propertyName: SimpleIdentifier
token: foo
element: <testLibrary>::@class::A::@getter::foo
staticType: int Function()
staticType: int Function()
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
element: <null>
staticInvokeType: int Function()
staticType: int
operator: .
propertyName: SimpleIdentifier
token: isEven
element: dart:core::@class::int::@getter::isEven
staticType: bool
staticType: bool?
''');
}
test_on_switchExpression() async {
var result = await resolveTestCodeWithDiagnostics(r'''
void f(Object? x) {
(switch (x) {
_ => foo,
}());
}
void foo() {}
''');
var node = result.findNode.callInvocation('}()');
assertResolvedNodeText(node, r'''
CallInvocation
receiver: SwitchExpression
switchKeyword: switch
leftParenthesis: (
expression2: UnqualifiedNameExpression
name: x
resolution: VariableReadResolution
element: <testLibrary>::@function::f::@formalParameter::x
type: Object?
staticType: Object?
rightParenthesis: )
leftBracket: {
cases
SwitchExpressionCase
guardedPattern: GuardedPattern
pattern: WildcardPattern
name: _
matchedValueType: Object?
arrow: =>
expression2: UnqualifiedNameExpression
name: foo
resolution: ExecutableTearOffResolution
element: <testLibrary>::@function::foo
type: void Function()
staticType: void Function()
rightBracket: }
staticType: void Function()
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
resolution: FunctionTypeInvocationResolution
invokeType: void Function()
type: void
staticType: void
V1: FunctionExpressionInvocation
function: SwitchExpression
switchKeyword: switch
leftParenthesis: (
expression: SimpleIdentifier
token: x
element: <testLibrary>::@function::f::@formalParameter::x
staticType: Object?
rightParenthesis: )
leftBracket: {
cases
SwitchExpressionCase
guardedPattern: GuardedPattern
pattern: WildcardPattern
name: _
matchedValueType: Object?
arrow: =>
expression: SimpleIdentifier
token: foo
element: <testLibrary>::@function::foo
staticType: void Function()
rightBracket: }
staticType: void Function()
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
element: <null>
staticInvokeType: void Function()
staticType: void
''');
}
test_record_field_named() async {
var result = await resolveTestCodeWithDiagnostics(r'''
void f(({void Function(int) foo}) r) {
r.foo(0);
}
''');
var node = result.findNode.callInvocation('(0)');
assertResolvedNodeText(node, r'''
CallInvocation
receiver: ReceiverPropertyExtraction
receiver: UnqualifiedNameExpression
name: r
resolution: VariableReadResolution
element: <testLibrary>::@function::f::@formalParameter::r
type: ({void Function(int) foo})
staticType: ({void Function(int) foo})
operator: .
name: foo
resolution: RecordFieldReadResolution
type: void Function(int)
staticType: void Function(int)
argumentList: ArgumentList
leftParenthesis: (
arguments2
IntegerLiteral
literal: 0
correspondingParameter: <null-name>@null
staticType: int
rightParenthesis: )
resolution: FunctionTypeInvocationResolution
invokeType: void Function(int)
type: void
staticType: void
V1: FunctionExpressionInvocation
function: PropertyAccess
target: SimpleIdentifier
token: r
element: <testLibrary>::@function::f::@formalParameter::r
staticType: ({void Function(int) foo})
operator: .
propertyName: SimpleIdentifier
token: foo
element: <null>
staticType: void Function(int)
staticType: void Function(int)
argumentList: ArgumentList
leftParenthesis: (
arguments
IntegerLiteral
literal: 0
correspondingParameter: <null-name>@null
staticType: int
rightParenthesis: )
element: <null>
staticInvokeType: void Function(int)
staticType: void
''');
}
test_record_field_positional_rewrite() async {
var result = await resolveTestCodeWithDiagnostics(r'''
void f((void Function(int),) r) {
r.$1(0);
}
''');
var node = result.findNode.callInvocation('(0)');
assertResolvedNodeText(node, r'''
CallInvocation
receiver: ReceiverPropertyExtraction
receiver: UnqualifiedNameExpression
name: r
resolution: VariableReadResolution
element: <testLibrary>::@function::f::@formalParameter::r
type: (void Function(int),)
staticType: (void Function(int),)
operator: .
name: $1
resolution: RecordFieldReadResolution
type: void Function(int)
staticType: void Function(int)
argumentList: ArgumentList
leftParenthesis: (
arguments2
IntegerLiteral
literal: 0
correspondingParameter: <null-name>@null
staticType: int
rightParenthesis: )
resolution: FunctionTypeInvocationResolution
invokeType: void Function(int)
type: void
staticType: void
V1: FunctionExpressionInvocation
function: PropertyAccess
target: SimpleIdentifier
token: r
element: <testLibrary>::@function::f::@formalParameter::r
staticType: (void Function(int),)
operator: .
propertyName: SimpleIdentifier
token: $1
element: <null>
staticType: void Function(int)
staticType: void Function(int)
argumentList: ArgumentList
leftParenthesis: (
arguments
IntegerLiteral
literal: 0
correspondingParameter: <null-name>@null
staticType: int
rightParenthesis: )
element: <null>
staticInvokeType: void Function(int)
staticType: void
''');
}
test_record_field_positional_withParenthesis() async {
var result = await resolveTestCodeWithDiagnostics(r'''
void f((void Function(int),) r) {
(r.$1)(0);
}
''');
var node = result.findNode.callInvocation('(0)');
assertResolvedNodeText(node, r'''
CallInvocation
receiver: ParenthesizedExpression
leftParenthesis: (
expression2: ReceiverPropertyExtraction
receiver: UnqualifiedNameExpression
name: r
resolution: VariableReadResolution
element: <testLibrary>::@function::f::@formalParameter::r
type: (void Function(int),)
staticType: (void Function(int),)
operator: .
name: $1
resolution: RecordFieldReadResolution
type: void Function(int)
staticType: void Function(int)
rightParenthesis: )
staticType: void Function(int)
argumentList: ArgumentList
leftParenthesis: (
arguments2
IntegerLiteral
literal: 0
correspondingParameter: <null-name>@null
staticType: int
rightParenthesis: )
resolution: FunctionTypeInvocationResolution
invokeType: void Function(int)
type: void
staticType: void
V1: FunctionExpressionInvocation
function: ParenthesizedExpression
leftParenthesis: (
expression: PropertyAccess
target: SimpleIdentifier
token: r
element: <testLibrary>::@function::f::@formalParameter::r
staticType: (void Function(int),)
operator: .
propertyName: SimpleIdentifier
token: $1
element: <null>
staticType: void Function(int)
staticType: void Function(int)
rightParenthesis: )
staticType: void Function(int)
argumentList: ArgumentList
leftParenthesis: (
arguments
IntegerLiteral
literal: 0
correspondingParameter: <null-name>@null
staticType: int
rightParenthesis: )
element: <null>
staticInvokeType: void Function(int)
staticType: void
''');
}
test_super_generic() async {
var result = await resolveTestCodeWithDiagnostics(r'''
class A<T> {
T call(T value) => value;
}
class B extends A<int> {
@override
int call(int value) => value * 2;
int f() => super(1);
}
''');
var node = result.findNode.singleCallInvocation;
assertResolvedNodeText(node, r'''
CallInvocation
receiver: SuperReference
superKeyword: super
argumentList: ArgumentList
leftParenthesis: (
arguments2
IntegerLiteral
literal: 1
correspondingParameter: value@null
staticType: int
rightParenthesis: )
resolution: ExecutableInvocationResolution
element: SubstitutedMethodElementImpl
baseElement: <testLibrary>::@class::A::@method::call
substitution: {T: int}
invokeType: int Function(int)
type: int
staticType: int
V1: FunctionExpressionInvocation
function: SuperExpression
superKeyword: super
staticType: B
argumentList: ArgumentList
leftParenthesis: (
arguments
IntegerLiteral
literal: 1
correspondingParameter: value@null
staticType: int
rightParenthesis: )
element: SubstitutedMethodElementImpl
baseElement: <testLibrary>::@class::A::@method::call
substitution: {T: int}
staticInvokeType: int Function(int)
staticType: int
''');
}
test_super_missingCall() async {
var result = await resolveTestCodeWithDiagnostics(r'''
class A {
void f() {
super();
// ^^^^^
// [diag.invocationOfNonFunctionExpression] The expression doesn't evaluate to a function, so it can't be invoked.
}
}
''');
var node = result.findNode.singleCallInvocation;
assertResolvedNodeText(node, r'''
CallInvocation
receiver: SuperReference
superKeyword: super
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
resolution: InvalidInvocationResolution
type: InvalidType
recovery: <null>
staticType: InvalidType
V1: FunctionExpressionInvocation
function: SuperExpression
superKeyword: super
staticType: A
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
element: <null>
staticInvokeType: InvalidType
staticType: InvalidType
''');
}
}