// 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 'package:status_file/environment.dart'; import 'configuration.dart'; typedef String _LookUpFunction(Configuration configuration); typedef bool _BoolLookUpFunction(Configuration configuration); // TODO(29756): Instead of synthesized negated variables like "unchecked", // consider adding support for "!" to status expressions. final _variables = { "analyzer": new _Variable.bool((c) => c.compiler == Compiler.dart2analyzer), "arch": new _Variable((c) => c.architecture.name, Architecture.names), "browser": new _Variable.bool((c) => c.runtime.isBrowser), "builder_tag": new _Variable((c) => c.builderTag ?? "", const []), "checked": new _Variable.bool((c) => c.isChecked), "compiler": new _Variable((c) => c.compiler.name, Compiler.names), "csp": new _Variable.bool((c) => c.isCsp), "dart2js_with_kernel": new _Variable.bool((c) => c.useDart2JSWithKernel), "dart2js_old_frontend": new _Variable.bool((c) => c.useDart2JSOldFrontend), "enable_asserts": new _Variable.bool((c) => c.useEnableAsserts), "fast_startup": new _Variable.bool((c) => c.useFastStartup), "fasta": new _Variable.bool((c) => c.usesFasta), "host_checked": new _Variable.bool((c) => c.isHostChecked), "host_unchecked": new _Variable.bool((c) => !c.isHostChecked), "hot_reload": new _Variable.bool((c) => c.hotReload), "hot_reload_rollback": new _Variable.bool((c) => c.hotReloadRollback), "ie": new _Variable.bool((c) => c.runtime.isIE), "jscl": new _Variable.bool((c) => c.runtime.isJSCommandLine), "minified": new _Variable.bool((c) => c.isMinified), "mode": new _Variable((c) => c.mode.name, Mode.names), "no_preview_dart_2": new _Variable.bool((c) => c.noPreviewDart2), "preview_dart_2": new _Variable.bool((c) => c.previewDart2), "runtime": new _Variable(_runtimeName, Runtime.names), "spec_parser": new _Variable.bool((c) => c.compiler == Compiler.specParser), "strong": new _Variable.bool((c) => c.isStrong), "system": new _Variable((c) => c.system.name, System.names), "use_sdk": new _Variable.bool((c) => c.useSdk) }; /// Gets the name of the runtime as it appears in status files. String _runtimeName(Configuration configuration) { // TODO(rnystrom): Handle "ff" being used as the name for firefox. We don't // want to make the Runtime itself use that as the name because it appears // elsewhere in test.dart and we want those other places to show "firefox". if (configuration.runtime == Runtime.firefox) return 'ff'; return configuration.runtime.name; } /// Defines the variables that are available for use inside a status file /// section header. /// /// These mostly map to command line arguments with the same name, though this /// is only a subset of the full set of command line arguments. class ConfigurationEnvironment implements Environment { /// The configuration where variable data is found. final Configuration _configuration; ConfigurationEnvironment(this._configuration); /// Validates that the variable with [name] exists and can be compared /// against [value]. /// /// If any errors are found, adds them to [errors]. void validate(String name, String value, List errors) { var variable = _variables[name]; if (variable == null) { errors.add('Unknown variable "$name".'); return; } // The "builder_tag" variable doesn't have an enumerated set of values. if (variable.allowedValues.isEmpty) return; if (!variable.allowedValues.contains(value)) { errors.add( 'Variable "$name" cannot have value "$value". Allowed values are:\n' + variable.allowedValues.join(', ') + '.'); } } /// Looks up the value of the variable with [name]. String lookUp(String name) { var variable = _variables[name]; if (variable == null) { // This shouldn't happen since we validate variables before evaluating // expressions. throw new ArgumentError('Unknown variable "$variable".'); } return variable.lookUp(_configuration); } } // TODO(rnystrom): There's some overlap between these and _Option in // options.dart. Unify? /// Describes a variable name whose value can be tested in a status file. /// /// Each variable is an enumerated string type that only accepts a limited range /// of values. Each instance of this class defines one variable, the values it /// permits, and the logic needed to look up the variable's value from a /// [Configuration] class _Variable { final _LookUpFunction _lookUp; final List allowedValues; _Variable(this._lookUp, Iterable allowed) : allowedValues = allowed.toList(); /// Creates a Boolean variable with allowed values "true" and "false". _Variable.bool(_BoolLookUpFunction lookUp) : _lookUp = ((configuration) => lookUp(configuration).toString()), allowedValues = const ["true", "false"]; String lookUp(Configuration configuration) => _lookUp(configuration); }