| // Copyright (c) 2019, 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. | |
| /// An implementation of [Pipeline] that runs in-memory. | |
| /// | |
| /// Kept alongside `test/memory_pipeline_test.dart` so this general-purpose | |
| /// modular framework continues to support in-memory execution and keeps the | |
| /// shared [Pipeline] abstractions free of `dart:io` dependencies. | |
| /// | |
| /// To define a step, implement [MemoryModularStep]. | |
| library; | |
| import 'pipeline.dart'; | |
| import 'suite.dart'; | |
| /// A hook to fetch data previously computed for a dependency. | |
| typedef ModuleDataProvider = Object? Function(Module, DataId); | |
| typedef SourceProvider = String? Function(Uri); | |
| abstract class MemoryModularStep extends ModularStep { | |
| Future<Map<DataId, Object>> execute( | |
| Module module, | |
| SourceProvider sourceProvider, | |
| ModuleDataProvider dataProvider, | |
| List<String> flags, | |
| ); | |
| } | |
| class MemoryPipeline extends Pipeline<MemoryModularStep> { | |
| final Map<Uri, String> _sources; | |
| /// Internal state to hold the current results as they are computed by the | |
| /// pipeline. Expected to be null before and after the pipeline runs. | |
| Map<Module, Map<DataId, Object>>? _results; | |
| /// A copy of [_result] at the time the pipeline last finished running. | |
| Map<Module, Map<DataId, Object>>? resultsForTesting; | |
| final ConfigurationRegistry? _registry; | |
| /// Cache of results when [cacheSharedModules] is true | |
| final List<Map<Module, Map<DataId, Object>>> _resultCache; | |
| MemoryPipeline( | |
| this._sources, | |
| List<MemoryModularStep> steps, { | |
| bool cacheSharedModules = false, | |
| }) : _registry = cacheSharedModules ? ConfigurationRegistry() : null, | |
| _resultCache = cacheSharedModules ? [] : const [], | |
| super(steps, cacheSharedModules); | |
| @override | |
| Future<void> run(ModularTest test) async { | |
| var results = _results = {}; | |
| Map<Module, Map<DataId, Object>>? cache; | |
| if (cacheSharedModules) { | |
| int id = _registry!.computeConfigurationId(test); | |
| if (id < _resultCache.length) { | |
| cache = _resultCache[id]; | |
| } else { | |
| assert(id == _resultCache.length); | |
| _resultCache.add(cache = {}); | |
| } | |
| results.addAll(cache); | |
| } | |
| await super.run(test); | |
| resultsForTesting = results; | |
| if (cacheSharedModules) { | |
| for (var module in results.keys) { | |
| if (module.isShared) { | |
| cache![module] = results[module]!; | |
| } | |
| } | |
| } | |
| _results = null; | |
| } | |
| @override | |
| Future<void> runStep( | |
| MemoryModularStep step, | |
| Module module, | |
| Map<Module, Set<DataId>> visibleData, | |
| List<String> flags, | |
| ) async { | |
| final results = _results!; | |
| if (cacheSharedModules && module.isShared) { | |
| bool allCachedResultsFound = true; | |
| for (var dataId in step.resultData) { | |
| if (results[module] == null || results[module]![dataId] == null) { | |
| allCachedResultsFound = false; | |
| break; | |
| } | |
| } | |
| if (allCachedResultsFound) { | |
| step.notifyCached(module); | |
| return; | |
| } | |
| } | |
| Map<Module, Map<DataId, Object>> inputData = {}; | |
| visibleData.forEach((module, dataIdSet) { | |
| inputData[module] = {}; | |
| for (var dataId in dataIdSet) { | |
| inputData[module]![dataId] = results[module]![dataId]!; | |
| } | |
| }); | |
| Map<Uri, String> inputSources = {}; | |
| if (step.needsSources) { | |
| for (var relativeUri in module.sources) { | |
| var uri = module.rootUri.resolveUri(relativeUri); | |
| inputSources[uri] = _sources[uri]!; | |
| } | |
| } | |
| Map<DataId, Object> result = await step.execute( | |
| module, | |
| (Uri uri) => inputSources[uri], | |
| (Module m, DataId id) => inputData[m]![id], | |
| flags, | |
| ); | |
| for (var dataId in step.resultData) { | |
| (results[module] ??= {})[dataId] = result[dataId]!; | |
| } | |
| } | |
| } |