blob: f1a745f0fb8ace1eb14eeac74fa60db184874818 [file] [edit]
// 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/element/element.dart';
import 'package:analyzer/file_system/file_system.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/util/performance/operation_performance.dart';
import 'package:analyzer/src/utilities/cancellation.dart';
import 'package:analyzer_testing/package_config_file_builder.dart';
import 'package:collection/collection.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../../../util/diff.dart';
import '../resolution/context_collection_resolution.dart';
import '../resolution/node_text_expectations.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(SearchTest);
defineReflectiveTests(SearchMultipleDriversTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
@reflectiveTest
class SearchMultipleDriversTest extends PubPackageResolutionTest {
@override
List<String> get collectionIncludedPaths => [
workspaceRootPath,
otherPackageRootPath,
];
AnalysisDriver get driver => driverFor(testFile);
String get otherPackageRootPath => '$workspaceRootPath/other';
test_declarations_searchesFilesOnlyOnce() async {
// Create another driver to search in to ensure we don't get dupe results.
var otherFile = newFile(convertPath('$otherPackageRootPath/main.dart'), '');
var otherDriver = driverFor(otherFile);
var results = WorkspaceSymbols();
// Search both drivers.
await FindDeclarations(
[driver, otherDriver],
results,
'',
null,
ownedFiles: analysisContextCollection.ownedFiles,
performance: OperationPerformanceImpl('<root>'),
).compute();
// Ensure only one result for an SDK class, and that the file was tracked as searched.
var declarations = results.declarations;
expect(
declarations.where((element) => element.name == 'Duration'),
hasLength(1),
);
}
}
@reflectiveTest
class SearchTest extends PubPackageResolutionTest {
final OperationPerformanceImpl performance = OperationPerformanceImpl(
'<root>',
);
late AnalysisDriver driver = driverFor(testFile);
Set<Uri>? includedLibraryUris;
String get testUriStr => 'package:test/test.dart';
void assertDeclarationsText(
WorkspaceSymbols symbols,
Map<File, String> inFiles,
String expected,
) {
var actual = _getDeclarationsText(symbols, inFiles);
if (actual != expected) {
NodeTextExpectationsCollector.add(actual);
if (NodeTextExpectationsCollector.shouldPrintFailureDetails) {
printPrettyDiff(expected, actual);
}
fail('See the difference above.');
}
}
Future<void> assertDirectSubtypeReferencesText(
InterfaceElement element,
String expected,
) async {
var results = await driver.search.directSubtypeReferences(element);
var actual = _getSearchResultsText(results);
if (actual != expected) {
NodeTextExpectationsCollector.add(actual);
if (NodeTextExpectationsCollector.shouldPrintFailureDetails) {
printPrettyDiff(expected, actual);
}
fail('See the difference above.');
}
}
Future<void> assertElementReferencesText(
Element element,
String expected,
) async {
var results = await driver.search.references(element);
var actual = _getSearchResultsText(results);
if (actual != expected) {
NodeTextExpectationsCollector.add(actual);
if (NodeTextExpectationsCollector.shouldPrintFailureDetails) {
printPrettyDiff(expected, actual);
}
fail('See the difference above.');
}
}
Future<void> assertElementsReferencesText(
Map<String, Element> elements,
String expected,
) async {
var resultsByLabel = <String, List<SearchResult>>{};
for (var entry in elements.entries) {
resultsByLabel[entry.key] = await driver.search.references(entry.value);
}
var actual = _getSearchResultsTextByLabel(resultsByLabel);
if (actual != expected) {
NodeTextExpectationsCollector.add(actual);
if (NodeTextExpectationsCollector.shouldPrintFailureDetails) {
printPrettyDiff(expected, actual);
}
fail('See the difference above.');
}
}
Future<void> assertLibraryFragmentReferencesText(
LibraryFragment fragment,
String expected,
) async {
var results = await driver.search.referencesLibraryFragment(fragment);
var actual = _getSearchResultsText2(results);
if (actual != expected) {
NodeTextExpectationsCollector.add(actual);
if (NodeTextExpectationsCollector.shouldPrintFailureDetails) {
printPrettyDiff(expected, actual);
}
fail('See the difference above.');
}
}
Future<void> assertLibraryImportReferencesText(
LibraryImport import,
String expected,
) async {
var results = await driver.search.referencesLibraryImport(import);
var actual = _getSearchResultsText2(results);
if (actual != expected) {
NodeTextExpectationsCollector.add(actual);
if (NodeTextExpectationsCollector.shouldPrintFailureDetails) {
printPrettyDiff(expected, actual);
}
fail('See the difference above.');
}
}
Future<void> assertUnresolvedMemberReferencesText(
String name,
String expected,
) async {
var results = await driver.search.unresolvedMemberReferences(name);
var actual = _getSearchResultsText(results);
if (actual != expected) {
NodeTextExpectationsCollector.add(actual);
if (NodeTextExpectationsCollector.shouldPrintFailureDetails) {
printPrettyDiff(expected, actual);
}
fail('See the difference above.');
}
}
test_classMembers_class() async {
var result = await resolveTestCode('''
class A {
test() {}
}
class B {
int test = 1;
int testTwo = 2;
main() {
int test = 3;
}
}
''');
expect(
await _findClassMembers('test'),
unorderedEquals([
result.findElement.method('test', of: 'A'),
result.findElement.field('test', of: 'B'),
]),
);
}
test_classMembers_enum() async {
var result = await resolveTestCode('''
enum E1 {
v;
void test() {}
}
enum E2 {
v;
final int test = 0;
}
''');
expect(
await _findClassMembers('test'),
unorderedEquals([
result.findElement.method('test', of: 'E1'),
result.findElement.field('test', of: 'E2'),
]),
);
}
test_classMembers_importNotDart() async {
await resolveTestCode('''
import 'not-dart.txt';
''');
expect(await _findClassMembers('test'), isEmpty);
}
test_classMembers_mixin() async {
var result = await resolveTestCode('''
mixin A {
test() {}
}
mixin B {
int test = 1;
int testTwo = 2;
main() {
int test = 3;
}
}
''');
expect(
await _findClassMembers('test'),
unorderedEquals([
result.findElement.method('test', of: 'A'),
result.findElement.field('test', of: 'B'),
]),
);
}
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 = FindDeclarations(
[driver],
results,
'',
null,
ownedFiles: analysisContextCollection.ownedFiles,
performance: performance,
).compute(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 FindDeclarations(
[driver],
results,
'',
null,
ownedFiles: analysisContextCollection.ownedFiles,
performance: performance,
).compute();
assertDeclarationsText(
results,
{testFile: 'testFile'},
r'''
testFile
CLASS C
offset: 6 1:7
codeOffset: 0 + 91
FIELD f
offset: 16 2:7
codeOffset: 12 + 5
className: C
CONSTRUCTOR new
offset: 21 3:3
codeOffset: 21 + 4
className: C
parameters: ()
CONSTRUCTOR named
offset: 30 4:5
codeOffset: 28 + 10
className: C
parameters: ()
GETTER g
offset: 49 5:11
codeOffset: 41 + 15
className: C
SETTER s
offset: 68 6:12
codeOffset: 59 + 16
className: C
parameters: (dynamic _)
METHOD m
offset: 83 7:8
codeOffset: 78 + 11
className: C
parameters: ()
''',
);
}
test_declarations_class_unnamed() async {
await resolveTestCode('''
class {
void foo() {}
}
''');
var results = WorkspaceSymbols();
await FindDeclarations(
[driver],
results,
'foo',
null,
ownedFiles: analysisContextCollection.ownedFiles,
performance: performance,
).compute();
assertDeclarationsText(
results,
{testFile: 'testFile'},
r'''
''',
);
}
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', rootFolder: getFolder(aaaPackageRootPath))
..add(name: 'bbb', rootFolder: getFolder(bbbPackageRootPath)),
);
var file_a = newFile(aaaFilePath, 'class A {}');
var file_b = newFile(bbbFilePath, 'class B {}');
var file_c = newFile(cccFilePath, 'class C {}');
await resolveTestCode('class T {}');
var results = WorkspaceSymbols();
await FindDeclarations(
[driver],
results,
'',
null,
ownedFiles: analysisContextCollection.ownedFiles,
performance: performance,
).compute();
assertDeclarationsText(
results,
{
testFile: 'testFile',
file_a: 'file_a',
file_b: 'file_b',
file_c: 'file_c',
},
r'''
testFile
CLASS T
offset: 6 1:7
codeOffset: 0 + 10
file_a
CLASS A
offset: 6 1:7
codeOffset: 0 + 10
file_b
CLASS B
offset: 6 1:7
codeOffset: 0 + 10
''',
);
}
test_declarations_enum() async {
await resolveTestCode('''
enum E {
a, bb, ccc
}
''');
var results = WorkspaceSymbols();
await FindDeclarations(
[driver],
results,
'',
null,
ownedFiles: analysisContextCollection.ownedFiles,
performance: performance,
).compute();
assertDeclarationsText(
results,
{testFile: 'testFile'},
r'''
testFile
ENUM E
offset: 5 1:6
codeOffset: 0 + 23
ENUM_CONSTANT a
offset: 11 2:3
codeOffset: 11 + 1
ENUM_CONSTANT bb
offset: 14 2:6
codeOffset: 14 + 2
ENUM_CONSTANT ccc
offset: 18 2:10
codeOffset: 18 + 3
''',
);
}
test_declarations_enum_unnamed() async {
await resolveTestCode('''
enum {
foo
}
''');
var results = WorkspaceSymbols();
await FindDeclarations(
[driver],
results,
'foo',
null,
ownedFiles: analysisContextCollection.ownedFiles,
performance: performance,
).compute();
assertDeclarationsText(
results,
{testFile: 'testFile'},
r'''
''',
);
}
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 FindDeclarations(
[driver],
results,
'',
null,
ownedFiles: analysisContextCollection.ownedFiles,
performance: performance,
).compute();
assertDeclarationsText(
results,
{testFile: 'testFile'},
r'''
testFile
EXTENSION E
offset: 10 1:11
codeOffset: 0 + 82
FIELD f
offset: 27 2:7
codeOffset: 23 + 5
GETTER g
offset: 40 3:11
codeOffset: 32 + 15
SETTER s
offset: 59 4:12
codeOffset: 50 + 16
parameters: (dynamic _)
METHOD m
offset: 74 5:8
codeOffset: 69 + 11
parameters: ()
''',
);
}
test_declarations_extensionType() async {
await resolveTestCode('''
extension type E(int it) {
int get g => 0;
void set s(_) {}
void m() {}
}
''');
var results = WorkspaceSymbols();
await FindDeclarations(
[driver],
results,
'',
null,
ownedFiles: analysisContextCollection.ownedFiles,
performance: performance,
).compute();
assertDeclarationsText(
results,
{testFile: 'testFile'},
r'''
testFile
EXTENSION_TYPE E
offset: 15 1:16
codeOffset: 0 + 79
CONSTRUCTOR new
offset: 15 1:16
codeOffset: 15 + 9
className: E
parameters: (int it)
GETTER g
offset: 37 2:11
codeOffset: 29 + 15
className: E
SETTER s
offset: 56 3:12
codeOffset: 47 + 16
className: E
parameters: (dynamic _)
METHOD m
offset: 71 4:8
codeOffset: 66 + 11
className: E
parameters: ()
''',
);
}
test_declarations_extensionType_unnamed() async {
await resolveTestCode('''
extension type (int foo) {}
''');
var results = WorkspaceSymbols();
await FindDeclarations(
[driver],
results,
'foo',
null,
ownedFiles: analysisContextCollection.ownedFiles,
performance: performance,
).compute();
assertDeclarationsText(
results,
{testFile: 'testFile'},
r'''
''',
);
}
test_declarations_fuzzyMatch() async {
await resolveTestCode('''
class A {}
class B {}
class C {}
class D {}
''');
var results = WorkspaceSymbols();
await FindDeclarations(
[driver],
results,
'A',
null,
ownedFiles: analysisContextCollection.ownedFiles,
performance: performance,
).compute();
assertDeclarationsText(
results,
{testFile: 'testFile'},
r'''
testFile
CLASS A
offset: 6 1:7
codeOffset: 0 + 10
''',
);
}
test_declarations_maxResults() async {
await resolveTestCode('''
class A {}
class B {}
class C {}
''');
var results = WorkspaceSymbols();
await FindDeclarations(
[driver],
results,
'',
2,
ownedFiles: analysisContextCollection.ownedFiles,
performance: performance,
).compute();
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 FindDeclarations(
[driver],
results,
'',
null,
ownedFiles: analysisContextCollection.ownedFiles,
performance: performance,
).compute();
assertDeclarationsText(
results,
{testFile: 'testFile'},
r'''
testFile
MIXIN M
offset: 6 1:7
codeOffset: 0 + 71
FIELD f
offset: 16 2:7
codeOffset: 12 + 5
mixinName: M
GETTER g
offset: 29 3:11
codeOffset: 21 + 15
mixinName: M
SETTER s
offset: 48 4:12
codeOffset: 39 + 16
mixinName: M
parameters: (dynamic _)
METHOD m
offset: 63 5:8
codeOffset: 58 + 11
mixinName: M
parameters: ()
''',
);
}
test_declarations_mixin_unnamed() async {
await resolveTestCode('''
mixin {
void foo() {}
}
''');
var results = WorkspaceSymbols();
await FindDeclarations(
[driver],
results,
'foo',
null,
ownedFiles: analysisContextCollection.ownedFiles,
performance: performance,
).compute();
assertDeclarationsText(
results,
{testFile: 'testFile'},
r'''
''',
);
}
test_declarations_onlyForFile() async {
newFile('$testPackageLibPath/a.dart', 'class A {}');
var b = newFile('$testPackageLibPath/b.dart', 'class B {}');
var results = WorkspaceSymbols();
await FindDeclarations(
[driver],
results,
'',
null,
onlyForFile: b.path,
ownedFiles: analysisContextCollection.ownedFiles,
performance: performance,
).compute();
expect(results.files, [b.path]);
assertDeclarationsText(
results,
{testFile: 'testFile', b: 'file_b'},
r'''
file_b
CLASS B
offset: 6 1:7
codeOffset: 0 + 10
''',
);
}
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 FindDeclarations(
[driver],
results,
'',
null,
ownedFiles: analysisContextCollection.ownedFiles,
performance: performance,
).compute();
assertDeclarationsText(
results,
{testFile: 'testFile'},
r'''
testFile
CLASS C
offset: 6 1:7
codeOffset: 0 + 58
GETTER g
offset: 20 2:11
codeOffset: 12 + 15
className: C
METHOD m
offset: 35 3:8
codeOffset: 30 + 26
className: C
parameters: (int a, double b)
FUNCTION f
offset: 64 5:6
codeOffset: 59 + 27
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 FindDeclarations(
[driver],
results,
'',
null,
ownedFiles: analysisContextCollection.ownedFiles,
performance: performance,
).compute();
assertDeclarationsText(
results,
{testFile: 'testFile'},
r'''
testFile
FUNCTION f1
offset: 5 1:6
codeOffset: 0 + 35
parameters: (bool Function(int, String) a)
FUNCTION f2
offset: 41 2:6
codeOffset: 36 + 19
parameters: (dynamic Function(dynamic, dynamic) a)
FUNCTION f3
offset: 61 3:6
codeOffset: 56 + 44
parameters: (bool Function(int, String) c)
FUNCTION f4
offset: 106 4:6
codeOffset: 101 + 40
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 FindDeclarations(
[driver],
results,
'',
null,
ownedFiles: analysisContextCollection.ownedFiles,
performance: performance,
).compute();
assertDeclarationsText(
results,
{testFile: 'testFile'},
r'''
testFile
CLASS A
offset: 6 1:7
codeOffset: 0 + 133
METHOD m1
offset: 24 2:8
codeOffset: 19 + 30
className: A
parameters: (Map<int, String> a)
METHOD m2
offset: 57 3:8
codeOffset: 52 + 26
className: A
parameters: (Map<T, U> a)
METHOD m3
offset: 86 4:8
codeOffset: 81 + 50
className: A
parameters: (Map<Map<T2, U2>, Map<U1, T>> a)
''',
);
}
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 FindDeclarations(
[driver],
results,
'',
null,
ownedFiles: analysisContextCollection.ownedFiles,
performance: performance,
).compute();
assertDeclarationsText(
results,
{testFile: 'testFile'},
r'''
testFile
GETTER g
offset: 8 1:9
codeOffset: 0 + 15
SETTER s
offset: 25 2:10
codeOffset: 16 + 16
parameters: (dynamic _)
FUNCTION f
offset: 38 3:6
codeOffset: 33 + 16
parameters: (int p)
VARIABLE v
offset: 54 4:5
codeOffset: 50 + 5
TYPE_ALIAS tf1
offset: 70 5:14
codeOffset: 57 + 19
TYPE_ALIAS tf2
offset: 85 6:9
codeOffset: 77 + 45
''',
);
}
test_directSubtypeReferences_class_discover2() async {
var aaaPackageRootPath = '$packagesRootPath/aaa';
var bbbPackageRootPath = '$packagesRootPath/bbb';
var cccPackageRootPath = '$packagesRootPath/ccc';
writeTestPackageConfig(
PackageConfigFileBuilder()
..add(name: 'aaa', rootFolder: getFolder(aaaPackageRootPath))
..add(name: 'bbb', rootFolder: getFolder(bbbPackageRootPath)),
);
addTestFile('class T implements List {}');
newFile('$aaaPackageRootPath/lib/a.dart', r'''
class A implements List {}
''');
newFile('$bbbPackageRootPath/lib/b.dart', r'''
class B implements List {}
''');
newFile('$cccPackageRootPath/lib/c.dart', r'''
class C implements List {}
''');
var coreLibResult =
await driver.getLibraryByUri('dart:core') as LibraryElementResult;
var listElement = coreLibResult.element.getClass('List')!;
var results = await driver.search.directSubtypeReferences(listElement);
void assertHasResult(String uriStr, String name, {bool not = false}) {
var matcher = contains(
predicate((SearchResult r) {
var element = r.enclosingFragment.element;
return element.library!.uri.toString() == uriStr &&
element.name == name;
}),
);
expect(results, not ? isNot(matcher) : matcher);
}
assertHasResult('package:test/test.dart', 'T');
assertHasResult('package:aaa/a.dart', 'A');
assertHasResult('package:bbb/b.dart', 'B');
assertHasResult('package:ccc/c.dart', 'C', not: true);
}
test_directSubtypesWithMembers_class() async {
var result = 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 = result.findElement.class_('A');
// Search by 'type'.
var directSubtypes = await driver.search.directSubtypesWithMembersOfType(a);
expect(directSubtypes, hasLength(3));
DirectSubtypeWithMembers b = directSubtypes.singleWhere(
(r) => r.name == 'B',
);
DirectSubtypeWithMembers c = directSubtypes.singleWhere(
(r) => r.name == 'C',
);
DirectSubtypeWithMembers d = directSubtypes.singleWhere(
(r) => r.name == 'D',
);
expect(b.library.resource, testFile);
expect(b.id, '${testFile.path};${testFile.path};B');
expect(b.members, ['methodB']);
expect(c.library.resource, testFile);
expect(c.id, '${testFile.path};${testFile.path};C');
expect(c.members, ['methodC']);
expect(d.library.resource, testFile);
expect(d.id, '${testFile.path};${testFile.path};D');
expect(d.members, ['methodD']);
// Search by 'id'.
{
var directSubtypes = await driver.search
.directSubtypesWithMembersOfSubtype(b);
expect(directSubtypes, hasLength(1));
DirectSubtypeWithMembers e = directSubtypes.singleWhere(
(r) => r.name == 'E',
);
expect(e.members, ['methodE']);
}
}
test_directSubtypesWithMembers_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', rootFolder: getFolder(aaaPackageRootPath))
..add(name: 'bbb', rootFolder: getFolder(bbbPackageRootPath)),
);
var aUri = 'package:aaa/a.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;
var aClass = aLibraryResult.element.getClass('A')!;
// Search by 'type'.
var directSubtypes = await driver.search.directSubtypesWithMembersOfType(
aClass,
);
expect(directSubtypes, hasLength(3));
DirectSubtypeWithMembers t1 = directSubtypes.singleWhere(
(r) => r.name == 'T1',
);
DirectSubtypeWithMembers t2 = directSubtypes.singleWhere(
(r) => r.name == 'T2',
);
DirectSubtypeWithMembers b = directSubtypes.singleWhere(
(r) => r.name == 'B',
);
expect(t1.library.resource, testFile);
expect(t1.id, '${testFile.path};${testFile.path};T1');
expect(t1.members, ['method1']);
expect(t2.library.resource, testFile);
expect(t2.id, '${testFile.path};${testFile.path};T2');
expect(t2.members, ['method2']);
expect(b.library.resource, getFile(bbbFilePath));
expect(b.id, '$bbbFilePath;$bbbFilePath;B');
expect(b.members, ['method1']);
}
test_directSubtypesWithMembers_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 {}
''');
var result = await resolveTestCode('''
class A {}
''');
var a = result.findElement.class_('A');
var directSubtypes = await driver.search.directSubtypesWithMembersOfType(a);
expect(directSubtypes, hasLength(2));
DirectSubtypeWithMembers b = directSubtypes.singleWhere(
(r) => r.name == 'B',
);
DirectSubtypeWithMembers c = directSubtypes.singleWhere(
(r) => r.name == 'C',
);
expect(b.id, endsWith('b.dart;B'));
expect(c.id, endsWith('c.dart;C'));
}
test_directSubtypesWithMembers_class_missingName() async {
var result = await resolveTestCode('''
class {}
''');
var a = result.findElement.libraryElement.classes.single;
var directSubtypes = await driver.search.directSubtypesWithMembersOfType(a);
expect(directSubtypes, isEmpty);
}
test_directSubtypesWithMembers_enum() async {
var result = await resolveTestCode('''
class A {}
enum E1 implements A {
v;
void methodE1() {}
}
enum E2 with A {
v;
void methodE2() {}
}
class B {}
''');
var directSubtypes = await driver.search.directSubtypesWithMembersOfType(
result.findElement.class_('A'),
);
expect(directSubtypes, hasLength(2));
var resultE1 = directSubtypes.singleWhere((r) => r.name == 'E1');
var resultE2 = directSubtypes.singleWhere((r) => r.name == 'E2');
expect(resultE1.library.resource, testFile);
expect(resultE1.id, '${testFile.path};${testFile.path};E1');
expect(resultE1.members, ['methodE1']);
expect(resultE2.library.resource, testFile);
expect(resultE2.id, '${testFile.path};${testFile.path};E2');
expect(resultE2.members, ['methodE2']);
}
test_directSubtypesWithMembers_extensionType() async {
var result = await resolveTestCode('''
class A {}
extension type E1(A it) implements A {
void methodE1() {}
}
extension type E2(A it) implements A {
void methodE2() {}
}
''');
var directSubtypes = await driver.search.directSubtypesWithMembersOfType(
result.findElement.class_('A'),
);
expect(directSubtypes, hasLength(2));
var resultE1 = directSubtypes.singleWhere((r) => r.name == 'E1');
var resultE2 = directSubtypes.singleWhere((r) => r.name == 'E2');
expect(resultE1.library.resource, testFile);
expect(resultE1.id, '${testFile.path};${testFile.path};E1');
expect(resultE1.members, ['methodE1']);
expect(resultE2.library.resource, testFile);
expect(resultE2.id, '${testFile.path};${testFile.path};E2');
expect(resultE2.members, ['methodE2']);
}
test_directSubtypesWithMembers_extensionType2() async {
var result = await resolveTestCode('''
extension type A(int it) {}
extension type B(int it) implements A {
void methodB() {}
}
''');
var directSubtypes = await driver.search.directSubtypesWithMembersOfType(
result.findElement.extensionType('A'),
);
expect(directSubtypes, hasLength(1));
var B = directSubtypes.singleWhere((r) => r.name == 'B');
expect(B.library.resource, testFile);
expect(B.id, '${testFile.path};${testFile.path};B');
expect(B.members, ['methodB']);
}
test_directSubtypesWithMembers_mixin_superclassConstraints() async {
var result = await resolveTestCode('''
class A {
void methodA() {}
}
class B {
void methodB() {}
}
mixin M on A, B {
void methodA() {}
void methodM() {}
}
''');
var a = result.findElement.class_('A');
var b = result.findElement.class_('B');
{
var directSubtypes = await driver.search.directSubtypesWithMembersOfType(
a,
);
expect(directSubtypes, hasLength(1));
var m = directSubtypes.singleWhere((r) => r.name == 'M');
expect(m.library.resource, testFile);
expect(m.id, '${testFile.path};${testFile.path};M');
expect(m.members, ['methodA', 'methodM']);
}
{
var directSubtypes = await driver.search.directSubtypesWithMembersOfType(
b,
);
expect(directSubtypes, hasLength(1));
var m = directSubtypes.singleWhere((r) => r.name == 'M');
expect(m.library.resource, testFile);
expect(m.id, '${testFile.path};${testFile.path};M');
expect(m.members, ['methodA', 'methodM']);
}
}
test_issue49951_references_dontAddToKnown_unrelated() async {
var myRoot = newFolder('$workspaceRootPath/packages/my');
var myFile = newFile('${myRoot.path}/lib/my.dart', r'''
class A {}
''');
// Configure `package:my`.
writePackageConfig(
myRoot.path,
PackageConfigFileBuilder()..add(name: 'my', rootFolder: myRoot),
);
var mySession = contextFor(myFile).currentSession;
var libraryElementResult = await mySession.getLibraryByUri(
'package:my/my.dart',
);
libraryElementResult as LibraryElementResult;
var A = libraryElementResult.element.getClass('A')!;
var testDriver = driverFor(testFile);
// No references, but this is not the most important.
var references = await testDriver.search.references(A);
expect(references, isEmpty);
// We should not add the file to known files. It is not in the
// `package:test` itself, and not in a package from its package config.
// So, it is absolutely unrelated to `package:test`.
for (var knowFile in testDriver.fsState.knownFiles) {
if (knowFile.path == myFile.path) {
fail('The file should not be added.');
}
}
}
test_sameNameDeclarations_class() async {
var result = await resolveTestCode('''
class Foo {
Foo.bar() {
bar();
}
void bar() => Foo.bar();
}
''');
var results = WorkspaceSymbols();
await FindDeclarations(
[driver],
results,
'',
null,
ownedFiles: analysisContextCollection.ownedFiles,
performance: performance,
).compute();
assertDeclarationsText(
results,
{testFile: 'testFile'},
r'''
testFile
CLASS Foo
offset: 6 1:7
codeOffset: 0 + 69
CONSTRUCTOR bar
offset: 18 2:7
codeOffset: 14 + 26
className: Foo
parameters: ()
METHOD bar
offset: 48 5:8
codeOffset: 43 + 24
className: Foo
parameters: ()
''',
);
Element element = result.findElement.constructor('bar');
await assertElementReferencesText(element, '''
class Foo {
Foo.bar() {
bar();
}
void bar() => Foo.bar();
^^^^ INVOCATION qualified
}
''');
element = result.findElement.method('bar');
await assertElementReferencesText(element, r'''
class Foo {
Foo.bar() {
bar();
^^^ INVOCATION
}
void bar() => Foo.bar();
}
''');
}
test_scenario_ClassElement_hierarchy_class_extends() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
class A {}
class B extends A {}
class B_q extends p.A {}
''');
var element = result.findElement.class_('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
class A {}
class B extends A {}
^ REFERENCE
class B_q extends p.A {}
^ REFERENCE qualified
''');
await assertDirectSubtypeReferencesText(element, r'''
import 'test.dart' as p;
class A {}
class B extends A {}
^ REFERENCE_IN_EXTENDS_CLAUSE
class B_q extends p.A {}
^ REFERENCE_IN_EXTENDS_CLAUSE qualified
''');
}
test_scenario_ClassElement_hierarchy_class_extends_implicitObject() async {
var result = await resolveTestCode('''
class A {}
''');
includedLibraryUris = {Uri.parse(testUriStr)};
var element = result.typeProvider.objectType.element;
await assertElementReferencesText(element, r'''''');
await assertDirectSubtypeReferencesText(element, '');
}
test_scenario_ClassElement_hierarchy_class_implements() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
class A {}
class B implements A {}
class B_q implements p.A {}
''');
var element = result.findElement.class_('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
class A {}
class B implements A {}
^ REFERENCE
class B_q implements p.A {}
^ REFERENCE qualified
''');
await assertDirectSubtypeReferencesText(element, r'''
import 'test.dart' as p;
class A {}
class B implements A {}
^ REFERENCE_IN_IMPLEMENTS_CLAUSE
class B_q implements p.A {}
^ REFERENCE_IN_IMPLEMENTS_CLAUSE qualified
''');
}
test_scenario_ClassElement_hierarchy_class_with() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
class A {}
class D extends Object with A {}
class D_q extends Object with p.A {}
''');
var element = result.findElement.class_('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
class A {}
class D extends Object with A {}
^ REFERENCE
class D_q extends Object with p.A {}
^ REFERENCE qualified
''');
await assertDirectSubtypeReferencesText(element, r'''
import 'test.dart' as p;
class A {}
class D extends Object with A {}
^ REFERENCE_IN_WITH_CLAUSE
class D_q extends Object with p.A {}
^ REFERENCE_IN_WITH_CLAUSE qualified
''');
}
test_scenario_ClassElement_hierarchy_classTypeAlias_with() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
class A {}
class D2 = Object with A;
class D2_q = Object with p.A;
''');
var element = result.findElement.class_('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
class A {}
class D2 = Object with A;
^ REFERENCE
class D2_q = Object with p.A;
^ REFERENCE qualified
''');
await assertDirectSubtypeReferencesText(element, r'''
import 'test.dart' as p;
class A {}
class D2 = Object with A;
^ REFERENCE_IN_WITH_CLAUSE
class D2_q = Object with p.A;
^ REFERENCE_IN_WITH_CLAUSE qualified
''');
}
test_scenario_ClassElement_hierarchy_enum_implements() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
class A {}
enum E implements A { v }
enum E_q implements p.A { v }
''');
var element = result.findElement.class_('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
class A {}
enum E implements A { v }
^ REFERENCE
enum E_q implements p.A { v }
^ REFERENCE qualified
''');
await assertDirectSubtypeReferencesText(element, r'''
import 'test.dart' as p;
class A {}
enum E implements A { v }
^ REFERENCE_IN_IMPLEMENTS_CLAUSE
enum E_q implements p.A { v }
^ REFERENCE_IN_IMPLEMENTS_CLAUSE qualified
''');
}
test_scenario_ClassElement_hierarchy_extensionType_implements() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
class A {}
extension type E(A it) implements A {}
extension type E_q(A it) implements p.A {}
''');
var element = result.findElement.class_('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
class A {}
extension type E(A it) implements A {}
^ REFERENCE
^ REFERENCE
extension type E_q(A it) implements p.A {}
^ REFERENCE
^ REFERENCE qualified
''');
await assertDirectSubtypeReferencesText(element, r'''
import 'test.dart' as p;
class A {}
extension type E(A it) implements A {}
^ REFERENCE_IN_IMPLEMENTS_CLAUSE
extension type E_q(A it) implements p.A {}
^ REFERENCE_IN_IMPLEMENTS_CLAUSE qualified
''');
}
test_scenario_ClassElement_hierarchy_mixin_implements() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
class A {}
mixin M implements A {}
mixin M_q implements p.A {}
''');
var element = result.findElement.class_('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
class A {}
mixin M implements A {}
^ REFERENCE
mixin M_q implements p.A {}
^ REFERENCE qualified
''');
await assertDirectSubtypeReferencesText(element, r'''
import 'test.dart' as p;
class A {}
mixin M implements A {}
^ REFERENCE_IN_IMPLEMENTS_CLAUSE
mixin M_q implements p.A {}
^ REFERENCE_IN_IMPLEMENTS_CLAUSE qualified
''');
}
test_scenario_ClassElement_hierarchy_mixin_on() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
class A {}
mixin M2 on A {}
mixin M2_q on p.A {}
''');
var element = result.findElement.class_('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
class A {}
mixin M2 on A {}
^ REFERENCE
mixin M2_q on p.A {}
^ REFERENCE qualified
''');
await assertDirectSubtypeReferencesText(element, r'''
import 'test.dart' as p;
class A {}
mixin M2 on A {}
^ REFERENCE_IN_ON_CLAUSE
mixin M2_q on p.A {}
^ REFERENCE_IN_ON_CLAUSE qualified
''');
}
test_scenario_ExtensionTypeElement_hierarchy_extensionType_implements() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
extension type A(int it) {}
extension type B(int it) implements A {}
extension type B_q(int it) implements p.A {}
''');
var element = result.findElement.extensionType('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
extension type A(int it) {}
extension type B(int it) implements A {}
^ REFERENCE
extension type B_q(int it) implements p.A {}
^ REFERENCE qualified
''');
await assertDirectSubtypeReferencesText(element, r'''
import 'test.dart' as p;
extension type A(int it) {}
extension type B(int it) implements A {}
^ REFERENCE_IN_IMPLEMENTS_CLAUSE
extension type B_q(int it) implements p.A {}
^ REFERENCE_IN_IMPLEMENTS_CLAUSE qualified
''');
}
test_scenario_MixinElement_hierarchy_class_implements() async {
var result = await resolveTestCode(r'''
mixin A {}
class B implements A {}
''');
var element = result.findElement.mixin('A');
await assertElementReferencesText(element, r'''
mixin A {}
class B implements A {}
^ REFERENCE
''');
await assertDirectSubtypeReferencesText(element, r'''
mixin A {}
class B implements A {}
^ REFERENCE_IN_IMPLEMENTS_CLAUSE
''');
}
test_scenario_MixinElement_hierarchy_class_with() async {
var result = await resolveTestCode(r'''
mixin A {}
class B extends Object with A {}
''');
var element = result.findElement.mixin('A');
await assertElementReferencesText(element, r'''
mixin A {}
class B extends Object with A {}
^ REFERENCE
''');
await assertDirectSubtypeReferencesText(element, r'''
mixin A {}
class B extends Object with A {}
^ REFERENCE_IN_WITH_CLAUSE
''');
}
test_scenario_MixinElement_hierarchy_classTypeAlias_with() async {
var result = await resolveTestCode(r'''
mixin A {}
class B = Object with A;
''');
var element = result.findElement.mixin('A');
await assertElementReferencesText(element, r'''
mixin A {}
class B = Object with A;
^ REFERENCE
''');
await assertDirectSubtypeReferencesText(element, r'''
mixin A {}
class B = Object with A;
^ REFERENCE_IN_WITH_CLAUSE
''');
}
test_scenario_MixinElement_hierarchy_enum_implements() async {
var result = await resolveTestCode(r'''
mixin A {}
enum E implements A {
v
}
''');
var element = result.findElement.mixin('A');
await assertElementReferencesText(element, r'''
mixin A {}
enum E implements A {
^ REFERENCE
v
}
''');
await assertDirectSubtypeReferencesText(element, r'''
mixin A {}
enum E implements A {
^ REFERENCE_IN_IMPLEMENTS_CLAUSE
v
}
''');
}
test_scenario_MixinElement_hierarchy_enum_with() async {
var result = await resolveTestCode(r'''
mixin A {}
enum E with A {
v
}
''');
var element = result.findElement.mixin('A');
await assertElementReferencesText(element, r'''
mixin A {}
enum E with A {
^ REFERENCE
v
}
''');
await assertDirectSubtypeReferencesText(element, r'''
mixin A {}
enum E with A {
^ REFERENCE_IN_WITH_CLAUSE
v
}
''');
}
test_scenario_MixinElement_hierarchy_extensionType_implements() async {
var result = await resolveTestCode(r'''
mixin A {}
extension type E(A it) implements A {}
''');
var element = result.findElement.mixin('A');
await assertElementReferencesText(element, r'''
mixin A {}
extension type E(A it) implements A {}
^ REFERENCE
^ REFERENCE
''');
await assertDirectSubtypeReferencesText(element, r'''
mixin A {}
extension type E(A it) implements A {}
^ REFERENCE_IN_IMPLEMENTS_CLAUSE
''');
}
test_scenario_MixinElement_hierarchy_mixin_implements() async {
var result = await resolveTestCode(r'''
mixin A {}
mixin M implements A {}
''');
var element = result.findElement.mixin('A');
await assertElementReferencesText(element, r'''
mixin A {}
mixin M implements A {}
^ REFERENCE
''');
await assertDirectSubtypeReferencesText(element, r'''
mixin A {}
mixin M implements A {}
^ REFERENCE_IN_IMPLEMENTS_CLAUSE
''');
}
test_scenario_MixinElement_hierarchy_mixin_on() async {
var result = await resolveTestCode(r'''
mixin A {}
mixin M on A {}
''');
var element = result.findElement.mixin('A');
await assertElementReferencesText(element, r'''
mixin A {}
mixin M on A {}
^ REFERENCE
''');
await assertDirectSubtypeReferencesText(element, r'''
mixin A {}
mixin M on A {}
^ REFERENCE_IN_ON_CLAUSE
''');
}
test_scenario_TypeAliasElement_modern_hierarchy_class_extends() async {
var result = await resolveTestCode('''
class A<T> {}
typedef B = A<int>;
class C extends B {}
''');
var element = result.findElement.typeAlias('B');
await assertElementReferencesText(element, r'''
class A<T> {}
typedef B = A<int>;
class C extends B {}
^ REFERENCE
''');
var aliasedClass = result.findElement.class_('A');
// TODO(scheglov): Subtypes for the aliased class should be reported.
await assertDirectSubtypeReferencesText(aliasedClass, r'''
''');
}
test_scenario_TypeAliasElement_modern_hierarchy_class_implements() async {
var result = await resolveTestCode('''
class A<T> {}
typedef B = A<int>;
class C implements B {}
''');
var element = result.findElement.typeAlias('B');
await assertElementReferencesText(element, r'''
class A<T> {}
typedef B = A<int>;
class C implements B {}
^ REFERENCE
''');
var aliasedClass = result.findElement.class_('A');
// TODO(scheglov): Subtypes for the aliased class should be reported.
await assertDirectSubtypeReferencesText(aliasedClass, r'''
''');
}
test_scenario_TypeAliasElement_modern_hierarchy_class_with() async {
var result = await resolveTestCode('''
class A<T> {}
typedef B = A<int>;
class C extends Object with B {}
''');
var element = result.findElement.typeAlias('B');
await assertElementReferencesText(element, r'''
class A<T> {}
typedef B = A<int>;
class C extends Object with B {}
^ REFERENCE
''');
var aliasedClass = result.findElement.class_('A');
// TODO(scheglov): Subtypes for the aliased class should be reported.
await assertDirectSubtypeReferencesText(aliasedClass, r'''
''');
}
test_searchMemberReferences_qualified_resolved() async {
await resolveTestCode('''
class C {
var test;
}
main(C c) {
c.test;
c.test = 1;
c.test += 2;
c.test();
}
''');
await assertUnresolvedMemberReferencesText('test', '');
}
test_searchMemberReferences_qualified_unresolved() async {
await resolveTestCode('''
void f(p) {
p.test;
p.test = 1;
p.test += 2;
p.test();
}
''');
await assertUnresolvedMemberReferencesText('test', r'''
void f(p) {
p.test;
^^^^ READ qualified unresolved
p.test = 1;
^^^^ WRITE qualified unresolved
p.test += 2;
^^^^ READ_WRITE qualified unresolved
p.test();
^^^^ INVOCATION qualified unresolved
}
''');
}
test_searchMemberReferences_unqualified_resolved() async {
await resolveTestCode('''
class C {
var test;
main() {
test;
test = 1;
test += 2;
test();
}
}
''');
await assertUnresolvedMemberReferencesText('test', '');
}
test_searchMemberReferences_unqualified_unresolved() async {
await resolveTestCode('''
class C {
main() {
print(test);
test = 1;
test += 2;
test();
}
}
''');
await assertUnresolvedMemberReferencesText('test', r'''
class C {
main() {
print(test);
^^^^ READ unresolved
test = 1;
^^^^ WRITE unresolved
test += 2;
^^^^ READ_WRITE unresolved
test();
^^^^ INVOCATION unresolved
}
}
''');
}
test_searchReferences_analyzer_diagnosticCode() async {
var analyzerPackageRootPath = '$workspaceRootPath/pkg/analyzer';
writePackageConfig(
analyzerPackageRootPath,
PackageConfigFileBuilder()
..add(name: 'analyzer', rootFolder: getFolder(analyzerPackageRootPath)),
);
var analyzerPackageLibPath = '$analyzerPackageRootPath/lib';
var analyzerPackageTestPath = '$analyzerPackageRootPath/test';
var diagnosticFile = newFile(
'$analyzerPackageLibPath/src/diagnostic/diagnostic.dart',
r'''
const myDiagnosticCode = 0;
''',
);
var diagnosticLibrary = await libraryElementForFile(diagnosticFile);
var element = diagnosticLibrary.topLevelVariables.firstWhere(
(v) => v.name == 'myDiagnosticCode',
);
var analyzerTestFile = newFile('$analyzerPackageTestPath/test.dart', r'''
void f() {
'// [diag.myDiagnosticCode]';
}
''');
driver = driverFor(analyzerTestFile);
driver.addFile2(analyzerTestFile);
await driver.applyPendingFileChanges();
await assertElementReferencesText(element, r'''
test.dart
---------
void f() {
'// [diag.myDiagnosticCode]';
^^^^^^^^^^^^^^^^ REFERENCE qualified
}
''');
}
@FailingTest() // TODO(scheglov): implement augmentation
test_searchReferences_class_constructor_declaredInAugmentation() async {
newFile('$testPackageLibPath/a.dart', r'''
part of 'test.dart';
augment class A {
A.named();
}
''');
var result = await resolveTestCode('''
part 'a.dart';
class A {
void foo() {
A.named();
}
}
void f() {
A.named();
}
''');
var A = result.findElement.class_('A');
var element = A.constructors.single;
expect(element.name, 'named');
await assertElementReferencesText(element, r'''
<testLibraryFragment>::@class::A::@method::foo
46 5:6 |.named| INVOCATION qualified
<testLibraryFragment>::@function::f
77 10:4 |.named| INVOCATION qualified
''');
}
test_searchReferences_class_getter_in_objectPattern() async {
var result = await resolveTestCode('''
void f(Object? x) {
if (x case A(foo: 0)) {}
if (x case A(: var foo)) {}
}
class A {
int get foo => 0;
}
''');
var element = result.findElement.getter('foo');
await assertElementReferencesText(element, r'''
void f(Object? x) {
if (x case A(foo: 0)) {}
^^^ REFERENCE_IN_PATTERN_FIELD qualified
if (x case A(: var foo)) {}
^0 REFERENCE_IN_PATTERN_FIELD qualified
}
class A {
int get foo => 0;
}
''');
}
test_searchReferences_class_method_in_objectPattern() async {
var result = await resolveTestCode('''
void f(Object? x) {
if (x case A(foo: _)) {}
if (x case A(: var foo)) {}
}
class A {
void foo() {}
}
''');
var element = result.findElement.method('foo');
await assertElementReferencesText(element, r'''
void f(Object? x) {
if (x case A(foo: _)) {}
^^^ REFERENCE qualified
if (x case A(: var foo)) {}
^0 REFERENCE qualified
}
class A {
void foo() {}
}
''');
}
test_searchReferences_class_method_in_objectPattern_otherFile() async {
String other = convertPath('$testPackageLibPath/other.dart');
String otherCode = '''
import 'test.dart';
void f(Object? x) {
if (x case A(foo: _)) {}
if (x case A(: var foo)) {}
}
''';
newFile(other, otherCode);
var result = await resolveTestCode('''
class A {
void foo() {}
}
''');
var element = result.findElement.method('foo');
await assertElementReferencesText(element, r'''
package:test/other.dart
-----------------------
import 'test.dart';
void f(Object? x) {
if (x case A(foo: _)) {}
^^^ REFERENCE qualified
if (x case A(: var foo)) {}
^0 REFERENCE qualified
}
''');
}
test_searchReferences_ClassElement_enum() async {
var result = await resolveTestCode('''
enum MyEnum {a}
main(MyEnum p) {
MyEnum v;
MyEnum.a;
}
''');
var element = result.findElement.enum_('MyEnum');
await assertElementReferencesText(element, r'''
enum MyEnum {a}
main(MyEnum p) {
^^^^^^ REFERENCE
MyEnum v;
^^^^^^ REFERENCE
MyEnum.a;
^^^^^^ REFERENCE
}
''');
}
test_searchReferences_ClassElement_mixin() async {
var result = await resolveTestCode('''
mixin A {}
class B extends Object with A {}
''');
var element = result.findElement.mixin('A');
await assertElementReferencesText(element, r'''
mixin A {}
class B extends Object with A {}
^ REFERENCE
''');
}
test_searchReferences_ClassElement_reference_annotation() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
class A {
const A();
const A.named();
static const int myConstant = 0;
}
@A()
@p.A()
@A.named()
@p.A.named()
@A.myConstant
@p.A.myConstant
void f() {}
''');
var element = result.findElement.class_('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
class A {
const A();
^ REFERENCE
const A.named();
^ REFERENCE
static const int myConstant = 0;
}
@A()
^ REFERENCE
@p.A()
^ REFERENCE qualified
@A.named()
^ REFERENCE
@p.A.named()
^ REFERENCE qualified
@A.myConstant
^ REFERENCE
@p.A.myConstant
^ REFERENCE qualified
void f() {}
''');
}
test_searchReferences_ClassElement_reference_annotation_typeArgument() async {
var result = await resolveTestCode('''
class A<T> {
const A();
}
class B {}
@A<B>()
void f() {}
''');
var element = result.findElement.class_('B');
await assertElementReferencesText(element, r'''
class A<T> {
const A();
}
class B {}
@A<B>()
^ REFERENCE
void f() {}
''');
}
test_searchReferences_ClassElement_reference_classTypeAlias() async {
var result = await resolveTestCode(r'''
class A {}
class B = Object with A;
void f(B p) {
B v;
}
''');
var element = result.findElement.class_('B');
await assertElementReferencesText(element, r'''
class A {}
class B = Object with A;
void f(B p) {
^ REFERENCE
B v;
^ REFERENCE
}
''');
}
test_searchReferences_ClassElement_reference_comment() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
class A {}
/// [A] and [p.A].
void f() {}
''');
var element = result.findElement.class_('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
class A {}
/// [A] and [p.A].
^ REFERENCE
^ REFERENCE qualified
void f() {}
''');
}
test_searchReferences_ClassElement_reference_definedInSdk() async {
var result = await resolveTestCode('''
import 'dart:math';
Random v1;
Random v2;
''');
includedLibraryUris = {Uri.parse(testUriStr)};
var element = result.findElement.importFind('dart:math').class_('Random');
await assertElementReferencesText(element, r'''
import 'dart:math';
Random v1;
^^^^^^ REFERENCE
Random v2;
^^^^^^ REFERENCE
''');
}
test_searchReferences_ClassElement_reference_definedInside() async {
var result = await resolveTestCode('''
class A {};
main(A p) {
A v;
}
class B1 extends A {}
class B2 implements A {}
class B3 extends Object with A {}
List<A> v2 = null;
''');
var element = result.findElement.class_('A');
await assertElementReferencesText(element, r'''
class A {};
main(A p) {
^ REFERENCE
A v;
^ REFERENCE
}
class B1 extends A {}
^ REFERENCE
class B2 implements A {}
^ REFERENCE
class B3 extends Object with A {}
^ REFERENCE
List<A> v2 = null;
^ REFERENCE
''');
}
test_searchReferences_ClassElement_reference_definedOutside() async {
newFile('$testPackageLibPath/lib.dart', r'''
class A {};
''');
var result = await resolveTestCode('''
import 'lib.dart';
main(A p) {
A v;
}
''');
var element = result.findNode.namedType('A p').element!;
await assertElementReferencesText(element, r'''
import 'lib.dart';
main(A p) {
^ REFERENCE
A v;
^ REFERENCE
}
''');
}
test_searchReferences_ClassElement_reference_instanceCreation() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
class A {}
void f() {
A();
p.A();
}
''');
var element = result.findElement.class_('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
class A {}
void f() {
A();
^ REFERENCE
p.A();
^ REFERENCE qualified
}
''');
}
test_searchReferences_ClassElement_reference_memberAccess() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
class A {
static void foo() {}
}
void f() {
A.foo();
p.A.foo();
}
''');
var element = result.findElement.class_('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
class A {
static void foo() {}
}
void f() {
A.foo();
^ REFERENCE
p.A.foo();
^ REFERENCE qualified
}
''');
}
test_searchReferences_ClassElement_reference_namedType() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
class A {}
void f() {
A v1;
p.A v2;
List<A> v3;
List<p.A> v4;
}
''');
var element = result.findElement.class_('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
class A {}
void f() {
A v1;
^ REFERENCE
p.A v2;
^ REFERENCE qualified
List<A> v3;
^ REFERENCE
List<p.A> v4;
^ REFERENCE qualified
}
''');
}
test_searchReferences_ClassElement_reference_recordTypeAnnotation_named() async {
var result = await resolveTestCode('''
class A {}
void f(({int foo, A bar}) r) {}
''');
var element = result.findElement.class_('A');
await assertElementReferencesText(element, r'''
class A {}
void f(({int foo, A bar}) r) {}
^ REFERENCE
''');
}
test_searchReferences_ClassElement_reference_recordTypeAnnotation_positional() async {
var result = await resolveTestCode('''
class A {}
void f((int, A) r) {}
''');
var element = result.findElement.class_('A');
await assertElementReferencesText(element, r'''
class A {}
void f((int, A) r) {}
^ REFERENCE
''');
}
test_searchReferences_ClassElement_reference_typeLiteral() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
class A {}
var v = A;
var v_p = p.A;
''');
var element = result.findElement.class_('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
class A {}
var v = A;
^ REFERENCE
var v_p = p.A;
^ REFERENCE qualified
''');
}
test_searchReferences_ConstructorElement_class_annotation() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
class A {
const A();
const A.named();
}
@A()
@p.A()
@A.named()
@p.A.named()
void f() {}
''');
var unnamed = result.findElement.unnamedConstructor('A');
await assertElementReferencesText(unnamed, r'''
import 'test.dart' as p;
class A {
const A();
const A.named();
}
@A()
^0 INVOCATION qualified
@p.A()
^0 INVOCATION qualified
@A.named()
@p.A.named()
void f() {}
''');
var named = result.findElement.constructor('named', of: 'A');
await assertElementReferencesText(named, r'''
import 'test.dart' as p;
class A {
const A();
const A.named();
}
@A()
@p.A()
@A.named()
^^^^^^ INVOCATION qualified
@p.A.named()
^^^^^^ INVOCATION qualified
void f() {}
''');
}
test_searchReferences_ConstructorElement_class_method_sameName() async {
var result = await resolveTestCode('''
class A {
A.foo() {
foo();
}
A foo() => A.foo();
}
''');
var element = result.findElement.constructor('foo');
await assertElementReferencesText(element, r'''
class A {
A.foo() {
foo();
}
A foo() => A.foo();
^^^^ INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_class_named_dotShorthand_otherFile() async {
// Note, we don't mention `A`, only the constructor name `foo`.
newFile('$testPackageLibPath/other.dart', '''
import 'test.dart';
void useConstructor() {
useA(.foo());
}
''');
var result = await resolveTestCode('''
class A {
A.foo();
}
void useA(A a) {}
''');
var element = result.findElement.constructor('foo');
await assertElementReferencesText(element, r'''
package:test/other.dart
-----------------------
import 'test.dart';
void useConstructor() {
useA(.foo());
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_class_named_newHead() async {
var result = await resolveTestCode('''
/// [new A.foo] and [A.foo]
class A {
new foo() {}
new bar() : this.foo();
factory baz() = A.foo;
}
class B extends A {
new () : super.foo();
}
void useConstructor() {
A.foo();
A.foo;
A a = .foo();
}
''');
var element = result.findElement.constructor('foo');
await assertElementReferencesText(element, r'''
/// [new A.foo] and [A.foo]
^^^^ REFERENCE qualified
^^^^ REFERENCE qualified
class A {
new foo() {}
new bar() : this.foo();
^^^^ INVOCATION qualified
factory baz() = A.foo;
^^^^ REFERENCE qualified
}
class B extends A {
new () : super.foo();
^^^^ INVOCATION qualified
}
void useConstructor() {
A.foo();
^^^^ INVOCATION qualified
A.foo;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
A a = .foo();
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_class_named_primary() async {
var result = await resolveTestCode('''
/// [new A.foo] and [A.foo]
class A.foo() {
new bar() : this.foo();
factory baz() = A.foo;
}
class B() extends A {
this : super.foo();
}
void useConstructor() {
A.foo();
A.foo;
A a = .foo();
}
''');
var element = result.findElement.constructor('foo');
await assertElementReferencesText(element, r'''
/// [new A.foo] and [A.foo]
^^^^ REFERENCE qualified
^^^^ REFERENCE qualified
class A.foo() {
new bar() : this.foo();
^^^^ INVOCATION qualified
factory baz() = A.foo;
^^^^ REFERENCE qualified
}
class B() extends A {
this : super.foo();
^^^^ INVOCATION qualified
}
void useConstructor() {
A.foo();
^^^^ INVOCATION qualified
A.foo;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
A a = .foo();
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_class_named_typeName() async {
var result = await resolveTestCode('''
/// [new A.foo] and [A.foo]
class A {
A.foo() {}
A.bar() : this.foo();
factory A.baz() = A.foo;
}
class B extends A {
B() : super.foo();
}
void useConstructor() {
A.foo();
A.foo;
A a = .foo();
}
''');
var element = result.findElement.constructor('foo');
await assertElementReferencesText(element, r'''
/// [new A.foo] and [A.foo]
^^^^ REFERENCE qualified
^^^^ REFERENCE qualified
class A {
A.foo() {}
A.bar() : this.foo();
^^^^ INVOCATION qualified
factory A.baz() = A.foo;
^^^^ REFERENCE qualified
}
class B extends A {
B() : super.foo();
^^^^ INVOCATION qualified
}
void useConstructor() {
A.foo();
^^^^ INVOCATION qualified
A.foo;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
A a = .foo();
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_class_named_typeName_viaTypeAlias() async {
var result = await resolveTestCode('''
/// [new B.foo] and [B.foo]
class A<T> {
A.foo() {}
A.bar() : this.foo();
factory A.baz() = A.foo;
}
typedef B = A<int>;
class C extends B {
C() : super.foo();
}
void useConstructor() {
B.foo();
B.foo;
B b = .foo();
}
''');
var element = result.findElement.constructor('foo');
await assertElementReferencesText(element, r'''
/// [new B.foo] and [B.foo]
^^^^ REFERENCE qualified
^^^^ REFERENCE qualified
class A<T> {
A.foo() {}
A.bar() : this.foo();
^^^^ INVOCATION qualified
factory A.baz() = A.foo;
^^^^ REFERENCE qualified
}
typedef B = A<int>;
class C extends B {
C() : super.foo();
^^^^ INVOCATION qualified
}
void useConstructor() {
B.foo();
^^^^ INVOCATION qualified
B.foo;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
B b = .foo();
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_class_unnamed_dotShorthand_otherFile() async {
// Note, we don't mention `A`, only the constructor name `new`.
newFile('$testPackageLibPath/other.dart', '''
import 'test.dart';
void useConstructor() {
useA(.new());
}
''');
var result = await resolveTestCode('''
class A {}
void useA(A a) {}
''');
var element = result.findElement.unnamedConstructor('A');
await assertElementReferencesText(element, r'''
package:test/other.dart
-----------------------
import 'test.dart';
void useConstructor() {
useA(.new());
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_class_unnamed_implicit() async {
var result = await resolveTestCode('''
/// [new A] and [A.new]
class B {
B();
factory B.baz() = A;
}
class A extends B {}
class C extends A {
C() : super();
}
void useConstructor() {
A();
A.new;
A a = .new();
}
''');
var element = result.findElement.unnamedConstructor('A');
await assertElementReferencesText(element, r'''
/// [new A] and [A.new]
^0 REFERENCE qualified
^^^^ REFERENCE qualified
class B {
B();
factory B.baz() = A;
^0 REFERENCE qualified
}
class A extends B {}
class C extends A {
C() : super();
^0 INVOCATION qualified
}
void useConstructor() {
A();
^0 INVOCATION qualified
A.new;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
A a = .new();
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_class_unnamed_implicitInvocation_fromNewHead() async {
var result = await resolveTestCode('''
class A {
A();
}
class B extends A {
new ();
new bar();
factory new.baz() = A;
}
''');
var element = result.findElement.unnamedConstructor('A');
await assertElementReferencesText(element, r'''
class A {
A();
}
class B extends A {
new ();
^^^ INVOCATION qualified
new bar();
^^^^^^^ INVOCATION qualified
factory new.baz() = A;
^0 REFERENCE qualified
}
''');
}
test_searchReferences_ConstructorElement_class_unnamed_implicitInvocation_fromTypeName() async {
var result = await resolveTestCode('''
class A {
A();
}
class B extends A {
B();
B.bar();
factory B.baz() = A;
}
class C extends A {}
''');
var element = result.findElement.unnamedConstructor('A');
await assertElementReferencesText(element, r'''
class A {
A();
}
class B extends A {
B();
^ INVOCATION qualified
B.bar();
^^^^^ INVOCATION qualified
factory B.baz() = A;
^0 REFERENCE qualified
}
class C extends A {}
^ INVOCATION qualified
''');
}
test_searchReferences_ConstructorElement_class_unnamed_newHead() async {
var result = await resolveTestCode('''
/// [new A] and [A.new]
class A {
new () {}
new bar() : this();
factory baz() = A;
}
class B extends A {
new () : super();
}
void useConstructor() {
A();
A.new;
A a = .new();
}
''');
var element = result.findElement.unnamedConstructor('A');
await assertElementReferencesText(element, r'''
/// [new A] and [A.new]
^0 REFERENCE qualified
^^^^ REFERENCE qualified
class A {
new () {}
new bar() : this();
^0 INVOCATION qualified
factory baz() = A;
^0 REFERENCE qualified
}
class B extends A {
new () : super();
^0 INVOCATION qualified
}
void useConstructor() {
A();
^0 INVOCATION qualified
A.new;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
A a = .new();
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_class_unnamed_otherFile() async {
String other = convertPath('$testPackageLibPath/other.dart');
String otherCode = '''
import 'test.dart';
void f() {
A();
}
''';
newFile(other, otherCode);
var result = await resolveTestCode('''
class A {
A() {}
}
''');
var element = result.findElement.unnamedConstructor('A');
await assertElementReferencesText(element, r'''
package:test/other.dart
-----------------------
import 'test.dart';
void f() {
A();
^0 INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_class_unnamed_primary() async {
var result = await resolveTestCode('''
/// [new A] and [A.new]
class A() {
new bar() : this();
factory baz() = A;
}
class B() extends A {
this : super();
}
void useConstructor() {
A();
A.new;
A a = .new();
}
''');
var element = result.findElement.unnamedConstructor('A');
await assertElementReferencesText(element, r'''
/// [new A] and [A.new]
^0 REFERENCE qualified
^^^^ REFERENCE qualified
class A() {
new bar() : this();
^0 INVOCATION qualified
factory baz() = A;
^0 REFERENCE qualified
}
class B() extends A {
this : super();
^0 INVOCATION qualified
}
void useConstructor() {
A();
^0 INVOCATION qualified
A.new;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
A a = .new();
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_class_unnamed_typeName() async {
var result = await resolveTestCode('''
/// [new A] and [A.new]
class A {
A() {}
A.bar() : this();
factory A.baz() = A;
}
class B extends A {
B() : super();
}
void useConstructor() {
A();
A.new;
A a = .new();
}
''');
var element = result.findElement.unnamedConstructor('A');
await assertElementReferencesText(element, r'''
/// [new A] and [A.new]
^0 REFERENCE qualified
^^^^ REFERENCE qualified
class A {
A() {}
A.bar() : this();
^0 INVOCATION qualified
factory A.baz() = A;
^0 REFERENCE qualified
}
class B extends A {
B() : super();
^0 INVOCATION qualified
}
void useConstructor() {
A();
^0 INVOCATION qualified
A.new;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
A a = .new();
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_class_unnamed_typeName_explicitNew() async {
var result = await resolveTestCode('''
/// [new A] and [A.new]
class A {
A.new() {}
A.bar() : this.new();
factory A.baz() = A.new;
}
class B extends A {
B() : super.new();
}
void useConstructor() {
A.new();
A.new;
A a = .new();
}
''');
var element = result.findElement.unnamedConstructor('A');
await assertElementReferencesText(element, r'''
/// [new A] and [A.new]
^0 REFERENCE qualified
^^^^ REFERENCE qualified
class A {
A.new() {}
A.bar() : this.new();
^^^^ INVOCATION qualified
factory A.baz() = A.new;
^^^^ REFERENCE qualified
}
class B extends A {
B() : super.new();
^^^^ INVOCATION qualified
}
void useConstructor() {
A.new();
^^^^ INVOCATION qualified
A.new;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
A a = .new();
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_class_unnamed_viaTypeAlias_otherFile() async {
// Note, we use neither `A` nor `new`, only `B`.
newFile('$testPackageLibPath/other.dart', '''
import 'test.dart';
class C extends B {
C() : super();
}
void useConstructor() {
B();
}
''');
var result = await resolveTestCode('''
class A<T> {}
typedef B = A<int>;
''');
var element = result.findElement.unnamedConstructor('A');
await assertElementReferencesText(element, r'''
package:test/other.dart
-----------------------
import 'test.dart';
class C extends B {
C() : super();
^0 INVOCATION qualified
}
void useConstructor() {
B();
^0 INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_class_unnamed_viaTypeAliasChain_otherFile() async {
// Note, we use neither `A` nor `new`, only `C`.
newFile('$testPackageLibPath/other.dart', '''
import 'test.dart';
class D extends C {
D() : super();
}
void useConstructor() {
C();
}
''');
var result = await resolveTestCode('''
class A<T> {}
typedef B = A<int>;
typedef C = B;
''');
var element = result.findElement.unnamedConstructor('A');
await assertElementReferencesText(element, r'''
package:test/other.dart
-----------------------
import 'test.dart';
class D extends C {
D() : super();
^0 INVOCATION qualified
}
void useConstructor() {
C();
^0 INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_classTypeAlias_cycle() async {
var result = await resolveTestCode('''
class M {}
class A = B with M;
class B = A with M;
void useConstructor() {
A();
B();
}
''');
expect(result.errors, isNotEmpty);
}
test_searchReferences_ConstructorElement_classTypeAlias_named() async {
var result = await resolveTestCode('''
class M {}
class A {
A() {}
A.named() {}
}
class B = A with M;
class C = B with M;
void useConstructor() {
B();
B.named();
C();
C.named();
}
''');
var element = result.findElement.constructor('named', of: 'A');
await assertElementReferencesText(element, r'''
class M {}
class A {
A() {}
A.named() {}
}
class B = A with M;
class C = B with M;
void useConstructor() {
B();
B.named();
^^^^^^ INVOCATION qualified
C();
C.named();
^^^^^^ INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_classTypeAlias_unnamed() async {
var result = await resolveTestCode('''
class M {}
class A {
A() {}
A.named() {}
}
class B = A with M;
class C = B with M;
void useConstructor() {
B();
B.named();
C();
C.named();
}
''');
var element = result.findElement.unnamedConstructor('A');
await assertElementReferencesText(element, r'''
class M {}
class A {
A() {}
A.named() {}
}
class B = A with M;
class C = B with M;
void useConstructor() {
B();
^0 INVOCATION qualified
B.named();
C();
^0 INVOCATION qualified
C.named();
}
''');
}
test_searchReferences_ConstructorElement_enum_named_newHead() async {
var result = await resolveTestCode('''
/// [new E.foo] and [E.foo]
enum E {
v.foo();
const new foo();
const new bar() : this.foo();
const factory baz() = E.foo;
}
void useConstructor() {
E.foo();
E.foo;
E a = .foo();
}
''');
var element = result.findElement.constructor('foo');
await assertElementReferencesText(element, r'''
/// [new E.foo] and [E.foo]
^^^^ REFERENCE qualified
^^^^ REFERENCE qualified
enum E {
v.foo();
^^^^ INVOCATION qualified
const new foo();
const new bar() : this.foo();
^^^^ INVOCATION qualified
const factory baz() = E.foo;
^^^^ REFERENCE qualified
}
void useConstructor() {
E.foo();
^^^^ INVOCATION qualified
E.foo;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
E a = .foo();
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_enum_named_primary() async {
var result = await resolveTestCode('''
/// [new E.foo] and [E.foo]
enum E.foo() {
v.foo();
const new bar() : this.foo();
const factory baz() = E.foo;
}
void useConstructor() {
E.foo();
E.foo;
E a = .foo();
}
''');
var element = result.findElement.constructor('foo');
await assertElementReferencesText(element, r'''
/// [new E.foo] and [E.foo]
^^^^ REFERENCE qualified
^^^^ REFERENCE qualified
enum E.foo() {
v.foo();
^^^^ INVOCATION qualified
const new bar() : this.foo();
^^^^ INVOCATION qualified
const factory baz() = E.foo;
^^^^ REFERENCE qualified
}
void useConstructor() {
E.foo();
^^^^ INVOCATION qualified
E.foo;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
E a = .foo();
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_enum_named_typeName() async {
var result = await resolveTestCode('''
/// [new E.foo] and [E.foo]
enum E {
v.foo();
const E.foo();
const E.bar() : this.foo();
const factory E.baz() = E.foo;
}
void useConstructor() {
E.foo();
E.foo;
E a = .foo();
}
''');
var element = result.findElement.constructor('foo');
await assertElementReferencesText(element, r'''
/// [new E.foo] and [E.foo]
^^^^ REFERENCE qualified
^^^^ REFERENCE qualified
enum E {
v.foo();
^^^^ INVOCATION qualified
const E.foo();
const E.bar() : this.foo();
^^^^ INVOCATION qualified
const factory E.baz() = E.foo;
^^^^ REFERENCE qualified
}
void useConstructor() {
E.foo();
^^^^ INVOCATION qualified
E.foo;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
E a = .foo();
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_enum_unnamed_implicit() async {
var result = await resolveTestCode('''
/// [new E] and [E.new]
enum E {
v1,
v2(),
v3.new();
const factory E.other() = E;
}
void useConstructor() {
E();
E.new;
E a = .new();
}
''');
var element = result.findElement.unnamedConstructor('E');
await assertElementReferencesText(element, r'''
/// [new E] and [E.new]
^0 REFERENCE qualified
^^^^ REFERENCE qualified
enum E {
v1,
^0 INVOCATION_BY_ENUM_CONSTANT_WITHOUT_ARGUMENTS qualified
v2(),
^0 INVOCATION qualified
v3.new();
^^^^ INVOCATION qualified
const factory E.other() = E;
^0 REFERENCE qualified
}
void useConstructor() {
E();
^0 INVOCATION qualified
E.new;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
E a = .new();
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_enum_unnamed_newHead() async {
var result = await resolveTestCode('''
/// [new E] and [E.new]
enum E {
v1,
v2(),
v3.new();
const new ();
const factory other() = E.new;
}
void useConstructor() {
E();
E.new;
E a = .new();
}
''');
var element = result.findElement.unnamedConstructor('E');
await assertElementReferencesText(element, r'''
/// [new E] and [E.new]
^0 REFERENCE qualified
^^^^ REFERENCE qualified
enum E {
v1,
^0 INVOCATION_BY_ENUM_CONSTANT_WITHOUT_ARGUMENTS qualified
v2(),
^0 INVOCATION qualified
v3.new();
^^^^ INVOCATION qualified
const new ();
const factory other() = E.new;
^^^^ REFERENCE qualified
}
void useConstructor() {
E();
^0 INVOCATION qualified
E.new;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
E a = .new();
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_enum_unnamed_primary() async {
var result = await resolveTestCode('''
/// [new E] and [E.new]
enum E() {
v1,
v2(),
v3.new();
const factory other() = E.new;
}
void useConstructor() {
E();
E.new;
E a = .new();
}
''');
var element = result.findElement.unnamedConstructor('E');
await assertElementReferencesText(element, r'''
/// [new E] and [E.new]
^0 REFERENCE qualified
^^^^ REFERENCE qualified
enum E() {
v1,
^0 INVOCATION_BY_ENUM_CONSTANT_WITHOUT_ARGUMENTS qualified
v2(),
^0 INVOCATION qualified
v3.new();
^^^^ INVOCATION qualified
const factory other() = E.new;
^^^^ REFERENCE qualified
}
void useConstructor() {
E();
^0 INVOCATION qualified
E.new;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
E a = .new();
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_enum_unnamed_typeName() async {
var result = await resolveTestCode('''
/// [new E] and [E.new]
enum E {
v1,
v2(),
v3.new();
const E();
const factory E.other() = E;
}
void useConstructor() {
E();
E.new;
E a = .new();
}
''');
var element = result.findElement.unnamedConstructor('E');
await assertElementReferencesText(element, r'''
/// [new E] and [E.new]
^0 REFERENCE qualified
^^^^ REFERENCE qualified
enum E {
v1,
^0 INVOCATION_BY_ENUM_CONSTANT_WITHOUT_ARGUMENTS qualified
v2(),
^0 INVOCATION qualified
v3.new();
^^^^ INVOCATION qualified
const E();
const factory E.other() = E;
^0 REFERENCE qualified
}
void useConstructor() {
E();
^0 INVOCATION qualified
E.new;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
E a = .new();
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_enum_unnamed_typeName_explicitNew() async {
var result = await resolveTestCode('''
/// [new E] and [E.new]
enum E {
v1,
v2(),
v3.new();
const E.new();
const factory E.other() = E.new;
}
void useConstructor() {
E();
E.new;
E a = .new();
}
''');
var element = result.findElement.unnamedConstructor('E');
await assertElementReferencesText(element, r'''
/// [new E] and [E.new]
^0 REFERENCE qualified
^^^^ REFERENCE qualified
enum E {
v1,
^0 INVOCATION_BY_ENUM_CONSTANT_WITHOUT_ARGUMENTS qualified
v2(),
^0 INVOCATION qualified
v3.new();
^^^^ INVOCATION qualified
const E.new();
const factory E.other() = E.new;
^^^^ REFERENCE qualified
}
void useConstructor() {
E();
^0 INVOCATION qualified
E.new;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
E a = .new();
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_extensionType_named_newHead() async {
var result = await resolveTestCode('''
/// [new A.foo] and [A.foo]
extension type A(int it) {
new foo(this.it);
new bar() : this.foo(0);
factory baz(int it) = A.foo;
}
void useConstructor() {
A.foo(0);
A.foo;
A a = .foo(0);
}
''');
var element = result.findElement.constructor('foo');
await assertElementReferencesText(element, r'''
/// [new A.foo] and [A.foo]
^^^^ REFERENCE qualified
^^^^ REFERENCE qualified
extension type A(int it) {
new foo(this.it);
new bar() : this.foo(0);
^^^^ INVOCATION qualified
factory baz(int it) = A.foo;
^^^^ REFERENCE qualified
}
void useConstructor() {
A.foo(0);
^^^^ INVOCATION qualified
A.foo;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
A a = .foo(0);
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_extensionType_named_primary() async {
var result = await resolveTestCode('''
/// [new A.foo] and [A.foo]
extension type A.foo(int it) {
new bar() : this.foo(0);
factory baz(int it) = A.foo;
}
void useConstructor() {
A.foo(0);
A.foo;
A a = .foo(0);
}
''');
var element = result.findElement.constructor('foo');
await assertElementReferencesText(element, r'''
/// [new A.foo] and [A.foo]
^^^^ REFERENCE qualified
^^^^ REFERENCE qualified
extension type A.foo(int it) {
new bar() : this.foo(0);
^^^^ INVOCATION qualified
factory baz(int it) = A.foo;
^^^^ REFERENCE qualified
}
void useConstructor() {
A.foo(0);
^^^^ INVOCATION qualified
A.foo;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
A a = .foo(0);
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_extensionType_named_typeName() async {
var result = await resolveTestCode('''
/// [new A.foo] and [A.foo]
extension type A(int it) {
A.foo(this.it);
A.bar() : this.foo(0);
factory A.baz(int it) = A.foo;
}
void useConstructor() {
A.foo(0);
A.foo;
A a = .foo(0);
}
''');
var element = result.findElement.constructor('foo');
await assertElementReferencesText(element, r'''
/// [new A.foo] and [A.foo]
^^^^ REFERENCE qualified
^^^^ REFERENCE qualified
extension type A(int it) {
A.foo(this.it);
A.bar() : this.foo(0);
^^^^ INVOCATION qualified
factory A.baz(int it) = A.foo;
^^^^ REFERENCE qualified
}
void useConstructor() {
A.foo(0);
^^^^ INVOCATION qualified
A.foo;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
A a = .foo(0);
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_extensionType_unnamed_newHead() async {
var result = await resolveTestCode('''
/// [new A] and [A.new]
extension type A.named(int it) {
new (this.it);
new bar() : this(0);
factory baz(int it) = A.new;
}
void useConstructor() {
A(0);
A.new;
A a = .new(0);
}
''');
var element = result.findElement.unnamedConstructor('A');
await assertElementReferencesText(element, r'''
/// [new A] and [A.new]
^0 REFERENCE qualified
^^^^ REFERENCE qualified
extension type A.named(int it) {
new (this.it);
new bar() : this(0);
^0 INVOCATION qualified
factory baz(int it) = A.new;
^^^^ REFERENCE qualified
}
void useConstructor() {
A(0);
^0 INVOCATION qualified
A.new;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
A a = .new(0);
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_extensionType_unnamed_primary() async {
var result = await resolveTestCode('''
/// [new A] and [A.new]
extension type A(int it) {
new bar() : this(0);
factory baz(int it) = A.new;
}
void useConstructor() {
A(0);
A.new;
A a = .new(0);
}
''');
var element = result.findElement.unnamedConstructor('A');
await assertElementReferencesText(element, r'''
/// [new A] and [A.new]
^0 REFERENCE qualified
^^^^ REFERENCE qualified
extension type A(int it) {
new bar() : this(0);
^0 INVOCATION qualified
factory baz(int it) = A.new;
^^^^ REFERENCE qualified
}
void useConstructor() {
A(0);
^0 INVOCATION qualified
A.new;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
A a = .new(0);
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_extensionType_unnamed_typeName() async {
var result = await resolveTestCode('''
/// [new A] and [A.new]
extension type A.named(int it) {
A(this.it);
A.bar() : this(0);
factory A.baz(int it) = A.new;
}
void useConstructor() {
A(0);
A.new;
A a = .new(0);
}
''');
var element = result.findElement.unnamedConstructor('A');
await assertElementReferencesText(element, r'''
/// [new A] and [A.new]
^0 REFERENCE qualified
^^^^ REFERENCE qualified
extension type A.named(int it) {
A(this.it);
A.bar() : this(0);
^0 INVOCATION qualified
factory A.baz(int it) = A.new;
^^^^ REFERENCE qualified
}
void useConstructor() {
A(0);
^0 INVOCATION qualified
A.new;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
A a = .new(0);
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_ConstructorElement_extensionType_unnamed_typeName_explicitNew() async {
var result = await resolveTestCode('''
/// [new A] and [A.new]
extension type A.named(int it) {
A.new(this.it);
A.bar() : this.new(0);
factory A.baz(int it) = A.new;
}
void useConstructor() {
A.new(0);
A.new;
A a = .new(0);
}
''');
var element = result.findElement.unnamedConstructor('A');
await assertElementReferencesText(element, r'''
/// [new A] and [A.new]
^0 REFERENCE qualified
^^^^ REFERENCE qualified
extension type A.named(int it) {
A.new(this.it);
A.bar() : this.new(0);
^^^^ INVOCATION qualified
factory A.baz(int it) = A.new;
^^^^ REFERENCE qualified
}
void useConstructor() {
A.new(0);
^^^^ INVOCATION qualified
A.new;
^^^^ REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
A a = .new(0);
^^^ DOT_SHORTHANDS_CONSTRUCTOR_INVOCATION qualified
}
''');
}
test_searchReferences_constructorField_outsideFile() async {
// Create an external file with a class that has a constructor field.
newFile('$testPackageLibPath/other.dart', r'''
import 'test.dart';
class B extends A {
B({super.x});
}
''');
// Resolve test code that imports the external file and references the field.
var result = await resolveTestCode(r'''
class A {
int? x;
A({this.x});
}
''');
// Look up field 'x' and assert that its reference is correctly found.
var field = result.findElement.fieldFormalParameter('x');
await assertElementReferencesText(field, r'''
package:test/other.dart
-----------------------
import 'test.dart';
class B extends A {
B({super.x});
^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
''');
}
test_searchReferences_EnumElement_reference_annotation() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
enum E {
v;
const E();
const E.named();
static const int myConstant = 0;
}
@E()
@p.E()
@E.named()
@p.E.named()
@E.myConstant
@p.E.myConstant
void f() {}
''');
var element = result.findElement.enum_('E');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
enum E {
v;
const E();
^ REFERENCE
const E.named();
^ REFERENCE
static const int myConstant = 0;
}
@E()
^ REFERENCE
@p.E()
^ REFERENCE qualified
@E.named()
^ REFERENCE
@p.E.named()
^ REFERENCE qualified
@E.myConstant
^ REFERENCE
@p.E.myConstant
^ REFERENCE qualified
void f() {}
''');
}
test_searchReferences_EnumElement_reference_comment() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
enum E { v }
/// [E] and [p.E].
void f() {}
''');
var element = result.findElement.enum_('E');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
enum E { v }
/// [E] and [p.E].
^ REFERENCE
^ REFERENCE qualified
void f() {}
''');
}
test_searchReferences_EnumElement_reference_instanceCreation() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
enum E {
v;
const E();
}
void f() {
const E();
const p.E();
}
''');
var element = result.findElement.enum_('E');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
enum E {
v;
const E();
^ REFERENCE
}
void f() {
const E();
^ REFERENCE
const p.E();
^ REFERENCE qualified
}
''');
}
test_searchReferences_EnumElement_reference_memberAccess() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
enum E {
v;
static void foo() {}
}
void f() {
E.foo();
p.E.foo();
}
''');
var element = result.findElement.enum_('E');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
enum E {
v;
static void foo() {}
}
void f() {
E.foo();
^ REFERENCE
p.E.foo();
^ REFERENCE qualified
}
''');
}
test_searchReferences_EnumElement_reference_namedType() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
enum E { v }
void f() {
E v1;
p.E v2;
}
''');
var element = result.findElement.enum_('E');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
enum E { v }
void f() {
E v1;
^ REFERENCE
p.E v2;
^ REFERENCE qualified
}
''');
}
test_searchReferences_ExtensionElement() async {
var result = await resolveTestCode('''
extension E on int {
void foo() {}
static void bar() {}
}
main() {
E(0).foo();
E.bar();
}
''');
var element = result.findElement.extension_('E');
await assertElementReferencesText(element, r'''
extension E on int {
void foo() {}
static void bar() {}
}
main() {
E(0).foo();
^ REFERENCE
E.bar();
^ REFERENCE
}
''');
}
test_searchReferences_ExtensionTypeElement_reference_annotation() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
extension type const A(int it) {}
@A(0)
@p.A(0)
void f() {}
''');
var element = result.findElement.extensionType('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
extension type const A(int it) {}
@A(0)
^ REFERENCE
@p.A(0)
^ REFERENCE qualified
void f() {}
''');
}
test_searchReferences_ExtensionTypeElement_reference_comment() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
extension type A(int it) {}
/// [A] and [p.A].
void f() {}
''');
var element = result.findElement.extensionType('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
extension type A(int it) {}
/// [A] and [p.A].
^ REFERENCE
^ REFERENCE qualified
void f() {}
''');
}
test_searchReferences_ExtensionTypeElement_reference_instanceCreation() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
extension type A(int it) {}
void f() {
A(0);
p.A(0);
}
''');
var element = result.findElement.extensionType('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
extension type A(int it) {}
void f() {
A(0);
^ REFERENCE
p.A(0);
^ REFERENCE qualified
}
''');
}
test_searchReferences_ExtensionTypeElement_reference_memberAccess() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
extension type A(int it) {
static void foo() {}
}
void f() {
A.foo();
p.A.foo();
}
''');
var element = result.findElement.extensionType('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
extension type A(int it) {
static void foo() {}
}
void f() {
A.foo();
^ REFERENCE
p.A.foo();
^ REFERENCE qualified
}
''');
}
test_searchReferences_ExtensionTypeElement_reference_namedType() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
extension type A(int it) {}
void f() {
A v1;
p.A v2;
}
''');
var element = result.findElement.extensionType('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
extension type A(int it) {}
void f() {
A v1;
^ REFERENCE
p.A v2;
^ REFERENCE qualified
}
''');
}
test_searchReferences_FieldElement_ofClass_instance_fieldDeclaration() async {
var result = await resolveTestCode('''
/// [foo] and [A.foo]
class A {
int foo;
A({this.foo = 0});
A.foo() : foo = 0;
void useField() {
foo;
foo = 0;
foo += 1;
foo ??= 2;
foo++;
--foo;
this.foo;
this.foo = 0;
this.foo += 1;
this.foo ??= 2;
this.foo++;
--this.foo;
}
}
void useField(A a) {
a.foo;
a.foo = 0;
a.foo += 1;
a.foo ??= 2;
a.foo++;
--a.foo;
A(foo: 0);
}
class B extends A {
void useSuper() {
super.foo;
super.foo = 0;
super.foo += 1;
super.foo ??= 2;
super.foo++;
--super.foo;
}
}
''');
var field = result.findElement.field('foo');
await assertElementsReferencesText(
{
'field': field,
'getter': field.getter!,
'setter': field.setter!,
'num.+': result.typeProvider.numElement.getMethod('+')!,
'num.-': result.typeProvider.numElement.getMethod('-')!,
},
r'''
/// [foo] and [A.foo]
^^^ field REFERENCE
^^^ getter REFERENCE
^^^ field REFERENCE qualified
^^^ getter REFERENCE qualified
class A {
int foo;
A({this.foo = 0});
^^^ field WRITE qualified
A.foo() : foo = 0;
^^^ field WRITE qualified
void useField() {
foo;
^^^ field READ
^^^ getter INVOCATION
foo = 0;
^^^ field WRITE
^^^ setter INVOCATION
foo += 1;
^^^ field READ_WRITE
^^^ getter INVOCATION
^^^ setter INVOCATION
^^ num.+ INVOCATION qualified
foo ??= 2;
^^^ field READ_WRITE
^^^ getter INVOCATION
^^^ setter INVOCATION
foo++;
^^^ field READ_WRITE
^^^ getter INVOCATION
^^^ setter INVOCATION
^^ num.+ INVOCATION qualified
--foo;
^^ num.- INVOCATION qualified
^^^ field READ_WRITE
^^^ getter INVOCATION
^^^ setter INVOCATION
this.foo;
^^^ field READ qualified
^^^ getter INVOCATION qualified
this.foo = 0;
^^^ field WRITE qualified
^^^ setter INVOCATION qualified
this.foo += 1;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
this.foo ??= 2;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
this.foo++;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
--this.foo;
^^ num.- INVOCATION qualified
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
}
}
void useField(A a) {
a.foo;
^^^ field READ qualified
^^^ getter INVOCATION qualified
a.foo = 0;
^^^ field WRITE qualified
^^^ setter INVOCATION qualified
a.foo += 1;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
a.foo ??= 2;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
a.foo++;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
--a.foo;
^^ num.- INVOCATION qualified
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
A(foo: 0);
}
class B extends A {
void useSuper() {
super.foo;
^^^ field READ qualified
^^^ getter INVOCATION qualified
super.foo = 0;
^^^ field WRITE qualified
^^^ setter INVOCATION qualified
super.foo += 1;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
super.foo ??= 2;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
super.foo++;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
--super.foo;
^^ num.- INVOCATION qualified
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
}
}
''',
);
}
test_searchReferences_FieldElement_ofClass_instance_getterDeclaration() async {
var result = await resolveTestCode('''
/// [foo] and [A.foo]
class A {
A() : foo = 0;
int get foo => 0;
void useGetter() {
foo;
this.foo;
}
}
void useGetter(A a) {
a.foo;
}
class B extends A {
void useSuper() {
super.foo;
}
}
''');
var field = result.findElement.field('foo');
await assertElementsReferencesText(
{'field': field, 'getter': field.getter!},
r'''
/// [foo] and [A.foo]
^^^ field REFERENCE
^^^ getter REFERENCE
^^^ field REFERENCE qualified
^^^ getter REFERENCE qualified
class A {
A() : foo = 0;
int get foo => 0;
void useGetter() {
foo;
^^^ field READ
^^^ getter INVOCATION
this.foo;
^^^ field READ qualified
^^^ getter INVOCATION qualified
}
}
void useGetter(A a) {
a.foo;
^^^ field READ qualified
^^^ getter INVOCATION qualified
}
class B extends A {
void useSuper() {
super.foo;
^^^ field READ qualified
^^^ getter INVOCATION qualified
}
}
''',
);
}
test_searchReferences_FieldElement_ofClass_instance_getterSetterDeclarations() async {
var result = await resolveTestCode('''
class A {
A() : foo = 0;
int get foo => 0;
set foo(int _) {}
void useField() {
foo;
foo = 0;
foo += 1;
foo ??= 2;
foo++;
--foo;
this.foo;
this.foo = 0;
this.foo += 1;
this.foo ??= 2;
this.foo++;
--this.foo;
}
}
void useField(A a) {
a.foo;
a.foo = 0;
a.foo += 1;
a.foo ??= 2;
a.foo++;
--a.foo;
}
class B extends A {
void useSuper() {
super.foo;
super.foo = 0;
super.foo += 1;
super.foo ??= 2;
super.foo++;
--super.foo;
}
}
''');
var field = result.findElement.field('foo');
await assertElementsReferencesText(
{
'field': field,
'getter': field.getter!,
'setter': field.setter!,
'num.+': result.typeProvider.numElement.getMethod('+')!,
'num.-': result.typeProvider.numElement.getMethod('-')!,
},
r'''
class A {
A() : foo = 0;
int get foo => 0;
set foo(int _) {}
void useField() {
foo;
^^^ field READ
^^^ getter INVOCATION
foo = 0;
^^^ field WRITE
^^^ setter INVOCATION
foo += 1;
^^^ field READ_WRITE
^^^ getter INVOCATION
^^^ setter INVOCATION
^^ num.+ INVOCATION qualified
foo ??= 2;
^^^ field READ_WRITE
^^^ getter INVOCATION
^^^ setter INVOCATION
foo++;
^^^ field READ_WRITE
^^^ getter INVOCATION
^^^ setter INVOCATION
^^ num.+ INVOCATION qualified
--foo;
^^ num.- INVOCATION qualified
^^^ field READ_WRITE
^^^ getter INVOCATION
^^^ setter INVOCATION
this.foo;
^^^ field READ qualified
^^^ getter INVOCATION qualified
this.foo = 0;
^^^ field WRITE qualified
^^^ setter INVOCATION qualified
this.foo += 1;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
this.foo ??= 2;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
this.foo++;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
--this.foo;
^^ num.- INVOCATION qualified
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
}
}
void useField(A a) {
a.foo;
^^^ field READ qualified
^^^ getter INVOCATION qualified
a.foo = 0;
^^^ field WRITE qualified
^^^ setter INVOCATION qualified
a.foo += 1;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
a.foo ??= 2;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
a.foo++;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
--a.foo;
^^ num.- INVOCATION qualified
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
}
class B extends A {
void useSuper() {
super.foo;
^^^ field READ qualified
^^^ getter INVOCATION qualified
super.foo = 0;
^^^ field WRITE qualified
^^^ setter INVOCATION qualified
super.foo += 1;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
super.foo ??= 2;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
super.foo++;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
--super.foo;
^^ num.- INVOCATION qualified
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
}
}
''',
);
}
test_searchReferences_FieldElement_ofClass_instance_propertyAssignmentTarget() async {
var result = await resolveTestCode('''
class A {
num x = 0;
}
class B {
num? x;
}
void use(A a, A? nullableA, B b, B? nullableB) {
(a).x = 1;
(nullableA)?.x = 2;
(a).x += 3;
(nullableA)?.x += 4;
(b).x ??= 5;
(nullableB)?.x ??= 6;
}
''');
await assertElementsReferencesText(
{
'aField': result.findElement.field('x', of: 'A'),
'aGetter': result.findElement.getter('x', of: 'A'),
'aSetter': result.findElement.setter('x', of: 'A'),
'bField': result.findElement.field('x', of: 'B'),
'bGetter': result.findElement.getter('x', of: 'B'),
'bSetter': result.findElement.setter('x', of: 'B'),
'num.+': result.typeProvider.numElement.getMethod('+')!,
},
r'''
class A {
num x = 0;
}
class B {
num? x;
}
void use(A a, A? nullableA, B b, B? nullableB) {
(a).x = 1;
^ aField WRITE qualified
^ aSetter INVOCATION qualified
(nullableA)?.x = 2;
^ aField WRITE qualified
^ aSetter INVOCATION qualified
(a).x += 3;
^ aField READ_WRITE qualified
^ aGetter INVOCATION qualified
^ aSetter INVOCATION qualified
^^ num.+ INVOCATION qualified
(nullableA)?.x += 4;
^ aField READ_WRITE qualified
^ aGetter INVOCATION qualified
^ aSetter INVOCATION qualified
^^ num.+ INVOCATION qualified
(b).x ??= 5;
^ bField READ_WRITE qualified
^ bGetter INVOCATION qualified
^ bSetter INVOCATION qualified
(nullableB)?.x ??= 6;
^ bField READ_WRITE qualified
^ bGetter INVOCATION qualified
^ bSetter INVOCATION qualified
}
''',
);
}
test_searchReferences_FieldElement_ofClass_instance_propertyExtraction() async {
var result = await resolveTestCode('''
class A {
num x = 0;
}
void use(A a, A? nullableA) {
(a).x;
(nullableA)?.x;
}
''');
var field = result.findElement.field('x', of: 'A');
await assertElementsReferencesText(
{'field': field, 'getter': field.getter!},
r'''
class A {
num x = 0;
}
void use(A a, A? nullableA) {
(a).x;
^ field READ qualified
^ getter INVOCATION qualified
(nullableA)?.x;
^ field READ qualified
^ getter INVOCATION qualified
}
''',
);
}
test_searchReferences_FieldElement_ofClass_instance_setterDeclaration() async {
var result = await resolveTestCode('''
/// [foo] and [A.foo]
class A {
A() : foo = 0;
set foo(int _) {}
void useSetter() {
foo = 0;
this.foo = 0;
}
}
void useSetter(A a) {
a.foo = 0;
}
class B extends A {
void useSuper() {
super.foo = 0;
}
}
''');
var field = result.findElement.field('foo');
await assertElementsReferencesText(
{'field': field, 'setter': field.setter!},
r'''
/// [foo] and [A.foo]
^^^ field REFERENCE
^^^ setter REFERENCE
^^^ field REFERENCE qualified
^^^ setter REFERENCE qualified
class A {
A() : foo = 0;
set foo(int _) {}
void useSetter() {
foo = 0;
^^^ field WRITE
^^^ setter INVOCATION
this.foo = 0;
^^^ field WRITE qualified
^^^ setter INVOCATION qualified
}
}
void useSetter(A a) {
a.foo = 0;
^^^ field WRITE qualified
^^^ setter INVOCATION qualified
}
class B extends A {
void useSuper() {
super.foo = 0;
^^^ field WRITE qualified
^^^ setter INVOCATION qualified
}
}
''',
);
}
test_searchReferences_FieldElement_ofClass_parenthesizedReceiver_compound() async {
var result = await resolveTestCode('''
class A {
int foo = 0;
}
void f(A a) {
(a).foo += 2;
}
''');
var field = result.findElement.field('foo');
await assertElementsReferencesText(
{
'field': field,
'getter': field.getter!,
'setter': field.setter!,
'num.+': result.typeProvider.numElement.getMethod('+')!,
},
r'''
class A {
int foo = 0;
}
void f(A a) {
(a).foo += 2;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
}
''',
);
}
test_searchReferences_FieldElement_ofClass_parenthesizedReceiver_ifNull() async {
var result = await resolveTestCode('''
class A {
int? foo;
}
void f(A a) {
(a).foo ??= 2;
}
''');
var field = result.findElement.field('foo');
await assertElementsReferencesText(
{'field': field, 'getter': field.getter!, 'setter': field.setter!},
r'''
class A {
int? foo;
}
void f(A a) {
(a).foo ??= 2;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
}
''',
);
}
test_searchReferences_FieldElement_ofClass_static_fieldDeclaration() async {
var result = await resolveTestCode('''
/// [foo] and [A.foo]
class A {
static int foo = 0;
static void useField() {
foo;
foo = 0;
A.foo;
A.foo = 0;
}
}
void useField() {
A.foo;
A.foo = 0;
A a = .foo;
}
''');
var field = result.findElement.field('foo');
await assertElementsReferencesText(
{'field': field, 'getter': field.getter!, 'setter': field.setter!},
r'''
/// [foo] and [A.foo]
^^^ field REFERENCE
^^^ getter REFERENCE
^^^ field REFERENCE qualified
^^^ getter REFERENCE qualified
class A {
static int foo = 0;
static void useField() {
foo;
^^^ field READ
^^^ getter INVOCATION
foo = 0;
^^^ field WRITE
^^^ setter INVOCATION
A.foo;
^^^ field READ qualified
^^^ getter INVOCATION qualified
A.foo = 0;
^^^ field WRITE qualified
^^^ setter INVOCATION qualified
}
}
void useField() {
A.foo;
^^^ field READ qualified
^^^ getter INVOCATION qualified
A.foo = 0;
^^^ field WRITE qualified
^^^ setter INVOCATION qualified
A a = .foo;
^^^ field READ qualified
^^^ getter INVOCATION qualified
}
''',
);
}
test_searchReferences_FieldElement_ofEnum_instance_fieldDeclaration() async {
var result = await resolveTestCode('''
/// [foo] and [E.foo]
enum E {
v;
int? foo; // a compile-time error
E({this.foo});
void useField() {
foo;
foo = 0;
}
}
void useField(E e) {
e.foo;
e.foo = 0;
E(foo: 0);
}
''');
var field = result.findElement.field('foo');
await assertElementsReferencesText(
{'field': field, 'getter': field.getter!, 'setter': field.setter!},
r'''
/// [foo] and [E.foo]
^^^ field REFERENCE
^^^ getter REFERENCE
^^^ field REFERENCE qualified
^^^ getter REFERENCE qualified
enum E {
v;
int? foo; // a compile-time error
E({this.foo});
^^^ field WRITE qualified
void useField() {
foo;
^^^ field READ
^^^ getter INVOCATION
foo = 0;
^^^ field WRITE
^^^ setter INVOCATION
}
}
void useField(E e) {
e.foo;
^^^ field READ qualified
^^^ getter INVOCATION qualified
e.foo = 0;
^^^ field WRITE qualified
^^^ setter INVOCATION qualified
E(foo: 0);
}
''',
);
}
test_searchReferences_FieldElement_ofEnum_instance_fieldDeclaration_final_invalidWrite() async {
var result = await resolveTestCode('''
enum E {
v;
final int foo = 0;
void f() {
foo = 1;
}
}
''');
var field = result.findElement.field('foo');
await assertElementsReferencesText(
{'field': field, 'getter': field.getter!},
r'''
enum E {
v;
final int foo = 0;
void f() {
foo = 1;
^^^ field REFERENCE
^^^ getter REFERENCE
}
}
''',
);
}
test_searchReferences_FieldElement_ofEnum_instance_getterDeclaration() async {
var result = await resolveTestCode('''
enum E {
v;
E() : foo = 0;
int get foo => 0;
}
''');
var field = result.findElement.field('foo');
await assertElementsReferencesText(
{'field': field, 'getter': field.getter!},
r'''
''',
);
}
test_searchReferences_FieldElement_ofEnum_instance_getterSetterDeclarations() async {
var result = await resolveTestCode('''
enum E {
v;
E() : foo = 0;
int get foo => 0;
set foo(_) {}
}
''');
var field = result.findElement.field('foo');
await assertElementsReferencesText(
{'field': field, 'getter': field.getter!, 'setter': field.setter!},
r'''
''',
);
}
test_searchReferences_FieldElement_ofEnum_instance_index() async {
var result = await resolveTestCode('''
enum MyEnum {
v1, v2, v3
}
main() {
MyEnum.v1.index;
MyEnum.values;
MyEnum.v1;
MyEnum.v2;
}
''');
var index = result.typeProvider.enumElement!.getField('index')!;
await assertElementsReferencesText(
{'field': index, 'getter': index.getter!},
r'''
enum MyEnum {
v1, v2, v3
}
main() {
MyEnum.v1.index;
^^^^^ field READ qualified
^^^^^ getter INVOCATION qualified
MyEnum.values;
MyEnum.v1;
MyEnum.v2;
}
''',
);
}
test_searchReferences_FieldElement_ofEnum_instance_setterDeclaration() async {
var result = await resolveTestCode('''
enum E {
v;
E() : foo = 0;
set foo(_) {}
}
''');
var field = result.findElement.field('foo');
await assertElementsReferencesText(
{'field': field, 'setter': field.setter!},
r'''
''',
);
}
test_searchReferences_FieldElement_ofEnum_static_constants() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
/// [v1], [MyEnum.v1], and [p.MyEnum.v1]
enum MyEnum {
v1, v2, v3
}
main() {
MyEnum.v1.index;
MyEnum.values;
MyEnum.v1;
MyEnum.v2;
p.MyEnum.v1;
p.MyEnum.values;
}
''');
var values = result.findElement.field('values');
await assertElementsReferencesText(
{'field': values, 'getter': values.getter!},
r'''
import 'test.dart' as p;
/// [v1], [MyEnum.v1], and [p.MyEnum.v1]
enum MyEnum {
v1, v2, v3
}
main() {
MyEnum.v1.index;
MyEnum.values;
^^^^^^ field READ qualified
^^^^^^ getter INVOCATION qualified
MyEnum.v1;
MyEnum.v2;
p.MyEnum.v1;
p.MyEnum.values;
^^^^^^ field READ qualified
^^^^^^ getter INVOCATION qualified
}
''',
);
var v1 = result.findElement.field('v1');
await assertElementsReferencesText(
{'field': v1, 'getter': v1.getter!},
r'''
import 'test.dart' as p;
/// [v1], [MyEnum.v1], and [p.MyEnum.v1]
^^ field REFERENCE
^^ getter REFERENCE
^^ field REFERENCE qualified
^^ getter REFERENCE qualified
^^ field REFERENCE qualified
^^ getter REFERENCE qualified
enum MyEnum {
v1, v2, v3
}
main() {
MyEnum.v1.index;
^^ field READ qualified
^^ getter INVOCATION qualified
MyEnum.values;
MyEnum.v1;
^^ field READ qualified
^^ getter INVOCATION qualified
MyEnum.v2;
p.MyEnum.v1;
^^ field READ qualified
^^ getter INVOCATION qualified
p.MyEnum.values;
}
''',
);
var v2 = result.findElement.field('v2');
await assertElementsReferencesText(
{'field': v2, 'getter': v2.getter!},
r'''
import 'test.dart' as p;
/// [v1], [MyEnum.v1], and [p.MyEnum.v1]
enum MyEnum {
v1, v2, v3
}
main() {
MyEnum.v1.index;
MyEnum.values;
MyEnum.v1;
MyEnum.v2;
^^ field READ qualified
^^ getter INVOCATION qualified
p.MyEnum.v1;
p.MyEnum.values;
}
''',
);
}
test_searchReferences_FieldElement_ofExtension_instance_getterSetterDeclarations() async {
var result = await resolveTestCode('''
extension E on int {
int get foo => 0;
set foo(int _) {}
}
void useField(int a) {
a.foo;
a.foo = 0;
a.foo += 1;
a.foo ??= 2;
a.foo++;
--a.foo;
E(a).foo;
E(a).foo = 0;
E(a).foo += 1;
E(a).foo ??= 2;
E(a).foo++;
--E(a).foo;
}
''');
var field = result.findElement.field('foo');
await assertElementsReferencesText(
{
'field': field,
'getter': field.getter!,
'setter': field.setter!,
'num.+': result.typeProvider.numElement.getMethod('+')!,
'num.-': result.typeProvider.numElement.getMethod('-')!,
},
r'''
extension E on int {
int get foo => 0;
set foo(int _) {}
}
void useField(int a) {
a.foo;
^^^ field READ qualified
^^^ getter INVOCATION qualified
a.foo = 0;
^^^ field WRITE qualified
^^^ setter INVOCATION qualified
a.foo += 1;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
a.foo ??= 2;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
a.foo++;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
--a.foo;
^^ num.- INVOCATION qualified
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
E(a).foo;
^^^ field READ qualified
^^^ getter INVOCATION qualified
E(a).foo = 0;
^^^ field WRITE qualified
^^^ setter INVOCATION qualified
E(a).foo += 1;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
E(a).foo ??= 2;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
E(a).foo++;
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
--E(a).foo;
^^ num.- INVOCATION qualified
^^^ field READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
}
''',
);
}
test_searchReferences_FieldElement_ofExtensionType_static_fieldDeclaration() async {
var result = await resolveTestCode('''
/// [foo] and [A.foo]
extension type A(int it) {
static int foo = 0;
void useField() {
foo;
foo = 0;
}
}
void useField() {
A.foo;
A.foo = 0;
}
''');
var field = result.findElement.field('foo');
await assertElementsReferencesText(
{'field': field, 'getter': field.getter!, 'setter': field.setter!},
r'''
/// [foo] and [A.foo]
^^^ field REFERENCE
^^^ getter REFERENCE
^^^ field REFERENCE qualified
^^^ getter REFERENCE qualified
extension type A(int it) {
static int foo = 0;
void useField() {
foo;
^^^ field READ
^^^ getter INVOCATION
foo = 0;
^^^ field WRITE
^^^ setter INVOCATION
}
}
void useField() {
A.foo;
^^^ field READ qualified
^^^ getter INVOCATION qualified
A.foo = 0;
^^^ field WRITE qualified
^^^ setter INVOCATION qualified
}
''',
);
}
test_searchReferences_FormalParameterElement_multiplyDefined_generic() async {
newFile('$testPackageLibPath/a.dart', r'''
void foo<T>({T? test}) {}
''');
newFile('$testPackageLibPath/b.dart', r'''
void foo<T>({T? test}) {}
''');
var result = await resolveTestCode(r"""
import 'a.dart';
import 'b.dart';
void f() {
foo(test: 0);
}
""");
var elementA = result.findElement
.importFind('package:test/a.dart')
.topFunction('foo')
.parameter('test');
await assertElementReferencesText(elementA, r'''
import 'a.dart';
import 'b.dart';
void f() {
foo(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
''');
var elementB = result.findElement
.importFind('package:test/b.dart')
.topFunction('foo')
.parameter('test');
await assertElementReferencesText(elementB, r'''
''');
}
test_searchReferences_FormalParameterElement_ofConstructor_primary_optionalNamed() async {
var result = await resolveTestCode('''
class A({int? test}) {
/// [test]
this : assert(test != null) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
A.redirect({int? test}) : this(test: test);
}
class B extends A {
B({super.test});
}
class C extends A {
C({int? test}) : super(test: test);
}
void f() {
A(test: 0);
A _ = .new(test: 0);
}
''');
var element = result.findElement.unnamedConstructor('A').parameter('test');
await assertElementReferencesText(element, r'''
class A({int? test}) {
/// [test]
^^^^ REFERENCE
this : assert(test != null) {
^^^^ READ
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
A.redirect({int? test}) : this(test: test);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
class B extends A {
B({super.test});
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
class C extends A {
C({int? test}) : super(test: test);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
void f() {
A(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
A _ = .new(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
''');
}
test_searchReferences_FormalParameterElement_ofConstructor_primary_optionalNamed_genericClass() async {
var result = await resolveTestCode('''
class A<T>({T? test}) {
/// [test]
this : assert(test != null) {
test;
test = null;
(test,) = (null,);
for (test in [null]) {}
}
A.redirect({T? test}) : this(test: test);
}
class B<T> extends A<T> {
B({super.test});
}
class C<T> extends A<T> {
C({T? test}) : super(test: test);
}
void f() {
A(test: 0);
A<int> _ = .new(test: 0);
}
''');
var element = result.findElement.unnamedConstructor('A').parameter('test');
await assertElementReferencesText(element, r'''
class A<T>({T? test}) {
/// [test]
^^^^ REFERENCE
this : assert(test != null) {
^^^^ READ
test;
^^^^ READ
test = null;
^^^^ WRITE
(test,) = (null,);
^^^^ WRITE
for (test in [null]) {}
^^^^ WRITE
}
A.redirect({T? test}) : this(test: test);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
class B<T> extends A<T> {
B({super.test});
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
class C<T> extends A<T> {
C({T? test}) : super(test: test);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
void f() {
A(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
A<int> _ = .new(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
''');
}
test_searchReferences_FormalParameterElement_ofConstructor_primary_optionalPositional() async {
var result = await resolveTestCode('''
class A([int? test]) {
/// [test]
this : assert(test != null) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
A.redirect([int? test]) : this(test);
}
class B extends A {
B([super.test]);
}
class C extends A {
C([int? test]) : super(test);
}
void f() {
A(0);
A _ = .new(0);
}
''');
var element = result.findElement.unnamedConstructor('A').parameter('test');
await assertElementReferencesText(element, r'''
class A([int? test]) {
/// [test]
^^^^ REFERENCE
this : assert(test != null) {
^^^^ READ
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
A.redirect([int? test]) : this(test);
}
class B extends A {
B([super.test]);
^^^^ REFERENCE qualified
}
class C extends A {
C([int? test]) : super(test);
}
void f() {
A(0);
A _ = .new(0);
}
''');
}
test_searchReferences_FormalParameterElement_ofConstructor_primary_requiredNamed() async {
var result = await resolveTestCode('''
class A({required int test}) {
/// [test]
this : assert(test != -1) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
A.redirect({required int test}) : this(test: test);
}
class B extends A {
B({required super.test});
}
class C extends A {
C({required int test}) : super(test: test);
}
void f() {
A(test: 0);
A _ = .new(test: 0);
}
''');
var element = result.findElement.unnamedConstructor('A').parameter('test');
await assertElementReferencesText(element, r'''
class A({required int test}) {
/// [test]
^^^^ REFERENCE
this : assert(test != -1) {
^^^^ READ
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
A.redirect({required int test}) : this(test: test);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
class B extends A {
B({required super.test});
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
class C extends A {
C({required int test}) : super(test: test);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
void f() {
A(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
A _ = .new(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
''');
}
test_searchReferences_FormalParameterElement_ofConstructor_primary_requiredPositional() async {
var result = await resolveTestCode('''
class A(int test) {
/// [test]
this : assert(test != -1) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
A.redirect(int test) : this(test);
}
class B extends A {
B(super.test);
}
class C extends A {
C(int test) : super(test);
}
void f() {
A(0);
A _ = .new(0);
}
''');
var element = result.findElement.unnamedConstructor('A').parameter('test');
await assertElementReferencesText(element, r'''
class A(int test) {
/// [test]
^^^^ REFERENCE
this : assert(test != -1) {
^^^^ READ
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
A.redirect(int test) : this(test);
}
class B extends A {
B(super.test);
^^^^ REFERENCE qualified
}
class C extends A {
C(int test) : super(test);
}
void f() {
A(0);
A _ = .new(0);
}
''');
}
test_searchReferences_FormalParameterElement_ofConstructor_typeName_optionalNamed() async {
var result = await resolveTestCode('''
class A {
/// [test]
A({int? test}) : assert(test != null) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
A.redirect({int? test}) : this(test: test);
}
class B extends A {
B({super.test});
}
class C extends A {
C({int? test}) : super(test: test);
}
void f() {
A(test: 0);
A _ = .new(test: 0);
}
''');
var element = result.findElement.unnamedConstructor('A').parameter('test');
await assertElementReferencesText(element, r'''
class A {
/// [test]
^^^^ REFERENCE
A({int? test}) : assert(test != null) {
^^^^ READ
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
A.redirect({int? test}) : this(test: test);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
class B extends A {
B({super.test});
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
class C extends A {
C({int? test}) : super(test: test);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
void f() {
A(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
A _ = .new(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
''');
}
test_searchReferences_FormalParameterElement_ofConstructor_typeName_optionalNamed_genericClass() async {
var result = await resolveTestCode('''
class A<T> {
/// [test]
A({T? test}) : assert(test != null) {
test;
test = null;
(test,) = (null,);
for (test in [null]) {}
}
A.redirect({T? test}) : this(test: test);
}
class B<T> extends A<T> {
B({super.test});
}
class C<T> extends A<T> {
C({T? test}) : super(test: test);
}
void f() {
A(test: 0);
A<int> _ = .new(test: 0);
}
''');
var element = result.findElement.unnamedConstructor('A').parameter('test');
await assertElementReferencesText(element, r'''
class A<T> {
/// [test]
^^^^ REFERENCE
A({T? test}) : assert(test != null) {
^^^^ READ
test;
^^^^ READ
test = null;
^^^^ WRITE
(test,) = (null,);
^^^^ WRITE
for (test in [null]) {}
^^^^ WRITE
}
A.redirect({T? test}) : this(test: test);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
class B<T> extends A<T> {
B({super.test});
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
class C<T> extends A<T> {
C({T? test}) : super(test: test);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
void f() {
A(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
A<int> _ = .new(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
''');
}
test_searchReferences_FormalParameterElement_ofConstructor_typeName_optionalPositional() async {
var result = await resolveTestCode('''
class A {
/// [test]
A([int? test]) : assert(test != null) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
A.redirect([int? test]) : this(test);
}
class B extends A {
B([super.test]);
}
class C extends A {
C([int? test]) : super(test);
}
void f() {
A(0);
A _ = .new(0);
}
''');
var element = result.findElement.unnamedConstructor('A').parameter('test');
await assertElementReferencesText(element, r'''
class A {
/// [test]
^^^^ REFERENCE
A([int? test]) : assert(test != null) {
^^^^ READ
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
A.redirect([int? test]) : this(test);
}
class B extends A {
B([super.test]);
^^^^ REFERENCE qualified
}
class C extends A {
C([int? test]) : super(test);
}
void f() {
A(0);
A _ = .new(0);
}
''');
}
test_searchReferences_FormalParameterElement_ofConstructor_typeName_requiredNamed() async {
var result = await resolveTestCode('''
class A {
/// [test]
A({required int test}) : assert(test != -1) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
A.redirect({required int test}) : this(test: test);
}
class B extends A {
B({required super.test});
}
class C extends A {
C({required int test}) : super(test: test);
}
void f() {
A(test: 0);
A _ = .new(test: 0);
}
''');
var element = result.findElement.unnamedConstructor('A').parameter('test');
await assertElementReferencesText(element, r'''
class A {
/// [test]
^^^^ REFERENCE
A({required int test}) : assert(test != -1) {
^^^^ READ
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
A.redirect({required int test}) : this(test: test);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
class B extends A {
B({required super.test});
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
class C extends A {
C({required int test}) : super(test: test);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
void f() {
A(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
A _ = .new(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
''');
}
test_searchReferences_FormalParameterElement_ofConstructor_typeName_requiredPositional() async {
var result = await resolveTestCode('''
class A {
/// [test]
A(int test) : assert(test != -1) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
A.redirect(int test) : this(test);
}
class B extends A {
B(super.test);
}
class C extends A {
C(int test) : super(test);
}
void f() {
A(0);
A _ = .new(0);
}
''');
var element = result.findElement.unnamedConstructor('A').parameter('test');
await assertElementReferencesText(element, r'''
class A {
/// [test]
^^^^ REFERENCE
A(int test) : assert(test != -1) {
^^^^ READ
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
A.redirect(int test) : this(test);
}
class B extends A {
B(super.test);
^^^^ REFERENCE qualified
}
class C extends A {
C(int test) : super(test);
}
void f() {
A(0);
A _ = .new(0);
}
''');
}
test_searchReferences_FormalParameterElement_ofGenericFunctionType_optionalNamed() async {
var result = await resolveTestCode('''
typedef F = void Function({int? test});
void g(F f) {
f(test: 0);
}
''');
var element = result.findElement.parameter('test');
await assertElementReferencesText(element, r'''
''');
}
test_searchReferences_FormalParameterElement_ofGenericFunctionType_optionalNamed_call() async {
var result = await resolveTestCode('''
typedef F<T> = void Function({T? test});
void g(F<int> f) {
f.call(test: 0);
}
''');
var element = result.findElement.parameter('test');
await assertElementReferencesText(element, r'''
''');
}
test_searchReferences_FormalParameterElement_ofLocalFunction_optionalNamed() async {
_makeTestFilePriority();
var result = await resolveTestCode('''
void f() {
/// [test]
void foo({int? test}) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
foo(test: 0);
foo.call(test: 1);
(foo)(test: 2);
}
''');
var element = result.findElement.parameter('test');
await assertElementReferencesText(element, r'''
void f() {
/// [test]
void foo({int? test}) {
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
foo(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
foo.call(test: 1);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
(foo)(test: 2);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
''');
}
test_searchReferences_FormalParameterElement_ofLocalFunction_optionalNamed_generic() async {
_makeTestFilePriority();
var result = await resolveTestCode('''
void f() {
void foo<T>({T? test}) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
foo(test: 0);
foo.call(test: 1);
(foo)(test: 2);
}
''');
var element = result.findElement.parameter('test');
await assertElementReferencesText(element, r'''
void f() {
void foo<T>({T? test}) {
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
foo(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
foo.call(test: 1);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
(foo)(test: 2);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
''');
}
test_searchReferences_FormalParameterElement_ofLocalFunction_optionalPositional() async {
_makeTestFilePriority();
var result = await resolveTestCode('''
void f() {
/// [test]
void foo([int? test]) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
foo(0);
foo.call(1);
(foo)(2);
}
''');
var element = result.findElement.parameter('test');
await assertElementReferencesText(element, r'''
void f() {
/// [test]
void foo([int? test]) {
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
foo(0);
foo.call(1);
(foo)(2);
}
''');
}
test_searchReferences_FormalParameterElement_ofLocalFunction_requiredNamed() async {
_makeTestFilePriority();
var result = await resolveTestCode('''
void f() {
/// [test]
void foo({required int test}) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
foo(test: 0);
foo.call(test: 1);
(foo)(test: 2);
}
''');
var element = result.findElement.parameter('test');
await assertElementReferencesText(element, r'''
void f() {
/// [test]
void foo({required int test}) {
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
foo(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
foo.call(test: 1);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
(foo)(test: 2);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
''');
}
test_searchReferences_FormalParameterElement_ofLocalFunction_requiredPositional() async {
_makeTestFilePriority();
var result = await resolveTestCode('''
void f() {
/// [test]
void foo(int test) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
foo(0);
foo.call(1);
(foo)(2);
}
''');
var element = result.findElement.parameter('test');
await assertElementReferencesText(element, r'''
void f() {
/// [test]
void foo(int test) {
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
foo(0);
foo.call(1);
(foo)(2);
}
''');
}
test_searchReferences_FormalParameterElement_ofMethod_optionalNamed() async {
var result = await resolveTestCode('''
class A {
/// [test]
void foo({int? test}) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
}
void f(A a) {
a.foo(test: 0);
a.foo.call(test: 1);
(a.foo)(test: 2);
}
''');
var element = result.findElement.parameter('test');
await assertElementReferencesText(element, r'''
class A {
/// [test]
^^^^ REFERENCE
void foo({int? test}) {
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
}
void f(A a) {
a.foo(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
a.foo.call(test: 1);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
(a.foo)(test: 2);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
''');
}
test_searchReferences_FormalParameterElement_ofMethod_optionalNamed_genericClass() async {
var result = await resolveTestCode('''
class A<T> {
/// [test]
void foo({T? test}) {
test;
test = null;
test = test;
(test,) = (null,);
for (test in [null]) {}
}
}
void f(A<int> a) {
a.foo(test: 0);
a.foo.call(test: 1);
(a.foo)(test: 2);
}
''');
var element = result.findElement.parameter('test');
await assertElementReferencesText(element, r'''
class A<T> {
/// [test]
^^^^ REFERENCE
void foo({T? test}) {
test;
^^^^ READ
test = null;
^^^^ WRITE
test = test;
^^^^ WRITE
^^^^ READ
(test,) = (null,);
^^^^ WRITE
for (test in [null]) {}
^^^^ WRITE
}
}
void f(A<int> a) {
a.foo(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
a.foo.call(test: 1);
(a.foo)(test: 2);
}
''');
}
test_searchReferences_FormalParameterElement_ofMethod_optionalPositional() async {
var result = await resolveTestCode('''
class A {
/// [test]
void foo([int? test]) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
}
void f(A a) {
a.foo(0);
a.foo.call(1);
(a.foo)(2);
}
''');
var element = result.findElement.parameter('test');
await assertElementReferencesText(element, r'''
class A {
/// [test]
^^^^ REFERENCE
void foo([int? test]) {
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
}
void f(A a) {
a.foo(0);
a.foo.call(1);
(a.foo)(2);
}
''');
}
test_searchReferences_FormalParameterElement_ofMethod_requiredNamed() async {
var result = await resolveTestCode('''
class A {
/// [test]
void foo({required int test}) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
}
void f(A a) {
a.foo(test: 0);
a.foo.call(test: 1);
(a.foo)(test: 2);
}
''');
var element = result.findElement.parameter('test');
await assertElementReferencesText(element, r'''
class A {
/// [test]
^^^^ REFERENCE
void foo({required int test}) {
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
}
void f(A a) {
a.foo(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
a.foo.call(test: 1);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
(a.foo)(test: 2);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
''');
}
test_searchReferences_FormalParameterElement_ofMethod_requiredPositional() async {
var result = await resolveTestCode('''
class A {
/// [test]
void foo(int test) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
}
void f(A a) {
a.foo(0);
a.foo.call(1);
(a.foo)(2);
}
''');
var element = result.findElement.parameter('test');
await assertElementReferencesText(element, r'''
class A {
/// [test]
^^^^ REFERENCE
void foo(int test) {
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
}
void f(A a) {
a.foo(0);
a.foo.call(1);
(a.foo)(2);
}
''');
}
test_searchReferences_FormalParameterElement_ofTopLevelFunction_optionalNamed() async {
var result = await resolveTestCode('''
/// [test]
void foo({int? test}) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
void f() {
foo(test: 0);
foo.call(test: 1);
(foo)(test: 2);
}
''');
var element = result.findElement.parameter('test');
await assertElementReferencesText(element, r'''
/// [test]
^^^^ REFERENCE
void foo({int? test}) {
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
void f() {
foo(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
foo.call(test: 1);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
(foo)(test: 2);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
''');
}
test_searchReferences_FormalParameterElement_ofTopLevelFunction_optionalNamed_argumentAnywhere() async {
var result = await resolveTestCode('''
/// [test]
void foo(int a, int b, {int? test}) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
void f() {
foo(0, test: 0, 0);
foo.call(0, test: 1, 0);
(foo)(0, test: 2, 0);
}
''');
var element = result.findElement.parameter('test');
await assertElementReferencesText(element, r'''
/// [test]
^^^^ REFERENCE
void foo(int a, int b, {int? test}) {
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
void f() {
foo(0, test: 0, 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
foo.call(0, test: 1, 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
(foo)(0, test: 2, 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
''');
}
test_searchReferences_FormalParameterElement_ofTopLevelFunction_optionalPositional() async {
var result = await resolveTestCode('''
/// [test]
void foo([int? test]) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
void f() {
foo(0);
foo.call(1);
(foo)(2);
}
''');
var element = result.findElement.parameter('test');
await assertElementReferencesText(element, r'''
/// [test]
^^^^ REFERENCE
void foo([int? test]) {
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
void f() {
foo(0);
foo.call(1);
(foo)(2);
}
''');
}
test_searchReferences_FormalParameterElement_ofTopLevelFunction_requiredNamed() async {
var result = await resolveTestCode('''
/// [test]
void foo({required int test}) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
void f() {
foo(test: 0);
foo.call(test: 1);
(foo)(test: 2);
}
''');
var element = result.findElement.parameter('test');
await assertElementReferencesText(element, r'''
/// [test]
^^^^ REFERENCE
void foo({required int test}) {
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
void f() {
foo(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
foo.call(test: 1);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
(foo)(test: 2);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
''');
}
test_searchReferences_FormalParameterElement_ofTopLevelFunction_requiredPositional() async {
var result = await resolveTestCode('''
/// [test]
void foo(int test) {
test;
test = 0;
test += 0;
(test,) = (0,);
for (test in [0]) {}
}
void f() {
foo(0);
foo.call(1);
(foo)(2);
}
''');
var element = result.findElement.parameter('test');
await assertElementReferencesText(element, r'''
/// [test]
^^^^ REFERENCE
void foo(int test) {
test;
^^^^ READ
test = 0;
^^^^ WRITE
test += 0;
^^^^ READ_WRITE
(test,) = (0,);
^^^^ WRITE
for (test in [0]) {}
^^^^ WRITE
}
void f() {
foo(0);
foo.call(1);
(foo)(2);
}
''');
}
test_searchReferences_FormalParameterElement_synthetic_leastUpperBound() async {
var result = await resolveTestCode('''
int f1({int? test}) => 0;
int f2({int? test}) => 0;
void g(bool b) {
var f = b ? f1 : f2;
f(test: 0);
}''');
var element1 = result.findElement.function('f1').parameter('test');
await assertElementReferencesText(element1, r'''
''');
var element2 = result.findElement.function('f2').parameter('test');
await assertElementReferencesText(element2, r'''
''');
}
test_searchReferences_FunctionElement() async {
var result = await resolveTestCode('''
test() {}
main() {
test();
test;
}
''');
var element = result.findElement.function('test');
await assertElementReferencesText(element, r'''
test() {}
main() {
test();
^^^^ INVOCATION
test;
^^^^ REFERENCE
}
''');
}
test_searchReferences_FunctionElement_local() async {
makeFilePriority(testFile);
var result = await resolveTestCode('''
main() {
test() {}
test();
test;
}
''');
var element = result.findElement.localFunction('test');
await assertElementReferencesText(element, r'''
main() {
test() {}
test();
^^^^ INVOCATION
test;
^^^^ REFERENCE
}
''');
}
test_searchReferences_GetterElement_ofClass_instance_invalidWrite() async {
var result = await resolveTestCode('''
class A {
int get foo => 0;
void f() {
foo = 1;
}
}
''');
var element = result.findElement.getter('foo');
await assertElementReferencesText(element, r'''
class A {
int get foo => 0;
void f() {
foo = 1;
^^^ REFERENCE
}
}
''');
}
test_searchReferences_GetterElement_ofClass_invocation() async {
var result = await resolveTestCode('''
class A {
get foo => null;
void useGetter() {
this.foo();
foo();
}
}''');
var element = result.findElement.getter('foo');
await assertElementReferencesText(element, r'''
class A {
get foo => null;
void useGetter() {
this.foo();
^^^ INVOCATION qualified
foo();
^^^ INVOCATION
}
}
''');
}
test_searchReferences_GetterElement_ofClass_objectPattern() async {
var result = await resolveTestCode('''
class A {
int get foo => 0;
}
void useGetter(Object? x) {
if (x case A(foo: 0)) {}
if (x case A(: var foo)) {}
}
''');
var element = result.findElement.getter('foo');
await assertElementReferencesText(element, r'''
class A {
int get foo => 0;
}
void useGetter(Object? x) {
if (x case A(foo: 0)) {}
^^^ REFERENCE_IN_PATTERN_FIELD qualified
if (x case A(: var foo)) {}
^0 REFERENCE_IN_PATTERN_FIELD qualified
}
''');
}
test_searchReferences_GetterElement_ofClass_objectPattern_otherFile() async {
String other = convertPath('$testPackageLibPath/other.dart');
String otherCode = '''
import 'test.dart';
void useGetter(Object? x) {
if (x case A(foo: 0)) {}
if (x case A(: var foo)) {}
}
''';
newFile(other, otherCode);
var result = await resolveTestCode('''
class A {
int get foo => 0;
}
''');
var element = result.findElement.getter('foo');
await assertElementReferencesText(element, r'''
package:test/other.dart
-----------------------
import 'test.dart';
void useGetter(Object? x) {
if (x case A(foo: 0)) {}
^^^ REFERENCE_IN_PATTERN_FIELD qualified
if (x case A(: var foo)) {}
^0 REFERENCE_IN_PATTERN_FIELD qualified
}
''');
}
test_searchReferences_GetterElement_ofClass_parenthesizedReceiver_read() async {
var result = await resolveTestCode('''
class A {
int get foo => 0;
void useGetter() {
(this).foo;
}
}''');
var element = result.findElement.getter('foo');
await assertElementReferencesText(element, r'''
class A {
int get foo => 0;
void useGetter() {
(this).foo;
^^^ INVOCATION qualified
}
}
''');
}
test_searchReferences_GetterElement_ofClass_static() async {
var result = await resolveTestCode('''
import 'test.dart' as p;
/// [foo], [A.foo], [p.A.foo]
class A {
static int get foo => 0;
static void useGetter() {
foo;
}
}
void useGetter() {
A.foo;
p.A.foo;
}
''');
var element = result.findElement.getter('foo');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
/// [foo], [A.foo], [p.A.foo]
^^^ REFERENCE
^^^ REFERENCE qualified
^^^ REFERENCE qualified
class A {
static int get foo => 0;
static void useGetter() {
foo;
^^^ INVOCATION
}
}
void useGetter() {
A.foo;
^^^ INVOCATION qualified
p.A.foo;
^^^ INVOCATION qualified
}
''');
}
test_searchReferences_ImportElement_noPrefix() async {
var result = await resolveTestCode('''
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;
''');
var element = result.findElement.import('dart:math', mustBeUnique: false);
await assertLibraryImportReferencesText(element, r'''
import 'dart:math' show max, pi, Random hide min;
export 'dart:math' show max, pi, Random hide min;
main() {
pi;
^0
new Random();
^0
max(1, 2);
^0
}
Random bar() => null;
^0
''');
}
test_searchReferences_ImportElement_noPrefix_inPackage() async {
var aaaPackageRootPath = '$packagesRootPath/aaa';
var aaaFilePath = convertPath('$aaaPackageRootPath/lib/a.dart');
writeTestPackageConfig(
PackageConfigFileBuilder()
..add(name: 'aaa', rootFolder: getFolder(aaaPackageRootPath)),
);
fileForContextSelection = testFile;
var result = 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;
''');
var element = result.findElement.import('dart:math');
await assertLibraryImportReferencesText(element, r'''
package:aaa/a.dart
------------------
import 'dart:math' show max, pi, Random hide min;
export 'dart:math' show max, pi, Random hide min;
main() {
pi;
^0
new Random();
^0
max(1, 2);
^0
}
Random bar() => null;
^0
''');
}
test_searchReferences_ImportElement_withPrefix() async {
var result = await resolveTestCode('''
import 'dart:math' as math show max, pi, Random hide min;
export 'dart:math' show max, pi, Random hide min;
main() {
math.pi;
new math.Random();
math.max(1, 2);
}
math.Random bar() => null;
''');
var element = result.findElement.import('dart:math', mustBeUnique: false);
await assertLibraryImportReferencesText(element, r'''
import 'dart:math' as math show max, pi, Random hide min;
export 'dart:math' show max, pi, Random hide min;
main() {
math.pi;
^^^^^
new math.Random();
^^^^^
math.max(1, 2);
^^^^^
}
math.Random bar() => null;
^^^^^
''');
}
test_searchReferences_ImportElement_withPrefix_forMultipleImports() async {
var result = await resolveTestCode('''
import 'dart:async' as p;
import 'dart:math' as p;
main() {
p.Random r;
p.Future f;
}
''');
{
var element = result.findElement.import('dart:async');
await assertLibraryImportReferencesText(element, r'''
import 'dart:async' as p;
import 'dart:math' as p;
main() {
p.Random r;
p.Future f;
^^
}
''');
}
{
var element = result.findElement.import('dart:math');
await assertLibraryImportReferencesText(element, r'''
import 'dart:async' as p;
import 'dart:math' as p;
main() {
p.Random r;
^^
p.Future f;
}
''');
}
}
test_searchReferences_LabelElement() async {
makeFilePriority(testFile);
var result = await resolveTestCode('''
main() {
label:
while (true) {
if (true) {
break label;
}
break label;
}
}
''');
var element = result.findElement.label('label');
await assertElementReferencesText(element, r'''
main() {
label:
while (true) {
if (true) {
break label;
^^^^^ REFERENCE
}
break label;
^^^^^ REFERENCE
}
}
''');
}
test_searchReferences_LibraryElement_inPackage() async {
var aaaPackageRootPath = '$packagesRootPath/aaa';
writeTestPackageConfig(
PackageConfigFileBuilder()
..add(name: 'aaa', rootFolder: getFolder(aaaPackageRootPath)),
);
var libPath = convertPath('$aaaPackageRootPath/lib/a.dart');
var partPathA = convertPath('$aaaPackageRootPath/lib/unitA.dart');
var partPathB = convertPath('$aaaPackageRootPath/lib/unitB.dart');
newFile(partPathA, 'part of lib;');
newFile(partPathB, 'part of lib;');
fileForContextSelection = testFile;
var result = await resolveFileCode(libPath, '''
library lib;
part 'unitA.dart';
part 'unitB.dart';
''');
var element = result.libraryElement;
await assertElementReferencesText(element, r'''
package:aaa/unitA.dart
----------------------
part of lib;
^^^ REFERENCE
package:aaa/unitB.dart
----------------------
part of lib;
^^^ REFERENCE
''');
}
test_searchReferences_LibraryElement_partOfName() async {
newFile('$testPackageLibPath/unitA.dart', 'part of lib;');
newFile('$testPackageLibPath/unitB.dart', 'part of lib;');
var result = await resolveTestCode('''
library lib;
part 'unitA.dart';
part 'unitB.dart';
''');
var element = result.libraryElement;
await assertElementReferencesText(element, r'''
package:test/unitA.dart
-----------------------
part of lib;
^^^ REFERENCE
package:test/unitB.dart
-----------------------
part of lib;
^^^ REFERENCE
''');
}
test_searchReferences_LibraryElement_partOfUri() async {
newFile('$testPackageLibPath/unitA.dart', r'''
part of 'test.dart';
''');
newFile('$testPackageLibPath/unitB.dart', r'''
part of 'test.dart';
''');
var result = await resolveTestCode('''
part 'unitA.dart';
part 'unitB.dart';
''');
var element = result.libraryElement;
await assertElementReferencesText(element, r'''
package:test/unitA.dart
-----------------------
part of 'test.dart';
^^^^^^^^^^^ REFERENCE
package:test/unitB.dart
-----------------------
part of 'test.dart';
^^^^^^^^^^^ REFERENCE
''');
}
test_searchReferences_LibraryFragment_reference_export() async {
newFile('$testPackageLibPath/foo.dart', '');
var result = await resolveTestCode('''
export 'foo.dart';
''');
var element = result.findElement
.export('package:test/foo.dart')
.exportedLibrary!
.firstFragment;
await assertLibraryFragmentReferencesText(element, r'''
export 'foo.dart';
^^^^^^^^^^
''');
}
test_searchReferences_LibraryFragment_reference_import() async {
newFile('$testPackageLibPath/foo.dart', '');
var result = await resolveTestCode('''
import 'foo.dart';
''');
var element = result.findElement
.importFind('package:test/foo.dart')
.libraryFragment;
await assertLibraryFragmentReferencesText(element, r'''
import 'foo.dart';
^^^^^^^^^^
''');
}
test_searchReferences_LibraryFragment_reference_part() async {
newFile('$testPackageLibPath/foo.dart', r'''
part of 'test.dart';
''');
var result = await resolveTestCode('''
part 'foo.dart';
''');
var element = result.findElement.part('package:test/foo.dart');
await assertLibraryFragmentReferencesText(element, r'''
part 'foo.dart';
^^^^^^^^^^
''');
}
test_searchReferences_LocalVariableElement() async {
makeFilePriority(testFile);
var result = await resolveTestCode(r'''
main() {
var v;
v = 1;
v += 2;
v;
v();
}
''');
var element = result.findElement.localVar('v');
await assertElementReferencesText(element, r'''
main() {
var v;
v = 1;
^ WRITE
v += 2;
^ READ_WRITE
v;
^ READ
v();
^ READ
}
''');
}
test_searchReferences_LocalVariableElement_inForEachElement_expressionBody() async {
makeFilePriority(testFile);
var result = await resolveTestCode('''
Object f() => [
for (var v in []) v,
];
''');
var element = result.findElement.localVar('v');
await assertElementReferencesText(element, r'''
Object f() => [
for (var v in []) v,
^ READ
];
''');
}
test_searchReferences_LocalVariableElement_inForEachElement_inBlock() async {
makeFilePriority(testFile);
var result = await resolveTestCode('''
Object f() {
{
return [
for (var v in []) v,
];
}
}
''');
var element = result.findElement.localVar('v');
await assertElementReferencesText(element, r'''
Object f() {
{
return [
for (var v in []) v,
^ READ
];
}
}
''');
}
test_searchReferences_LocalVariableElement_inForEachElement_inFunctionBody() async {
makeFilePriority(testFile);
var result = await resolveTestCode('''
Object f() {
return [
for (var v in []) v,
];
}
''');
var element = result.findElement.localVar('v');
await assertElementReferencesText(element, r'''
Object f() {
return [
for (var v in []) v,
^ READ
];
}
''');
}
test_searchReferences_LocalVariableElement_inForEachElement_topLevel() async {
makeFilePriority(testFile);
var result = await resolveTestCode('''
var x = [
for (var v in []) v,
];
''');
var element = result.findElement.localVar('v');
await assertElementReferencesText(element, r'''
var x = [
for (var v in []) v,
^ READ
];
''');
}
test_searchReferences_LocalVariableElement_inForEachLoop() async {
makeFilePriority(testFile);
var result = await resolveTestCode('''
main() {
for (var v in []) {
v = 1;
v += 2;
v;
v();
}
}
''');
var element = result.findElement.localVar('v');
await assertElementReferencesText(element, r'''
main() {
for (var v in []) {
v = 1;
^ WRITE
v += 2;
^ READ_WRITE
v;
^ READ
v();
^ READ
}
}
''');
}
test_searchReferences_LocalVariableElement_inPackage() async {
var aaaPackageRootPath = '$packagesRootPath/aaa';
var a_file = newFile('$aaaPackageRootPath/lib/a.dart', '''
main() {
var v;
v = 1;
v += 2;
v;
v();
}
''');
writeTestPackageConfig(
PackageConfigFileBuilder()
..add(name: 'aaa', rootFolder: getFolder(aaaPackageRootPath)),
);
fileForContextSelection = testFile;
driverFor(testFile).priorityFiles2 = [a_file];
var result = await resolveFile2(a_file);
var element = result.findElement.localVar('v');
await assertElementReferencesText(element, r'''
package:aaa/a.dart
------------------
main() {
var v;
v = 1;
^ WRITE
v += 2;
^ READ_WRITE
v;
^ READ
v();
^ READ
}
''');
}
test_searchReferences_MethodElement_normal_ofClass_instance() async {
var result = await resolveTestCode('''
/// [foo] and [A.foo]
class A {
void foo() {}
void useFoo(Object? x) {
this.foo();
foo();
this.foo;
foo;
if (x case A(foo: _)) {}
if (x case A(: var foo)) {}
}
}
void useFoo(A a) {
a.foo();
a.foo;
}
''');
var element = result.findElement.method('foo');
await assertElementReferencesText(element, r'''
/// [foo] and [A.foo]
^^^ REFERENCE
^^^ REFERENCE qualified
class A {
void foo() {}
void useFoo(Object? x) {
this.foo();
^^^ INVOCATION qualified
foo();
^^^ INVOCATION
this.foo;
^^^ REFERENCE qualified
foo;
^^^ REFERENCE
if (x case A(foo: _)) {}
^^^ REFERENCE qualified
if (x case A(: var foo)) {}
^0 REFERENCE qualified
}
}
void useFoo(A a) {
a.foo();
^^^ INVOCATION qualified
a.foo;
^^^ REFERENCE qualified
}
''');
}
test_searchReferences_MethodElement_normal_ofClass_instance_generic() async {
var result = await resolveTestCode('''
/// [foo] and [A.foo]
class A<T> {
void foo() {}
void useFoo(Object? x) {
this.foo();
foo();
this.foo;
foo;
if (x case A<int>(foo: _)) {}
if (x case A<int>(: var foo)) {}
}
}
void useFoo(A<int> a) {
a.foo();
a.foo;
}
''');
var element = result.findElement.method('foo');
await assertElementReferencesText(element, r'''
/// [foo] and [A.foo]
^^^ REFERENCE
^^^ REFERENCE qualified
class A<T> {
void foo() {}
void useFoo(Object? x) {
this.foo();
^^^ INVOCATION qualified
foo();
^^^ INVOCATION
this.foo;
^^^ REFERENCE qualified
foo;
^^^ REFERENCE
if (x case A<int>(foo: _)) {}
^^^ REFERENCE qualified
if (x case A<int>(: var foo)) {}
^0 REFERENCE qualified
}
}
void useFoo(A<int> a) {
a.foo();
^^^ INVOCATION qualified
a.foo;
^^^ REFERENCE qualified
}
''');
}
test_searchReferences_MethodElement_normal_ofClass_parenthesizedReceiver_ifNull() async {
var result = await resolveTestCode('''
class A {
void foo() {}
}
void f(A a) {
(a).foo ??= () {};
// ^^^
// [diag.assignmentToMethod] Methods can't be assigned a value.
// ^^^^^
// [diag.deadCode] Dead code.
// [diag.deadNullAwareExpression] The left operand can't be null, so the right operand is never executed.
}
''');
var element = result.findElement.method('foo');
await assertElementReferencesText(element, r'''
class A {
void foo() {}
}
void f(A a) {
(a).foo ??= () {};
^^^ REFERENCE qualified
// ^^^
// [diag.assignmentToMethod] Methods can't be assigned a value.
// ^^^^^
// [diag.deadCode] Dead code.
// [diag.deadNullAwareExpression] The left operand can't be null, so the right operand is never executed.
}
''');
}
test_searchReferences_MethodElement_normal_ofClass_static() async {
var result = await resolveTestCode('''
import 'test.dart' as p;
/// [foo], [A.foo], [p.A.foo]
class A {
static A foo() => A();
static void useFoo() {
foo();
foo;
}
}
void useFoo() {
A.foo();
A.foo;
A a = .foo();
A aa = .foo;
p.A.foo();
p.A.foo;
}
''');
var element = result.findElement.method('foo');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
/// [foo], [A.foo], [p.A.foo]
^^^ REFERENCE
^^^ REFERENCE qualified
^^^ REFERENCE qualified
class A {
static A foo() => A();
static void useFoo() {
foo();
^^^ INVOCATION
foo;
^^^ REFERENCE
}
}
void useFoo() {
A.foo();
^^^ INVOCATION qualified
A.foo;
^^^ REFERENCE qualified
A a = .foo();
^^^ INVOCATION qualified
A aa = .foo;
^^^ REFERENCE qualified
p.A.foo();
^^^ INVOCATION qualified
p.A.foo;
^^^ REFERENCE qualified
}
''');
}
test_searchReferences_MethodElement_normal_ofClass_static_dotShorthand_otherFile() async {
// Note, we don't mention `A`, only the method name `foo`.
newFile('$testPackageLibPath/other.dart', '''
import 'test.dart';
void useFoo() {
useA(.foo());
}
''');
var result = await resolveTestCode('''
class A {
static A foo() => A();
}
void useA(A a) {}
''');
var element = result.findElement.method('foo');
await assertElementReferencesText(element, r'''
package:test/other.dart
-----------------------
import 'test.dart';
void useFoo() {
useA(.foo());
^^^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_normal_ofClass_static_viaTypeAlias_otherFile() async {
newFile('$testPackageLibPath/other.dart', '''
import 'test.dart';
void useFoo() {
B.foo();
B.foo;
}
''');
var result = await resolveTestCode('''
class A {
static A foo() => A();
}
typedef B = A;
''');
var element = result.findElement.method('foo');
await assertElementReferencesText(element, r'''
package:test/other.dart
-----------------------
import 'test.dart';
void useFoo() {
B.foo();
^^^ INVOCATION qualified
B.foo;
^^^ REFERENCE qualified
}
''');
}
test_searchReferences_MethodElement_normal_ofEnum_instance() async {
var result = await resolveTestCode('''
/// [foo] and [E.foo]
enum E {
v;
void foo() {}
void useFoo() {
this.foo();
foo();
this.foo;
foo;
}
}
void useFoo(E e) {
e.foo();
e.foo;
}
''');
var element = result.findElement.method('foo');
await assertElementReferencesText(element, r'''
/// [foo] and [E.foo]
^^^ REFERENCE
^^^ REFERENCE qualified
enum E {
v;
void foo() {}
void useFoo() {
this.foo();
^^^ INVOCATION qualified
foo();
^^^ INVOCATION
this.foo;
^^^ REFERENCE qualified
foo;
^^^ REFERENCE
}
}
void useFoo(E e) {
e.foo();
^^^ INVOCATION qualified
e.foo;
^^^ REFERENCE qualified
}
''');
}
test_searchReferences_MethodElement_normal_ofEnum_static() async {
var result = await resolveTestCode('''
/// [foo] and [E.foo]
enum E {
v;
static void foo() {}
static void useFoo() {
foo();
foo;
}
}
void useFoo() {
E.foo();
E.foo;
}
''');
var element = result.findElement.method('foo');
await assertElementReferencesText(element, r'''
/// [foo] and [E.foo]
^^^ REFERENCE
^^^ REFERENCE qualified
enum E {
v;
static void foo() {}
static void useFoo() {
foo();
^^^ INVOCATION
foo;
^^^ REFERENCE
}
}
void useFoo() {
E.foo();
^^^ INVOCATION qualified
E.foo;
^^^ REFERENCE qualified
}
''');
}
test_searchReferences_MethodElement_normal_ofExtension_named_instance() async {
var result = await resolveTestCode('''
/// [foo] and [E.foo]
extension E on int {
void foo() {}
}
void useFoo() {
0.foo();
0.foo;
}
''');
var element = result.findElement.method('foo');
await assertElementReferencesText(element, r'''
/// [foo] and [E.foo]
^^^ REFERENCE
^^^ REFERENCE qualified
extension E on int {
void foo() {}
}
void useFoo() {
0.foo();
^^^ INVOCATION qualified
0.foo;
^^^ REFERENCE qualified
}
''');
}
test_searchReferences_MethodElement_normal_ofExtension_named_static() async {
var result = await resolveTestCode('''
/// [foo] and [E.foo]
extension E on int {
static void foo() {}
}
void useFoo() {
E.foo();
E.foo;
}
''');
var element = result.findElement.method('foo');
await assertElementReferencesText(element, r'''
/// [foo] and [E.foo]
^^^ REFERENCE
^^^ REFERENCE qualified
extension E on int {
static void foo() {}
}
void useFoo() {
E.foo();
^^^ INVOCATION qualified
E.foo;
^^^ REFERENCE qualified
}
''');
}
test_searchReferences_MethodElement_normal_ofExtension_unnamed_instance() async {
var result = await resolveTestCode('''
/// [foo] and [int.foo]
extension on int {
void foo() {} // int
}
/// [foo] and [double.foo]
extension on double {
void foo() {} // double
}
void useFoo() {
0.foo();
0.foo;
(1.2).foo();
(1.2).foo;
}
''');
var intMethod = result.findNode.methodDeclaration('foo() {} // int');
var intMethodElement = intMethod.declaredFragment!.element;
await assertElementReferencesText(intMethodElement, r'''
/// [foo] and [int.foo]
^^^ REFERENCE
extension on int {
void foo() {} // int
}
/// [foo] and [double.foo]
extension on double {
void foo() {} // double
}
void useFoo() {
0.foo();
^^^ INVOCATION qualified
0.foo;
^^^ REFERENCE qualified
(1.2).foo();
(1.2).foo;
}
''');
var doubleMethod = result.findNode.methodDeclaration('foo() {} // double');
var doubleMethodElement = doubleMethod.declaredFragment!.element;
await assertElementReferencesText(doubleMethodElement, r'''
/// [foo] and [int.foo]
extension on int {
void foo() {} // int
}
/// [foo] and [double.foo]
^^^ REFERENCE
extension on double {
void foo() {} // double
}
void useFoo() {
0.foo();
0.foo;
(1.2).foo();
^^^ INVOCATION qualified
(1.2).foo;
^^^ REFERENCE qualified
}
''');
}
test_searchReferences_MethodElement_normal_ofExtensionType_instance() async {
var result = await resolveTestCode('''
/// [foo] and [A.foo]
extension type A(int it) {
void foo() {}
void useFoo() {
this.foo();
foo();
this.foo;
foo;
}
}
void useFoo() {
var a = A(0);
a.foo();
a.foo;
}
''');
var element = result.findElement.method('foo');
await assertElementReferencesText(element, r'''
/// [foo] and [A.foo]
^^^ REFERENCE
^^^ REFERENCE qualified
extension type A(int it) {
void foo() {}
void useFoo() {
this.foo();
^^^ INVOCATION qualified
foo();
^^^ INVOCATION
this.foo;
^^^ REFERENCE qualified
foo;
^^^ REFERENCE
}
}
void useFoo() {
var a = A(0);
a.foo();
^^^ INVOCATION qualified
a.foo;
^^^ REFERENCE qualified
}
''');
}
test_searchReferences_MethodElement_normal_ofExtensionType_static() async {
var result = await resolveTestCode('''
/// [foo] and [A.foo]
extension type A(int it) {
static void foo() {}
static void useFoo() {
foo();
foo;
}
}
void useFoo() {
A.foo();
A.foo;
}
''');
var element = result.findElement.method('foo');
await assertElementReferencesText(element, r'''
/// [foo] and [A.foo]
^^^ REFERENCE
^^^ REFERENCE qualified
extension type A(int it) {
static void foo() {}
static void useFoo() {
foo();
^^^ INVOCATION
foo;
^^^ REFERENCE
}
}
void useFoo() {
A.foo();
^^^ INVOCATION qualified
A.foo;
^^^ REFERENCE qualified
}
''');
}
test_searchReferences_MethodElement_normal_ofMixin_instance() async {
var result = await resolveTestCode('''
/// [foo] and [M.foo]
mixin M {
void foo() {}
void useFoo() {
this.foo();
foo();
this.foo;
foo;
}
}
void useFoo(M m) {
m.foo();
m.foo;
}
''');
var element = result.findElement.method('foo');
await assertElementReferencesText(element, r'''
/// [foo] and [M.foo]
^^^ REFERENCE
^^^ REFERENCE qualified
mixin M {
void foo() {}
void useFoo() {
this.foo();
^^^ INVOCATION qualified
foo();
^^^ INVOCATION
this.foo;
^^^ REFERENCE qualified
foo;
^^^ REFERENCE
}
}
void useFoo(M m) {
m.foo();
^^^ INVOCATION qualified
m.foo;
^^^ REFERENCE qualified
}
''');
}
test_searchReferences_MethodElement_normal_ofMixin_static() async {
var result = await resolveTestCode('''
/// [foo] and [M.foo]
mixin M {
static void foo() {}
static void useFoo() {
foo();
foo;
}
}
void useFoo() {
M.foo();
M.foo;
M m = .foo();
}
''');
var element = result.findElement.method('foo');
await assertElementReferencesText(element, r'''
/// [foo] and [M.foo]
^^^ REFERENCE
^^^ REFERENCE qualified
mixin M {
static void foo() {}
static void useFoo() {
foo();
^^^ INVOCATION
foo;
^^^ REFERENCE
}
}
void useFoo() {
M.foo();
^^^ INVOCATION qualified
M.foo;
^^^ REFERENCE qualified
M m = .foo();
^^^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_operator_ofClass_binary() async {
var result = await resolveTestCode('''
/// [operator +] and [A.operator +]
class A {
operator +(other) => this;
}
void useOperator(A a) {
a + 1;
a += 2;
++a;
a++;
}
''');
var element = result.findElement.method('+');
await assertElementReferencesText(element, r'''
/// [operator +] and [A.operator +]
^ REFERENCE
^ REFERENCE qualified
class A {
operator +(other) => this;
}
void useOperator(A a) {
a + 1;
^ INVOCATION qualified
a += 2;
^^ INVOCATION qualified
++a;
^^ INVOCATION qualified
a++;
^^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_operator_ofClass_indexAssignmentTarget() async {
var result = await resolveTestCode('''
class A {
num operator [](int i) => 0;
void operator []=(int i, num v) {}
}
class B {
num? operator [](int i) => 0;
void operator []=(int i, num v) {}
}
void useOperator(A a, A? nullableA, B b, B? nullableB) {
a[0] = 1;
nullableA?[1] = 2;
a[2] += 3;
nullableA?[3] += 4;
b[4] ??= 5;
nullableB?[5] ??= 6;
}
''');
await assertElementsReferencesText(
{
'aRead': result.findElement.method('[]', of: 'A'),
'aWrite': result.findElement.method('[]=', of: 'A'),
'bRead': result.findElement.method('[]', of: 'B'),
'bWrite': result.findElement.method('[]=', of: 'B'),
'num.+': result.typeProvider.numElement.getMethod('+')!,
},
r'''
class A {
num operator [](int i) => 0;
void operator []=(int i, num v) {}
}
class B {
num? operator [](int i) => 0;
void operator []=(int i, num v) {}
}
void useOperator(A a, A? nullableA, B b, B? nullableB) {
a[0] = 1;
^ aWrite INVOCATION qualified
nullableA?[1] = 2;
^ aWrite INVOCATION qualified
a[2] += 3;
^ aRead INVOCATION qualified
^ aWrite INVOCATION qualified
^^ num.+ INVOCATION qualified
nullableA?[3] += 4;
^ aRead INVOCATION qualified
^ aWrite INVOCATION qualified
^^ num.+ INVOCATION qualified
b[4] ??= 5;
^ bRead INVOCATION qualified
^ bWrite INVOCATION qualified
nullableB?[5] ??= 6;
^ bRead INVOCATION qualified
^ bWrite INVOCATION qualified
}
''',
);
}
test_searchReferences_MethodElement_operator_ofClass_indexExpression() async {
var result = await resolveTestCode('''
/// [operator []] and [A.operator []]
class A {
num operator [](int i) => 0;
}
void useOperator(A a, A? b) {
a[0];
b?[1];
}
''');
var element = result.findElement.method('[]');
await assertElementReferencesText(element, r'''
/// [operator []] and [A.operator []]
class A {
num operator [](int i) => 0;
}
void useOperator(A a, A? b) {
a[0];
^ INVOCATION qualified
b?[1];
^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_operator_ofClass_prefix() async {
var result = await resolveTestCode('''
/// [operator ~] and [A.operator ~]
class A {
A operator ~() => this;
}
void useOperator(A a) {
~a;
}
''');
var element = result.findElement.method('~');
await assertElementReferencesText(element, r'''
/// [operator ~] and [A.operator ~]
^ REFERENCE
^ REFERENCE qualified
class A {
A operator ~() => this;
}
void useOperator(A a) {
~a;
^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_operator_ofEnum_binary() async {
var result = await resolveTestCode('''
/// [operator +] and [E.operator +]
enum E {
v;
int operator +(other) => 0;
}
void useOperator(E e) {
e + 1;
e += 2;
++e;
e++;
}
''');
var element = result.findElement.method('+');
await assertElementReferencesText(element, r'''
/// [operator +] and [E.operator +]
^ REFERENCE
^ REFERENCE qualified
enum E {
v;
int operator +(other) => 0;
}
void useOperator(E e) {
e + 1;
^ INVOCATION qualified
e += 2;
^^ INVOCATION qualified
++e;
^^ INVOCATION qualified
e++;
^^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_operator_ofEnum_index() async {
var result = await resolveTestCode('''
/// [operator []] and [E.operator []]
enum E {
v;
int operator [](int index) => 0;
}
void useOperator(E e) {
e[0];
}
''');
var element = result.findElement.method('[]');
await assertElementReferencesText(element, r'''
/// [operator []] and [E.operator []]
enum E {
v;
int operator [](int index) => 0;
}
void useOperator(E e) {
e[0];
^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_operator_ofEnum_indexEq() async {
var result = await resolveTestCode('''
/// [operator []=] and [E.operator []=]
enum E {
v;
operator []=(int index, int value) {}
}
void useOperator(E e) {
e[1] = 42;
}
''');
var element = result.findElement.method('[]=');
await assertElementReferencesText(element, r'''
/// [operator []=] and [E.operator []=]
enum E {
v;
operator []=(int index, int value) {}
}
void useOperator(E e) {
e[1] = 42;
^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_operator_ofEnum_prefix() async {
var result = await resolveTestCode('''
/// [operator ~] and [E.operator ~]
enum E {
e;
int operator ~() => 0;
}
void useOperator(E e) {
~e;
}
''');
var element = result.findElement.method('~');
await assertElementReferencesText(element, r'''
/// [operator ~] and [E.operator ~]
^ REFERENCE
^ REFERENCE qualified
enum E {
e;
int operator ~() => 0;
}
void useOperator(E e) {
~e;
^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_operator_ofExtension_binary() async {
var result = await resolveTestCode('''
/// [operator +] and [E.operator +]
extension E on int {
int operator +(int other) => 0;
}
void useOperator(int e) {
E(e) + 1;
}
''');
var element = result.findElement.method('+');
await assertElementReferencesText(element, r'''
/// [operator +] and [E.operator +]
^ REFERENCE
^ REFERENCE qualified
extension E on int {
int operator +(int other) => 0;
}
void useOperator(int e) {
E(e) + 1;
^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_operator_ofExtension_index() async {
var result = await resolveTestCode('''
/// [operator []] and [E.operator []]
extension E on int {
int operator [](int index) => 0;
}
void useOperator(int e) {
E(e)[0];
}
''');
var element = result.findElement.method('[]');
await assertElementReferencesText(element, r'''
/// [operator []] and [E.operator []]
extension E on int {
int operator [](int index) => 0;
}
void useOperator(int e) {
E(e)[0];
^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_operator_ofExtension_indexEq() async {
var result = await resolveTestCode('''
/// [operator []=] and [E.operator []=]
extension E on int {
operator []=(int index, int value) {}
}
void useOperator(int e) {
E(e)[1] = 42;
}
''');
var element = result.findElement.method('[]=');
await assertElementReferencesText(element, r'''
/// [operator []=] and [E.operator []=]
extension E on int {
operator []=(int index, int value) {}
}
void useOperator(int e) {
E(e)[1] = 42;
^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_operator_ofExtension_prefix() async {
var result = await resolveTestCode('''
/// [operator ~] and [E.operator ~]
extension E on int {
int operator ~() => 0;
}
void useOperator(int e) {
~E(e);
}
''');
var element = result.findElement.method('~');
await assertElementReferencesText(element, r'''
/// [operator ~] and [E.operator ~]
^ REFERENCE
^ REFERENCE qualified
extension E on int {
int operator ~() => 0;
}
void useOperator(int e) {
~E(e);
^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_operator_ofExtensionType_binary() async {
var result = await resolveTestCode('''
/// [operator +] and [A.operator +]
extension type A(int it) {
int operator +(int other) => 0;
}
void useOperator(A a) {
a + 1;
a += 2;
++a;
a++;
}
''');
var element = result.findElement.method('+');
await assertElementReferencesText(element, r'''
/// [operator +] and [A.operator +]
^ REFERENCE
^ REFERENCE qualified
extension type A(int it) {
int operator +(int other) => 0;
}
void useOperator(A a) {
a + 1;
^ INVOCATION qualified
a += 2;
^^ INVOCATION qualified
++a;
^^ INVOCATION qualified
a++;
^^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_operator_ofExtensionType_index() async {
var result = await resolveTestCode('''
/// [operator []] and [A.operator []]
extension type A(int it) {
int operator [](int index) => 0;
}
void useOperator(A a) {
a[0];
}
''');
var element = result.findElement.method('[]');
await assertElementReferencesText(element, r'''
/// [operator []] and [A.operator []]
extension type A(int it) {
int operator [](int index) => 0;
}
void useOperator(A a) {
a[0];
^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_operator_ofExtensionType_indexEq() async {
var result = await resolveTestCode('''
/// [operator []=] and [A.operator []=]
extension type A(int it) {
operator []=(int index, int value) {}
}
void useOperator(A a) {
a[1] = 42;
}
''');
var element = result.findElement.method('[]=');
await assertElementReferencesText(element, r'''
/// [operator []=] and [A.operator []=]
extension type A(int it) {
operator []=(int index, int value) {}
}
void useOperator(A a) {
a[1] = 42;
^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_operator_ofExtensionType_prefix() async {
var result = await resolveTestCode('''
/// [operator ~] and [A.operator ~]
extension type A(int it) {
int operator ~() => 0;
}
void useOperator(A a) {
~a;
}
''');
var element = result.findElement.method('~');
await assertElementReferencesText(element, r'''
/// [operator ~] and [A.operator ~]
^ REFERENCE
^ REFERENCE qualified
extension type A(int it) {
int operator ~() => 0;
}
void useOperator(A a) {
~a;
^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_operator_ofMixin_binary() async {
var result = await resolveTestCode('''
/// [operator +] and [M.operator +]
mixin M {
int operator +(int other) => 0;
}
void useOperator(M m) {
m + 1;
m += 2;
++m;
m++;
}
''');
var element = result.findElement.method('+');
await assertElementReferencesText(element, r'''
/// [operator +] and [M.operator +]
^ REFERENCE
^ REFERENCE qualified
mixin M {
int operator +(int other) => 0;
}
void useOperator(M m) {
m + 1;
^ INVOCATION qualified
m += 2;
^^ INVOCATION qualified
++m;
^^ INVOCATION qualified
m++;
^^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_operator_ofMixin_index() async {
var result = await resolveTestCode('''
/// [operator []] and [M.operator []]
mixin M {
int operator [](int index) => 0;
}
void useOperator(M m) {
m[0];
}
''');
var element = result.findElement.method('[]');
await assertElementReferencesText(element, r'''
/// [operator []] and [M.operator []]
mixin M {
int operator [](int index) => 0;
}
void useOperator(M m) {
m[0];
^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_operator_ofMixin_indexEq() async {
var result = await resolveTestCode('''
/// [operator []=] and [M.operator []=]
mixin M {
operator []=(int index, int value) {}
}
void useOperator(M m) {
m[1] = 42;
}
''');
var element = result.findElement.method('[]=');
await assertElementReferencesText(element, r'''
/// [operator []=] and [M.operator []=]
mixin M {
operator []=(int index, int value) {}
}
void useOperator(M m) {
m[1] = 42;
^ INVOCATION qualified
}
''');
}
test_searchReferences_MethodElement_operator_ofMixin_prefix() async {
var result = await resolveTestCode('''
/// [operator ~] and [M.operator ~]
mixin M {
int operator ~() => 0;
}
void useOperator(M m) {
~m;
}
''');
var element = result.findElement.method('~');
await assertElementReferencesText(element, r'''
/// [operator ~] and [M.operator ~]
^ REFERENCE
^ REFERENCE qualified
mixin M {
int operator ~() => 0;
}
void useOperator(M m) {
~m;
^ INVOCATION qualified
}
''');
}
test_searchReferences_MixinElement_reference_annotation() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
mixin A {
static const int myConstant = 0;
}
@A.myConstant
@p.A.myConstant
void f() {}
''');
var element = result.findElement.mixin('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
mixin A {
static const int myConstant = 0;
}
@A.myConstant
^ REFERENCE
@p.A.myConstant
^ REFERENCE qualified
void f() {}
''');
}
test_searchReferences_MixinElement_reference_comment() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
mixin A {}
/// [A] and [p.A].
void f() {}
''');
var element = result.findElement.mixin('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
mixin A {}
/// [A] and [p.A].
^ REFERENCE
^ REFERENCE qualified
void f() {}
''');
}
test_searchReferences_MixinElement_reference_memberAccess() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
mixin A {
static void foo() {}
}
void f() {
A.foo();
p.A.foo();
}
''');
var element = result.findElement.mixin('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
mixin A {
static void foo() {}
}
void f() {
A.foo();
^ REFERENCE
p.A.foo();
^ REFERENCE qualified
}
''');
}
test_searchReferences_MixinElement_reference_namedType() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
mixin A {}
void f(A v1, p.A v2) {}
''');
var element = result.findElement.mixin('A');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
mixin A {}
void f(A v1, p.A v2) {}
^ REFERENCE
^ REFERENCE qualified
''');
}
test_searchReferences_ParameterElement_generic_atDeclaration() async {
var result = await resolveTestCode('''
void f() {
B().m(p: null); // 1
B().m(p: null); // 2
}
class A<T> {
void m({T? p}) {} // 3
}
class B extends A<String> {}
''');
var element = result.findElement.parameter('p');
await assertElementReferencesText(element, r'''
void f() {
B().m(p: null); // 1
^ REFERENCE_BY_NAMED_ARGUMENT qualified
B().m(p: null); // 2
^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
class A<T> {
void m({T? p}) {} // 3
}
class B extends A<String> {}
''');
}
@FailingTest(
// When this test begins passing, the temporary test
// test_searchReferences_ParameterElement_generic_atInvocation_doesNotThrow_issue60005
// can be removed.
issue: 'https://github.com/dart-lang/sdk/issues/60200',
)
test_searchReferences_ParameterElement_generic_atInvocation() async {
var result = await resolveTestCode('''
void f() {
B().m(p: null); // 1
B().m(p: null); // 2
}
class A<T> {
void m({T? p}) {} // 3
}
class B extends A<String> {}
''');
var element = result.findNode
.namedArgument('p: null); // 1')
.correspondingParameter!;
await assertElementReferencesText(element, r'''
<testLibraryFragment>::@function::f
19 2:9 |p| REFERENCE qualified
42 3:9 |p| REFERENCE qualified
''');
}
/// A temporary test to ensure the search does not throw, while
/// [test_searchReferences_ParameterElement_generic_atInvocation] is marked as
/// failing.
///
/// This test can be removed once [test_searchReferences_ParameterElement_generic_atInvocation]
/// is passing.
test_searchReferences_ParameterElement_generic_atInvocation_doesNotThrow_issue60005() async {
var result = await resolveTestCode('''
void f() {
B().m(p: null); // 1
B().m(p: null); // 2
}
class A<T> {
void m({T? p}) {} // 3
}
class B extends A<String> {}
''');
var element = result.findNode
.namedArgument('p: null); // 1')
.correspondingParameter!;
expect(driver.search.references(element), completes);
}
test_searchReferences_PrefixElement() async {
String partCode = r'''
part of my_lib;
ppp.Future c;
''';
newFile('$testPackageLibPath/my_part.dart', partCode);
var result = await resolveTestCode('''
library my_lib;
import 'dart:async' as ppp;
part 'my_part.dart';
main() {
ppp.Future a;
ppp.Stream b;
}
''');
var element = result.findElement.prefix('ppp');
await assertElementReferencesText(element, r'''
package:test/my_part.dart
-------------------------
part of my_lib;
ppp.Future c;
^^^ REFERENCE
package:test/test.dart
----------------------
library my_lib;
import 'dart:async' as ppp;
part 'my_part.dart';
main() {
ppp.Future a;
^^^ REFERENCE
ppp.Stream b;
^^^ REFERENCE
}
''');
}
test_searchReferences_PrefixElement_extensionOverride() async {
newFile('$testPackageLibPath/a.dart', r'''
extension E on int {
void foo() {}
}
''');
var result = await resolveTestCode('''
import 'a.dart' as prefix;
void f() {
prefix.E(0).foo();
}
''');
var element = result.findElement.prefix('prefix');
await assertElementReferencesText(element, r'''
import 'a.dart' as prefix;
void f() {
prefix.E(0).foo();
^^^^^^ REFERENCE
}
''');
}
test_searchReferences_PrefixElement_inPackage() async {
var aaaPackageRootPath = '$packagesRootPath/aaa';
writeTestPackageConfig(
PackageConfigFileBuilder()
..add(name: 'aaa', rootFolder: getFolder(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);
var result = await resolveFileCode(libPath, '''
library my_lib;
import 'dart:async' as ppp;
part 'my_part.dart';
main() {
ppp.Future a;
ppp.Stream b;
}
''');
var element = result.findElement.prefix('ppp');
await assertElementReferencesText(element, r'''
package:aaa/a.dart
------------------
library my_lib;
import 'dart:async' as ppp;
part 'my_part.dart';
main() {
ppp.Future a;
^^^ REFERENCE
ppp.Stream b;
^^^ REFERENCE
}
package:aaa/my_part.dart
------------------------
part of my_lib;
ppp.Future c;
^^^ REFERENCE
''');
}
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;');
var result = await resolveTestCode('''
library lib;
part 'part1.dart';
part 'part2.dart';
part 'part3.dart';
class _C {}
_C v;
''');
var element = result.findElement.class_('_C');
await assertElementReferencesText(element, r'''
package:test/part1.dart
-----------------------
part of lib; _C v1;
^^ REFERENCE
package:test/part2.dart
-----------------------
part of lib; _C v2;
^^ REFERENCE
package:test/test.dart
----------------------
library lib;
part 'part1.dart';
part 'part2.dart';
part 'part3.dart';
class _C {}
_C v;
^^ REFERENCE
''');
}
test_searchReferences_private_declaredInPart() async {
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(p1, code1);
newFile(p2, code2);
var result = await resolveTestCode(code);
var element = result.findElement
.partFind('package:test/part1.dart')
.class_('_C');
await assertElementReferencesText(element, r'''
package:test/part1.dart
-----------------------
part of lib;
class _C {}
_C v1;
^^ REFERENCE
package:test/part2.dart
-----------------------
part of lib; _C v2;
^^ REFERENCE
package:test/test.dart
----------------------
library lib;
part 'part1.dart';
part 'part2.dart';
_C v;
^^ REFERENCE
''');
}
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', rootFolder: getFolder(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);
var result = await resolveFileCode(testFile, testCode);
var element = result.findElement.class_('_C');
await assertElementReferencesText(element, r'''
package:aaa/a.dart
------------------
library lib;
part 'part1.dart';
part 'part2.dart';
class _C {}
_C v;
^^ REFERENCE
package:aaa/part1.dart
----------------------
part of lib; _C v1;
^^ REFERENCE
package:aaa/part2.dart
----------------------
part of lib; _C v2;
^^ REFERENCE
''');
}
test_searchReferences_PropertyAccessor_getter_ofExtension_instance() async {
var result = await resolveTestCode('''
extension E on int {
int get foo => 0;
void bar() {
foo;
this.foo;
}
}
main() {
E(0).foo;
0.foo;
}
''');
var element = result.findElement.getter('foo');
await assertElementReferencesText(element, r'''
extension E on int {
int get foo => 0;
void bar() {
foo;
^^^ INVOCATION
this.foo;
^^^ INVOCATION qualified
}
}
main() {
E(0).foo;
^^^ INVOCATION qualified
0.foo;
^^^ INVOCATION qualified
}
''');
}
test_searchReferences_PropertyAccessor_setter_ofExtension_instance() async {
var result = 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 = result.findElement.setter('foo');
await assertElementReferencesText(element, r'''
extension E on int {
set foo(int _) {}
void bar() {
foo = 1;
^^^ INVOCATION
this.foo = 2;
^^^ INVOCATION qualified
}
}
main() {
E(0).foo = 3;
^^^ INVOCATION qualified
0.foo = 4;
^^^ INVOCATION qualified
}
''');
}
test_searchReferences_PropertyAccessorElement_getter() async {
var result = await resolveTestCode('''
class A {
get ggg => null;
main() {
ggg;
this.ggg;
ggg();
this.ggg();
}
}
''');
var element = result.findElement.getter('ggg');
await assertElementReferencesText(element, r'''
class A {
get ggg => null;
main() {
ggg;
^^^ INVOCATION
this.ggg;
^^^ INVOCATION qualified
ggg();
^^^ INVOCATION
this.ggg();
^^^ INVOCATION qualified
}
}
''');
}
test_searchReferences_PropertyAccessorElement_setter() async {
var result = await resolveTestCode('''
class A {
set s(x) {}
main() {
s = 1;
this.s = 2;
}
}
''');
var element = result.findElement.setter('s');
await assertElementReferencesText(element, r'''
class A {
set s(x) {}
main() {
s = 1;
^ INVOCATION
this.s = 2;
^ INVOCATION qualified
}
}
''');
}
test_searchReferences_SetterElement_ofClass_static() async {
var result = await resolveTestCode('''
import 'test.dart' as p;
/// [foo], [A.foo], [p.A.foo]
class A {
static set foo(int _) {}
static void useSetter() {
foo = 0;
}
}
void useSetter() {
A.foo = 0;
p.A.foo = 0;
}
''');
var element = result.findElement.setter('foo');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
/// [foo], [A.foo], [p.A.foo]
^^^ REFERENCE
^^^ REFERENCE qualified
^^^ REFERENCE qualified
class A {
static set foo(int _) {}
static void useSetter() {
foo = 0;
^^^ INVOCATION
}
}
void useSetter() {
A.foo = 0;
^^^ INVOCATION qualified
p.A.foo = 0;
^^^ INVOCATION qualified
}
''');
}
test_searchReferences_SuperFormalParameterElement_ofConstructor_optionalNamed() async {
var result = await resolveTestCode('''
class A {
A({int? test});
}
class B extends A {
/// [test]
B({super.test}) : assert(test != null);
}
void f() {
B(test: 0);
B _ = .new(test: 0);
}
''');
var element = result.findElement.unnamedConstructor('B').parameter('test');
await assertElementReferencesText(element, r'''
class A {
A({int? test});
}
class B extends A {
/// [test]
^^^^ REFERENCE
B({super.test}) : assert(test != null);
^^^^ READ
}
void f() {
B(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
B _ = .new(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
''');
}
test_searchReferences_SuperFormalParameterElement_ofConstructor_optionalPositional() async {
var result = await resolveTestCode('''
class A {
A([int? test]);
}
class B extends A {
/// [test]
B([super.test]) : assert(test != null);
}
void f() {
B(0);
B _ = .new(0);
}
''');
var element = result.findElement.unnamedConstructor('B').parameter('test');
await assertElementReferencesText(element, r'''
class A {
A([int? test]);
}
class B extends A {
/// [test]
^^^^ REFERENCE
B([super.test]) : assert(test != null);
^^^^ READ
}
void f() {
B(0);
B _ = .new(0);
}
''');
}
test_searchReferences_SuperFormalParameterElement_ofConstructor_requiredNamed() async {
var result = await resolveTestCode('''
class A {
A({required int test});
}
class B extends A {
/// [test]
B({required super.test}) : assert(test != -1);
}
void f() {
B(test: 0);
B _ = .new(test: 0);
}
''');
var element = result.findElement.unnamedConstructor('B').parameter('test');
await assertElementReferencesText(element, r'''
class A {
A({required int test});
}
class B extends A {
/// [test]
^^^^ REFERENCE
B({required super.test}) : assert(test != -1);
^^^^ READ
}
void f() {
B(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
B _ = .new(test: 0);
^^^^ REFERENCE_BY_NAMED_ARGUMENT qualified
}
''');
}
test_searchReferences_SuperFormalParameterElement_ofConstructor_requiredPositional() async {
var result = await resolveTestCode('''
class A {
A(int test);
}
class B extends A {
/// [test]
B(super.test) : assert(test != -1);
}
void f() {
B(0);
B _ = .new(0);
}
''');
var element = result.findElement.unnamedConstructor('B').parameter('test');
await assertElementReferencesText(element, r'''
class A {
A(int test);
}
class B extends A {
/// [test]
^^^^ REFERENCE
B(super.test) : assert(test != -1);
^^^^ READ
}
void f() {
B(0);
B _ = .new(0);
}
''');
}
test_searchReferences_TopLevelFunctionElement() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
void foo() {}
/// [foo] and [p.foo]
void f() {
foo();
p.foo();
foo;
p.foo;
}
''');
var element = result.findElement.topFunction('foo');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
void foo() {}
/// [foo] and [p.foo]
^^^ REFERENCE
^^^ REFERENCE qualified
void f() {
foo();
^^^ INVOCATION
p.foo();
^^^ INVOCATION qualified
foo;
^^^ REFERENCE
p.foo;
^^^ REFERENCE qualified
}
''');
}
test_searchReferences_TopLevelFunctionElement_invalidWrite() async {
var result = await resolveTestCodeWithDiagnostics(r'''
void foo() {}
void f() {
foo = 0;
//^^^
// [diag.assignmentToFunction] Functions can't be assigned a value.
}
''');
var element = result.findElement.topFunction('foo');
await assertElementReferencesText(element, r'''
void foo() {}
void f() {
foo = 0;
^^^ REFERENCE
}
''');
}
test_searchReferences_TopLevelFunctionElement_loadLibrary() async {
var result = await resolveTestCode('''
import 'dart:math' deferred as math;
void f() {
math.loadLibrary();
}
''');
var mathLib = result.findElement.import('dart:math').importedLibrary!;
var element = mathLib.loadLibraryFunction;
await assertElementReferencesText(element, r'''
import 'dart:math' deferred as math;
void f() {
math.loadLibrary();
^^^^^^^^^^^ INVOCATION qualified
}
''');
}
test_searchReferences_TopLevelFunctionElement_unqualified_ifNull() async {
var result = await resolveTestCodeWithDiagnostics(r'''
void foo() {}
void f() {
foo ??= () {};
//^^^
// [diag.assignmentToFunction] Functions can't be assigned a value.
// ^^^^^
// [diag.deadCode] Dead code.
// [diag.deadNullAwareExpression] The left operand can't be null, so the right operand is never executed.
}
''');
var element = result.findElement.topFunction('foo');
await assertElementReferencesText(element, r'''
void foo() {}
void f() {
foo ??= () {};
^^^ REFERENCE
}
''');
}
test_searchReferences_TopLevelVariableElement_getterDeclaration() async {
var result = await resolveTestCode('''
import 'test.dart' as p;
int get foo => 0;
/// [foo] and [p.foo].
void f() {
foo;
p.foo;
}
''');
var variable = result.findElement.topVar('foo');
await assertElementsReferencesText(
{'variable': variable, 'getter': variable.getter!},
r'''
import 'test.dart' as p;
int get foo => 0;
/// [foo] and [p.foo].
^^^ variable REFERENCE
^^^ getter REFERENCE
^^^ variable REFERENCE qualified
^^^ getter REFERENCE qualified
void f() {
foo;
^^^ variable READ
^^^ getter INVOCATION
p.foo;
^^^ variable READ qualified
^^^ getter INVOCATION qualified
}
''',
);
}
test_searchReferences_TopLevelVariableElement_getterDeclaration_invalidWrite() async {
var result = await resolveTestCodeWithDiagnostics(r'''
int get foo => 0;
void f() {
foo = 1;
//^^^
// [diag.assignmentToFinal] 'foo' can't be used as a setter because it's final.
}
''');
var variable = result.findElement.topVar('foo');
await assertElementsReferencesText(
{'variable': variable, 'getter': variable.getter!},
r'''
int get foo => 0;
void f() {
foo = 1;
^^^ variable REFERENCE
^^^ getter REFERENCE
}
''',
);
}
test_searchReferences_TopLevelVariableElement_getterSetterDeclarations() async {
var result = await resolveTestCode('''
import 'test.dart' as p;
int get foo => 0;
set foo(int _) {}
/// [foo] and [p.foo].
void f() {
foo;
foo = 0;
foo += 1;
foo ??= 2;
foo++;
--foo;
p.foo;
p.foo = 0;
p.foo += 1;
p.foo ??= 2;
p.foo++;
--p.foo;
}
''');
var variable = result.findElement.topVar('foo');
await assertElementsReferencesText(
{
'variable': variable,
'getter': variable.getter!,
'setter': variable.setter!,
'num.+': result.typeProvider.numElement.getMethod('+')!,
'num.-': result.typeProvider.numElement.getMethod('-')!,
},
r'''
import 'test.dart' as p;
int get foo => 0;
set foo(int _) {}
/// [foo] and [p.foo].
^^^ variable REFERENCE
^^^ getter REFERENCE
^^^ variable REFERENCE qualified
^^^ getter REFERENCE qualified
void f() {
foo;
^^^ variable READ
^^^ getter INVOCATION
foo = 0;
^^^ variable WRITE
^^^ setter INVOCATION
foo += 1;
^^^ variable READ_WRITE
^^^ getter INVOCATION
^^^ setter INVOCATION
^^ num.+ INVOCATION qualified
foo ??= 2;
^^^ variable READ_WRITE
^^^ getter INVOCATION
^^^ setter INVOCATION
foo++;
^^^ variable READ_WRITE
^^^ getter INVOCATION
^^^ setter INVOCATION
^^ num.+ INVOCATION qualified
--foo;
^^ num.- INVOCATION qualified
^^^ variable READ_WRITE
^^^ getter INVOCATION
^^^ setter INVOCATION
p.foo;
^^^ variable READ qualified
^^^ getter INVOCATION qualified
p.foo = 0;
^^^ variable WRITE qualified
^^^ setter INVOCATION qualified
p.foo += 1;
^^^ variable READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
p.foo ??= 2;
^^^ variable READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
p.foo++;
^^^ variable READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
--p.foo;
^^ num.- INVOCATION qualified
^^^ variable READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
}
''',
);
}
test_searchReferences_TopLevelVariableElement_getterSetterDeclarations_importCombinator_show() async {
var result = await resolveTestCode('''
import 'test.dart' show foo;
int get foo => 0;
void set foo(_) {}
''');
var variable = result.findElement.topVar('foo');
await assertElementsReferencesText(
{
'variable': variable,
'getter': variable.getter!,
'setter': variable.setter!,
},
r'''
import 'test.dart' show foo;
^^^ variable REFERENCE qualified
^^^ getter REFERENCE qualified
^^^ setter REFERENCE qualified
int get foo => 0;
void set foo(_) {}
''',
);
}
test_searchReferences_TopLevelVariableElement_setterDeclaration() async {
var result = await resolveTestCode('''
import 'test.dart' as p;
set foo(int _) {}
void f() {
foo = 0;
p.foo = 0;
}
''');
var variable = result.findElement.topVar('foo');
await assertElementsReferencesText(
{'variable': variable, 'setter': variable.setter!},
r'''
import 'test.dart' as p;
set foo(int _) {}
void f() {
foo = 0;
^^^ variable WRITE
^^^ setter INVOCATION
p.foo = 0;
^^^ variable WRITE qualified
^^^ setter INVOCATION qualified
}
''',
);
}
test_searchReferences_TopLevelVariableElement_setterDeclaration_importCombinator_show() async {
var result = await resolveTestCode('''
import 'test.dart' show foo;
void set foo(_) {}
''');
var variable = result.findElement.topVar('foo');
await assertElementsReferencesText(
{'variable': variable, 'setter': variable.setter!},
r'''
import 'test.dart' show foo;
^^^ variable REFERENCE qualified
^^^ setter REFERENCE qualified
void set foo(_) {}
''',
);
}
test_searchReferences_TopLevelVariableElement_variableDeclaration() async {
var result = await resolveTestCode('''
import 'test.dart' as p;
int foo = 0;
/// [foo] and [p.foo].
@foo
@p.foo
void f() {
foo;
foo = 0;
foo += 1;
foo ??= 2;
foo++;
--foo;
p.foo;
p.foo = 0;
p.foo += 1;
p.foo ??= 2;
p.foo++;
--p.foo;
}
''');
var variable = result.findElement.topVar('foo');
await assertElementsReferencesText(
{
'variable': variable,
'getter': variable.getter!,
'setter': variable.setter!,
'num.+': result.typeProvider.numElement.getMethod('+')!,
'num.-': result.typeProvider.numElement.getMethod('-')!,
},
r'''
import 'test.dart' as p;
int foo = 0;
/// [foo] and [p.foo].
^^^ variable REFERENCE
^^^ getter REFERENCE
^^^ variable REFERENCE qualified
^^^ getter REFERENCE qualified
@foo
^^^ variable READ
^^^ getter INVOCATION
@p.foo
^^^ variable READ qualified
^^^ getter INVOCATION qualified
void f() {
foo;
^^^ variable READ
^^^ getter INVOCATION
foo = 0;
^^^ variable WRITE
^^^ setter INVOCATION
foo += 1;
^^^ variable READ_WRITE
^^^ getter INVOCATION
^^^ setter INVOCATION
^^ num.+ INVOCATION qualified
foo ??= 2;
^^^ variable READ_WRITE
^^^ getter INVOCATION
^^^ setter INVOCATION
foo++;
^^^ variable READ_WRITE
^^^ getter INVOCATION
^^^ setter INVOCATION
^^ num.+ INVOCATION qualified
--foo;
^^ num.- INVOCATION qualified
^^^ variable READ_WRITE
^^^ getter INVOCATION
^^^ setter INVOCATION
p.foo;
^^^ variable READ qualified
^^^ getter INVOCATION qualified
p.foo = 0;
^^^ variable WRITE qualified
^^^ setter INVOCATION qualified
p.foo += 1;
^^^ variable READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
p.foo ??= 2;
^^^ variable READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
p.foo++;
^^^ variable READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
^^ num.+ INVOCATION qualified
--p.foo;
^^ num.- INVOCATION qualified
^^^ variable READ_WRITE qualified
^^^ getter INVOCATION qualified
^^^ setter INVOCATION qualified
}
''',
);
}
test_searchReferences_TopLevelVariableElement_variableDeclaration_invocation() async {
newFile('$testPackageLibPath/lib.dart', '''
library lib;
var V;
''');
var result = await resolveTestCode('''
import 'lib.dart' show V;
import 'lib.dart' as pref;
main() {
pref.V = 1;
pref.V;
pref.V();
V = 1;
V;
V();
}
''');
var variable = result.findElement
.importFind('package:test/lib.dart', mustBeUnique: false)
.topVar('V');
await assertElementsReferencesText(
{
'variable': variable,
'getter': variable.getter!,
'setter': variable.setter!,
},
r'''
import 'lib.dart' show V;
^ variable REFERENCE qualified
^ getter REFERENCE qualified
^ setter REFERENCE qualified
import 'lib.dart' as pref;
main() {
pref.V = 1;
^ variable WRITE qualified
^ setter INVOCATION qualified
pref.V;
^ variable READ qualified
^ getter INVOCATION qualified
pref.V();
^ variable READ qualified
^ getter INVOCATION qualified
V = 1;
^ variable WRITE
^ setter INVOCATION
V;
^ variable READ
^ getter INVOCATION
V();
^ variable READ
^ getter INVOCATION
}
''',
);
}
test_searchReferences_TypeAliasElement_inConstructorName() async {
var result = await resolveTestCode('''
class A<T> {}
typedef B = A<int>;
void f() {
B();
}
''');
var element = result.findElement.typeAlias('B');
await assertElementReferencesText(element, r'''
class A<T> {}
typedef B = A<int>;
void f() {
B();
^ REFERENCE
}
''');
}
test_searchReferences_TypeAliasElement_legacy_reference() async {
var result = await resolveTestCode('''
typedef void A();
/// [A]
void f(A p) {}
''');
var element = result.findElement.typeAlias('A');
await assertElementReferencesText(element, r'''
typedef void A();
/// [A]
^ REFERENCE
void f(A p) {}
^ REFERENCE
''');
}
test_searchReferences_TypeAliasElement_modern_reference() async {
var result = await resolveTestCode('''
class A<T> {
static int field = 0;
static void method() {}
}
typedef B = A<int>;
/// [B]
void f(B p) {
B v;
B();
B.field;
B.field = 0;
B.method();
}
''');
var element = result.findElement.typeAlias('B');
await assertElementReferencesText(element, r'''
class A<T> {
static int field = 0;
static void method() {}
}
typedef B = A<int>;
/// [B]
^ REFERENCE
void f(B p) {
^ REFERENCE
B v;
^ REFERENCE
B();
^ REFERENCE
B.field;
^ REFERENCE
B.field = 0;
^ REFERENCE
B.method();
^ REFERENCE
}
''');
}
test_searchReferences_TypeAliasElement_modern_reference_comment() async {
var result = await resolveTestCode(r'''
import 'test.dart' as p;
class A<T> {}
typedef B = A<int>;
/// [B] and [p.B].
void f() {}
''');
var element = result.findElement.typeAlias('B');
await assertElementReferencesText(element, r'''
import 'test.dart' as p;
class A<T> {}
typedef B = A<int>;
/// [B] and [p.B].
^ REFERENCE
^ REFERENCE qualified
void f() {}
''');
}
test_searchReferences_TypeParameterElement_ofClass() async {
var result = await resolveTestCode('''
class A<T> {
foo(T a) {}
bar(T b) {}
}
''');
var element = result.findElement.typeParameter('T');
await assertElementReferencesText(element, r'''
class A<T> {
foo(T a) {}
^ REFERENCE
bar(T b) {}
^ REFERENCE
}
''');
}
test_searchReferences_TypeParameterElement_ofEnum() async {
var result = await resolveTestCode('''
enum E<T> {
v;
final T a;
void foo(T b) {}
}
''');
var element = result.findElement.typeParameter('T');
await assertElementReferencesText(element, r'''
enum E<T> {
v;
final T a;
^ REFERENCE
void foo(T b) {}
^ REFERENCE
}
''');
}
test_searchReferences_TypeParameterElement_ofLocalFunction() async {
makeFilePriority(testFile);
var result = await resolveTestCode('''
main() {
void foo<T>(T a) {
void bar(T b) {}
}
}
''');
var element = result.findElement.typeParameter('T');
await assertElementReferencesText(element, r'''
main() {
void foo<T>(T a) {
^ REFERENCE
void bar(T b) {}
^ REFERENCE
}
}
''');
}
test_searchReferences_TypeParameterElement_ofMethod() async {
var result = await resolveTestCode('''
class A {
foo<T>(T p) {}
}
''');
var element = result.findElement.typeParameter('T');
await assertElementReferencesText(element, r'''
class A {
foo<T>(T p) {}
^ REFERENCE
}
''');
}
test_searchReferences_TypeParameterElement_ofTopLevelFunction() async {
var result = await resolveTestCode('''
foo<T>(T a) {
bar(T b) {}
}
''');
var element = result.findElement.typeParameter('T');
await assertElementReferencesText(element, r'''
foo<T>(T a) {
^ REFERENCE
bar(T b) {}
^ REFERENCE
}
''');
}
test_searchReferences_VariablePatternElement_declaration() async {
var result = await resolveTestCode('''
void f(x) {
var (v) = x;
v = 1;
v += 2;
v;
v();
}
''');
var element = result.findNode.bindPatternVariableElement('v) =');
await assertElementReferencesText(element, r'''
void f(x) {
var (v) = x;
v = 1;
^ WRITE
v += 2;
^ READ_WRITE
v;
^ READ
v();
^ READ
}
''');
}
test_searchReferences_VariablePatternElement_expressionFunctionBody() async {
var result = await resolveTestCode('''
List<int> f(Map<int, String> map) => [
for (var MapEntry(:key) in map.entries)
key,
];
''');
var element = result.findNode.bindPatternVariableElement('key)');
await assertElementReferencesText(element, r'''
List<int> f(Map<int, String> map) => [
for (var MapEntry(:key) in map.entries)
key,
^^^ READ
];
''');
}
test_searchReferences_VariablePatternElement_ifCase() async {
var result = await resolveTestCode('''
void f(Object? x) {
if (x case int v) {
v;
}
}
''');
var element = result.findNode.bindPatternVariableElement('v)');
await assertElementReferencesText(element, r'''
void f(Object? x) {
if (x case int v) {
v;
^ READ
}
}
''');
}
test_searchReferences_VariablePatternElement_ifCase_logicalOr() async {
var result = await resolveTestCode('''
void f(Object? x) {
if (x case int v || [int v]) {
v;
v = 1;
}
}
''');
var element = result.findNode.bindPatternVariableElement('v]');
await assertElementReferencesText(element, r'''
void f(Object? x) {
if (x case int v || [int v]) {
v;
^ READ
v = 1;
^ WRITE
}
}
''');
}
test_searchReferences_VariablePatternElement_patternAssignment() async {
makeFilePriority(testFile);
var result = await resolveTestCode('''
void f() {
int v;
(v, _) = (0, 1);
v;
}
''');
var element = result.findElement.localVar('v');
await assertElementReferencesText(element, r'''
void f() {
int v;
(v, _) = (0, 1);
^ WRITE
v;
^ READ
}
''');
}
test_searchReferences_VariablePatternElement_switchExpression() async {
var result = await resolveTestCode('''
Object f(Object? x) => switch (0) {
int v when v > 0 => v + 1 + (v = 2),
_ => -1,
}
''');
var element = result.findNode.bindPatternVariableElement('int v');
await assertElementReferencesText(element, r'''
Object f(Object? x) => switch (0) {
int v when v > 0 => v + 1 + (v = 2),
^ READ
^ READ
^ WRITE
_ => -1,
}
''');
}
test_searchReferences_VariablePatternElement_switchExpression_topLevel() async {
var result = await resolveTestCode('''
var f = switch (0) {
int v when v > 0 => v + 1 + (v = 2),
_ => -1,
}
''');
var element = result.findNode.bindPatternVariableElement('int v');
await assertElementReferencesText(element, r'''
var f = switch (0) {
int v when v > 0 => v + 1 + (v = 2),
^ READ
^ READ
^ WRITE
_ => -1,
}
''');
}
test_searchReferences_VariablePatternElement_switchStatement_shared() async {
var result = await resolveTestCode('''
void f(Object? x) {
switch (0) {
case int v when v > 0:
case [int v] when v < 0:
v;
v = 1;
}
}
''');
var element = result.findNode.bindPatternVariableElement('int v when');
await assertElementReferencesText(element, r'''
void f(Object? x) {
switch (0) {
case int v when v > 0:
^ READ
case [int v] when v < 0:
^ READ
v;
^ READ
v = 1;
^ WRITE
}
}
''');
}
test_searchReferences_VariablePatternElement_switchStatement_shared_hasLogicalOr() async {
var result = await resolveTestCode('''
void f(Object? x) {
switch (0) {
case int v when v > 0:
case [int v] || [..., int v] when v < 0:
v;
v = 1;
}
}
''');
var element = result.findNode.bindPatternVariableElement('int v when');
await assertElementReferencesText(element, r'''
void f(Object? x) {
switch (0) {
case int v when v > 0:
^ READ
case [int v] || [..., int v] when v < 0:
^ READ
v;
^ READ
v = 1;
^ WRITE
}
}
''');
}
test_searchSubtypes() async {
var result = await resolveTestCode('''
class T {}
class A extends T {}
class B = Object with T;
class C implements T {}
''');
var element = result.findElement.class_('T');
await assertElementReferencesText(element, r'''
class T {}
class A extends T {}
^ REFERENCE
class B = Object with T;
^ REFERENCE
class C implements T {}
^ REFERENCE
''');
}
test_searchSubtypes_mixinDeclaration() async {
var result = await resolveTestCode('''
class T {}
mixin A on T {}
mixin B implements T {}
''');
var element = result.findElement.class_('T');
await assertElementReferencesText(element, r'''
class T {}
mixin A on T {}
^ REFERENCE
mixin B implements T {}
^ REFERENCE
''');
}
test_topLevelElements() async {
var result = await resolveTestCode('''
class A {}
class B = Object with A;
mixin C {}
typedef D();
f() {}
var g = null;
class NoMatchABCDEF {}
''');
var a = result.findElement.class_('A');
var b = result.findElement.class_('B');
var c = result.findElement.mixin('C');
var d = result.findElement.typeAlias('D');
var f = result.findElement.function('f');
var g = result.findElement.topVar('g');
RegExp regExp = RegExp(r'^[ABCDfg]$');
expect(
await driver.search.topLevelElements(regExp),
unorderedEquals([a, b, c, d, f, g]),
);
}
String _fileHeader(String unitPath) {
var unitResult = driver.currentSession.getParsedUnit(unitPath);
unitResult as ParsedUnitResult;
var uri = unitResult.uri;
if (uri.isScheme('package') || uri.isScheme('dart')) {
return uri.toString();
}
var uriStr = uri.toString();
if (uriStr.startsWith('file:')) {
return uriStr.substring(uriStr.lastIndexOf('/') + 1);
}
return uriStr;
}
Future<List<Element>> _findClassMembers(String name) {
return driver.search.classMembers(name);
}
String _getDeclarationsText(
WorkspaceSymbols symbols,
Map<File, String> inFiles,
) {
var groups = symbols.declarations
.map((declaration) {
var file = getFile(symbols.files[declaration.fileIndex]);
var fileStr = inFiles[file];
return fileStr != null ? MapEntry(fileStr, declaration) : null;
})
.nonNulls
.groupListsBy((entry) => entry.key);
var buffer = StringBuffer();
for (var group in groups.entries) {
var fileStr = group.key;
buffer.writeln(fileStr);
var fileDeclarations = group.value.map((e) => e.value).toList();
var sorted = fileDeclarations.sortedBy<num>((e) => e.offset);
for (var declaration in sorted) {
var name = declaration.name;
buffer.write(' ${declaration.kind.name} ');
buffer.writeln(name.isNotEmpty ? name : '<unnamed>');
buffer.writeln(
' offset: ${declaration.offset} '
'${declaration.line}:${declaration.column}',
);
buffer.writeln(
' codeOffset: ${declaration.codeOffset} + '
'${declaration.codeLength}',
);
var className = declaration.className;
if (className != null) {
buffer.writeln(' className: $className');
}
var mixinName = declaration.mixinName;
if (mixinName != null) {
buffer.writeln(' mixinName: $mixinName');
}
var parameters = declaration.parameters;
if (parameters != null) {
buffer.writeln(' parameters: $parameters');
}
}
}
return buffer.toString();
}
String _getSearchResultsText(List<SearchResult> results) {
return _getSearchResultsTextByLabel({'': results});
}
String _getSearchResultsText2(List<LibraryFragmentSearchMatch> results) {
if (includedLibraryUris case var included?) {
results = results.where((result) {
var uri = result.libraryFragment.source.uri;
return included.contains(uri);
}).toList();
}
if (results.isEmpty) {
return '';
}
var annotationsByPath = <String, List<_SearchAnnotation>>{};
for (var result in results) {
var unitPath = result.libraryFragment.source.fullName;
(annotationsByPath[unitPath] ??= []).add(
_SearchAnnotation(
offset: result.range.offset,
length: result.range.length,
text: '',
),
);
}
return _renderAnnotations(annotationsByPath);
}
String _getSearchResultsTextByLabel(
Map<String, List<SearchResult>> resultsByLabel,
) {
var annotationsByPath = <String, List<_SearchAnnotation>>{};
var labelOrder = 0;
for (var entry in resultsByLabel.entries) {
var label = entry.key;
var results = entry.value;
if (includedLibraryUris case var included?) {
results = results.where((result) {
var uri = result.enclosingFragment.libraryFragment?.source.uri;
return uri != null && included.contains(uri);
}).toList();
}
for (var result in results) {
var unitPath =
result.enclosingFragment.libraryFragment!.source.fullName;
var buffer = StringBuffer();
if (label.isNotEmpty) {
buffer.write('$label ');
}
buffer.write(result.kind.name);
if (result.isQualified) {
buffer.write(' qualified');
}
if (!result.isResolved) {
buffer.write(' unresolved');
}
(annotationsByPath[unitPath] ??= []).add(
_SearchAnnotation(
offset: result.offset,
length: result.length,
order: labelOrder,
text: buffer.toString(),
),
);
}
labelOrder++;
}
if (annotationsByPath.isEmpty) {
return '';
}
return _renderAnnotations(annotationsByPath);
}
/// When the file is priority, its resolved result is cached, so when
/// [Search] uses AST to find local references, it can see the same elements
/// for formal parameters.
void _makeTestFilePriority() {
makeFilePriority(testFile);
}
String _renderAnnotations(
Map<String, List<_SearchAnnotation>> annotationsByPath,
) {
var buffer = StringBuffer();
if (annotationsByPath.length == 1 &&
annotationsByPath.keys.single == testFile.path) {
_writeAnnotatedFile(
buffer,
testFile.path,
annotationsByPath.values.single,
);
return buffer.toString();
}
var sortedPaths = annotationsByPath.keys.sortedBy(
(path) => _fileHeader(path),
);
for (var path in sortedPaths) {
if (buffer.isNotEmpty) {
buffer.writeln();
}
var header = _fileHeader(path);
buffer.writeln(header);
buffer.writeln('-' * header.length);
_writeAnnotatedFile(buffer, path, annotationsByPath[path]!);
}
return buffer.toString();
}
void _writeAnnotatedFile(
StringBuffer buffer,
String unitPath,
List<_SearchAnnotation> annotations,
) {
var unitResult = driver.currentSession.getParsedUnit(unitPath);
unitResult as ParsedUnitResult;
var lineInfo = unitResult.lineInfo;
var content = unitResult.content;
annotations.sort((first, second) {
var result = first.offset.compareTo(second.offset);
if (result != 0) return result;
result = first.length.compareTo(second.length);
if (result != 0) return result;
result = first.order.compareTo(second.order);
if (result != 0) return result;
return first.text.compareTo(second.text);
});
for (var i = 1; i < annotations.length; i++) {
var previous = annotations[i - 1];
var current = annotations[i];
if (previous.offset == current.offset &&
previous.length == current.length &&
previous.text == current.text) {
fail('Duplicate search result at ${current.offset}: ${current.text}');
}
}
var annotationsByLine = annotations.groupListsBy((annotation) {
return lineInfo.getLocation(annotation.offset).lineNumber;
});
var lines = content.split('\n');
if (lines.isNotEmpty && lines.last.isEmpty) {
lines.removeLast();
}
for (var i = 0; i < lines.length; i++) {
buffer.writeln(lines[i]);
for (var annotation
in annotationsByLine[i + 1] ?? const <_SearchAnnotation>[]) {
var location = lineInfo.getLocation(annotation.offset);
buffer.write(' ' * (location.columnNumber - 1));
if (annotation.length == 0) {
buffer.write('^0');
} else {
buffer.write('^' * annotation.length);
}
if (annotation.text.isNotEmpty) {
buffer.write(' ${annotation.text}');
}
buffer.writeln();
}
}
}
}
class _SearchAnnotation {
final int offset;
final int length;
final int order;
final String text;
_SearchAnnotation({
required this.offset,
required this.length,
this.order = 0,
required this.text,
});
}