| 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'; | 5 import 'dart:convert'; |
| 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'; |
| 11 import 'package:analyzer/src/generated/error.dart'; |
| 11 import 'package:analyzer/src/generated/source.dart'; | 12 import 'package:analyzer/src/generated/source.dart'; |
| 12 import 'package:analyzer/src/summary/format.dart'; | 13 import 'package:analyzer/src/summary/format.dart'; |
| 13 import 'package:analyzer/src/summary/idl.dart'; | 14 import 'package:analyzer/src/summary/idl.dart'; |
| 14 import 'package:analyzer/src/summary/summarize_elements.dart'; | 15 import 'package:analyzer/src/summary/summarize_elements.dart'; |
| 15 import 'package:convert/convert.dart'; | 16 import 'package:convert/convert.dart'; |
| 16 import 'package:crypto/crypto.dart'; | 17 import 'package:crypto/crypto.dart'; |
| 17 | 18 |
| 18 /** | 19 /** |
| 19 * Storage for cache data. | 20 * Storage for cache data. |
| 20 */ | 21 */ |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 } | 153 } |
| 153 closureBundles.add(new LibraryBundleWithId(source, key, bundle)); | 154 closureBundles.add(new LibraryBundleWithId(source, key, bundle)); |
| 154 } | 155 } |
| 155 return closureBundles; | 156 return closureBundles; |
| 156 } catch (e) { | 157 } catch (e) { |
| 157 return null; | 158 return null; |
| 158 } | 159 } |
| 159 } | 160 } |
| 160 | 161 |
| 161 /** | 162 /** |
| 163 * Return cached errors in the given [source] in the context of the given |
| 164 * [librarySource], or `null` if the cache does not have this information. |
| 165 */ |
| 166 List<AnalysisError> getSourceErrorsInLibrary( |
| 167 Source librarySource, Source source) { |
| 168 try { |
| 169 String key = _getSourceErrorsKey(librarySource, source); |
| 170 List<int> bytes = storage.get(key); |
| 171 if (bytes == null) { |
| 172 return null; |
| 173 } |
| 174 CacheSourceErrorsInLibrary errorsObject = |
| 175 new CacheSourceErrorsInLibrary.fromBuffer(bytes); |
| 176 return errorsObject.errors |
| 177 .map((e) => _convertErrorFromCached(source, e)) |
| 178 .toList(); |
| 179 } catch (e) { |
| 180 return null; |
| 181 } |
| 182 } |
| 183 |
| 184 /** |
| 162 * Return the kind of the given [source], or `null` if unknown. | 185 * Return the kind of the given [source], or `null` if unknown. |
| 163 */ | 186 */ |
| 164 SourceKind getSourceKind(Source source) { | 187 SourceKind getSourceKind(Source source) { |
| 165 try { | 188 try { |
| 166 CacheSourceContent contentSource = _getCacheSourceContent(source); | 189 CacheSourceContent contentSource = _getCacheSourceContent(source); |
| 167 if (contentSource != null) { | 190 if (contentSource != null) { |
| 168 if (contentSource.kind == CacheSourceKind.library) { | 191 if (contentSource.kind == CacheSourceKind.library) { |
| 169 return SourceKind.LIBRARY; | 192 return SourceKind.LIBRARY; |
| 170 } | 193 } |
| 171 if (contentSource.kind == CacheSourceKind.part) { | 194 if (contentSource.kind == CacheSourceKind.part) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 182 void putLibrary(LibraryElement libraryElement) { | 205 void putLibrary(LibraryElement libraryElement) { |
| 183 _writeCacheSourceContents(libraryElement); | 206 _writeCacheSourceContents(libraryElement); |
| 184 String key = _getLibraryBundleKey(libraryElement.source); | 207 String key = _getLibraryBundleKey(libraryElement.source); |
| 185 PackageBundleAssembler assembler = new PackageBundleAssembler(); | 208 PackageBundleAssembler assembler = new PackageBundleAssembler(); |
| 186 assembler.serializeLibraryElement(libraryElement); | 209 assembler.serializeLibraryElement(libraryElement); |
| 187 List<int> bytes = assembler.assemble().toBuffer(); | 210 List<int> bytes = assembler.assemble().toBuffer(); |
| 188 storage.put(key, bytes); | 211 storage.put(key, bytes); |
| 189 } | 212 } |
| 190 | 213 |
| 191 /** | 214 /** |
| 215 * Associate the given [errors] with the [source] in the [librarySource]. |
| 216 */ |
| 217 void putSourceErrorsInLibrary( |
| 218 Source librarySource, Source source, List<AnalysisError> errors) { |
| 219 CacheSourceErrorsInLibraryBuilder builder = |
| 220 new CacheSourceErrorsInLibraryBuilder( |
| 221 errors: errors.map(_convertErrorToCached).toList()); |
| 222 String key = _getSourceErrorsKey(librarySource, source); |
| 223 List<int> bytes = builder.toBuffer(); |
| 224 storage.put(key, bytes); |
| 225 } |
| 226 |
| 227 /** |
| 192 * Fill the whole source closure of the library with the given | 228 * Fill the whole source closure of the library with the given |
| 193 * [librarySource]. It includes defining units and parts of the library and | 229 * [librarySource]. It includes defining units and parts of the library and |
| 194 * all its directly or indirectly imported or exported libraries. | 230 * all its directly or indirectly imported or exported libraries. |
| 195 */ | 231 */ |
| 196 void _appendLibraryClosure(Set<Source> closure, Source librarySource) { | 232 void _appendLibraryClosure(Set<Source> closure, Source librarySource) { |
| 197 if (closure.add(librarySource)) { | 233 if (closure.add(librarySource)) { |
| 198 CacheSourceContent contentSource = _getCacheSourceContent(librarySource); | 234 CacheSourceContent contentSource = _getCacheSourceContent(librarySource); |
| 199 if (contentSource == null) { | 235 if (contentSource == null) { |
| 200 throw new StateError('No structure for $librarySource'); | 236 throw new StateError('No structure for $librarySource'); |
| 201 } | 237 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 229 ByteConversionSink byteSink = md5.startChunkedConversion(digestSink); | 265 ByteConversionSink byteSink = md5.startChunkedConversion(digestSink); |
| 230 // Add data. | 266 // Add data. |
| 231 addData(byteSink); | 267 addData(byteSink); |
| 232 byteSink.add(configSalt); | 268 byteSink.add(configSalt); |
| 233 // Done. | 269 // Done. |
| 234 byteSink.close(); | 270 byteSink.close(); |
| 235 return digest.bytes; | 271 return digest.bytes; |
| 236 } | 272 } |
| 237 | 273 |
| 238 /** | 274 /** |
| 275 * Return the [AnalysisError] for the given [cachedError]. |
| 276 */ |
| 277 AnalysisError _convertErrorFromCached( |
| 278 Source source, CacheAnalysisError cachedError) { |
| 279 ErrorCode errorCode = _getErrorCode(cachedError); |
| 280 return new AnalysisError.forValues( |
| 281 source, |
| 282 cachedError.offset, |
| 283 cachedError.length, |
| 284 errorCode, |
| 285 cachedError.message, |
| 286 cachedError.correction); |
| 287 } |
| 288 |
| 289 /** |
| 290 * Return the [CacheAnalysisError] for the given [error]. |
| 291 */ |
| 292 CacheAnalysisError _convertErrorToCached(AnalysisError error) { |
| 293 return new CacheAnalysisErrorBuilder( |
| 294 errorCodeClass: error.errorCode.runtimeType.toString(), |
| 295 errorCodeField: error.errorCode.name, |
| 296 offset: error.offset, |
| 297 length: error.length, |
| 298 message: error.message, |
| 299 correction: error.correction); |
| 300 } |
| 301 |
| 302 /** |
| 239 * Get the content based information about the given [source], maybe `null` | 303 * Get the content based information about the given [source], maybe `null` |
| 240 * if the information is not in the cache. | 304 * if the information is not in the cache. |
| 241 */ | 305 */ |
| 242 CacheSourceContent _getCacheSourceContent(Source source) { | 306 CacheSourceContent _getCacheSourceContent(Source source) { |
| 243 CacheSourceContent content = _sourceContentMap[source]; | 307 CacheSourceContent content = _sourceContentMap[source]; |
| 244 if (content == null) { | 308 if (content == null) { |
| 245 String key = _getCacheSourceContentKey(source); | 309 String key = _getCacheSourceContentKey(source); |
| 246 List<int> bytes = storage.get(key); | 310 List<int> bytes = storage.get(key); |
| 247 if (bytes == null) { | 311 if (bytes == null) { |
| 248 return null; | 312 return null; |
| 249 } | 313 } |
| 250 content = new CacheSourceContent.fromBuffer(bytes); | 314 content = new CacheSourceContent.fromBuffer(bytes); |
| 251 _sourceContentMap[source] = content; | 315 _sourceContentMap[source] = content; |
| 252 } | 316 } |
| 253 return content; | 317 return content; |
| 254 } | 318 } |
| 255 | 319 |
| 256 /** | 320 /** |
| 257 * Return the key of the content based [source] information. | 321 * Return the key of the content based [source] information. |
| 258 */ | 322 */ |
| 259 String _getCacheSourceContentKey(Source source) { | 323 String _getCacheSourceContentKey(Source source) { |
| 260 List<int> hash = _getSourceContentHash(source); | 324 List<int> hash = _getSourceContentHash(source); |
| 261 String hashStr = hex.encode(hash); | 325 String hashStr = hex.encode(hash); |
| 262 return '$hashStr.content'; | 326 return '$hashStr.content'; |
| 263 } | 327 } |
| 264 | 328 |
| 265 /** | 329 /** |
| 330 * Return the [ErrorCode] reference by the given [error], throws if not found. |
| 331 */ |
| 332 ErrorCode _getErrorCode(CacheAnalysisError error) { |
| 333 String name = '${error.errorCodeClass}.${error.errorCodeField}'; |
| 334 for (ErrorCode errorCode in ErrorCode.values) { |
| 335 if (errorCode.uniqueName == name) { |
| 336 return errorCode; |
| 337 } |
| 338 } |
| 339 throw new StateError('Unable to find ErrorCode: $name'); |
| 340 } |
| 341 |
| 342 /** |
| 266 * Get the bundle for the given key. | 343 * Get the bundle for the given key. |
| 267 */ | 344 */ |
| 268 PackageBundle _getLibraryBundle(String key) { | 345 PackageBundle _getLibraryBundle(String key) { |
| 269 PackageBundle bundle = _bundleMap[key]; | 346 PackageBundle bundle = _bundleMap[key]; |
| 270 if (bundle == null) { | 347 if (bundle == null) { |
| 271 List<int> bytes = storage.get(key); | 348 List<int> bytes = storage.get(key); |
| 272 if (bytes == null) { | 349 if (bytes == null) { |
| 273 return null; | 350 return null; |
| 274 } | 351 } |
| 275 bundle = new PackageBundle.fromBuffer(bytes); | 352 bundle = new PackageBundle.fromBuffer(bytes); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 */ | 398 */ |
| 322 List<int> _getSourceContentHash(Source source) { | 399 List<int> _getSourceContentHash(Source source) { |
| 323 return _sourceContentHashMap.putIfAbsent(source, () { | 400 return _sourceContentHashMap.putIfAbsent(source, () { |
| 324 String sourceText = source.contents.data; | 401 String sourceText = source.contents.data; |
| 325 List<int> sourceBytes = UTF8.encode(sourceText); | 402 List<int> sourceBytes = UTF8.encode(sourceText); |
| 326 return md5.convert(sourceBytes).bytes; | 403 return md5.convert(sourceBytes).bytes; |
| 327 }); | 404 }); |
| 328 } | 405 } |
| 329 | 406 |
| 330 /** | 407 /** |
| 408 * Return the key for errors in the [source] in the [librarySource]. |
| 409 */ |
| 410 String _getSourceErrorsKey(Source librarySource, Source source) { |
| 411 List<int> hash = _computeSaltedMD5OfBytes((ByteConversionSink byteSink) { |
| 412 byteSink.add(_getLibraryClosureHash(librarySource)); |
| 413 byteSink.add(_getSourceContentHash(source)); |
| 414 }); |
| 415 String hashStr = hex.encode(hash); |
| 416 return '$hashStr.errorsInLibrary'; |
| 417 } |
| 418 |
| 419 /** |
| 331 * Return a source representing the URI that results from resolving the given | 420 * Return a source representing the URI that results from resolving the given |
| 332 * (possibly relative) [containedUri] against the URI associated with the | 421 * (possibly relative) [containedUri] against the URI associated with the |
| 333 * [containingSource], whether or not the resulting source exists, or `null` | 422 * [containingSource], whether or not the resulting source exists, or `null` |
| 334 * if either the [containedUri] is invalid or if it cannot be resolved against | 423 * if either the [containedUri] is invalid or if it cannot be resolved against |
| 335 * the [containingSource]'s URI. | 424 * the [containingSource]'s URI. |
| 336 */ | 425 */ |
| 337 Source _resolveUri(Source containingSource, String containedUri) { | 426 Source _resolveUri(Source containingSource, String containedUri) { |
| 338 // Cache absolute URIs. | 427 // Cache absolute URIs. |
| 339 if (containedUri.startsWith('dart:') || | 428 if (containedUri.startsWith('dart:') || |
| 340 containedUri.startsWith('package:')) { | 429 containedUri.startsWith('package:')) { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 */ | 515 */ |
| 427 final String id; | 516 final String id; |
| 428 | 517 |
| 429 /** | 518 /** |
| 430 * The payload bundle. | 519 * The payload bundle. |
| 431 */ | 520 */ |
| 432 final PackageBundle bundle; | 521 final PackageBundle bundle; |
| 433 | 522 |
| 434 LibraryBundleWithId(this.source, this.id, this.bundle); | 523 LibraryBundleWithId(this.source, this.id, this.bundle); |
| 435 } | 524 } |
| OLD | NEW |