blob: a848c7cebcaf4479d09121bae0f87cae6ea72deb [file] [log] [blame]
// Copyright (c) 2020, 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(BinaryExpressionResolutionTest);
});
}
@reflectiveTest
class BinaryExpressionResolutionTest extends PubPackageResolutionTest
with BinaryExpressionResolutionTestCases {
test_ifNull_left_nullableContext() async {
await assertNoErrorsInCode(r'''
T f<T>(T t) => t;
int g() => f(null) ?? 0;
''');
assertResolvedNodeText(findNode.binary('?? 0'), r'''
BinaryExpression
leftOperand: MethodInvocation
methodName: SimpleIdentifier
token: f
staticElement: self::@function::f
staticType: T Function<T>(T)
argumentList: ArgumentList
leftParenthesis: (
arguments
NullLiteral
literal: null
staticType: Null
rightParenthesis: )
staticInvokeType: int? Function(int?)
staticType: int?
typeArgumentTypes
int?
operator: ??
rightOperand: IntegerLiteral
literal: 0
staticType: int
staticElement: <null>
staticInvokeType: null
staticType: int
''');
}
test_ifNull_nullableInt_int() async {
await assertNoErrorsInCode(r'''
void f(int? x, int y) {
x ?? y;
}
''');
assertResolvedNodeText(findNode.binary('x ?? y'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: x
staticElement: self::@function::f::@parameter::x
staticType: int?
operator: ??
rightOperand: SimpleIdentifier
token: y
staticElement: self::@function::f::@parameter::y
staticType: int
staticElement: <null>
staticInvokeType: null
staticType: int
''');
}
test_ifNull_nullableInt_nullableDouble() async {
await assertNoErrorsInCode(r'''
void f(int? x, double? y) {
x ?? y;
}
''');
assertResolvedNodeText(findNode.binary('x ?? y'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: x
staticElement: self::@function::f::@parameter::x
staticType: int?
operator: ??
rightOperand: SimpleIdentifier
token: y
staticElement: self::@function::f::@parameter::y
staticType: double?
staticElement: <null>
staticInvokeType: null
staticType: num?
''');
}
test_ifNull_nullableInt_nullableInt() async {
await assertNoErrorsInCode(r'''
void f(int? x) {
x ?? x;
}
''');
assertResolvedNodeText(findNode.binary('x ?? x'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: x
staticElement: self::@function::f::@parameter::x
staticType: int?
operator: ??
rightOperand: SimpleIdentifier
token: x
staticElement: self::@function::f::@parameter::x
staticType: int?
staticElement: <null>
staticInvokeType: null
staticType: int?
''');
}
test_plus_int_never() async {
await assertNoErrorsInCode('''
f(int a, Never b) {
a + b;
}
''');
assertResolvedNodeText(findNode.binary('a + b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int
operator: +
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: Never
staticElement: dart:core::@class::num::@method::+
staticInvokeType: num Function(num)
staticType: num
''');
}
test_plus_never_int() async {
await assertErrorsInCode(r'''
f(Never a, int b) {
a + b;
}
''', [
error(HintCode.RECEIVER_OF_TYPE_NEVER, 22, 1),
error(HintCode.DEAD_CODE, 26, 2),
]);
assertResolvedNodeText(findNode.binary('a + b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: Never
operator: +
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: int
staticElement: <null>
staticInvokeType: null
staticType: Never
''');
}
}
mixin BinaryExpressionResolutionTestCases on PubPackageResolutionTest {
test_bangEq() async {
await assertNoErrorsInCode(r'''
f(int a, int b) {
a != b;
}
''');
assertResolvedNodeText(findNode.binary('a != b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int
operator: !=
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: int
staticElement: dart:core::@class::num::@method::==
staticInvokeType: bool Function(Object)
staticType: bool
''');
}
test_bangEq_extensionOverride_left() async {
await assertErrorsInCode(r'''
extension E on int {}
void f(int a) {
E(a) != 0;
}
''', [
error(CompileTimeErrorCode.UNDEFINED_EXTENSION_OPERATOR, 46, 2),
]);
assertResolvedNodeText(findNode.binary('!= 0'), r'''
BinaryExpression
leftOperand: ExtensionOverride
extensionName: SimpleIdentifier
token: E
staticElement: self::@extension::E
staticType: null
argumentList: ArgumentList
leftParenthesis: (
arguments
SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int
rightParenthesis: )
extendedType: int
staticType: null
operator: !=
rightOperand: IntegerLiteral
literal: 0
staticType: int
staticElement: <null>
staticInvokeType: null
staticType: dynamic
''');
}
test_bangEqEq() async {
await assertErrorsInCode(r'''
f(int a, int b) {
a !== b;
}
''', [
error(ScannerErrorCode.UNSUPPORTED_OPERATOR, 22, 1),
]);
assertResolvedNodeText(findNode.binary('a !== b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int
operator: !==
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: int
staticElement: <null>
staticInvokeType: null
staticType: dynamic
''');
}
test_eqEq() async {
await assertNoErrorsInCode(r'''
f(int a, int b) {
a == b;
}
''');
assertResolvedNodeText(findNode.binary('a == b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int
operator: ==
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: int
staticElement: dart:core::@class::num::@method::==
staticInvokeType: bool Function(Object)
staticType: bool
''');
}
test_eqEq_extensionOverride_left() async {
await assertErrorsInCode(r'''
extension E on int {}
void f(int a) {
E(a) == 0;
}
''', [
error(CompileTimeErrorCode.UNDEFINED_EXTENSION_OPERATOR, 46, 2),
]);
assertResolvedNodeText(findNode.binary('== 0'), r'''
BinaryExpression
leftOperand: ExtensionOverride
extensionName: SimpleIdentifier
token: E
staticElement: self::@extension::E
staticType: null
argumentList: ArgumentList
leftParenthesis: (
arguments
SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int
rightParenthesis: )
extendedType: int
staticType: null
operator: ==
rightOperand: IntegerLiteral
literal: 0
staticType: int
staticElement: <null>
staticInvokeType: null
staticType: dynamic
''');
}
test_eqEqEq() async {
await assertErrorsInCode(r'''
f(int a, int b) {
a === b;
}
''', [
error(ScannerErrorCode.UNSUPPORTED_OPERATOR, 22, 1),
]);
assertResolvedNodeText(findNode.binary('a === b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int
operator: ===
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: int
staticElement: <null>
staticInvokeType: null
staticType: dynamic
''');
}
test_ifNull() async {
var question = isNullSafetyEnabled ? '?' : '';
await assertNoErrorsInCode('''
f(int$question a, double b) {
a ?? b;
}
''');
assertResolvedNodeText(findNode.binary('a ?? b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int?
operator: ??
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: double
staticElement: <null>
staticInvokeType: null
staticType: num
''');
}
test_logicalAnd() async {
await assertNoErrorsInCode(r'''
f(bool a, bool b) {
a && b;
}
''');
assertResolvedNodeText(findNode.binary('a && b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: bool
operator: &&
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: bool
staticElement: <null>
staticInvokeType: null
staticType: bool
''');
}
test_logicalOr() async {
await assertNoErrorsInCode(r'''
f(bool a, bool b) {
a || b;
}
''');
assertResolvedNodeText(findNode.binary('a || b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: bool
operator: ||
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: bool
staticElement: <null>
staticInvokeType: null
staticType: bool
''');
}
test_minus_int_context_int() async {
await assertNoErrorsInCode('''
T f<T>() => throw Error();
g(int a) {
h(a - f());
}
h(int x) {}
''');
assertTypeArgumentTypes(findNode.methodInvocation('f()'),
[typeStringByNullability(nullable: 'int', legacy: 'num')]);
}
test_minus_int_double() async {
await assertNoErrorsInCode(r'''
f(int a, double b) {
a - b;
}
''');
assertResolvedNodeText(findNode.binary('a - b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int
operator: -
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: double
staticElement: dart:core::@class::num::@method::-
staticInvokeType: num Function(num)
staticType: double
''');
}
test_minus_int_int() async {
await assertNoErrorsInCode(r'''
f(int a, int b) {
a - b;
}
''');
assertResolvedNodeText(findNode.binary('a - b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int
operator: -
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: int
staticElement: dart:core::@class::num::@method::-
staticInvokeType: num Function(num)
staticType: int
''');
}
test_mod_int_context_int() async {
await assertNoErrorsInCode('''
T f<T>() => throw Error();
g(int a) {
h(a % f());
}
h(int x) {}
''');
assertTypeArgumentTypes(findNode.methodInvocation('f()'),
[typeStringByNullability(nullable: 'int', legacy: 'num')]);
}
test_mod_int_double() async {
await assertNoErrorsInCode(r'''
f(int a, double b) {
a % b;
}
''');
assertResolvedNodeText(findNode.binary('a % b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int
operator: %
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: double
staticElement: dart:core::@class::num::@method::%
staticInvokeType: num Function(num)
staticType: double
''');
}
test_mod_int_int() async {
await assertNoErrorsInCode(r'''
f(int a, int b) {
a % b;
}
''');
assertResolvedNodeText(findNode.binary('a % b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int
operator: %
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: int
staticElement: dart:core::@class::num::@method::%
staticInvokeType: num Function(num)
staticType: int
''');
}
test_plus_double_context_double() async {
await assertNoErrorsInCode('''
T f<T>() => throw Error();
g(double a) {
h(a + f());
}
h(double x) {}
''');
assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['num']);
}
test_plus_double_context_int() async {
await assertErrorsInCode('''
T f<T>() => throw Error();
g(double a) {
h(a + f());
}
h(int x) {}
''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 45, 7),
]);
assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['num']);
}
test_plus_double_context_none() async {
await assertNoErrorsInCode('''
T f<T>() => throw Error();
g(double a) {
a + f();
}
''');
assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['num']);
}
test_plus_double_dynamic() async {
await assertNoErrorsInCode(r'''
f(double a, dynamic b) {
a + b;
}
''');
assertResolvedNodeText(findNode.binary('a + b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: double
operator: +
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: dynamic
staticElement: dart:core::@class::double::@method::+
staticInvokeType: double Function(num)
staticType: double
''');
}
test_plus_int_context_double() async {
await assertNoErrorsInCode('''
T f<T>() => throw Error();
g(int a) {
h(a + f());
}
h(double x) {}
''');
assertTypeArgumentTypes(findNode.methodInvocation('f()'),
[typeStringByNullability(nullable: 'double', legacy: 'num')]);
}
test_plus_int_context_int() async {
await assertNoErrorsInCode('''
T f<T>() => throw Error();
g(int a) {
h(a + f());
}
h(int x) {}
''');
assertTypeArgumentTypes(findNode.methodInvocation('f()'),
[typeStringByNullability(nullable: 'int', legacy: 'num')]);
}
test_plus_int_context_int_target_rewritten() async {
await assertNoErrorsInCode('''
T f<T>() => throw Error();
g(int Function() a) {
h(a() + f());
}
h(int x) {}
''');
assertTypeArgumentTypes(findNode.methodInvocation('f()'),
[typeStringByNullability(nullable: 'int', legacy: 'num')]);
}
test_plus_int_context_int_via_extension_explicit() async {
await assertErrorsInCode('''
extension E on int {
String operator+(num x) => '';
}
T f<T>() => throw Error();
g(int a) {
h(E(a) + f());
}
h(int x) {}
''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 98, 10),
]);
assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['num']);
}
test_plus_int_context_none() async {
await assertNoErrorsInCode('''
T f<T>() => throw Error();
g(int a) {
a + f();
}
''');
assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['num']);
}
test_plus_int_double() async {
await assertNoErrorsInCode(r'''
f(int a, double b) {
a + b;
}
''');
assertResolvedNodeText(findNode.binary('a + b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int
operator: +
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: double
staticElement: dart:core::@class::num::@method::+
staticInvokeType: num Function(num)
staticType: double
''');
}
test_plus_int_dynamic() async {
await assertNoErrorsInCode(r'''
f(int a, dynamic b) {
a + b;
}
''');
assertResolvedNodeText(findNode.binary('a + b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int
operator: +
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: dynamic
staticElement: dart:core::@class::num::@method::+
staticInvokeType: num Function(num)
staticType: num
''');
}
test_plus_int_int() async {
await assertNoErrorsInCode(r'''
f(int a, int b) {
a + b;
}
''');
assertResolvedNodeText(findNode.binary('a + b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int
operator: +
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: int
staticElement: dart:core::@class::num::@method::+
staticInvokeType: num Function(num)
staticType: int
''');
}
test_plus_int_int_target_rewritten() async {
await assertNoErrorsInCode('''
f(int Function() a, int b) {
a() + b;
}
''');
assertResolvedNodeText(findNode.binary('a() + b'), r'''
BinaryExpression
leftOperand: FunctionExpressionInvocation
function: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int Function()
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
staticElement: <null>
staticInvokeType: int Function()
staticType: int
operator: +
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: int
staticElement: dart:core::@class::num::@method::+
staticInvokeType: num Function(num)
staticType: int
''');
}
test_plus_int_int_via_extension_explicit() async {
await assertNoErrorsInCode('''
extension E on int {
String operator+(int other) => '';
}
f(int a, int b) {
E(a) + b;
}
''');
assertResolvedNodeText(findNode.binary('E(a) + b'), r'''
BinaryExpression
leftOperand: ExtensionOverride
extensionName: SimpleIdentifier
token: E
staticElement: self::@extension::E
staticType: null
argumentList: ArgumentList
leftParenthesis: (
arguments
SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int
rightParenthesis: )
extendedType: int
staticType: null
operator: +
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: int
staticElement: self::@extension::E::@method::+
staticInvokeType: String Function(int)
staticType: String
''');
}
test_plus_int_num() async {
await assertNoErrorsInCode(r'''
f(int a, num b) {
a + b;
}
''');
assertResolvedNodeText(findNode.binary('a + b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int
operator: +
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: num
staticElement: dart:core::@class::num::@method::+
staticInvokeType: num Function(num)
staticType: num
''');
}
test_plus_num_context_int() async {
await assertErrorsInCode(
'''
T f<T>() => throw Error();
g(num a) {
h(a + f());
}
h(int x) {}
''',
expectedErrorsByNullability(nullable: [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 42, 7),
], legacy: []));
assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['num']);
}
test_plus_other_context_int() async {
await assertErrorsInCode(
'''
abstract class A {
num operator+(String x);
}
T f<T>() => throw Error();
g(A a) {
h(a + f());
}
h(int x) {}
''',
expectedErrorsByNullability(nullable: [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 88, 7),
], legacy: []));
assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['String']);
}
test_plus_other_context_int_via_extension_explicit() async {
await assertErrorsInCode('''
class A {}
extension E on A {
String operator+(num x) => '';
}
T f<T>() => throw Error();
g(A a) {
h(E(a) + f());
}
h(int x) {}
''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 105, 10),
]);
assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['num']);
}
test_plus_other_context_int_via_extension_implicit() async {
await assertErrorsInCode('''
class A {}
extension E on A {
String operator+(num x) => '';
}
T f<T>() => throw Error();
g(A a) {
h(a + f());
}
h(int x) {}
''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 105, 7),
]);
assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['num']);
}
test_plus_other_double() async {
await assertNoErrorsInCode('''
abstract class A {
String operator+(double other);
}
f(A a, double b) {
a + b;
}
''');
assertResolvedNodeText(findNode.binary('a + b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: A
operator: +
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: double
staticElement: self::@class::A::@method::+
staticInvokeType: String Function(double)
staticType: String
''');
}
test_plus_other_int_via_extension_explicit() async {
await assertNoErrorsInCode('''
class A {}
extension E on A {
String operator+(int other) => '';
}
f(A a, int b) {
E(a) + b;
}
''');
assertResolvedNodeText(findNode.binary('E(a) + b'), r'''
BinaryExpression
leftOperand: ExtensionOverride
extensionName: SimpleIdentifier
token: E
staticElement: self::@extension::E
staticType: null
argumentList: ArgumentList
leftParenthesis: (
arguments
SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: A
rightParenthesis: )
extendedType: A
staticType: null
operator: +
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: int
staticElement: self::@extension::E::@method::+
staticInvokeType: String Function(int)
staticType: String
''');
}
test_plus_other_int_via_extension_implicit() async {
await assertNoErrorsInCode('''
class A {}
extension E on A {
String operator+(int other) => '';
}
f(A a, int b) {
a + b;
}
''');
assertResolvedNodeText(findNode.binary('a + b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: A
operator: +
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: int
staticElement: self::@extension::E::@method::+
staticInvokeType: String Function(int)
staticType: String
''');
}
test_receiverTypeParameter_bound_dynamic() async {
await assertNoErrorsInCode(r'''
f<T extends dynamic>(T a) {
a + 0;
}
''');
assertResolvedNodeText(findNode.binary('a + 0'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: T
operator: +
rightOperand: IntegerLiteral
literal: 0
staticType: int
staticElement: <null>
staticInvokeType: null
staticType: dynamic
''');
}
test_receiverTypeParameter_bound_num() async {
await assertNoErrorsInCode(r'''
f<T extends num>(T a) {
a + 0;
}
''');
assertResolvedNodeText(findNode.binary('a + 0'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: T
operator: +
rightOperand: IntegerLiteral
literal: 0
staticType: int
staticElement: dart:core::@class::num::@method::+
staticInvokeType: num Function(num)
staticType: num
''');
}
test_slash() async {
await assertNoErrorsInCode(r'''
f(int a, int b) {
a / b;
}
''');
assertResolvedNodeText(findNode.binary('a / b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int
operator: /
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: int
staticElement: dart:core::@class::num::@method::/
staticInvokeType: double Function(num)
staticType: double
''');
}
test_star_int_context_int() async {
await assertNoErrorsInCode('''
T f<T>() => throw Error();
g(int a) {
h(a * f());
}
h(int x) {}
''');
assertTypeArgumentTypes(findNode.methodInvocation('f()'),
[typeStringByNullability(nullable: 'int', legacy: 'num')]);
}
test_star_int_double() async {
await assertNoErrorsInCode(r'''
f(int a, double b) {
a * b;
}
''');
assertResolvedNodeText(findNode.binary('a * b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int
operator: *
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: double
staticElement: dart:core::@class::num::@method::*
staticInvokeType: num Function(num)
staticType: double
''');
}
test_star_int_int() async {
await assertNoErrorsInCode(r'''
f(int a, int b) {
a * b;
}
''');
assertResolvedNodeText(findNode.binary('a * b'), r'''
BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: int
operator: *
rightOperand: SimpleIdentifier
token: b
staticElement: self::@function::f::@parameter::b
staticType: int
staticElement: dart:core::@class::num::@method::*
staticInvokeType: num Function(num)
staticType: int
''');
}
}