Changes to bazel worker to support modular testing.

This includes:
 * accepting null values like sdk-summary or .packages (which are not used when building kernel for the sdk itself)
 * allow enabling language experiments
 * only exclude-non-sources on the non-incremental code path if that's requested

Change-Id: I08eeb643676f1f1406f0f3030c341d68179d42a2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/103574
Reviewed-by: Nate Bosch <nbosch@google.com>
This commit is contained in:
Sigmund Cherem 2019-05-24 19:09:12 +00:00 committed by commit-bot@chromium.org
parent fc6954f084
commit 64ed4bf664
5 changed files with 72 additions and 64 deletions

View file

@ -11,10 +11,13 @@ import 'package:kernel/kernel.dart' show Component, CanonicalName;
import 'package:kernel/target/targets.dart' show Target;
import '../api_prototype/compiler_options.dart' show CompilerOptions;
import '../api_prototype/compiler_options.dart'
show CompilerOptions, parseExperimentalFlags;
import '../api_prototype/diagnostic_message.dart' show DiagnosticMessageHandler;
import '../api_prototype/experimental_flags.dart' show ExperimentalFlag;
import '../api_prototype/file_system.dart' show FileSystem;
import '../base/processed_options.dart' show ProcessedOptions;
@ -41,6 +44,8 @@ export '../fasta/severity.dart' show Severity;
export 'compiler_state.dart' show InitializedCompilerState;
import 'util.dart' show equalMaps;
/// Initializes the compiler for a modular build.
///
/// Re-uses cached components from [_workerInputCache], and reloads them
@ -54,6 +59,7 @@ Future<InitializedCompilerState> initializeIncrementalCompiler(
Map<Uri, List<int>> workerInputDigests,
Target target,
FileSystem fileSystem,
Iterable<String> experiments,
bool outlineOnly) async {
final List<int> sdkDigest = workerInputDigests[sdkSummary];
if (sdkDigest == null) {
@ -66,10 +72,13 @@ Future<InitializedCompilerState> initializeIncrementalCompiler(
Map<Uri, WorkerInputComponent> workerInputCache =
oldState?.workerInputCache ?? new Map<Uri, WorkerInputComponent>();
bool startOver = false;
Map<ExperimentalFlag, bool> experimentalFlags =
parseExperimentalFlags(experiments, (e) => throw e);
if (oldState == null ||
oldState.incrementalCompiler == null ||
oldState.incrementalCompiler.outlineOnly != outlineOnly) {
oldState.incrementalCompiler.outlineOnly != outlineOnly ||
!equalMaps(oldState.options.experimentalFlags, experimentalFlags)) {
// No - or immediately not correct - previous state.
startOver = true;
@ -184,7 +193,8 @@ Future<InitializedCompilerState> initializeCompiler(
List<Uri> summaryInputs,
List<Uri> linkedInputs,
Target target,
FileSystem fileSystem) async {
FileSystem fileSystem,
Iterable<String> experiments) async {
// TODO(sigmund): use incremental compiler when it supports our use case.
// Note: it is common for the summary worker to invoke the compiler with the
// same input summary URIs, but with different contents, so we'd need to be
@ -198,7 +208,8 @@ Future<InitializedCompilerState> initializeCompiler(
..linkedDependencies = linkedInputs
..target = target
..fileSystem = fileSystem
..environmentDefines = const {};
..environmentDefines = const {}
..experimentalFlags = parseExperimentalFlags(experiments, (e) => throw e);
ProcessedOptions processedOpts = new ProcessedOptions(options: options);

View file

@ -32,6 +32,8 @@ import '../fasta/scanner.dart' show ErrorToken, StringToken, Token;
import 'compiler_state.dart' show InitializedCompilerState;
import 'util.dart' show equalLists, equalMaps;
export '../api_prototype/compiler_options.dart'
show CompilerOptions, parseExperimentalFlags;
@ -116,30 +118,13 @@ InitializedCompilerState initializeCompiler(
Map<ExperimentalFlag, bool> experimentalFlags,
bool verify: false,
bool enableAsserts: false}) {
bool mapEqual(Map<ExperimentalFlag, bool> a, Map<ExperimentalFlag, bool> b) {
if (a == null || b == null) return a == b;
if (a.length != b.length) return false;
for (var flag in a.keys) {
if (!b.containsKey(flag) || a[flag] != b[flag]) return false;
}
return true;
}
bool listEqual(List<Uri> a, List<Uri> b) {
if (a.length != b.length) return false;
for (int i = 0; i < a.length; ++i) {
if (a[i] != b[i]) return false;
}
return true;
}
linkedDependencies.sort((a, b) => a.toString().compareTo(b.toString()));
if (oldState != null &&
oldState.options.packagesFileUri == packagesFileUri &&
oldState.options.librariesSpecificationUri == librariesSpecificationUri &&
listEqual(oldState.options.linkedDependencies, linkedDependencies) &&
mapEqual(oldState.options.experimentalFlags, experimentalFlags)) {
equalLists(oldState.options.linkedDependencies, linkedDependencies) &&
equalMaps(oldState.options.experimentalFlags, experimentalFlags)) {
return oldState;
}

View file

@ -29,6 +29,8 @@ import '../kernel_generator_impl.dart' show generateKernel;
import 'compiler_state.dart'
show InitializedCompilerState, WorkerInputComponent, digestsEqual;
import 'util.dart' show equalLists, equalMaps;
export '../api_prototype/compiler_options.dart' show CompilerOptions;
export '../api_prototype/diagnostic_message.dart' show DiagnosticMessage;
@ -79,29 +81,13 @@ Future<InitializedCompilerState> initializeCompiler(
{FileSystem fileSystem,
Map<ExperimentalFlag, bool> experiments}) async {
inputSummaries.sort((a, b) => a.toString().compareTo(b.toString()));
bool listEqual(List<Uri> a, List<Uri> b) {
if (a.length != b.length) return false;
for (int i = 0; i < a.length; ++i) {
if (a[i] != b[i]) return false;
}
return true;
}
bool mapEqual(Map<ExperimentalFlag, bool> a, Map<ExperimentalFlag, bool> b) {
if (a == null || b == null) return a == b;
if (a.length != b.length) return false;
for (var flag in a.keys) {
if (!b.containsKey(flag) || a[flag] != b[flag]) return false;
}
return true;
}
if (oldState != null &&
oldState.options.sdkSummary == sdkSummary &&
oldState.options.packagesFileUri == packagesFile &&
oldState.options.librariesSpecificationUri == librariesSpecificationUri &&
listEqual(oldState.options.inputSummaries, inputSummaries) &&
mapEqual(oldState.options.experimentalFlags, experiments)) {
equalLists(oldState.options.inputSummaries, inputSummaries) &&
equalMaps(oldState.options.experimentalFlags, experiments)) {
// Reuse old state.
// These libraries are marked external when compiling. If not un-marking

View file

@ -0,0 +1,23 @@
// 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.
bool equalLists<T>(List<T> a, List<T> b) {
if (identical(a, b)) return true;
if (a == null || b == null) return false;
if (a.length != b.length) return false;
for (int i = 0; i < a.length; ++i) {
if (a[i] != b[i]) return false;
}
return true;
}
bool equalMaps<K, V>(Map<K, V> a, Map<K, V> b) {
if (identical(a, b)) return true;
if (a == null || b == null) return false;
if (a.length != b.length) return false;
for (K key in a.keys) {
if (!b.containsKey(key) || a[key] != b[key]) return false;
}
return true;
}

View file

@ -128,7 +128,9 @@ final summaryArgsParser = new ArgParser()
..addOption('output')
..addFlag('reuse-compiler-result', defaultsTo: false)
..addFlag('use-incremental-compiler', defaultsTo: false)
..addFlag('track-widget-creation', defaultsTo: false);
..addFlag('track-widget-creation', defaultsTo: false)
..addMultiOption('enable-experiment',
help: 'Enable a language experiment when invoking the CFE.');
class ComputeKernelResult {
final bool succeeded;
@ -167,8 +169,7 @@ Future<ComputeKernelResult> computeKernel(List<String> args,
if (multiRoots.isEmpty) multiRoots.add(Uri.base);
var fileSystem = new MultiRootFileSystem(parsedArgs['multi-root-scheme'],
multiRoots, fe.StandardFileSystem.instance);
var sources =
(parsedArgs['source'] as List<String>).map(Uri.base.resolve).toList();
var sources = (parsedArgs['source'] as List<String>).map(_toUri).toList();
var excludeNonSources = parsedArgs['exclude-non-sources'] as bool;
var summaryOnly = parsedArgs['summary-only'] as bool;
@ -222,19 +223,11 @@ Future<ComputeKernelResult> computeKernel(List<String> args,
out.writeln('error: unsupported target: $targetName');
}
// TODO(sigmund,jakemac): make it mandatory. We allow null while we migrate
// existing clients of this tool.
var librariesSpec = parsedArgs['libraries-file'] == null
? null
: Uri.base.resolve(parsedArgs['libraries-file']);
List<Uri> linkedInputs =
(parsedArgs['input-linked'] as List<String>).map(_toUri).toList();
List<Uri> linkedInputs = (parsedArgs['input-linked'] as List<String>)
.map(Uri.base.resolve)
.toList();
List<Uri> summaryInputs = (parsedArgs['input-summary'] as List<String>)
.map(Uri.base.resolve)
.toList();
List<Uri> summaryInputs =
(parsedArgs['input-summary'] as List<String>).map(_toUri).toList();
fe.InitializedCompilerState state;
bool usingIncrementalCompiler = false;
@ -253,27 +246,30 @@ Future<ComputeKernelResult> computeKernel(List<String> args,
inputDigests[uri] = input.digest;
}
// TODO(sigmund): add support for experiments with the incremental compiler.
state = await fe.initializeIncrementalCompiler(
previousState,
Uri.base.resolve(parsedArgs['dart-sdk-summary']),
Uri.base.resolve(parsedArgs['packages-file']),
librariesSpec,
_toUri(parsedArgs['dart-sdk-summary']),
_toUri(parsedArgs['packages-file']),
_toUri(parsedArgs['libraries-file']),
summaryInputs,
inputDigests,
target,
fileSystem,
(parsedArgs['enable-experiment'] as List<String>),
summaryOnly);
} else {
state = await fe.initializeCompiler(
// TODO(sigmund): pass an old state once we can make use of it.
null,
Uri.base.resolve(parsedArgs['dart-sdk-summary']),
librariesSpec,
Uri.base.resolve(parsedArgs['packages-file']),
_toUri(parsedArgs['dart-sdk-summary']),
_toUri(parsedArgs['libraries-file']),
_toUri(parsedArgs['packages-file']),
summaryInputs,
linkedInputs,
target,
fileSystem);
fileSystem,
(parsedArgs['enable-experiment'] as List<String>));
}
void onDiagnostic(fe.DiagnosticMessage message) {
@ -308,7 +304,9 @@ Future<ComputeKernelResult> computeKernel(List<String> args,
Component component =
await fe.compileComponent(state, sources, onDiagnostic);
kernel = fe.serializeComponent(component,
filter: (library) => sources.contains(library.importUri),
filter: excludeNonSources
? (library) => sources.contains(library.importUri)
: null,
includeOffsets: true);
}
@ -365,3 +363,8 @@ class DevCompilerSummaryTarget extends DevCompilerTarget {
}
}
}
Uri _toUri(String uriString) {
if (uriString == null) return null;
return Uri.base.resolve(uriString);
}