1a9801e9fa
... and update comment and test output to indicate how files should be regenerated from tools/experimental_features.yaml Change-Id: I369b93c35b91f7a93c915f0abf9cebdd00c13f8e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/106003 Commit-Queue: Paul Berry <paulberry@google.com> Auto-Submit: Dan Rubel <danrubel@google.com> Reviewed-by: Paul Berry <paulberry@google.com>
284 lines
7.9 KiB
Dart
284 lines
7.9 KiB
Dart
/**
|
|
* This file contains code to generate experimental flags
|
|
* based on the information in tools/experimental_features.yaml.
|
|
*/
|
|
import 'dart:io';
|
|
|
|
import 'package:analysis_tool/tools.dart';
|
|
import 'package:front_end/src/fasta/scanner/characters.dart' show $MINUS, $_;
|
|
import 'package:front_end/src/testing/package_root.dart' as pkgRoot;
|
|
import 'package:path/path.dart';
|
|
import 'package:yaml/yaml.dart' show YamlMap, loadYaml;
|
|
|
|
main() async {
|
|
await GeneratedContent.generateAll(
|
|
normalize(join(pkgRoot.packageRoot, 'analyzer')), allTargets);
|
|
}
|
|
|
|
List<GeneratedContent> get allTargets {
|
|
Map<dynamic, dynamic> experimentsYaml = loadYaml(new File(join(
|
|
normalize(join(pkgRoot.packageRoot, '../tools')),
|
|
'experimental_features.yaml'))
|
|
.readAsStringSync());
|
|
|
|
return <GeneratedContent>[
|
|
new GeneratedFile('lib/src/dart/analysis/experiments.g.dart',
|
|
(String pkgPath) async {
|
|
var generator = new _ExperimentsGenerator(experimentsYaml);
|
|
generator.generateFormatCode();
|
|
return generator.out.toString();
|
|
}),
|
|
];
|
|
}
|
|
|
|
String keyToIdentifier(String key) {
|
|
var identifier = StringBuffer();
|
|
for (int index = 0; index < key.length; ++index) {
|
|
var code = key.codeUnitAt(index);
|
|
if (code == $MINUS) {
|
|
code = $_;
|
|
}
|
|
identifier.writeCharCode(code);
|
|
}
|
|
return identifier.toString();
|
|
}
|
|
|
|
class _ExperimentsGenerator {
|
|
final Map experimentsYaml;
|
|
|
|
List<String> keysSorted;
|
|
|
|
final out = new StringBuffer('''
|
|
//
|
|
// THIS FILE IS GENERATED. DO NOT EDIT.
|
|
//
|
|
// Instead modify 'tools/experimental_features.yaml' and run
|
|
// 'dart pkg/analyzer/tool/experiments/generate.dart' to update.
|
|
|
|
part of 'experiments.dart';
|
|
''');
|
|
|
|
_ExperimentsGenerator(this.experimentsYaml);
|
|
|
|
void generateFormatCode() {
|
|
keysSorted = experimentsYaml.keys.cast<String>().toList()..sort();
|
|
generateSection_KnownFeatures();
|
|
generateSection_BuildExperimentalFlagsArray();
|
|
generateSection_EnableString();
|
|
generateSection_ExperimentalFeature();
|
|
generateSection_IsEnabledByDefault();
|
|
generateSection_IsExpired();
|
|
generateSection_CurrentState();
|
|
}
|
|
|
|
void generateSection_BuildExperimentalFlagsArray() {
|
|
out.write('''
|
|
|
|
List<bool> _buildExperimentalFlagsArray() => <bool>[
|
|
''');
|
|
for (var key in keysSorted) {
|
|
var id = keyToIdentifier(key);
|
|
var entry = experimentsYaml[key] as YamlMap;
|
|
bool shipped = entry['enabledIn'] != null;
|
|
bool expired = entry['expired'];
|
|
if (shipped || expired == true) {
|
|
out.writeln('true, // $key');
|
|
} else {
|
|
out.writeln('IsEnabledByDefault.$id,');
|
|
}
|
|
}
|
|
// TODO(danrubel): Remove bogus entries
|
|
out.write('''
|
|
false, // bogus-disabled
|
|
true, // bogus-enabled
|
|
];
|
|
''');
|
|
}
|
|
|
|
void generateSection_CurrentState() {
|
|
// TODO(danrubel): Remove bogus entries
|
|
out.write('''
|
|
|
|
mixin _CurrentState {
|
|
/// Current state for the flag "bogus-disabled"
|
|
@deprecated
|
|
bool get bogus_disabled => isEnabled(ExperimentalFeatures.bogus_disabled);
|
|
|
|
/// Current state for the flag "bogus-enabled"
|
|
@deprecated
|
|
bool get bogus_enabled => isEnabled(ExperimentalFeatures.bogus_enabled);
|
|
''');
|
|
for (var key in keysSorted) {
|
|
var id = keyToIdentifier(key);
|
|
out.write('''
|
|
/// Current state for the flag "$key"
|
|
bool get $id => isEnabled(ExperimentalFeatures.$id);
|
|
''');
|
|
}
|
|
out.write('''
|
|
|
|
bool isEnabled(covariant ExperimentalFeature feature);
|
|
}''');
|
|
}
|
|
|
|
void generateSection_EnableString() {
|
|
out.write('''
|
|
|
|
/// Constant strings for enabling each of the currently known experimental
|
|
/// flags.
|
|
class EnableString {
|
|
''');
|
|
for (var key in keysSorted) {
|
|
out.write('''
|
|
/// String to enable the experiment "$key"
|
|
static const String ${keyToIdentifier(key)} = '$key';
|
|
''');
|
|
}
|
|
// TODO(danrubel): Remove bogus entries
|
|
out.write('''
|
|
|
|
/// String to enable the experiment "bogus-disabled"
|
|
@deprecated
|
|
static const String bogus_disabled = 'bogus-disabled';
|
|
|
|
/// String to enable the experiment "bogus-enabled"
|
|
@deprecated
|
|
static const String bogus_enabled = 'bogus-enabled';
|
|
}''');
|
|
}
|
|
|
|
void generateSection_ExperimentalFeature() {
|
|
out.write('''
|
|
|
|
class ExperimentalFeatures {
|
|
''');
|
|
int index = 0;
|
|
for (var key in keysSorted) {
|
|
var id = keyToIdentifier(key);
|
|
var help = (experimentsYaml[key] as YamlMap)['help'] ?? '';
|
|
var enabledIn = (experimentsYaml[key] as YamlMap)['enabledIn'];
|
|
out.write('''
|
|
|
|
static const $id = const ExperimentalFeature(
|
|
$index,
|
|
EnableString.$id,
|
|
IsEnabledByDefault.$id,
|
|
IsExpired.$id,
|
|
'$help'
|
|
''');
|
|
if (enabledIn != null) {
|
|
if (enabledIn is double) {
|
|
enabledIn = '$enabledIn.0';
|
|
}
|
|
out.write(",firstSupportedVersion: '$enabledIn'");
|
|
}
|
|
out.writeln(');');
|
|
++index;
|
|
}
|
|
// TODO(danrubel): Remove bogus entries
|
|
out.write('''
|
|
|
|
@deprecated
|
|
static const bogus_disabled = const ExperimentalFeature(
|
|
$index,
|
|
// ignore: deprecated_member_use_from_same_package
|
|
EnableString.bogus_disabled,
|
|
IsEnabledByDefault.bogus_disabled,
|
|
IsExpired.bogus_disabled,
|
|
null);
|
|
|
|
@deprecated
|
|
static const bogus_enabled = const ExperimentalFeature(
|
|
${index + 1},
|
|
// ignore: deprecated_member_use_from_same_package
|
|
EnableString.bogus_enabled,
|
|
IsEnabledByDefault.bogus_enabled,
|
|
IsExpired.bogus_enabled,
|
|
null,
|
|
firstSupportedVersion: '1.0.0');
|
|
}''');
|
|
}
|
|
|
|
void generateSection_IsEnabledByDefault() {
|
|
out.write('''
|
|
|
|
/// Constant bools indicating whether each experimental flag is currently
|
|
/// enabled by default.
|
|
class IsEnabledByDefault {
|
|
''');
|
|
for (var key in keysSorted) {
|
|
var entry = experimentsYaml[key] as YamlMap;
|
|
bool shipped = entry['enabledIn'] != null;
|
|
out.write('''
|
|
/// Default state of the experiment "$key"
|
|
static const bool ${keyToIdentifier(key)} = $shipped;
|
|
''');
|
|
}
|
|
// TODO(danrubel): Remove bogus entries
|
|
out.write('''
|
|
|
|
/// Default state of the experiment "bogus-disabled"
|
|
@deprecated
|
|
static const bool bogus_disabled = false;
|
|
|
|
/// Default state of the experiment "bogus-enabled"
|
|
@deprecated
|
|
static const bool bogus_enabled = true;
|
|
}''');
|
|
}
|
|
|
|
void generateSection_IsExpired() {
|
|
out.write('''
|
|
|
|
/// Constant bools indicating whether each experimental flag is currently
|
|
/// expired (meaning its enable/disable status can no longer be altered from the
|
|
/// value in [IsEnabledByDefault]).
|
|
class IsExpired {
|
|
''');
|
|
for (var key in keysSorted) {
|
|
var entry = experimentsYaml[key] as YamlMap;
|
|
bool shipped = entry['enabledIn'] != null;
|
|
bool expired = entry['expired'];
|
|
out.write('''
|
|
/// Expiration status of the experiment "$key"
|
|
static const bool ${keyToIdentifier(key)} = ${expired == true};
|
|
''');
|
|
if (shipped && expired == false) {
|
|
throw 'Cannot mark shipped feature as "expired: false"';
|
|
}
|
|
}
|
|
// TODO(danrubel): Remove bogus entries
|
|
out.write('''
|
|
|
|
/// Expiration status of the experiment "bogus-disabled"
|
|
static const bool bogus_disabled = true;
|
|
|
|
/// Expiration status of the experiment "bogus-enabled"
|
|
static const bool bogus_enabled = true;
|
|
}''');
|
|
}
|
|
|
|
void generateSection_KnownFeatures() {
|
|
out.write('''
|
|
|
|
/// A map containing information about all known experimental flags.
|
|
const _knownFeatures = <String, ExperimentalFeature>{
|
|
''');
|
|
for (var key in keysSorted) {
|
|
var id = keyToIdentifier(key);
|
|
out.write('''
|
|
EnableString.$id: ExperimentalFeatures.$id,
|
|
''');
|
|
}
|
|
// TODO(danrubel): Remove bogus entries
|
|
out.write('''
|
|
|
|
// ignore: deprecated_member_use_from_same_package
|
|
EnableString.bogus_disabled: ExperimentalFeatures.bogus_disabled,
|
|
// ignore: deprecated_member_use_from_same_package
|
|
EnableString.bogus_enabled: ExperimentalFeatures.bogus_enabled,
|
|
};
|
|
''');
|
|
}
|
|
}
|