Skip to content

Commit 981be87

Browse files
munificentcommit-bot@chromium.org
authored andcommitted
Add configuration options and flags for controlling NNBD mode.
This data is parsed by configurations and allowed as command-line options to the test runner, but isn't currently plumbed through to any of the tools. That's the next step. Change-Id: I7931a11502a1c460e28b2a4a13d8722d8ad6974d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/115767 Commit-Queue: Bob Nystrom <[email protected]> Auto-Submit: Bob Nystrom <[email protected]> Reviewed-by: Mayank Patke <[email protected]>
1 parent 9ff104e commit 981be87

File tree

6 files changed

+265
-134
lines changed

6 files changed

+265
-134
lines changed

pkg/smith/lib/configuration.dart

Lines changed: 116 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,12 @@ class Configuration {
212212
var mode = enumOption("mode", Mode.names, Mode.find);
213213
var runtime = enumOption("runtime", Runtime.names, Runtime.find);
214214
var system = enumOption("system", System.names, System.find);
215+
var nnbdMode = enumOption("nnbd", NnbdMode.names, NnbdMode.find);
215216

216217
// Fill in any missing values using defaults when possible.
217218
architecture ??= Architecture.x64;
218219
system ??= System.host;
220+
nnbdMode ??= NnbdMode.legacy;
219221

220222
// Infer from compiler from runtime or vice versa.
221223
if (compiler == null) {
@@ -239,10 +241,12 @@ class Configuration {
239241

240242
var configuration = Configuration(
241243
name, architecture, compiler, mode, runtime, system,
244+
nnbdMode: nnbdMode,
242245
babel: stringOption("babel"),
243246
builderTag: stringOption("builder-tag"),
244247
vmOptions: stringListOption("vm-options"),
245248
dart2jsOptions: stringListOption("dart2js-options"),
249+
experiments: stringListOption("experiments"),
246250
timeout: intOption("timeout"),
247251
enableAsserts: boolOption("enable-asserts"),
248252
isChecked: boolOption("checked"),
@@ -277,6 +281,9 @@ class Configuration {
277281

278282
final System system;
279283

284+
/// Which NNBD mode to run the test files under.
285+
final NnbdMode nnbdMode;
286+
280287
final String babel;
281288

282289
final String builderTag;
@@ -285,6 +292,17 @@ class Configuration {
285292

286293
final List<String> dart2jsOptions;
287294

295+
/// The names of the experiments to enable while running tests.
296+
///
297+
/// A test may *require* an experiment to always be enabled by containing a
298+
/// comment like:
299+
///
300+
/// // SharedOptions=--enable-experiment=extension-methods
301+
///
302+
/// Enabling an experiment here in the configuration allows running the same
303+
/// test both with an experiment on and off.
304+
final List<String> experiments;
305+
288306
final int timeout;
289307

290308
final bool enableAsserts;
@@ -314,10 +332,12 @@ class Configuration {
314332

315333
Configuration(this.name, this.architecture, this.compiler, this.mode,
316334
this.runtime, this.system,
317-
{String babel,
335+
{NnbdMode nnbdMode,
336+
String babel,
318337
String builderTag,
319338
List<String> vmOptions,
320339
List<String> dart2jsOptions,
340+
List<String> experiments,
321341
int timeout,
322342
bool enableAsserts,
323343
bool isChecked,
@@ -331,10 +351,12 @@ class Configuration {
331351
bool useHotReload,
332352
bool useHotReloadRollback,
333353
bool useSdk})
334-
: babel = babel ?? "",
354+
: nnbdMode = nnbdMode ?? NnbdMode.legacy,
355+
babel = babel ?? "",
335356
builderTag = builderTag ?? "",
336357
vmOptions = vmOptions ?? <String>[],
337358
dart2jsOptions = dart2jsOptions ?? <String>[],
359+
experiments = experiments ?? <String>[],
338360
timeout = timeout ?? -1,
339361
enableAsserts = enableAsserts ?? false,
340362
isChecked = isChecked ?? false,
@@ -357,10 +379,12 @@ class Configuration {
357379
mode == other.mode &&
358380
runtime == other.runtime &&
359381
system == other.system &&
382+
nnbdMode == other.nnbdMode &&
360383
babel == other.babel &&
361384
builderTag == other.builderTag &&
362-
vmOptions.join(" & ") == other.vmOptions.join(" & ") &&
363-
dart2jsOptions.join(" & ") == other.dart2jsOptions.join(" & ") &&
385+
_listsEqual(vmOptions, other.vmOptions) &&
386+
_listsEqual(dart2jsOptions, other.dart2jsOptions) &&
387+
_listsEqual(experiments, other.experiments) &&
364388
timeout == other.timeout &&
365389
enableAsserts == other.enableAsserts &&
366390
isChecked == other.isChecked &&
@@ -375,6 +399,20 @@ class Configuration {
375399
useHotReloadRollback == other.useHotReloadRollback &&
376400
useSdk == other.useSdk;
377401

402+
/// Whether [a] and [b] contain the same strings, regardless of order.
403+
bool _listsEqual(List<String> a, List<String> b) {
404+
if (a.length != b.length) return false;
405+
406+
// Using sorted lists instead of sets in case there are duplicate strings
407+
// in the lists. ["a"] should not be considered equal to ["a", "a"].
408+
var aSorted = a.toList()..sort();
409+
var bSorted = b.toList()..sort();
410+
for (var i = 0; i < aSorted.length; i++) {
411+
if (aSorted[i] != bSorted[i]) return false;
412+
}
413+
return true;
414+
}
415+
378416
bool operator ==(Object other) =>
379417
other is Configuration && name == other.name && optionsEqual(other);
380418

@@ -388,10 +426,12 @@ class Configuration {
388426
mode.hashCode ^
389427
runtime.hashCode ^
390428
system.hashCode ^
429+
nnbdMode.hashCode ^
391430
babel.hashCode ^
392431
builderTag.hashCode ^
393432
vmOptions.join(" & ").hashCode ^
394433
dart2jsOptions.join(" & ").hashCode ^
434+
experiments.join(" & ").hashCode ^
395435
timeout.hashCode ^
396436
_toBinary([
397437
enableAsserts,
@@ -420,12 +460,18 @@ class Configuration {
420460
fields.add("runtime: $runtime");
421461
fields.add("system: $system");
422462

463+
if (nnbdMode != NnbdMode.legacy) fields.add("nnbd: $nnbdMode");
464+
465+
stringListField(String name, List<String> field) {
466+
if (field.isEmpty) return;
467+
fields.add("$name: [${field.join(", ")}]");
468+
}
469+
423470
if (babel.isNotEmpty) fields.add("babel: $babel");
424471
if (builderTag.isNotEmpty) fields.add("builder-tag: $builderTag");
425-
if (vmOptions.isNotEmpty)
426-
fields.add("vm-options: [${vmOptions.join(", ")}]");
427-
if (dart2jsOptions.isNotEmpty)
428-
fields.add("dart2js-options: [${dart2jsOptions.join(", ")}]");
472+
stringListField("vm-options", vmOptions);
473+
stringListField("dart2js-options", dart2jsOptions);
474+
stringListField("experiments", experiments);
429475
if (timeout > 0) fields.add("timeout: $timeout");
430476
if (enableAsserts) fields.add("enable-asserts");
431477
if (isChecked) fields.add("checked");
@@ -456,65 +502,44 @@ class Configuration {
456502
fields.add("runtime: $runtime ${other.runtime}");
457503
fields.add("system: $system ${other.system}");
458504

459-
if (babel.isNotEmpty || other.babel.isNotEmpty) {
460-
var ours = babel == "" ? "(none)" : babel;
461-
var theirs = other.babel == "" ? "(none)" : other.babel;
462-
fields.add("babel: $ours $theirs");
463-
}
464-
if (builderTag.isNotEmpty || other.builderTag.isNotEmpty) {
465-
var ours = builderTag == "" ? "(none)" : builderTag;
466-
var theirs = other.builderTag == "" ? "(none)" : other.builderTag;
467-
fields.add("builder-tag: $ours $theirs");
505+
stringField(String name, String value, String otherValue) {
506+
if (value.isEmpty && otherValue.isEmpty) return;
507+
var ours = value.isEmpty ? "(none)" : value;
508+
var theirs = otherValue.isEmpty ? "(none)" : otherValue;
509+
fields.add("$name: $ours $theirs");
468510
}
469-
if (vmOptions.isNotEmpty || other.vmOptions.isNotEmpty) {
470-
var ours = "[${vmOptions.join(", ")}]";
471-
var theirs = "[${other.vmOptions.join(", ")}]";
472-
fields.add("vm-options: $ours $theirs");
511+
512+
stringListField(String name, List<String> value, List<String> otherValue) {
513+
if (value.isEmpty && otherValue.isEmpty) return;
514+
fields.add("$name: [${value.join(', ')}] [${otherValue.join(', ')}]");
473515
}
474-
if (dart2jsOptions.isNotEmpty || other.dart2jsOptions.isNotEmpty) {
475-
var ours = "[${dart2jsOptions.join(", ")}]";
476-
var theirs = "[${other.dart2jsOptions.join(", ")}]";
477-
fields.add("dart2js-options: $ours $theirs");
516+
517+
boolField(String name, bool value, bool otherValue) {
518+
if (!value && !otherValue) return;
519+
fields.add("$name: $value $otherValue");
478520
}
521+
522+
fields.add("nnbd: $nnbdMode ${other.nnbdMode}");
523+
stringField("babel", babel, other.babel);
524+
stringField("builder-tag", builderTag, other.builderTag);
525+
stringListField("vm-options", vmOptions, other.vmOptions);
526+
stringListField("dart2js-options", dart2jsOptions, other.dart2jsOptions);
527+
stringListField("experiments", experiments, other.experiments);
479528
fields.add("timeout: $timeout ${other.timeout}");
480-
if (enableAsserts || other.enableAsserts) {
481-
fields.add("enable-asserts $enableAsserts ${other.enableAsserts}");
482-
}
483-
if (isChecked || other.isChecked) {
484-
fields.add("checked $isChecked ${other.isChecked}");
485-
}
486-
if (isCsp || other.isCsp) {
487-
fields.add("csp $isCsp ${other.isCsp}");
488-
}
489-
if (isHostChecked || other.isHostChecked) {
490-
fields.add("isHostChecked $isHostChecked ${other.isHostChecked}");
491-
}
492-
if (isMinified || other.isMinified) {
493-
fields.add("isMinified $isMinified ${other.isMinified}");
494-
}
495-
if (useAnalyzerCfe || other.useAnalyzerCfe) {
496-
fields.add("useAnalyzerCfe $useAnalyzerCfe ${other.useAnalyzerCfe}");
497-
}
498-
if (useAnalyzerFastaParser || other.useAnalyzerFastaParser) {
499-
fields.add("useAnalyzerFastaParser "
500-
"$useAnalyzerFastaParser ${other.useAnalyzerFastaParser}");
501-
}
502-
if (useBlobs || other.useBlobs) {
503-
fields.add("useBlobs $useBlobs ${other.useBlobs}");
504-
}
505-
if (useHotReload || other.useHotReload) {
506-
fields.add("useHotReload $useHotReload ${other.useHotReload}");
507-
}
508-
if (isHostChecked) {
509-
fields.add("host-checked $isHostChecked ${other.isHostChecked}");
510-
}
511-
if (useHotReloadRollback || other.useHotReloadRollback) {
512-
fields.add("useHotReloadRollback"
513-
" $useHotReloadRollback ${other.useHotReloadRollback}");
514-
}
515-
if (useSdk || other.useSdk) {
516-
fields.add("useSdk $useSdk ${other.useSdk}");
517-
}
529+
boolField("enable-asserts", enableAsserts, other.enableAsserts);
530+
boolField("checked", isChecked, other.isChecked);
531+
boolField("csp", isCsp, other.isCsp);
532+
boolField("host-checked", isHostChecked, other.isHostChecked);
533+
boolField("minified", isMinified, other.isMinified);
534+
boolField("use-cfe", useAnalyzerCfe, other.useAnalyzerCfe);
535+
boolField("analyzer-use-fasta-parser", useAnalyzerFastaParser,
536+
other.useAnalyzerFastaParser);
537+
boolField("use-blobs", useBlobs, other.useBlobs);
538+
boolField("host-checked", isHostChecked, other.isHostChecked);
539+
boolField("hot-reload", useHotReload, other.useHotReload);
540+
boolField("hot-reload-rollback", useHotReloadRollback,
541+
other.useHotReloadRollback);
542+
boolField("use-sdk", useSdk, other.useSdk);
518543

519544
buffer.write(fields.join("\n "));
520545
buffer.write("\n");
@@ -876,6 +901,34 @@ class System extends NamedEnum {
876901
}
877902
}
878903

904+
/// What level of non-nullability support should be applied to the test files.
905+
class NnbdMode extends NamedEnum {
906+
/// "Opted out" legacy mode with no NNBD features allowed.
907+
static const legacy = NnbdMode._('legacy');
908+
909+
/// Opted in to NNBD features, but only static checking and weak runtime
910+
/// checks.
911+
static const optedIn = NnbdMode._('opted-in');
912+
913+
/// Opted in to NNBD features and with full sound runtime checks.
914+
static const strong = NnbdMode._('strong');
915+
916+
static final List<String> names = _all.keys.toList();
917+
918+
static final _all = {
919+
for (var mode in [legacy, optedIn, strong]) mode.name: mode
920+
};
921+
922+
static NnbdMode find(String name) {
923+
var mode = _all[name];
924+
if (mode != null) return mode;
925+
926+
throw ArgumentError('Unknown NNBD mode "$name".');
927+
}
928+
929+
const NnbdMode._(String name) : super(name);
930+
}
931+
879932
/// Base class for an enum-like class whose values are identified by name.
880933
abstract class NamedEnum {
881934
final String name;

0 commit comments

Comments
 (0)