blob: d95cf7521b7f584035ee5460ffb5b786c5e79c3f [file] [log] [blame]
// 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.
// @dart = 2.9
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:front_end/src/fasta/source/source_library_builder.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,
enableNonNullableExplicitly: true,
// 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,
enableNonNullableExplicitly: false,
// 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);
print('--------------------------------------------------------------------');
print('Test on-by-default and explicitly with command-line flag');
print('--------------------------------------------------------------------');
await test(
enableNonNullableByDefault: true,
enableNonNullableExplicitly: true,
// When the flag is on by default but the experiment is enabled explicitly
// the experiment release version should be used as the opt-in criterion
// for all libraries.
versionImpliesOptIn: experimentReleaseVersion,
versionOptsInAllowed: experimentReleaseVersion);
}
test(
{bool enableNonNullableByDefault,
bool enableNonNullableExplicitly,
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.
options.defaultExperimentFlagsForTesting = {
ExperimentalFlag.nonNullable: false
};
}
if (enableNonNullableExplicitly) {
// Enable non-nullable explicitly on the command-line.
options..explicitExperimentalFlags = {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
};
bool hadDiagnostic = false;
options.onDiagnostic = (DiagnosticMessage message) {
print(message.plainTextFormatted);
hadDiagnostic = true;
};
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);
Expect.isFalse(
hadDiagnostic, "Compilation had diagnostics (errors, warnings)!");
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 ||
SourceLibraryBuilder.isOptOutTest(library.fileUri),
"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 ||
SourceLibraryBuilder.isOptOutTest(library.fileUri),
"Expected allowed library ${library.importUri} with version "
"${library.languageVersion} to be opted in.");
}
}
}