blob: f1739194f56f6d456f6285d0004d61bd05d82f7a [file] [log] [blame]
// Copyright (c) 2016, 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/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart' hide Declaration;
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/search.dart';
import 'package:analyzer/src/test_utilities/find_element.dart';
import 'package:analyzer/src/utilities/cancellation.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../resolution/context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(SearchTest);
});
}
class ExpectedResult {
final Element enclosingElement;
final SearchResultKind kind;
final int offset;
final int length;
final bool isResolved;
final bool isQualified;
ExpectedResult(this.enclosingElement, this.kind, this.offset, this.length,
{this.isResolved = true, this.isQualified = false});
@override
bool operator ==(Object result) {
return result is SearchResult &&
result.kind == kind &&
result.isResolved == isResolved &&
result.isQualified == isQualified &&
result.offset == offset &&
result.length == length &&
result.enclosingElement == enclosingElement;
}
@override
String toString() {
StringBuffer buffer = StringBuffer();
buffer.write("ExpectedResult(kind=");
buffer.write(kind);
buffer.write(", enclosingElement=");
buffer.write(enclosingElement);
buffer.write(", offset=");
buffer.write(offset);
buffer.write(", length=");
buffer.write(length);
buffer.write(", isResolved=");
buffer.write(isResolved);
buffer.write(", isQualified=");
buffer.write(isQualified);
buffer.write(")");
return buffer.toString();
}
}
@reflectiveTest
class SearchTest extends PubPackageResolutionTest {
AnalysisDriver get driver => driverFor(testFile);
CompilationUnitElement get resultUnitElement => result.unit.declaredElement!;
String get testUriStr => 'package:test/test.dart';
test_classMembers_class() async {
await resolveTestCode('''
class A {
test() {}
}
class B {
int test = 1;
int testTwo = 2;
main() {
int test = 3;
}
}
''');
var a = findElement.class_('A');
var b = findElement.class_('B');
expect(await _findClassMembers('test'),
unorderedEquals([a.methods[0], b.fields[0]]));
}
test_classMembers_enum() async {
await resolveTestCode('''
enum E1 {
v;
void test() {}
}
enum E2 {
v;
final int test = 0;
}
''');
expect(
await _findClassMembers('test'),
unorderedEquals([
findElement.method('test', of: 'E1'),
findElement.field('test', of: 'E2'),
]),
);
}
test_classMembers_importNotDart() async {
await resolveTestCode('''
import 'not-dart.txt';
''');
expect(await _findClassMembers('test'), isEmpty);
}
test_classMembers_mixin() async {
await resolveTestCode('''
mixin A {
test() {}
}
mixin B {
int test = 1;
int testTwo = 2;
main() {
int test = 3;
}
}
''');
var a = findElement.mixin('A');
var b = findElement.mixin('B');
expect(await _findClassMembers('test'),
unorderedEquals([a.methods[0], b.fields[0]]));
}
test_declarations_cancel() async {
await resolveTestCode('''
class C {
int f;
C();
C.named();
int get g => 0;
void set s(_) {}
void m() {}
}
''');
var results = WorkspaceSymbols();
var token = CancelableToken();
var searchFuture = driver.search
.declarations(results, null, null, cancellationToken: token);
token.cancel();
await searchFuture;
expect(results.cancelled, isTrue);
}
test_declarations_class() async {
await resolveTestCode('''
class C {
int f;
C();
C.named();
int get g => 0;
void set s(_) {}
void m() {}
}
''');
var results = WorkspaceSymbols();
await driver.search.declarations(results, null, null);
var declarations = results.declarations;
declarations.assertHas('C', DeclarationKind.CLASS,
offset: 6, codeOffset: 0, codeLength: 91);
declarations.assertHas('f', DeclarationKind.FIELD,
offset: 16, codeOffset: 12, codeLength: 5, className: 'C');
declarations.assertHas('named', DeclarationKind.CONSTRUCTOR,
offset: 30, codeOffset: 28, codeLength: 10, className: 'C');
declarations.assertHas('g', DeclarationKind.GETTER,
offset: 49, codeOffset: 41, codeLength: 15, className: 'C');
declarations.assertHas('s', DeclarationKind.SETTER,
offset: 68, codeOffset: 59, codeLength: 16, className: 'C');
declarations.assertHas('m', DeclarationKind.METHOD,
offset: 83, codeOffset: 78, codeLength: 11, className: 'C');
}
test_declarations_discover() async {
var aaaPackageRootPath = '$packagesRootPath/aaa';
var bbbPackageRootPath = '$packagesRootPath/bbb';
var cccPackageRootPath = '$packagesRootPath/ccc';
var aaaFilePath = convertPath('$aaaPackageRootPath/lib/a.dart');
var bbbFilePath = convertPath('$bbbPackageRootPath/lib/b.dart');
var cccFilePath = convertPath('$cccPackageRootPath/lib/c.dart');
writeTestPackageConfig(
PackageConfigFileBuilder()
..add(name: 'aaa', rootPath: aaaPackageRootPath)
..add(name: 'bbb', rootPath: bbbPackageRootPath),
);
newFile(aaaFilePath, 'class A {}');
newFile(bbbFilePath, 'class B {}');
newFile(cccFilePath, 'class C {}');
await resolveTestCode('class T {}');
var results = WorkspaceSymbols();
await driver.search.declarations(results, null, null);
var declarations = results.declarations;
declarations.assertHas('T', DeclarationKind.CLASS);
declarations.assertHas('A', DeclarationKind.CLASS);
declarations.assertHas('B', DeclarationKind.CLASS);
declarations.assertNo('C');
}
test_declarations_enum() async {
await resolveTestCode('''
enum E {
a, bb, ccc
}
''');
var results = WorkspaceSymbols();
await driver.search.declarations(results, null, null);
var declarations = results.declarations;
declarations.assertHas('E', DeclarationKind.ENUM,
offset: 5, codeOffset: 0, codeLength: 23);
declarations.assertHas('a', DeclarationKind.ENUM_CONSTANT,
offset: 11, codeOffset: 11, codeLength: 1);
declarations.assertHas('bb', DeclarationKind.ENUM_CONSTANT,
offset: 14, codeOffset: 14, codeLength: 2);
declarations.assertHas('ccc', DeclarationKind.ENUM_CONSTANT,
offset: 18, codeOffset: 18, codeLength: 3);
}
test_declarations_extension() async {
await resolveTestCode('''
extension E on int {
int f;
int get g => 0;
void set s(_) {}
void m() {}
}
''');
var results = WorkspaceSymbols();
await driver.search.declarations(results, null, null);
var declarations = results.declarations;
declarations.assertHas('E', DeclarationKind.EXTENSION,
offset: 10, codeOffset: 0, codeLength: 82);
declarations.assertHas('f', DeclarationKind.FIELD,
offset: 27, codeOffset: 23, codeLength: 5);
declarations.assertHas('g', DeclarationKind.GETTER,
offset: 40, codeOffset: 32, codeLength: 15);
declarations.assertHas('s', DeclarationKind.SETTER,
offset: 59, codeOffset: 50, codeLength: 16);
declarations.assertHas('m', DeclarationKind.METHOD,
offset: 74, codeOffset: 69, codeLength: 11);
}
test_declarations_maxResults() async {
await resolveTestCode('''
class A {}
class B {}
class C {}
''');
var results = WorkspaceSymbols();
await driver.search.declarations(results, null, 2);
expect(results.declarations, hasLength(2));
}
test_declarations_mixin() async {
await resolveTestCode('''
mixin M {
int f;
int get g => 0;
void set s(_) {}
void m() {}
}
''');
var results = WorkspaceSymbols();
await driver.search.declarations(results, null, null);
var declarations = results.declarations;
declarations.assertHas('M', DeclarationKind.MIXIN,
offset: 6, codeOffset: 0, codeLength: 71);
declarations.assertHas('f', DeclarationKind.FIELD,
offset: 16, codeOffset: 12, codeLength: 5, mixinName: 'M');
declarations.assertHas('g', DeclarationKind.GETTER,
offset: 29, codeOffset: 21, codeLength: 15, mixinName: 'M');
declarations.assertHas('s', DeclarationKind.SETTER,
offset: 48, codeOffset: 39, codeLength: 16, mixinName: 'M');
declarations.assertHas('m', DeclarationKind.METHOD,
offset: 63, codeOffset: 58, codeLength: 11, mixinName: 'M');
}
test_declarations_onlyForFile() async {
newFile('$testPackageLibPath/a.dart', 'class A {}');
var b = newFile('$testPackageLibPath/b.dart', 'class B {}').path;
var results = WorkspaceSymbols();
await driver.search.declarations(results, null, null, onlyForFile: b);
var declarations = results.declarations;
expect(results.files, [b]);
declarations.assertNo('A');
declarations.assertHas('B', DeclarationKind.CLASS);
}
test_declarations_parameters() async {
await resolveTestCode('''
class C {
int get g => 0;
void m(int a, double b) {}
}
void f(bool a, String b) {}
''');
var results = WorkspaceSymbols();
await driver.search.declarations(results, null, null);
var declarations = results.declarations;
var declaration = declarations.assertHas('C', DeclarationKind.CLASS);
expect(declaration.parameters, isNull);
declaration =
declarations.assertHas('g', DeclarationKind.GETTER, className: 'C');
expect(declaration.parameters, isNull);
declaration =
declarations.assertHas('m', DeclarationKind.METHOD, className: 'C');
expect(declaration.parameters, '(int a, double b)');
declaration = declarations.assertHas('f', DeclarationKind.FUNCTION);
expect(declaration.parameters, '(bool a, String b)');
}
test_declarations_parameters_functionTyped() async {
await resolveTestCode('''
void f1(bool a(int b, String c)) {}
void f2(a(b, c)) {}
void f3(bool Function(int a, String b) c) {}
void f4(bool Function(int, String) a) {}
''');
var results = WorkspaceSymbols();
await driver.search.declarations(results, null, null);
var declarations = results.declarations;
var declaration = declarations.assertHas('f1', DeclarationKind.FUNCTION);
expect(declaration.parameters, '(bool Function(int, String) a)');
declaration = declarations.assertHas('f2', DeclarationKind.FUNCTION);
expect(declaration.parameters, '(dynamic Function(dynamic, dynamic) a)');
declaration = declarations.assertHas('f3', DeclarationKind.FUNCTION);
expect(declaration.parameters, '(bool Function(int, String) c)');
declaration = declarations.assertHas('f4', DeclarationKind.FUNCTION);
expect(declaration.parameters, '(bool Function(int, String) a)');
}
test_declarations_parameters_typeArguments() async {
await resolveTestCode('''
class A<T, T2> {
void m1(Map<int, String> a) {}
void m2<U>(Map<T, U> a) {}
void m3<U1, U2>(Map<Map<T2, U2>, Map<U1, T>> a) {}
}
''');
var results = WorkspaceSymbols();
await driver.search.declarations(results, null, null);
var declarations = results.declarations;
var declaration =
declarations.assertHas('m1', DeclarationKind.METHOD, className: 'A');
expect(declaration.parameters, '(Map<int, String> a)');
declaration =
declarations.assertHas('m2', DeclarationKind.METHOD, className: 'A');
expect(declaration.parameters, '(Map<T, U> a)');
declaration =
declarations.assertHas('m3', DeclarationKind.METHOD, className: 'A');
expect(declaration.parameters, '(Map<Map<T2, U2>, Map<U1, T>> a)');
}
test_declarations_regExp() async {
await resolveTestCode('''
class A {}
class B {}
class C {}
class D {}
''');
var results = WorkspaceSymbols();
await driver.search.declarations(results, RegExp(r'[A-C]'), null);
var declarations = results.declarations;
declarations.assertHas('A', DeclarationKind.CLASS);
declarations.assertHas('B', DeclarationKind.CLASS);
declarations.assertHas('C', DeclarationKind.CLASS);
declarations.assertNo('D');
}
test_declarations_top() async {
await resolveTestCode('''
int get g => 0;
void set s(_) {}
void f(int p) {}
int v;
typedef void tf1();
typedef tf2<T> = int Function<S>(T tp, S sp);
''');
var results = WorkspaceSymbols();
await driver.search.declarations(results, null, null);
var declarations = results.declarations;
declarations.assertHas('g', DeclarationKind.GETTER,
offset: 8, codeOffset: 0, codeLength: 15);
declarations.assertHas('s', DeclarationKind.SETTER,
offset: 25, codeOffset: 16, codeLength: 16);
declarations.assertHas(
'f',
DeclarationKind.FUNCTION,
offset: 38,
codeOffset: 33,
codeLength: 16,
);
declarations.assertHas('v', DeclarationKind.VARIABLE,
offset: 54, codeOffset: 50, codeLength: 5);
declarations.assertHas('tf1', DeclarationKind.TYPE_ALIAS,
offset: 70, codeOffset: 57, codeLength: 19);
declarations.assertHas('tf2', DeclarationKind.TYPE_ALIAS,
offset: 85, codeOffset: 77, codeLength: 45);
}
test_searchMemberReferences_qualified_resolved() async {
await resolveTestCode('''
class C {
var test;
}
main(C c) {
print(c.test);
c.test = 1;
c.test += 2;
c.test();
}
''');
await _verifyNameReferences('test', []);
}
test_searchMemberReferences_qualified_unresolved() async {
await resolveTestCode('''
main(p) {
print(p.test);
p.test = 1;
p.test += 2;
p.test();
}
''');
var main = findElement.function('main');
await _verifyNameReferences('test', <ExpectedResult>[
_expectIdQU(main, SearchResultKind.READ, 'test);'),
_expectIdQU(main, SearchResultKind.WRITE, 'test = 1;'),
_expectIdQU(main, SearchResultKind.READ_WRITE, 'test += 2;'),
_expectIdQU(main, SearchResultKind.INVOCATION, 'test();'),
]);
}
test_searchMemberReferences_unqualified_resolved() async {
await resolveTestCode('''
class C {
var test;
main() {
print(test);
test = 1;
test += 2;
test();
}
}
''');
await _verifyNameReferences('test', []);
}
test_searchMemberReferences_unqualified_unresolved() async {
await resolveTestCode('''
class C {
main() {
print(test);
test = 1;
test += 2;
test();
}
}
''');
var main = findElement.method('main');
await _verifyNameReferences('test', <ExpectedResult>[
_expectIdU(main, SearchResultKind.READ, 'test);'),
_expectIdU(main, SearchResultKind.WRITE, 'test = 1;'),
_expectIdU(main, SearchResultKind.READ_WRITE, 'test += 2;'),
_expectIdU(main, SearchResultKind.INVOCATION, 'test();'),
]);
}
test_searchReferences_ClassElement_definedInSdk_declarationSite() async {
await resolveTestCode('''
import 'dart:math';
Random v1;
Random v2;
''');
// Find the Random class element in the SDK source.
// IDEA performs search always at declaration, never at reference.
var randomElement = findElement.importFind('dart:math').class_('Random');
var v1 = findElement.topVar('v1');
var v2 = findElement.topVar('v2');
var expected = [
_expectId(v1, SearchResultKind.REFERENCE, 'Random v1;'),
_expectId(v2, SearchResultKind.REFERENCE, 'Random v2;'),
];
await _verifyReferences(randomElement, expected);
}
test_searchReferences_ClassElement_definedInSdk_useSite() async {
await resolveTestCode('''
import 'dart:math';
Random v1;
Random v2;
''');
var v1 = findElement.topVar('v1');
var v2 = findElement.topVar('v2');
final v1Type = v1.type as InterfaceType;
var randomElement = v1Type.element2 as ClassElement;
var expected = [
_expectId(v1, SearchResultKind.REFERENCE, 'Random v1;'),
_expectId(v2, SearchResultKind.REFERENCE, 'Random v2;'),
];
await _verifyReferences(randomElement, expected);
}
test_searchReferences_ClassElement_definedInside() async {
await resolveTestCode('''
class A {};
main(A p) {
A v;
}
class B1 extends A {} // extends
class B2 implements A {} // implements
class B3 extends Object with A {} // with
List<A> v2 = null;
''');
var element = findElement.class_('A');
var p = findElement.parameter('p');
var main = findElement.function('main');
var b1 = findElement.class_('B1');
var b2 = findElement.class_('B2');
var b3 = findElement.class_('B3');
var v2 = findElement.topVar('v2');
var expected = [
_expectId(p, SearchResultKind.REFERENCE, 'A p'),
_expectId(main, SearchResultKind.REFERENCE, 'A v'),
_expectId(b1, SearchResultKind.REFERENCE, 'A {} // extends'),
_expectId(b2, SearchResultKind.REFERENCE, 'A {} // implements'),
_expectId(b3, SearchResultKind.REFERENCE, 'A {} // with'),
_expectId(v2, SearchResultKind.REFERENCE, 'A> v2'),
];
await _verifyReferences(element, expected);
}
test_searchReferences_ClassElement_definedOutside() async {
newFile('$testPackageLibPath/lib.dart', r'''
class A {};
''');
await resolveTestCode('''
import 'lib.dart';
main(A p) {
A v;
}
''');
var element = findNode.simple('A p').staticElement!;
var p = findElement.parameter('p');
var main = findElement.function('main');
var expected = [
_expectId(p, SearchResultKind.REFERENCE, 'A p'),
_expectId(main, SearchResultKind.REFERENCE, 'A v')
];
await _verifyReferences(element, expected);
}
test_searchReferences_ClassElement_enum() async {
await resolveTestCode('''
enum MyEnum {a}
main(MyEnum p) {
MyEnum v;
MyEnum.a;
}
''');
var element = findElement.enum_('MyEnum');
var main = findElement.function('main');
var expected = [
_expectId(
findElement.parameter('p'),
SearchResultKind.REFERENCE,
'MyEnum p',
),
_expectId(main, SearchResultKind.REFERENCE, 'MyEnum v'),
_expectId(main, SearchResultKind.REFERENCE, 'MyEnum.a'),
];
await _verifyReferences(element, expected);
}
test_searchReferences_ClassElement_mixin() async {
await resolveTestCode('''
mixin A {}
class B extends Object with A {} // with
''');
var element = findElement.mixin('A');
var b = findElement.class_('B');
var expected = [
_expectId(b, SearchResultKind.REFERENCE, 'A {} // with'),
];
await _verifyReferences(element, expected);
}
test_searchReferences_ClassElement_typeArgument_ofGenericAnnotation() async {
await resolveTestCode('''
class A<T> {
const A();
}
class B {}
@A<B>()
void f() {}
''');
var element = findElement.class_('B');
var f = findElement.topFunction('f');
await _verifyReferences(element, [
_expectId(f, SearchResultKind.REFERENCE, 'B>()'),
]);
}
test_searchReferences_CompilationUnitElement() async {
newFile('$testPackageLibPath/foo.dart', '');
await resolveTestCode('''
import 'foo.dart'; // import
export 'foo.dart'; // export
''');
var element = findElement.importFind('package:test/foo.dart').unitElement;
int uriLength = "'foo.dart'".length;
var expected = [
_expectIdQ(resultUnitElement, SearchResultKind.REFERENCE,
"'foo.dart'; // import",
length: uriLength),
_expectIdQ(resultUnitElement, SearchResultKind.REFERENCE,
"'foo.dart'; // export",
length: uriLength),
];
await _verifyReferences(element, expected);
}
test_searchReferences_ConstructorElement_class_named() async {
await resolveTestCode('''
/// [new A.named] 1
class A {
A.named() {}
A.other() : this.named(); // 2
}
class B extends A {
B() : super.named(); // 3
factory B.other() = A.named; // 4
}
void f() {
A.named(); // 5
A.named; // 6
}
''');
var element = findElement.constructor('named');
var f = findElement.function('f');
var expected = [
_expectIdQ(
findElement.class_('A'), SearchResultKind.REFERENCE, '.named] 1',
length: '.named'.length),
_expectIdQ(findElement.constructor('other', of: 'A'),
SearchResultKind.INVOCATION, '.named(); // 2',
length: '.named'.length),
_expectIdQ(findElement.unnamedConstructor('B'),
SearchResultKind.INVOCATION, '.named(); // 3',
length: '.named'.length),
_expectIdQ(findElement.constructor('other', of: 'B'),
SearchResultKind.REFERENCE, '.named; // 4',
length: '.named'.length),
_expectIdQ(f, SearchResultKind.INVOCATION, '.named(); // 5',
length: '.named'.length),
_expectIdQ(
f, SearchResultKind.REFERENCE_BY_CONSTRUCTOR_TEAR_OFF, '.named; // 6',
length: '.named'.length),
];
await _verifyReferences(element, expected);
}
test_searchReferences_ConstructorElement_class_named_viaTypeAlias() async {
await resolveTestCode('''
class A<T> {
A.named();
}
typedef B = A<int>;
void f() {
B.named(); // ref
B.named;
}
''');
var element = findElement.constructor('named');
var f = findElement.topFunction('f');
await _verifyReferences(element, [
_expectIdQ(f, SearchResultKind.INVOCATION, '.named(); // ref',
length: '.named'.length),
_expectIdQ(
f, SearchResultKind.REFERENCE_BY_CONSTRUCTOR_TEAR_OFF, '.named;',
length: '.named'.length),
]);
}
test_searchReferences_ConstructorElement_class_unnamed_declared() async {
await resolveTestCode('''
/// [new A] 1
class A {
A() {}
A.other() : this(); // 2
}
class B extends A {
B() : super(); // 3
factory B.other() = A; // 4
}
void f() {
A(); // 5
A.new; // 6
}
''');
var element = findElement.unnamedConstructor('A');
var f = findElement.function('f');
var expected = [
_expectIdQ(findElement.class_('A'), SearchResultKind.REFERENCE, '] 1',
length: 0),
_expectIdQ(findElement.constructor('other', of: 'A'),
SearchResultKind.INVOCATION, '(); // 2',
length: 0),
_expectIdQ(findElement.unnamedConstructor('B'),
SearchResultKind.INVOCATION, '(); // 3',
length: 0),
_expectIdQ(findElement.constructor('other', of: 'B'),
SearchResultKind.REFERENCE, '; // 4',
length: 0),
_expectIdQ(f, SearchResultKind.INVOCATION, '(); // 5', length: 0),
_expectIdQ(
f, SearchResultKind.REFERENCE_BY_CONSTRUCTOR_TEAR_OFF, '.new; // 6',
length: '.new'.length),
];
await _verifyReferences(element, expected);
}
test_searchReferences_ConstructorElement_class_unnamed_otherFile() async {
String other = convertPath('$testPackageLibPath/other.dart');
String otherCode = '''
import 'test.dart';
void f() {
A(); // in other
}
''';
newFile(other, otherCode);
await resolveTestCode('''
class A {
A() {}
}
''');
var element = findElement.unnamedConstructor('A');
var otherUnitResult = await driver.getResult(other) as ResolvedUnitResult;
CompilationUnit otherUnit = otherUnitResult.unit;
Element main = otherUnit.declaredElement!.functions[0];
var expected = [
ExpectedResult(main, SearchResultKind.INVOCATION,
otherCode.indexOf('(); // in other'), 0,
isResolved: true, isQualified: true)
];
await _verifyReferences(element, expected);
}
test_searchReferences_ConstructorElement_class_unnamed_synthetic() async {
await resolveTestCode('''
/// [new A] 1
class A {}
class B extends A {
B() : super(); // 2
factory B.other() = A; // 3
}
void f() {
A(); // 4
A.new; // 5
}
''');
var element = findElement.unnamedConstructor('A');
var f = findElement.function('f');
var expected = [
_expectIdQ(findElement.class_('A'), SearchResultKind.REFERENCE, '] 1',
length: 0),
_expectIdQ(findElement.unnamedConstructor('B'),
SearchResultKind.INVOCATION, '(); // 2',
length: 0),
_expectIdQ(findElement.constructor('other', of: 'B'),
SearchResultKind.REFERENCE, '; // 3',
length: 0),
_expectIdQ(f, SearchResultKind.INVOCATION, '(); // 4', length: 0),
_expectIdQ(
f, SearchResultKind.REFERENCE_BY_CONSTRUCTOR_TEAR_OFF, '.new; // 5',
length: '.new'.length),
];
await _verifyReferences(element, expected);
}
test_searchReferences_ConstructorElement_enum_named() async {
await resolveTestCode('''
/// [new E.named] 1
enum E {
v.named(); // 2
const E.named();
const E.other() : this.named(); // 3
}
''');
var element = findElement.constructor('named');
var expected = [
_expectIdQ(
findElement.enum_('E'), SearchResultKind.REFERENCE, '.named] 1',
length: '.named'.length),
_expectIdQ(findElement.field('v', of: 'E'), SearchResultKind.INVOCATION,
'.named(); // 2',
length: '.named'.length),
_expectIdQ(findElement.constructor('other', of: 'E'),
SearchResultKind.INVOCATION, '.named(); // 3',
length: '.named'.length),
];
await _verifyReferences(element, expected);
}
test_searchReferences_ConstructorElement_enum_unnamed_declared() async {
await resolveTestCode('''
/// [new E] 1
enum E {
v1, // 2
v2(), // 3
v3.new(); // 4
const E();
const E.other() : this(); // 5
}
''');
var element = findElement.unnamedConstructor('E');
var expected = [
_expectIdQ(findElement.enum_('E'), SearchResultKind.REFERENCE, '] 1',
length: 0),
_expectIdQ(
findElement.field('v1'),
SearchResultKind.INVOCATION_BY_ENUM_CONSTANT_WITHOUT_ARGUMENTS,
', // 2',
length: 0),
_expectIdQ(
findElement.field('v2'), SearchResultKind.INVOCATION, '(), // 3',
length: 0),
_expectIdQ(
findElement.field('v3'), SearchResultKind.INVOCATION, '.new(); // 4',
length: '.new'.length),
_expectIdQ(findElement.constructor('other'), SearchResultKind.INVOCATION,
'(); // 5',
length: 0),
];
await _verifyReferences(element, expected);
}
test_searchReferences_ConstructorElement_enum_unnamed_synthetic() async {
await resolveTestCode('''
/// [new E] 1
enum E {
v1, // 2
v2(), // 3
v3.new(); // 4
}
''');
var element = findElement.unnamedConstructor('E');
var expected = [
_expectIdQ(findElement.enum_('E'), SearchResultKind.REFERENCE, '] 1',
length: 0),
_expectIdQ(
findElement.field('v1'),
SearchResultKind.INVOCATION_BY_ENUM_CONSTANT_WITHOUT_ARGUMENTS,
', // 2',
length: 0),
_expectIdQ(
findElement.field('v2'), SearchResultKind.INVOCATION, '(), // 3',
length: 0),
_expectIdQ(
findElement.field('v3'), SearchResultKind.INVOCATION, '.new(); // 4',
length: '.new'.length),
];
await _verifyReferences(element, expected);
}
test_searchReferences_ExtensionElement() async {
await resolveTestCode('''
extension E on int {
void foo() {}
static void bar() {}
}
main() {
E(0).foo();
E.bar();
}
''');
var element = findElement.extension_('E');
var main = findElement.function('main');
var expected = [
_expectId(main, SearchResultKind.REFERENCE, 'E(0)'),
_expectId(main, SearchResultKind.REFERENCE, 'E.bar()'),
];
await _verifyReferences(element, expected);
}
test_searchReferences_FieldElement_class() async {
await resolveTestCode('''
class A {
var field;
A({this.field});
main() {
new A(field: 1);
// getter
print(field); // ref-nq
print(this.field); // ref-q
field(); // inv-nq
this.field(); // inv-q
// setter
field = 2; // ref-nq;
this.field = 3; // ref-q;
}
}
''');
var element = findElement.field('field');
var main = findElement.method('main');
var fieldParameter = findElement.parameter('field');
var expected = [
_expectIdQ(fieldParameter, SearchResultKind.WRITE, 'field}'),
_expectIdQ(main, SearchResultKind.REFERENCE, 'field: 1'),
_expectId(main, SearchResultKind.READ, 'field); // ref-nq'),
_expectIdQ(main, SearchResultKind.READ, 'field); // ref-q'),
_expectId(main, SearchResultKind.READ, 'field(); // inv-nq'),
_expectIdQ(main, SearchResultKind.READ, 'field(); // inv-q'),
_expectId(main, SearchResultKind.WRITE, 'field = 2; // ref-nq'),
_expectIdQ(main, SearchResultKind.WRITE, 'field = 3; // ref-q'),
];
await _verifyReferences(element, expected);
}
test_searchReferences_FieldElement_class_synthetic() async {
await resolveTestCode('''
class A {
get field => null;
set field(x) {}
main() {
// getter
print(field); // ref-nq
print(this.field); // ref-q
field(); // inv-nq
this.field(); // inv-q
// setter
field = 2; // ref-nq;
this.field = 3; // ref-q;
}
}
''');
var element = findElement.field('field');
var main = findElement.method('main');
var expected = [
_expectId(main, SearchResultKind.READ, 'field); // ref-nq'),
_expectIdQ(main, SearchResultKind.READ, 'field); // ref-q'),
_expectId(main, SearchResultKind.READ, 'field(); // inv-nq'),
_expectIdQ(main, SearchResultKind.READ, 'field(); // inv-q'),
_expectId(main, SearchResultKind.WRITE, 'field = 2; // ref-nq'),
_expectIdQ(main, SearchResultKind.WRITE, 'field = 3; // ref-q'),
];
await _verifyReferences(element, expected);
}
test_searchReferences_FieldElement_enum() async {
await resolveTestCode('''
enum E {
v(field: 0);
final int field;
const E({required this.field}); // 1
}
void f(E e) {
e.field; // 2
}
''');
await _verifyReferences(findElement.field('field'), [
_expectIdQ(
findElement.field('v'), SearchResultKind.REFERENCE, 'field: 0'),
_expectIdQ(findElement.parameter('field'), SearchResultKind.WRITE,
'field}); // 1'),
_expectIdQ(
findElement.topFunction('f'), SearchResultKind.READ, 'field; // 2'),
]);
}
test_searchReferences_FieldElement_enum_values() async {
await resolveTestCode('''
enum MyEnum {
A, B, C
}
main() {
print(MyEnum.A.index);
print(MyEnum.values);
print(MyEnum.A);
print(MyEnum.B);
}
''');
var enumElement = findElement.enum_('MyEnum');
var main = findElement.function('main');
await _verifyReferences(typeProvider.enumElement!.getField('index')!,
[_expectIdQ(main, SearchResultKind.READ, 'index);')]);
await _verifyReferences(enumElement.getField('values')!,
[_expectIdQ(main, SearchResultKind.READ, 'values);')]);
await _verifyReferences(enumElement.getField('A')!, [
_expectIdQ(main, SearchResultKind.READ, 'A.index);'),
_expectIdQ(main, SearchResultKind.READ, 'A);')
]);
await _verifyReferences(enumElement.getField('B')!,
[_expectIdQ(main, SearchResultKind.READ, 'B);')]);
}
test_searchReferences_FunctionElement() async {
await resolveTestCode('''
test() {}
main() {
test();
print(test);
}
''');
var element = findElement.function('test');
var main = findElement.function('main');
var expected = [
_expectId(main, SearchResultKind.INVOCATION, 'test();'),
_expectId(main, SearchResultKind.REFERENCE, 'test);')
];
await _verifyReferences(element, expected);
}
test_searchReferences_FunctionElement_local() async {
await resolveTestCode('''
main() {
test() {}
test();
print(test);
}
''');
var element = findElement.localFunction('test');
var main = findElement.function('main');
var expected = [
_expectId(main, SearchResultKind.INVOCATION, 'test();'),
_expectId(main, SearchResultKind.REFERENCE, 'test);')
];
await _verifyReferences(element, expected);
}
test_searchReferences_ImportElement_noPrefix() async {
await resolveTestCode('''
import 'dart:math' show max, pi, Random hide min;
export 'dart:math' show max, pi, Random hide min;
main() {
print(pi);
print(new Random());
print(max(1, 2));
}
Random bar() => null;
''');
var element = findElement.import('dart:math', mustBeUnique: false);
var main = findElement.function('main');
var bar = findElement.function('bar');
var kind = SearchResultKind.REFERENCE;
var expected = [
_expectId(main, kind, 'pi);', length: 0),
_expectId(main, kind, 'Random()', length: 0),
_expectId(main, kind, 'max(', length: 0),
_expectId(bar, kind, 'Random bar()', length: 0),
];
await _verifyReferences(element, expected);
}
test_searchReferences_ImportElement_noPrefix_inPackage() async {
var aaaPackageRootPath = '$packagesRootPath/aaa';
var aaaFilePath = convertPath('$aaaPackageRootPath/lib/a.dart');
writeTestPackageConfig(
PackageConfigFileBuilder()
..add(name: 'aaa', rootPath: aaaPackageRootPath),
);
fileForContextSelection = testFile;
await resolveFileCode(aaaFilePath, '''
import 'dart:math' show max, pi, Random hide min;
export 'dart:math' show max, pi, Random hide min;
main() {
pi;
new Random();
max(1, 2);
}
Random bar() => null;
''');
final element = findElement.import('dart:math');
var main = findElement.function('main');
var bar = findElement.function('bar');
var kind = SearchResultKind.REFERENCE;
var expected = [
_expectId(main, kind, 'pi;', length: 0),
_expectId(main, kind, 'Random();', length: 0),
_expectId(main, kind, 'max(1, 2);', length: 0),
_expectId(bar, kind, 'Random bar()', length: 0),
];
await _verifyReferences(element, expected);
}
test_searchReferences_ImportElement_noPrefix_optIn_fromOptOut() async {
newFile('$testPackageLibPath/a.dart', r'''
class N1 {}
void N2() {}
int get N3 => 0;
set N4(int _) {}
''');
await resolveTestCode('''
// @dart = 2.7
import 'a.dart';
main() {
N1;
N2();
N3;
N4 = 0;
}
''');
final element = findElement.import('package:test/a.dart');
var main = findElement.function('main');
var kind = SearchResultKind.REFERENCE;
var expected = [
_expectId(main, kind, 'N1;', length: 0),
_expectId(main, kind, 'N2();', length: 0),
_expectId(main, kind, 'N3;', length: 0),
_expectId(main, kind, 'N4 =', length: 0),
];
await _verifyReferences(element, expected);
}
test_searchReferences_ImportElement_withPrefix() async {
await resolveTestCode('''
import 'dart:math' as math show max, pi, Random hide min;
export 'dart:math' show max, pi, Random hide min;
main() {
print(math.pi);
print(new math.Random());
print(math.max(1, 2));
}
math.Random bar() => null;
''');
var element = findElement.import('dart:math', mustBeUnique: false);
var main = findElement.function('main');
var bar = findElement.function('bar');
var kind = SearchResultKind.REFERENCE;
var length = 'math.'.length;
var expected = [
_expectId(main, kind, 'math.pi);', length: length),
_expectId(main, kind, 'math.Random()', length: length),
_expectId(main, kind, 'math.max(', length: length),
_expectId(bar, kind, 'math.Random bar()', length: length),
];
await _verifyReferences(element, expected);
}
test_searchReferences_ImportElement_withPrefix_forMultipleImports() async {
await resolveTestCode('''
import 'dart:async' as p;
import 'dart:math' as p;
main() {
p.Random;
p.Future;
}
''');
var main = findElement.function('main');
var kind = SearchResultKind.REFERENCE;
var length = 'p.'.length;
{
final element = findElement.import('dart:async');
var expected = [
_expectId(main, kind, 'p.Future;', length: length),
];
await _verifyReferences(element, expected);
}
{
final element = findElement.import('dart:math');
var expected = [
_expectId(main, kind, 'p.Random', length: length),
];
await _verifyReferences(element, expected);
}
}
test_searchReferences_ImportElement_withPrefix_optIn_fromOptOut() async {
newFile('$testPackageLibPath/a.dart', r'''
class N1 {}
void N2() {}
int get N3 => 0;
set N4(int _) {}
''');
await resolveTestCode('''
// @dart = 2.7
import 'a.dart' as a;
main() {
a.N1;
a.N2();
a.N3;
a.N4 = 0;
}
''');
final element = findElement.import('package:test/a.dart');
var main = findElement.function('main');
var kind = SearchResultKind.REFERENCE;
var length = 'a.'.length;
var expected = [
_expectId(main, kind, 'a.N1;', length: length),
_expectId(main, kind, 'a.N2()', length: length),
_expectId(main, kind, 'a.N3', length: length),
_expectId(main, kind, 'a.N4', length: length),
];
await _verifyReferences(element, expected);
}
test_searchReferences_LabelElement() async {
await resolveTestCode('''
main() {
label:
while (true) {
if (true) {
break label; // 1
}
break label; // 2
}
}
''');
var element = findElement.label('label');
var main = findElement.function('main');
var expected = [
_expectId(main, SearchResultKind.REFERENCE, 'label; // 1'),
_expectId(main, SearchResultKind.REFERENCE, 'label; // 2')
];
await _verifyReferences(element, expected);
}
test_searchReferences_LibraryElement() async {
var codeA = 'part of lib; // A';
var codeB = 'part of lib; // B';
newFile('$testPackageLibPath/unitA.dart', codeA);
newFile('$testPackageLibPath/unitB.dart', codeB);
await resolveTestCode('''
library lib;
part 'unitA.dart';
part 'unitB.dart';
''');
LibraryElement element = result.libraryElement;
CompilationUnitElement unitElementA =
(element.parts2[0].uri as DirectiveUriWithUnit).unit;
CompilationUnitElement unitElementB =
(element.parts2[1].uri as DirectiveUriWithUnit).unit;
var expected = [
ExpectedResult(unitElementA, SearchResultKind.REFERENCE,
codeA.indexOf('lib; // A'), 'lib'.length),
ExpectedResult(unitElementB, SearchResultKind.REFERENCE,
codeB.indexOf('lib; // B'), 'lib'.length),
];
await _verifyReferences(element, expected);
}
test_searchReferences_LibraryElement_inPackage() async {
var aaaPackageRootPath = '$packagesRootPath/aaa';
writeTestPackageConfig(
PackageConfigFileBuilder()
..add(name: 'aaa', rootPath: aaaPackageRootPath),
);
var libPath = convertPath('$aaaPackageRootPath/lib/a.dart');
var partPathA = convertPath('$aaaPackageRootPath/lib/unitA.dart');
var partPathB = convertPath('$aaaPackageRootPath/lib/unitB.dart');
var codeA = 'part of lib; // A';
var codeB = 'part of lib; // B';
newFile(partPathA, codeA);
newFile(partPathB, codeB);
fileForContextSelection = testFile;
await resolveFileCode(libPath, '''
library lib;
part 'unitA.dart';
part 'unitB.dart';
''');
LibraryElement element = result.libraryElement;
CompilationUnitElement unitElementA =
(element.parts2[0].uri as DirectiveUriWithUnit).unit;
CompilationUnitElement unitElementB =
(element.parts2[1].uri as DirectiveUriWithUnit).unit;
var expected = [
ExpectedResult(unitElementA, SearchResultKind.REFERENCE,
codeA.indexOf('lib; // A'), 'lib'.length),
ExpectedResult(unitElementB, SearchResultKind.REFERENCE,
codeB.indexOf('lib; // B'), 'lib'.length),
];
await _verifyReferences(element, expected);
}
test_searchReferences_LocalVariableElement() async {
await resolveTestCode(r'''
main() {
var v;
v = 1;
v += 2;
print(v);
v();
}
''');
Element element = findElement.localVar('v');
var main = findElement.function('main');
var expected = [
_expectId(main, SearchResultKind.WRITE, 'v = 1;'),
_expectId(main, SearchResultKind.READ_WRITE, 'v += 2;'),
_expectId(main, SearchResultKind.READ, 'v);'),
_expectId(main, SearchResultKind.READ, 'v();')
];
await _verifyReferences(element, expected);
}
test_searchReferences_LocalVariableElement_inForEachLoop() async {
await resolveTestCode('''
main() {
for (var v in []) {
v = 1;
v += 2;
print(v);
v();
}
}
''');
Element element = findElement.localVar('v');
var main = findElement.function('main');
var expected = [
_expectId(main, SearchResultKind.WRITE, 'v = 1;'),
_expectId(main, SearchResultKind.READ_WRITE, 'v += 2;'),
_expectId(main, SearchResultKind.READ, 'v);'),
_expectId(main, SearchResultKind.READ, 'v();')
];
await _verifyReferences(element, expected);
}
test_searchReferences_LocalVariableElement_inPackage() async {
var aaaPackageRootPath = '$packagesRootPath/aaa';
var testPath = convertPath('$aaaPackageRootPath/lib/a.dart');
writeTestPackageConfig(
PackageConfigFileBuilder()
..add(name: 'aaa', rootPath: aaaPackageRootPath),
);
fileForContextSelection = testFile;
await resolveFileCode(testPath, '''
main() {
var v;
v = 1;
v += 2;
print(v);
v();
}
''');
var element = findElement.localVar('v');
var main = findElement.function('main');
var expected = [
_expectId(main, SearchResultKind.WRITE, 'v = 1;'),
_expectId(main, SearchResultKind.READ_WRITE, 'v += 2;'),
_expectId(main, SearchResultKind.READ, 'v);'),
_expectId(main, SearchResultKind.READ, 'v();')
];
await _verifyReferences(element, expected);
}
test_searchReferences_MethodElement_class() async {
await resolveTestCode('''
class A {
m() {}
main() {
m(); // 1
this.m(); // 2
print(m); // 3
print(this.m); // 4
}
}
''');
var method = findElement.method('m');
var main = findElement.method('main');
var expected = [
_expectId(main, SearchResultKind.INVOCATION, 'm(); // 1'),
_expectIdQ(main, SearchResultKind.INVOCATION, 'm(); // 2'),
_expectId(main, SearchResultKind.REFERENCE, 'm); // 3'),
_expectIdQ(main, SearchResultKind.REFERENCE, 'm); // 4')
];
await _verifyReferences(method, expected);
}
test_searchReferences_MethodElement_enum() async {
await resolveTestCode('''
enum E {
v;
void foo() {}
void bar() {
foo(); // 1
this.foo(); // 2
}
}
void f(E e) {
e.foo(); // 3
e.foo; // 4
}
''');
await _verifyReferences(findElement.method('foo'), [
_expectId(findElement.method('bar'), SearchResultKind.INVOCATION,
'foo(); // 1'),
_expectIdQ(findElement.method('bar'), SearchResultKind.INVOCATION,
'foo(); // 2'),
_expectIdQ(findElement.topFunction('f'), SearchResultKind.INVOCATION,
'foo(); // 3'),
_expectIdQ(findElement.topFunction('f'), SearchResultKind.REFERENCE,
'foo; // 4'),
]);
}
test_searchReferences_MethodElement_extension_instance() async {
await resolveTestCode('''
extension E on int {
void foo() {}
void bar() {
foo(); // 1
this.foo(); // 2
foo; // 3
this.foo; // 4
}
}
main() {
E(0).foo(); // 5
0.foo(); // 6
E(0).foo; // 7
0.foo; // 8
}
''');
var element = findElement.method('foo');
var bar = findElement.method('bar');
var main = findElement.function('main');
var expected = [
_expectId(bar, SearchResultKind.INVOCATION, 'foo(); // 1'),
_expectIdQ(bar, SearchResultKind.INVOCATION, 'foo(); // 2'),
_expectId(bar, SearchResultKind.REFERENCE, 'foo; // 3'),
_expectIdQ(bar, SearchResultKind.REFERENCE, 'foo; // 4'),
_expectIdQ(main, SearchResultKind.INVOCATION, 'foo(); // 5'),
_expectIdQ(main, SearchResultKind.INVOCATION, 'foo(); // 6'),
_expectIdQ(main, SearchResultKind.REFERENCE, 'foo; // 7'),
_expectIdQ(main, SearchResultKind.REFERENCE, 'foo; // 8'),
];
await _verifyReferences(element, expected);
}
test_searchReferences_MethodElement_extension_named() async {
await resolveTestCode('''
extension E on int {
void foo() {}
void bar() {
foo(); // 1
this.foo(); // 2
print(foo); // 3
print(this.foo); // 4
}
}
''');
var foo = findElement.method('foo');
var bar = findElement.method('bar');
var expected = [
_expectId(bar, SearchResultKind.INVOCATION, 'foo(); // 1'),
_expectIdQ(bar, SearchResultKind.INVOCATION, 'foo(); // 2'),
_expectId(bar, SearchResultKind.REFERENCE, 'foo); // 3'),
_expectIdQ(bar, SearchResultKind.REFERENCE, 'foo); // 4')
];
await _verifyReferences(foo, expected);
}
test_searchReferences_MethodElement_extension_static() async {
await resolveTestCode('''
extension E on int {
static void foo() {}
static void bar() {
foo(); // 1
foo; // 2
}
}
main() {
E.foo(); // 3
E.foo; // 4
}
''');
var element = findElement.method('foo');
var bar = findElement.method('bar');
var main = findElement.function('main');
var expected = [
_expectId(bar, SearchResultKind.INVOCATION, 'foo(); // 1'),
_expectId(bar, SearchResultKind.REFERENCE, 'foo; // 2'),
_expectIdQ(main, SearchResultKind.INVOCATION, 'foo(); // 3'),
_expectIdQ(main, SearchResultKind.REFERENCE, 'foo; // 4'),
];
await _verifyReferences(element, expected);
}
test_searchReferences_MethodElement_extension_unnamed() async {
await resolveTestCode('''
extension on int {
void foo() {}
void bar() {
foo(); // 1
this.foo(); // 2
print(foo); // 3
print(this.foo); // 4
}
}
''');
var foo = findElement.method('foo');
var bar = findElement.method('bar');
var expected = [
_expectId(bar, SearchResultKind.INVOCATION, 'foo(); // 1'),
_expectIdQ(bar, SearchResultKind.INVOCATION, 'foo(); // 2'),
_expectId(bar, SearchResultKind.REFERENCE, 'foo); // 3'),
_expectIdQ(bar, SearchResultKind.REFERENCE, 'foo); // 4')
];
await _verifyReferences(foo, expected);
}
test_searchReferences_MethodMember_class() async {
await resolveTestCode('''
class A<T> {
T m() => null;
}
main(A<int> a) {
a.m(); // ref
}
''');
var method = findElement.method('m');
var main = findElement.function('main');
var expected = [
_expectIdQ(main, SearchResultKind.INVOCATION, 'm(); // ref')
];
await _verifyReferences(method, expected);
}
test_searchReferences_ParameterElement_ofConstructor_super_named() async {
await resolveTestCode('''
class A {
A({required int a});
}
class B extends A {
B({required super.a}); // ref
}
''');
var element = findElement.unnamedConstructor('A').parameter('a');
var expected = [
_expectIdQ(
findElement.unnamedConstructor('B').superFormalParameter('a'),
SearchResultKind.REFERENCE,
'a}); // ref',
),
];
await _verifyReferences(element, expected);
}
test_searchReferences_ParameterElement_ofConstructor_super_positional() async {
await resolveTestCode('''
class A {
A(int a);
}
class B extends A {
B(super.a); // ref
}
''');
var element = findElement.unnamedConstructor('A').parameter('a');
var expected = [
_expectIdQ(
findElement.unnamedConstructor('B').superFormalParameter('a'),
SearchResultKind.REFERENCE,
'a); // ref',
),
];
await _verifyReferences(element, expected);
}
test_searchReferences_ParameterElement_optionalNamed() async {
await resolveTestCode('''
foo({p}) {
p = 1;
p += 2;
print(p);
p();
}
main() {
foo(p: 42);
}
''');
var element = findElement.parameter('p');
var foo = findElement.function('foo');
var main = findElement.function('main');
var expected = [
_expectId(foo, SearchResultKind.WRITE, 'p = 1;'),
_expectId(foo, SearchResultKind.READ_WRITE, 'p += 2;'),
_expectId(foo, SearchResultKind.READ, 'p);'),
_expectId(foo, SearchResultKind.READ, 'p();'),
_expectIdQ(main, SearchResultKind.REFERENCE, 'p: 42')
];
await _verifyReferences(element, expected);
}
test_searchReferences_ParameterElement_optionalNamed_anywhere() async {
await resolveTestCode('''
foo(int a, int b, {p}) {
p;
}
main() {
foo(0, p: 1, 2);
}
''');
var element = findElement.parameter('p');
var foo = findElement.function('foo');
var main = findElement.function('main');
var expected = [
_expectId(foo, SearchResultKind.READ, 'p;'),
_expectIdQ(main, SearchResultKind.REFERENCE, 'p: 1')
];
await _verifyReferences(element, expected);
}
test_searchReferences_ParameterElement_optionalPositional() async {
await resolveTestCode('''
foo([p]) {
p = 1;
p += 2;
print(p);
p();
}
main() {
foo(42);
}
''');
var element = findElement.parameter('p');
var foo = findElement.function('foo');
var main = findElement.function('main');
var expected = [
_expectId(foo, SearchResultKind.WRITE, 'p = 1;'),
_expectId(foo, SearchResultKind.READ_WRITE, 'p += 2;'),
_expectId(foo, SearchResultKind.READ, 'p);'),
_expectId(foo, SearchResultKind.READ, 'p();'),
_expectIdQ(main, SearchResultKind.REFERENCE, '42', length: 0)
];
await _verifyReferences(element, expected);
}
test_searchReferences_ParameterElement_requiredNamed() async {
await resolveTestCode('''
foo({required int p}) {
p = 1;
p += 2;
print(p);
p();
}
main() {
foo(p: 42);
}
''');
var element = findElement.parameter('p');
var foo = findElement.function('foo');
var main = findElement.function('main');
var expected = [
_expectId(foo, SearchResultKind.WRITE, 'p = 1;'),
_expectId(foo, SearchResultKind.READ_WRITE, 'p += 2;'),
_expectId(foo, SearchResultKind.READ, 'p);'),
_expectId(foo, SearchResultKind.READ, 'p();'),
_expectIdQ(main, SearchResultKind.REFERENCE, 'p: 42')
];
await _verifyReferences(element, expected);
}
test_searchReferences_ParameterElement_requiredPositional_ofConstructor() async {
await resolveTestCode('''
class C {
var f;
C(p) : f = p + 1 {
p = 2;
p += 3;
print(p);
p();
}
}
main() {
new C(42);
}
''');
var element = findElement.parameter('p');
var constructor = findElement.unnamedConstructor('C');
var expected = [
_expectId(constructor, SearchResultKind.READ, 'p + 1 {'),
_expectId(constructor, SearchResultKind.WRITE, 'p = 2;'),
_expectId(constructor, SearchResultKind.READ_WRITE, 'p += 3;'),
_expectId(constructor, SearchResultKind.READ, 'p);'),
_expectId(constructor, SearchResultKind.READ, 'p();')
];
await _verifyReferences(element, expected);
}
test_searchReferences_ParameterElement_requiredPositional_ofLocalFunction() async {
await resolveTestCode('''
main() {
foo(p) {
p = 1;
p += 2;
print(p);
p();
}
foo(42);
}
''');
var main = findElement.function('main');
var element = findElement.parameter('p');
var expected = [
_expectId(main, SearchResultKind.WRITE, 'p = 1;'),
_expectId(main, SearchResultKind.READ_WRITE, 'p += 2;'),
_expectId(main, SearchResultKind.READ, 'p);'),
_expectId(main, SearchResultKind.READ, 'p();')
];
await _verifyReferences(element, expected);
}
test_searchReferences_ParameterElement_requiredPositional_ofMethod() async {
await resolveTestCode('''
class C {
foo(p) {
p = 1;
p += 2;
print(p);
p();
}
}
main(C c) {
c.foo(42);
}
''');
var element = findElement.parameter('p');
var foo = findElement.method('foo');
var expected = [
_expectId(foo, SearchResultKind.WRITE, 'p = 1;'),
_expectId(foo, SearchResultKind.READ_WRITE, 'p += 2;'),
_expectId(foo, SearchResultKind.READ, 'p);'),
_expectId(foo, SearchResultKind.READ, 'p();')
];
await _verifyReferences(element, expected);
}
test_searchReferences_ParameterElement_requiredPositional_ofTopLevelFunction() async {
await resolveTestCode('''
foo(p) {
p = 1;
p += 2;
print(p);
p();
}
main() {
foo(42);
}
''');
var element = findElement.parameter('p');
var foo = findElement.function('foo');
var expected = [
_expectId(foo, SearchResultKind.WRITE, 'p = 1;'),
_expectId(foo, SearchResultKind.READ_WRITE, 'p += 2;'),
_expectId(foo, SearchResultKind.READ, 'p);'),
_expectId(foo, SearchResultKind.READ, 'p();')
];
await _verifyReferences(element, expected);
}
test_searchReferences_PrefixElement() async {
String partCode = r'''
part of my_lib;
ppp.Future c;
''';
newFile('$testPackageLibPath/my_part.dart', partCode);
await resolveTestCode('''
library my_lib;
import 'dart:async' as ppp;
part 'my_part.dart';
main() {
ppp.Future a;
ppp.Stream b;
}
''');
var element = findElement.prefix('ppp');
var main = findElement.function('main');
var c = findElement.partFind('package:test/my_part.dart').topVar('c');
var expected = [
_expectId(main, SearchResultKind.REFERENCE, 'ppp.Future'),
_expectId(main, SearchResultKind.REFERENCE, 'ppp.Stream'),
ExpectedResult(c, SearchResultKind.REFERENCE,
partCode.indexOf('ppp.Future c'), 'ppp'.length)
];
await _verifyReferences(element, expected);
}
test_searchReferences_PrefixElement_inPackage() async {
var aaaPackageRootPath = '$packagesRootPath/aaa';
writeTestPackageConfig(
PackageConfigFileBuilder()
..add(name: 'aaa', rootPath: aaaPackageRootPath),
);
fileForContextSelection = testFile;
var libPath = convertPath('$aaaPackageRootPath/lib/a.dart');
var partPath = convertPath('$aaaPackageRootPath/lib/my_part.dart');
String partCode = r'''
part of my_lib;
ppp.Future c;
''';
newFile(partPath, partCode);
await resolveFileCode(libPath, '''
library my_lib;
import 'dart:async' as ppp;
part 'my_part.dart';
main() {
ppp.Future a;
ppp.Stream b;
}
''');
var element = findElement.prefix('ppp');
var main = findElement.function('main');
var c = findElement.partFind('package:aaa/my_part.dart').topVar('c');
var expected = [
_expectId(main, SearchResultKind.REFERENCE, 'ppp.Future'),
_expectId(main, SearchResultKind.REFERENCE, 'ppp.Stream'),
ExpectedResult(c, SearchResultKind.REFERENCE,
partCode.indexOf('ppp.Future c'), 'ppp'.length)
];
await _verifyReferences(element, expected);
}
test_searchReferences_private_declaredInDefiningUnit() async {
String p1 = convertPath('$testPackageLibPath/part1.dart');
String p2 = convertPath('$testPackageLibPath/part2.dart');
String p3 = convertPath('$testPackageLibPath/part3.dart');
String code1 = 'part of lib; _C v1;';
String code2 = 'part of lib; _C v2;';
newFile(p1, code1);
newFile(p2, code2);
newFile(p3, 'part of lib; int v3;');
await resolveTestCode('''
library lib;
part 'part1.dart';
part 'part2.dart';
part 'part3.dart';
class _C {}
_C v;
''');
var element = findElement.class_('_C');
Element v = findElement.topVar('v');
Element v1 = findElement.partFind('package:test/part1.dart').topVar('v1');
Element v2 = findElement.partFind('package:test/part2.dart').topVar('v2');
var expected = [
_expectId(v, SearchResultKind.REFERENCE, '_C v;', length: 2),
ExpectedResult(
v1, SearchResultKind.REFERENCE, code1.indexOf('_C v1;'), 2),
ExpectedResult(
v2, SearchResultKind.REFERENCE, code2.indexOf('_C v2;'), 2),
];
await _verifyReferences(element, expected);
}
test_searchReferences_private_declaredInPart() async {
String p = convertPath('$testPackageLibPath/lib.dart');
String p1 = convertPath('$testPackageLibPath/part1.dart');
String p2 = convertPath('$testPackageLibPath/part2.dart');
var code = '''
library lib;
part 'part1.dart';
part 'part2.dart';
_C v;
''';
var code1 = '''
part of lib;
class _C {}
_C v1;
''';
String code2 = 'part of lib; _C v2;';
newFile(p, code);
newFile(p1, code1);
newFile(p2, code2);
await resolveTestCode(code);
ClassElement element =
findElement.partFind('package:test/part1.dart').class_('_C');
Element v = findElement.topVar('v');
Element v1 = findElement.partFind('package:test/part1.dart').topVar('v1');
Element v2 = findElement.partFind('package:test/part2.dart').topVar('v2');
var expected = [
ExpectedResult(v, SearchResultKind.REFERENCE, code.indexOf('_C v;'), 2),
ExpectedResult(
v1, SearchResultKind.REFERENCE, code1.indexOf('_C v1;'), 2),
ExpectedResult(
v2, SearchResultKind.REFERENCE, code2.indexOf('_C v2;'), 2),
];
await _verifyReferences(element, expected);
}
test_searchReferences_private_inPackage() async {
var aaaPackageRootPath = '$packagesRootPath/aaa';
var testFile = convertPath('$aaaPackageRootPath/lib/a.dart');
var p1 = convertPath('$aaaPackageRootPath/lib/part1.dart');
var p2 = convertPath('$aaaPackageRootPath/lib/part2.dart');
writeTestPackageConfig(
PackageConfigFileBuilder()
..add(name: 'aaa', rootPath: aaaPackageRootPath),
);
fileForContextSelection = this.testFile;
String testCode = '''
library lib;
part 'part1.dart';
part 'part2.dart';
class _C {}
_C v;
''';
String code1 = 'part of lib; _C v1;';
String code2 = 'part of lib; _C v2;';
newFile(p1, code1);
newFile(p2, code2);
await resolveFileCode(testFile, testCode);
ClassElement element = findElement.class_('_C');
Element v = findElement.topVar('v');
Element v1 = findElement.partFind('package:aaa/part1.dart').topVar('v1');
Element v2 = findElement.partFind('package:aaa/part2.dart').topVar('v2');
var expected = [
ExpectedResult(
v, SearchResultKind.REFERENCE, testCode.indexOf('_C v;'), 2),
ExpectedResult(
v1, SearchResultKind.REFERENCE, code1.indexOf('_C v1;'), 2),
ExpectedResult(
v2, SearchResultKind.REFERENCE, code2.indexOf('_C v2;'), 2),
];
await _verifyReferences(element, expected);
}
test_searchReferences_PropertyAccessor_getter_ofExtension_instance() async {
await resolveTestCode('''
extension E on int {
int get foo => 0;
void bar() {
foo; // 1
this.foo; // 2
}
}
main() {
E(0).foo; // 3
0.foo; // 4
}
''');
var element = findElement.getter('foo');
var bar = findElement.method('bar');
var main = findElement.function('main');
var expected = [
_expectId(bar, SearchResultKind.REFERENCE, 'foo; // 1'),
_expectIdQ(bar, SearchResultKind.REFERENCE, 'foo; // 2'),
_expectIdQ(main, SearchResultKind.REFERENCE, 'foo; // 3'),
_expectIdQ(main, SearchResultKind.REFERENCE, 'foo; // 4'),
];
await _verifyReferences(element, expected);
}
test_searchReferences_PropertyAccessor_setter_ofExtension_instance() async {
await resolveTestCode('''
extension E on int {
set foo(int _) {}
void bar() {
foo = 1;
this.foo = 2;
}
}
main() {
E(0).foo = 3;
0.foo = 4;
}
''');
var element = findElement.setter('foo');
var bar = findElement.method('bar');
var main = findElement.function('main');
var expected = [
_expectId(bar, SearchResultKind.REFERENCE, 'foo = 1;'),
_expectIdQ(bar, SearchResultKind.REFERENCE, 'foo = 2;'),
_expectIdQ(main, SearchResultKind.REFERENCE, 'foo = 3;'),
_expectIdQ(main, SearchResultKind.REFERENCE, 'foo = 4;'),
];
await _verifyReferences(element, expected);
}
test_searchReferences_PropertyAccessorElement_getter() async {
await resolveTestCode('''
class A {
get ggg => null;
main() {
print(ggg); // ref-nq
print(this.ggg); // ref-q
ggg(); // inv-nq
this.ggg(); // inv-q
}
}
''');
var element = findElement.getter('ggg');
var main = findElement.method('main');
var expected = [
_expectId(main, SearchResultKind.REFERENCE, 'ggg); // ref-nq'),
_expectIdQ(main, SearchResultKind.REFERENCE, 'ggg); // ref-q'),
_expectId(main, SearchResultKind.REFERENCE, 'ggg(); // inv-nq'),
_expectIdQ(main, SearchResultKind.REFERENCE, 'ggg(); // inv-q'),
];
await _verifyReferences(element, expected);
}
test_searchReferences_PropertyAccessorElement_setter() async {
await resolveTestCode('''
class A {
set s(x) {}
main() {
s = 1;
this.s = 2;
}
}
''');
var element = findElement.setter('s');
var main = findElement.method('main');
var expected = [
_expectId(main, SearchResultKind.REFERENCE, 's = 1'),
_expectIdQ(main, SearchResultKind.REFERENCE, 's = 2')
];
await _verifyReferences(element, expected);
}
test_searchReferences_TopLevelVariableElement() async {
newFile('$testPackageLibPath/lib.dart', '''
library lib;
var V;
''');
await resolveTestCode('''
import 'lib.dart' show V; // imp
import 'lib.dart' as pref;
main() {
pref.V = 1; // q
print(pref.V); // q
pref.V(); // q
V = 1; // nq
print(V); // nq
V(); // nq
}
''');
final importElement = findNode.import('show V').element2!;
CompilationUnitElement impUnit =
importElement.importedLibrary!.definingCompilationUnit;
TopLevelVariableElement variable = impUnit.topLevelVariables[0];
var main = findElement.function('main');
var expected = [
_expectIdQ(resultUnitElement, SearchResultKind.REFERENCE, 'V; // imp'),
_expectIdQ(main, SearchResultKind.WRITE, 'V = 1; // q'),
_expectIdQ(main, SearchResultKind.READ, 'V); // q'),
_expectIdQ(main, SearchResultKind.READ, 'V(); // q'),
_expectId(main, SearchResultKind.WRITE, 'V = 1; // nq'),
_expectId(main, SearchResultKind.READ, 'V); // nq'),
_expectId(main, SearchResultKind.READ, 'V(); // nq'),
];
await _verifyReferences(variable, expected);
}
test_searchReferences_TypeAliasElement() async {
await resolveTestCode('''
class A<T> {
static int field = 0;
static void method() {}
}
typedef B = A<int>;
class C extends B {} // extends
void f(B p) {
B v;
B.field = 1;
B.field;
B.method();
}
''');
var element = findElement.typeAlias('B');
var f = findElement.topFunction('f');
await _verifyReferences(element, [
_expectId(findElement.class_('C'), SearchResultKind.REFERENCE,
'B {} // extends'),
_expectId(findElement.parameter('p'), SearchResultKind.REFERENCE, 'B p'),
_expectId(f, SearchResultKind.REFERENCE, 'B v'),
_expectId(f, SearchResultKind.REFERENCE, 'B.field ='),
_expectId(f, SearchResultKind.REFERENCE, 'B.field;'),
_expectId(f, SearchResultKind.REFERENCE, 'B.method();'),
]);
}
test_searchReferences_TypeAliasElement_fromLegacy() async {
newFile('$testPackageLibPath/a.dart', r'''
typedef A<T> = Map<int, T>;
''');
await resolveTestCode('''
// @dart = 2.9
import 'a.dart';
void f(A<String> a) {}
''');
var A = findElement.importFind('package:test/a.dart').typeAlias('A');
await _verifyReferences(A, [
_expectId(
findElement.parameter('a'),
SearchResultKind.REFERENCE,
'A<String>',
),
]);
}
test_searchReferences_TypeAliasElement_inConstructorName() async {
await resolveTestCode('''
class A<T> {}
typedef B = A<int>;
void f() {
B();
}
''');
var element = findElement.typeAlias('B');
var f = findElement.topFunction('f');
await _verifyReferences(element, [
_expectId(f, SearchResultKind.REFERENCE, 'B();'),
]);
}
test_searchReferences_TypeParameterElement_ofClass() async {
await resolveTestCode('''
class A<T> {
foo(T a) {}
bar(T b) {}
}
''');
var element = findElement.typeParameter('T');
var a = findElement.parameter('a');
var b = findElement.parameter('b');
var expected = [
_expectId(a, SearchResultKind.REFERENCE, 'T a'),
_expectId(b, SearchResultKind.REFERENCE, 'T b'),
];
await _verifyReferences(element, expected);
}
test_searchReferences_TypeParameterElement_ofEnum() async {
await resolveTestCode('''
enum E<T> {
v;
final T a;
void foo(T b) {}
}
''');
var element = findElement.typeParameter('T');
await _verifyReferences(element, [
_expectId(
findElement.field('a'),
SearchResultKind.REFERENCE,
'T a',
),
_expectId(
findElement.parameter('b'),
SearchResultKind.REFERENCE,
'T b',
),
]);
}
test_searchReferences_TypeParameterElement_ofLocalFunction() async {
await resolveTestCode('''
main() {
void foo<T>(T a) {
void bar(T b) {}
}
}
''');
var main = findElement.function('main');
var foo = findElement.localFunction('foo');
var element = foo.typeParameters.single;
var expected = [
_expectId(main, SearchResultKind.REFERENCE, 'T a'),
_expectId(main, SearchResultKind.REFERENCE, 'T b'),
];
await _verifyReferences(element, expected);
}
test_searchReferences_TypeParameterElement_ofMethod() async {
await resolveTestCode('''
class A {
foo<T>(T p) {}
}
''');
var element = findElement.typeParameter('T');
var p = findElement.parameter('p');
var expected = [
_expectId(p, SearchResultKind.REFERENCE, 'T p'),
];
await _verifyReferences(element, expected);
}
test_searchReferences_TypeParameterElement_ofTopLevelFunction() async {
await resolveTestCode('''
foo<T>(T a) {
bar(T b) {}
}
''');
var foo = findElement.function('foo');
var element = findElement.typeParameter('T');
var a = findElement.parameter('a');
var expected = [
_expectId(a, SearchResultKind.REFERENCE, 'T a'),
_expectId(foo, SearchResultKind.REFERENCE, 'T b'),
];
await _verifyReferences(element, expected);
}
test_searchSubtypes() async {
await resolveTestCode('''
class T {}
class A extends T {} // A
class B = Object with T; // B
class C implements T {} // C
''');
var element = findElement.class_('T');
var a = findElement.class_('A');
var b = findElement.class_('B');
var c = findElement.class_('C');
var expected = [
_expectId(a, SearchResultKind.REFERENCE, 'T {} // A'),
_expectId(b, SearchResultKind.REFERENCE, 'T; // B'),
_expectId(c, SearchResultKind.REFERENCE, 'T {} // C'),
];
await _verifyReferences(element, expected);
}
test_searchSubtypes_mixinDeclaration() async {
await resolveTestCode('''
class T {}
mixin A on T {} // A
mixin B implements T {} // B
''');
var element = findElement.class_('T');
var a = findElement.mixin('A');
var b = findElement.mixin('B');
var expected = [
_expectId(a, SearchResultKind.REFERENCE, 'T {} // A'),
_expectId(b, SearchResultKind.REFERENCE, 'T {} // B'),
];
await _verifyReferences(element, expected);
}
test_subtypes_class() async {
await resolveTestCode('''
class A {}
class B extends A {
void methodB() {}
}
class C extends Object with A {
void methodC() {}
}
class D implements A {
void methodD() {}
}
class E extends B {
void methodE() {}
}
class F {}
''');
var a = findElement.class_('A');
// Search by 'type'.
List<SubtypeResult> subtypes =
await driver.search.subtypes(SearchedFiles(), type: a);
expect(subtypes, hasLength(3));
SubtypeResult b = subtypes.singleWhere((r) => r.name == 'B');
SubtypeResult c = subtypes.singleWhere((r) => r.name == 'C');
SubtypeResult d = subtypes.singleWhere((r) => r.name == 'D');
expect(b.libraryUri, testUriStr);
expect(b.id, '$testUriStr;$testUriStr;B');
expect(b.members, ['methodB']);
expect(c.libraryUri, testUriStr);
expect(c.id, '$testUriStr;$testUriStr;C');
expect(c.members, ['methodC']);
expect(d.libraryUri, testUriStr);
expect(d.id, '$testUriStr;$testUriStr;D');
expect(d.members, ['methodD']);
// Search by 'id'.
{
List<SubtypeResult> subtypes =
await driver.search.subtypes(SearchedFiles(), subtype: b);
expect(subtypes, hasLength(1));
SubtypeResult e = subtypes.singleWhere((r) => r.name == 'E');
expect(e.members, ['methodE']);
}
}
test_subtypes_class_discover() async {
var aaaPackageRootPath = '$packagesRootPath/aaa';
var bbbPackageRootPath = '$packagesRootPath/bbb';
var aaaFilePath = convertPath('$aaaPackageRootPath/lib/a.dart');
var bbbFilePath = convertPath('$bbbPackageRootPath/lib/b.dart');
writeTestPackageConfig(
PackageConfigFileBuilder()
..add(name: 'aaa', rootPath: aaaPackageRootPath)
..add(name: 'bbb', rootPath: bbbPackageRootPath),
);
var tUri = 'package:test/test.dart';
var aUri = 'package:aaa/a.dart';
var bUri = 'package:bbb/b.dart';
addTestFile(r'''
import 'package:aaa/a.dart';
class T1 extends A {
void method1() {}
}
class T2 extends A {
void method2() {}
}
''');
newFile(bbbFilePath, r'''
import 'package:aaa/a.dart';
class B extends A {
void method1() {}
}
''');
newFile(aaaFilePath, r'''
class A {
void method1() {}
void method2() {}
}
''');
var aLibraryResult =
await driver.getLibraryByUri(aUri) as LibraryElementResult;
ClassElement aClass = aLibraryResult.element.getType('A')!;
// Search by 'type'.
List<SubtypeResult> subtypes =
await driver.search.subtypes(SearchedFiles(), type: aClass);
expect(subtypes, hasLength(3));
SubtypeResult t1 = subtypes.singleWhere((r) => r.name == 'T1');
SubtypeResult t2 = subtypes.singleWhere((r) => r.name == 'T2');
SubtypeResult b = subtypes.singleWhere((r) => r.name == 'B');
expect(t1.libraryUri, tUri);
expect(t1.id, '$tUri;$tUri;T1');
expect(t1.members, ['method1']);
expect(t2.libraryUri, tUri);
expect(t2.id, '$tUri;$tUri;T2');
expect(t2.members, ['method2']);
expect(b.libraryUri, bUri);
expect(b.id, '$bUri;$bUri;B');
expect(b.members, ['method1']);
}
test_subTypes_class_discover() async {
var aaaPackageRootPath = '$packagesRootPath/aaa';
var bbbPackageRootPath = '$packagesRootPath/bbb';
var cccPackageRootPath = '$packagesRootPath/ccc';
var aaaFilePath = convertPath('$aaaPackageRootPath/lib/a.dart');
var bbbFilePath = convertPath('$bbbPackageRootPath/lib/b.dart');
var cccFilePath = convertPath('$cccPackageRootPath/lib/c.dart');
writeTestPackageConfig(
PackageConfigFileBuilder()
..add(name: 'aaa', rootPath: aaaPackageRootPath)
..add(name: 'bbb', rootPath: bbbPackageRootPath),
);
addTestFile('class T implements List {}');
newFile(aaaFilePath, 'class A implements List {}');
newFile(bbbFilePath, 'class B implements List {}');
newFile(cccFilePath, 'class C implements List {}');
var coreLibResult =
await driver.getLibraryByUri('dart:core') as LibraryElementResult;
ClassElement listElement = coreLibResult.element.getType('List')!;
var searchedFiles = SearchedFiles();
var results = await driver.search.subTypes(listElement, searchedFiles);
void assertHasResult(String path, String name, {bool not = false}) {
var matcher = contains(predicate((SearchResult r) {
var element = r.enclosingElement;
return element.name == name && element.source!.fullName == path;
}));
expect(results, not ? isNot(matcher) : matcher);
}
assertHasResult(testFile.path, 'T');
assertHasResult(aaaFilePath, 'A');
assertHasResult(bbbFilePath, 'B');
assertHasResult(cccFilePath, 'C', not: true);
}
test_subtypes_class_files() async {
String pathB = convertPath('$testPackageLibPath/b.dart');
String pathC = convertPath('$testPackageLibPath/c.dart');
newFile(pathB, r'''
import 'test.dart';
class B extends A {}
''');
newFile(pathC, r'''
import 'test.dart';
class C extends A {}
class D {}
''');
await resolveTestCode('''
class A {}
''');
var a = findElement.class_('A');
List<SubtypeResult> subtypes =
await driver.search.subtypes(SearchedFiles(), type: a);
expect(subtypes, hasLength(2));
SubtypeResult b = subtypes.singleWhere((r) => r.name == 'B');
SubtypeResult c = subtypes.singleWhere((r) => r.name == 'C');
expect(b.id, endsWith('b.dart;B'));
expect(c.id, endsWith('c.dart;C'));
}
test_subtypes_enum() async {
await resolveTestCode('''
class A {}
enum E1 implements A {
v;
void methodE1() {}
}
enum E2 with A {
v;
void methodE2() {}
}
class B {}
''');
var subtypes = await driver.search.subtypes(
SearchedFiles(),
type: findElement.class_('A'),
);
expect(subtypes, hasLength(2));
var resultE1 = subtypes.singleWhere((r) => r.name == 'E1');
var resultE2 = subtypes.singleWhere((r) => r.name == 'E2');
expect(resultE1.libraryUri, testUriStr);
expect(resultE1.id, '$testUriStr;$testUriStr;E1');
expect(resultE1.members, ['methodE1']);
expect(resultE2.libraryUri, testUriStr);
expect(resultE2.id, '$testUriStr;$testUriStr;E2');
expect(resultE2.members, ['methodE2']);
}
test_subtypes_mixin_superclassConstraints() async {
await resolveTestCode('''
class A {
void methodA() {}
}
class B {
void methodB() {}
}
mixin M on A, B {
void methodA() {}
void methodM() {}
}
''');
var a = findElement.class_('A');
var b = findElement.class_('B');
{
var subtypes = await driver.search.subtypes(SearchedFiles(), type: a);
expect(subtypes, hasLength(1));
var m = subtypes.singleWhere((r) => r.name == 'M');
expect(m.libraryUri, testUriStr);
expect(m.id, '$testUriStr;$testUriStr;M');
expect(m.members, ['methodA', 'methodM']);
}
{
var subtypes = await driver.search.subtypes(SearchedFiles(), type: b);
expect(subtypes, hasLength(1));
var m = subtypes.singleWhere((r) => r.name == 'M');
expect(m.libraryUri, testUriStr);
expect(m.id, '$testUriStr;$testUriStr;M');
expect(m.members, ['methodA', 'methodM']);
}
}
test_topLevelElements() async {
await resolveTestCode('''
class A {} // A
class B = Object with A;
mixin C {}
typedef D();
f() {}
var g = null;
class NoMatchABCDEF {}
''');
var a = findElement.class_('A');
var b = findElement.class_('B');
var c = findElement.mixin('C');
var d = findElement.typeAlias('D');
var f = findElement.function('f');
var g = findElement.topVar('g');
RegExp regExp = RegExp(r'^[ABCDfg]$');
expect(await driver.search.topLevelElements(regExp),
unorderedEquals([a, b, c, d, f, g]));
}
ExpectedResult _expectId(
Element enclosingElement, SearchResultKind kind, String search,
{int? length, bool isResolved = true, bool isQualified = false}) {
int offset = findNode.offset(search);
length ??= findNode.simple(search).length;
return ExpectedResult(enclosingElement, kind, offset, length,
isResolved: isResolved, isQualified: isQualified);
}
/// Create [ExpectedResult] for a qualified and resolved match.
ExpectedResult _expectIdQ(
Element element, SearchResultKind kind, String search,
{int? length}) {
return _expectId(element, kind, search, isQualified: true, length: length);
}
/// Create [ExpectedResult] for a qualified and unresolved match.
ExpectedResult _expectIdQU(
Element element, SearchResultKind kind, String search,
{int? length}) {
return _expectId(element, kind, search,
isQualified: true, isResolved: false, length: length);
}
/// Create [ExpectedResult] for a unqualified and unresolved match.
ExpectedResult _expectIdU(
Element element, SearchResultKind kind, String search,
{int? length}) {
return _expectId(element, kind, search,
isQualified: false, isResolved: false, length: length);
}
Future<List<Element>> _findClassMembers(String name) {
var searchedFiles = SearchedFiles();
return driver.search.classMembers(name, searchedFiles);
}
Future<void> _verifyNameReferences(
String name, List<ExpectedResult> expectedMatches) async {
var searchedFiles = SearchedFiles();
List<SearchResult> results =
await driver.search.unresolvedMemberReferences(name, searchedFiles);
_assertResults(results, expectedMatches);
expect(results, hasLength(expectedMatches.length));
}
Future _verifyReferences(
Element element, List<ExpectedResult> expectedMatches) async {
var searchedFiles = SearchedFiles();
var results = await driver.search.references(element, searchedFiles);
_assertResults(results, expectedMatches);
expect(results, hasLength(expectedMatches.length));
}
static void _assertResults(
List<SearchResult> matches, List<ExpectedResult> expectedMatches) {
expect(matches, unorderedEquals(expectedMatches));
}
}
extension on List<Declaration> {
Declaration assertHas(String name, DeclarationKind kind,
{int? offset,
int? codeOffset,
int? codeLength,
String? className,
String? mixinName}) {
for (var declaration in this) {
if (declaration.name == name &&
declaration.kind == kind &&
(offset == null || declaration.offset == offset) &&
(codeOffset == null || declaration.codeOffset == codeOffset) &&
(codeLength == null || declaration.codeLength == codeLength) &&
declaration.className == className &&
declaration.mixinName == mixinName) {
return declaration;
}
}
var actual =
map((d) => '(name=${d.name}, kind=${d.kind}, offset=${d.offset}, '
'codeOffset=${d.codeOffset}, codeLength=${d.codeLength}, '
'className=${d.className}, mixinName=${d.mixinName})').join('\n');
fail('Expected to find (name=$name, kind=$kind, offset=$offset, '
'codeOffset=$codeOffset, codeLength=$codeLength) in\n$actual');
}
void assertNo(String name) {
for (var declaration in this) {
if (declaration.name == name) {
fail('Unexpected declaration $name');
}
}
}
}