Experimental flags in Fasta

Change-Id: Ifc807059d9b434934e077f8fe5845d723807640c
Reviewed-on: https://dart-review.googlesource.com/c/87843
Reviewed-by: Peter von der Ahé <ahe@google.com>
This commit is contained in:
Aske Simon Christensen 2019-01-03 13:45:36 +00:00 committed by commit-bot@chromium.org
parent fa296dc3fa
commit 451fdc41e6
7 changed files with 81 additions and 4 deletions

View file

@ -8,6 +8,8 @@ import 'package:kernel/target/targets.dart' show Target;
import 'diagnostic_message.dart' show DiagnosticMessageHandler;
import 'experimental_flags.dart' show ExperimentalFlag;
import 'file_system.dart' show FileSystem;
import 'standard_file_system.dart' show StandardFileSystem;
@ -120,6 +122,11 @@ class CompilerOptions {
// libraries.json)
Map<String, List<Uri>> targetPatches = {};
/// Enable or disable experimental features. Features mapping to `true` are
/// explicitly enabled. Features mapping to `false` are explicitly disabled.
/// Features not mentioned in the map will have their default value.
Map<ExperimentalFlag, bool> experimentalFlags = {};
/// The target platform that will consume the compiled code.
///
/// Used to provide platform-specific details to the compiler like:

View file

@ -0,0 +1,15 @@
// Copyright (c) 2018, 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.
// TODO(askesc): Generate this file from a flag specification.
enum ExperimentalFlag { setLiterals }
ExperimentalFlag parseExperimentalFlag(String flag) {
switch (flag) {
case "set-literals":
return ExperimentalFlag.setLiterals;
}
return null;
}

View file

@ -24,6 +24,8 @@ import 'package:package_config/src/packages_impl.dart' show MapPackages;
import '../api_prototype/compiler_options.dart'
show CompilerOptions, DiagnosticMessage;
import '../api_prototype/experimental_flags.dart' show ExperimentalFlag;
import '../api_prototype/file_system.dart'
show FileSystem, FileSystemEntity, FileSystemException;
@ -293,6 +295,11 @@ class ProcessedOptions {
Target get target => _target ??=
_raw.target ?? new NoneTarget(new TargetFlags(legacyMode: legacyMode));
bool isExperimentEnabled(ExperimentalFlag flag) {
// TODO(askesc): Determine default flag value from specification file.
return _raw.experimentalFlags[flag] ?? false;
}
/// Get an outline component that summarizes the SDK, if any.
// TODO(sigmund): move, this doesn't feel like an "option".
Future<Component> loadSdkSummary(CanonicalName nameRoot) async {

View file

@ -3320,7 +3320,12 @@ const MessageCode messageFastaUsageLong =
Makes messages of the given kinds fatal, that is, immediately stop the
compiler with a non-zero exit-code. In --verbose mode, also display an
internal stack trace from the compiler. Multiple kinds can be separated by
commas, for example, --fatal=errors,warnings.""");
commas, for example, --fatal=errors,warnings.
--enable-experiment=<flag>
--disable-experiment=<flag>
Enable or disable an experimental flag, used to guard features currently
in development. Multiple experiments can be separated by commas.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeFastaUsageShort = messageFastaUsageShort;

View file

@ -18,6 +18,8 @@ import 'ticker.dart' show Ticker;
import 'uri_translator.dart' show UriTranslator;
import '../api_prototype/experimental_flags.dart' show ExperimentalFlag;
/// Provides the implementation details used by a loader for a target.
abstract class TargetImplementation extends Target {
final UriTranslator uriTranslator;
@ -33,8 +35,12 @@ abstract class TargetImplementation extends Target {
Declaration cachedNativeAnnotation;
Declaration cachedNativeExtensionAnnotation;
bool enableSetLiterals;
TargetImplementation(Ticker ticker, this.uriTranslator, this.backendTarget)
: super(ticker);
: enableSetLiterals = CompilerContext.current.options
.isExperimentEnabled(ExperimentalFlag.setLiterals),
super(ticker);
/// Creates a [LibraryBuilder] corresponding to [uri], if one doesn't exist
/// already.

View file

@ -1582,6 +1582,11 @@ FastaUsageLong:
internal stack trace from the compiler. Multiple kinds can be separated by
commas, for example, --fatal=errors,warnings.
--enable-experiment=<flag>
--disable-experiment=<flag>
Enable or disable an experimental flag, used to guard features currently
in development. Multiple experiments can be separated by commas.
FastaCLIArgumentRequired:
template: "Expected value after '#name'."

View file

@ -14,6 +14,9 @@ import 'package:build_integration/file_system/single_root.dart'
import 'package:front_end/src/api_prototype/compiler_options.dart'
show CompilerOptions;
import 'package:front_end/src/api_prototype/experimental_flags.dart'
show ExperimentalFlag, parseExperimentalFlag;
import 'package:front_end/src/api_prototype/file_system.dart' show FileSystem;
import 'package:front_end/src/api_prototype/standard_file_system.dart'
@ -237,7 +240,9 @@ class ParsedArguments {
const Map<String, dynamic> optionSpecification = const <String, dynamic>{
"--bytecode": false,
"--compile-sdk": Uri,
"--disable-experiment": ",",
"--dump-ir": false,
"--enable-experiment": ",",
"--exclude-source": false,
"--omit-platform": false,
"--fatal": ",",
@ -338,6 +343,31 @@ ProcessedOptions analyzeCommandLine(
});
}
final List<String> enabledExperiments = options["--enable-experiment"];
final List<String> disabledExperiments = options["--disable-experiment"];
Map<ExperimentalFlag, bool> experimentalFlags = {};
void setExperimentalFlags(List<String> experiments, bool value) {
if (experiments != null) {
for (String experiment in experiments) {
ExperimentalFlag flag = parseExperimentalFlag(experiment);
if (flag == null) {
throw new CommandLineProblem.deprecated(
"Unknown experiment: " + experiment);
}
if (experimentalFlags.containsKey(flag)) {
throw new CommandLineProblem.deprecated(
"Experiment mentioned more than once: " + experiment);
}
experimentalFlags[flag] = value;
}
}
}
setExperimentalFlags(enabledExperiments, true);
setExperimentalFlags(disabledExperiments, false);
if (programName == "compile_platform") {
if (arguments.length != 5) {
return throw new CommandLineProblem.deprecated(
@ -369,7 +399,8 @@ ProcessedOptions analyzeCommandLine(
..omitPlatform = omitPlatform
..verbose = verbose
..verify = verify
..bytecode = bytecode,
..bytecode = bytecode
..experimentalFlags = experimentalFlags,
inputs: <Uri>[Uri.parse(arguments[0])],
output: resolveInputUri(arguments[3], extraSchemes: extraSchemes));
} else if (arguments.isEmpty) {
@ -403,7 +434,8 @@ ProcessedOptions analyzeCommandLine(
..debugDump = dumpIr
..omitPlatform = omitPlatform
..verbose = verbose
..verify = verify;
..verify = verify
..experimentalFlags = experimentalFlags;
// TODO(ahe): What about chase dependencies?