| Index: tools/testing/dart/configuration.dart
|
| diff --git a/tools/testing/dart/configuration.dart b/tools/testing/dart/configuration.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..2b41503b042d9955ad9f6503ff84fdc60bc64071
|
| --- /dev/null
|
| +++ b/tools/testing/dart/configuration.dart
|
| @@ -0,0 +1,741 @@
|
| +// Copyright (c) 2017, 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:async';
|
| +import 'dart:convert';
|
| +import 'dart:io';
|
| +
|
| +import 'compiler_configuration.dart';
|
| +import 'http_server.dart';
|
| +import 'path.dart';
|
| +import 'runtime_configuration.dart';
|
| +import 'test_suite.dart';
|
| +
|
| +/// All of the contextual information to determine how a test suite should be
|
| +/// run.
|
| +///
|
| +/// Includes the compiler used to compile the code, the runtime the result is
|
| +/// executed on, etc.
|
| +class Configuration {
|
| + Configuration(
|
| + {this.architecture,
|
| + this.compiler,
|
| + this.mode,
|
| + this.progress,
|
| + this.runtime,
|
| + this.system,
|
| + this.selectors,
|
| + this.appendLogs,
|
| + this.batch,
|
| + this.batchDart2JS,
|
| + this.copyCoreDumps,
|
| + this.hotReload,
|
| + this.hotReloadRollback,
|
| + this.isChecked,
|
| + this.isStrong,
|
| + this.isHostChecked,
|
| + this.isCsp,
|
| + this.isMinified,
|
| + this.isVerbose,
|
| + this.listTests,
|
| + this.printTiming,
|
| + this.printReport,
|
| + this.reportInJson,
|
| + this.resetBrowser,
|
| + this.skipCompilation,
|
| + this.useBlobs,
|
| + this.useSdk,
|
| + this.useFastStartup,
|
| + this.useDart2JSWithKernel,
|
| + this.writeDebugLog,
|
| + this.writeTestOutcomeLog,
|
| + this.drtPath,
|
| + this.dartiumPath,
|
| + this.chromePath,
|
| + this.safariPath,
|
| + this.firefoxPath,
|
| + this.dartPath,
|
| + this.dartPrecompiledPath,
|
| + this.flutterPath,
|
| + this.recordingPath,
|
| + this.replayPath,
|
| + this.taskCount,
|
| + int timeout,
|
| + this.shardCount,
|
| + this.shard,
|
| + this.stepName,
|
| + this.testServerPort,
|
| + this.testServerCrossOriginPort,
|
| + this.testDriverErrorPort,
|
| + this.localIP,
|
| + this.dart2jsOptions,
|
| + this.vmOptions,
|
| + String packages,
|
| + this.packageRoot,
|
| + this.suiteDirectory,
|
| + this.builderTag,
|
| + this.reproducingArguments})
|
| + : _packages = packages,
|
| + _timeout = timeout;
|
| +
|
| + final Architecture architecture;
|
| + final Compiler compiler;
|
| + final Mode mode;
|
| + final Progress progress;
|
| + final Runtime runtime;
|
| + final System system;
|
| +
|
| + final Map<String, RegExp> selectors;
|
| +
|
| + // Boolean flags.
|
| +
|
| + final bool appendLogs;
|
| + final bool batch;
|
| + final bool batchDart2JS;
|
| + final bool copyCoreDumps;
|
| + final bool hotReload;
|
| + final bool hotReloadRollback;
|
| + final bool isChecked;
|
| + final bool isStrong;
|
| + final bool isHostChecked;
|
| + final bool isCsp;
|
| + final bool isMinified;
|
| + final bool isVerbose;
|
| + final bool listTests;
|
| + final bool printTiming;
|
| + final bool printReport;
|
| + final bool reportInJson;
|
| + final bool resetBrowser;
|
| + final bool skipCompilation;
|
| + final bool useBlobs;
|
| + final bool useSdk;
|
| + final bool useFastStartup;
|
| + final bool useDart2JSWithKernel;
|
| + final bool writeDebugLog;
|
| + final bool writeTestOutcomeLog;
|
| +
|
| + // Various file paths.
|
| +
|
| + final String drtPath;
|
| + final String dartiumPath;
|
| + final String chromePath;
|
| + final String safariPath;
|
| + final String firefoxPath;
|
| + final String dartPath;
|
| + final String dartPrecompiledPath;
|
| + final String flutterPath;
|
| + final String recordingPath;
|
| + final String replayPath;
|
| +
|
| + final int taskCount;
|
| + final int shardCount;
|
| + final int shard;
|
| + final String stepName;
|
| +
|
| + final int testServerPort;
|
| + final int testServerCrossOriginPort;
|
| + final int testDriverErrorPort;
|
| + final String localIP;
|
| +
|
| + /// Extra dart2js options passed to the testing script.
|
| + final List<String> dart2jsOptions;
|
| +
|
| + /// Extra VM options passed to the testing script.
|
| + final List<String> vmOptions;
|
| +
|
| + String _packages;
|
| + String get packages {
|
| + // If the .packages file path wasn't given, find it.
|
| + if (packageRoot == null && _packages == null) {
|
| + _packages = TestUtils.dartDirUri.resolve('.packages').toFilePath();
|
| + }
|
| +
|
| + return _packages;
|
| + }
|
| +
|
| + final String packageRoot;
|
| + final String suiteDirectory;
|
| + final String builderTag;
|
| + final List<String> reproducingArguments;
|
| +
|
| + TestingServers _servers;
|
| + TestingServers get servers {
|
| + if (_servers == null) {
|
| + throw new StateError("Servers have not been started yet.");
|
| + }
|
| + return _servers;
|
| + }
|
| +
|
| + /// The base directory named for this configuration, like:
|
| + ///
|
| + /// none_vm_release_x64
|
| + String _configurationDirectory;
|
| + String get configurationDirectory {
|
| + // Lazy initialize and cache since it requires hitting the file system.
|
| + if (_configurationDirectory == null) {
|
| + _configurationDirectory = _calculateDirectory();
|
| + }
|
| +
|
| + return _configurationDirectory;
|
| + }
|
| +
|
| + /// The build directory path for this configuration, like:
|
| + ///
|
| + /// build/none_vm_release_x64
|
| + String get buildDirectory => system.outputDirectory + configurationDirectory;
|
| +
|
| + int _timeout;
|
| + int get timeout {
|
| + if (_timeout == null) {
|
| + var isReload = hotReload || hotReloadRollback;
|
| +
|
| + var compilerMulitiplier = compilerConfiguration.timeoutMultiplier;
|
| + var runtimeMultiplier = runtimeConfiguration.timeoutMultiplier(
|
| + mode: mode,
|
| + isChecked: isChecked,
|
| + isReload: isReload,
|
| + arch: architecture);
|
| +
|
| + _timeout = 60 * compilerMulitiplier * runtimeMultiplier;
|
| + }
|
| +
|
| + return _timeout;
|
| + }
|
| +
|
| + List<String> get standardOptions {
|
| + if (compiler != Compiler.dart2js) {
|
| + return const ["--ignore-unrecognized-flags"];
|
| + }
|
| +
|
| + var args = ['--generate-code-with-compile-time-errors', '--test-mode'];
|
| + if (isChecked) args.add('--enable-checked-mode');
|
| +
|
| + if (!runtime.isBrowser) {
|
| + args.add("--allow-mock-compilation");
|
| + args.add("--categories=all");
|
| + }
|
| +
|
| + if (isMinified) args.add("--minify");
|
| + if (isCsp) args.add("--csp");
|
| + if (useFastStartup) args.add("--fast-startup");
|
| + if (useDart2JSWithKernel) args.add("--use-kernel");
|
| + return args;
|
| + }
|
| +
|
| + String _windowsSdkPath;
|
| + String get windowsSdkPath {
|
| + if (!Platform.isWindows) {
|
| + throw new StateError(
|
| + "Should not use windowsSdkPath when not running on Windows.");
|
| + }
|
| +
|
| + if (_windowsSdkPath == null) {
|
| + // When running tests on Windows, use cdb from depot_tools to dump
|
| + // stack traces of tests timing out.
|
| + try {
|
| + var path = new Path("build/win_toolchain.json").toNativePath();
|
| + var text = new File(path).readAsStringSync();
|
| + _windowsSdkPath = JSON.decode(text)['win_sdk'] as String;
|
| + } on dynamic {
|
| + // Ignore errors here. If win_sdk is not found, stack trace dumping
|
| + // for timeouts won't work.
|
| + }
|
| + }
|
| +
|
| + return _windowsSdkPath;
|
| + }
|
| +
|
| + /// Gets the local file path to the browser executable for this configuration.
|
| + String get browserLocation {
|
| + // If the user has explicitly configured a browser path, use it.
|
| + String location;
|
| + switch (runtime) {
|
| + case Runtime.chrome:
|
| + location = chromePath;
|
| + break;
|
| + case Runtime.dartium:
|
| + location = dartiumPath;
|
| + break;
|
| + case Runtime.drt:
|
| + location = drtPath;
|
| + break;
|
| + case Runtime.firefox:
|
| + location = firefoxPath;
|
| + break;
|
| + case Runtime.flutter:
|
| + location = flutterPath;
|
| + break;
|
| + case Runtime.safari:
|
| + location = safariPath;
|
| + break;
|
| + }
|
| +
|
| + if (location != null) return location;
|
| +
|
| + const locations = const {
|
| + Runtime.firefox: const {
|
| + System.windows: 'C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe',
|
| + System.linux: 'firefox',
|
| + System.macos: '/Applications/Firefox.app/Contents/MacOS/firefox'
|
| + },
|
| + Runtime.chrome: const {
|
| + System.windows:
|
| + 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
|
| + System.macos:
|
| + '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
|
| + System.linux: 'google-chrome'
|
| + },
|
| + Runtime.dartium: const {
|
| + System.windows: 'client\\tests\\dartium\\chrome.exe',
|
| + System.macos:
|
| + 'client/tests/dartium/Chromium.app/Contents/MacOS/Chromium',
|
| + System.linux: 'client/tests/dartium/chrome'
|
| + },
|
| + Runtime.safari: const {
|
| + System.macos: '/Applications/Safari.app/Contents/MacOS/Safari'
|
| + },
|
| + Runtime.safariMobileSim: const {
|
| + System.macos: '/Applications/Xcode.app/Contents/Developer/Platforms/'
|
| + 'iPhoneSimulator.platform/Developer/Applications/'
|
| + 'iPhone Simulator.app/Contents/MacOS/iPhone Simulator'
|
| + },
|
| + Runtime.ie9: const {
|
| + System.windows: 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
|
| + },
|
| + Runtime.ie10: const {
|
| + System.windows: 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
|
| + },
|
| + Runtime.ie11: const {
|
| + System.windows: 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
|
| + }
|
| + };
|
| +
|
| + location = locations[runtime][System.find(Platform.operatingSystem)];
|
| +
|
| + if (location == null) {
|
| + throw "${runtime.name} is not supported on ${Platform.operatingSystem}";
|
| + }
|
| +
|
| + return location;
|
| + }
|
| +
|
| + RuntimeConfiguration _runtimeConfiguration;
|
| + RuntimeConfiguration get runtimeConfiguration =>
|
| + _runtimeConfiguration ??= new RuntimeConfiguration(this);
|
| +
|
| + CompilerConfiguration _compilerConfiguration;
|
| + CompilerConfiguration get compilerConfiguration =>
|
| + _compilerConfiguration ??= new CompilerConfiguration(this);
|
| +
|
| + /// Determines if this configuration has a compatible compiler and runtime
|
| + /// and other valid fields.
|
| + ///
|
| + /// Prints a warning if the configuration isn't valid. Returns whether or not
|
| + /// it is.
|
| + bool validate() {
|
| + var isValid = true;
|
| + var validRuntimes = compiler.supportedRuntimes;
|
| +
|
| + if (!validRuntimes.contains(runtime)) {
|
| + print("Warning: combination of compiler '${compiler.name}' and "
|
| + "runtime '${runtime.name}' is invalid. Skipping this combination.");
|
| + isValid = false;
|
| + }
|
| +
|
| + if (runtime.isIE && Platform.operatingSystem != 'windows') {
|
| + print("Warning: cannot run Internet Explorer on non-Windows operating"
|
| + " system.");
|
| + isValid = false;
|
| + }
|
| +
|
| + if (shard < 1 || shard > shardCount) {
|
| + print("Error: shard index is $shard out of $shardCount shards");
|
| + isValid = false;
|
| + }
|
| +
|
| + if (runtime == Runtime.flutter && flutterPath == null) {
|
| + print("-rflutter requires the flutter engine executable to "
|
| + "be specified using --flutter");
|
| + isValid = false;
|
| + }
|
| +
|
| + if (runtime == Runtime.flutter && architecture != Architecture.x64) {
|
| + isValid = false;
|
| + print("-rflutter is applicable only for --arch=x64");
|
| + }
|
| +
|
| + return isValid;
|
| + }
|
| +
|
| + /// Starts global HTTP servers that serve the entire dart repo.
|
| + ///
|
| + /// The HTTP server is available on `window.location.port`, and a second
|
| + /// server for cross-domain tests can be found by calling
|
| + /// `getCrossOriginPortNumber()`.
|
| + Future startServers() {
|
| + _servers = new TestingServers(
|
| + buildDirectory, isCsp, runtime, null, packageRoot, packages);
|
| + var future = servers.startServers(localIP,
|
| + port: testServerPort, crossOriginPort: testServerCrossOriginPort);
|
| +
|
| + if (isVerbose) {
|
| + future = future.then((_) {
|
| + print('Started HttpServers: ${servers.httpServerCommandLine()}');
|
| + });
|
| + }
|
| +
|
| + return future;
|
| + }
|
| +
|
| + void stopServers() {
|
| + if (_servers != null) _servers.stopServers();
|
| + }
|
| +
|
| + /// Returns the correct configuration directory (the last component of the
|
| + /// output directory path) for regular dart checkouts.
|
| + ///
|
| + /// Dartium checkouts use the `--build-directory` option to pass in the
|
| + /// correct build directory explicitly. We allow our code to have been cross
|
| + /// compiled, i.e., that there is an X in front of the arch. We don't allow
|
| + /// both a cross compiled and a normal version to be present (except if you
|
| + /// specifically pass in the build_directory).
|
| + String _calculateDirectory() {
|
| + // Capitalize the mode name.
|
| + var modeName =
|
| + mode.name.substring(0, 1).toUpperCase() + mode.name.substring(1);
|
| +
|
| + var os = '';
|
| + if (system == System.android) os = "Android";
|
| +
|
| + var arch = architecture.name.toUpperCase();
|
| + var normal = '$modeName$os$arch';
|
| + var cross = '$modeName${os}X$arch';
|
| + var outDir = system.outputDirectory;
|
| + var normalDir = new Directory(new Path('$outDir$normal').toNativePath());
|
| + var crossDir = new Directory(new Path('$outDir$cross').toNativePath());
|
| +
|
| + if (normalDir.existsSync() && crossDir.existsSync()) {
|
| + throw "You can't have both $normalDir and $crossDir. We don't know which"
|
| + " binary to use.";
|
| + }
|
| +
|
| + if (crossDir.existsSync()) return cross;
|
| +
|
| + return normal;
|
| + }
|
| +}
|
| +
|
| +class Architecture {
|
| + static const ia32 = const Architecture._('ia32');
|
| + static const x64 = const Architecture._('x64');
|
| + static const arm = const Architecture._('arm');
|
| + static const armv6 = const Architecture._('armv6');
|
| + static const armv5te = const Architecture._('armv5te');
|
| + static const arm64 = const Architecture._('arm64');
|
| + static const simarm = const Architecture._('simarm');
|
| + static const simarmv6 = const Architecture._('simarmv6');
|
| + static const simarmv5te = const Architecture._('simarmv5te');
|
| + static const simarm64 = const Architecture._('simarm64');
|
| + static const mips = const Architecture._('mips');
|
| + static const simmips = const Architecture._('simmips');
|
| + static const simdbc = const Architecture._('simdbc');
|
| + static const simdbc64 = const Architecture._('simdbc64');
|
| +
|
| + static final List<String> names = _all.keys.toList();
|
| +
|
| + static final _all = new Map<String, Architecture>.fromIterable([
|
| + ia32,
|
| + x64,
|
| + arm,
|
| + armv6,
|
| + armv5te,
|
| + arm64,
|
| + simarm,
|
| + simarmv6,
|
| + simarmv5te,
|
| + simarm64,
|
| + mips,
|
| + simmips,
|
| + simdbc,
|
| + simdbc64
|
| + ], key: (Architecture architecture) => architecture.name);
|
| +
|
| + static Architecture find(String name) {
|
| + var architecture = _all[name];
|
| + if (architecture != null) return architecture;
|
| +
|
| + throw new ArgumentError('Unknown architecture "$name".');
|
| + }
|
| +
|
| + final String name;
|
| +
|
| + const Architecture._(this.name);
|
| +
|
| + String toString() => "Architecture($name)";
|
| +}
|
| +
|
| +class Compiler {
|
| + static const none = const Compiler._('none');
|
| + static const precompiler = const Compiler._('precompiler');
|
| + static const dart2js = const Compiler._('dart2js');
|
| + static const dart2analyzer = const Compiler._('dart2analyzer');
|
| + static const appJit = const Compiler._('app_jit');
|
| + static const dartk = const Compiler._('dartk');
|
| + static const dartkp = const Compiler._('dartkp');
|
| +
|
| + static final List<String> names = _all.keys.toList();
|
| +
|
| + static final _all = new Map<String, Compiler>.fromIterable(
|
| + [none, precompiler, dart2js, dart2analyzer, appJit, dartk, dartkp],
|
| + key: (Compiler compiler) => compiler.name);
|
| +
|
| + static Compiler find(String name) {
|
| + var compiler = _all[name];
|
| + if (compiler != null) return compiler;
|
| +
|
| + throw new ArgumentError('Unknown compiler "$name".');
|
| + }
|
| +
|
| + final String name;
|
| +
|
| + const Compiler._(this.name);
|
| +
|
| + /// Gets the runtimes this compiler can target.
|
| + List<Runtime> get supportedRuntimes {
|
| + switch (this) {
|
| + case Compiler.dart2js:
|
| + // Note: by adding 'none' as a configuration, if the user
|
| + // runs test.py -c dart2js -r drt,none the dart2js_none and
|
| + // dart2js_drt will be duplicating work. If later we don't need 'none'
|
| + // with dart2js, we should remove it from here.
|
| + return const [
|
| + Runtime.d8,
|
| + Runtime.jsshell,
|
| + Runtime.drt,
|
| + Runtime.none,
|
| + Runtime.dartium,
|
| + Runtime.firefox,
|
| + Runtime.chrome,
|
| + Runtime.safari,
|
| + Runtime.ie9,
|
| + Runtime.ie10,
|
| + Runtime.ie11,
|
| + Runtime.opera,
|
| + Runtime.chromeOnAndroid,
|
| + Runtime.safariMobileSim
|
| + ];
|
| +
|
| + case Compiler.dart2analyzer:
|
| + return const [Runtime.none];
|
| + case Compiler.appJit:
|
| + case Compiler.dartk:
|
| + return const [Runtime.vm, Runtime.selfCheck, Runtime.none];
|
| + case Compiler.precompiler:
|
| + case Compiler.dartkp:
|
| + return const [Runtime.dartPrecompiled];
|
| + case Compiler.none:
|
| + return const [
|
| + Runtime.vm,
|
| + Runtime.flutter,
|
| + Runtime.drt,
|
| + Runtime.dartium,
|
| + Runtime.contentShellOnAndroid,
|
| + Runtime.dartiumOnAndroid
|
| + ];
|
| + }
|
| +
|
| + throw "unreachable";
|
| + }
|
| +
|
| + String toString() => "Compiler($name)";
|
| +}
|
| +
|
| +class Mode {
|
| + static const debug = const Mode._('debug');
|
| + static const product = const Mode._('product');
|
| + static const release = const Mode._('release');
|
| +
|
| + static final List<String> names = _all.keys.toList();
|
| +
|
| + static final _all = new Map<String, Mode>.fromIterable(
|
| + [debug, product, release],
|
| + key: (Mode mode) => mode.name);
|
| +
|
| + static Mode find(String name) {
|
| + var mode = _all[name];
|
| + if (mode != null) return mode;
|
| +
|
| + throw new ArgumentError('Unknown mode "$name".');
|
| + }
|
| +
|
| + final String name;
|
| +
|
| + const Mode._(this.name);
|
| +
|
| + bool get isDebug => this == debug;
|
| +
|
| + String toString() => "Mode($name)";
|
| +}
|
| +
|
| +class Progress {
|
| + static const compact = const Progress._('compact');
|
| + static const color = const Progress._('color');
|
| + static const line = const Progress._('line');
|
| + static const verbose = const Progress._('verbose');
|
| + static const silent = const Progress._('silent');
|
| + static const status = const Progress._('status');
|
| + static const buildbot = const Progress._('buildbot');
|
| + static const diff = const Progress._('diff');
|
| +
|
| + static final List<String> names = _all.keys.toList();
|
| +
|
| + static final _all = new Map<String, Progress>.fromIterable(
|
| + [compact, color, line, verbose, silent, status, buildbot, diff],
|
| + key: (Progress progress) => progress.name);
|
| +
|
| + static Progress find(String name) {
|
| + var progress = _all[name];
|
| + if (progress != null) return progress;
|
| +
|
| + throw new ArgumentError('Unknown progress type "$name".');
|
| + }
|
| +
|
| + final String name;
|
| +
|
| + const Progress._(this.name);
|
| +
|
| + String toString() => "Progress($name)";
|
| +}
|
| +
|
| +class Runtime {
|
| + static const vm = const Runtime._('vm');
|
| + static const flutter = const Runtime._('flutter');
|
| + static const dartPrecompiled = const Runtime._('dart_precompiled');
|
| + static const d8 = const Runtime._('d8');
|
| + static const jsshell = const Runtime._('jsshell');
|
| + static const drt = const Runtime._('drt');
|
| + static const dartium = const Runtime._('dartium');
|
| + static const firefox = const Runtime._('firefox');
|
| + static const chrome = const Runtime._('chrome');
|
| + static const safari = const Runtime._('safari');
|
| + static const ie9 = const Runtime._('ie9');
|
| + static const ie10 = const Runtime._('ie10');
|
| + static const ie11 = const Runtime._('ie11');
|
| + static const opera = const Runtime._('opera');
|
| + static const chromeOnAndroid = const Runtime._('chromeOnAndroid');
|
| + static const safariMobileSim = const Runtime._('safarimobilesim');
|
| + static const contentShellOnAndroid = const Runtime._('ContentShellOnAndroid');
|
| + static const dartiumOnAndroid = const Runtime._('DartiumOnAndroid');
|
| + static const selfCheck = const Runtime._('self_check');
|
| + static const none = const Runtime._('none');
|
| +
|
| + static final List<String> names = _all.keys.toList()..add("ff");
|
| +
|
| + static final _all = new Map<String, Runtime>.fromIterable([
|
| + vm,
|
| + flutter,
|
| + dartPrecompiled,
|
| + d8,
|
| + jsshell,
|
| + drt,
|
| + dartium,
|
| + firefox,
|
| + chrome,
|
| + safari,
|
| + ie9,
|
| + ie10,
|
| + ie11,
|
| + opera,
|
| + chromeOnAndroid,
|
| + safariMobileSim,
|
| + contentShellOnAndroid,
|
| + dartiumOnAndroid,
|
| + selfCheck,
|
| + none
|
| + ], key: (Runtime runtime) => runtime.name);
|
| +
|
| + static Runtime find(String name) {
|
| + // Allow "ff" as a synonym for Firefox.
|
| + if (name == "ff") return firefox;
|
| +
|
| + var runtime = _all[name];
|
| + if (runtime != null) return runtime;
|
| +
|
| + throw new ArgumentError('Unknown runtime "$name".');
|
| + }
|
| +
|
| + final String name;
|
| +
|
| + const Runtime._(this.name);
|
| +
|
| + bool get isBrowser => const [
|
| + drt,
|
| + dartium,
|
| + ie9,
|
| + ie10,
|
| + ie11,
|
| + safari,
|
| + opera,
|
| + chrome,
|
| + firefox,
|
| + chromeOnAndroid,
|
| + safariMobileSim,
|
| + contentShellOnAndroid,
|
| + dartiumOnAndroid,
|
| + ].contains(this);
|
| +
|
| + bool get isIE => name.startsWith("ie");
|
| + bool get isSafari => name.startsWith("safari");
|
| +
|
| + /// Whether this runtime is a command-line JavaScript environment.
|
| + bool get isJSCommandLine => const [d8, jsshell].contains(this);
|
| +
|
| + /// If the runtime doesn't support `Window.open`, we use iframes instead.
|
| + bool get requiresIFrame => !const [ie11, ie10].contains(this);
|
| +
|
| + String toString() => "Runtime($name)";
|
| +}
|
| +
|
| +class System {
|
| + static const android = const System._('android');
|
| + static const fuchsia = const System._('fuchsia');
|
| + static const linux = const System._('linux');
|
| + static const macos = const System._('macos');
|
| + static const windows = const System._('windows');
|
| +
|
| + static final List<String> names = _all.keys.toList();
|
| +
|
| + static final _all = new Map<String, System>.fromIterable(
|
| + [android, fuchsia, linux, macos, windows],
|
| + key: (System system) => system.name);
|
| +
|
| + static System find(String name) {
|
| + var system = _all[name];
|
| + if (system != null) return system;
|
| +
|
| + throw new ArgumentError('Unknown operating system "$name".');
|
| + }
|
| +
|
| + final String name;
|
| +
|
| + const System._(this.name);
|
| +
|
| + /// The root directory name for build outputs on this system.
|
| + String get outputDirectory {
|
| + switch (this) {
|
| + case android:
|
| + case fuchsia:
|
| + case linux:
|
| + case windows:
|
| + return 'out/';
|
| +
|
| + case macos:
|
| + return 'xcodebuild/';
|
| + }
|
| +
|
| + throw "unreachable";
|
| + }
|
| +
|
| + String toString() => "System($name)";
|
| +}
|
|
|