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

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

Issue 2409403002: Issue 27542. Guard against CompilationUnitElement is null in SearchMatch.element getter. (Closed)
Patch Set: Created 4 years, 2 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
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/search/search_domain.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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';
10 import 'package:analysis_server/src/protocol_server.dart' 9 import 'package:analysis_server/src/protocol_server.dart'
11 show SearchResult, newSearchResult_fromMatch; 10 show SearchResult, newSearchResult_fromMatch;
12 import 'package:analysis_server/src/services/search/hierarchy.dart'; 11 import 'package:analysis_server/src/services/search/hierarchy.dart';
13 import 'package:analysis_server/src/services/search/search_engine.dart'; 12 import 'package:analysis_server/src/services/search/search_engine.dart';
14 import 'package:analyzer/dart/element/element.dart'; 13 import 'package:analyzer/dart/element/element.dart';
15 import 'package:analyzer/src/generated/source.dart'; 14 import 'package:analyzer/src/generated/source.dart';
16 15
17 /** 16 /**
18 * A computer for `search.findElementReferences` request results. 17 * A computer for `search.findElementReferences` request results.
19 */ 18 */
20 class ElementReferencesComputer { 19 class ElementReferencesComputer {
21 final SearchEngine searchEngine; 20 final SearchEngine searchEngine;
22 21
23 ElementReferencesComputer(this.searchEngine); 22 ElementReferencesComputer(this.searchEngine);
24 23
25 /** 24 /**
26 * Computes [SearchResult]s for [element] references. 25 * Computes [SearchResult]s for [element] references.
27 */ 26 */
28 Future<List<SearchResult>> compute(Element element, bool withPotential) { 27 Future<List<SearchResult>> compute(
29 var futureGroup = new _ConcatFutureGroup<SearchResult>(); 28 Element element, bool withPotential) async {
30 // find element references 29 List<SearchResult> results = <SearchResult>[];
31 futureGroup.add(_findElementsReferences(element)); 30
32 // add potential references 31 // Add element references.
32 results.addAll(await _findElementsReferences(element));
33
34 // Add potential references.
33 if (withPotential && _isMemberElement(element)) { 35 if (withPotential && _isMemberElement(element)) {
34 String name = element.displayName; 36 String name = element.displayName;
35 var matchesFuture = searchEngine.searchMemberReferences(name); 37 List<SearchMatch> matches =
36 var resultsFuture = matchesFuture.then((List<SearchMatch> matches) { 38 await searchEngine.searchMemberReferences(name);
37 return matches.where((match) => !match.isResolved).map(toResult); 39 matches = SearchMatch.withNotNullElement(matches);
38 }); 40 results.addAll(matches.where((match) => !match.isResolved).map(toResult));
39 futureGroup.add(resultsFuture);
40 } 41 }
41 // merge results 42
42 return futureGroup.future; 43 return results;
43 } 44 }
44 45
45 /** 46 /**
46 * Returns a [Future] completing with a [List] of references to [element] or 47 * Returns a [Future] completing with a [List] of references to [element] or
47 * to the corresponding hierarchy [Element]s. 48 * to the corresponding hierarchy [Element]s.
48 */ 49 */
49 Future<List<SearchResult>> _findElementsReferences(Element element) async { 50 Future<List<SearchResult>> _findElementsReferences(Element element) async {
51 List<SearchResult> allResults = <SearchResult>[];
50 Iterable<Element> refElements = await _getRefElements(element); 52 Iterable<Element> refElements = await _getRefElements(element);
51 var futureGroup = new _ConcatFutureGroup<SearchResult>();
52 for (Element refElement in refElements) { 53 for (Element refElement in refElements) {
53 // add declaration 54 // add declaration
54 if (_isDeclarationInteresting(refElement)) { 55 if (_isDeclarationInteresting(refElement)) {
55 SearchResult searchResult = _newDeclarationResult(refElement); 56 SearchResult searchResult = _newDeclarationResult(refElement);
56 futureGroup.add(searchResult); 57 allResults.add(searchResult);
57 } 58 }
58 // do search 59 // do search
59 futureGroup.add(_findSingleElementReferences(refElement)); 60 List<SearchResult> elementResults =
61 await _findSingleElementReferences(refElement);
62 allResults.addAll(elementResults);
60 } 63 }
61 return futureGroup.future; 64 return allResults;
62 } 65 }
63 66
64 /** 67 /**
65 * Returns a [Future] completing with a [List] of references to [element]. 68 * Returns a [Future] completing with a [List] of references to [element].
66 */ 69 */
67 Future<List<SearchResult>> _findSingleElementReferences( 70 Future<List<SearchResult>> _findSingleElementReferences(
68 Element element) async { 71 Element element) async {
69 List<SearchMatch> matches = await searchEngine.searchReferences(element); 72 List<SearchMatch> matches = await searchEngine.searchReferences(element);
73 matches = SearchMatch.withNotNullElement(matches);
70 return matches.map(toResult).toList(); 74 return matches.map(toResult).toList();
71 } 75 }
72 76
73 /** 77 /**
74 * Returns a [Future] completing with [Element]s to search references to. 78 * Returns a [Future] completing with [Element]s to search references to.
75 * 79 *
76 * If a [ClassMemberElement] is given, each corresponding [Element] in the 80 * If a [ClassMemberElement] is given, each corresponding [Element] in the
77 * hierarchy is returned. 81 * hierarchy is returned.
78 * 82 *
79 * Otherwise, only references to [element] should be searched. 83 * Otherwise, only references to [element] should be searched.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 return false; 126 return false;
123 } 127 }
124 128
125 static bool _isMemberElement(Element element) { 129 static bool _isMemberElement(Element element) {
126 if (element is ConstructorElement) { 130 if (element is ConstructorElement) {
127 return false; 131 return false;
128 } 132 }
129 return element.enclosingElement is ClassElement; 133 return element.enclosingElement is ClassElement;
130 } 134 }
131 } 135 }
132
133 /**
134 * A collection of [Future]s that concats [List] results of added [Future]s into
135 * a single [List].
136 */
137 class _ConcatFutureGroup<E> {
138 final List<Future<List<E>>> _futures = <Future<List<E>>>[];
139
140 Future<List<E>> get future {
141 return Future.wait(_futures).then(concatToList);
142 }
143
144 /**
145 * Adds a [Future] or an [E] value to results.
146 */
147 void add(value) {
148 if (value is Future) {
149 _futures.add(value as Future<List<E>>);
150 } else {
151 _futures.add(new Future.value(<E>[value as E]));
152 }
153 }
154 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/search/search_domain.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698