mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:39:49 +00:00
Search for ImportElement(s).
R=brianwilkerson@google.com BUG= Review URL: https://codereview.chromium.org/2542583003 .
This commit is contained in:
parent
4686d364bb
commit
fa0b825269
|
@ -13,6 +13,7 @@ import 'package:analyzer/src/dart/analysis/index.dart';
|
|||
import 'package:analyzer/src/dart/ast/utilities.dart';
|
||||
import 'package:analyzer/src/dart/element/element.dart';
|
||||
import 'package:analyzer/src/dart/element/member.dart';
|
||||
import 'package:analyzer/src/dart/resolver/scope.dart' show NamespaceBuilder;
|
||||
import 'package:analyzer/src/summary/idl.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
|
@ -55,6 +56,8 @@ class Search {
|
|||
return _searchReferences_Local(element, (n) => n is Block);
|
||||
}
|
||||
return _searchReferences_Function(element);
|
||||
} else if (kind == ElementKind.IMPORT) {
|
||||
return _searchReferences_Import(element);
|
||||
} else if (kind == ElementKind.LABEL ||
|
||||
kind == ElementKind.LOCAL_VARIABLE) {
|
||||
return _searchReferences_Local(element, (n) => n is Block);
|
||||
|
@ -155,6 +158,27 @@ class Search {
|
|||
return results;
|
||||
}
|
||||
|
||||
Future<List<SearchResult>> _searchReferences_Import(
|
||||
ImportElement element) async {
|
||||
// Search only in drivers to which the library was added.
|
||||
String path = element.source.fullName;
|
||||
if (!_driver.addedFiles.contains(path)) {
|
||||
return const <SearchResult>[];
|
||||
}
|
||||
|
||||
List<SearchResult> results = <SearchResult>[];
|
||||
LibraryElement libraryElement = element.library;
|
||||
for (CompilationUnitElement unitElement in libraryElement.units) {
|
||||
String unitPath = unitElement.source.fullName;
|
||||
AnalysisResult unitAnalysisResult = await _driver.getResult(unitPath);
|
||||
_ImportElementReferencesVisitor visitor =
|
||||
new _ImportElementReferencesVisitor(element, unitElement);
|
||||
unitAnalysisResult.unit.accept(visitor);
|
||||
results.addAll(visitor.results);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
Future<List<SearchResult>> _searchReferences_Local(
|
||||
Element element, bool isRootNode(AstNode n)) async {
|
||||
String path = element.source.fullName;
|
||||
|
@ -309,6 +333,72 @@ class _ContainingElementFinder extends GeneralizingElementVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor that adds [SearchResult]s for references to the [importElement].
|
||||
*/
|
||||
class _ImportElementReferencesVisitor extends RecursiveAstVisitor {
|
||||
final List<SearchResult> results = <SearchResult>[];
|
||||
|
||||
final ImportElement importElement;
|
||||
final CompilationUnitElement enclosingUnitElement;
|
||||
|
||||
Set<Element> importedElements;
|
||||
|
||||
_ImportElementReferencesVisitor(
|
||||
ImportElement element, this.enclosingUnitElement)
|
||||
: importElement = element {
|
||||
importedElements = new NamespaceBuilder()
|
||||
.createImportNamespaceForDirective(element)
|
||||
.definedNames
|
||||
.values
|
||||
.toSet();
|
||||
}
|
||||
|
||||
@override
|
||||
visitExportDirective(ExportDirective node) {}
|
||||
|
||||
@override
|
||||
visitImportDirective(ImportDirective node) {}
|
||||
|
||||
@override
|
||||
visitSimpleIdentifier(SimpleIdentifier node) {
|
||||
if (node.inDeclarationContext()) {
|
||||
return;
|
||||
}
|
||||
if (importElement.prefix != null) {
|
||||
if (node.staticElement == importElement.prefix) {
|
||||
AstNode parent = node.parent;
|
||||
if (parent is PrefixedIdentifier && parent.prefix == node) {
|
||||
if (importedElements.contains(parent.staticElement)) {
|
||||
_addResultForPrefix(node, parent.identifier);
|
||||
}
|
||||
}
|
||||
if (parent is MethodInvocation && parent.target == node) {
|
||||
if (importedElements.contains(parent.methodName.staticElement)) {
|
||||
_addResultForPrefix(node, parent.methodName);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (importedElements.contains(node.staticElement)) {
|
||||
_addResult(node.offset, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _addResult(int offset, int length) {
|
||||
Element enclosingElement =
|
||||
_getEnclosingElement(enclosingUnitElement, offset);
|
||||
results.add(new SearchResult._(importElement, enclosingElement,
|
||||
SearchResultKind.REFERENCE, offset, length, true, false));
|
||||
}
|
||||
|
||||
void _addResultForPrefix(SimpleIdentifier prefixNode, AstNode nextNode) {
|
||||
int prefixOffset = prefixNode.offset;
|
||||
_addResult(prefixOffset, nextNode.offset - prefixOffset);
|
||||
}
|
||||
}
|
||||
|
||||
class _IndexRequest {
|
||||
final AnalysisDriverUnitIndex index;
|
||||
|
||||
|
|
|
@ -300,6 +300,83 @@ main() {
|
|||
await _verifyReferences(element, expected);
|
||||
}
|
||||
|
||||
test_searchReferences_ImportElement_noPrefix() async {
|
||||
await _resolveTestUnit('''
|
||||
import 'dart:math' show max, PI, Random hide min;
|
||||
export 'dart:math' show max, PI, Random hide min;
|
||||
main() {
|
||||
print(PI);
|
||||
print(new Random());
|
||||
print(max(1, 2));
|
||||
}
|
||||
Random bar() => null;
|
||||
''');
|
||||
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(', 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;
|
||||
export 'dart:math' show max, PI, Random hide min;
|
||||
main() {
|
||||
print(math.PI);
|
||||
print(new math.Random());
|
||||
print(math.max(1, 2));
|
||||
}
|
||||
math.Random bar() => null;
|
||||
''');
|
||||
ImportElement element = testLibraryElement.imports[0];
|
||||
Element mainElement = await _findElement('main');
|
||||
Element barElement = await _findElement('bar');
|
||||
var kind = SearchResultKind.REFERENCE;
|
||||
var length = 'math.'.length;
|
||||
var expected = [
|
||||
_expectId(mainElement, kind, 'math.PI);', length: length),
|
||||
_expectId(mainElement, kind, 'math.Random()', length: length),
|
||||
_expectId(mainElement, kind, 'math.max(', length: length),
|
||||
_expectId(barElement, kind, 'math.Random bar()', length: length),
|
||||
];
|
||||
await _verifyReferences(element, expected);
|
||||
}
|
||||
|
||||
test_searchReferences_ImportElement_withPrefix_forMultipleImports() async {
|
||||
await _resolveTestUnit('''
|
||||
import 'dart:async' as p;
|
||||
import 'dart:math' as p;
|
||||
main() {
|
||||
p.Random;
|
||||
p.Future;
|
||||
}
|
||||
''');
|
||||
Element mainElement = await _findElement('main');
|
||||
var kind = SearchResultKind.REFERENCE;
|
||||
var length = 'p.'.length;
|
||||
{
|
||||
ImportElement element = testLibraryElement.imports[0];
|
||||
var expected = [
|
||||
_expectId(mainElement, kind, 'p.Future;', length: length),
|
||||
];
|
||||
await _verifyReferences(element, expected);
|
||||
}
|
||||
{
|
||||
ImportElement element = testLibraryElement.imports[1];
|
||||
var expected = [
|
||||
_expectId(mainElement, kind, 'p.Random', length: length),
|
||||
];
|
||||
await _verifyReferences(element, expected);
|
||||
}
|
||||
}
|
||||
|
||||
test_searchReferences_LabelElement() async {
|
||||
await _resolveTestUnit('''
|
||||
main() {
|
||||
|
|
Loading…
Reference in a new issue