Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1332)

Unified Diff: pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart

Issue 1760243004: Implement search for local elements. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analysis_server/test/services/search/search_engine2_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart
diff --git a/pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart b/pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart
index caf93f095e6359bcc890883da14e2569ee4bdd5d..14eb51e4c4b05a2b7274be05249e1a724886d82c 100644
--- a/pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart
+++ b/pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart
@@ -8,10 +8,12 @@ import 'dart:async';
import 'package:analysis_server/src/services/index2/index2.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
-import 'package:analyzer/src/generated/source.dart' show SourceRange;
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/idl.dart';
/**
@@ -61,21 +63,26 @@ class SearchEngineImpl2 implements SearchEngine {
kind == ElementKind.TOP_LEVEL_VARIABLE) {
return _searchReferences_Field(element as PropertyInducingElement);
} else if (kind == ElementKind.FUNCTION || kind == ElementKind.METHOD) {
+ if (element.enclosingElement is ExecutableElement) {
+ return _searchReferences_Local(element, (n) => n is Block);
+ }
return _searchReferences_Function(element);
} else if (kind == ElementKind.IMPORT) {
+ // TODO(scheglov) implement whole library search
return _searchReferences(element);
- } else if (kind == ElementKind.LABEL) {
- return _searchReferences(element);
+ } else if (kind == ElementKind.LABEL ||
+ kind == ElementKind.LOCAL_VARIABLE) {
+ return _searchReferences_Local(element, (n) => n is Block);
} else if (kind == ElementKind.LIBRARY) {
+ // TODO(scheglov) implement whole library search
return _searchReferences(element);
- } else if (kind == ElementKind.LOCAL_VARIABLE) {
- return _searchReferences_LocalVariable(element as LocalVariableElement);
} else if (kind == ElementKind.PARAMETER) {
- return _searchReferences_Parameter(element as ParameterElement);
+ return _searchReferences_Parameter(element);
} else if (kind == ElementKind.PREFIX) {
+ // TODO(scheglov) implement whole library search
return _searchReferences(element);
} else if (kind == ElementKind.TYPE_PARAMETER) {
- return _searchReferences_TypeParameter(element);
+ return _searchReferences_Local(element, (n) => n is ClassDeclaration);
}
return new Future.value(<SearchMatch>[]);
}
@@ -92,128 +99,134 @@ class SearchEngineImpl2 implements SearchEngine {
throw new UnimplementedError();
}
- Future<List<SearchMatch>> _searchReferences(Element element) {
- _Requestor requestor = new _Requestor(context, _index);
- requestor.addElement(
- element, IndexRelationKind.IS_REFERENCED_BY, MatchKind.REFERENCE);
- return requestor.merge();
+ _addMatches(List<SearchMatch> matches, Element element,
+ IndexRelationKind relationKind, MatchKind kind) async {
+ List<Location> locations = await _index.getRelations(element, relationKind);
+ for (Location location in locations) {
+ matches.add(new SearchMatch(
+ context,
+ location.libraryUri,
+ location.unitUri,
+ kind,
+ new SourceRange(location.offset, location.length),
+ true,
+ location.isQualified));
+ }
+ }
+
+ Future<List<SearchMatch>> _searchReferences(Element element) async {
+ List<SearchMatch> matches = <SearchMatch>[];
+ await _addMatches(matches, element, IndexRelationKind.IS_REFERENCED_BY,
+ MatchKind.REFERENCE);
+ return matches;
}
Future<List<SearchMatch>> _searchReferences_Field(
- PropertyInducingElement field) {
+ PropertyInducingElement field) async {
+ List<SearchMatch> matches = <SearchMatch>[];
PropertyAccessorElement getter = field.getter;
PropertyAccessorElement setter = field.setter;
- _Requestor requestor = new _Requestor(context, _index);
// field itself
- requestor.addElement(
- field, IndexRelationKind.IS_REFERENCED_BY, MatchKind.REFERENCE);
+ await _addMatches(matches, field, IndexRelationKind.IS_REFERENCED_BY,
+ MatchKind.REFERENCE);
// getter
if (getter != null) {
- requestor.addElement(
- getter, IndexRelationKind.IS_REFERENCED_BY, MatchKind.READ);
- requestor.addElement(
- getter, IndexRelationKind.IS_INVOKED_BY, MatchKind.INVOCATION);
+ await _addMatches(
+ matches, getter, IndexRelationKind.IS_REFERENCED_BY, MatchKind.READ);
+ await _addMatches(matches, getter, IndexRelationKind.IS_INVOKED_BY,
+ MatchKind.INVOCATION);
}
// setter
if (setter != null) {
- requestor.addElement(
- setter, IndexRelationKind.IS_REFERENCED_BY, MatchKind.WRITE);
+ await _addMatches(
+ matches, setter, IndexRelationKind.IS_REFERENCED_BY, MatchKind.WRITE);
}
// done
- return requestor.merge();
+ return matches;
}
- Future<List<SearchMatch>> _searchReferences_Function(Element element) {
+ Future<List<SearchMatch>> _searchReferences_Function(Element element) async {
if (element is Member) {
element = (element as Member).baseElement;
}
- _Requestor requestor = new _Requestor(context, _index);
- requestor.addElement(
- element, IndexRelationKind.IS_REFERENCED_BY, MatchKind.REFERENCE);
- requestor.addElement(
- element, IndexRelationKind.IS_INVOKED_BY, MatchKind.INVOCATION);
- return requestor.merge();
+ List<SearchMatch> matches = <SearchMatch>[];
+ await _addMatches(matches, element, IndexRelationKind.IS_REFERENCED_BY,
+ MatchKind.REFERENCE);
+ await _addMatches(matches, element, IndexRelationKind.IS_INVOKED_BY,
+ MatchKind.INVOCATION);
+ return matches;
}
- Future<List<SearchMatch>> _searchReferences_LocalVariable(
- LocalVariableElement variable) {
- // TODO(scheglov) implement using AST visitor
- throw new UnimplementedError();
-// _Requestor requestor = new _Requestor(context, _index);
-// requestor.addElement(variable, IndexRelationKind.IS_READ_BY, MatchKind.READ);
-// requestor.addElement(
-// variable, IndexRelationKind.IS_READ_WRITTEN_BY, MatchKind.READ_WRITE);
-// requestor.addElement(
-// variable, IndexRelationKind.IS_WRITTEN_BY, MatchKind.WRITE);
-// requestor.addElement(
-// variable, IndexRelationKind.IS_INVOKED_BY, MatchKind.INVOCATION);
-// return requestor.merge();
+ Future<List<SearchMatch>> _searchReferences_Local(
+ Element element, bool isRootNode(AstNode n)) async {
+ AstNode node = element.computeNode();
+ AstNode enclosingNode = node.getAncestor(isRootNode);
+ _LocalReferencesVisitor visitor = new _LocalReferencesVisitor(element);
+ enclosingNode.accept(visitor);
+ return visitor.matches;
}
Future<List<SearchMatch>> _searchReferences_Parameter(
- ParameterElement parameter) {
- // TODO(scheglov) implement using AST visitor
- throw new UnimplementedError();
-// _Requestor requestor = new _Requestor(context, _index);
-// requestor.addElement(parameter, IndexRelationKind.IS_READ_BY, MatchKind.READ);
-// requestor.addElement(
-// parameter, IndexRelationKind.IS_READ_WRITTEN_BY, MatchKind.READ_WRITE);
-// requestor.addElement(
-// parameter, IndexRelationKind.IS_WRITTEN_BY, MatchKind.WRITE);
-// requestor.addElement(
-// parameter, IndexRelationKind.IS_REFERENCED_BY, MatchKind.REFERENCE);
-// requestor.addElement(
-// parameter, IndexRelationKind.IS_INVOKED_BY, MatchKind.INVOCATION);
-// return requestor.merge();
- }
-
- Future<List<SearchMatch>> _searchReferences_TypeParameter(
- ParameterElement parameter) {
- // TODO(scheglov) implement using AST visitor
- throw new UnimplementedError();
+ ParameterElement parameter) async {
+ List<SearchMatch> matches = <SearchMatch>[];
+ matches.addAll(await _searchReferences(parameter));
+ matches.addAll(await _searchReferences_Local(
+ parameter, (n) => n is MethodDeclaration || n is FunctionExpression));
+ return matches;
}
}
-class _Requestor {
+/**
+ * Visitor that adds [SearchMatch]es for local elements - labels, local
+ * functions, local variables and parameters.
+ */
+class _LocalReferencesVisitor extends RecursiveAstVisitor {
+ final List<SearchMatch> matches = <SearchMatch>[];
+
+ final Element element;
final AnalysisContext context;
- final Index2 index;
- final List<Future<List<SearchMatch>>> futures = <Future<List<SearchMatch>>>[];
-
- _Requestor(this.context, this.index);
-
- void addElement(
- Element element, IndexRelationKind relationKind, MatchKind kind) {
- Future relationsFuture = index.getRelations(element, relationKind);
- Future matchesFuture = relationsFuture.then((List<Location> locations) {
- List<SearchMatch> matches = <SearchMatch>[];
- for (Location location in locations) {
- matches.add(_convertLocation(location, kind));
- }
- return matches;
- });
- futures.add(matchesFuture);
- }
+ final String libraryUri;
+ final String unitUri;
-// void addElement(
-// Element element, RelationshipImpl relationship, MatchKind kind) {
-// IndexableElement indexable = new IndexableElement(element);
-// add(indexable, relationship, kind);
-// }
+ _LocalReferencesVisitor(Element element)
+ : element = element,
+ context = element.context,
+ libraryUri = element.library.source.uri.toString(),
+ unitUri = element.source.uri.toString();
- Future<List<SearchMatch>> merge() {
- return Future.wait(futures).then((List<List<SearchMatch>> matchesList) {
- return matchesList.expand((matches) => matches).toList();
- });
+ @override
+ visitSimpleIdentifier(SimpleIdentifier node) {
+ if (node.inDeclarationContext()) {
+ return;
+ }
+ if (node.bestElement == element) {
+ AstNode parent = node.parent;
+ MatchKind kind = MatchKind.REFERENCE;
+ if (element is FunctionElement) {
+ if (parent is MethodInvocation && parent.methodName == node) {
+ kind = MatchKind.INVOCATION;
+ }
+ } else if (element is VariableElement) {
+ bool isGet = node.inGetterContext();
+ bool isSet = node.inSetterContext();
+ if (isGet && isSet) {
+ kind = MatchKind.READ_WRITE;
+ } else if (isGet) {
+ if (parent is MethodInvocation && parent.methodName == node) {
+ kind = MatchKind.INVOCATION;
+ } else {
+ kind = MatchKind.READ;
+ }
+ } else if (isSet) {
+ kind = MatchKind.WRITE;
+ }
+ }
+ _addMatch(node, kind);
+ }
}
- SearchMatch _convertLocation(Location location, MatchKind kind) {
- return new SearchMatch(
- context,
- location.libraryUri,
- location.unitUri,
- kind,
- new SourceRange(location.offset, location.length),
- true,
- location.isQualified);
+ void _addMatch(SimpleIdentifier node, MatchKind kind) {
+ matches.add(new SearchMatch(context, libraryUri, unitUri, kind,
+ new SourceRange(node.offset, node.length), true, node.isQualified));
}
}
« no previous file with comments | « no previous file | pkg/analysis_server/test/services/search/search_engine2_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698