OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 import 'dart:async'; |
| 6 import 'dart:convert'; |
| 7 import 'dart:io'; |
| 8 |
| 9 import 'compiler_configuration.dart'; |
| 10 import 'http_server.dart'; |
| 11 import 'path.dart'; |
| 12 import 'runtime_configuration.dart'; |
| 13 import 'test_suite.dart'; |
| 14 |
| 15 /// All of the contextual information to determine how a test suite should be |
| 16 /// run. |
| 17 /// |
| 18 /// Includes the compiler used to compile the code, the runtime the result is |
| 19 /// executed on, etc. |
| 20 class Configuration { |
| 21 Configuration( |
| 22 {this.architecture, |
| 23 this.compiler, |
| 24 this.mode, |
| 25 this.progress, |
| 26 this.runtime, |
| 27 this.system, |
| 28 this.selectors, |
| 29 this.appendLogs, |
| 30 this.batch, |
| 31 this.batchDart2JS, |
| 32 this.copyCoreDumps, |
| 33 this.hotReload, |
| 34 this.hotReloadRollback, |
| 35 this.isChecked, |
| 36 this.isStrong, |
| 37 this.isHostChecked, |
| 38 this.isCsp, |
| 39 this.isMinified, |
| 40 this.isVerbose, |
| 41 this.listTests, |
| 42 this.printTiming, |
| 43 this.printReport, |
| 44 this.reportInJson, |
| 45 this.resetBrowser, |
| 46 this.skipCompilation, |
| 47 this.useBlobs, |
| 48 this.useSdk, |
| 49 this.useFastStartup, |
| 50 this.useDart2JSWithKernel, |
| 51 this.writeDebugLog, |
| 52 this.writeTestOutcomeLog, |
| 53 this.drtPath, |
| 54 this.dartiumPath, |
| 55 this.chromePath, |
| 56 this.safariPath, |
| 57 this.firefoxPath, |
| 58 this.dartPath, |
| 59 this.dartPrecompiledPath, |
| 60 this.flutterPath, |
| 61 this.recordingPath, |
| 62 this.replayPath, |
| 63 this.taskCount, |
| 64 int timeout, |
| 65 this.shardCount, |
| 66 this.shard, |
| 67 this.stepName, |
| 68 this.testServerPort, |
| 69 this.testServerCrossOriginPort, |
| 70 this.testDriverErrorPort, |
| 71 this.localIP, |
| 72 this.dart2jsOptions, |
| 73 this.vmOptions, |
| 74 String packages, |
| 75 this.packageRoot, |
| 76 this.suiteDirectory, |
| 77 this.builderTag, |
| 78 this.reproducingArguments}) |
| 79 : _packages = packages, |
| 80 _timeout = timeout; |
| 81 |
| 82 final Architecture architecture; |
| 83 final Compiler compiler; |
| 84 final Mode mode; |
| 85 final Progress progress; |
| 86 final Runtime runtime; |
| 87 final System system; |
| 88 |
| 89 final Map<String, RegExp> selectors; |
| 90 |
| 91 // Boolean flags. |
| 92 |
| 93 final bool appendLogs; |
| 94 final bool batch; |
| 95 final bool batchDart2JS; |
| 96 final bool copyCoreDumps; |
| 97 final bool hotReload; |
| 98 final bool hotReloadRollback; |
| 99 final bool isChecked; |
| 100 final bool isStrong; |
| 101 final bool isHostChecked; |
| 102 final bool isCsp; |
| 103 final bool isMinified; |
| 104 final bool isVerbose; |
| 105 final bool listTests; |
| 106 final bool printTiming; |
| 107 final bool printReport; |
| 108 final bool reportInJson; |
| 109 final bool resetBrowser; |
| 110 final bool skipCompilation; |
| 111 final bool useBlobs; |
| 112 final bool useSdk; |
| 113 final bool useFastStartup; |
| 114 final bool useDart2JSWithKernel; |
| 115 final bool writeDebugLog; |
| 116 final bool writeTestOutcomeLog; |
| 117 |
| 118 // Various file paths. |
| 119 |
| 120 final String drtPath; |
| 121 final String dartiumPath; |
| 122 final String chromePath; |
| 123 final String safariPath; |
| 124 final String firefoxPath; |
| 125 final String dartPath; |
| 126 final String dartPrecompiledPath; |
| 127 final String flutterPath; |
| 128 final String recordingPath; |
| 129 final String replayPath; |
| 130 |
| 131 final int taskCount; |
| 132 final int shardCount; |
| 133 final int shard; |
| 134 final String stepName; |
| 135 |
| 136 final int testServerPort; |
| 137 final int testServerCrossOriginPort; |
| 138 final int testDriverErrorPort; |
| 139 final String localIP; |
| 140 |
| 141 /// Extra dart2js options passed to the testing script. |
| 142 final List<String> dart2jsOptions; |
| 143 |
| 144 /// Extra VM options passed to the testing script. |
| 145 final List<String> vmOptions; |
| 146 |
| 147 String _packages; |
| 148 String get packages { |
| 149 // If the .packages file path wasn't given, find it. |
| 150 if (packageRoot == null && _packages == null) { |
| 151 _packages = TestUtils.dartDirUri.resolve('.packages').toFilePath(); |
| 152 } |
| 153 |
| 154 return _packages; |
| 155 } |
| 156 |
| 157 final String packageRoot; |
| 158 final String suiteDirectory; |
| 159 final String builderTag; |
| 160 final List<String> reproducingArguments; |
| 161 |
| 162 TestingServers _servers; |
| 163 TestingServers get servers { |
| 164 if (_servers == null) { |
| 165 throw new StateError("Servers have not been started yet."); |
| 166 } |
| 167 return _servers; |
| 168 } |
| 169 |
| 170 /// The base directory named for this configuration, like: |
| 171 /// |
| 172 /// none_vm_release_x64 |
| 173 String _configurationDirectory; |
| 174 String get configurationDirectory { |
| 175 // Lazy initialize and cache since it requires hitting the file system. |
| 176 if (_configurationDirectory == null) { |
| 177 _configurationDirectory = _calculateDirectory(); |
| 178 } |
| 179 |
| 180 return _configurationDirectory; |
| 181 } |
| 182 |
| 183 /// The build directory path for this configuration, like: |
| 184 /// |
| 185 /// build/none_vm_release_x64 |
| 186 String get buildDirectory => system.outputDirectory + configurationDirectory; |
| 187 |
| 188 int _timeout; |
| 189 int get timeout { |
| 190 if (_timeout == null) { |
| 191 var isReload = hotReload || hotReloadRollback; |
| 192 |
| 193 var compilerMulitiplier = compilerConfiguration.timeoutMultiplier; |
| 194 var runtimeMultiplier = runtimeConfiguration.timeoutMultiplier( |
| 195 mode: mode, |
| 196 isChecked: isChecked, |
| 197 isReload: isReload, |
| 198 arch: architecture); |
| 199 |
| 200 _timeout = 60 * compilerMulitiplier * runtimeMultiplier; |
| 201 } |
| 202 |
| 203 return _timeout; |
| 204 } |
| 205 |
| 206 List<String> get standardOptions { |
| 207 if (compiler != Compiler.dart2js) { |
| 208 return const ["--ignore-unrecognized-flags"]; |
| 209 } |
| 210 |
| 211 var args = ['--generate-code-with-compile-time-errors', '--test-mode']; |
| 212 if (isChecked) args.add('--enable-checked-mode'); |
| 213 |
| 214 if (!runtime.isBrowser) { |
| 215 args.add("--allow-mock-compilation"); |
| 216 args.add("--categories=all"); |
| 217 } |
| 218 |
| 219 if (isMinified) args.add("--minify"); |
| 220 if (isCsp) args.add("--csp"); |
| 221 if (useFastStartup) args.add("--fast-startup"); |
| 222 if (useDart2JSWithKernel) args.add("--use-kernel"); |
| 223 return args; |
| 224 } |
| 225 |
| 226 String _windowsSdkPath; |
| 227 String get windowsSdkPath { |
| 228 if (!Platform.isWindows) { |
| 229 throw new StateError( |
| 230 "Should not use windowsSdkPath when not running on Windows."); |
| 231 } |
| 232 |
| 233 if (_windowsSdkPath == null) { |
| 234 // When running tests on Windows, use cdb from depot_tools to dump |
| 235 // stack traces of tests timing out. |
| 236 try { |
| 237 var path = new Path("build/win_toolchain.json").toNativePath(); |
| 238 var text = new File(path).readAsStringSync(); |
| 239 _windowsSdkPath = JSON.decode(text)['win_sdk'] as String; |
| 240 } on dynamic { |
| 241 // Ignore errors here. If win_sdk is not found, stack trace dumping |
| 242 // for timeouts won't work. |
| 243 } |
| 244 } |
| 245 |
| 246 return _windowsSdkPath; |
| 247 } |
| 248 |
| 249 /// Gets the local file path to the browser executable for this configuration. |
| 250 String get browserLocation { |
| 251 // If the user has explicitly configured a browser path, use it. |
| 252 String location; |
| 253 switch (runtime) { |
| 254 case Runtime.chrome: |
| 255 location = chromePath; |
| 256 break; |
| 257 case Runtime.dartium: |
| 258 location = dartiumPath; |
| 259 break; |
| 260 case Runtime.drt: |
| 261 location = drtPath; |
| 262 break; |
| 263 case Runtime.firefox: |
| 264 location = firefoxPath; |
| 265 break; |
| 266 case Runtime.flutter: |
| 267 location = flutterPath; |
| 268 break; |
| 269 case Runtime.safari: |
| 270 location = safariPath; |
| 271 break; |
| 272 } |
| 273 |
| 274 if (location != null) return location; |
| 275 |
| 276 const locations = const { |
| 277 Runtime.firefox: const { |
| 278 System.windows: 'C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe', |
| 279 System.linux: 'firefox', |
| 280 System.macos: '/Applications/Firefox.app/Contents/MacOS/firefox' |
| 281 }, |
| 282 Runtime.chrome: const { |
| 283 System.windows: |
| 284 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe', |
| 285 System.macos: |
| 286 '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', |
| 287 System.linux: 'google-chrome' |
| 288 }, |
| 289 Runtime.dartium: const { |
| 290 System.windows: 'client\\tests\\dartium\\chrome.exe', |
| 291 System.macos: |
| 292 'client/tests/dartium/Chromium.app/Contents/MacOS/Chromium', |
| 293 System.linux: 'client/tests/dartium/chrome' |
| 294 }, |
| 295 Runtime.safari: const { |
| 296 System.macos: '/Applications/Safari.app/Contents/MacOS/Safari' |
| 297 }, |
| 298 Runtime.safariMobileSim: const { |
| 299 System.macos: '/Applications/Xcode.app/Contents/Developer/Platforms/' |
| 300 'iPhoneSimulator.platform/Developer/Applications/' |
| 301 'iPhone Simulator.app/Contents/MacOS/iPhone Simulator' |
| 302 }, |
| 303 Runtime.ie9: const { |
| 304 System.windows: 'C:\\Program Files\\Internet Explorer\\iexplore.exe' |
| 305 }, |
| 306 Runtime.ie10: const { |
| 307 System.windows: 'C:\\Program Files\\Internet Explorer\\iexplore.exe' |
| 308 }, |
| 309 Runtime.ie11: const { |
| 310 System.windows: 'C:\\Program Files\\Internet Explorer\\iexplore.exe' |
| 311 } |
| 312 }; |
| 313 |
| 314 location = locations[runtime][System.find(Platform.operatingSystem)]; |
| 315 |
| 316 if (location == null) { |
| 317 throw "${runtime.name} is not supported on ${Platform.operatingSystem}"; |
| 318 } |
| 319 |
| 320 return location; |
| 321 } |
| 322 |
| 323 RuntimeConfiguration _runtimeConfiguration; |
| 324 RuntimeConfiguration get runtimeConfiguration => |
| 325 _runtimeConfiguration ??= new RuntimeConfiguration(this); |
| 326 |
| 327 CompilerConfiguration _compilerConfiguration; |
| 328 CompilerConfiguration get compilerConfiguration => |
| 329 _compilerConfiguration ??= new CompilerConfiguration(this); |
| 330 |
| 331 /// Determines if this configuration has a compatible compiler and runtime |
| 332 /// and other valid fields. |
| 333 /// |
| 334 /// Prints a warning if the configuration isn't valid. Returns whether or not |
| 335 /// it is. |
| 336 bool validate() { |
| 337 var isValid = true; |
| 338 var validRuntimes = compiler.supportedRuntimes; |
| 339 |
| 340 if (!validRuntimes.contains(runtime)) { |
| 341 print("Warning: combination of compiler '${compiler.name}' and " |
| 342 "runtime '${runtime.name}' is invalid. Skipping this combination."); |
| 343 isValid = false; |
| 344 } |
| 345 |
| 346 if (runtime.isIE && Platform.operatingSystem != 'windows') { |
| 347 print("Warning: cannot run Internet Explorer on non-Windows operating" |
| 348 " system."); |
| 349 isValid = false; |
| 350 } |
| 351 |
| 352 if (shard < 1 || shard > shardCount) { |
| 353 print("Error: shard index is $shard out of $shardCount shards"); |
| 354 isValid = false; |
| 355 } |
| 356 |
| 357 if (runtime == Runtime.flutter && flutterPath == null) { |
| 358 print("-rflutter requires the flutter engine executable to " |
| 359 "be specified using --flutter"); |
| 360 isValid = false; |
| 361 } |
| 362 |
| 363 if (runtime == Runtime.flutter && architecture != Architecture.x64) { |
| 364 isValid = false; |
| 365 print("-rflutter is applicable only for --arch=x64"); |
| 366 } |
| 367 |
| 368 return isValid; |
| 369 } |
| 370 |
| 371 /// Starts global HTTP servers that serve the entire dart repo. |
| 372 /// |
| 373 /// The HTTP server is available on `window.location.port`, and a second |
| 374 /// server for cross-domain tests can be found by calling |
| 375 /// `getCrossOriginPortNumber()`. |
| 376 Future startServers() { |
| 377 _servers = new TestingServers( |
| 378 buildDirectory, isCsp, runtime, null, packageRoot, packages); |
| 379 var future = servers.startServers(localIP, |
| 380 port: testServerPort, crossOriginPort: testServerCrossOriginPort); |
| 381 |
| 382 if (isVerbose) { |
| 383 future = future.then((_) { |
| 384 print('Started HttpServers: ${servers.httpServerCommandLine()}'); |
| 385 }); |
| 386 } |
| 387 |
| 388 return future; |
| 389 } |
| 390 |
| 391 void stopServers() { |
| 392 if (_servers != null) _servers.stopServers(); |
| 393 } |
| 394 |
| 395 /// Returns the correct configuration directory (the last component of the |
| 396 /// output directory path) for regular dart checkouts. |
| 397 /// |
| 398 /// Dartium checkouts use the `--build-directory` option to pass in the |
| 399 /// correct build directory explicitly. We allow our code to have been cross |
| 400 /// compiled, i.e., that there is an X in front of the arch. We don't allow |
| 401 /// both a cross compiled and a normal version to be present (except if you |
| 402 /// specifically pass in the build_directory). |
| 403 String _calculateDirectory() { |
| 404 // Capitalize the mode name. |
| 405 var modeName = |
| 406 mode.name.substring(0, 1).toUpperCase() + mode.name.substring(1); |
| 407 |
| 408 var os = ''; |
| 409 if (system == System.android) os = "Android"; |
| 410 |
| 411 var arch = architecture.name.toUpperCase(); |
| 412 var normal = '$modeName$os$arch'; |
| 413 var cross = '$modeName${os}X$arch'; |
| 414 var outDir = system.outputDirectory; |
| 415 var normalDir = new Directory(new Path('$outDir$normal').toNativePath()); |
| 416 var crossDir = new Directory(new Path('$outDir$cross').toNativePath()); |
| 417 |
| 418 if (normalDir.existsSync() && crossDir.existsSync()) { |
| 419 throw "You can't have both $normalDir and $crossDir. We don't know which" |
| 420 " binary to use."; |
| 421 } |
| 422 |
| 423 if (crossDir.existsSync()) return cross; |
| 424 |
| 425 return normal; |
| 426 } |
| 427 } |
| 428 |
| 429 class Architecture { |
| 430 static const ia32 = const Architecture._('ia32'); |
| 431 static const x64 = const Architecture._('x64'); |
| 432 static const arm = const Architecture._('arm'); |
| 433 static const armv6 = const Architecture._('armv6'); |
| 434 static const armv5te = const Architecture._('armv5te'); |
| 435 static const arm64 = const Architecture._('arm64'); |
| 436 static const simarm = const Architecture._('simarm'); |
| 437 static const simarmv6 = const Architecture._('simarmv6'); |
| 438 static const simarmv5te = const Architecture._('simarmv5te'); |
| 439 static const simarm64 = const Architecture._('simarm64'); |
| 440 static const mips = const Architecture._('mips'); |
| 441 static const simmips = const Architecture._('simmips'); |
| 442 static const simdbc = const Architecture._('simdbc'); |
| 443 static const simdbc64 = const Architecture._('simdbc64'); |
| 444 |
| 445 static final List<String> names = _all.keys.toList(); |
| 446 |
| 447 static final _all = new Map<String, Architecture>.fromIterable([ |
| 448 ia32, |
| 449 x64, |
| 450 arm, |
| 451 armv6, |
| 452 armv5te, |
| 453 arm64, |
| 454 simarm, |
| 455 simarmv6, |
| 456 simarmv5te, |
| 457 simarm64, |
| 458 mips, |
| 459 simmips, |
| 460 simdbc, |
| 461 simdbc64 |
| 462 ], key: (Architecture architecture) => architecture.name); |
| 463 |
| 464 static Architecture find(String name) { |
| 465 var architecture = _all[name]; |
| 466 if (architecture != null) return architecture; |
| 467 |
| 468 throw new ArgumentError('Unknown architecture "$name".'); |
| 469 } |
| 470 |
| 471 final String name; |
| 472 |
| 473 const Architecture._(this.name); |
| 474 |
| 475 String toString() => "Architecture($name)"; |
| 476 } |
| 477 |
| 478 class Compiler { |
| 479 static const none = const Compiler._('none'); |
| 480 static const precompiler = const Compiler._('precompiler'); |
| 481 static const dart2js = const Compiler._('dart2js'); |
| 482 static const dart2analyzer = const Compiler._('dart2analyzer'); |
| 483 static const appJit = const Compiler._('app_jit'); |
| 484 static const dartk = const Compiler._('dartk'); |
| 485 static const dartkp = const Compiler._('dartkp'); |
| 486 |
| 487 static final List<String> names = _all.keys.toList(); |
| 488 |
| 489 static final _all = new Map<String, Compiler>.fromIterable( |
| 490 [none, precompiler, dart2js, dart2analyzer, appJit, dartk, dartkp], |
| 491 key: (Compiler compiler) => compiler.name); |
| 492 |
| 493 static Compiler find(String name) { |
| 494 var compiler = _all[name]; |
| 495 if (compiler != null) return compiler; |
| 496 |
| 497 throw new ArgumentError('Unknown compiler "$name".'); |
| 498 } |
| 499 |
| 500 final String name; |
| 501 |
| 502 const Compiler._(this.name); |
| 503 |
| 504 /// Gets the runtimes this compiler can target. |
| 505 List<Runtime> get supportedRuntimes { |
| 506 switch (this) { |
| 507 case Compiler.dart2js: |
| 508 // Note: by adding 'none' as a configuration, if the user |
| 509 // runs test.py -c dart2js -r drt,none the dart2js_none and |
| 510 // dart2js_drt will be duplicating work. If later we don't need 'none' |
| 511 // with dart2js, we should remove it from here. |
| 512 return const [ |
| 513 Runtime.d8, |
| 514 Runtime.jsshell, |
| 515 Runtime.drt, |
| 516 Runtime.none, |
| 517 Runtime.dartium, |
| 518 Runtime.firefox, |
| 519 Runtime.chrome, |
| 520 Runtime.safari, |
| 521 Runtime.ie9, |
| 522 Runtime.ie10, |
| 523 Runtime.ie11, |
| 524 Runtime.opera, |
| 525 Runtime.chromeOnAndroid, |
| 526 Runtime.safariMobileSim |
| 527 ]; |
| 528 |
| 529 case Compiler.dart2analyzer: |
| 530 return const [Runtime.none]; |
| 531 case Compiler.appJit: |
| 532 case Compiler.dartk: |
| 533 return const [Runtime.vm, Runtime.selfCheck, Runtime.none]; |
| 534 case Compiler.precompiler: |
| 535 case Compiler.dartkp: |
| 536 return const [Runtime.dartPrecompiled]; |
| 537 case Compiler.none: |
| 538 return const [ |
| 539 Runtime.vm, |
| 540 Runtime.flutter, |
| 541 Runtime.drt, |
| 542 Runtime.dartium, |
| 543 Runtime.contentShellOnAndroid, |
| 544 Runtime.dartiumOnAndroid |
| 545 ]; |
| 546 } |
| 547 |
| 548 throw "unreachable"; |
| 549 } |
| 550 |
| 551 String toString() => "Compiler($name)"; |
| 552 } |
| 553 |
| 554 class Mode { |
| 555 static const debug = const Mode._('debug'); |
| 556 static const product = const Mode._('product'); |
| 557 static const release = const Mode._('release'); |
| 558 |
| 559 static final List<String> names = _all.keys.toList(); |
| 560 |
| 561 static final _all = new Map<String, Mode>.fromIterable( |
| 562 [debug, product, release], |
| 563 key: (Mode mode) => mode.name); |
| 564 |
| 565 static Mode find(String name) { |
| 566 var mode = _all[name]; |
| 567 if (mode != null) return mode; |
| 568 |
| 569 throw new ArgumentError('Unknown mode "$name".'); |
| 570 } |
| 571 |
| 572 final String name; |
| 573 |
| 574 const Mode._(this.name); |
| 575 |
| 576 bool get isDebug => this == debug; |
| 577 |
| 578 String toString() => "Mode($name)"; |
| 579 } |
| 580 |
| 581 class Progress { |
| 582 static const compact = const Progress._('compact'); |
| 583 static const color = const Progress._('color'); |
| 584 static const line = const Progress._('line'); |
| 585 static const verbose = const Progress._('verbose'); |
| 586 static const silent = const Progress._('silent'); |
| 587 static const status = const Progress._('status'); |
| 588 static const buildbot = const Progress._('buildbot'); |
| 589 static const diff = const Progress._('diff'); |
| 590 |
| 591 static final List<String> names = _all.keys.toList(); |
| 592 |
| 593 static final _all = new Map<String, Progress>.fromIterable( |
| 594 [compact, color, line, verbose, silent, status, buildbot, diff], |
| 595 key: (Progress progress) => progress.name); |
| 596 |
| 597 static Progress find(String name) { |
| 598 var progress = _all[name]; |
| 599 if (progress != null) return progress; |
| 600 |
| 601 throw new ArgumentError('Unknown progress type "$name".'); |
| 602 } |
| 603 |
| 604 final String name; |
| 605 |
| 606 const Progress._(this.name); |
| 607 |
| 608 String toString() => "Progress($name)"; |
| 609 } |
| 610 |
| 611 class Runtime { |
| 612 static const vm = const Runtime._('vm'); |
| 613 static const flutter = const Runtime._('flutter'); |
| 614 static const dartPrecompiled = const Runtime._('dart_precompiled'); |
| 615 static const d8 = const Runtime._('d8'); |
| 616 static const jsshell = const Runtime._('jsshell'); |
| 617 static const drt = const Runtime._('drt'); |
| 618 static const dartium = const Runtime._('dartium'); |
| 619 static const firefox = const Runtime._('firefox'); |
| 620 static const chrome = const Runtime._('chrome'); |
| 621 static const safari = const Runtime._('safari'); |
| 622 static const ie9 = const Runtime._('ie9'); |
| 623 static const ie10 = const Runtime._('ie10'); |
| 624 static const ie11 = const Runtime._('ie11'); |
| 625 static const opera = const Runtime._('opera'); |
| 626 static const chromeOnAndroid = const Runtime._('chromeOnAndroid'); |
| 627 static const safariMobileSim = const Runtime._('safarimobilesim'); |
| 628 static const contentShellOnAndroid = const Runtime._('ContentShellOnAndroid'); |
| 629 static const dartiumOnAndroid = const Runtime._('DartiumOnAndroid'); |
| 630 static const selfCheck = const Runtime._('self_check'); |
| 631 static const none = const Runtime._('none'); |
| 632 |
| 633 static final List<String> names = _all.keys.toList()..add("ff"); |
| 634 |
| 635 static final _all = new Map<String, Runtime>.fromIterable([ |
| 636 vm, |
| 637 flutter, |
| 638 dartPrecompiled, |
| 639 d8, |
| 640 jsshell, |
| 641 drt, |
| 642 dartium, |
| 643 firefox, |
| 644 chrome, |
| 645 safari, |
| 646 ie9, |
| 647 ie10, |
| 648 ie11, |
| 649 opera, |
| 650 chromeOnAndroid, |
| 651 safariMobileSim, |
| 652 contentShellOnAndroid, |
| 653 dartiumOnAndroid, |
| 654 selfCheck, |
| 655 none |
| 656 ], key: (Runtime runtime) => runtime.name); |
| 657 |
| 658 static Runtime find(String name) { |
| 659 // Allow "ff" as a synonym for Firefox. |
| 660 if (name == "ff") return firefox; |
| 661 |
| 662 var runtime = _all[name]; |
| 663 if (runtime != null) return runtime; |
| 664 |
| 665 throw new ArgumentError('Unknown runtime "$name".'); |
| 666 } |
| 667 |
| 668 final String name; |
| 669 |
| 670 const Runtime._(this.name); |
| 671 |
| 672 bool get isBrowser => const [ |
| 673 drt, |
| 674 dartium, |
| 675 ie9, |
| 676 ie10, |
| 677 ie11, |
| 678 safari, |
| 679 opera, |
| 680 chrome, |
| 681 firefox, |
| 682 chromeOnAndroid, |
| 683 safariMobileSim, |
| 684 contentShellOnAndroid, |
| 685 dartiumOnAndroid, |
| 686 ].contains(this); |
| 687 |
| 688 bool get isIE => name.startsWith("ie"); |
| 689 bool get isSafari => name.startsWith("safari"); |
| 690 |
| 691 /// Whether this runtime is a command-line JavaScript environment. |
| 692 bool get isJSCommandLine => const [d8, jsshell].contains(this); |
| 693 |
| 694 /// If the runtime doesn't support `Window.open`, we use iframes instead. |
| 695 bool get requiresIFrame => !const [ie11, ie10].contains(this); |
| 696 |
| 697 String toString() => "Runtime($name)"; |
| 698 } |
| 699 |
| 700 class System { |
| 701 static const android = const System._('android'); |
| 702 static const fuchsia = const System._('fuchsia'); |
| 703 static const linux = const System._('linux'); |
| 704 static const macos = const System._('macos'); |
| 705 static const windows = const System._('windows'); |
| 706 |
| 707 static final List<String> names = _all.keys.toList(); |
| 708 |
| 709 static final _all = new Map<String, System>.fromIterable( |
| 710 [android, fuchsia, linux, macos, windows], |
| 711 key: (System system) => system.name); |
| 712 |
| 713 static System find(String name) { |
| 714 var system = _all[name]; |
| 715 if (system != null) return system; |
| 716 |
| 717 throw new ArgumentError('Unknown operating system "$name".'); |
| 718 } |
| 719 |
| 720 final String name; |
| 721 |
| 722 const System._(this.name); |
| 723 |
| 724 /// The root directory name for build outputs on this system. |
| 725 String get outputDirectory { |
| 726 switch (this) { |
| 727 case android: |
| 728 case fuchsia: |
| 729 case linux: |
| 730 case windows: |
| 731 return 'out/'; |
| 732 |
| 733 case macos: |
| 734 return 'xcodebuild/'; |
| 735 } |
| 736 |
| 737 throw "unreachable"; |
| 738 } |
| 739 |
| 740 String toString() => "System($name)"; |
| 741 } |
OLD | NEW |