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

Side by Side Diff: pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart

Issue 1536683003: remove unused DartCompletionCache (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: merge Created 5 years 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/services/completion/dart_completion_manager.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library services.completion.dart.cache;
6
7 import 'dart:async';
8 import 'dart:collection';
9
10 import 'package:analysis_server/src/protocol_server.dart'
11 hide Element, ElementKind;
12 import 'package:analysis_server/src/services/completion/completion_manager.dart' ;
13 import 'package:analysis_server/src/services/completion/dart_completion_manager. dart';
14 import 'package:analysis_server/src/services/completion/suggestion_builder.dart' ;
15 import 'package:analysis_server/src/services/search/search_engine.dart';
16 import 'package:analyzer/dart/element/element.dart';
17 import 'package:analyzer/dart/element/type.dart';
18 import 'package:analyzer/src/generated/ast.dart';
19 import 'package:analyzer/src/generated/engine.dart';
20 import 'package:analyzer/src/generated/resolver.dart';
21 import 'package:analyzer/src/generated/source.dart';
22 import 'package:analyzer/src/task/dart.dart';
23
24 /**
25 * The `DartCompletionCache` contains cached information from a prior code
26 * completion operation.
27 */
28 class DartCompletionCache extends CompletionCache {
29 /**
30 * A hash of the import directives
31 * or `null` if nothing has been cached.
32 */
33 String _importKey;
34
35 /**
36 * Type suggestions based upon imports,
37 * or `null` if nothing has been cached.
38 */
39 List<CompletionSuggestion> importedTypeSuggestions;
40
41 /**
42 * Suggestions for methods and functions that have void return type,
43 * or `null` if nothing has been cached.
44 */
45 List<CompletionSuggestion> importedVoidReturnSuggestions;
46
47 /**
48 * Other suggestions based upon imports,
49 * or `null` if nothing has been cached.
50 */
51 List<CompletionSuggestion> otherImportedSuggestions;
52
53 /**
54 * Suggestions for constructors
55 * or `null` if nothing has been cached.
56 */
57 List<CompletionSuggestion> importedConstructorSuggestions;
58
59 /**
60 * A collection of all imported completions
61 * or `null` if nothing has been cached.
62 */
63 HashSet<String> _importedCompletions;
64
65 /**
66 * A map of simple identifier to imported class element
67 * or `null` if nothing has been cached.
68 */
69 Map<String, ClassElement> importedClassMap;
70
71 /**
72 * The [ClassElement] for Object.
73 */
74 ClassElement _objectClassElement;
75
76 DartCompletionCache(AnalysisContext context, Source source)
77 : super(context, source);
78
79 /**
80 * Return a hash of the import directives for the cached import info
81 * or `null` if nothing has been cached.
82 */
83 String get importKey => _importKey;
84
85 /**
86 * Return the [ClassElement] for Object.
87 */
88 ClassElement get objectClassElement {
89 if (_objectClassElement == null) {
90 Source coreUri = context.sourceFactory.forUri('dart:core');
91 LibraryElement coreLib = context.getResult(coreUri, LIBRARY_ELEMENT8);
92 _objectClassElement = coreLib.getType('Object');
93 }
94 return _objectClassElement;
95 }
96
97 /**
98 * Given a resolved compilation unit, compute suggestions based upon the
99 * imports and other dart files (e.g. "part" files) in the library containing
100 * the given compilation unit. The returned future completes when the cache
101 * is populated.
102 *
103 * If [shouldWaitForLowPrioritySuggestions] is `true` then the returned
104 * future will complete when the cache is fully populated. If `false`,
105 * the returned future will complete sooner, but the cache will not include
106 * the lower priority suggestions added as a result of a global search.
107 * In this case, those lower priority suggestions will be added later
108 * when the index has been updated and the global search completes.
109 */
110 Future<bool> computeImportInfo(CompilationUnit unit,
111 SearchEngine searchEngine, bool shouldWaitForLowPrioritySuggestions) {
112 importedTypeSuggestions = <CompletionSuggestion>[];
113 otherImportedSuggestions = <CompletionSuggestion>[];
114 importedConstructorSuggestions = <CompletionSuggestion>[];
115 importedVoidReturnSuggestions = <CompletionSuggestion>[];
116 importedClassMap = new Map<String, ClassElement>();
117 _importedCompletions = new HashSet<String>();
118
119 // Assert that the compilation unit is resolved
120 // and represents the expected source
121 assert(unit.element.source == source);
122
123 // Exclude elements from local library
124 // because they are provided by LocalReferenceContributor
125 Set<LibraryElement> excludedLibs = new Set<LibraryElement>();
126 excludedLibs.add(unit.element.enclosingElement);
127
128 // Determine the compilation unit defining the library containing
129 // this compilation unit
130 List<Source> libraries = context.getLibrariesContaining(source);
131 assert(libraries != null);
132 Source libSource = libraries.length > 0 ? libraries[0] : null;
133 Future<CompilationUnit> futureLibUnit = _computeLibUnit(libSource, unit);
134
135 // Include implicitly imported dart:core elements
136 _addDartCoreSuggestions();
137
138 // Include explicitly imported and part elements
139 Future futureImportsCached = futureLibUnit.then((CompilationUnit libUnit) {
140 _addImportedElemSuggestions(libSource, libUnit, excludedLibs);
141 // Don't wait for search of lower relevance results to complete.
142 // Set key indicating results are ready, and lower relevance results
143 // will be added to the cache when the search completes.
144 _importKey = _computeImportKey(unit);
145 return true;
146 });
147
148 // Add non-imported elements as low relevance
149 // after the imported element suggestions have been added
150 Future<bool> futureAllCached = futureImportsCached.then((_) {
151 return searchEngine
152 .searchTopLevelDeclarations('')
153 .then((List<SearchMatch> matches) {
154 _addNonImportedElementSuggestions(matches, excludedLibs);
155 return true;
156 });
157 });
158
159 return shouldWaitForLowPrioritySuggestions
160 ? futureAllCached
161 : futureImportsCached;
162 }
163
164 /**
165 * Return `true` if the import information is cached for the given
166 * compilation unit.
167 */
168 bool isImportInfoCached(CompilationUnit unit) =>
169 _importKey != null && _importKey == _computeImportKey(unit);
170
171 /**
172 * Add constructor suggestions for the given class.
173 */
174 void _addConstructorSuggestions(
175 ClassElement classElem, int relevance, Source importForSource) {
176 String className = classElem.name;
177 for (ConstructorElement constructor in classElem.constructors) {
178 if (!constructor.isPrivate) {
179 CompletionSuggestion suggestion = createSuggestion(constructor,
180 relevance: relevance, importForSource: importForSource);
181 if (suggestion != null) {
182 String name = suggestion.completion;
183 name = name.length > 0 ? '$className.$name' : className;
184 suggestion.completion = name;
185 suggestion.selectionOffset = suggestion.completion.length;
186 importedConstructorSuggestions.add(suggestion);
187 }
188 }
189 }
190 }
191
192 /**
193 * Add suggestions for implicitly imported elements in dart:core.
194 */
195 void _addDartCoreSuggestions() {
196 Source coreUri = context.sourceFactory.forUri('dart:core');
197 LibraryElement coreLib = context.getResult(coreUri, LIBRARY_ELEMENT8);
198 if (coreLib == null) {
199 // If the core library has not been analyzed yet, then we cannot add any
200 // suggestions from it.
201 return;
202 }
203 Namespace coreNamespace =
204 new NamespaceBuilder().createPublicNamespaceForLibrary(coreLib);
205 coreNamespace.definedNames.forEach((String name, Element elem) {
206 if (elem is ClassElement) {
207 importedClassMap[name] = elem;
208 }
209 _addSuggestion(elem, DART_RELEVANCE_DEFAULT);
210 });
211 }
212
213 /**
214 * Add suggestions for explicitly imported and part elements in the given
215 * library. Add libraries that should not have their elements suggested
216 * even as low priority to [excludedLibs].
217 */
218 void _addImportedElemSuggestions(Source libSource, CompilationUnit libUnit,
219 Set<LibraryElement> excludedLibs) {
220 if (libUnit != null) {
221 libUnit.directives.forEach((Directive directive) {
222 if (directive is ImportDirective) {
223 ImportElement importElem = directive.element;
224 if (importElem != null && importElem.importedLibrary != null) {
225 if (directive.prefix == null) {
226 Namespace importNamespace = new NamespaceBuilder()
227 .createImportNamespaceForDirective(importElem);
228 // Include top level elements
229 importNamespace.definedNames.forEach((String name, Element elem) {
230 if (elem is ClassElement) {
231 importedClassMap[name] = elem;
232 }
233 _addSuggestion(elem, DART_RELEVANCE_DEFAULT);
234 });
235 } else {
236 // Exclude elements from prefixed imports
237 // because they are provided by PrefixedElementContributor
238 // Suggested by LibraryPrefixContributor
239 // _addLibraryPrefixSuggestion(importElem);
240 // excludedLibs.add(importElem.importedLibrary);
241 }
242 }
243 } else if (directive is PartDirective) {
244 // Suggested by LocalLibraryContributor
245 // CompilationUnitElement partElem = directive.element;
246 // if (partElem != null && partElem.source != source) {
247 // partElem.accept(new _NonLocalElementCacheVisitor(this));
248 // }
249 }
250 });
251 if (libSource != source) {
252 // Suggested by LocalLibraryContributor
253 // libUnit.element.accept(new _NonLocalElementCacheVisitor(this));
254 }
255 }
256 }
257
258 /**
259 * Add suggestions for all top level elements in the context
260 * excluding those elemnents for which suggestions have already been added.
261 */
262 void _addNonImportedElementSuggestions(
263 List<SearchMatch> matches, Set<LibraryElement> excludedLibs) {
264 // Exclude internal Dart SDK libraries
265 for (var lib in context.sourceFactory.dartSdk.sdkLibraries) {
266 if (lib.isInternal) {
267 Source libUri = context.sourceFactory.forUri(lib.shortName);
268 if (libUri != null) {
269 LibraryElement libElem = context.getResult(libUri, LIBRARY_ELEMENT8);
270 if (libElem != null) {
271 excludedLibs.add(libElem);
272 }
273 }
274 }
275 }
276
277 AnalysisContext sdkContext = context.sourceFactory.dartSdk.context;
278 matches.forEach((SearchMatch match) {
279 if (match.kind == MatchKind.DECLARATION) {
280 Element element = match.element;
281 if ((element.context == context || element.context == sdkContext) &&
282 element.isPublic &&
283 !excludedLibs.contains(element.library) &&
284 !_importedCompletions.contains(element.displayName)) {
285 _addSuggestion(element, DART_RELEVANCE_LOW, importForSource: source);
286 }
287 }
288 });
289 }
290
291 /**
292 * Add a suggestion for the given element.
293 */
294 void _addSuggestion(Element element, int relevance,
295 {Source importForSource}) {
296 if (element is ExecutableElement) {
297 // Do not suggest operators or local functions
298 if (element.isOperator) {
299 return;
300 }
301 if (element is FunctionElement) {
302 if (element.enclosingElement is! CompilationUnitElement) {
303 return;
304 }
305 }
306 }
307
308 CompletionSuggestion suggestion = createSuggestion(element,
309 relevance: relevance, importForSource: importForSource);
310
311 if (suggestion != null) {
312 if (element is ExecutableElement) {
313 DartType returnType = element.returnType;
314 if (returnType != null && returnType.isVoid) {
315 importedVoidReturnSuggestions.add(suggestion);
316 } else {
317 otherImportedSuggestions.add(suggestion);
318 }
319 } else if (element is FunctionTypeAliasElement) {
320 importedTypeSuggestions.add(suggestion);
321 } else if (element is ClassElement) {
322 importedTypeSuggestions.add(suggestion);
323 _addConstructorSuggestions(element, relevance, importForSource);
324 } else {
325 otherImportedSuggestions.add(suggestion);
326 }
327 _importedCompletions.add(suggestion.completion);
328 }
329 }
330
331 /**
332 * Compute the hash of the imports for the given compilation unit.
333 */
334 String _computeImportKey(CompilationUnit unit) {
335 StringBuffer sb = new StringBuffer();
336 unit.directives.forEach((Directive directive) {
337 sb.write(directive.toSource());
338 });
339 return sb.toString();
340 }
341
342 /**
343 * Compute the library unit for the given library source,
344 * where the [unit] is the resolved compilation unit associated with [source].
345 */
346 Future<CompilationUnit> _computeLibUnit(
347 Source libSource, CompilationUnit unit) {
348 // If the sources are the same then we already have the library unit
349 if (libSource == source) {
350 return new Future.value(unit);
351 }
352 // If [source] is a part, then compute the library unit
353 if (libSource != null) {
354 return context.computeResolvedCompilationUnitAsync(libSource, libSource);
355 }
356 return new Future.value(null);
357 }
358 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698