Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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. On return, the cache will be populated |
| 87 * on the returned future if they want to ensure those lower priority | 87 * except for lower priority suggestions added as a result of a global search. |
| 88 * suggestions are part of the cached suggestions. | 88 * Callers may wait on the returned future if they want to ensure those lower |
| 89 * priority suggestions are part of the cached suggestions. | |
| 89 */ | 90 */ |
| 90 Future<bool> computeImportInfo(CompilationUnit unit, | 91 Future<bool> computeImportInfo(CompilationUnit unit, |
| 91 SearchEngine searchEngine) { | 92 SearchEngine searchEngine) { |
| 92 importedTypeSuggestions = <CompletionSuggestion>[]; | 93 importedTypeSuggestions = <CompletionSuggestion>[]; |
| 93 libraryPrefixSuggestions = <CompletionSuggestion>[]; | 94 libraryPrefixSuggestions = <CompletionSuggestion>[]; |
| 94 otherImportedSuggestions = <CompletionSuggestion>[]; | 95 otherImportedSuggestions = <CompletionSuggestion>[]; |
| 95 importedVoidReturnSuggestions = <CompletionSuggestion>[]; | 96 importedVoidReturnSuggestions = <CompletionSuggestion>[]; |
| 96 importedClassMap = new Map<String, ClassElement>(); | 97 importedClassMap = new Map<String, ClassElement>(); |
| 97 _importedCompletions = new HashSet<String>(); | 98 _importedCompletions = new HashSet<String>(); |
| 98 | 99 |
| 100 // Assert the that compilation unit is resolved | |
| 101 // and represents the expected source | |
| 102 assert(unit.element.source == source); | |
| 103 | |
| 99 // Exclude elements from local library | 104 // Exclude elements from local library |
| 100 // because they are provided by LocalComputer | 105 // because they are provided by LocalComputer |
| 101 Set<LibraryElement> excludedLibs = new Set<LibraryElement>(); | 106 Set<LibraryElement> excludedLibs = new Set<LibraryElement>(); |
| 102 excludedLibs.add(unit.element.enclosingElement); | 107 excludedLibs.add(unit.element.enclosingElement); |
| 103 | 108 |
| 109 // Determine the compilation unit defining the library containing | |
| 110 // this compilation unit | |
| 111 List<Source> libraries = context.getLibrariesContaining(source); | |
| 112 Source libSource = null; | |
| 113 CompilationUnit libUnit = null; | |
| 114 if (libraries != null && libraries.length > 0) { | |
| 115 libSource = libraries[0]; | |
| 116 if (libSource == source) { | |
| 117 // If the sources are the same then we already have the library unit | |
| 118 libUnit = unit; | |
| 119 } else { | |
| 120 // If this is a part and we have the resolved unit for the part, | |
| 121 // then assume that the library unit is cached | |
| 122 // or is not-costly to recompute | |
| 123 libUnit = context.resolveCompilationUnit2(libSource, libSource); | |
|
Paul Berry
2014/12/18 18:37:02
Two issues:
1. context.resolveCompilationUnit2(lib
danrubel
2014/12/19 18:46:09
I need the library unit not the part unit to trave
Paul Berry
2014/12/19 19:13:30
Ok. It would be nice to add a comment to the code
danrubel
2014/12/20 05:12:30
Good point. Done.
| |
| 124 } | |
| 125 } | |
| 126 | |
| 104 // Include explicitly imported elements | 127 // Include explicitly imported elements |
| 105 unit.directives.forEach((Directive directive) { | 128 if (libUnit != null) { |
| 106 if (directive is ImportDirective) { | 129 libUnit.directives.forEach((Directive directive) { |
| 107 ImportElement importElem = directive.element; | 130 if (directive is ImportDirective) { |
| 108 if (importElem != null && importElem.importedLibrary != null) { | 131 ImportElement importElem = directive.element; |
| 109 if (directive.prefix == null) { | 132 if (importElem != null && importElem.importedLibrary != null) { |
| 110 Namespace importNamespace = | 133 if (directive.prefix == null) { |
| 111 new NamespaceBuilder().createImportNamespaceForDirective(importE lem); | 134 Namespace importNamespace = |
| 112 // Include top level elements | 135 new NamespaceBuilder().createImportNamespaceForDirective(impor tElem); |
| 113 importNamespace.definedNames.forEach((String name, Element elem) { | 136 // Include top level elements |
| 114 if (elem is ClassElement) { | 137 importNamespace.definedNames.forEach((String name, Element elem) { |
| 115 importedClassMap[name] = elem; | 138 if (elem is ClassElement) { |
| 116 } | 139 importedClassMap[name] = elem; |
| 117 addSuggestion(elem, CompletionRelevance.DEFAULT); | 140 } |
| 118 }); | 141 addSuggestion(elem, CompletionRelevance.DEFAULT); |
| 119 } else { | 142 }); |
| 120 // Exclude elements from prefixed imports | 143 } else { |
| 121 // because they are provided by InvocationComputer | 144 // Exclude elements from prefixed imports |
| 122 excludedLibs.add(importElem.importedLibrary); | 145 // because they are provided by InvocationComputer |
| 123 _addLibraryPrefixSuggestion(importElem); | 146 excludedLibs.add(importElem.importedLibrary); |
| 147 _addLibraryPrefixSuggestion(importElem); | |
| 148 } | |
| 149 } | |
| 150 } else if (directive is PartDirective) { | |
| 151 CompilationUnitElement partElem = directive.element; | |
| 152 if (partElem != null && partElem.source != source) { | |
| 153 partElem.accept(new _NonLocalElementCacheVisitor(this)); | |
| 124 } | 154 } |
| 125 } | 155 } |
| 156 }); | |
| 157 if (libSource != source) { | |
| 158 libUnit.element.accept(new _NonLocalElementCacheVisitor(this)); | |
| 126 } | 159 } |
| 127 }); | 160 } |
| 128 | 161 |
| 129 // Include implicitly imported dart:core elements | 162 // Include implicitly imported dart:core elements |
| 130 Source coreUri = context.sourceFactory.forUri('dart:core'); | 163 Source coreUri = context.sourceFactory.forUri('dart:core'); |
| 131 LibraryElement coreLib = context.getLibraryElement(coreUri); | 164 LibraryElement coreLib = context.getLibraryElement(coreUri); |
| 132 Namespace coreNamespace = | 165 Namespace coreNamespace = |
| 133 new NamespaceBuilder().createPublicNamespaceForLibrary(coreLib); | 166 new NamespaceBuilder().createPublicNamespaceForLibrary(coreLib); |
| 134 coreNamespace.definedNames.forEach((String name, Element elem) { | 167 coreNamespace.definedNames.forEach((String name, Element elem) { |
| 135 if (elem is ClassElement) { | 168 if (elem is ClassElement) { |
| 136 importedClassMap[name] = elem; | 169 importedClassMap[name] = elem; |
| 137 } | 170 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 238 String _computeImportKey(CompilationUnit unit) { | 271 String _computeImportKey(CompilationUnit unit) { |
| 239 StringBuffer sb = new StringBuffer(); | 272 StringBuffer sb = new StringBuffer(); |
| 240 unit.directives.forEach((Directive directive) { | 273 unit.directives.forEach((Directive directive) { |
| 241 if (directive is ImportDirective) { | 274 if (directive is ImportDirective) { |
| 242 sb.write(directive.toSource()); | 275 sb.write(directive.toSource()); |
| 243 } | 276 } |
| 244 }); | 277 }); |
| 245 return sb.toString(); | 278 return sb.toString(); |
| 246 } | 279 } |
| 247 } | 280 } |
| 281 | |
| 282 /** | |
| 283 * A visitor for building suggestions based upon the elements defined by | |
| 284 * a source file contained in the same library but not the same as | |
| 285 * the source in which the completions are being requested. | |
| 286 */ | |
| 287 class _NonLocalElementCacheVisitor extends GeneralizingElementVisitor { | |
| 288 final DartCompletionCache cache; | |
| 289 | |
| 290 _NonLocalElementCacheVisitor(this.cache); | |
| 291 | |
| 292 @override | |
| 293 void visitClassElement(ClassElement element) { | |
| 294 cache.addSuggestion(element, CompletionRelevance.DEFAULT); | |
| 295 } | |
| 296 | |
| 297 @override | |
| 298 void visitCompilationUnitElement(CompilationUnitElement element) { | |
| 299 element.visitChildren(this); | |
| 300 } | |
| 301 | |
| 302 @override | |
| 303 void visitElement(Element element) { | |
| 304 // ignored | |
| 305 } | |
| 306 | |
| 307 @override | |
| 308 void visitFunctionElement(FunctionElement element) { | |
| 309 cache.addSuggestion(element, CompletionRelevance.DEFAULT); | |
| 310 } | |
| 311 | |
| 312 @override | |
| 313 void visitFunctionTypeAliasElement(FunctionTypeAliasElement element) { | |
| 314 cache.addSuggestion(element, CompletionRelevance.DEFAULT); | |
| 315 } | |
| 316 | |
| 317 @override | |
| 318 void visitTopLevelVariableElement(TopLevelVariableElement element) { | |
| 319 cache.addSuggestion(element, CompletionRelevance.DEFAULT); | |
| 320 } | |
| 321 } | |
| OLD | NEW |