| Index: pkg/analyzer/lib/src/summary/incremental_cache.dart
|
| diff --git a/pkg/analyzer/lib/src/summary/incremental_cache.dart b/pkg/analyzer/lib/src/summary/incremental_cache.dart
|
| deleted file mode 100644
|
| index 19a42259f7e6995ccd6d88d01e08edbef74aacce..0000000000000000000000000000000000000000
|
| --- a/pkg/analyzer/lib/src/summary/incremental_cache.dart
|
| +++ /dev/null
|
| @@ -1,656 +0,0 @@
|
| -// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
| -// for details. All rights reserved. Use of this source code is governed by a
|
| -// BSD-style license that can be found in the LICENSE file.
|
| -
|
| -import 'dart:collection';
|
| -import 'dart:convert';
|
| -import 'dart:core';
|
| -
|
| -import 'package:analyzer/dart/element/element.dart';
|
| -import 'package:analyzer/error/error.dart';
|
| -import 'package:analyzer/file_system/file_system.dart';
|
| -import 'package:analyzer/src/generated/engine.dart';
|
| -import 'package:analyzer/src/generated/source.dart';
|
| -import 'package:analyzer/src/summary/format.dart';
|
| -import 'package:analyzer/src/summary/idl.dart';
|
| -import 'package:analyzer/src/summary/summarize_elements.dart';
|
| -import 'package:convert/convert.dart';
|
| -import 'package:crypto/crypto.dart';
|
| -
|
| -/**
|
| - * The version of the incremental cache. It should be incremented every time
|
| - * when any cache data structure is changed.
|
| - */
|
| -const int _VERSION = 1;
|
| -
|
| -/**
|
| - * Compare the given file paths [a] and [b]. Because paths usually have long
|
| - * equal prefix, comparison is done not as comparision of two generic [String]s.
|
| - * Instead it starts from the ends of each strings.
|
| - *
|
| - * Return `-1` if [a] is ordered before [b], `1` if `this` is ordered after [b],
|
| - * and zero if [a] and [b] are ordered together.
|
| - */
|
| -int comparePaths(String a, String b) {
|
| - int thisLength = a.length;
|
| - int otherLength = b.length;
|
| - int len = (thisLength < otherLength) ? thisLength : otherLength;
|
| - for (int i = 0; i < len; i++) {
|
| - int thisCodeUnit = a.codeUnitAt(thisLength - 1 - i);
|
| - int otherCodeUnit = b.codeUnitAt(otherLength - 1 - i);
|
| - if (thisCodeUnit < otherCodeUnit) {
|
| - return -1;
|
| - }
|
| - if (thisCodeUnit > otherCodeUnit) {
|
| - return 1;
|
| - }
|
| - }
|
| - if (thisLength < otherLength) {
|
| - return -1;
|
| - }
|
| - if (thisLength > otherLength) {
|
| - return 1;
|
| - }
|
| - return 0;
|
| -}
|
| -
|
| -/**
|
| - * Storage for cache data.
|
| - */
|
| -abstract class CacheStorage {
|
| - /**
|
| - * Compact the storage, e.g. remove unused entries.
|
| - */
|
| - void compact();
|
| -
|
| - /**
|
| - * Return bytes for the given [key], `null` if [key] is not in the storage.
|
| - */
|
| - List<int> get(String key);
|
| -
|
| - /**
|
| - * Associate the [key] with the given [bytes].
|
| - *
|
| - * If the [key] was already in the storage, its associated value is changed.
|
| - * Otherwise the key-value pair is added to the storage.
|
| - *
|
| - * It is not guaranteed that data will always be accessible using [get], in
|
| - * some implementations association may silently fail or become inaccessible
|
| - * after some time.
|
| - */
|
| - void put(String key, List<int> bytes);
|
| -}
|
| -
|
| -/**
|
| - * A [Folder] based implementation of [CacheStorage].
|
| - */
|
| -class FolderCacheStorage implements CacheStorage {
|
| - /**
|
| - * The maximum number of entries to keep in the cache.
|
| - */
|
| - static const MAX_ENTRIES = 20000;
|
| -
|
| - /**
|
| - * The folder to read and write files.
|
| - */
|
| - final Folder folder;
|
| -
|
| - /**
|
| - * To ensure that operations of writing files are atomic we create a temporary
|
| - * file with this name in the [folder] and then rename it once we are
|
| - * done writing.
|
| - */
|
| - final String tempFileName;
|
| -
|
| - /**
|
| - * The set of recently used entries, with the most recently used entries
|
| - * on the bottom.
|
| - */
|
| - final LinkedHashSet<String> _recentEntries = new LinkedHashSet<String>();
|
| -
|
| - FolderCacheStorage(this.folder, this.tempFileName) {
|
| - try {
|
| - File file = folder.getChildAssumingFile('.entries');
|
| - if (file.exists) {
|
| - String entriesString = file.readAsStringSync();
|
| - List<String> entriesLists = entriesString.split('\n');
|
| - _recentEntries.addAll(entriesLists);
|
| - }
|
| - } catch (_) {}
|
| - }
|
| -
|
| - @override
|
| - void compact() {
|
| - while (_recentEntries.length > MAX_ENTRIES) {
|
| - String key = _recentEntries.first;
|
| - _recentEntries.remove(key);
|
| - try {
|
| - folder.getChildAssumingFile(key).delete();
|
| - } catch (_) {}
|
| - }
|
| - try {
|
| - List<int> bytes = UTF8.encode(_recentEntries.join('\n'));
|
| - folder.getChildAssumingFile('.entries').writeAsBytesSync(bytes);
|
| - } catch (_) {}
|
| - }
|
| -
|
| - @override
|
| - List<int> get(String key) {
|
| - Resource file = folder.getChild(key);
|
| - if (file is File) {
|
| - try {
|
| - List<int> bytes = file.readAsBytesSync();
|
| - _accessedKey(key);
|
| - return bytes;
|
| - } on FileSystemException {}
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - @override
|
| - void put(String key, List<int> bytes) {
|
| - String absPath = folder.getChild(key).path;
|
| - File tempFile = folder.getChild(tempFileName);
|
| - tempFile.writeAsBytesSync(bytes);
|
| - try {
|
| - tempFile.renameSync(absPath);
|
| - _accessedKey(key);
|
| - } catch (e) {}
|
| - }
|
| -
|
| - /**
|
| - * The given [key] was accessed, update recently used entries.
|
| - */
|
| - void _accessedKey(String key) {
|
| - _recentEntries.remove(key);
|
| - _recentEntries.add(key);
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * Cache of information to support incremental analysis.
|
| - *
|
| - * Note that currently this class is not intended for interactive use.
|
| - */
|
| -class IncrementalCache {
|
| - /**
|
| - * The storage for the cache data.
|
| - */
|
| - final CacheStorage storage;
|
| -
|
| - /**
|
| - * The context in which this cache is used.
|
| - */
|
| - final AnalysisContext context;
|
| -
|
| - /**
|
| - * Opaque data that reflects the current configuration, such as the [context]
|
| - * options, and is mixed into the hashes.
|
| - */
|
| - final List<int> configSalt;
|
| -
|
| - final Map<Source, CacheSourceContent> _sourceContentMap =
|
| - <Source, CacheSourceContent>{};
|
| - final Map<Source, List<Source>> _libraryClosureMap = <Source, List<Source>>{};
|
| - final Map<Source, List<int>> _libraryClosureHashMap = <Source, List<int>>{};
|
| - final Map<Source, List<int>> _sourceContentHashMap = <Source, List<int>>{};
|
| -
|
| - /**
|
| - * Mapping from a library closure key to its [PackageBundle].
|
| - */
|
| - final Map<String, PackageBundle> _bundleMap = <String, PackageBundle>{};
|
| -
|
| - final Map<String, Source> _absoluteUriMap = <String, Source>{};
|
| -
|
| - IncrementalCache(this.storage, this.context, this.configSalt);
|
| -
|
| - /**
|
| - * Clear internal caches so that we read from file system again.
|
| - */
|
| - void clearInternalCaches() {
|
| - _sourceContentMap.clear();
|
| - _libraryClosureMap.clear();
|
| - _sourceContentHashMap.clear();
|
| - _bundleMap.clear();
|
| - }
|
| -
|
| - /**
|
| - * Return all summaries that are required to provide results about the library
|
| - * with the given [librarySource] from its summary. It includes all of the
|
| - * bundles in the import/export closure of the library. If any of the
|
| - * bundles are not in the cache, then `null` is returned. If any of the
|
| - * [LibraryBundleWithId]s were already returned as a part of the closure of
|
| - * another library, they are still included - it is up to the client to
|
| - * decide whether a bundle should be used or not, but it is easy to do
|
| - * using [LibraryBundleWithId.id].
|
| - */
|
| - List<LibraryBundleWithId> getLibraryClosureBundles(Source librarySource) {
|
| - try {
|
| - List<Source> closureSources = _getLibraryClosure(librarySource);
|
| - List<LibraryBundleWithId> closureBundles = <LibraryBundleWithId>[];
|
| - for (Source source in closureSources) {
|
| - if (getSourceKind(source) == SourceKind.PART) {
|
| - continue;
|
| - }
|
| - String key = _getLibraryBundleKey(source);
|
| - PackageBundle bundle = _getLibraryBundle(key);
|
| - if (bundle == null) {
|
| - return null;
|
| - }
|
| - closureBundles.add(new LibraryBundleWithId(source, key, bundle));
|
| - }
|
| - return closureBundles;
|
| - } catch (e) {
|
| - return null;
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Return the parts of the given [librarySource], or `null` if unknown.
|
| - */
|
| - List<Source> getLibraryParts(Source librarySource) {
|
| - try {
|
| - CacheSourceContent contentSource = _getCacheSourceContent(librarySource);
|
| - if (contentSource != null) {
|
| - return contentSource.partUris.map((String partUri) {
|
| - Source partSource = _resolveUri(librarySource, partUri);
|
| - if (partSource == null) {
|
| - throw new StateError(
|
| - 'Unable to resolve $partUri in $librarySource');
|
| - }
|
| - return partSource;
|
| - }).toList();
|
| - }
|
| - } catch (e) {}
|
| - return null;
|
| - }
|
| -
|
| - /**
|
| - * Return cached errors in the given [source] in the context of the given
|
| - * [librarySource], or `null` if the cache does not have this information.
|
| - */
|
| - List<AnalysisError> getSourceErrorsInLibrary(
|
| - Source librarySource, Source source) {
|
| - try {
|
| - String key = _getSourceErrorsKey(librarySource, source);
|
| - List<int> bytes = storage.get(key);
|
| - if (bytes == null) {
|
| - return null;
|
| - }
|
| - CacheSourceErrorsInLibrary errorsObject =
|
| - new CacheSourceErrorsInLibrary.fromBuffer(bytes);
|
| - return errorsObject.errors
|
| - .map((e) => _convertErrorFromCached(source, e))
|
| - .toList();
|
| - } catch (e) {
|
| - return null;
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Return the kind of the given [source], or `null` if unknown.
|
| - */
|
| - SourceKind getSourceKind(Source source) {
|
| - try {
|
| - CacheSourceContent contentSource = _getCacheSourceContent(source);
|
| - if (contentSource != null) {
|
| - if (contentSource.kind == CacheSourceKind.library) {
|
| - return SourceKind.LIBRARY;
|
| - }
|
| - if (contentSource.kind == CacheSourceKind.part) {
|
| - return SourceKind.PART;
|
| - }
|
| - }
|
| - } catch (e) {}
|
| - return null;
|
| - }
|
| -
|
| - /**
|
| - * Write information about the [libraryElement] into the cache.
|
| - */
|
| - void putLibrary(LibraryElement libraryElement) {
|
| - _writeCacheSourceContents(libraryElement);
|
| - String key = _getLibraryBundleKey(libraryElement.source);
|
| - PackageBundleAssembler assembler = new PackageBundleAssembler();
|
| - assembler.serializeLibraryElement(libraryElement);
|
| - List<int> bytes = assembler.assemble().toBuffer();
|
| - storage.put(key, bytes);
|
| - }
|
| -
|
| - /**
|
| - * Associate the given [errors] with the [source] in the [librarySource].
|
| - */
|
| - void putSourceErrorsInLibrary(
|
| - Source librarySource, Source source, List<AnalysisError> errors) {
|
| - CacheSourceErrorsInLibraryBuilder builder =
|
| - new CacheSourceErrorsInLibraryBuilder(
|
| - errors: errors.map(_convertErrorToCached).toList());
|
| - String key = _getSourceErrorsKey(librarySource, source);
|
| - List<int> bytes = builder.toBuffer();
|
| - storage.put(key, bytes);
|
| - }
|
| -
|
| - /**
|
| - * Fill the whole source closure of the library with the given
|
| - * [librarySource]. It includes defining units and parts of the library and
|
| - * all its directly or indirectly imported or exported libraries.
|
| - */
|
| - void _appendLibraryClosure(Set<Source> closure, Source librarySource) {
|
| - if (librarySource.isInSystemLibrary) {
|
| - return;
|
| - }
|
| - if (closure.add(librarySource)) {
|
| - CacheSourceContent contentSource = _getCacheSourceContent(librarySource);
|
| - if (contentSource == null) {
|
| - throw new StateError('No structure for $librarySource');
|
| - }
|
| - // Append parts.
|
| - for (String partUri in contentSource.partUris) {
|
| - Source partSource = _resolveUri(librarySource, partUri);
|
| - if (partSource == null) {
|
| - throw new StateError('Unable to resolve $partUri in $librarySource');
|
| - }
|
| - closure.add(partSource);
|
| - }
|
| - // Append imports and exports.
|
| - void appendLibrarySources(String refUri) {
|
| - Source refSource = _resolveUri(librarySource, refUri);
|
| - if (refSource == null) {
|
| - throw new StateError('Unable to resolve $refUri in $librarySource');
|
| - }
|
| - // If we have already the closure for the 'refSource', use it.
|
| - // Otherwise, continue computing recursively.
|
| - // It's not the most efficient algorithm, but in practice we might
|
| - // visit each library multiple times only for the first top-level
|
| - // bundle requested in `getLibraryClosureBundles`.
|
| - List<Source> refClosure = _libraryClosureMap[refSource];
|
| - if (refClosure != null) {
|
| - closure.addAll(refClosure);
|
| - } else {
|
| - _appendLibraryClosure(closure, refSource);
|
| - }
|
| - }
|
| -
|
| - contentSource.importedUris.forEach(appendLibrarySources);
|
| - contentSource.exportedUris.forEach(appendLibrarySources);
|
| - }
|
| - }
|
| -
|
| - List<int> _computeSaltedMD5OfBytes(addData(ByteConversionSink byteSink)) {
|
| - Digest digest;
|
| - ChunkedConversionSink<Digest> digestSink =
|
| - new ChunkedConversionSink<Digest>.withCallback((List<Digest> digests) {
|
| - digest = digests.single;
|
| - });
|
| - ByteConversionSink byteSink = md5.startChunkedConversion(digestSink);
|
| - // Add data.
|
| - addData(byteSink);
|
| - byteSink.add(const <int>[_VERSION]);
|
| - byteSink.add(configSalt);
|
| - // Done.
|
| - byteSink.close();
|
| - return digest.bytes;
|
| - }
|
| -
|
| - /**
|
| - * Return the [AnalysisError] for the given [cachedError].
|
| - */
|
| - AnalysisError _convertErrorFromCached(
|
| - Source source, CacheAnalysisError cachedError) {
|
| - ErrorCode errorCode = _getErrorCode(cachedError);
|
| - return new AnalysisError.forValues(
|
| - source,
|
| - cachedError.offset,
|
| - cachedError.length,
|
| - errorCode,
|
| - cachedError.message,
|
| - cachedError.correction);
|
| - }
|
| -
|
| - /**
|
| - * Return the [CacheAnalysisError] for the given [error].
|
| - */
|
| - CacheAnalysisError _convertErrorToCached(AnalysisError error) {
|
| - return new CacheAnalysisErrorBuilder(
|
| - errorCodeUniqueName: error.errorCode.uniqueName,
|
| - offset: error.offset,
|
| - length: error.length,
|
| - message: error.message,
|
| - correction: error.correction);
|
| - }
|
| -
|
| - /**
|
| - * Get the content based information about the given [source], maybe `null`
|
| - * if the information is not in the cache.
|
| - */
|
| - CacheSourceContent _getCacheSourceContent(Source source) {
|
| - CacheSourceContent content = _sourceContentMap[source];
|
| - if (content == null) {
|
| - String key = _getCacheSourceContentKey(source);
|
| - List<int> bytes = storage.get(key);
|
| - if (bytes == null) {
|
| - return null;
|
| - }
|
| - content = new CacheSourceContent.fromBuffer(bytes);
|
| - _sourceContentMap[source] = content;
|
| - }
|
| - return content;
|
| - }
|
| -
|
| - /**
|
| - * Return the key of the content based [source] information.
|
| - */
|
| - String _getCacheSourceContentKey(Source source) {
|
| - List<int> hash = _getSourceContentHash(source);
|
| - String hashStr = hex.encode(hash);
|
| - return '$hashStr.content';
|
| - }
|
| -
|
| - /**
|
| - * Return the [ErrorCode] of the given [error], throws if not found.
|
| - */
|
| - ErrorCode _getErrorCode(CacheAnalysisError error) {
|
| - String uniqueName = error.errorCodeUniqueName;
|
| - ErrorCode errorCode = ErrorCode.byUniqueName(uniqueName);
|
| - if (errorCode != null) {
|
| - return errorCode;
|
| - }
|
| - throw new StateError('Unable to find ErrorCode: $uniqueName');
|
| - }
|
| -
|
| - /**
|
| - * Get the bundle for the given key.
|
| - */
|
| - PackageBundle _getLibraryBundle(String key) {
|
| - PackageBundle bundle = _bundleMap[key];
|
| - if (bundle == null) {
|
| - List<int> bytes = storage.get(key);
|
| - if (bytes == null) {
|
| - return null;
|
| - }
|
| - bundle = new PackageBundle.fromBuffer(bytes);
|
| - if (bundle.majorVersion != PackageBundleAssembler.currentMajorVersion ||
|
| - bundle.minorVersion != PackageBundleAssembler.currentMinorVersion) {
|
| - return null;
|
| - }
|
| - _bundleMap[key] = bundle;
|
| - }
|
| - return bundle;
|
| - }
|
| -
|
| - /**
|
| - * Return the key of the bundle of the [librarySource].
|
| - */
|
| - String _getLibraryBundleKey(Source librarySource) {
|
| - List<int> hash = _getLibraryClosureHash(librarySource);
|
| - String hashStr = hex.encode(hash);
|
| - return '$hashStr.summary';
|
| - }
|
| -
|
| - /**
|
| - * Return the whole source closure of the library with the given
|
| - * [librarySource]. It includes defining units and parts of the library and
|
| - * of all its directly or indirectly imported or exported libraries.
|
| - */
|
| - List<Source> _getLibraryClosure(Source librarySource) {
|
| - return _libraryClosureMap.putIfAbsent(librarySource, () {
|
| - Set<Source> closureSet = new Set<Source>();
|
| - _appendLibraryClosure(closureSet, librarySource);
|
| - List<Source> closureList = closureSet.toList();
|
| - closureList.sort((a, b) => comparePaths(a.fullName, b.fullName));
|
| - return closureList;
|
| - });
|
| - }
|
| -
|
| - /**
|
| - * Return the [context]-specific hash of the closure of the library with
|
| - * the given [librarySource].
|
| - */
|
| - List<int> _getLibraryClosureHash(Source librarySource) {
|
| - return _libraryClosureHashMap.putIfAbsent(librarySource, () {
|
| - List<Source> closure = _getLibraryClosure(librarySource);
|
| - return _computeSaltedMD5OfBytes((ByteConversionSink byteSink) {
|
| - for (Source source in closure) {
|
| - List<int> sourceHash = _getSourceContentHash(source);
|
| - byteSink.add(sourceHash);
|
| - }
|
| - // When we sort closure sources for two libraries (A, B) we get exactly
|
| - // the same list of sources for both A and B. So, their hash is exactly
|
| - // the same. But we use it to store separate summary bundles for
|
| - // separate libraries. Ideally would be nice to group these libraries
|
| - // into a single summary bundle. But this would require delaying
|
| - // saving bundles until we know all of them.
|
| - // So, for now we make hashes for separate libraries unique be mixing
|
| - // in the library source again.
|
| - byteSink.add(_getSourceContentHash(librarySource));
|
| - });
|
| - });
|
| - }
|
| -
|
| - /**
|
| - * Compute a hash of the given [source] contents.
|
| - */
|
| - List<int> _getSourceContentHash(Source source) {
|
| - return _sourceContentHashMap.putIfAbsent(source, () {
|
| - String sourceText = source.contents.data;
|
| - List<int> sourceBytes = UTF8.encode(sourceText);
|
| - return md5.convert(sourceBytes).bytes;
|
| - });
|
| - }
|
| -
|
| - /**
|
| - * Return the key for errors in the [source] in the [librarySource].
|
| - */
|
| - String _getSourceErrorsKey(Source librarySource, Source source) {
|
| - List<int> hash = _computeSaltedMD5OfBytes((ByteConversionSink byteSink) {
|
| - byteSink.add(_getLibraryClosureHash(librarySource));
|
| - byteSink.add(_getSourceContentHash(source));
|
| - });
|
| - String hashStr = hex.encode(hash);
|
| - return '$hashStr.errorsInLibrary';
|
| - }
|
| -
|
| - /**
|
| - * Return a source representing the URI that results from resolving the given
|
| - * (possibly relative) [containedUri] against the URI associated with the
|
| - * [containingSource], whether or not the resulting source exists, or `null`
|
| - * if either the [containedUri] is invalid or if it cannot be resolved against
|
| - * the [containingSource]'s URI.
|
| - */
|
| - Source _resolveUri(Source containingSource, String containedUri) {
|
| - // Cache absolute URIs.
|
| - if (containedUri.startsWith('dart:') ||
|
| - containedUri.startsWith('package:')) {
|
| - return _absoluteUriMap.putIfAbsent(containedUri, () {
|
| - return context.sourceFactory.resolveUri(containingSource, containedUri);
|
| - });
|
| - }
|
| - // Resolve relative URIs without caching.
|
| - return context.sourceFactory.resolveUri(containingSource, containedUri);
|
| - }
|
| -
|
| - /**
|
| - * Write the content based information about the given [source].
|
| - */
|
| - void _writeCacheSourceContent(Source source, CacheSourceContentBuilder b) {
|
| - if (!_sourceContentMap.containsKey(source)) {
|
| - String key = _getCacheSourceContentKey(source);
|
| - List<int> bytes = b.toBuffer();
|
| - storage.put(key, bytes);
|
| - // Put into the cache to avoid reading it later.
|
| - _sourceContentMap[source] = new CacheSourceContent.fromBuffer(bytes);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Write [CacheSourceContent] for every unit of the given [library] and its
|
| - * direct and indirect imports/exports.
|
| - */
|
| - void _writeCacheSourceContents(LibraryElement library,
|
| - [Set<LibraryElement> writtenLibraries]) {
|
| - Source librarySource = library.source;
|
| - // Stop recursion cycle.
|
| - writtenLibraries ??= new Set<LibraryElement>();
|
| - if (!writtenLibraries.add(library)) {
|
| - return;
|
| - }
|
| - // Write parts.
|
| - List<String> partUris = <String>[];
|
| - for (CompilationUnitElement part in library.parts) {
|
| - partUris.add(part.uri);
|
| - Source partSource = part.source;
|
| - if (context.getKindOf(partSource) == SourceKind.PART) {
|
| - _writeCacheSourceContent(partSource,
|
| - new CacheSourceContentBuilder(kind: CacheSourceKind.part));
|
| - }
|
| - }
|
| - // Write imports.
|
| - List<String> importUris = <String>[];
|
| - for (ImportElement element in library.imports) {
|
| - String uri = element.uri;
|
| - if (uri != null) {
|
| - importUris.add(uri);
|
| - _writeCacheSourceContents(element.importedLibrary, writtenLibraries);
|
| - }
|
| - }
|
| - // Write exports.
|
| - List<String> exportUris = <String>[];
|
| - for (ExportElement element in library.exports) {
|
| - String uri = element.uri;
|
| - if (uri != null) {
|
| - exportUris.add(uri);
|
| - _writeCacheSourceContents(element.exportedLibrary, writtenLibraries);
|
| - }
|
| - }
|
| - // Write the library.
|
| - _writeCacheSourceContent(
|
| - librarySource,
|
| - new CacheSourceContentBuilder(
|
| - kind: CacheSourceKind.library,
|
| - importedUris: importUris,
|
| - exportedUris: exportUris,
|
| - partUris: partUris));
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * The bundle for a source in the context.
|
| - */
|
| -class LibraryBundleWithId {
|
| - /**
|
| - * The source of the library this bundle is for.
|
| - */
|
| - final Source source;
|
| -
|
| - /**
|
| - * The unique ID of the [bundle] of the [source] in the context.
|
| - */
|
| - final String id;
|
| -
|
| - /**
|
| - * The payload bundle.
|
| - */
|
| - final PackageBundle bundle;
|
| -
|
| - LibraryBundleWithId(this.source, this.id, this.bundle);
|
| -}
|
|
|