diff --git a/pkg/front_end/lib/src/api_prototype/compiler_options.dart b/pkg/front_end/lib/src/api_prototype/compiler_options.dart index c9b519df4a3..43d380976df 100644 --- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart +++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart @@ -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 diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart index 110685b1287..99457331ef8 100644 --- a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart +++ b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart @@ -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": diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart index 51842c7cd59..6e651cef43f 100644 --- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart @@ -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; diff --git a/pkg/front_end/test/language_versioning/language_versioning_up_to_date_test.dart b/pkg/front_end/test/language_versioning/language_versioning_up_to_date_test.dart index 36d07996e59..171e2127bdc 100644 --- a/pkg/front_end/test/language_versioning/language_versioning_up_to_date_test.dart +++ b/pkg/front_end/test/language_versioning/language_versioning_up_to_date_test.dart @@ -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 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."); diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt index 867b5d0bcf7..f66e476b18e 100644 --- a/pkg/front_end/test/spell_checking_list_code.txt +++ b/pkg/front_end/test/spell_checking_list_code.txt @@ -1124,6 +1124,7 @@ unshadowed unwraps unzip upcast +update2018 ur uri's url diff --git a/pkg/front_end/tool/_fasta/generate_experimental_flags.dart b/pkg/front_end/tool/_fasta/generate_experimental_flags.dart index 2b2442e75a2..9d8b6341930 100644 --- a/pkg/front_end/tool/_fasta/generate_experimental_flags.dart +++ b/pkg/front_end/tool/_fasta/generate_experimental_flags.dart @@ -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 arguments) async { - var port = new ReceivePort(); - await new File.fromUri(await computeGeneratedFile()) - .writeAsString(await generateMessagesFile(), flush: true); - port.close(); +main(List arguments) { + new File.fromUri(computeCfeGeneratedFile()) + .writeAsStringSync(generateCfeFile(), flush: true); + new File.fromUri(computeKernelGeneratedFile()) + .writeAsStringSync(generateKernelFile(), flush: true); } -Future 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 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 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 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 yaml = + loadYaml(new File.fromUri(yamlFile).readAsStringSync()); + + int currentVersionMajor; + int currentVersionMinor; + { + String currentVersion = getAsVersionNumberString(yaml['current-version']); + List split = currentVersion.split("."); + currentVersionMajor = int.parse(split[0]); + currentVersionMinor = int.parse(split[1]); + } + StringBuffer sb = new StringBuffer(); sb.write(''' @@ -53,16 +101,41 @@ Future 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 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 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 defaultExperimentalFlags = { const Map 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 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})"; +} diff --git a/pkg/front_end/tool/_fasta/generate_experimental_flags_test.dart b/pkg/front_end/tool/_fasta/generate_experimental_flags_test.dart index ad1ac6e74af..1249933b41d 100644 --- a/pkg/front_end/tool/_fasta/generate_experimental_flags_test.dart +++ b/pkg/front_end/tool/_fasta/generate_experimental_flags_test.dart @@ -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; + } } diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart index aa2408c0e7e..92e1b4cfb07 100644 --- a/pkg/kernel/lib/ast.dart +++ b/pkg/kernel/lib/ast.dart @@ -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 => diff --git a/pkg/kernel/lib/default_language_version.dart b/pkg/kernel/lib/default_language_version.dart new file mode 100644 index 00000000000..73670a5f9f5 --- /dev/null +++ b/pkg/kernel/lib/default_language_version.dart @@ -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;