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

Side by Side Diff: pkg/analysis_server/lib/src/search/element_references.dart

Issue 395623006: Add hierarchy utils and use them in search. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: tweaks Created 6 years, 5 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library search.element_references; 5 library search.element_references;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import 'package:analysis_server/src/collections.dart';
9 import 'package:analysis_server/src/search/search_result.dart'; 10 import 'package:analysis_server/src/search/search_result.dart';
11 import 'package:analysis_services/search/hierarchy.dart';
10 import 'package:analysis_services/search/search_engine.dart'; 12 import 'package:analysis_services/search/search_engine.dart';
11 import 'package:analyzer/src/generated/element.dart'; 13 import 'package:analyzer/src/generated/element.dart';
12 import 'package:analyzer/src/generated/source.dart'; 14 import 'package:analyzer/src/generated/source.dart';
13 15
14 16
15 /** 17 /**
16 * A computer for `search.findElementReferences` request results. 18 * A computer for `search.findElementReferences` request results.
17 */ 19 */
18 class ElementReferencesComputer { 20 class ElementReferencesComputer {
19 final SearchEngine searchEngine; 21 final SearchEngine searchEngine;
20 22
21 ElementReferencesComputer(this.searchEngine); 23 ElementReferencesComputer(this.searchEngine);
22 24
23 /** 25 /**
24 * Computes [SearchResult]s for [element] references. 26 * Computes [SearchResult]s for [element] references.
25 */ 27 */
26 Future<List<SearchResult>> compute(Element element, bool withPotential) { 28 Future<List<SearchResult>> compute(Element element, bool withPotential) {
27 var futures = <Future<List<SearchResult>>>[]; 29 var futureGroup = new _ConcatFutureGroup<SearchResult>();
28 // tweak element 30 // tweak element
29 if (element is FieldFormalParameterElement) { 31 if (element is FieldFormalParameterElement) {
30 element = (element as FieldFormalParameterElement).field; 32 element = (element as FieldFormalParameterElement).field;
31 } 33 }
32 if (element is PropertyAccessorElement) { 34 if (element is PropertyAccessorElement) {
33 element = (element as PropertyAccessorElement).variable; 35 element = (element as PropertyAccessorElement).variable;
34 } 36 }
35 // prepare Element(s) to find references to 37 // find element references
36 List<Element> refElements = <Element>[]; 38 futureGroup.add(_findElementsReferences(element));
37 if (element != null) { 39 // add potential references
38 // TODO(scheglov) find all hierarchy members 40 if (withPotential) {
39 // if (element is ClassMemberElement) { 41 String name = element.displayName;
40 // refElements = HierarchyUtils.getHierarchyMembers(searchEngine, element ); 42 var matchesFuture = searchEngine.searchMemberReferences(name);
41 // } else { 43 var resultsFuture = matchesFuture.then((List<SearchMatch> matches) {
42 // refElements = <Element>[element]; 44 return matches.where((match) => !match.isResolved).map(toResult);
43 // }
44 refElements = <Element>[element];
45 }
46 // process each 'refElement'
47 for (Element refElement in refElements) {
48 // add variable declaration
49 if (_isVariableLikeElement(refElement)) {
50 int nameOffset = refElement.nameOffset;
51 int nameLength = refElement.name.length;
52 SearchMatch searchMatch =
53 new SearchMatch(
54 MatchKind.DECLARATION,
55 refElement,
56 new SourceRange(nameOffset, nameLength),
57 true,
58 false);
59 SearchResult searchResult = new SearchResult.fromMatch(searchMatch);
60 futures.add(new Future.value(<SearchResult>[searchResult]));
61 }
62 // do search
63 Future<List<SearchMatch>> matchesFuture =
64 searchEngine.searchReferences(refElement);
65 Future<List<SearchResult>> resultsFuture =
66 matchesFuture.then((List<SearchMatch> matches) {
67 return matches.map(toResult).toList();
68 }); 45 });
69 futures.add(resultsFuture); 46 futureGroup.add(resultsFuture);
70 }
71 // report potential references
72 if (withPotential) {
73 var matchesFuture = searchEngine.searchMemberReferences(element.name);
74 var resultsFuture = matchesFuture.then((List<SearchMatch> matches) {
75 return matches.where(
76 (match) => !match.isResolved).map(toResult).toList();
77 });
78 futures.add(resultsFuture);
79 } 47 }
80 // merge results 48 // merge results
81 var futuresFuture = Future.wait(futures); 49 return futureGroup.future;
82 return futuresFuture.then((List<List<SearchResult>> lists) { 50 }
83 // TODO(scheglov) extract? 51
84 return lists.expand((List<SearchResult> matches) => matches).toList(); 52 /**
53 * Returns a [Future] completing with a [List] of references to [element] or
54 * to the corresponding hierarchy [Element]s.
55 */
56 Future<List<SearchResult>> _findElementsReferences(Element element) {
57 return _getRefElements(element).then((Iterable<Element> refElements) {
58 var futureGroup = new _ConcatFutureGroup<SearchResult>();
59 for (Element refElement in refElements) {
60 // add variable declaration
61 if (_isVariableLikeElement(refElement)) {
62 SearchResult searchResult = _newDeclarationResult(refElement);
63 futureGroup.add(searchResult);
64 }
65 // do search
66 futureGroup.add(_findSingleElementReferences(refElement));
67 }
68 return futureGroup.future;
85 }); 69 });
86 } 70 }
87 71
72 /**
73 * Returns a [Future] completing with a [List] of references to [element].
74 */
75 Future<List<SearchResult>> _findSingleElementReferences(Element element) {
76 Future<List<SearchMatch>> matchesFuture =
77 searchEngine.searchReferences(element);
78 return matchesFuture.then((List<SearchMatch> matches) {
79 return matches.map(toResult).toList();
80 });
81 }
82
83 /**
84 * Returns a [Future] completing with [Element]s to search references to.
85 *
86 * If a [ClassMemberElement] is given, each corresponding [Element] in the
87 * hierarchy is returned.
88 *
89 * Otherwise, only references to [element] should be searched.
90 */
91 Future<Iterable<Element>> _getRefElements(Element element) {
92 if (element is ClassMemberElement) {
93 return getHierarchyMembers(searchEngine, element);
94 }
95 return new Future.value([element]);
96 }
97
98 SearchResult _newDeclarationResult(Element refElement) {
99 int nameOffset = refElement.nameOffset;
100 int nameLength = refElement.name.length;
101 SearchMatch searchMatch =
102 new SearchMatch(
103 MatchKind.DECLARATION,
104 refElement,
105 new SourceRange(nameOffset, nameLength),
106 true,
107 false);
108 return new SearchResult.fromMatch(searchMatch);
109 }
110
88 static SearchResult toResult(SearchMatch match) { 111 static SearchResult toResult(SearchMatch match) {
89 return new SearchResult.fromMatch(match); 112 return new SearchResult.fromMatch(match);
90 } 113 }
91 114
92 static bool _isVariableLikeElement(Element element) { 115 static bool _isVariableLikeElement(Element element) {
93 if (element is LocalVariableElement) { 116 if (element is LocalVariableElement) {
94 return true; 117 return true;
95 } 118 }
96 if (element is ParameterElement) { 119 if (element is ParameterElement) {
97 return true; 120 return true;
98 } 121 }
99 if (element is PropertyInducingElement) { 122 if (element is PropertyInducingElement) {
100 return !element.isSynthetic; 123 return !element.isSynthetic;
101 } 124 }
102 return false; 125 return false;
103 } 126 }
104 } 127 }
128
129
130 /**
131 * A collection of [Future]s that concats [List] results of added [Future]s into
132 * a single [List].
133 */
134 class _ConcatFutureGroup<E> {
135 final List<Future<List<E>>> _futures = <Future<List<E>>>[];
136
137 Future<List<E>> get future {
138 return Future.wait(_futures).then(concatToList);
139 }
140
141 /**
142 * Adds a [Future] or an [E] value to results.
143 */
144 void add(value) {
145 if (value is Future) {
146 _futures.add(value);
147 } else {
148 _futures.add(new Future.value(<E>[value]));
149 }
150 }
151 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/lib/src/collections.dart ('k') | pkg/analysis_server/test/search/element_references_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698