[CFE/kernel] Generate dart files with versions in them from tools/experimental_features.yaml

Use the version from tools/experimental_features.yaml as the current
language version (as specified in kernel).

Use the "enabledIn" from tools/experimental_features.yaml to write out
the major and minor version for enabling features. This replaces the
hard-coding of when nnbd is enabled (in front-end).

Change-Id: I5b5dd7c2bb0c1a412ef1e660dfbe61e227193e1b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/138284
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
This commit is contained in:
Jens Johansen
2020-03-04 14:15:05 +00:00
committed by commit-bot@chromium.org
parent f828f00b59
commit 4e2a1a1b0f
9 changed files with 192 additions and 58 deletions
@@ -7,7 +7,8 @@ library front_end.compiler_options;
import 'package:_fe_analyzer_shared/src/messages/diagnostic_message.dart'
show DiagnosticMessageHandler;
import 'package:kernel/ast.dart' as kernel show Library;
import 'package:kernel/default_language_version.dart' as kernel
show defaultLanguageVersionMajor, defaultLanguageVersionMinor;
import 'package:kernel/target/targets.dart' show Target;
@@ -243,9 +244,9 @@ class CompilerOptions {
/// The current sdk version string, e.g. "2.6.0-edge.sha1hash".
/// For instance used for language versioning (specifying the maximum
/// version).
String currentSdkVersion = "${kernel.Library.defaultLanguageVersionMajor}"
String currentSdkVersion = "${kernel.defaultLanguageVersionMajor}"
"."
"${kernel.Library.defaultLanguageVersionMinor}";
"${kernel.defaultLanguageVersionMinor}";
}
/// Parse experimental flag arguments of the form 'flag' or 'no-flag' into a map
@@ -19,6 +19,25 @@ enum ExperimentalFlag {
variance,
}
const int enableConstantUpdate2018MajorVersion = 2;
const int enableConstantUpdate2018MinorVersion = 4;
const int enableControlFlowCollectionsMajorVersion = 2;
const int enableControlFlowCollectionsMinorVersion = 2;
const int enableExtensionMethodsMajorVersion = 2;
const int enableExtensionMethodsMinorVersion = 6;
const int enableNonNullableMajorVersion = 2;
const int enableNonNullableMinorVersion = 8;
const int enableNonfunctionTypeAliasesMajorVersion = 2;
const int enableNonfunctionTypeAliasesMinorVersion = 8;
const int enableSetLiteralsMajorVersion = 2;
const int enableSetLiteralsMinorVersion = 2;
const int enableSpreadCollectionsMajorVersion = 2;
const int enableSpreadCollectionsMinorVersion = 2;
const int enableTripleShiftMajorVersion = 2;
const int enableTripleShiftMinorVersion = 8;
const int enableVarianceMajorVersion = 2;
const int enableVarianceMinorVersion = 8;
ExperimentalFlag parseExperimentalFlag(String flag) {
switch (flag) {
case "constant-update-2018":
@@ -51,6 +51,9 @@ import 'package:kernel/ast.dart'
VariableDeclaration,
VoidType;
import 'package:kernel/default_language_version.dart' as kernel
show defaultLanguageVersionMajor, defaultLanguageVersionMinor;
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
import 'package:kernel/clone.dart' show CloneVisitorNotMembers;
@@ -165,9 +168,8 @@ import 'source_extension_builder.dart' show SourceExtensionBuilder;
import 'source_loader.dart' show SourceLoader;
// TODO(johnniwinther,jensj): Replace this with the correct scheme.
const int enableNonNullableDefaultMajorVersion = 2;
const int enableNonNullableDefaultMinorVersion = 8;
import '../../api_prototype/experimental_flags.dart'
show enableNonNullableMajorVersion, enableNonNullableMinorVersion;
class SourceLibraryBuilder extends LibraryBuilderImpl {
static const String MALFORMED_URI_SCHEME = "org-dartlang-malformed-uri";
@@ -383,8 +385,8 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
@override
bool get isNonNullableByDefault =>
loader.target.enableNonNullable &&
languageVersion.major >= enableNonNullableDefaultMajorVersion &&
languageVersion.minor >= enableNonNullableDefaultMinorVersion &&
languageVersion.major >= enableNonNullableMajorVersion &&
languageVersion.minor >= enableNonNullableMinorVersion &&
!isOptOutPackage(library.importUri) &&
!isOptOutTest(library.importUri);
@@ -3958,10 +3960,10 @@ class InvalidLanguageVersion implements LanguageVersion {
this.fileUri, this.charOffset, this.charCount, this.isExplicit);
@override
int get major => Library.defaultLanguageVersionMajor;
int get major => kernel.defaultLanguageVersionMajor;
@override
int get minor => Library.defaultLanguageVersionMinor;
int get minor => kernel.defaultLanguageVersionMinor;
@override
bool get valid => false;
@@ -3983,10 +3985,10 @@ class ImplicitLanguageVersion implements LanguageVersion {
const ImplicitLanguageVersion();
@override
int get major => Library.defaultLanguageVersionMajor;
int get major => kernel.defaultLanguageVersionMajor;
@override
int get minor => Library.defaultLanguageVersionMinor;
int get minor => kernel.defaultLanguageVersionMinor;
@override
bool get valid => true;
@@ -3,8 +3,11 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:io' show Platform, Process, ProcessResult;
import 'package:front_end/src/api_prototype/compiler_options.dart';
import 'package:kernel/ast.dart' as kernel show Library;
import 'package:kernel/default_language_version.dart' as kernel
show defaultLanguageVersionMajor, defaultLanguageVersionMinor;
import '../utils/io_utils.dart';
@@ -34,12 +37,12 @@ main(List<String> args) async {
int major = int.tryParse(dotSeparatedParts[0]);
int minor = int.tryParse(dotSeparatedParts[1]);
if (kernel.Library.defaultLanguageVersionMajor != major ||
kernel.Library.defaultLanguageVersionMinor != minor) {
if (kernel.defaultLanguageVersionMajor != major ||
kernel.defaultLanguageVersionMinor != minor) {
throw "Kernel defaults "
"${kernel.Library.defaultLanguageVersionMajor}"
"${kernel.defaultLanguageVersionMajor}"
"."
"${kernel.Library.defaultLanguageVersionMinor}"
"${kernel.defaultLanguageVersionMinor}"
" does not match output from make_version.py ($major.$minor)";
} else {
print("Kernel version matches.");
@@ -1124,6 +1124,7 @@ unshadowed
unwraps
unzip
upcast
update2018
ur
uri's
url
@@ -2,11 +2,7 @@
// 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:io';
import 'dart:isolate';
import 'dart:io' show File, Platform;
import 'package:_fe_analyzer_shared/src/scanner/characters.dart'
show $A, $MINUS, $a, $z;
@@ -15,23 +11,75 @@ import 'package:dart_style/dart_style.dart' show DartFormatter;
import 'package:yaml/yaml.dart' show YamlMap, loadYaml;
main(List<String> arguments) async {
var port = new ReceivePort();
await new File.fromUri(await computeGeneratedFile())
.writeAsString(await generateMessagesFile(), flush: true);
port.close();
main(List<String> arguments) {
new File.fromUri(computeCfeGeneratedFile())
.writeAsStringSync(generateCfeFile(), flush: true);
new File.fromUri(computeKernelGeneratedFile())
.writeAsStringSync(generateKernelFile(), flush: true);
}
Future<Uri> computeGeneratedFile() {
return Isolate.resolvePackageUri(
Uri.parse('package:front_end/src/api_prototype/experimental_flags.dart'));
Uri computeCfeGeneratedFile() {
return Platform.script
.resolve("../../lib/src/api_prototype/experimental_flags.dart");
}
Future<String> generateMessagesFile() async {
Uri messagesFile =
Platform.script.resolve("../../../../tools/experimental_features.yaml");
Uri computeKernelGeneratedFile() {
return Platform.script
.resolve("../../../kernel/lib/default_language_version.dart");
}
Uri computeYamlFile() {
return Platform.script
.resolve("../../../../tools/experimental_features.yaml");
}
String generateKernelFile() {
Uri yamlFile = computeYamlFile();
Map<dynamic, dynamic> yaml =
loadYaml(await new File.fromUri(messagesFile).readAsStringSync());
loadYaml(new File.fromUri(yamlFile).readAsStringSync());
int currentVersionMajor;
int currentVersionMinor;
{
String currentVersion = getAsVersionNumberString(yaml['current-version']);
List<String> split = currentVersion.split(".");
currentVersionMajor = int.parse(split[0]);
currentVersionMinor = int.parse(split[1]);
}
StringBuffer sb = new StringBuffer();
sb.write('''
// Copyright (c) 2020, 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.
// NOTE: THIS FILE IS GENERATED. DO NOT EDIT.
//
// Instead modify 'tools/experimental_features.yaml' and run
// 'pkg/front_end/tool/fasta generate-experimental-flags' to update.
int defaultLanguageVersionMajor = $currentVersionMajor;
int defaultLanguageVersionMinor = $currentVersionMinor;
''');
return new DartFormatter().format("$sb");
}
String generateCfeFile() {
Uri yamlFile = computeYamlFile();
Map<dynamic, dynamic> yaml =
loadYaml(new File.fromUri(yamlFile).readAsStringSync());
int currentVersionMajor;
int currentVersionMinor;
{
String currentVersion = getAsVersionNumberString(yaml['current-version']);
List<String> split = currentVersion.split(".");
currentVersionMajor = int.parse(split[0]);
currentVersionMinor = int.parse(split[1]);
}
StringBuffer sb = new StringBuffer();
sb.write('''
@@ -53,16 +101,41 @@ Future<String> generateMessagesFile() async {
enum ExperimentalFlag {
''');
for (var key in keys) {
for (String key in keys) {
sb.writeln(' ${keyToIdentifier(key)},');
}
sb.write('''
}
''');
for (String key in keys) {
int major;
int minor;
String enabledIn =
getAsVersionNumberString((features[key] as YamlMap)['enabledIn']);
if (enabledIn == null) {
major = currentVersionMajor;
minor = currentVersionMinor;
} else {
List<String> split = enabledIn.split(".");
major = int.parse(split[0]);
minor = int.parse(split[1]);
}
sb.writeln(' const int enable'
'${keyToIdentifier(key, upperCaseFirst: true)}'
'MajorVersion = $major;');
sb.writeln(' const int enable'
'${keyToIdentifier(key, upperCaseFirst: true)}'
'MinorVersion = $minor;');
}
sb.write('''
ExperimentalFlag parseExperimentalFlag(String flag) {
switch (flag) {
''');
for (var key in keys) {
for (String key in keys) {
sb.writeln(' case "$key":');
sb.writeln(' return ExperimentalFlag.${keyToIdentifier(key)};');
}
@@ -72,8 +145,8 @@ ExperimentalFlag parseExperimentalFlag(String flag) {
const Map<ExperimentalFlag, bool> defaultExperimentalFlags = {
''');
for (var key in keys) {
var expired = (features[key] as YamlMap)['expired'];
for (String key in keys) {
bool expired = (features[key] as YamlMap)['expired'];
bool shipped = (features[key] as YamlMap)['enabledIn'] != null;
sb.writeln(' ExperimentalFlag.${keyToIdentifier(key)}: ${shipped},');
if (shipped) {
@@ -87,7 +160,7 @@ const Map<ExperimentalFlag, bool> defaultExperimentalFlags = {
const Map<ExperimentalFlag, bool> expiredExperimentalFlags = {
''');
for (var key in keys) {
for (String key in keys) {
bool expired = (features[key] as YamlMap)['expired'] == true;
sb.writeln(' ExperimentalFlag.${keyToIdentifier(key)}: ${expired},');
}
@@ -96,10 +169,11 @@ const Map<ExperimentalFlag, bool> expiredExperimentalFlags = {
return new DartFormatter().format("$sb");
}
keyToIdentifier(String key) {
var identifier = StringBuffer();
keyToIdentifier(String key, {bool upperCaseFirst = false}) {
StringBuffer identifier = StringBuffer();
bool first = true;
for (int index = 0; index < key.length; ++index) {
var code = key.codeUnitAt(index);
int code = key.codeUnitAt(index);
if (code == $MINUS) {
++index;
code = key.codeUnitAt(index);
@@ -107,7 +181,18 @@ keyToIdentifier(String key) {
code = code - $a + $A;
}
}
if (first && upperCaseFirst && $a <= code && code <= $z) {
code = code - $a + $A;
}
first = false;
identifier.writeCharCode(code);
}
return identifier.toString();
}
String getAsVersionNumberString(dynamic value) {
if (value == null) return null;
if (value is String) return value;
if (value is double) return "$value";
throw "Unexpected value: $value (${value.runtimeType})";
}
@@ -2,22 +2,35 @@
// 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:io" show File;
import "package:async_helper/async_helper.dart" show asyncTest;
import "package:expect/expect.dart" show Expect;
import "dart:io" show File, exitCode;
import "generate_experimental_flags.dart"
show computeGeneratedFile, generateMessagesFile;
show
computeCfeGeneratedFile,
computeKernelGeneratedFile,
generateCfeFile,
generateKernelFile;
main() {
asyncTest(() async {
Uri generatedFile = await computeGeneratedFile();
String generated = await generateMessagesFile();
String actual = (await new File.fromUri(generatedFile).readAsString())
{
Uri generatedFile = computeCfeGeneratedFile();
String generated = generateCfeFile();
String actual = (new File.fromUri(generatedFile).readAsStringSync())
.replaceAll('\r\n', '\n');
Expect.stringEquals(generated, actual, """
check(generated, actual, generatedFile);
}
{
Uri generatedFile = computeKernelGeneratedFile();
String generated = generateKernelFile();
String actual = (new File.fromUri(generatedFile).readAsStringSync())
.replaceAll('\r\n', '\n');
check(generated, actual, generatedFile);
}
}
void check(String generated, String actual, Uri generatedFile) {
if (generated != actual) {
print("""
------------------------
The generated file
@@ -28,5 +41,6 @@ is out of date. To regenerate the file, run
------------------------
""");
});
exitCode = 1;
}
}
+2 -4
View File
@@ -73,6 +73,8 @@ export 'visitor.dart';
import 'canonical_name.dart' show CanonicalName;
export 'canonical_name.dart' show CanonicalName;
import 'default_language_version.dart';
import 'transformations/flags.dart';
import 'text/ast_to_text.dart';
import 'core_types.dart';
@@ -329,10 +331,6 @@ class Library extends NamedNode
/// The URI of the source file this library was loaded from.
Uri fileUri;
// TODO(jensj): Do we have a better option than this?
static int defaultLanguageVersionMajor = 2;
static int defaultLanguageVersionMinor = 8;
int _languageVersionMajor;
int _languageVersionMinor;
int get languageVersionMajor =>
@@ -0,0 +1,11 @@
// Copyright (c) 2020, 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.
// NOTE: THIS FILE IS GENERATED. DO NOT EDIT.
//
// Instead modify 'tools/experimental_features.yaml' and run
// 'pkg/front_end/tool/fasta generate-experimental-flags' to update.
int defaultLanguageVersionMajor = 2;
int defaultLanguageVersionMinor = 8;