Fix search for private elements inside of discovered packages.
R=brianwilkerson@google.com
Change-Id: Ie2e4055369624d89c090a55787477a235754db5e
Reviewed-on: https://dart-review.googlesource.com/58940
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index 1212bdc..0817ced 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -305,23 +305,24 @@
return _searchReferences_Field(element, searchedFiles);
} else if (kind == ElementKind.FUNCTION || kind == ElementKind.METHOD) {
if (element.enclosingElement is ExecutableElement) {
- return _searchReferences_Local(element, (n) => n is Block);
+ return _searchReferences_Local(
+ element, (n) => n is Block, searchedFiles);
}
return _searchReferences_Function(element, searchedFiles);
} else if (kind == ElementKind.IMPORT) {
- return _searchReferences_Import(element);
+ return _searchReferences_Import(element, searchedFiles);
} else if (kind == ElementKind.LABEL ||
kind == ElementKind.LOCAL_VARIABLE) {
- return _searchReferences_Local(element, (n) => n is Block);
+ return _searchReferences_Local(element, (n) => n is Block, searchedFiles);
} else if (kind == ElementKind.LIBRARY) {
- return _searchReferences_Library(element);
+ return _searchReferences_Library(element, searchedFiles);
} else if (kind == ElementKind.PARAMETER) {
return _searchReferences_Parameter(element, searchedFiles);
} else if (kind == ElementKind.PREFIX) {
- return _searchReferences_Prefix(element);
+ return _searchReferences_Prefix(element, searchedFiles);
} else if (kind == ElementKind.TYPE_PARAMETER) {
return _searchReferences_Local(
- element, (n) => n.parent is CompilationUnit);
+ element, (n) => n.parent is CompilationUnit, searchedFiles);
}
return const <SearchResult>[];
}
@@ -470,7 +471,7 @@
String path = element.source.fullName;
if (name.startsWith('_')) {
String libraryPath = element.library.source.fullName;
- if (_driver.addedFiles.contains(libraryPath)) {
+ if (searchedFiles.add(libraryPath, this)) {
FileState library = _driver.fsState.getFileForPath(libraryPath);
List<FileState> candidates = [library]..addAll(library.partedFiles);
for (FileState file in candidates) {
@@ -603,10 +604,9 @@
}
Future<List<SearchResult>> _searchReferences_Import(
- ImportElement element) async {
- // Search only in drivers to which the library was added.
+ ImportElement element, SearchedFiles searchedFiles) async {
String path = element.source.fullName;
- if (!_driver.addedFiles.contains(path)) {
+ if (!searchedFiles.add(path, this)) {
return const <SearchResult>[];
}
@@ -624,10 +624,9 @@
}
Future<List<SearchResult>> _searchReferences_Library(
- LibraryElement element) async {
- // Search only in drivers to which the library with the prefix was added.
+ LibraryElement element, SearchedFiles searchedFiles) async {
String path = element.source.fullName;
- if (!_driver.addedFiles.contains(path)) {
+ if (!searchedFiles.add(path, this)) {
return const <SearchResult>[];
}
@@ -651,10 +650,10 @@
return results;
}
- Future<List<SearchResult>> _searchReferences_Local(
- Element element, bool isRootNode(AstNode n)) async {
+ Future<List<SearchResult>> _searchReferences_Local(Element element,
+ bool isRootNode(AstNode n), SearchedFiles searchedFiles) async {
String path = element.source.fullName;
- if (!_driver.addedFiles.contains(path)) {
+ if (!searchedFiles.add(path, this)) {
return const <SearchResult>[];
}
@@ -687,10 +686,14 @@
Future<List<SearchResult>> _searchReferences_Parameter(
ParameterElement parameter, SearchedFiles searchedFiles) async {
List<SearchResult> results = <SearchResult>[];
- results.addAll(await _searchReferences_Local(parameter, (AstNode node) {
- AstNode parent = node.parent;
- return parent is ClassDeclaration || parent is CompilationUnit;
- }));
+ results.addAll(await _searchReferences_Local(
+ parameter,
+ (AstNode node) {
+ AstNode parent = node.parent;
+ return parent is ClassDeclaration || parent is CompilationUnit;
+ },
+ searchedFiles,
+ ));
if (parameter.isOptional) {
results.addAll(await _searchReferences(parameter, searchedFiles));
}
@@ -698,10 +701,9 @@
}
Future<List<SearchResult>> _searchReferences_Prefix(
- PrefixElement element) async {
- // Search only in drivers to which the library with the prefix was added.
+ PrefixElement element, SearchedFiles searchedFiles) async {
String path = element.source.fullName;
- if (!_driver.addedFiles.contains(path)) {
+ if (!searchedFiles.add(path, this)) {
return const <SearchResult>[];
}
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index ac55908..82570b6 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -856,6 +856,31 @@
await _verifyReferences(element, expected);
}
+ test_searchReferences_ImportElement_noPrefix_inPackage() async {
+ testFile = _p('/aaa/lib/a.dart');
+ await _resolveTestUnit('''
+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;
+''', addToDriver: false);
+ ImportElement element = testLibraryElement.imports[0];
+ Element mainElement = await _findElement('main');
+ Element barElement = await _findElement('bar');
+ var kind = SearchResultKind.REFERENCE;
+ var expected = [
+ _expectId(mainElement, kind, 'PI;', length: 0),
+ _expectId(mainElement, kind, 'Random();', length: 0),
+ _expectId(mainElement, kind, 'max(1, 2);', length: 0),
+ _expectId(barElement, kind, 'Random bar()', length: 0),
+ ];
+ await _verifyReferences(element, expected);
+ }
+
test_searchReferences_ImportElement_withPrefix() async {
await _resolveTestUnit('''
import 'dart:math' as math show max, PI, Random hide min;
@@ -952,6 +977,32 @@
await _verifyReferences(element, expected);
}
+ test_searchReferences_LibraryElement_inPackage() async {
+ testFile = _p('/aaa/lib/a.dart');
+ var partPathA = _p('/aaa/lib/unitA.dart');
+ var partPathB = _p('/aaa/lib/unitB.dart');
+
+ var codeA = 'part of lib; // A';
+ var codeB = 'part of lib; // B';
+ provider.newFile(partPathA, codeA);
+ provider.newFile(partPathB, codeB);
+ await _resolveTestUnit('''
+library lib;
+part 'unitA.dart';
+part 'unitB.dart';
+''', addToDriver: false);
+ LibraryElement element = testLibraryElement;
+ CompilationUnitElement unitElementA = element.parts[0];
+ CompilationUnitElement unitElementB = element.parts[1];
+ var expected = [
+ new ExpectedResult(unitElementA, SearchResultKind.REFERENCE,
+ codeA.indexOf('lib; // A'), 'lib'.length),
+ new ExpectedResult(unitElementB, SearchResultKind.REFERENCE,
+ codeB.indexOf('lib; // B'), 'lib'.length),
+ ];
+ await _verifyReferences(element, expected);
+ }
+
test_searchReferences_LocalVariableElement() async {
await _resolveTestUnit(r'''
main() {
@@ -973,7 +1024,7 @@
await _verifyReferences(element, expected);
}
- test_searchReferences_localVariableElement_inForEachLoop() async {
+ test_searchReferences_LocalVariableElement_inForEachLoop() async {
await _resolveTestUnit('''
main() {
for (var v in []) {
@@ -995,6 +1046,30 @@
await _verifyReferences(element, expected);
}
+ test_searchReferences_LocalVariableElement_inPackage() async {
+ testFile = _p('/aaa/lib/a.dart');
+
+ await _resolveTestUnit('''
+main() {
+ var v;
+ v = 1;
+ v += 2;
+ print(v);
+ v();
+}
+''', addToDriver: false);
+ Element element = findElementsByName(testUnit, 'v').single;
+ Element main = _findElement('main');
+
+ var expected = [
+ _expectId(main, SearchResultKind.WRITE, 'v = 1;'),
+ _expectId(main, SearchResultKind.READ_WRITE, 'v += 2;'),
+ _expectId(main, SearchResultKind.READ, 'v);'),
+ _expectId(main, SearchResultKind.INVOCATION, 'v();')
+ ];
+ await _verifyReferences(element, expected);
+ }
+
test_searchReferences_MethodElement() async {
await _resolveTestUnit('''
class A {
@@ -1212,6 +1287,36 @@
await _verifyReferences(element, expected);
}
+ test_searchReferences_PrefixElement_inPackage() async {
+ testFile = _p('/aaa/lib/a.dart');
+ var partPath = _p('/aaa/lib/my_part.dart');
+
+ String partCode = r'''
+part of my_lib;
+ppp.Future c;
+''';
+ provider.newFile(partPath, partCode);
+ await _resolveTestUnit('''
+library my_lib;
+import 'dart:async' as ppp;
+part 'my_part.dart';
+main() {
+ ppp.Future a;
+ ppp.Stream b;
+}
+''', addToDriver: false);
+ PrefixElement element = _findElementAtString('ppp;');
+ Element main = _findElement('main');
+ Element c = findChildElement(testLibraryElement, 'c');
+ var expected = [
+ _expectId(main, SearchResultKind.REFERENCE, 'ppp.Future'),
+ _expectId(main, SearchResultKind.REFERENCE, 'ppp.Stream'),
+ new ExpectedResult(c, SearchResultKind.REFERENCE,
+ partCode.indexOf('ppp.Future c'), 'ppp'.length)
+ ];
+ await _verifyReferences(element, expected);
+ }
+
test_searchReferences_private_declaredInDefiningUnit() async {
String p1 = _p('$testProject/part1.dart');
String p2 = _p('$testProject/part2.dart');
@@ -1294,6 +1399,40 @@
await _verifyReferences(element, expected);
}
+ test_searchReferences_private_inPackage() async {
+ testFile = _p('/aaa/lib/a.dart');
+ var p1 = _p('/aaa/lib/part1.dart');
+ var p2 = _p('/aaa/lib/part2.dart');
+
+ String code1 = 'part of lib; _C v1;';
+ String code2 = 'part of lib; _C v2;';
+
+ provider.newFile(p1, code1);
+ provider.newFile(p2, code2);
+
+ await _resolveTestUnit('''
+library lib;
+part 'part1.dart';
+part 'part2.dart';
+class _C {}
+_C v;
+''', addToDriver: false);
+
+ Element element = testUnitElement.types.single;
+ Element v = testUnitElement.topLevelVariables[0];
+ Element v1 = testLibraryElement.parts[0].topLevelVariables[0];
+ Element v2 = testLibraryElement.parts[1].topLevelVariables[0];
+ var expected = [
+ new ExpectedResult(
+ v, SearchResultKind.REFERENCE, testCode.indexOf('_C v;'), 2),
+ new ExpectedResult(
+ v1, SearchResultKind.REFERENCE, code1.indexOf('_C v1;'), 2),
+ new ExpectedResult(
+ v2, SearchResultKind.REFERENCE, code2.indexOf('_C v2;'), 2),
+ ];
+ await _verifyReferences(element, expected);
+ }
+
test_searchReferences_PropertyAccessorElement_getter() async {
await _resolveTestUnit('''
class A {
@@ -1672,8 +1811,13 @@
String _p(String path) => provider.convertPath(path);
- Future<Null> _resolveTestUnit(String code) async {
- addTestFile(code);
+ Future<Null> _resolveTestUnit(String code, {bool addToDriver: true}) async {
+ if (addToDriver) {
+ addTestFile(code);
+ } else {
+ testCode = code;
+ provider.newFile(testFile, testCode);
+ }
if (testUnit == null) {
AnalysisResult result = await driver.getResult(testFile);
testUnit = result.unit;