[CFE] Language versioning max/default also setable via compiler options

* Max and default for language version controllable via language options
* Default (if not set) comes from kernel static fields
* Kernel static fields updated to 2.6
* (Also set version for debug expression library)
* Test added that checks that the kernel static fields aren't out-of-date
  (checked against python script "tools/make_version.py").

Change-Id: I65f26053081e4c55c215b677128f37fa970693c6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/114944
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
This commit is contained in:
Jens Johansen 2019-09-02 07:43:05 +00:00 committed by commit-bot@chromium.org
parent 29ca4e670a
commit 1400ab4136
14 changed files with 154 additions and 21 deletions

View file

@ -4,6 +4,8 @@
library front_end.compiler_options;
import 'package:kernel/ast.dart' as kernel show Library;
import 'package:kernel/target/targets.dart' show Target;
import 'diagnostic_message.dart' show DiagnosticMessageHandler;
@ -215,6 +217,13 @@ class CompilerOptions {
/// Whether to write a file (e.g. a dill file) when reporting a crash.
bool writeFileOnCrashReport = true;
/// 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}"
"."
"${kernel.Library.defaultLanguageVersionMinor}";
}
/// Parse experimental flag arguments of the form 'flag' or 'no-flag' into a map

View file

@ -306,6 +306,11 @@ class ProcessedOptions {
/// Whether to write a file (e.g. a dill file) when reporting a crash.
bool get writeFileOnCrashReport => _raw.writeFileOnCrashReport;
/// The current sdk version string, e.g. "2.6.0-edge.sha1hash".
/// For instance used for language versioning (specifying the maximum
/// version).
String get currentSdkVersion => _raw.currentSdkVersion;
Target _target;
Target get target => _target ??=
_raw.target ?? new NoneTarget(new TargetFlags(legacyMode: legacyMode));

View file

@ -861,6 +861,9 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
scope: libraryBuilder.scope.createNestedScope("expression"),
nameOrigin: libraryBuilder.library,
);
debugLibrary.setLanguageVersion(
libraryBuilder.library.languageVersionMajor,
libraryBuilder.library.languageVersionMinor);
if (libraryBuilder is DillLibraryBuilder) {
for (LibraryDependency dependency

View file

@ -78,8 +78,11 @@ Uint8List serializeComponent(Component component,
const String kDebugClassName = "#DebugClass";
Component createExpressionEvaluationComponent(Procedure procedure) {
Library fakeLibrary =
new Library(new Uri(scheme: 'evaluate', path: 'source'));
Library realLibrary = procedure.enclosingLibrary;
Library fakeLibrary = new Library(new Uri(scheme: 'evaluate', path: 'source'))
..setLanguageVersion(
realLibrary.languageVersionMajor, realLibrary.languageVersionMinor);
if (procedure.parent is Class) {
Class realClass = procedure.parent;

View file

@ -358,7 +358,9 @@ class SourceLibraryBuilder extends LibraryBuilder {
scope,
actualOrigin,
target ??
(actualOrigin?.library ?? new Library(uri, fileUri: fileUri)),
(actualOrigin?.library ?? new Library(uri, fileUri: fileUri)
..setLanguageVersion(loader.target.currentSdkVersionMajor,
loader.target.currentSdkVersionMinor)),
nameOrigin);
@override
@ -377,7 +379,7 @@ class SourceLibraryBuilder extends LibraryBuilder {
@override
void setLanguageVersion(int major, int minor,
{int offset: 0, int length: noLength, bool explicit}) {
{int offset: 0, int length: noLength, bool explicit: false}) {
if (languageVersionExplicitlySet) return;
if (explicit) languageVersionExplicitlySet = true;
@ -387,15 +389,15 @@ class SourceLibraryBuilder extends LibraryBuilder {
return;
}
// If trying to set a langauge version that is higher than the "sdk-one"
// it's an error.
if (major > Library.defaultLanguageVersionMajor ||
(major == Library.defaultLanguageVersionMajor &&
minor > Library.defaultLanguageVersionMinor)) {
// If trying to set a langauge version that is higher than the current sdk
// version it's an error.
if (major > loader.target.currentSdkVersionMajor ||
(major == loader.target.currentSdkVersionMajor &&
minor > loader.target.currentSdkVersionMinor)) {
addPostponedProblem(
templateLanguageVersionTooHigh.withArguments(
Library.defaultLanguageVersionMajor,
Library.defaultLanguageVersionMinor),
loader.target.currentSdkVersionMajor,
loader.target.currentSdkVersionMinor),
offset,
length,
fileUri);

View file

@ -214,9 +214,6 @@ class SourceLoader extends Loader {
enableExtensionMethods: target.enableExtensionMethods,
enableNonNullable: target.enableNonNullable),
languageVersionChanged: (_, LanguageVersionToken version) {
// TODO(jensj): What if we have several? What if it is unsupported?
// What if the language version was already set via packages and this is
// higher? Etc
library.setLanguageVersion(version.major, version.minor,
offset: version.offset, length: version.length, explicit: true);
});

View file

@ -153,4 +153,37 @@ abstract class TargetImplementation extends Target {
}
return rewriteSeverity(severity, message.code, fileUri);
}
String get currentSdkVersion {
return CompilerContext.current.options.currentSdkVersion;
}
int _currentSdkVersionMajor;
int _currentSdkVersionMinor;
int get currentSdkVersionMajor {
if (_currentSdkVersionMajor != null) return _currentSdkVersionMajor;
_parseCurrentSdkVersion();
return _currentSdkVersionMajor;
}
int get currentSdkVersionMinor {
if (_currentSdkVersionMinor != null) return _currentSdkVersionMinor;
_parseCurrentSdkVersion();
return _currentSdkVersionMinor;
}
void _parseCurrentSdkVersion() {
bool good = false;
if (currentSdkVersion != null) {
List<String> dotSeparatedParts = currentSdkVersion.split(".");
if (dotSeparatedParts.length >= 2) {
_currentSdkVersionMajor = int.tryParse(dotSeparatedParts[0]);
_currentSdkVersionMinor = int.tryParse(dotSeparatedParts[1]);
good = true;
}
}
if (!good) {
throw new StateError("Unparsable sdk version given: $currentSdkVersion");
}
}
}

View file

@ -44,6 +44,8 @@ class TestConfig {
final Map<ExperimentalFlag, bool> experimentalFlags;
const TestConfig(this.marker, this.name, {this.experimentalFlags = const {}});
void customizeCompilerOptions(CompilerOptions options) {}
}
// TODO(johnniwinther): Support annotations for compile-time errors.
@ -240,6 +242,7 @@ Future<bool> runTestForConfig<T>(
};
options.debugDump = printCode;
options.experimentalFlags.addAll(config.experimentalFlags);
config.customizeCompilerOptions(options);
InternalCompilerResult compilerResult = await compileScript(
testData.memorySourceFiles,
options: options,

View file

@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:io' show Directory, Platform;
import 'package:front_end/src/api_prototype/compiler_options.dart';
import 'package:front_end/src/fasta/messages.dart' show FormattedMessage;
import 'package:front_end/src/testing/id.dart' show ActualData, Id;
import 'package:front_end/src/testing/id_testing.dart'
@ -11,9 +12,9 @@ import 'package:front_end/src/testing/id_testing.dart';
import 'package:front_end/src/testing/id_testing_helper.dart'
show
CfeDataExtractor,
InternalCompilerResult,
DataComputer,
defaultCfeConfig,
InternalCompilerResult,
TestConfig,
createUriForFileName,
onFailure,
runTestFor;
@ -21,8 +22,9 @@ import 'package:kernel/ast.dart' show Library;
main(List<String> args) async {
// Fix default/max major and minor version so we can test it.
Library.defaultLanguageVersionMajor = 2;
Library.defaultLanguageVersionMinor = 8;
// This config sets it to 2.8.
TestConfigWithLanguageVersion cfeConfig =
new TestConfigWithLanguageVersion(cfeMarker, "cfe");
Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
await runTests(dataDir,
@ -30,8 +32,17 @@ main(List<String> args) async {
supportedMarkers: [cfeMarker],
createUriForFileName: createUriForFileName,
onFailure: onFailure,
runTest: runTestFor(
const LanguageVersioningDataComputer(), [defaultCfeConfig]));
runTest: runTestFor(const LanguageVersioningDataComputer(), [cfeConfig]));
}
class TestConfigWithLanguageVersion extends TestConfig {
TestConfigWithLanguageVersion(String marker, String name)
: super(marker, name);
@override
void customizeCompilerOptions(CompilerOptions options) {
options.currentSdkVersion = "2.8";
}
}
class LanguageVersioningDataComputer extends DataComputer<String> {

View file

@ -0,0 +1,61 @@
// 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 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 '../utils/io_utils.dart';
final String repoDir = computeRepoDir();
String get dartVm => Platform.executable;
main(List<String> args) async {
ProcessResult result = await Process.run(
"python", ["tools/make_version.py", "--no_git", "-q"],
workingDirectory: repoDir);
String stdout = result.stdout.toString();
String stderr = result.stderr.toString();
int exitCode = result.exitCode;
print("--- stdout ---");
print(stdout);
print("--- stderr ---");
print(stderr);
print("---exit code ---");
print(exitCode);
// E.g. "2.6.0-edge" (without the quotes).
String versionString = stdout.split("\n")[0];
List<String> dotSeparatedParts = versionString.split(".");
int major = int.tryParse(dotSeparatedParts[0]);
int minor = int.tryParse(dotSeparatedParts[1]);
if (kernel.Library.defaultLanguageVersionMajor != major ||
kernel.Library.defaultLanguageVersionMinor != minor) {
throw "Kernel defaults "
"${kernel.Library.defaultLanguageVersionMajor}"
"."
"${kernel.Library.defaultLanguageVersionMinor}"
" does not match output from make_version.py ($major.$minor)";
} else {
print("Kernel version matches.");
}
CompilerOptions compilerOptions = new CompilerOptions();
List<String> dotSeparatedPartsFromOptions =
compilerOptions.currentSdkVersion.split(".");
int majorFromOptions = int.tryParse(dotSeparatedPartsFromOptions[0]);
int minorFromOptions = int.tryParse(dotSeparatedPartsFromOptions[1]);
if (majorFromOptions != major || minorFromOptions != minor) {
throw "CompilerOptions defaults "
"${majorFromOptions}.${minorFromOptions}"
" does not match output from make_version.py ($major.$minor)";
} else {
print("CompilerOptions default version matches.");
}
}

View file

@ -709,6 +709,7 @@ server
service
setaf
sh
sha1hash
shadowed
shallow
shas

View file

@ -621,6 +621,7 @@ curly
current
currently
custom
customize
cyan
cycle
cycles
@ -1623,6 +1624,7 @@ mathematical
matter
maturity
max
maximum
may
maybe
mean
@ -2828,6 +2830,7 @@ unmodified
unnamed
unnecessarily
unnecessary
unparsable
unpromoted
unread
unrecognized
@ -2901,6 +2904,7 @@ verifies
verify
verifying
version
versioning
versions
vertex
vertical

View file

@ -270,6 +270,7 @@ pubspec
pv
px
py
python
quot
r"\s
rd

View file

@ -280,7 +280,7 @@ class Library extends NamedNode
// TODO(jensj): Do we have a better option than this?
static int defaultLanguageVersionMajor = 2;
static int defaultLanguageVersionMinor = 4;
static int defaultLanguageVersionMinor = 6;
int _languageVersionMajor;
int _languageVersionMinor;