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

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

Issue 815683002: support part file completions (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: merge Created 6 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 | Annotate | Revision Log
« 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
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 services.completion.dart.cache; 5 library services.completion.dart.cache;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 9
10 import 'package:analysis_server/src/protocol_server.dart' hide Element, 10 import 'package:analysis_server/src/protocol_server.dart' hide Element,
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 DartCompletionCache(AnalysisContext context, Source source) 74 DartCompletionCache(AnalysisContext context, Source source)
75 : super(context, source); 75 : super(context, source);
76 76
77 /** 77 /**
78 * Return a hash of the import directives for the cached import info 78 * Return a hash of the import directives for the cached import info
79 * or `null` if nothing has been cached. 79 * or `null` if nothing has been cached.
80 */ 80 */
81 String get importKey => _importKey; 81 String get importKey => _importKey;
82 82
83 /** 83 /**
84 * Compute suggestions based upon the imports in the given compilation unit. 84 * Given a resolved compilation unit, compute suggestions based upon the
85 * On return, the cache will be populated except for lower priority 85 * imports and other dart files (e.g. "part" files) in the library containing
86 * suggestions added as a result of a global search. Callers may wait 86 * the given compilation unit. The returned future completes when the cache
87 * on the returned future if they want to ensure those lower priority 87 * is populated.
88 * suggestions are part of the cached suggestions. 88 *
89 * If [shouldWaitForLowPrioritySuggestions] is `true` then the returned
90 * future will complete when the cache is fully populated. If `false`,
91 * the returned future will complete sooner, but the cache will not include
92 * the lower priority suggestions added as a result of a global search.
93 * In this case, those lower priority suggestions will be added later
94 * when the index has been updated and the global search completes.
89 */ 95 */
90 Future<bool> computeImportInfo(CompilationUnit unit, 96 Future<bool> computeImportInfo(CompilationUnit unit,
91 SearchEngine searchEngine) { 97 SearchEngine searchEngine, bool shouldWaitForLowPrioritySuggestions) {
92 importedTypeSuggestions = <CompletionSuggestion>[]; 98 importedTypeSuggestions = <CompletionSuggestion>[];
93 libraryPrefixSuggestions = <CompletionSuggestion>[]; 99 libraryPrefixSuggestions = <CompletionSuggestion>[];
94 otherImportedSuggestions = <CompletionSuggestion>[]; 100 otherImportedSuggestions = <CompletionSuggestion>[];
95 importedVoidReturnSuggestions = <CompletionSuggestion>[]; 101 importedVoidReturnSuggestions = <CompletionSuggestion>[];
96 importedClassMap = new Map<String, ClassElement>(); 102 importedClassMap = new Map<String, ClassElement>();
97 _importedCompletions = new HashSet<String>(); 103 _importedCompletions = new HashSet<String>();
98 104
105 // Assert that the compilation unit is resolved
106 // and represents the expected source
107 assert(unit.element.source == source);
108
99 // Exclude elements from local library 109 // Exclude elements from local library
100 // because they are provided by LocalComputer 110 // because they are provided by LocalComputer
101 Set<LibraryElement> excludedLibs = new Set<LibraryElement>(); 111 Set<LibraryElement> excludedLibs = new Set<LibraryElement>();
102 excludedLibs.add(unit.element.enclosingElement); 112 excludedLibs.add(unit.element.enclosingElement);
103 113
114 // Determine the compilation unit defining the library containing
115 // this compilation unit
116 List<Source> libraries = context.getLibrariesContaining(source);
117 Source libSource = null;
118 Future<CompilationUnit> futureLibUnit;
119 if (libraries != null && libraries.length > 0) {
120 libSource = libraries[0];
121 if (libSource == source) {
122 // If the sources are the same then we already have the library unit
123 futureLibUnit = new Future.value(unit);
124 } else {
125 // If the sources are different, then get the library unit
126 // to traverse the library directives and cache the imported elements
127 futureLibUnit =
128 context.computeResolvedCompilationUnitAsync(libSource, libSource);
129 }
130 } else {
131 futureLibUnit = new Future.value(null);
132 }
133
104 // Include explicitly imported elements 134 // Include explicitly imported elements
105 unit.directives.forEach((Directive directive) { 135 Future futureImportsCached = futureLibUnit.then((CompilationUnit libUnit) {
106 if (directive is ImportDirective) { 136 if (libUnit != null) {
107 ImportElement importElem = directive.element; 137 libUnit.directives.forEach((Directive directive) {
108 if (importElem != null && importElem.importedLibrary != null) { 138 if (directive is ImportDirective) {
109 if (directive.prefix == null) { 139 ImportElement importElem = directive.element;
110 Namespace importNamespace = 140 if (importElem != null && importElem.importedLibrary != null) {
111 new NamespaceBuilder().createImportNamespaceForDirective(importE lem); 141 if (directive.prefix == null) {
112 // Include top level elements 142 Namespace importNamespace =
113 importNamespace.definedNames.forEach((String name, Element elem) { 143 new NamespaceBuilder().createImportNamespaceForDirective(imp ortElem);
114 if (elem is ClassElement) { 144 // Include top level elements
115 importedClassMap[name] = elem; 145 importNamespace.definedNames.forEach(
146 (String name, Element elem) {
147 if (elem is ClassElement) {
148 importedClassMap[name] = elem;
149 }
150 addSuggestion(elem, CompletionRelevance.DEFAULT);
151 });
152 } else {
153 // Exclude elements from prefixed imports
154 // because they are provided by InvocationComputer
155 excludedLibs.add(importElem.importedLibrary);
156 _addLibraryPrefixSuggestion(importElem);
116 } 157 }
117 addSuggestion(elem, CompletionRelevance.DEFAULT); 158 }
118 }); 159 } else if (directive is PartDirective) {
119 } else { 160 CompilationUnitElement partElem = directive.element;
120 // Exclude elements from prefixed imports 161 if (partElem != null && partElem.source != source) {
121 // because they are provided by InvocationComputer 162 partElem.accept(new _NonLocalElementCacheVisitor(this));
122 excludedLibs.add(importElem.importedLibrary); 163 }
123 _addLibraryPrefixSuggestion(importElem);
124 } 164 }
165 });
166 if (libSource != source) {
167 libUnit.element.accept(new _NonLocalElementCacheVisitor(this));
125 } 168 }
126 } 169 }
170 // Don't wait for search of lower relevance results to complete.
171 // Set key indicating results are ready, and lower relevance results
172 // will be added to the cache when the search completes.
173 _importKey = _computeImportKey(unit);
174 return true;
127 }); 175 });
128 176
129 // Include implicitly imported dart:core elements 177 // Include implicitly imported dart:core elements
130 Source coreUri = context.sourceFactory.forUri('dart:core'); 178 Source coreUri = context.sourceFactory.forUri('dart:core');
131 LibraryElement coreLib = context.getLibraryElement(coreUri); 179 LibraryElement coreLib = context.getLibraryElement(coreUri);
132 Namespace coreNamespace = 180 Namespace coreNamespace =
133 new NamespaceBuilder().createPublicNamespaceForLibrary(coreLib); 181 new NamespaceBuilder().createPublicNamespaceForLibrary(coreLib);
134 coreNamespace.definedNames.forEach((String name, Element elem) { 182 coreNamespace.definedNames.forEach((String name, Element elem) {
135 if (elem is ClassElement) { 183 if (elem is ClassElement) {
136 importedClassMap[name] = elem; 184 importedClassMap[name] = elem;
137 } 185 }
138 addSuggestion(elem, CompletionRelevance.DEFAULT); 186 addSuggestion(elem, CompletionRelevance.DEFAULT);
139 }); 187 });
140 _objectClassElement = importedClassMap['Object']; 188 _objectClassElement = importedClassMap['Object'];
141 189
142 /* 190 // Add non-imported elements as low relevance
143 * Don't wait for search of lower relevance results to complete. 191 // after the imported element suggestions have been added
144 * Set key indicating results are ready, and lower relevance results 192 Future<bool> futureAllCached = futureImportsCached.then((_) {
145 * will be added to the cache when the search completes. 193 return searchEngine.searchTopLevelDeclarations(
146 */ 194 '').then((List<SearchMatch> matches) {
147 _importKey = _computeImportKey(unit); 195 matches.forEach((SearchMatch match) {
196 if (match.kind == MatchKind.DECLARATION) {
197 Element element = match.element;
198 if (element.isPublic &&
199 !excludedLibs.contains(element.library) &&
200 !_importedCompletions.contains(element.displayName)) {
201 addSuggestion(element, CompletionRelevance.LOW);
202 }
203 }
204 });
205 return true;
206 });
207 });
148 208
149 // Add non-imported elements as low relevance 209 return shouldWaitForLowPrioritySuggestions ?
150 Future<List<SearchMatch>> future = 210 futureAllCached :
151 searchEngine.searchTopLevelDeclarations(''); 211 futureImportsCached;
152 return future.then((List<SearchMatch> matches) {
153 matches.forEach((SearchMatch match) {
154 if (match.kind == MatchKind.DECLARATION) {
155 Element element = match.element;
156 if (element.isPublic &&
157 !excludedLibs.contains(element.library) &&
158 !_importedCompletions.contains(element.displayName)) {
159 addSuggestion(element, CompletionRelevance.LOW);
160 }
161 }
162 });
163 return true;
164 });
165 } 212 }
166 213
167 /** 214 /**
168 * Return the [ClassElement] for Object. 215 * Return the [ClassElement] for Object.
169 */ 216 */
170 ClassElement get objectClassElement { 217 ClassElement get objectClassElement {
171 if (_objectClassElement == null) { 218 if (_objectClassElement == null) {
172 Source coreUri = context.sourceFactory.forUri('dart:core'); 219 Source coreUri = context.sourceFactory.forUri('dart:core');
173 LibraryElement coreLib = context.getLibraryElement(coreUri); 220 LibraryElement coreLib = context.getLibraryElement(coreUri);
174 Namespace coreNamespace = 221 Namespace coreNamespace =
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 String _computeImportKey(CompilationUnit unit) { 285 String _computeImportKey(CompilationUnit unit) {
239 StringBuffer sb = new StringBuffer(); 286 StringBuffer sb = new StringBuffer();
240 unit.directives.forEach((Directive directive) { 287 unit.directives.forEach((Directive directive) {
241 if (directive is ImportDirective) { 288 if (directive is ImportDirective) {
242 sb.write(directive.toSource()); 289 sb.write(directive.toSource());
243 } 290 }
244 }); 291 });
245 return sb.toString(); 292 return sb.toString();
246 } 293 }
247 } 294 }
295
296 /**
297 * A visitor for building suggestions based upon the elements defined by
298 * a source file contained in the same library but not the same as
299 * the source in which the completions are being requested.
300 */
301 class _NonLocalElementCacheVisitor extends GeneralizingElementVisitor {
302 final DartCompletionCache cache;
303
304 _NonLocalElementCacheVisitor(this.cache);
305
306 @override
307 void visitClassElement(ClassElement element) {
308 cache.addSuggestion(element, CompletionRelevance.DEFAULT);
309 }
310
311 @override
312 void visitCompilationUnitElement(CompilationUnitElement element) {
313 element.visitChildren(this);
314 }
315
316 @override
317 void visitElement(Element element) {
318 // ignored
319 }
320
321 @override
322 void visitFunctionElement(FunctionElement element) {
323 cache.addSuggestion(element, CompletionRelevance.DEFAULT);
324 }
325
326 @override
327 void visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
328 cache.addSuggestion(element, CompletionRelevance.DEFAULT);
329 }
330
331 @override
332 void visitTopLevelVariableElement(TopLevelVariableElement element) {
333 cache.addSuggestion(element, CompletionRelevance.DEFAULT);
334 }
335 }
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