blob: 84e336237177eaf4bd0052a3eadb0a9c6c2aac35 [file] [log] [blame]
// 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:analyzer/dart/element/element.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(TearOffTest);
});
}
@reflectiveTest
class TearOffTest extends PubPackageResolutionTest {
test_empty_contextNotInstantiated() async {
await assertErrorsInCode('''
T f<T>(T x) => x;
void test() {
U Function<U>(U) context;
context = f; // 1
}
''', [
error(HintCode.UNUSED_LOCAL_VARIABLE, 52, 7),
]);
_assertTearOff(
'f; // 1',
findElement.topFunction('f'),
'T Function<T>(T)',
);
}
test_empty_notGeneric() async {
await assertErrorsInCode('''
int f(int x) => x;
void test() {
int Function(int) context;
context = f; // 1
}
''', [
error(HintCode.UNUSED_LOCAL_VARIABLE, 54, 7),
]);
_assertTearOff(
'f; // 1',
findElement.topFunction('f'),
'int Function(int)',
);
}
test_notEmpty_instanceMethod() async {
await assertNoErrorsInCode('''
class C {
T f<T>(T x) => x;
}
int Function(int) test() {
return new C().f;
}
''');
_assertGenericFunctionInstantiation(
'f;',
findElement.method('f', of: 'C'),
'int Function(int)',
['int'],
);
}
test_notEmpty_localFunction() async {
await assertNoErrorsInCode('''
int Function(int) test() {
T f<T>(T x) => x;
return f;
}
''');
_assertGenericFunctionInstantiation(
'f;',
findElement.localFunction('f'),
'int Function(int)',
['int'],
);
}
test_notEmpty_staticMethod() async {
await assertNoErrorsInCode('''
class C {
static T f<T>(T x) => x;
}
int Function(int) test() {
return C.f;
}
''');
_assertGenericFunctionInstantiation(
'f;',
findElement.method('f', of: 'C'),
'int Function(int)',
['int'],
);
}
test_notEmpty_superMethod() async {
await assertNoErrorsInCode('''
class C {
T f<T>(T x) => x;
}
class D extends C {
int Function(int) test() {
return super.f;
}
}
''');
_assertGenericFunctionInstantiation(
'f;',
findElement.method('f', of: 'C'),
'int Function(int)',
['int'],
);
}
test_notEmpty_topLevelFunction() async {
await assertNoErrorsInCode('''
T f<T>(T x) => x;
int Function(int) test() {
return f;
}
''');
_assertGenericFunctionInstantiation(
'f;',
findElement.topFunction('f'),
'int Function(int)',
['int'],
);
}
test_null_notTearOff() async {
await assertNoErrorsInCode('''
T f<T>(T x) => x;
void test() {
f(0);
}
''');
_assertTearOff(
'f(0);',
findElement.topFunction('f'),
'T Function<T>(T)',
);
assertInvokeType(
findNode.methodInvocation('f(0)'),
'int Function(int)',
);
}
void _assertGenericFunctionInstantiation(
String search,
ExecutableElement element,
String type,
List<String>? typeArguments,
) {
var id = findNode.functionReference(search);
assertElement(id, element);
assertType(id, type);
if (typeArguments != null) {
assertElementTypes(id.typeArgumentTypes, typeArguments);
} else {
expect(id.typeArgumentTypes, isNull);
}
}
void _assertTearOff(
String search,
ExecutableElement element,
String type,
) {
var id = findNode.simple(search);
assertElement(id, element);
assertType(id, type);
expect(id.tearOffTypeArgumentTypes, isNull);
}
}