| // 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_element2.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:analyzer_utilities/testing/tree_string_sink.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 '../../../util/element_printer.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> 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, ''' |
| <testLibraryFragment> bar@48 |
| 60 5:20 |.bar| INVOCATION qualified |
| '''); |
| element = result.findElement.method('bar'); |
| await assertElementReferencesText(element, r''' |
| <testLibraryFragment> bar@18 |
| 30 3:5 |bar| INVOCATION |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> B@44 |
| 54 5:17 |A| REFERENCE |
| <testLibraryFragment> B_q@65 |
| 79 6:21 |A| REFERENCE qualified |
| '''); |
| |
| await assertDirectSubtypeReferencesText(element, r''' |
| <testLibraryFragment> B@44 |
| 54 5:17 |A| REFERENCE_IN_EXTENDS_CLAUSE |
| <testLibraryFragment> B_q@65 |
| 79 6:21 |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''' |
| <testLibraryFragment> B@44 |
| 57 5:20 |A| REFERENCE |
| <testLibraryFragment> B_q@68 |
| 85 6:24 |A| REFERENCE qualified |
| '''); |
| |
| await assertDirectSubtypeReferencesText(element, r''' |
| <testLibraryFragment> B@44 |
| 57 5:20 |A| REFERENCE_IN_IMPLEMENTS_CLAUSE |
| <testLibraryFragment> B_q@68 |
| 85 6:24 |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''' |
| <testLibraryFragment> D@44 |
| 66 5:29 |A| REFERENCE |
| <testLibraryFragment> D_q@77 |
| 103 6:33 |A| REFERENCE qualified |
| '''); |
| |
| await assertDirectSubtypeReferencesText(element, r''' |
| <testLibraryFragment> D@44 |
| 66 5:29 |A| REFERENCE_IN_WITH_CLAUSE |
| <testLibraryFragment> D_q@77 |
| 103 6:33 |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''' |
| <testLibraryFragment> D2@44 |
| 61 5:24 |A| REFERENCE |
| <testLibraryFragment> D2_q@70 |
| 91 6:28 |A| REFERENCE qualified |
| '''); |
| |
| await assertDirectSubtypeReferencesText(element, r''' |
| <testLibraryFragment> D2@44 |
| 61 5:24 |A| REFERENCE_IN_WITH_CLAUSE |
| <testLibraryFragment> D2_q@70 |
| 91 6:28 |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''' |
| <testLibraryFragment> E@43 |
| 56 5:19 |A| REFERENCE |
| <testLibraryFragment> E_q@69 |
| 86 6:23 |A| REFERENCE qualified |
| '''); |
| |
| await assertDirectSubtypeReferencesText(element, r''' |
| <testLibraryFragment> E@43 |
| 56 5:19 |A| REFERENCE_IN_IMPLEMENTS_CLAUSE |
| <testLibraryFragment> E_q@69 |
| 86 6:23 |A| 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''' |
| <testLibraryFragment> it@57 |
| 55 5:18 |A| REFERENCE |
| <testLibraryFragment> E@53 |
| 72 5:35 |A| REFERENCE |
| <testLibraryFragment> it@98 |
| 96 6:20 |A| REFERENCE |
| <testLibraryFragment> E_q@92 |
| 115 6:39 |A| REFERENCE qualified |
| '''); |
| |
| await assertDirectSubtypeReferencesText(element, r''' |
| <testLibraryFragment> E@53 |
| 72 5:35 |A| REFERENCE_IN_IMPLEMENTS_CLAUSE |
| <testLibraryFragment> E_q@92 |
| 115 6:39 |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''' |
| <testLibraryFragment> M@44 |
| 57 5:20 |A| REFERENCE |
| <testLibraryFragment> M_q@68 |
| 85 6:24 |A| REFERENCE qualified |
| '''); |
| |
| await assertDirectSubtypeReferencesText(element, r''' |
| <testLibraryFragment> M@44 |
| 57 5:20 |A| REFERENCE_IN_IMPLEMENTS_CLAUSE |
| <testLibraryFragment> M_q@68 |
| 85 6:24 |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''' |
| <testLibraryFragment> M2@44 |
| 50 5:13 |A| REFERENCE |
| <testLibraryFragment> M2_q@61 |
| 71 6:17 |A| REFERENCE qualified |
| '''); |
| |
| await assertDirectSubtypeReferencesText(element, r''' |
| <testLibraryFragment> M2@44 |
| 50 5:13 |A| REFERENCE_IN_ON_CLAUSE |
| <testLibraryFragment> M2_q@61 |
| 71 6:17 |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''' |
| <testLibraryFragment> B@70 |
| 91 5:37 |A| REFERENCE |
| <testLibraryFragment> B_q@111 |
| 136 6:41 |A| REFERENCE qualified |
| '''); |
| |
| await assertDirectSubtypeReferencesText(element, r''' |
| <testLibraryFragment> B@70 |
| 91 5:37 |A| REFERENCE_IN_IMPLEMENTS_CLAUSE |
| <testLibraryFragment> B_q@111 |
| 136 6:41 |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''' |
| <testLibraryFragment> B@17 |
| 30 2:20 |A| REFERENCE |
| '''); |
| |
| await assertDirectSubtypeReferencesText(element, r''' |
| <testLibraryFragment> B@17 |
| 30 2:20 |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''' |
| <testLibraryFragment> B@17 |
| 39 2:29 |A| REFERENCE |
| '''); |
| |
| await assertDirectSubtypeReferencesText(element, r''' |
| <testLibraryFragment> B@17 |
| 39 2:29 |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''' |
| <testLibraryFragment> B@17 |
| 33 2:23 |A| REFERENCE |
| '''); |
| |
| await assertDirectSubtypeReferencesText(element, r''' |
| <testLibraryFragment> B@17 |
| 33 2:23 |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''' |
| <testLibraryFragment> E@16 |
| 29 2:19 |A| REFERENCE |
| '''); |
| |
| await assertDirectSubtypeReferencesText(element, r''' |
| <testLibraryFragment> E@16 |
| 29 2:19 |A| REFERENCE_IN_IMPLEMENTS_CLAUSE |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> E@16 |
| 23 2:13 |A| REFERENCE |
| '''); |
| |
| await assertDirectSubtypeReferencesText(element, r''' |
| <testLibraryFragment> E@16 |
| 23 2:13 |A| REFERENCE_IN_WITH_CLAUSE |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> it@30 |
| 28 2:18 |A| REFERENCE |
| <testLibraryFragment> E@26 |
| 45 2:35 |A| REFERENCE |
| '''); |
| |
| await assertDirectSubtypeReferencesText(element, r''' |
| <testLibraryFragment> E@26 |
| 45 2:35 |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''' |
| <testLibraryFragment> M@17 |
| 30 2:20 |A| REFERENCE |
| '''); |
| |
| await assertDirectSubtypeReferencesText(element, r''' |
| <testLibraryFragment> M@17 |
| 30 2:20 |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''' |
| <testLibraryFragment> M@17 |
| 22 2:12 |A| REFERENCE |
| '''); |
| |
| await assertDirectSubtypeReferencesText(element, r''' |
| <testLibraryFragment> M@17 |
| 22 2:12 |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''' |
| <testLibraryFragment> C@40 |
| 50 3:17 |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''' |
| <testLibraryFragment> C@40 |
| 53 3:20 |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''' |
| <testLibraryFragment> C@40 |
| 62 3:29 |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''' |
| <testLibraryFragment> f@5 |
| 16 2:5 |test| READ qualified unresolved |
| 26 3:5 |test| WRITE qualified unresolved |
| 40 4:5 |test| READ_WRITE qualified unresolved |
| 55 5:5 |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''' |
| <testLibraryFragment> main@12 |
| 31 3:11 |test| READ unresolved |
| 42 4:5 |test| WRITE unresolved |
| 56 5:5 |test| READ_WRITE unresolved |
| 71 6:5 |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 f@5 |
| 23 2:13 |myDiagnosticCode| REFERENCE qualified |
| '''); |
| } |
| |
| @SkippedTest() // 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''' |
| <testLibraryFragment> f@5 |
| 35 2:16 |foo| REFERENCE_IN_PATTERN_FIELD qualified |
| 62 3:16 || REFERENCE_IN_PATTERN_FIELD qualified |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> f@5 |
| 35 2:16 |foo| REFERENCE qualified |
| 62 3:16 || 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''' |
| <testLibraryFragment> p@29 |
| 22 3:6 |MyEnum| REFERENCE |
| <testLibraryFragment> main@17 |
| 36 4:3 |MyEnum| REFERENCE |
| 48 5:3 |MyEnum| 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''' |
| <testLibraryFragment> B@17 |
| 39 2:29 |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''' |
| <testLibraryFragment> new@null |
| 44 4:9 |A| REFERENCE |
| <testLibraryFragment> named@59 |
| 57 5:9 |A| REFERENCE |
| <testLibraryFragment> f@177 |
| 107 9:2 |A| REFERENCE |
| 114 10:4 |A| REFERENCE qualified |
| 119 11:2 |A| REFERENCE |
| 132 12:4 |A| REFERENCE qualified |
| 143 13:2 |A| REFERENCE |
| 159 14:4 |A| REFERENCE qualified |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> f@54 |
| 44 7:4 |B| REFERENCE |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> p@45 |
| 43 3:8 |B| REFERENCE |
| <testLibraryFragment> f@41 |
| 52 4:3 |B| 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''' |
| <testLibraryFragment> f@62 |
| 43 5:6 |A| REFERENCE |
| 53 5:16 |A| REFERENCE qualified |
| '''); |
| } |
| |
| test_searchReferences_ClassElement_reference_definedInSdk() async { |
| var result = await resolveTestCode(''' |
| import 'dart:math'; |
| Random v1; |
| Random v2; |
| '''); |
| |
| var element = result.findElement.importFind('dart:math').class_('Random'); |
| await assertElementReferencesText(element, r''' |
| <testLibraryFragment> v1@27 |
| 20 2:1 |Random| REFERENCE |
| <testLibraryFragment> v2@38 |
| 31 3:1 |Random| REFERENCE |
| dart:math new@null |
| 406 20:20 |Random| 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''' |
| <testLibraryFragment> p@19 |
| 17 2:6 |A| REFERENCE |
| <testLibraryFragment> main@12 |
| 26 3:3 |A| REFERENCE |
| <testLibraryFragment> B1@39 |
| 50 5:18 |A| REFERENCE |
| <testLibraryFragment> B2@61 |
| 75 6:21 |A| REFERENCE |
| <testLibraryFragment> B3@86 |
| 109 7:30 |A| REFERENCE |
| <testLibraryFragment> v2@122 |
| 119 8:6 |A| 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''' |
| <testLibraryFragment> p@26 |
| 24 2:6 |A| REFERENCE |
| <testLibraryFragment> main@19 |
| 33 3:3 |A| 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''' |
| <testLibraryFragment> f@43 |
| 51 6:3 |A| REFERENCE |
| 60 7:5 |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''' |
| <testLibraryFragment> f@67 |
| 75 8:3 |A| REFERENCE |
| 88 9:5 |A| 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''' |
| <testLibraryFragment> f@43 |
| 51 6:3 |A| REFERENCE |
| 61 7:5 |A| REFERENCE qualified |
| 74 8:8 |A| REFERENCE |
| 90 9:10 |A| 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''' |
| <testLibraryFragment> r@38 |
| 30 3:19 |A| 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''' |
| <testLibraryFragment> r@28 |
| 25 3:14 |A| 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''' |
| <testLibraryFragment> v@42 |
| 46 5:9 |A| REFERENCE |
| <testLibraryFragment> v_p@53 |
| 61 6:13 |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''' |
| <testLibraryFragment> f@112 |
| 73 8:3 || INVOCATION qualified |
| 80 9:5 || INVOCATION qualified |
| '''); |
| |
| var named = result.findElement.constructor('named', of: 'A'); |
| await assertElementReferencesText(named, r''' |
| <testLibraryFragment> f@112 |
| 85 10:3 |.named| INVOCATION qualified |
| 98 11:5 |.named| INVOCATION qualified |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> foo@42 |
| 52 6:15 |.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 useConstructor@26 |
| 53 4:9 |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''' |
| <testLibraryFragment> A@34 |
| 10 1:11 |.foo| REFERENCE qualified |
| 22 1:23 |.foo| REFERENCE qualified |
| <testLibraryFragment> bar@59 |
| 71 4:19 |.foo| INVOCATION qualified |
| <testLibraryFragment> baz@89 |
| 98 5:20 |.foo| REFERENCE qualified |
| <testLibraryFragment> new@null |
| 142 8:17 |.foo| INVOCATION qualified |
| <testLibraryFragment> useConstructor@157 |
| 179 11:4 |.foo| INVOCATION qualified |
| 190 12:4 |.foo| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 205 13:10 |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''' |
| <testLibraryFragment> A@34 |
| 10 1:11 |.foo| REFERENCE qualified |
| 22 1:23 |.foo| REFERENCE qualified |
| <testLibraryFragment> bar@50 |
| 62 3:19 |.foo| INVOCATION qualified |
| <testLibraryFragment> baz@80 |
| 89 4:20 |.foo| REFERENCE qualified |
| <testLibraryFragment> B@103 |
| 133 7:15 |.foo| INVOCATION qualified |
| <testLibraryFragment> useConstructor@148 |
| 170 10:4 |.foo| INVOCATION qualified |
| 181 11:4 |.foo| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 196 12:10 |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''' |
| <testLibraryFragment> A@34 |
| 10 1:11 |.foo| REFERENCE qualified |
| 22 1:23 |.foo| REFERENCE qualified |
| <testLibraryFragment> bar@55 |
| 67 4:17 |.foo| INVOCATION qualified |
| <testLibraryFragment> baz@87 |
| 96 5:22 |.foo| REFERENCE qualified |
| <testLibraryFragment> new@null |
| 137 8:14 |.foo| INVOCATION qualified |
| <testLibraryFragment> useConstructor@152 |
| 174 11:4 |.foo| INVOCATION qualified |
| 185 12:4 |.foo| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 200 13:10 |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''' |
| <testLibraryFragment> A@34 |
| 10 1:11 |.foo| REFERENCE qualified |
| 22 1:23 |.foo| REFERENCE qualified |
| <testLibraryFragment> bar@58 |
| 70 4:17 |.foo| INVOCATION qualified |
| <testLibraryFragment> baz@90 |
| 99 5:22 |.foo| REFERENCE qualified |
| <testLibraryFragment> new@null |
| 160 9:14 |.foo| INVOCATION qualified |
| <testLibraryFragment> useConstructor@175 |
| 197 12:4 |.foo| INVOCATION qualified |
| 208 13:4 |.foo| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 223 14:10 |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 useConstructor@26 |
| 53 4:9 |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''' |
| <testLibraryFragment> B@30 |
| 10 1:11 || REFERENCE qualified |
| 18 1:19 |.new| REFERENCE qualified |
| <testLibraryFragment> baz@53 |
| 62 4:22 || REFERENCE qualified |
| <testLibraryFragment> new@null |
| 120 8:14 || INVOCATION qualified |
| <testLibraryFragment> useConstructor@131 |
| 153 11:4 || INVOCATION qualified |
| 160 12:4 |.new| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 175 13:10 |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''' |
| <testLibraryFragment> new@null |
| 42 6:3 |new| INVOCATION qualified |
| <testLibraryFragment> bar@56 |
| 52 7:3 |new bar| INVOCATION qualified |
| <testLibraryFragment> baz@77 |
| 86 8:24 || 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''' |
| <testLibraryFragment> new@null |
| 42 6:3 |B| INVOCATION qualified |
| <testLibraryFragment> bar@51 |
| 49 7:3 |B.bar| INVOCATION qualified |
| <testLibraryFragment> baz@70 |
| 79 8:22 || REFERENCE qualified |
| <testLibraryFragment> C@90 |
| 90 11:7 |C| 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''' |
| <testLibraryFragment> A@30 |
| 10 1:11 || REFERENCE qualified |
| 18 1:19 |.new| REFERENCE qualified |
| <testLibraryFragment> bar@52 |
| 64 4:19 || INVOCATION qualified |
| <testLibraryFragment> baz@78 |
| 87 5:20 || REFERENCE qualified |
| <testLibraryFragment> new@null |
| 127 8:17 || INVOCATION qualified |
| <testLibraryFragment> useConstructor@138 |
| 160 11:4 || INVOCATION qualified |
| 167 12:4 |.new| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 182 13:10 |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 f@26 |
| 35 4:4 || 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''' |
| <testLibraryFragment> A@30 |
| 10 1:11 || REFERENCE qualified |
| 18 1:19 |.new| REFERENCE qualified |
| <testLibraryFragment> bar@42 |
| 54 3:19 || INVOCATION qualified |
| <testLibraryFragment> baz@68 |
| 77 4:20 || REFERENCE qualified |
| <testLibraryFragment> B@87 |
| 117 7:15 || INVOCATION qualified |
| <testLibraryFragment> useConstructor@128 |
| 150 10:4 || INVOCATION qualified |
| 157 11:4 |.new| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 172 12:10 |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''' |
| <testLibraryFragment> A@30 |
| 10 1:11 || REFERENCE qualified |
| 18 1:19 |.new| REFERENCE qualified |
| <testLibraryFragment> bar@47 |
| 59 4:17 || INVOCATION qualified |
| <testLibraryFragment> baz@75 |
| 84 5:22 || REFERENCE qualified |
| <testLibraryFragment> new@null |
| 121 8:14 || INVOCATION qualified |
| <testLibraryFragment> useConstructor@132 |
| 154 11:4 || INVOCATION qualified |
| 161 12:4 |.new| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 176 13:10 |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''' |
| <testLibraryFragment> A@30 |
| 10 1:11 || REFERENCE qualified |
| 18 1:19 |.new| REFERENCE qualified |
| <testLibraryFragment> bar@51 |
| 63 4:17 |.new| INVOCATION qualified |
| <testLibraryFragment> baz@83 |
| 92 5:22 |.new| REFERENCE qualified |
| <testLibraryFragment> new@null |
| 133 8:14 |.new| INVOCATION qualified |
| <testLibraryFragment> useConstructor@148 |
| 170 11:4 |.new| INVOCATION qualified |
| 181 12:4 |.new| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 196 13:10 |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 new@null |
| 54 4:14 || INVOCATION qualified |
| package:test/other.dart useConstructor@66 |
| 88 8:4 || 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 new@null |
| 54 4:14 || INVOCATION qualified |
| package:test/other.dart useConstructor@66 |
| 88 8:4 || 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''' |
| <testLibraryFragment> useConstructor@92 |
| 121 10:4 |.named| INVOCATION qualified |
| 141 12:4 |.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''' |
| <testLibraryFragment> useConstructor@92 |
| 114 9:4 || INVOCATION qualified |
| 134 11:4 || INVOCATION qualified |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> E@33 |
| 10 1:11 |.foo| REFERENCE qualified |
| 22 1:23 |.foo| REFERENCE qualified |
| <testLibraryFragment> v@39 |
| 40 3:4 |.foo| INVOCATION qualified |
| <testLibraryFragment> bar@79 |
| 91 5:25 |.foo| INVOCATION qualified |
| <testLibraryFragment> baz@115 |
| 124 6:26 |.foo| REFERENCE qualified |
| <testLibraryFragment> useConstructor@137 |
| 159 9:4 |.foo| INVOCATION qualified |
| 170 10:4 |.foo| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 185 11:10 |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''' |
| <testLibraryFragment> E@33 |
| 10 1:11 |.foo| REFERENCE qualified |
| 22 1:23 |.foo| REFERENCE qualified |
| <testLibraryFragment> v@45 |
| 46 3:4 |.foo| INVOCATION qualified |
| <testLibraryFragment> bar@66 |
| 78 4:25 |.foo| INVOCATION qualified |
| <testLibraryFragment> baz@102 |
| 111 5:26 |.foo| REFERENCE qualified |
| <testLibraryFragment> useConstructor@124 |
| 146 8:4 |.foo| INVOCATION qualified |
| 157 9:4 |.foo| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 172 10:10 |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''' |
| <testLibraryFragment> E@33 |
| 10 1:11 |.foo| REFERENCE qualified |
| 22 1:23 |.foo| REFERENCE qualified |
| <testLibraryFragment> v@39 |
| 40 3:4 |.foo| INVOCATION qualified |
| <testLibraryFragment> bar@75 |
| 87 5:23 |.foo| INVOCATION qualified |
| <testLibraryFragment> baz@113 |
| 122 6:28 |.foo| REFERENCE qualified |
| <testLibraryFragment> useConstructor@135 |
| 157 9:4 |.foo| INVOCATION qualified |
| 168 10:4 |.foo| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 183 11:10 |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''' |
| <testLibraryFragment> E@29 |
| 10 1:11 || REFERENCE qualified |
| 18 1:19 |.new| REFERENCE qualified |
| <testLibraryFragment> v1@35 |
| 37 3:5 || INVOCATION_BY_ENUM_CONSTANT_WITHOUT_ARGUMENTS qualified |
| <testLibraryFragment> v2@41 |
| 43 4:5 || INVOCATION qualified |
| <testLibraryFragment> v3@49 |
| 51 5:5 |.new| INVOCATION qualified |
| <testLibraryFragment> other@77 |
| 88 6:30 || REFERENCE qualified |
| <testLibraryFragment> useConstructor@97 |
| 119 9:4 || INVOCATION qualified |
| 126 10:4 |.new| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 141 11:10 |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''' |
| <testLibraryFragment> E@29 |
| 10 1:11 || REFERENCE qualified |
| 18 1:19 |.new| REFERENCE qualified |
| <testLibraryFragment> v1@35 |
| 37 3:5 || INVOCATION_BY_ENUM_CONSTANT_WITHOUT_ARGUMENTS qualified |
| <testLibraryFragment> v2@41 |
| 43 4:5 || INVOCATION qualified |
| <testLibraryFragment> v3@49 |
| 51 5:5 |.new| INVOCATION qualified |
| <testLibraryFragment> other@91 |
| 102 7:28 |.new| REFERENCE qualified |
| <testLibraryFragment> useConstructor@115 |
| 137 10:4 || INVOCATION qualified |
| 144 11:4 |.new| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 159 12:10 |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''' |
| <testLibraryFragment> E@29 |
| 10 1:11 || REFERENCE qualified |
| 18 1:19 |.new| REFERENCE qualified |
| <testLibraryFragment> v1@37 |
| 39 3:5 || INVOCATION_BY_ENUM_CONSTANT_WITHOUT_ARGUMENTS qualified |
| <testLibraryFragment> v2@43 |
| 45 4:5 || INVOCATION qualified |
| <testLibraryFragment> v3@51 |
| 53 5:5 |.new| INVOCATION qualified |
| <testLibraryFragment> other@77 |
| 88 6:28 |.new| REFERENCE qualified |
| <testLibraryFragment> useConstructor@101 |
| 123 9:4 || INVOCATION qualified |
| 130 10:4 |.new| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 145 11:10 |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''' |
| <testLibraryFragment> E@29 |
| 10 1:11 || REFERENCE qualified |
| 18 1:19 |.new| REFERENCE qualified |
| <testLibraryFragment> v1@35 |
| 37 3:5 || INVOCATION_BY_ENUM_CONSTANT_WITHOUT_ARGUMENTS qualified |
| <testLibraryFragment> v2@41 |
| 43 4:5 || INVOCATION qualified |
| <testLibraryFragment> v3@49 |
| 51 5:5 |.new| INVOCATION qualified |
| <testLibraryFragment> other@90 |
| 101 7:30 || REFERENCE qualified |
| <testLibraryFragment> useConstructor@110 |
| 132 10:4 || INVOCATION qualified |
| 139 11:4 |.new| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 154 12:10 |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''' |
| <testLibraryFragment> E@29 |
| 10 1:11 || REFERENCE qualified |
| 18 1:19 |.new| REFERENCE qualified |
| <testLibraryFragment> v1@35 |
| 37 3:5 || INVOCATION_BY_ENUM_CONSTANT_WITHOUT_ARGUMENTS qualified |
| <testLibraryFragment> v2@41 |
| 43 4:5 || INVOCATION qualified |
| <testLibraryFragment> v3@49 |
| 51 5:5 |.new| INVOCATION qualified |
| <testLibraryFragment> other@94 |
| 105 7:30 |.new| REFERENCE qualified |
| <testLibraryFragment> useConstructor@118 |
| 140 10:4 || INVOCATION qualified |
| 147 11:4 |.new| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 162 12:10 |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''' |
| <testLibraryFragment> A@43 |
| 10 1:11 |.foo| REFERENCE qualified |
| 22 1:23 |.foo| REFERENCE qualified |
| <testLibraryFragment> bar@81 |
| 93 4:19 |.foo| INVOCATION qualified |
| <testLibraryFragment> baz@112 |
| 127 5:26 |.foo| REFERENCE qualified |
| <testLibraryFragment> useConstructor@140 |
| 162 8:4 |.foo| INVOCATION qualified |
| 174 9:4 |.foo| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 189 10:10 |foo| 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''' |
| <testLibraryFragment> A@43 |
| 10 1:11 |.foo| REFERENCE qualified |
| 22 1:23 |.foo| REFERENCE qualified |
| <testLibraryFragment> bar@65 |
| 77 3:19 |.foo| INVOCATION qualified |
| <testLibraryFragment> baz@96 |
| 111 4:26 |.foo| REFERENCE qualified |
| <testLibraryFragment> useConstructor@124 |
| 146 7:4 |.foo| INVOCATION qualified |
| 158 8:4 |.foo| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 173 9:10 |foo| 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''' |
| <testLibraryFragment> A@43 |
| 10 1:11 |.foo| REFERENCE qualified |
| 22 1:23 |.foo| REFERENCE qualified |
| <testLibraryFragment> bar@77 |
| 89 4:17 |.foo| INVOCATION qualified |
| <testLibraryFragment> baz@110 |
| 125 5:28 |.foo| REFERENCE qualified |
| <testLibraryFragment> useConstructor@138 |
| 160 8:4 |.foo| INVOCATION qualified |
| 172 9:4 |.foo| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 187 10:10 |foo| 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''' |
| <testLibraryFragment> A@39 |
| 10 1:11 || REFERENCE qualified |
| 18 1:19 |.new| REFERENCE qualified |
| <testLibraryFragment> bar@80 |
| 92 4:19 || INVOCATION qualified |
| <testLibraryFragment> baz@107 |
| 122 5:26 |.new| REFERENCE qualified |
| <testLibraryFragment> useConstructor@135 |
| 157 8:4 || INVOCATION qualified |
| 165 9:4 |.new| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 180 10:10 |new| 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''' |
| <testLibraryFragment> A@39 |
| 10 1:11 || REFERENCE qualified |
| 18 1:19 |.new| REFERENCE qualified |
| <testLibraryFragment> bar@57 |
| 69 3:19 || INVOCATION qualified |
| <testLibraryFragment> baz@84 |
| 99 4:26 |.new| REFERENCE qualified |
| <testLibraryFragment> useConstructor@112 |
| 134 7:4 || INVOCATION qualified |
| 142 8:4 |.new| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 157 9:10 |new| 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''' |
| <testLibraryFragment> A@39 |
| 10 1:11 || REFERENCE qualified |
| 18 1:19 |.new| REFERENCE qualified |
| <testLibraryFragment> bar@75 |
| 87 4:17 || INVOCATION qualified |
| <testLibraryFragment> baz@104 |
| 119 5:28 |.new| REFERENCE qualified |
| <testLibraryFragment> useConstructor@132 |
| 154 8:4 || INVOCATION qualified |
| 162 9:4 |.new| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 177 10:10 |new| 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''' |
| <testLibraryFragment> A@39 |
| 10 1:11 || REFERENCE qualified |
| 18 1:19 |.new| REFERENCE qualified |
| <testLibraryFragment> bar@79 |
| 91 4:17 |.new| INVOCATION qualified |
| <testLibraryFragment> baz@112 |
| 127 5:28 |.new| REFERENCE qualified |
| <testLibraryFragment> useConstructor@140 |
| 162 8:4 |.new| INVOCATION qualified |
| 174 9:4 |.new| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified |
| 189 10:10 |new| 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 x@52 |
| 52 4:12 |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''' |
| <testLibraryFragment> new@null |
| 48 5:9 |E| REFERENCE |
| <testLibraryFragment> named@63 |
| 61 6:9 |E| REFERENCE |
| <testLibraryFragment> f@181 |
| 111 10:2 |E| REFERENCE |
| 118 11:4 |E| REFERENCE qualified |
| 123 12:2 |E| REFERENCE |
| 136 13:4 |E| REFERENCE qualified |
| 147 14:2 |E| REFERENCE |
| 163 15:4 |E| REFERENCE qualified |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> f@64 |
| 45 5:6 |E| REFERENCE |
| 55 5:16 |E| REFERENCE qualified |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> new@null |
| 48 5:9 |E| REFERENCE |
| <testLibraryFragment> f@61 |
| 75 9:9 |E| REFERENCE |
| 90 10:11 |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''' |
| <testLibraryFragment> f@71 |
| 79 9:3 |E| REFERENCE |
| 92 10:5 |E| 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''' |
| <testLibraryFragment> f@45 |
| 53 6:3 |E| REFERENCE |
| 63 7:5 |E| 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''' |
| <testLibraryFragment> main@63 |
| 74 7:3 |E| REFERENCE |
| 88 8:3 |E| 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''' |
| <testLibraryFragment> f@80 |
| 62 5:2 |A| REFERENCE |
| 70 6:4 |A| REFERENCE qualified |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> f@79 |
| 60 5:6 |A| REFERENCE |
| 70 5:16 |A| REFERENCE qualified |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> f@60 |
| 68 6:3 |A| REFERENCE |
| 78 7:5 |A| 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''' |
| <testLibraryFragment> f@84 |
| 92 8:3 |A| REFERENCE |
| 105 9:5 |A| 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''' |
| <testLibraryFragment> f@60 |
| 68 6:3 |A| REFERENCE |
| 78 7:5 |A| REFERENCE qualified |
| '''); |
| } |
| |
| test_searchReferences_FieldElement_ofClass_instance() async { |
| var result = await resolveTestCode(''' |
| /// [foo] and [A.foo] |
| class A { |
| int foo; |
| A({this.foo}); |
| A.foo() : foo = 0; |
| |
| void useField() { |
| foo; |
| foo = 0; |
| this.foo; |
| this.foo = 0; |
| } |
| } |
| |
| void useField(A a) { |
| a.foo; |
| a.foo = 0; |
| A(foo: 0); |
| } |
| '''); |
| var element = result.findElement.field('foo'); |
| |
| await assertElementReferencesText(element, r''' |
| <testLibraryFragment> A@28 |
| 5 1:6 |foo| READ |
| 17 1:18 |foo| READ qualified |
| <testLibraryFragment> foo@53 |
| 53 4:11 |foo| WRITE qualified |
| <testLibraryFragment> foo@64 |
| 72 5:13 |foo| WRITE qualified |
| <testLibraryFragment> useField@89 |
| 106 8:5 |foo| READ |
| 115 9:5 |foo| WRITE |
| 133 10:10 |foo| READ qualified |
| 147 11:10 |foo| WRITE qualified |
| <testLibraryFragment> useField@168 |
| 188 16:5 |foo| READ qualified |
| 197 17:5 |foo| WRITE qualified |
| '''); |
| } |
| |
| test_searchReferences_FieldElement_ofClass_instance_synthetic_hasGetter() async { |
| var result = await resolveTestCode(''' |
| class A { |
| A() : foo = 0; |
| int get foo => 0; |
| } |
| '''); |
| var element = result.findElement.field('foo'); |
| |
| await assertElementReferencesText(element, r''' |
| '''); |
| } |
| |
| test_searchReferences_FieldElement_ofClass_instance_synthetic_hasGetterSetter() async { |
| var result = await resolveTestCode(''' |
| class A { |
| A() : foo = 0; |
| int get foo => 0; |
| set foo(_) {} |
| } |
| '''); |
| var element = result.findElement.field('foo'); |
| |
| await assertElementReferencesText(element, r''' |
| '''); |
| } |
| |
| test_searchReferences_FieldElement_ofClass_instance_synthetic_hasSetter() async { |
| var result = await resolveTestCode(''' |
| class A { |
| A() : foo = 0; |
| set foo(_) {} |
| } |
| '''); |
| var element = result.findElement.field('foo'); |
| |
| await assertElementReferencesText(element, r''' |
| '''); |
| } |
| |
| test_searchReferences_FieldElement_ofClass_static() 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 element = result.findElement.field('foo'); |
| |
| await assertElementReferencesText(element, r''' |
| <testLibraryFragment> A@28 |
| 5 1:6 |foo| READ |
| 17 1:18 |foo| READ qualified |
| <testLibraryFragment> useField@68 |
| 85 5:5 |foo| READ |
| 94 6:5 |foo| WRITE |
| 109 7:7 |foo| READ qualified |
| 120 8:7 |foo| WRITE qualified |
| <testLibraryFragment> useField@141 |
| 158 13:5 |foo| READ qualified |
| 167 14:5 |foo| WRITE qualified |
| 185 15:10 |foo| READ qualified |
| '''); |
| } |
| |
| test_searchReferences_FieldElement_ofEnum_instance() 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 element = result.findElement.field('foo'); |
| |
| await assertElementReferencesText(element, r''' |
| <testLibraryFragment> E@27 |
| 5 1:6 |foo| READ |
| 17 1:18 |foo| READ qualified |
| <testLibraryFragment> foo@82 |
| 82 5:11 |foo| WRITE qualified |
| <testLibraryFragment> useField@96 |
| 113 7:5 |foo| READ |
| 122 8:5 |foo| WRITE |
| <testLibraryFragment> useField@142 |
| 162 12:5 |foo| READ qualified |
| 171 13:5 |foo| WRITE qualified |
| '''); |
| } |
| |
| 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 assertElementReferencesText(index, r''' |
| <testLibraryFragment> main@29 |
| 50 5:13 |index| READ qualified |
| '''); |
| } |
| |
| test_searchReferences_FieldElement_ofEnum_instance_synthetic_hasGetter() async { |
| var result = await resolveTestCode(''' |
| enum E { |
| v; |
| E() : foo = 0; |
| int get foo => 0; |
| } |
| '''); |
| var element = result.findElement.field('foo'); |
| |
| await assertElementReferencesText(element, r''' |
| '''); |
| } |
| |
| test_searchReferences_FieldElement_ofEnum_instance_synthetic_hasGetterSetter() async { |
| var result = await resolveTestCode(''' |
| enum E { |
| v; |
| E() : foo = 0; |
| int get foo => 0; |
| set foo(_) {} |
| } |
| '''); |
| var element = result.findElement.field('foo'); |
| |
| await assertElementReferencesText(element, r''' |
| '''); |
| } |
| |
| test_searchReferences_FieldElement_ofEnum_instance_synthetic_hasSetter() async { |
| var result = await resolveTestCode(''' |
| enum E { |
| v; |
| E() : foo = 0; |
| set foo(_) {} |
| } |
| '''); |
| var element = result.findElement.field('foo'); |
| |
| await assertElementReferencesText(element, 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 assertElementReferencesText(values, r''' |
| <testLibraryFragment> main@96 |
| 133 9:10 |values| READ qualified |
| 193 13:12 |values| READ qualified |
| '''); |
| |
| var v1 = result.findElement.field('v1'); |
| await assertElementReferencesText(v1, r''' |
| <testLibraryFragment> MyEnum@72 |
| 31 3:6 |v1| READ |
| 44 3:19 |v1| READ qualified |
| 63 3:38 |v1| READ qualified |
| <testLibraryFragment> main@96 |
| 114 8:10 |v1| READ qualified |
| 150 10:10 |v1| READ qualified |
| 178 12:12 |v1| READ qualified |
| '''); |
| |
| var v2 = result.findElement.field('v2'); |
| await assertElementReferencesText(v2, r''' |
| <testLibraryFragment> main@96 |
| 163 11:10 |v2| READ qualified |
| '''); |
| } |
| |
| test_searchReferences_FieldElement_ofExtensionType_static() 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 element = result.findElement.field('foo'); |
| |
| await assertElementReferencesText(element, r''' |
| <testLibraryFragment> A@37 |
| 5 1:6 |foo| READ |
| 17 1:18 |foo| READ qualified |
| <testLibraryFragment> useField@78 |
| 95 5:5 |foo| READ |
| 104 6:5 |foo| WRITE |
| <testLibraryFragment> useField@124 |
| 141 10:5 |foo| READ qualified |
| 150 11:5 |foo| WRITE 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''' |
| <testLibraryFragment> f@40 |
| 52 5:7 |test| 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''' |
| <testLibraryFragment> A@6 |
| 30 2:8 |test| REFERENCE |
| 52 3:17 |test| READ |
| 72 4:5 |test| READ |
| 82 5:5 |test| WRITE |
| 96 6:5 |test| READ_WRITE |
| 112 7:6 |test| WRITE |
| 136 8:10 |test| WRITE |
| <testLibraryFragment> redirect@161 |
| 190 11:34 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| <testLibraryFragment> test@237 |
| 237 15:12 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| <testLibraryFragment> new@null |
| 293 19:26 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| <testLibraryFragment> f@314 |
| 324 23:5 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 347 24:14 |test| 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''' |
| <testLibraryFragment> A@6 |
| 31 2:8 |test| REFERENCE |
| 53 3:17 |test| READ |
| 73 4:5 |test| READ |
| 83 5:5 |test| WRITE |
| 101 6:6 |test| WRITE |
| 128 7:10 |test| WRITE |
| <testLibraryFragment> redirect@156 |
| 183 10:32 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| <testLibraryFragment> test@236 |
| 236 14:12 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| <testLibraryFragment> new@null |
| 296 18:24 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| <testLibraryFragment> f@317 |
| 327 22:5 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 355 23:19 |test| 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''' |
| <testLibraryFragment> A@6 |
| 30 2:8 |test| REFERENCE |
| 52 3:17 |test| READ |
| 72 4:5 |test| READ |
| 82 5:5 |test| WRITE |
| 96 6:5 |test| READ_WRITE |
| 112 7:6 |test| WRITE |
| 136 8:10 |test| WRITE |
| <testLibraryFragment> test@231 |
| 231 15:12 |test| REFERENCE qualified |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> A@6 |
| 38 2:8 |test| REFERENCE |
| 60 3:17 |test| READ |
| 78 4:5 |test| READ |
| 88 5:5 |test| WRITE |
| 102 6:5 |test| READ_WRITE |
| 118 7:6 |test| WRITE |
| 142 8:10 |test| WRITE |
| <testLibraryFragment> redirect@167 |
| 204 11:42 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| <testLibraryFragment> test@260 |
| 260 15:21 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| <testLibraryFragment> new@null |
| 324 19:34 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| <testLibraryFragment> f@345 |
| 355 23:5 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 378 24:14 |test| 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''' |
| <testLibraryFragment> A@6 |
| 27 2:8 |test| REFERENCE |
| 49 3:17 |test| READ |
| 67 4:5 |test| READ |
| 77 5:5 |test| WRITE |
| 91 6:5 |test| READ_WRITE |
| 107 7:6 |test| WRITE |
| 131 8:10 |test| WRITE |
| <testLibraryFragment> test@222 |
| 222 15:11 |test| REFERENCE qualified |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> new@null |
| 17 2:8 |test| REFERENCE |
| 49 3:27 |test| READ |
| 69 4:5 |test| READ |
| 79 5:5 |test| WRITE |
| 93 6:5 |test| READ_WRITE |
| 109 7:6 |test| WRITE |
| 133 8:10 |test| WRITE |
| <testLibraryFragment> redirect@158 |
| 187 11:34 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| <testLibraryFragment> test@234 |
| 234 15:12 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| <testLibraryFragment> new@null |
| 290 19:26 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| <testLibraryFragment> f@311 |
| 321 23:5 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 344 24:14 |test| 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''' |
| <testLibraryFragment> new@null |
| 20 2:8 |test| REFERENCE |
| 50 3:25 |test| READ |
| 70 4:5 |test| READ |
| 80 5:5 |test| WRITE |
| 98 6:6 |test| WRITE |
| 125 7:10 |test| WRITE |
| <testLibraryFragment> redirect@153 |
| 180 10:32 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| <testLibraryFragment> test@233 |
| 233 14:12 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| <testLibraryFragment> new@null |
| 293 18:24 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| <testLibraryFragment> f@314 |
| 324 22:5 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 352 23:19 |test| 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''' |
| <testLibraryFragment> new@null |
| 17 2:8 |test| REFERENCE |
| 49 3:27 |test| READ |
| 69 4:5 |test| READ |
| 79 5:5 |test| WRITE |
| 93 6:5 |test| READ_WRITE |
| 109 7:6 |test| WRITE |
| 133 8:10 |test| WRITE |
| <testLibraryFragment> test@228 |
| 228 15:12 |test| REFERENCE qualified |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> new@null |
| 17 2:8 |test| REFERENCE |
| 57 3:35 |test| READ |
| 75 4:5 |test| READ |
| 85 5:5 |test| WRITE |
| 99 6:5 |test| READ_WRITE |
| 115 7:6 |test| WRITE |
| 139 8:10 |test| WRITE |
| <testLibraryFragment> redirect@164 |
| 201 11:42 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| <testLibraryFragment> test@257 |
| 257 15:21 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| <testLibraryFragment> new@null |
| 321 19:34 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| <testLibraryFragment> f@342 |
| 352 23:5 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 375 24:14 |test| 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''' |
| <testLibraryFragment> new@null |
| 17 2:8 |test| REFERENCE |
| 46 3:24 |test| READ |
| 64 4:5 |test| READ |
| 74 5:5 |test| WRITE |
| 88 6:5 |test| READ_WRITE |
| 104 7:6 |test| WRITE |
| 128 8:10 |test| WRITE |
| <testLibraryFragment> test@219 |
| 219 15:11 |test| REFERENCE qualified |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> f@5 |
| 54 4:5 |test| READ |
| 64 5:5 |test| WRITE |
| 78 6:5 |test| READ_WRITE |
| 94 7:6 |test| WRITE |
| 118 8:10 |test| WRITE |
| 145 11:7 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 166 12:12 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 184 13:9 |test| 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''' |
| <testLibraryFragment> f@5 |
| 42 3:5 |test| READ |
| 52 4:5 |test| WRITE |
| 66 5:5 |test| READ_WRITE |
| 82 6:6 |test| WRITE |
| 106 7:10 |test| WRITE |
| 133 10:7 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 154 11:12 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 172 12:9 |test| 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''' |
| <testLibraryFragment> f@5 |
| 54 4:5 |test| READ |
| 64 5:5 |test| WRITE |
| 78 6:5 |test| READ_WRITE |
| 94 7:6 |test| WRITE |
| 118 8:10 |test| WRITE |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> f@5 |
| 62 4:5 |test| READ |
| 72 5:5 |test| WRITE |
| 86 6:5 |test| READ_WRITE |
| 102 7:6 |test| WRITE |
| 126 8:10 |test| WRITE |
| 153 11:7 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 174 12:12 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 192 13:9 |test| 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''' |
| <testLibraryFragment> f@5 |
| 51 4:5 |test| READ |
| 61 5:5 |test| WRITE |
| 75 6:5 |test| READ_WRITE |
| 91 7:6 |test| WRITE |
| 115 8:10 |test| WRITE |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> foo@30 |
| 17 2:8 |test| REFERENCE |
| 53 4:5 |test| READ |
| 63 5:5 |test| WRITE |
| 77 6:5 |test| READ_WRITE |
| 93 7:6 |test| WRITE |
| 117 8:10 |test| WRITE |
| <testLibraryFragment> f@145 |
| 162 13:9 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 185 14:14 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 205 15:11 |test| 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''' |
| <testLibraryFragment> foo@33 |
| 20 2:8 |test| REFERENCE |
| 54 4:5 |test| READ |
| 64 5:5 |test| WRITE |
| 81 6:5 |test| WRITE |
| 88 6:12 |test| READ |
| 99 7:6 |test| WRITE |
| 126 8:10 |test| WRITE |
| <testLibraryFragment> f@157 |
| 179 13:9 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> foo@30 |
| 17 2:8 |test| REFERENCE |
| 53 4:5 |test| READ |
| 63 5:5 |test| WRITE |
| 77 6:5 |test| READ_WRITE |
| 93 7:6 |test| WRITE |
| 117 8:10 |test| WRITE |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> foo@30 |
| 17 2:8 |test| REFERENCE |
| 61 4:5 |test| READ |
| 71 5:5 |test| WRITE |
| 85 6:5 |test| READ_WRITE |
| 101 7:6 |test| WRITE |
| 125 8:10 |test| WRITE |
| <testLibraryFragment> f@153 |
| 170 13:9 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 193 14:14 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 213 15:11 |test| 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''' |
| <testLibraryFragment> foo@30 |
| 17 2:8 |test| REFERENCE |
| 50 4:5 |test| READ |
| 60 5:5 |test| WRITE |
| 74 6:5 |test| READ_WRITE |
| 90 7:6 |test| WRITE |
| 114 8:10 |test| WRITE |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> foo@16 |
| 5 1:6 |test| REFERENCE |
| 37 3:3 |test| READ |
| 45 4:3 |test| WRITE |
| 57 5:3 |test| READ_WRITE |
| 71 6:4 |test| WRITE |
| 93 7:8 |test| WRITE |
| <testLibraryFragment> f@116 |
| 128 10:7 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 149 11:12 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 167 12:9 |test| 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''' |
| <testLibraryFragment> foo@16 |
| 5 1:6 |test| REFERENCE |
| 51 3:3 |test| READ |
| 59 4:3 |test| WRITE |
| 71 5:3 |test| READ_WRITE |
| 85 6:4 |test| WRITE |
| 107 7:8 |test| WRITE |
| <testLibraryFragment> f@131 |
| 146 11:10 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 173 12:15 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 197 13:12 |test| 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''' |
| <testLibraryFragment> foo@16 |
| 5 1:6 |test| REFERENCE |
| 37 3:3 |test| READ |
| 45 4:3 |test| WRITE |
| 57 5:3 |test| READ_WRITE |
| 71 6:4 |test| WRITE |
| 93 7:8 |test| WRITE |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> foo@16 |
| 5 1:6 |test| REFERENCE |
| 45 3:3 |test| READ |
| 53 4:3 |test| WRITE |
| 65 5:3 |test| READ_WRITE |
| 79 6:4 |test| WRITE |
| 101 7:8 |test| WRITE |
| <testLibraryFragment> f@125 |
| 137 11:7 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 158 12:12 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 176 13:9 |test| 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''' |
| <testLibraryFragment> foo@16 |
| 5 1:6 |test| REFERENCE |
| 34 3:3 |test| READ |
| 42 4:3 |test| WRITE |
| 54 5:3 |test| READ_WRITE |
| 68 6:4 |test| WRITE |
| 90 7:8 |test| WRITE |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> main@10 |
| 21 3:3 |test| INVOCATION |
| 31 4:3 |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''' |
| <testLibraryFragment> main@0 |
| 23 3:3 |test| INVOCATION |
| 33 4:3 |test| REFERENCE |
| '''); |
| } |
| |
| test_searchReferences_GetterElement_ofClass_instance() async { |
| var result = await resolveTestCode(''' |
| /// [foo] and [A.foo] |
| class A { |
| int get foo => 0; |
| void useGetter() { |
| foo; |
| this.foo; |
| } |
| } |
| |
| void useGetter(A a) { |
| a.foo; |
| } |
| '''); |
| var element = result.findElement.getter('foo'); |
| await assertElementReferencesText(element, r''' |
| <testLibraryFragment> A@28 |
| 5 1:6 |foo| REFERENCE |
| 17 1:18 |foo| REFERENCE qualified |
| <testLibraryFragment> useGetter@59 |
| 77 5:5 |foo| REFERENCE |
| 91 6:10 |foo| REFERENCE qualified |
| <testLibraryFragment> useGetter@108 |
| 129 11:5 |foo| REFERENCE qualified |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> useGetter@36 |
| 59 4:10 |foo| REFERENCE qualified |
| 70 5:5 |foo| REFERENCE |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> useGetter@38 |
| 76 6:16 |foo| REFERENCE_IN_PATTERN_FIELD qualified |
| 103 7:16 || REFERENCE_IN_PATTERN_FIELD 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''' |
| <testLibraryFragment> A@62 |
| 31 3:6 |foo| REFERENCE |
| 40 3:15 |foo| REFERENCE qualified |
| 51 3:26 |foo| REFERENCE qualified |
| <testLibraryFragment> useGetter@107 |
| 125 7:5 |foo| REFERENCE |
| <testLibraryFragment> useGetter@142 |
| 160 12:5 |foo| REFERENCE qualified |
| 171 13:7 |foo| REFERENCE 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''' |
| #F0 |
| 111 4:3 || |
| 121 5:7 || |
| 133 6:3 || |
| 146 8:1 || |
| '''); |
| } |
| |
| 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''' |
| #F0 |
| 111 4:3 || |
| 121 5:7 || |
| 133 6:3 || |
| 146 8:1 || |
| '''); |
| } |
| |
| 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''' |
| #F0 |
| 119 4:3 |math.| |
| 134 5:7 |math.| |
| 151 6:3 |math.| |
| 169 8:1 |math.| |
| '''); |
| } |
| |
| 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''' |
| #F0 |
| 76 5:3 |p.| |
| '''); |
| } |
| { |
| var element = result.findElement.import('dart:math'); |
| await assertLibraryImportReferencesText(element, r''' |
| #F0 |
| 62 4:3 |p.| |
| '''); |
| } |
| } |
| |
| 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''' |
| <testLibraryFragment> main@0 |
| 61 5:13 |label| REFERENCE |
| 84 7:11 |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''' |
| #F0 |
| 8 1:9 |lib| REFERENCE |
| #F1 |
| 8 1:9 |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''' |
| #F0 |
| 8 1:9 |lib| REFERENCE |
| #F1 |
| 8 1:9 |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''' |
| #F0 |
| 8 1:9 |'test.dart'| REFERENCE |
| #F1 |
| 8 1:9 |'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''' |
| #F0 |
| 7 1:8 |'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''' |
| #F0 |
| 7 1:8 |'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''' |
| #F0 |
| 5 1:6 |'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''' |
| <testLibraryFragment> main@0 |
| 20 3:3 |v| WRITE |
| 29 4:3 |v| READ_WRITE |
| 39 5:3 |v| READ |
| 44 6:3 |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''' |
| <testLibraryFragment> f@7 |
| 36 2:21 |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''' |
| <testLibraryFragment> f@7 |
| 54 4:25 |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''' |
| <testLibraryFragment> f@7 |
| 46 3:23 |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''' |
| <testLibraryFragment> x@4 |
| 30 2:21 |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''' |
| <testLibraryFragment> main@0 |
| 35 3:5 |v| WRITE |
| 46 4:5 |v| READ_WRITE |
| 58 5:5 |v| READ |
| 65 6:5 |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@0 |
| 20 3:3 |v| WRITE |
| 29 4:3 |v| READ_WRITE |
| 39 5:3 |v| READ |
| 44 6:3 |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''' |
| <testLibraryFragment> A@28 |
| 5 1:6 |foo| REFERENCE |
| 17 1:18 |foo| REFERENCE qualified |
| <testLibraryFragment> useFoo@55 |
| 84 5:10 |foo| INVOCATION qualified |
| 95 6:5 |foo| INVOCATION |
| 111 7:10 |foo| REFERENCE qualified |
| 120 8:5 |foo| REFERENCE |
| 142 9:18 |foo| REFERENCE qualified |
| 171 10:18 || REFERENCE qualified |
| <testLibraryFragment> useFoo@197 |
| 215 14:5 |foo| INVOCATION qualified |
| 226 15:5 |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''' |
| <testLibraryFragment> A@28 |
| 5 1:6 |foo| REFERENCE |
| 17 1:18 |foo| REFERENCE qualified |
| <testLibraryFragment> useFoo@58 |
| 87 5:10 |foo| INVOCATION qualified |
| 98 6:5 |foo| INVOCATION |
| 114 7:10 |foo| REFERENCE qualified |
| 123 8:5 |foo| REFERENCE |
| 150 9:23 |foo| REFERENCE qualified |
| 184 10:23 || REFERENCE qualified |
| <testLibraryFragment> useFoo@210 |
| 233 14:5 |foo| INVOCATION qualified |
| 244 15:5 |foo| REFERENCE qualified |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> A@62 |
| 31 3:6 |foo| REFERENCE |
| 40 3:15 |foo| REFERENCE qualified |
| 51 3:26 |foo| REFERENCE qualified |
| <testLibraryFragment> useFoo@105 |
| 120 7:5 |foo| INVOCATION |
| 131 8:5 |foo| REFERENCE |
| <testLibraryFragment> useFoo@148 |
| 163 13:5 |foo| INVOCATION qualified |
| 174 14:5 |foo| REFERENCE qualified |
| 188 15:10 |foo| INVOCATION qualified |
| 205 16:11 |foo| REFERENCE qualified |
| 216 17:7 |foo| INVOCATION qualified |
| 229 18:7 |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 useFoo@26 |
| 45 4:9 |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 useFoo@26 |
| 41 4:5 |foo| INVOCATION qualified |
| 52 5:5 |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''' |
| <testLibraryFragment> E@27 |
| 5 1:6 |foo| REFERENCE |
| 17 1:18 |foo| REFERENCE qualified |
| <testLibraryFragment> useFoo@59 |
| 79 6:10 |foo| INVOCATION qualified |
| 90 7:5 |foo| INVOCATION |
| 106 8:10 |foo| REFERENCE qualified |
| 115 9:5 |foo| REFERENCE |
| <testLibraryFragment> useFoo@131 |
| 149 13:5 |foo| INVOCATION qualified |
| 160 14:5 |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''' |
| <testLibraryFragment> E@27 |
| 5 1:6 |foo| REFERENCE |
| 17 1:18 |foo| REFERENCE qualified |
| <testLibraryFragment> useFoo@73 |
| 88 6:5 |foo| INVOCATION |
| 99 7:5 |foo| REFERENCE |
| <testLibraryFragment> useFoo@115 |
| 130 11:5 |foo| INVOCATION qualified |
| 141 12:5 |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''' |
| <testLibraryFragment> E@32 |
| 5 1:6 |foo| REFERENCE |
| 17 1:18 |foo| REFERENCE qualified |
| <testLibraryFragment> useFoo@67 |
| 82 7:5 |foo| INVOCATION qualified |
| 93 8:5 |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''' |
| <testLibraryFragment> E@32 |
| 5 1:6 |foo| REFERENCE |
| 17 1:18 |foo| REFERENCE qualified |
| <testLibraryFragment> useFoo@74 |
| 89 7:5 |foo| INVOCATION qualified |
| 100 8:5 |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''' |
| <testLibraryFragment> null@null |
| 5 1:6 |foo| REFERENCE |
| <testLibraryFragment> useFoo@152 |
| 167 12:5 |foo| INVOCATION qualified |
| 178 13:5 |foo| REFERENCE qualified |
| '''); |
| |
| var doubleMethod = result.findNode.methodDeclaration('foo() {} // double'); |
| var doubleMethodElement = doubleMethod.declaredFragment!.element; |
| await assertElementReferencesText(doubleMethodElement, r''' |
| <testLibraryFragment> null@null |
| 74 6:6 |foo| REFERENCE |
| <testLibraryFragment> useFoo@152 |
| 191 14:9 |foo| INVOCATION qualified |
| 206 15:9 |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''' |
| <testLibraryFragment> A@37 |
| 5 1:6 |foo| REFERENCE |
| 17 1:18 |foo| REFERENCE qualified |
| <testLibraryFragment> useFoo@72 |
| 92 5:10 |foo| INVOCATION qualified |
| 103 6:5 |foo| INVOCATION |
| 119 7:10 |foo| REFERENCE qualified |
| 128 8:5 |foo| REFERENCE |
| <testLibraryFragment> useFoo@144 |
| 175 13:5 |foo| INVOCATION qualified |
| 186 14:5 |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''' |
| <testLibraryFragment> A@37 |
| 5 1:6 |foo| REFERENCE |
| 17 1:18 |foo| REFERENCE qualified |
| <testLibraryFragment> useFoo@86 |
| 101 5:5 |foo| INVOCATION |
| 112 6:5 |foo| REFERENCE |
| <testLibraryFragment> useFoo@128 |
| 143 10:5 |foo| INVOCATION qualified |
| 154 11:5 |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''' |
| <testLibraryFragment> M@28 |
| 5 1:6 |foo| REFERENCE |
| 17 1:18 |foo| REFERENCE qualified |
| <testLibraryFragment> useFoo@55 |
| 75 5:10 |foo| INVOCATION qualified |
| 86 6:5 |foo| INVOCATION |
| 102 7:10 |foo| REFERENCE qualified |
| 111 8:5 |foo| REFERENCE |
| <testLibraryFragment> useFoo@127 |
| 145 12:5 |foo| INVOCATION qualified |
| 156 13:5 |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''' |
| <testLibraryFragment> M@28 |
| 5 1:6 |foo| REFERENCE |
| 17 1:18 |foo| REFERENCE qualified |
| <testLibraryFragment> useFoo@69 |
| 84 5:5 |foo| INVOCATION |
| 95 6:5 |foo| REFERENCE |
| <testLibraryFragment> useFoo@111 |
| 126 10:5 |foo| INVOCATION qualified |
| 137 11:5 |foo| REFERENCE qualified |
| 151 12:10 |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''' |
| <testLibraryFragment> A@42 |
| 14 1:15 |+| REFERENCE |
| 33 1:34 |+| REFERENCE qualified |
| <testLibraryFragment> useOperator@82 |
| 105 6:5 |+| INVOCATION qualified |
| 114 7:5 |+=| INVOCATION qualified |
| 122 8:3 |++| INVOCATION qualified |
| 130 9:4 |++| INVOCATION qualified |
| '''); |
| } |
| |
| test_searchReferences_MethodElement_operator_ofClass_index() async { |
| var result = await resolveTestCode(''' |
| /// [operator []] and [A.operator []] |
| class A { |
| operator [](i) => null; |
| } |
| void useOperator(A a) { |
| a[0]; |
| } |
| '''); |
| var element = result.findElement.method('[]'); |
| |
| await assertElementReferencesText(element, r''' |
| <testLibraryFragment> useOperator@81 |
| 103 6:4 |[| INVOCATION qualified |
| '''); |
| } |
| |
| test_searchReferences_MethodElement_operator_ofClass_indexEq() async { |
| var result = await resolveTestCode(''' |
| /// [operator []=] and [A.operator []=] |
| class A { |
| operator []=(i, v) {} |
| } |
| void useOperator(A a) { |
| a[1] = 42; |
| } |
| '''); |
| var element = result.findElement.method('[]='); |
| |
| await assertElementReferencesText(element, r''' |
| <testLibraryFragment> useOperator@81 |
| 103 6:4 |[| 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''' |
| <testLibraryFragment> A@42 |
| 14 1:15 |~| REFERENCE |
| 33 1:34 |~| REFERENCE qualified |
| <testLibraryFragment> useOperator@79 |
| 100 6:3 |~| 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''' |
| <testLibraryFragment> E@41 |
| 14 1:15 |+| REFERENCE |
| 33 1:34 |+| REFERENCE qualified |
| <testLibraryFragment> useOperator@87 |
| 110 7:5 |+| INVOCATION qualified |
| 119 8:5 |+=| INVOCATION qualified |
| 127 9:3 |++| INVOCATION qualified |
| 135 10:4 |++| 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''' |
| <testLibraryFragment> useOperator@94 |
| 116 7:4 |[| 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''' |
| <testLibraryFragment> useOperator@101 |
| 123 7:4 |[| 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''' |
| <testLibraryFragment> E@41 |
| 14 1:15 |~| REFERENCE |
| 33 1:34 |~| REFERENCE qualified |
| <testLibraryFragment> useOperator@82 |
| 103 7:3 |~| 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''' |
| <testLibraryFragment> E@46 |
| 14 1:15 |+| REFERENCE |
| 33 1:34 |+| REFERENCE qualified |
| <testLibraryFragment> useOperator@98 |
| 126 6:8 |+| 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''' |
| <testLibraryFragment> useOperator@101 |
| 128 6:7 |[| 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''' |
| <testLibraryFragment> useOperator@108 |
| 135 6:7 |[| 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''' |
| <testLibraryFragment> E@46 |
| 14 1:15 |~| REFERENCE |
| 33 1:34 |~| REFERENCE qualified |
| <testLibraryFragment> useOperator@89 |
| 112 6:3 |~| 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''' |
| <testLibraryFragment> A@51 |
| 14 1:15 |+| REFERENCE |
| 33 1:34 |+| REFERENCE qualified |
| <testLibraryFragment> useOperator@104 |
| 127 6:5 |+| INVOCATION qualified |
| 136 7:5 |+=| INVOCATION qualified |
| 144 8:3 |++| INVOCATION qualified |
| 152 9:4 |++| 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''' |
| <testLibraryFragment> useOperator@107 |
| 129 6:4 |[| 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''' |
| <testLibraryFragment> useOperator@114 |
| 136 6:4 |[| 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''' |
| <testLibraryFragment> A@51 |
| 14 1:15 |~| REFERENCE |
| 33 1:34 |~| REFERENCE qualified |
| <testLibraryFragment> useOperator@95 |
| 116 6:3 |~| 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''' |
| <testLibraryFragment> M@42 |
| 14 1:15 |+| REFERENCE |
| 33 1:34 |+| REFERENCE qualified |
| <testLibraryFragment> useOperator@87 |
| 110 6:5 |+| INVOCATION qualified |
| 119 7:5 |+=| INVOCATION qualified |
| 127 8:3 |++| INVOCATION qualified |
| 135 9:4 |++| 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''' |
| <testLibraryFragment> useOperator@90 |
| 112 6:4 |[| 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''' |
| <testLibraryFragment> useOperator@97 |
| 119 6:4 |[| 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''' |
| <testLibraryFragment> M@42 |
| 14 1:15 |~| REFERENCE |
| 33 1:34 |~| REFERENCE qualified |
| <testLibraryFragment> useOperator@78 |
| 99 6:3 |~| 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''' |
| <testLibraryFragment> f@109 |
| 75 7:2 |A| REFERENCE |
| 91 8:4 |A| REFERENCE qualified |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> f@62 |
| 43 5:6 |A| REFERENCE |
| 53 5:16 |A| REFERENCE qualified |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> f@67 |
| 75 8:3 |A| REFERENCE |
| 88 9:5 |A| 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''' |
| <testLibraryFragment> v1@47 |
| 45 5:8 |A| REFERENCE |
| <testLibraryFragment> v2@55 |
| 53 5:16 |A| 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''' |
| <testLibraryFragment> f@5 |
| 19 2:9 |p| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 42 3:9 |p| REFERENCE_BY_NAMED_ARGUMENT qualified |
| '''); |
| } |
| |
| @SkippedTest( |
| // 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 c@27 |
| 16 2:1 |ppp| REFERENCE |
| <testLibraryFragment> main@65 |
| 76 5:3 |ppp| REFERENCE |
| 92 6:3 |ppp| 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''' |
| <testLibraryFragment> f@33 |
| 41 4:3 |prefix| 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 main@65 |
| 76 5:3 |ppp| REFERENCE |
| 92 6:3 |ppp| REFERENCE |
| package:aaa/my_part.dart c@27 |
| 16 2:1 |ppp| 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 v1@16 |
| 13 1:14 |_C| REFERENCE |
| package:test/part2.dart v2@16 |
| 13 1:14 |_C| REFERENCE |
| <testLibraryFragment> v@85 |
| 82 6:1 |_C| 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 v1@28 |
| 25 3:1 |_C| REFERENCE |
| package:test/part2.dart v2@16 |
| 13 1:14 |_C| REFERENCE |
| <testLibraryFragment> v@54 |
| 51 4:1 |_C| 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 v@66 |
| 63 5:1 |_C| REFERENCE |
| package:aaa/part1.dart v1@16 |
| 13 1:14 |_C| REFERENCE |
| package:aaa/part2.dart v2@16 |
| 13 1:14 |_C| 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''' |
| <testLibraryFragment> bar@49 |
| 61 5:5 |foo| REFERENCE |
| 75 6:10 |foo| REFERENCE qualified |
| <testLibraryFragment> main@87 |
| 103 11:8 |foo| REFERENCE qualified |
| 112 12:5 |foo| REFERENCE 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''' |
| <testLibraryFragment> bar@49 |
| 61 5:5 |foo| REFERENCE |
| 79 6:10 |foo| REFERENCE qualified |
| <testLibraryFragment> main@95 |
| 111 11:8 |foo| REFERENCE qualified |
| 124 12:5 |foo| REFERENCE 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''' |
| <testLibraryFragment> main@31 |
| 44 4:5 |ggg| REFERENCE |
| 58 5:10 |ggg| REFERENCE qualified |
| 67 6:5 |ggg| REFERENCE |
| 83 7:10 |ggg| REFERENCE 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''' |
| <testLibraryFragment> main@26 |
| 39 4:5 |s| REFERENCE |
| 55 5:10 |s| REFERENCE qualified |
| '''); |
| } |
| |
| test_searchReferences_SetterElement_ofClass_instance() async { |
| var result = await resolveTestCode(''' |
| /// [foo] and [A.foo] |
| class A { |
| set foo(int _) {} |
| void useSetter() { |
| foo = 0; |
| this.foo = 0; |
| } |
| } |
| |
| void useSetter(A a) { |
| a.foo = 0; |
| } |
| '''); |
| var element = result.findElement.setter('foo'); |
| await assertElementReferencesText(element, r''' |
| <testLibraryFragment> A@28 |
| 5 1:6 |foo| REFERENCE |
| 17 1:18 |foo| REFERENCE qualified |
| <testLibraryFragment> useSetter@59 |
| 77 5:5 |foo| REFERENCE |
| 95 6:10 |foo| REFERENCE qualified |
| <testLibraryFragment> useSetter@116 |
| 137 11:5 |foo| REFERENCE 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''' |
| <testLibraryFragment> A@62 |
| 31 3:6 |foo| REFERENCE |
| 40 3:15 |foo| REFERENCE qualified |
| 51 3:26 |foo| REFERENCE qualified |
| <testLibraryFragment> useSetter@107 |
| 125 7:5 |foo| REFERENCE |
| <testLibraryFragment> useSetter@146 |
| 164 12:5 |foo| REFERENCE qualified |
| 179 13:7 |foo| REFERENCE 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''' |
| <testLibraryFragment> new@null |
| 58 6:8 |test| REFERENCE |
| 91 7:28 |test| READ |
| <testLibraryFragment> f@114 |
| 124 11:5 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 147 12:14 |test| 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''' |
| <testLibraryFragment> new@null |
| 58 6:8 |test| REFERENCE |
| 91 7:28 |test| READ |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> new@null |
| 66 6:8 |test| REFERENCE |
| 108 7:37 |test| READ |
| <testLibraryFragment> f@129 |
| 139 11:5 |test| REFERENCE_BY_NAMED_ARGUMENT qualified |
| 162 12:14 |test| 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''' |
| <testLibraryFragment> new@null |
| 55 6:8 |test| REFERENCE |
| 86 7:26 |test| READ |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> f@68 |
| 46 5:6 |foo| REFERENCE |
| 58 5:18 |foo| REFERENCE qualified |
| 76 7:3 |foo| INVOCATION |
| 87 8:5 |foo| INVOCATION qualified |
| 96 9:3 |foo| REFERENCE |
| 105 10:5 |foo| REFERENCE qualified |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> f@43 |
| 56 4:8 |loadLibrary| INVOCATION qualified |
| '''); |
| } |
| |
| test_searchReferences_TopLevelVariableElement() 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 element = result.findElement |
| .importFind('package:test/lib.dart', mustBeUnique: false) |
| .topVar('V'); |
| await assertElementReferencesText(element, r''' |
| #F0 |
| 23 1:24 |V| REFERENCE qualified |
| <testLibraryFragment> main@53 |
| 69 4:8 |V| WRITE qualified |
| 83 5:8 |V| READ qualified |
| 93 6:8 |V| READ qualified |
| 100 7:3 |V| WRITE |
| 109 8:3 |V| READ |
| 114 9:3 |V| READ |
| '''); |
| } |
| |
| test_searchReferences_TopLevelVariableElement_reference() async { |
| var result = await resolveTestCode(''' |
| import 'test.dart' as p; |
| |
| var foo = 0; |
| |
| /// [foo] and [p.foo]. |
| @foo |
| @p.foo |
| void f() { |
| foo; |
| foo = 0; |
| p.foo; |
| p.foo = 0; |
| } |
| '''); |
| var element = result.findElement.topVar('foo'); |
| var getter = element.getter!; |
| var setter = element.setter!; |
| |
| await assertElementReferencesText(getter, r''' |
| <testLibraryFragment> f@80 |
| 45 5:6 |foo| REFERENCE |
| 57 5:18 |foo| REFERENCE qualified |
| 64 6:2 |foo| REFERENCE |
| 71 7:4 |foo| REFERENCE qualified |
| 88 9:3 |foo| REFERENCE |
| 108 11:5 |foo| REFERENCE qualified |
| '''); |
| |
| await assertElementReferencesText(setter, r''' |
| <testLibraryFragment> f@80 |
| 95 10:3 |foo| REFERENCE |
| 117 12:5 |foo| REFERENCE qualified |
| '''); |
| } |
| |
| test_searchReferences_TopLevelVariableElement_reference_combinator_show_hasGetterSetter() async { |
| var result = await resolveTestCode(''' |
| import 'test.dart' show foo; |
| |
| int get foo => 0; |
| void set foo(_) {} |
| '''); |
| var element = result.findElement.topVar('foo'); |
| await assertElementReferencesText(element, r''' |
| '''); |
| } |
| |
| test_searchReferences_TopLevelVariableElement_reference_combinator_show_hasSetter() async { |
| var result = await resolveTestCode(''' |
| import 'test.dart' show foo; |
| |
| void set foo(_) {} |
| '''); |
| var element = result.findElement.topVar('foo'); |
| await assertElementReferencesText(element, r''' |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> f@41 |
| 49 6:3 |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''' |
| <testLibraryFragment> f@31 |
| 23 2:6 |A| REFERENCE |
| <testLibraryFragment> p@35 |
| 33 3:8 |A| 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''' |
| <testLibraryFragment> f@100 |
| 92 8:6 |B| REFERENCE |
| 111 10:3 |B| REFERENCE |
| 118 11:3 |B| REFERENCE |
| 125 12:3 |B| REFERENCE |
| 136 13:3 |B| REFERENCE |
| 151 14:3 |B| REFERENCE |
| <testLibraryFragment> p@104 |
| 102 9:8 |B| 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''' |
| <testLibraryFragment> f@85 |
| 66 6:6 |B| REFERENCE |
| 76 6:16 |B| REFERENCE qualified |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> a@21 |
| 19 2:7 |T| REFERENCE |
| <testLibraryFragment> b@35 |
| 33 3:7 |T| 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''' |
| <testLibraryFragment> a@27 |
| 25 3:9 |T| REFERENCE |
| <testLibraryFragment> b@43 |
| 41 4:12 |T| 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''' |
| <testLibraryFragment> main@0 |
| 23 2:15 |T| REFERENCE |
| 43 3:14 |T| 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''' |
| <testLibraryFragment> p@21 |
| 19 2:10 |T| 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''' |
| <testLibraryFragment> a@9 |
| 7 1:8 |T| REFERENCE |
| <testLibraryFragment> foo@0 |
| 20 2:7 |T| 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''' |
| <testLibraryFragment> f@5 |
| 29 3:3 |v| WRITE |
| 38 4:3 |v| READ_WRITE |
| 48 5:3 |v| READ |
| 53 6:3 |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''' |
| <testLibraryFragment> f@10 |
| 85 3:5 |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''' |
| <testLibraryFragment> f@5 |
| 46 3:5 |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''' |
| <testLibraryFragment> f@5 |
| 57 3:5 |v| READ |
| 64 4:5 |v| 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''' |
| <testLibraryFragment> f@5 |
| 23 3:4 |v| WRITE |
| 41 4:3 |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''' |
| <testLibraryFragment> f@7 |
| 49 2:14 |v| READ |
| 58 2:23 |v| READ |
| 67 2:32 |v| WRITE |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> f@4 |
| 34 2:14 |v| READ |
| 43 2:23 |v| READ |
| 52 2:32 |v| WRITE |
| '''); |
| } |
| |
| 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''' |
| <testLibraryFragment> f@5 |
| 55 3:21 |v| READ |
| 84 4:23 |v| READ |
| 97 5:7 |v| READ |
| 106 6:7 |v| 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''' |
| <testLibraryFragment> f@5 |
| 55 3:21 |v| READ |
| 100 4:39 |v| READ |
| 113 5:7 |v| READ |
| 122 6:7 |v| 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''' |
| <testLibraryFragment> A@17 |
| 27 2:17 |T| REFERENCE |
| <testLibraryFragment> B@38 |
| 54 3:23 |T| REFERENCE |
| <testLibraryFragment> C@63 |
| 76 4:20 |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''' |
| <testLibraryFragment> A@17 |
| 22 2:12 |T| REFERENCE |
| <testLibraryFragment> B@33 |
| 46 3:20 |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]), |
| ); |
| } |
| |
| 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) { |
| var analysisSession = driver.currentSession; |
| |
| var groups = results |
| .groupListsBy((result) => result.enclosingFragment) |
| .entries |
| .where((entry) { |
| if (includedLibraryUris case var included?) { |
| var uri = entry.key.libraryFragment?.source.uri; |
| return uri != null && included.contains(uri); |
| } |
| return true; |
| }) |
| .map((entry) { |
| var enclosingFragment = entry.key; |
| return _GroupToPrint( |
| enclosingFragment: enclosingFragment, |
| results: entry.value.sortedBy<num>((e) => e.offset), |
| ); |
| }) |
| .sorted((first, second) { |
| var firstPath = first.path; |
| var secondPath = second.path; |
| var byPath = firstPath.compareTo(secondPath); |
| if (byPath != 0) { |
| return byPath; |
| } |
| return first.results.first.offset - second.results.first.offset; |
| }); |
| |
| var buffer = StringBuffer(); |
| var sink = TreeStringSink(sink: buffer, indent: ''); |
| var elementPrinter = ElementPrinter( |
| sink: sink, |
| configuration: ElementPrinterConfiguration(), |
| ); |
| |
| for (var group in groups) { |
| var unitPath = group.path; |
| var unitResult = analysisSession.getParsedUnit(unitPath); |
| unitResult as ParsedUnitResult; |
| elementPrinter.writelnFragmentReference(group.enclosingFragment); |
| for (var result in group.results) { |
| var offset = result.offset; |
| var length = result.length; |
| var end = offset + length; |
| var location = unitResult.lineInfo.getLocation(offset); |
| var snippet = unitResult.content.substring(offset, end); |
| |
| buffer.write(' '); |
| buffer.write(result.offset); |
| buffer.write(' '); |
| buffer.write(location.lineNumber); |
| buffer.write(':'); |
| buffer.write(location.columnNumber); |
| buffer.write(' |$snippet|'); |
| buffer.write(' '); |
| buffer.write(result.kind.name); |
| if (result.isQualified) { |
| buffer.write(' qualified'); |
| } |
| if (!result.isResolved) { |
| buffer.write(' unresolved'); |
| } |
| buffer.writeln(); |
| } |
| } |
| return buffer.toString(); |
| } |
| |
| String _getSearchResultsText2(List<LibraryFragmentSearchMatch> results) { |
| var analysisSession = driver.currentSession; |
| |
| var groups = results |
| .groupListsBy((result) => result.libraryFragment) |
| .entries |
| .map((entry) { |
| var enclosingFragment = entry.key; |
| return _GroupToPrint2( |
| enclosingFragment: enclosingFragment, |
| results: entry.value.sortedBy<num>((e) => e.range.offset), |
| ); |
| }) |
| .sorted((first, second) { |
| var firstPath = first.path; |
| var secondPath = second.path; |
| var byPath = firstPath.compareTo(secondPath); |
| if (byPath != 0) { |
| return byPath; |
| } |
| var firstOffset = first.results.first.range.offset; |
| var secondOffset = second.results.first.range.offset; |
| return firstOffset - secondOffset; |
| }); |
| |
| var buffer = StringBuffer(); |
| var sink = TreeStringSink(sink: buffer, indent: ''); |
| var elementPrinter = ElementPrinter( |
| sink: sink, |
| configuration: ElementPrinterConfiguration(), |
| ); |
| |
| for (var group in groups) { |
| var unitPath = group.path; |
| var unitResult = analysisSession.getParsedUnit(unitPath); |
| unitResult as ParsedUnitResult; |
| elementPrinter.writelnFragmentReference(group.enclosingFragment); |
| for (var result in group.results) { |
| var offset = result.range.offset; |
| var length = result.range.length; |
| var end = offset + length; |
| var location = unitResult.lineInfo.getLocation(offset); |
| var snippet = unitResult.content.substring(offset, end); |
| |
| buffer.write(' '); |
| buffer.write(result.range.offset); |
| buffer.write(' '); |
| buffer.write(location.lineNumber); |
| buffer.write(':'); |
| buffer.write(location.columnNumber); |
| buffer.write(' |$snippet|'); |
| buffer.writeln(); |
| } |
| } |
| return buffer.toString(); |
| } |
| |
| /// 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); |
| } |
| } |
| |
| class _GroupToPrint { |
| final Fragment enclosingFragment; |
| final List<SearchResult> results; |
| |
| _GroupToPrint({required this.enclosingFragment, required this.results}); |
| |
| String get path { |
| return enclosingFragment.libraryFragment!.source.fullName; |
| } |
| } |
| |
| class _GroupToPrint2 { |
| final Fragment enclosingFragment; |
| final List<LibraryFragmentSearchMatch> results; |
| |
| _GroupToPrint2({required this.enclosingFragment, required this.results}); |
| |
| String get path { |
| return enclosingFragment.libraryFragment!.source.fullName; |
| } |
| } |