Version 2.11.0-216.0.dev Merge commit '1d6eac5ebf0c57be373c7f551c637a57e6f108cb' into 'dev'
diff --git a/pkg/front_end/analysis_options_no_lints.yaml b/pkg/front_end/analysis_options_no_lints.yaml index 6bbd1ac..25f50ec 100644 --- a/pkg/front_end/analysis_options_no_lints.yaml +++ b/pkg/front_end/analysis_options_no_lints.yaml
@@ -4,16 +4,17 @@ analyzer: exclude: - - test/analyser_ignored/** - - test/extensions/data/** - parser_testcases/** - - testcases/** + - test/analyser_ignored/** + - test/enable_non_nullable/data/** + - test/extensions/data/** - test/id_testing/data/** - test/language_versioning/data/** - test/patching/data/** - test/predicates/data/** - test/static_types/data/** - test/text_representation/data/** + - testcases/** errors: # Allow having TODOs in the code todo: ignore
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 23cf4a1..7914ed3 100644 --- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart +++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
@@ -24,6 +24,9 @@ expiredExperimentalFlags, parseExperimentalFlag; +import 'experimental_flags.dart' as flags + show getExperimentEnabledVersionInLibrary, isExperimentEnabledInLibrary; + import 'file_system.dart' show FileSystem; import 'standard_file_system.dart' show StandardFileSystem; @@ -132,6 +135,7 @@ /// Features not mentioned in the map will have their default value. Map<ExperimentalFlag, bool> experimentalFlags = <ExperimentalFlag, bool>{}; + Map<ExperimentalFlag, bool> defaultExperimentFlagsForTesting; AllowedExperimentalFlags allowedExperimentalFlagsForTesting; Map<ExperimentalFlag, Version> experimentEnabledVersionForTesting; Map<ExperimentalFlag, Version> experimentReleasedVersionForTesting; @@ -248,6 +252,23 @@ /// compiling the platform dill. bool emitDeps = true; + bool isExperimentEnabledInLibrary(ExperimentalFlag flag, Uri importUri) { + return flags.isExperimentEnabledInLibrary(flag, importUri, + defaultExperimentFlagsForTesting: defaultExperimentFlagsForTesting, + experimentalFlags: experimentalFlags, + allowedExperimentalFlags: allowedExperimentalFlagsForTesting); + } + + Version getExperimentEnabledVersionInLibrary( + ExperimentalFlag flag, Uri importUri) { + return flags.getExperimentEnabledVersionInLibrary(flag, importUri, + defaultExperimentFlagsForTesting: defaultExperimentFlagsForTesting, + allowedExperimentalFlags: allowedExperimentalFlagsForTesting, + experimentEnabledVersionForTesting: experimentEnabledVersionForTesting, + experimentReleasedVersionForTesting: + experimentReleasedVersionForTesting); + } + bool equivalent(CompilerOptions other, {bool ignoreOnDiagnostic: true, bool ignoreVerbose: true,
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 582b79e..9e21c12 100644 --- a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart +++ b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
@@ -83,7 +83,8 @@ /// defines the identity of a library, for instance `dart:core`, `package:foo`, /// or `file:///path/dir/file.dart`. bool isExperimentEnabledInLibrary(ExperimentalFlag flag, Uri canonicalUri, - {Map<ExperimentalFlag, bool> experimentalFlags, + {Map<ExperimentalFlag, bool> defaultExperimentFlagsForTesting, + Map<ExperimentalFlag, bool> experimentalFlags, AllowedExperimentalFlags allowedExperimentalFlags}) { assert(defaultExperimentalFlags.containsKey(flag), "No default value for $flag."); @@ -96,6 +97,9 @@ if (experimentalFlags != null) { enabled = experimentalFlags[flag]; } + if (defaultExperimentFlagsForTesting != null) { + enabled ??= defaultExperimentFlagsForTesting[flag]; + } enabled ??= defaultExperimentalFlags[flag]; if (!enabled) { allowedExperimentalFlags ??= defaultAllowedExperimentalFlags; @@ -119,13 +123,51 @@ return enabled; } -Version getExperimentEnabledVersion(ExperimentalFlag flag, - {Map<ExperimentalFlag, Version> experimentReleasedVersionForTesting}) { - Version version; - if (experimentReleasedVersionForTesting != null) { - version = experimentReleasedVersionForTesting[flag]; +/// Returns the version in which [flag] is enabled for the library with the +/// [canonicalUri]. +Version getExperimentEnabledVersionInLibrary( + ExperimentalFlag flag, Uri canonicalUri, + {AllowedExperimentalFlags allowedExperimentalFlags, + Map<ExperimentalFlag, bool> defaultExperimentFlagsForTesting, + Map<ExperimentalFlag, Version> experimentEnabledVersionForTesting, + Map<ExperimentalFlag, Version> experimentReleasedVersionForTesting}) { + allowedExperimentalFlags ??= defaultAllowedExperimentalFlags; + + Set<ExperimentalFlag> allowedFlags; + if (canonicalUri.scheme == 'dart') { + allowedFlags = allowedExperimentalFlags.forSdkLibrary(canonicalUri.path); + } else if (canonicalUri.scheme == 'package') { + int index = canonicalUri.path.indexOf('/'); + String packageName; + if (index >= 0) { + packageName = canonicalUri.path.substring(0, index); + } else { + packageName = canonicalUri.path; + } + allowedFlags = allowedExperimentalFlags.forPackage(packageName); } - version ??= experimentReleasedVersion[flag]; - assert(version != null, "No version for enabling $flag."); + Version version; + bool enabledByDefault; + if (defaultExperimentFlagsForTesting != null) { + enabledByDefault = defaultExperimentFlagsForTesting[flag]; + } + enabledByDefault ??= defaultExperimentalFlags[flag]; + if (!enabledByDefault || + allowedFlags != null && allowedFlags.contains(flag)) { + // If the feature is not enabled by default or is enabled by the allowed + // list use the experiment release version. + if (experimentReleasedVersionForTesting != null) { + version = experimentReleasedVersionForTesting[flag]; + } + version ??= experimentReleasedVersion[flag]; + } else { + // If the feature is enabled by default and is not enabled by the allowed + // list use the enabled version. + if (experimentEnabledVersionForTesting != null) { + version = experimentEnabledVersionForTesting[flag]; + } + version ??= experimentEnabledVersion[flag]; + } + assert(version != null, "No version for enabling $flag in $canonicalUri."); return version; }
diff --git a/pkg/front_end/lib/src/api_prototype/language_version.dart b/pkg/front_end/lib/src/api_prototype/language_version.dart index a77b716..02db78f 100644 --- a/pkg/front_end/lib/src/api_prototype/language_version.dart +++ b/pkg/front_end/lib/src/api_prototype/language_version.dart
@@ -23,8 +23,7 @@ import 'compiler_options.dart' show CompilerOptions; -import 'experimental_flags.dart' - show ExperimentalFlag, experimentReleasedVersion; +import 'experimental_flags.dart' show ExperimentalFlag; import 'file_system.dart' show FileSystem, FileSystemException; /// Gets the language version for a specific URI. @@ -34,7 +33,8 @@ /// specifies a language version that's too high). /// /// The language version returned is valid though. -Future<Version> languageVersionForUri(Uri uri, CompilerOptions options) async { +Future<VersionAndPackageUri> languageVersionForUri( + Uri uri, CompilerOptions options) async { return await CompilerContext.runWithOptions( new ProcessedOptions(options: options, inputs: [uri]), (context) async { // Get largest valid version / default version. @@ -65,6 +65,13 @@ fileUri = uri; package = uriTranslator.packages.packageOf(uri); } + Uri packageUri = uri; + if (packageUri.scheme != 'dart' && + packageUri.scheme != 'package' && + package != null && + package.name != null) { + packageUri = new Uri(scheme: 'package', path: package.name); + } // Check file content for @dart annotation. int major; @@ -102,7 +109,7 @@ } if (major != null && minor != null) { // The file decided. Return result. - return new Version(major, minor); + return new VersionAndPackageUri(new Version(major, minor), packageUri); } // Check package. @@ -119,11 +126,13 @@ } if (major != null && minor != null) { // The package decided. Return result. - return new Version(major, minor); + return new VersionAndPackageUri(new Version(major, minor), packageUri); } // Return default. - return new Version(currentSdkVersionMajor, currentSdkVersionMinor); + return new VersionAndPackageUri( + new Version(currentSdkVersionMajor, currentSdkVersionMinor), + packageUri); }); } @@ -134,6 +143,16 @@ // This method is here in order to use the opt out hack here for test // sources. if (SourceLibraryBuilder.isOptOutTest(uri)) return true; - Version uriVersion = await languageVersionForUri(uri, options); - return (uriVersion < experimentReleasedVersion[ExperimentalFlag.nonNullable]); + VersionAndPackageUri versionAndLibraryUri = + await languageVersionForUri(uri, options); + return (versionAndLibraryUri.version < + options.getExperimentEnabledVersionInLibrary( + ExperimentalFlag.nonNullable, versionAndLibraryUri.packageUri)); +} + +class VersionAndPackageUri { + final Version version; + final Uri packageUri; + + VersionAndPackageUri(this.version, this.packageUri); }
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart index 6682c79..1c158cd 100644 --- a/pkg/front_end/lib/src/base/processed_options.dart +++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -353,15 +353,12 @@ /// the 'allowed_experiments.json' file for this library. bool isExperimentEnabledInLibrary( flags.ExperimentalFlag flag, Uri importUri) { - return flags.isExperimentEnabledInLibrary(flag, importUri, - experimentalFlags: _raw.experimentalFlags, - allowedExperimentalFlags: _raw.allowedExperimentalFlagsForTesting); + return _raw.isExperimentEnabledInLibrary(flag, importUri); } - Version getExperimentEnabledVersion(flags.ExperimentalFlag flag) { - return flags.getExperimentEnabledVersion(flag, - experimentReleasedVersionForTesting: - _raw.experimentReleasedVersionForTesting); + Version getExperimentEnabledVersionInLibrary( + flags.ExperimentalFlag flag, Uri importUri) { + return _raw.getExperimentEnabledVersionInLibrary(flag, importUri); } Component _validateNullSafetyMode(Component component) {
diff --git a/pkg/front_end/lib/src/fasta/builder/field_builder.dart b/pkg/front_end/lib/src/fasta/builder/field_builder.dart index 607bf99..4f7945b 100644 --- a/pkg/front_end/lib/src/fasta/builder/field_builder.dart +++ b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
@@ -327,6 +327,7 @@ _fieldEncoding.registerMembers(library, this, f); } + /// Builds the core AST structures for this field as needed for the outline. void build(SourceLibraryBuilder libraryBuilder) { if (type != null) { // notInstanceContext is set to true for extension fields as they
diff --git a/pkg/front_end/lib/src/fasta/builder/member_builder.dart b/pkg/front_end/lib/src/fasta/builder/member_builder.dart index 05c1bc4..fef6b53 100644 --- a/pkg/front_end/lib/src/fasta/builder/member_builder.dart +++ b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
@@ -149,6 +149,7 @@ @override void buildOutlineExpressions(LibraryBuilder library, CoreTypes coreTypes) {} + /// Builds the core AST structures for this member as needed for the outline. void buildMembers( LibraryBuilder library, void Function(Member, BuiltMemberKind) f);
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 0bd7da5..7942b40 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
@@ -332,13 +332,12 @@ importUri.scheme != 'dart' || _packageUri == null, "Package uri '$_packageUri' set on dart: library with import uri " "'${importUri}'."); - updateLibraryNNBDSettings(); } bool _enableVarianceInLibrary; bool _enableNonfunctionTypeAliasesInLibrary; bool _enableNonNullableInLibrary; - Version _enableNonNullableVersionCache; + Version _enableNonNullableVersionInLibrary; bool _enableTripleShiftInLibrary; bool _enableExtensionMethodsInLibrary; @@ -360,8 +359,10 @@ loader.target.isExperimentEnabledInLibrary( ExperimentalFlag.nonNullable, _packageUri ?? importUri); - Version get _enableNonNullableVersion => _enableNonNullableVersionCache ??= - loader.target.getExperimentEnabledVersion(ExperimentalFlag.nonNullable); + Version get enableNonNullableVersionInLibrary => + _enableNonNullableVersionInLibrary ??= loader.target + .getExperimentEnabledVersionInLibrary( + ExperimentalFlag.nonNullable, _packageUri ?? importUri); bool get enableTripleShiftInLibrary => _enableTripleShiftInLibrary ??= loader.target.isExperimentEnabledInLibrary( @@ -434,10 +435,30 @@ return type; } + bool _isNonNullableByDefault; + @override - bool get isNonNullableByDefault => + bool get isNonNullableByDefault { + assert( + _isNonNullableByDefault == null || + _isNonNullableByDefault == _computeIsNonNullableByDefault(), + "Unstable isNonNullableByDefault property, changed " + "from ${_isNonNullableByDefault} to " + "${_computeIsNonNullableByDefault()}"); + return _ensureIsNonNullableByDefault(); + } + + bool _ensureIsNonNullableByDefault() { + if (_isNonNullableByDefault == null) { + _isNonNullableByDefault = _computeIsNonNullableByDefault(); + updateLibraryNNBDSettings(); + } + return _isNonNullableByDefault; + } + + bool _computeIsNonNullableByDefault() => enableNonNullableInLibrary && - languageVersion.version >= _enableNonNullableVersion && + languageVersion.version >= enableNonNullableVersionInLibrary && !isOptOutTest(library.importUri); static bool isOptOutTest(Uri uri) { @@ -480,6 +501,7 @@ } } _languageVersion.isFinal = true; + _ensureIsNonNullableByDefault(); } @override @@ -904,6 +926,7 @@ return true; } + /// Builds the core AST structure of this library as needed for the outline. Library build(LibraryBuilder coreLibrary, {bool modifyTarget}) { assert(implementationBuilders.isEmpty); canAddImplementationBuilders = true; @@ -955,8 +978,6 @@ reference: referenceFrom?.reference)); } - // TODO(CFE Team): Is this really needed in two places? - updateLibraryNNBDSettings(); return library; } @@ -2552,6 +2573,7 @@ MetadataBuilder.buildAnnotations(library, metadata, this, null, null); } + /// Builds the core AST structures for [declaration] needed for the outline. void buildBuilder(Builder declaration, LibraryBuilder coreLibrary) { String findDuplicateSuffix(Builder declaration) { if (declaration.next != null) {
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart index 14803dd..50dcccf 100644 --- a/pkg/front_end/lib/src/fasta/source/source_loader.dart +++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -251,7 +251,7 @@ configuration: new ScannerConfiguration( enableTripleShift: library.enableTripleShiftInLibrary, enableExtensionMethods: library.enableExtensionMethodsInLibrary, - enableNonNullable: library.isNonNullableByDefault), + enableNonNullable: library.enableNonNullableInLibrary), languageVersionChanged: (Scanner scanner, LanguageVersionToken version) { if (!suppressLexicalErrors) { @@ -346,8 +346,7 @@ // libraries with no corresponding package config we generate a message // per library. Map<String, List<LibraryBuilder>> libraryByPackage = {}; - Version enableNonNullableVersion = - target.getExperimentEnabledVersion(ExperimentalFlag.nonNullable); + Map<Package, Version> enableNonNullableVersionByPackage = {}; for (LibraryBuilder libraryBuilder in _strongOptOutLibraries) { Package package = target.uriTranslator.getPackage(libraryBuilder.importUri); @@ -355,6 +354,11 @@ if (package != null && package.languageVersion != null && package.languageVersion is! InvalidLanguageVersion) { + Version enableNonNullableVersion = + enableNonNullableVersionByPackage[package] ??= + target.getExperimentEnabledVersionInLibrary( + ExperimentalFlag.nonNullable, + new Uri(scheme: 'package', path: package.name)); Version version = new Version( package.languageVersion.major, package.languageVersion.minor); if (version < enableNonNullableVersion) { @@ -908,6 +912,7 @@ return handleHierarchyCycles(objectClass); } + /// Builds the core AST structure needed for the outline of the component. void buildComponent() { builders.forEach((Uri uri, LibraryBuilder library) { if (library.loader == this) {
diff --git a/pkg/front_end/lib/src/fasta/source/stack_listener_impl.dart b/pkg/front_end/lib/src/fasta/source/stack_listener_impl.dart index ba35905..0e6a737 100644 --- a/pkg/front_end/lib/src/fasta/source/stack_listener_impl.dart +++ b/pkg/front_end/lib/src/fasta/source/stack_listener_impl.dart
@@ -14,7 +14,7 @@ import 'package:front_end/src/api_prototype/experimental_flags.dart'; import 'package:kernel/ast.dart' - show AsyncMarker, Expression, FunctionNode, TreeNode, Version; + show AsyncMarker, Expression, FunctionNode, TreeNode; import '../fasta_codes.dart'; @@ -90,13 +90,11 @@ void reportMissingNonNullableSupport(Token token) { assert(!libraryBuilder.isNonNullableByDefault); assert(token != null); - Version enableNonNullableVersion = libraryBuilder.loader.target - .getExperimentEnabledVersion(ExperimentalFlag.nonNullable); if (libraryBuilder.enableNonNullableInLibrary) { if (libraryBuilder.languageVersion.isExplicit) { addProblem( - templateNonNullableOptOutExplicit - .withArguments(enableNonNullableVersion.toText()), + templateNonNullableOptOutExplicit.withArguments( + libraryBuilder.enableNonNullableVersionInLibrary.toText()), token.charOffset, token.charCount, context: <LocatedMessage>[ @@ -107,17 +105,19 @@ ]); } else { addProblem( - templateNonNullableOptOutImplicit - .withArguments(enableNonNullableVersion.toText()), + templateNonNullableOptOutImplicit.withArguments( + libraryBuilder.enableNonNullableVersionInLibrary.toText()), token.charOffset, token.charCount); } } else if (!libraryBuilder.loader.target .isExperimentEnabledGlobally(ExperimentalFlag.nonNullable)) { - if (libraryBuilder.languageVersion.version < enableNonNullableVersion) { + if (libraryBuilder.languageVersion.version < + libraryBuilder.enableNonNullableVersionInLibrary) { addProblem( templateExperimentNotEnabledNoFlagInvalidLanguageVersion - .withArguments(enableNonNullableVersion.toText()), + .withArguments( + libraryBuilder.enableNonNullableVersionInLibrary.toText()), token.offset, noLength); } else { @@ -125,8 +125,8 @@ } } else { addProblem( - templateExperimentNotEnabled.withArguments( - 'non-nullable', enableNonNullableVersion.toText()), + templateExperimentNotEnabled.withArguments('non-nullable', + libraryBuilder.enableNonNullableVersionInLibrary.toText()), token.offset, noLength); }
diff --git a/pkg/front_end/lib/src/fasta/target_implementation.dart b/pkg/front_end/lib/src/fasta/target_implementation.dart index ebacbfc..57a4369 100644 --- a/pkg/front_end/lib/src/fasta/target_implementation.dart +++ b/pkg/front_end/lib/src/fasta/target_implementation.dart
@@ -61,8 +61,9 @@ return _options.isExperimentEnabledInLibrary(flag, importUri); } - Version getExperimentEnabledVersion(ExperimentalFlag flag) { - return _options.getExperimentEnabledVersion(flag); + Version getExperimentEnabledVersionInLibrary( + ExperimentalFlag flag, Uri importUri) { + return _options.getExperimentEnabledVersionInLibrary(flag, importUri); } bool isExperimentEnabledGlobally(ExperimentalFlag flag) {
diff --git a/pkg/front_end/test/enable_non_nullable/data/.dart_tool/package_config.json b/pkg/front_end/test/enable_non_nullable/data/.dart_tool/package_config.json new file mode 100644 index 0000000..bc435fb --- /dev/null +++ b/pkg/front_end/test/enable_non_nullable/data/.dart_tool/package_config.json
@@ -0,0 +1,18 @@ +{ + "configVersion": 2, + "packages": [ + { + "name": "allowed_package", + "rootUri": "../allowed_package/", + "packageUri": "lib/", + "languageVersion": "2.9" + }, + { + "name": "not_allowed_package", + "rootUri": "../not_allowed_package/", + "packageUri": "lib/", + "languageVersion": "2.9" + } + + ] +} \ No newline at end of file
diff --git a/pkg/front_end/test/enable_non_nullable/data/allowed_package/lib/unversioned_lib.dart b/pkg/front_end/test/enable_non_nullable/data/allowed_package/lib/unversioned_lib.dart new file mode 100644 index 0000000..a08c72e --- /dev/null +++ b/pkg/front_end/test/enable_non_nullable/data/allowed_package/lib/unversioned_lib.dart
@@ -0,0 +1,3 @@ +// 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.
diff --git a/pkg/front_end/test/enable_non_nullable/data/allowed_package/lib/versioned_2_10_lib.dart b/pkg/front_end/test/enable_non_nullable/data/allowed_package/lib/versioned_2_10_lib.dart new file mode 100644 index 0000000..5f60217 --- /dev/null +++ b/pkg/front_end/test/enable_non_nullable/data/allowed_package/lib/versioned_2_10_lib.dart
@@ -0,0 +1,5 @@ +// 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. + +// @dart=2.10
diff --git a/pkg/front_end/test/enable_non_nullable/data/allowed_package/lib/versioned_2_11_lib.dart b/pkg/front_end/test/enable_non_nullable/data/allowed_package/lib/versioned_2_11_lib.dart new file mode 100644 index 0000000..8de228b --- /dev/null +++ b/pkg/front_end/test/enable_non_nullable/data/allowed_package/lib/versioned_2_11_lib.dart
@@ -0,0 +1,5 @@ +// 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. + +// @dart=2.11
diff --git a/pkg/front_end/test/enable_non_nullable/data/allowed_package/lib/versioned_2_8_lib.dart b/pkg/front_end/test/enable_non_nullable/data/allowed_package/lib/versioned_2_8_lib.dart new file mode 100644 index 0000000..e7d43c5 --- /dev/null +++ b/pkg/front_end/test/enable_non_nullable/data/allowed_package/lib/versioned_2_8_lib.dart
@@ -0,0 +1,5 @@ +// 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. + +// @dart=2.8
diff --git a/pkg/front_end/test/enable_non_nullable/data/allowed_package/lib/versioned_2_9_lib.dart b/pkg/front_end/test/enable_non_nullable/data/allowed_package/lib/versioned_2_9_lib.dart new file mode 100644 index 0000000..c2de893 --- /dev/null +++ b/pkg/front_end/test/enable_non_nullable/data/allowed_package/lib/versioned_2_9_lib.dart
@@ -0,0 +1,5 @@ +// 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. + +// @dart=2.9
diff --git a/pkg/front_end/test/enable_non_nullable/data/main.dart b/pkg/front_end/test/enable_non_nullable/data/main.dart new file mode 100644 index 0000000..cc333b0 --- /dev/null +++ b/pkg/front_end/test/enable_non_nullable/data/main.dart
@@ -0,0 +1,21 @@ +// 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. + +import 'package:allowed_package/unversioned_lib.dart'; +import 'package:allowed_package/versioned_2_8_lib.dart'; +import 'package:allowed_package/versioned_2_9_lib.dart'; +import 'package:allowed_package/versioned_2_10_lib.dart'; +import 'package:allowed_package/versioned_2_11_lib.dart'; +import 'package:not_allowed_package/unversioned_lib.dart'; +import 'package:not_allowed_package/versioned_2_8_lib.dart'; +import 'package:not_allowed_package/versioned_2_9_lib.dart'; +import 'package:not_allowed_package/versioned_2_10_lib.dart'; +import 'package:not_allowed_package/versioned_2_11_lib.dart'; +import 'unversioned_lib.dart'; +import 'versioned_2_8_lib.dart'; +import 'versioned_2_9_lib.dart'; +import 'versioned_2_10_lib.dart'; +import 'versioned_2_11_lib.dart'; + +main() {}
diff --git a/pkg/front_end/test/enable_non_nullable/data/not_allowed_package/lib/unversioned_lib.dart b/pkg/front_end/test/enable_non_nullable/data/not_allowed_package/lib/unversioned_lib.dart new file mode 100644 index 0000000..a08c72e --- /dev/null +++ b/pkg/front_end/test/enable_non_nullable/data/not_allowed_package/lib/unversioned_lib.dart
@@ -0,0 +1,3 @@ +// 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.
diff --git a/pkg/front_end/test/enable_non_nullable/data/not_allowed_package/lib/versioned_2_10_lib.dart b/pkg/front_end/test/enable_non_nullable/data/not_allowed_package/lib/versioned_2_10_lib.dart new file mode 100644 index 0000000..5f60217 --- /dev/null +++ b/pkg/front_end/test/enable_non_nullable/data/not_allowed_package/lib/versioned_2_10_lib.dart
@@ -0,0 +1,5 @@ +// 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. + +// @dart=2.10
diff --git a/pkg/front_end/test/enable_non_nullable/data/not_allowed_package/lib/versioned_2_11_lib.dart b/pkg/front_end/test/enable_non_nullable/data/not_allowed_package/lib/versioned_2_11_lib.dart new file mode 100644 index 0000000..8de228b --- /dev/null +++ b/pkg/front_end/test/enable_non_nullable/data/not_allowed_package/lib/versioned_2_11_lib.dart
@@ -0,0 +1,5 @@ +// 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. + +// @dart=2.11
diff --git a/pkg/front_end/test/enable_non_nullable/data/not_allowed_package/lib/versioned_2_8_lib.dart b/pkg/front_end/test/enable_non_nullable/data/not_allowed_package/lib/versioned_2_8_lib.dart new file mode 100644 index 0000000..e7d43c5 --- /dev/null +++ b/pkg/front_end/test/enable_non_nullable/data/not_allowed_package/lib/versioned_2_8_lib.dart
@@ -0,0 +1,5 @@ +// 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. + +// @dart=2.8
diff --git a/pkg/front_end/test/enable_non_nullable/data/not_allowed_package/lib/versioned_2_9_lib.dart b/pkg/front_end/test/enable_non_nullable/data/not_allowed_package/lib/versioned_2_9_lib.dart new file mode 100644 index 0000000..c2de893 --- /dev/null +++ b/pkg/front_end/test/enable_non_nullable/data/not_allowed_package/lib/versioned_2_9_lib.dart
@@ -0,0 +1,5 @@ +// 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. + +// @dart=2.9
diff --git a/pkg/front_end/test/enable_non_nullable/data/unversioned_lib.dart b/pkg/front_end/test/enable_non_nullable/data/unversioned_lib.dart new file mode 100644 index 0000000..a08c72e --- /dev/null +++ b/pkg/front_end/test/enable_non_nullable/data/unversioned_lib.dart
@@ -0,0 +1,3 @@ +// 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.
diff --git a/pkg/front_end/test/enable_non_nullable/data/versioned_2_10_lib.dart b/pkg/front_end/test/enable_non_nullable/data/versioned_2_10_lib.dart new file mode 100644 index 0000000..5f60217 --- /dev/null +++ b/pkg/front_end/test/enable_non_nullable/data/versioned_2_10_lib.dart
@@ -0,0 +1,5 @@ +// 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. + +// @dart=2.10
diff --git a/pkg/front_end/test/enable_non_nullable/data/versioned_2_11_lib.dart b/pkg/front_end/test/enable_non_nullable/data/versioned_2_11_lib.dart new file mode 100644 index 0000000..8de228b --- /dev/null +++ b/pkg/front_end/test/enable_non_nullable/data/versioned_2_11_lib.dart
@@ -0,0 +1,5 @@ +// 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. + +// @dart=2.11
diff --git a/pkg/front_end/test/enable_non_nullable/data/versioned_2_8_lib.dart b/pkg/front_end/test/enable_non_nullable/data/versioned_2_8_lib.dart new file mode 100644 index 0000000..e7d43c5 --- /dev/null +++ b/pkg/front_end/test/enable_non_nullable/data/versioned_2_8_lib.dart
@@ -0,0 +1,5 @@ +// 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. + +// @dart=2.8
diff --git a/pkg/front_end/test/enable_non_nullable/data/versioned_2_9_lib.dart b/pkg/front_end/test/enable_non_nullable/data/versioned_2_9_lib.dart new file mode 100644 index 0000000..c2de893 --- /dev/null +++ b/pkg/front_end/test/enable_non_nullable/data/versioned_2_9_lib.dart
@@ -0,0 +1,5 @@ +// 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. + +// @dart=2.9
diff --git a/pkg/front_end/test/enable_non_nullable/enable_non_nullable_test.dart b/pkg/front_end/test/enable_non_nullable/enable_non_nullable_test.dart new file mode 100644 index 0000000..d6feb1d --- /dev/null +++ b/pkg/front_end/test/enable_non_nullable/enable_non_nullable_test.dart
@@ -0,0 +1,128 @@ +// Copyright (c) 2019, 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.md file. + +import 'dart:io'; + +import 'package:expect/expect.dart'; +import 'package:front_end/src/api_prototype/compiler_options.dart'; +import 'package:front_end/src/api_prototype/experimental_flags.dart'; +import 'package:front_end/src/api_prototype/kernel_generator.dart'; +import 'package:front_end/src/api_prototype/language_version.dart'; +import 'package:front_end/src/compute_platform_binaries_location.dart'; +import 'package:kernel/ast.dart'; + +/// The version used in this test as the experiment release version. +const Version experimentReleaseVersion = const Version(2, 9); + +/// The version used in this test as the experiment enabled version. +const Version experimentEnabledVersion = const Version(2, 10); + +main() async { + print('--------------------------------------------------------------------'); + print('Test off-by-default with command-line flag'); + print('--------------------------------------------------------------------'); + await test( + enableNonNullableByDefault: false, + // When the flag is off by default, the experiment release version should + // be used as the opt-in criterion for all libraries. + versionImpliesOptIn: experimentReleaseVersion, + versionOptsInAllowed: experimentReleaseVersion); + + print('--------------------------------------------------------------------'); + print('Test on-by-default'); + print('--------------------------------------------------------------------'); + await test( + enableNonNullableByDefault: true, + // When the flag is on by default, the experiment release version should + // be used as the opt-in criterion only for libraries in allowed packages + // and the experiment enabled version should be used as the opt-in + // criterion for all other libraries. + versionImpliesOptIn: experimentEnabledVersion, + versionOptsInAllowed: experimentReleaseVersion); +} + +test( + {bool enableNonNullableByDefault, + Version versionImpliesOptIn, + Version versionOptsInAllowed}) async { + CompilerOptions options = new CompilerOptions(); + if (enableNonNullableByDefault) { + // Pretend non-nullable is on by default. + options.defaultExperimentFlagsForTesting = { + ExperimentalFlag.nonNullable: true + }; + } else { + // Pretend non-nullable is off by default but enabled on command-line. + options + ..defaultExperimentFlagsForTesting = {ExperimentalFlag.nonNullable: false} + ..experimentalFlags = {ExperimentalFlag.nonNullable: true}; + } + + Uri sdkSummary = computePlatformBinariesLocation(forceBuildDir: true) + .resolve('vm_platform_strong.dill'); + options + ..sdkSummary = sdkSummary + // Pretend current version is 2.11 + ..currentSdkVersion = '2.11' + ..allowedExperimentalFlagsForTesting = new AllowedExperimentalFlags( + sdkDefaultExperiments: + defaultAllowedExperimentalFlags.sdkDefaultExperiments, + sdkLibraryExperiments: + defaultAllowedExperimentalFlags.sdkLibraryExperiments, + packageExperiments: { + ...defaultAllowedExperimentalFlags.packageExperiments, + 'allowed_package': {ExperimentalFlag.nonNullable} + }) + ..experimentReleasedVersionForTesting = const { + // Pretend non-nullable is released in version 2.9. + ExperimentalFlag.nonNullable: experimentReleaseVersion + } + ..experimentEnabledVersionForTesting = const { + // Pretend non-nullable is enabled in version 2.10. + ExperimentalFlag.nonNullable: experimentEnabledVersion + }; + + Directory directory = new Directory.fromUri( + Uri.base.resolve('pkg/front_end/test/enable_non_nullable/data/')); + CompilerResult result = await kernelForProgramInternal( + directory.uri.resolve('main.dart'), options, + retainDataForTesting: true); + for (Library library in result.component.libraries) { + if (library.importUri.scheme != 'dart') { + bool usesLegacy = + await uriUsesLegacyLanguageVersion(library.fileUri, options); + VersionAndPackageUri versionAndPackageUri = + await languageVersionForUri(library.fileUri, options); + bool isNonNullableByDefault = library.isNonNullableByDefault; + print('${library.fileUri}:'); + print(' version=${versionAndPackageUri.version}'); + print(' (package) uri=${versionAndPackageUri.packageUri}'); + print(' isNonNullableByDefault=${isNonNullableByDefault}'); + print(' uriUsesLegacyLanguageVersion=${usesLegacy}'); + Expect.equals(library.languageVersion, versionAndPackageUri.version, + "Language version mismatch for ${library.importUri}"); + Expect.equals( + !usesLegacy, + isNonNullableByDefault, + "Unexpected null-safe state for ${library.importUri}:" + " isNonNullableByDefault=$isNonNullableByDefault," + " uriUsesLegacyLanguageVersion=$usesLegacy. " + "Computed version=${versionAndPackageUri.version}," + " (package) uri=${versionAndPackageUri.packageUri}"); + Expect.isTrue( + library.languageVersion < versionImpliesOptIn || + library.isNonNullableByDefault, + "Expected library ${library.importUri} with version " + "${library.languageVersion} to be opted in."); + Expect.isTrue( + versionAndPackageUri.packageUri.scheme != 'package' || + !versionAndPackageUri.packageUri.path + .startsWith('allowed_package') || + library.languageVersion < versionOptsInAllowed || + library.isNonNullableByDefault, + "Expected allowed library ${library.importUri} with version " + "${library.languageVersion} to be opted in."); + } + } +}
diff --git a/pkg/front_end/test/language_versioning/language_versioning_test.dart b/pkg/front_end/test/language_versioning/language_versioning_test.dart index 4146239..b44c90d 100644 --- a/pkg/front_end/test/language_versioning/language_versioning_test.dart +++ b/pkg/front_end/test/language_versioning/language_versioning_test.dart
@@ -87,9 +87,11 @@ for (Library library in component.libraries) { if (library.importUri.scheme == "dart") continue; Version lvFile = - await lv.languageVersionForUri(library.fileUri, stashedOptions); + (await lv.languageVersionForUri(library.fileUri, stashedOptions)) + .version; Version lvImportUri = - await lv.languageVersionForUri(library.importUri, stashedOptions); + (await lv.languageVersionForUri(library.importUri, stashedOptions)) + .version; if ((lvFile != lvImportUri || lvFile != library.languageVersion)) { throw """ Language version disagreement:
diff --git a/pkg/front_end/test/lint_test.status b/pkg/front_end/test/lint_test.status index cc1e0e3..10f7b68 100644 --- a/pkg/front_end/test/lint_test.status +++ b/pkg/front_end/test/lint_test.status
@@ -8,6 +8,7 @@ _fe_analyzer_shared/lib/src/scanner/string_scanner/ImportsTwice: Fail _fe_analyzer_shared/lib/src/scanner/token_impl/ImportsTwice: Fail _fe_analyzer_shared/lib/src/scanner/utf8_bytes_scanner/ImportsTwice: Fail +front_end/lib/src/api_prototype/compiler_options/ImportsTwice: Fail front_end/lib/src/api_prototype/compiler_options/Exports: Fail front_end/lib/src/api_prototype/constant_evaluator/Exports: Fail front_end/lib/src/api_prototype/front_end/Exports: Fail
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_bound_access.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_bound_access.dart.weak.expect index 080ff9e..dec49a6 100644 --- a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_bound_access.dart.weak.expect +++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_bound_access.dart.weak.expect
@@ -13,7 +13,7 @@ class DynamicClass<T extends dynamic = dynamic, S extends self::DynamicClass::T* = dynamic> extends core::Object { generic-covariant-impl field self::DynamicClass::T* field1; generic-covariant-impl field self::DynamicClass::T* field2; - constructor •(self::DynamicClass::T* field1, self::DynamicClass::T* field2) → self::DynamicClass<self::DynamicClass::T%, self::DynamicClass::S*>* + constructor •(self::DynamicClass::T* field1, self::DynamicClass::T* field2) → self::DynamicClass<self::DynamicClass::T*, self::DynamicClass::S*>* : self::DynamicClass::field1 = field1, self::DynamicClass::field2 = field2, super core::Object::•() ; method method() → dynamic
diff --git a/pkg/front_end/testcases/nnbd_mixed/experiment_release_version/not_allowed_package/lib/versioned_2_9_lib.dart b/pkg/front_end/testcases/nnbd_mixed/experiment_release_version/not_allowed_package/lib/versioned_2_9_lib.dart index 43a931e..ff693f6 100644 --- a/pkg/front_end/testcases/nnbd_mixed/experiment_release_version/not_allowed_package/lib/versioned_2_9_lib.dart +++ b/pkg/front_end/testcases/nnbd_mixed/experiment_release_version/not_allowed_package/lib/versioned_2_9_lib.dart
@@ -4,4 +4,4 @@ // @dart=2.9 -int? versioned_2_9_AllowedPackage; // ok \ No newline at end of file +int? versioned_2_9_AllowedPackage; // error \ No newline at end of file
diff --git a/pkg/front_end/testcases/nnbd_mixed/experiment_release_version/versioned_2_9_lib.dart b/pkg/front_end/testcases/nnbd_mixed/experiment_release_version/versioned_2_9_lib.dart index 6df385a..7a9a3ee 100644 --- a/pkg/front_end/testcases/nnbd_mixed/experiment_release_version/versioned_2_9_lib.dart +++ b/pkg/front_end/testcases/nnbd_mixed/experiment_release_version/versioned_2_9_lib.dart
@@ -4,4 +4,4 @@ // @dart=2.9 -int? versioned_2_9_Library; // ok \ No newline at end of file +int? versioned_2_9_Library; // error \ No newline at end of file
diff --git a/pkg/front_end/testing.json b/pkg/front_end/testing.json index 47f67ff..deda925 100644 --- a/pkg/front_end/testing.json +++ b/pkg/front_end/testing.json
@@ -480,6 +480,7 @@ "exclude": [ "^pkg/analysis_server/lib/src/analysis_server\\.dart", "test/analyser_ignored/", + "test/enable_non_nullable/data/", "test/extensions/data/", "test/id_testing/data/", "test/language_versioning/data/",
diff --git a/tools/VERSION b/tools/VERSION index 82fc3c8..8436a26 100644 --- a/tools/VERSION +++ b/tools/VERSION
@@ -27,5 +27,5 @@ MAJOR 2 MINOR 11 PATCH 0 -PRERELEASE 215 +PRERELEASE 216 PRERELEASE_PATCH 0 \ No newline at end of file