| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 import 'dart:convert' show UTF8; | 5 import 'dart:convert' show UTF8; |
| 6 import 'dart:core' hide Resource; | 6 import 'dart:core' hide Resource; |
| 7 | 7 |
| 8 import 'package:analyzer/dart/element/element.dart'; | 8 import 'package:analyzer/dart/element/element.dart'; |
| 9 import 'package:analyzer/file_system/file_system.dart'; | 9 import 'package:analyzer/file_system/file_system.dart'; |
| 10 import 'package:analyzer/src/generated/engine.dart'; | 10 import 'package:analyzer/src/generated/engine.dart'; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 * Opaque data that reflects the current configuration, such as the [context] | 96 * Opaque data that reflects the current configuration, such as the [context] |
| 97 * options, and is mixed into the hashes. | 97 * options, and is mixed into the hashes. |
| 98 */ | 98 */ |
| 99 final List<int> configSalt; | 99 final List<int> configSalt; |
| 100 | 100 |
| 101 final Map<Source, CacheSourceContent> _sourceContentMap = | 101 final Map<Source, CacheSourceContent> _sourceContentMap = |
| 102 <Source, CacheSourceContent>{}; | 102 <Source, CacheSourceContent>{}; |
| 103 final Map<Source, List<Source>> _libraryClosureMap = <Source, List<Source>>{}; | 103 final Map<Source, List<Source>> _libraryClosureMap = <Source, List<Source>>{}; |
| 104 final Map<Source, List<int>> _sourceContentHashMap = <Source, List<int>>{}; | 104 final Map<Source, List<int>> _sourceContentHashMap = <Source, List<int>>{}; |
| 105 | 105 |
| 106 /** |
| 107 * Mapping from a library closure key to its [PackageBundle]. |
| 108 */ |
| 109 final Map<String, PackageBundle> _bundleMap = <String, PackageBundle>{}; |
| 110 |
| 106 IncrementalCache(this.storage, this.context, this.configSalt); | 111 IncrementalCache(this.storage, this.context, this.configSalt); |
| 107 | 112 |
| 108 /** | 113 /** |
| 109 * Clear internal caches so that we read from file system again. | 114 * Clear internal caches so that we read from file system again. |
| 110 */ | 115 */ |
| 111 void clearInternalCaches() { | 116 void clearInternalCaches() { |
| 112 _sourceContentMap.clear(); | 117 _sourceContentMap.clear(); |
| 113 _libraryClosureMap.clear(); | 118 _libraryClosureMap.clear(); |
| 114 _sourceContentHashMap.clear(); | 119 _sourceContentHashMap.clear(); |
| 120 _bundleMap.clear(); |
| 115 } | 121 } |
| 116 | 122 |
| 117 /** | 123 /** |
| 124 * Return all summaries that are required to provide results about the library |
| 125 * with the given [librarySource] from its summary. It includes all of the |
| 126 * bundles in the import/export closure of the library. If any of the |
| 127 * bundles are not in the cache, then `null` is returned. If any of the |
| 128 * [LibraryBundleWithId]s were already returned as a part of the closure of |
| 129 * another library, they are still included - it is up to the client to |
| 130 * decide whether a bundle should be used or not, but it is easy to do |
| 131 * using [LibraryBundleWithId.id]. |
| 132 */ |
| 133 List<LibraryBundleWithId> getLibraryClosureBundles(Source librarySource) { |
| 134 try { |
| 135 List<Source> closureSources = _getLibraryClosure(librarySource); |
| 136 List<LibraryBundleWithId> closureBundles = <LibraryBundleWithId>[]; |
| 137 for (Source source in closureSources) { |
| 138 if (source.isInSystemLibrary) { |
| 139 continue; |
| 140 } |
| 141 String key = _getLibraryBundleKey(source); |
| 142 PackageBundle bundle = _getLibraryBundle(key); |
| 143 if (bundle == null) { |
| 144 return null; |
| 145 } |
| 146 closureBundles.add(new LibraryBundleWithId(source, key, bundle)); |
| 147 } |
| 148 return closureBundles; |
| 149 } catch (e) { |
| 150 return null; |
| 151 } |
| 152 } |
| 153 |
| 154 /** |
| 118 * Return the kind of the given [source], or `null` if unknown. | 155 * Return the kind of the given [source], or `null` if unknown. |
| 119 */ | 156 */ |
| 120 SourceKind getSourceKind(Source source) { | 157 SourceKind getSourceKind(Source source) { |
| 121 try { | 158 try { |
| 122 CacheSourceContent contentSource = _getCacheSourceContent(source); | 159 CacheSourceContent contentSource = _getCacheSourceContent(source); |
| 123 if (contentSource != null) { | 160 if (contentSource != null) { |
| 124 if (contentSource.kind == CacheSourceKind.library) { | 161 if (contentSource.kind == CacheSourceKind.library) { |
| 125 return SourceKind.LIBRARY; | 162 return SourceKind.LIBRARY; |
| 126 } | 163 } |
| 127 if (contentSource.kind == CacheSourceKind.part) { | 164 if (contentSource.kind == CacheSourceKind.part) { |
| 128 return SourceKind.PART; | 165 return SourceKind.PART; |
| 129 } | 166 } |
| 130 } | 167 } |
| 131 } catch (e) {} | 168 } catch (e) {} |
| 132 return null; | 169 return null; |
| 133 } | 170 } |
| 134 | 171 |
| 135 /** | 172 /** |
| 136 * Write information about the [library] into the cache. | 173 * Write information about the [libraryElement] into the cache. |
| 137 */ | 174 */ |
| 138 void putLibrary(LibraryElement library) { | 175 void putLibrary(LibraryElement libraryElement) { |
| 139 _writeCacheSourceContents(library); | 176 _writeCacheSourceContents(libraryElement); |
| 140 List<int> hash = _getLibraryClosureHash(library.source); | 177 String key = _getLibraryBundleKey(libraryElement.source); |
| 141 String hashStr = CryptoUtils.bytesToHex(hash); | |
| 142 PackageBundleAssembler assembler = new PackageBundleAssembler(); | 178 PackageBundleAssembler assembler = new PackageBundleAssembler(); |
| 143 assembler.serializeLibraryElement(library); | 179 assembler.serializeLibraryElement(libraryElement); |
| 144 List<int> bytes = assembler.assemble().toBuffer(); | 180 List<int> bytes = assembler.assemble().toBuffer(); |
| 145 storage.put('$hashStr.sum', bytes); | 181 storage.put(key, bytes); |
| 146 } | 182 } |
| 147 | 183 |
| 148 /** | 184 /** |
| 149 * Read the [PackageBundle] for the library with the given [source] from | |
| 150 * the cache. The returned bundle will correspond to the state when the set | |
| 151 * of direct and indirect dependencies is resolved in the [context]. Return | |
| 152 * `null` if such bundle does not exist. | |
| 153 */ | |
| 154 PackageBundle readBundle(Source source) { | |
| 155 try { | |
| 156 List<int> hash = _getLibraryClosureHash(source); | |
| 157 String hashStr = CryptoUtils.bytesToHex(hash); | |
| 158 List<int> bytes = storage.get('$hashStr.sum'); | |
| 159 if (bytes == null) { | |
| 160 return null; | |
| 161 } | |
| 162 return new PackageBundle.fromBuffer(bytes); | |
| 163 } catch (e) { | |
| 164 return null; | |
| 165 } | |
| 166 } | |
| 167 | |
| 168 /** | |
| 169 * Fill the whole source closure of the library with the given | 185 * Fill the whole source closure of the library with the given |
| 170 * [librarySource]. It includes defining units and parts of the library and | 186 * [librarySource]. It includes defining units and parts of the library and |
| 171 * all its directly or indirectly imported or exported libraries. | 187 * all its directly or indirectly imported or exported libraries. |
| 172 */ | 188 */ |
| 173 void _appendLibraryClosure(Set<Source> closure, Source librarySource) { | 189 void _appendLibraryClosure(Set<Source> closure, Source librarySource) { |
| 174 if (closure.add(librarySource)) { | 190 if (closure.add(librarySource)) { |
| 175 CacheSourceContent contentSource = _getCacheSourceContent(librarySource); | 191 CacheSourceContent contentSource = _getCacheSourceContent(librarySource); |
| 176 if (contentSource == null) { | 192 if (contentSource == null) { |
| 177 throw new StateError('No structure for $librarySource'); | 193 throw new StateError('No structure for $librarySource'); |
| 178 } | 194 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 /** | 236 /** |
| 221 * Return the key of the content based [source] information. | 237 * Return the key of the content based [source] information. |
| 222 */ | 238 */ |
| 223 String _getCacheSourceContentKey(Source source) { | 239 String _getCacheSourceContentKey(Source source) { |
| 224 List<int> hash = _getSourceContentHash(source); | 240 List<int> hash = _getSourceContentHash(source); |
| 225 String hashStr = CryptoUtils.bytesToHex(hash); | 241 String hashStr = CryptoUtils.bytesToHex(hash); |
| 226 return '$hashStr.content'; | 242 return '$hashStr.content'; |
| 227 } | 243 } |
| 228 | 244 |
| 229 /** | 245 /** |
| 246 * Get the bundle for the given key. |
| 247 */ |
| 248 PackageBundle _getLibraryBundle(String key) { |
| 249 PackageBundle bundle = _bundleMap[key]; |
| 250 if (bundle == null) { |
| 251 List<int> bytes = storage.get(key); |
| 252 if (bytes == null) { |
| 253 return null; |
| 254 } |
| 255 bundle = new PackageBundle.fromBuffer(bytes); |
| 256 _bundleMap[key] = bundle; |
| 257 } |
| 258 return bundle; |
| 259 } |
| 260 |
| 261 /** |
| 262 * Return the key of the bundle of the [librarySource]. |
| 263 */ |
| 264 String _getLibraryBundleKey(Source librarySource) { |
| 265 List<int> hash = _getLibraryClosureHash(librarySource); |
| 266 String hashStr = CryptoUtils.bytesToHex(hash); |
| 267 return '$hashStr.summary'; |
| 268 } |
| 269 |
| 270 /** |
| 230 * Return the whole source closure of the library with the given | 271 * Return the whole source closure of the library with the given |
| 231 * [librarySource]. It includes defining units and parts of the library and | 272 * [librarySource]. It includes defining units and parts of the library and |
| 232 * of all its directly or indirectly imported or exported libraries. | 273 * of all its directly or indirectly imported or exported libraries. |
| 233 */ | 274 */ |
| 234 List<Source> _getLibraryClosure(Source librarySource) { | 275 List<Source> _getLibraryClosure(Source librarySource) { |
| 235 return _libraryClosureMap.putIfAbsent(librarySource, () { | 276 return _libraryClosureMap.putIfAbsent(librarySource, () { |
| 236 Set<Source> closure = new Set<Source>(); | 277 Set<Source> closure = new Set<Source>(); |
| 237 _appendLibraryClosure(closure, librarySource); | 278 _appendLibraryClosure(closure, librarySource); |
| 238 return closure.toList(); | 279 return closure.toList(); |
| 239 }); | 280 }); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 // Write the library. | 364 // Write the library. |
| 324 _writeCacheSourceContent( | 365 _writeCacheSourceContent( |
| 325 librarySource, | 366 librarySource, |
| 326 new CacheSourceContentBuilder( | 367 new CacheSourceContentBuilder( |
| 327 kind: CacheSourceKind.library, | 368 kind: CacheSourceKind.library, |
| 328 importedUris: importUris, | 369 importedUris: importUris, |
| 329 exportedUris: exportUris, | 370 exportedUris: exportUris, |
| 330 partUris: partUris)); | 371 partUris: partUris)); |
| 331 } | 372 } |
| 332 } | 373 } |
| 374 |
| 375 /** |
| 376 * The bundle for a source in the context. |
| 377 */ |
| 378 class LibraryBundleWithId { |
| 379 /** |
| 380 * The source of the library this bundle is for. |
| 381 */ |
| 382 final Source source; |
| 383 |
| 384 /** |
| 385 * The unique ID of the [bundle] of the [source] in the context. |
| 386 */ |
| 387 final String id; |
| 388 |
| 389 /** |
| 390 * The payload bundle. |
| 391 */ |
| 392 final PackageBundle bundle; |
| 393 |
| 394 LibraryBundleWithId(this.source, this.id, this.bundle); |
| 395 } |
| OLD | NEW |