Skip to content

Commit 3312fe3

Browse files
johnniwinthercommit-bot@chromium.org
authored andcommitted
[cfe] Fully support expired flags in CFE
This ensures that we can prohibit the disabling of an enabled and expired flag while still support the use of enum value in implementation code. Change-Id: Ib92c506365bb61853d6ff791461c5065acabcd4c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99173 Commit-Queue: Johnni Winther <[email protected]> Reviewed-by: Dan Rubel <[email protected]> Reviewed-by: Nicholas Shahan <[email protected]>
1 parent 5601eab commit 3312fe3

File tree

16 files changed

+141
-96
lines changed

16 files changed

+141
-96
lines changed

pkg/compiler/lib/src/dart2js.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,9 @@ Future<api.CompilationResult> compile(List<String> argv,
758758
diagnosticHandler.autoReadFileUri = true;
759759
CompilerOptions compilerOptions = CompilerOptions.parse(options,
760760
librariesSpecificationUri: librariesSpecificationUri,
761-
platformBinaries: platformBinaries)
761+
platformBinaries: platformBinaries,
762+
onError: (String message) => fail(message),
763+
onWarning: (String message) => print(message))
762764
..entryPoint = script
763765
..packageRoot = packageRoot
764766
..packageConfig = packageConfig

pkg/compiler/lib/src/options.dart

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -351,9 +351,12 @@ class CompilerOptions implements DiagnosticOptions {
351351

352352
/// Create an options object by parsing flags from [options].
353353
static CompilerOptions parse(List<String> options,
354-
{Uri librariesSpecificationUri, Uri platformBinaries}) {
354+
{Uri librariesSpecificationUri,
355+
Uri platformBinaries,
356+
void Function(String) onError,
357+
void Function(String) onWarning}) {
355358
Map<fe.ExperimentalFlag, bool> languageExperiments =
356-
_extractExperiments(options);
359+
_extractExperiments(options, onError: onError, onWarning: onWarning);
357360
if (equalMaps(languageExperiments, fe.defaultExperimentalFlags)) {
358361
platformBinaries ??= fe.computePlatformBinariesLocation();
359362
}
@@ -607,11 +610,14 @@ List<Uri> _extractUriListOption(List<String> options, String flag) {
607610
return stringUris.map(Uri.parse).toList();
608611
}
609612

610-
Map<fe.ExperimentalFlag, bool> _extractExperiments(List<String> options) {
613+
Map<fe.ExperimentalFlag, bool> _extractExperiments(List<String> options,
614+
{void Function(String) onError, void Function(String) onWarning}) {
611615
List<String> experiments =
612616
_extractOptionalCsvOption(options, Flags.enableLanguageExperiments);
613-
return fe.parseExperimentalFlags(
614-
experiments, (String error) => throw new ArgumentError(error));
617+
onError ??= (String error) => throw new ArgumentError(error);
618+
onWarning ??= (String warning) => print(warning);
619+
return fe.parseExperimentalFlags(fe.parseExperimentalArguments(experiments),
620+
onError: onError, onWarning: onWarning);
615621
}
616622

617623
const String _UNDETERMINED_BUILD_ID = "build number could not be determined";

pkg/dev_compiler/lib/src/compiler/shared_command.dart

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import 'dart:io';
77
import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
88
import 'package:args/args.dart';
99
import 'package:front_end/src/api_unstable/ddc.dart'
10-
show InitializedCompilerState;
10+
show InitializedCompilerState, parseExperimentalArguments;
1111
import 'package:path/path.dart' as p;
1212
import 'module_builder.dart';
1313
import '../analyzer/command.dart' as analyzer_compiler;
@@ -117,8 +117,8 @@ class SharedCompilerOptions {
117117
summarizeApi: args['summarize'] as bool,
118118
emitMetadata: args['emit-metadata'] as bool,
119119
enableAsserts: args['enable-asserts'] as bool,
120-
experiments:
121-
_parseExperiments(args['enable-experiment'] as List<String>),
120+
experiments: parseExperimentalArguments(
121+
args['enable-experiment'] as List<String>),
122122
bazelMapping:
123123
_parseBazelMappings(args['bazel-mapping'] as List<String>),
124124
summaryModules: _parseCustomSummaryModules(
@@ -232,20 +232,6 @@ Map<String, String> _parseCustomSummaryModules(List<String> summaryPaths,
232232
return pathToModule;
233233
}
234234

235-
Map<String, bool> _parseExperiments(List<String> arguments) {
236-
var result = <String, bool>{};
237-
for (var argument in arguments) {
238-
for (var feature in argument.split(',')) {
239-
if (feature.startsWith('no-')) {
240-
result[feature.substring(3)] = false;
241-
} else {
242-
result[feature] = true;
243-
}
244-
}
245-
}
246-
return result;
247-
}
248-
249235
Map<String, String> _parseBazelMappings(List<String> argument) {
250236
var mappings = <String, String>{};
251237
for (var mapping in argument) {

pkg/dev_compiler/lib/src/kernel/command.dart

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -227,17 +227,8 @@ Future<CompilerResult> _compile(List<String> args,
227227
fe.printDiagnosticMessage(message, print);
228228
}
229229

230-
var experiments = <fe.ExperimentalFlag, bool>{};
231-
for (var name in options.experiments.keys) {
232-
var flag = fe.parseExperimentalFlag(name);
233-
if (flag == fe.ExperimentalFlag.expiredFlag) {
234-
stderr.writeln("Flag '$name' is no longer required.");
235-
} else if (flag != null) {
236-
experiments[flag] = options.experiments[name];
237-
} else {
238-
stderr.writeln("Unknown experiment flag '$name'.");
239-
}
240-
}
230+
var experiments = fe.parseExperimentalFlags(options.experiments,
231+
onError: stderr.writeln, onWarning: print);
241232

242233
bool trackWidgetCreation =
243234
argResults['track-widget-creation'] as bool ?? false;

pkg/front_end/lib/src/api_prototype/compiler_options.dart

Lines changed: 69 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ import 'package:kernel/target/targets.dart' show Target;
99
import 'diagnostic_message.dart' show DiagnosticMessageHandler;
1010

1111
import 'experimental_flags.dart'
12-
show defaultExperimentalFlags, ExperimentalFlag, parseExperimentalFlag;
12+
show
13+
defaultExperimentalFlags,
14+
ExperimentalFlag,
15+
expiredExperimentalFlags,
16+
parseExperimentalFlag;
1317

1418
import 'file_system.dart' show FileSystem;
1519

@@ -213,40 +217,89 @@ class CompilerOptions {
213217
bool writeFileOnCrashReport = true;
214218
}
215219

216-
/// Parse experimental flags from a list of strings, each of which is either a
217-
/// flag name or a flag name prefixed by 'no-'. Return a map of flags to their
218-
/// values that can be passed to [experimentalFlags]. The returned map is
219-
/// normalized to contain default values for unmentioned flags.
220+
/// Parse experimental flag arguments of the form 'flag' or 'no-flag' into a map
221+
/// from 'flag' to `true` or `false`, respectively.
222+
Map<String, bool> parseExperimentalArguments(List<String> arguments) {
223+
Map<String, bool> result = {};
224+
if (arguments != null) {
225+
for (var argument in arguments) {
226+
for (var feature in argument.split(',')) {
227+
if (feature.startsWith('no-')) {
228+
result[feature.substring(3)] = false;
229+
} else {
230+
result[feature] = true;
231+
}
232+
}
233+
}
234+
}
235+
return result;
236+
}
237+
238+
/// Parse a map of experimental flags to values that can be passed to
239+
/// [CompilerOptions.experimentalFlags].
240+
/// The returned map is normalized to contain default values for unmentioned
241+
/// flags.
220242
///
221243
/// If an unknown flag is mentioned, or a flag is mentioned more than once,
222244
/// the supplied error handler is called with an error message.
245+
///
246+
/// If an expired flag is set to its non-default value the supplied error
247+
/// handler is called with an error message.
248+
///
249+
/// If an expired flag is set to its default value the supplied warning
250+
/// handler is called with a warning message.
223251
Map<ExperimentalFlag, bool> parseExperimentalFlags(
224-
Iterable<String> experiments, void onError(String message)) {
252+
Map<String, bool> experiments,
253+
{void onError(String message),
254+
void onWarning(String message)}) {
225255
Map<ExperimentalFlag, bool> flags = <ExperimentalFlag, bool>{};
226256
if (experiments != null) {
227-
for (String experiment in experiments) {
228-
bool value = true;
229-
if (experiment.startsWith("no-")) {
230-
value = false;
231-
experiment = experiment.substring(3);
232-
}
257+
for (String experiment in experiments.keys) {
258+
bool value = experiments[experiment];
233259
ExperimentalFlag flag = parseExperimentalFlag(experiment);
234260
if (flag == null) {
235261
onError("Unknown experiment: " + experiment);
236-
} else if (flag == ExperimentalFlag.expiredFlag) {
237-
print("Experiment flag no longer required: " + experiment);
238262
} else if (flags.containsKey(flag)) {
239263
if (flags[flag] != value) {
240264
onError(
241265
"Experiment specified with conflicting values: " + experiment);
242266
}
243267
} else {
244-
flags[flag] = value;
268+
if (expiredExperimentalFlags[flag]) {
269+
if (value != defaultExperimentalFlags[flag]) {
270+
/// Produce an error when the value is not the default value.
271+
if (value) {
272+
onError("Enabling experiment " +
273+
experiment +
274+
" is no longer supported.");
275+
} else {
276+
onError("Disabling experiment " +
277+
experiment +
278+
" is no longer supported.");
279+
}
280+
value = defaultExperimentalFlags[flag];
281+
} else if (onWarning != null) {
282+
/// Produce a warning when the value is the default value.
283+
if (value) {
284+
onWarning("Experiment " +
285+
experiment +
286+
" is enabled by default. "
287+
"The use of the flag is deprecated.");
288+
} else {
289+
onWarning("Experiment " +
290+
experiment +
291+
" is disabled by default. "
292+
"The use of the flag is deprecated.");
293+
}
294+
}
295+
flags[flag] = value;
296+
} else {
297+
flags[flag] = value;
298+
}
245299
}
246300
}
247301
}
248302
for (ExperimentalFlag flag in ExperimentalFlag.values) {
249-
if (flag == ExperimentalFlag.expiredFlag) continue;
250303
assert(defaultExperimentalFlags.containsKey(flag),
251304
"No default value for $flag.");
252305
flags[flag] ??= defaultExperimentalFlags[flag];

pkg/front_end/lib/src/api_prototype/experimental_flags.dart

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,9 @@ enum ExperimentalFlag {
1212
controlFlowCollections,
1313
extensionMethods,
1414
nonNullable,
15+
setLiterals,
1516
spreadCollections,
1617
tripleShift,
17-
18-
// A placeholder representing an "expired" flag which has been removed
19-
// from the codebase but still needs to be gracefully ignored
20-
// when specified on the command line.
21-
expiredFlag,
2218
}
2319

2420
ExperimentalFlag parseExperimentalFlag(String flag) {
@@ -31,14 +27,12 @@ ExperimentalFlag parseExperimentalFlag(String flag) {
3127
return ExperimentalFlag.extensionMethods;
3228
case "non-nullable":
3329
return ExperimentalFlag.nonNullable;
30+
case "set-literals":
31+
return ExperimentalFlag.setLiterals;
3432
case "spread-collections":
3533
return ExperimentalFlag.spreadCollections;
3634
case "triple-shift":
3735
return ExperimentalFlag.tripleShift;
38-
39-
// Expired flags
40-
case "set-literals":
41-
return ExperimentalFlag.expiredFlag;
4236
}
4337
return null;
4438
}
@@ -48,6 +42,17 @@ const Map<ExperimentalFlag, bool> defaultExperimentalFlags = {
4842
ExperimentalFlag.controlFlowCollections: true,
4943
ExperimentalFlag.extensionMethods: false,
5044
ExperimentalFlag.nonNullable: false,
45+
ExperimentalFlag.setLiterals: true,
5146
ExperimentalFlag.spreadCollections: true,
5247
ExperimentalFlag.tripleShift: false,
5348
};
49+
50+
const Map<ExperimentalFlag, bool> expiredExperimentalFlags = {
51+
ExperimentalFlag.constantUpdate2018: false,
52+
ExperimentalFlag.controlFlowCollections: false,
53+
ExperimentalFlag.extensionMethods: false,
54+
ExperimentalFlag.nonNullable: false,
55+
ExperimentalFlag.setLiterals: true,
56+
ExperimentalFlag.spreadCollections: false,
57+
ExperimentalFlag.tripleShift: false,
58+
};

pkg/front_end/lib/src/api_unstable/bazel_worker.dart

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
88
import 'dart:async' show Future;
99

10+
import 'package:front_end/src/api_prototype/compiler_options.dart';
1011
import 'package:kernel/kernel.dart' show Component, CanonicalName;
1112

1213
import 'package:kernel/target/targets.dart' show Target;
@@ -72,8 +73,9 @@ Future<InitializedCompilerState> initializeIncrementalCompiler(
7273
Map<Uri, WorkerInputComponent> workerInputCache =
7374
oldState?.workerInputCache ?? new Map<Uri, WorkerInputComponent>();
7475
bool startOver = false;
75-
Map<ExperimentalFlag, bool> experimentalFlags =
76-
parseExperimentalFlags(experiments, (e) => throw e);
76+
Map<ExperimentalFlag, bool> experimentalFlags = parseExperimentalFlags(
77+
parseExperimentalArguments(experiments),
78+
onError: (e) => throw e);
7779

7880
if (oldState == null ||
7981
oldState.incrementalCompiler == null ||
@@ -218,7 +220,9 @@ Future<InitializedCompilerState> initializeCompiler(
218220
..target = target
219221
..fileSystem = fileSystem
220222
..environmentDefines = const {}
221-
..experimentalFlags = parseExperimentalFlags(experiments, (e) => throw e);
223+
..experimentalFlags = parseExperimentalFlags(
224+
parseExperimentalArguments(experiments),
225+
onError: (e) => throw e);
222226

223227
ProcessedOptions processedOpts = new ProcessedOptions(options: options);
224228

pkg/front_end/lib/src/api_unstable/dart2js.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import 'compiler_state.dart' show InitializedCompilerState;
3939
import 'util.dart' show equalLists, equalMaps;
4040

4141
export '../api_prototype/compiler_options.dart'
42-
show CompilerOptions, parseExperimentalFlags;
42+
show CompilerOptions, parseExperimentalFlags, parseExperimentalArguments;
4343

4444
export '../api_prototype/diagnostic_message.dart'
4545
show

pkg/front_end/lib/src/api_unstable/ddc.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ import 'compiler_state.dart'
3131

3232
import 'util.dart' show equalLists, equalMaps;
3333

34-
export '../api_prototype/compiler_options.dart' show CompilerOptions;
34+
export '../api_prototype/compiler_options.dart'
35+
show CompilerOptions, parseExperimentalFlags, parseExperimentalArguments;
3536

3637
export '../api_prototype/diagnostic_message.dart' show DiagnosticMessage;
3738

pkg/front_end/lib/src/api_unstable/vm.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
export '../api_prototype/compiler_options.dart'
6-
show CompilerOptions, parseExperimentalFlags;
6+
show CompilerOptions, parseExperimentalArguments, parseExperimentalFlags;
77

88
export '../api_prototype/diagnostic_message.dart'
99
show DiagnosticMessage, DiagnosticMessageHandler, getMessageUri;

0 commit comments

Comments
 (0)