Version 2.17.0-83.0.dev
Merge commit '0fda2bfdaa50a2db7c0747e272b9aa7c688d1a82' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_raw_string.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_raw_string.dart
new file mode 100644
index 0000000..0ccd810
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_raw_string.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2022, 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:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/source/source_range.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class ConvertToRawString extends CorrectionProducer {
+ @override
+ bool get canBeAppliedInBulk => true;
+
+ @override
+ bool get canBeAppliedToFile => true;
+
+ @override
+ FixKind get fixKind => DartFixKind.CONVERT_TO_RAW_STRING;
+
+ @override
+ FixKind get multiFixKind => DartFixKind.CONVERT_TO_RAW_STRING_MULTI;
+
+ @override
+ Future<void> compute(ChangeBuilder builder) async {
+ var stringLiteral = node;
+ if ((stringLiteral is! SimpleStringLiteral) || stringLiteral.isRaw) {
+ return;
+ }
+
+ var literal = stringLiteral.literal;
+ var deletionOffsets = <int>[];
+ for (var offset = stringLiteral.contentsOffset;
+ offset < stringLiteral.contentsEnd;
+ offset++) {
+ var character = literal.lexeme[offset - literal.offset];
+ if (character == r'\') {
+ deletionOffsets.add(offset);
+ offset++;
+ }
+ }
+
+ await builder.addDartFileEdit(file, (builder) {
+ builder.addSimpleInsertion(stringLiteral.offset, 'r');
+ for (var offset in deletionOffsets) {
+ builder.addDeletion(SourceRange(offset, 1));
+ }
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ConvertToRawString newInstance() => ConvertToRawString();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index b4fb0b2..51f8992 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -508,6 +508,16 @@
DartFixKindPriority.IN_FILE,
"Convert to 'package:' imports everywhere in file",
);
+ static const CONVERT_TO_RAW_STRING = FixKind(
+ 'dart.fix.convert.toRawString',
+ DartFixKindPriority.DEFAULT,
+ 'Convert to raw string',
+ );
+ static const CONVERT_TO_RAW_STRING_MULTI = FixKind(
+ 'dart.fix.convert.toRawString.multi',
+ DartFixKindPriority.IN_FILE,
+ 'Convert to raw strings everywhere in file',
+ );
static const CONVERT_TO_RELATIVE_IMPORT = FixKind(
'dart.fix.convert.toRelativeImport',
DartFixKindPriority.DEFAULT,
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index bae5fc7..c3cdf0a 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -61,6 +61,7 @@
import 'package:analysis_server/src/services/correction/dart/convert_to_null_aware_spread.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_on_type.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_package_import.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_raw_string.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_relative_import.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_set_literal.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_where_type.dart';
@@ -630,6 +631,9 @@
LintNames.use_key_in_widget_constructors: [
AddKeyToConstructors.newInstance,
],
+ LintNames.use_raw_strings: [
+ ConvertToRawString.newInstance,
+ ],
LintNames.use_rethrow_when_possible: [
UseRethrow.newInstance,
],
diff --git a/pkg/analysis_server/lib/src/services/linter/lint_names.dart b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
index 90e9fbe..c5df9b7 100644
--- a/pkg/analysis_server/lib/src/services/linter/lint_names.dart
+++ b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
@@ -142,5 +142,6 @@
'use_function_type_syntax_for_parameters';
static const String use_key_in_widget_constructors =
'use_key_in_widget_constructors';
+ static const String use_raw_strings = 'use_raw_strings';
static const String use_rethrow_when_possible = 'use_rethrow_when_possible';
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_raw_string_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_raw_string_test.dart
new file mode 100644
index 0000000..7a0a79e
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_raw_string_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2022, 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:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertToRawStringBulkTest);
+ defineReflectiveTests(ConvertToRawStringTest);
+ });
+}
+
+@reflectiveTest
+class ConvertToRawStringBulkTest extends BulkFixProcessorTest {
+ @override
+ String get lintCode => LintNames.use_raw_strings;
+
+ Future<void> test_bulk() async {
+ await resolveTestCode(r"""
+var a = 'text \\ \$ \\\\' "\\" '${'\\'}';
+var b = '''
+text \\ \$ \\\\
+\\ \$ \\\\
+''';
+""");
+ await assertHasFix(r"""
+var a = r'text \ $ \\' r"\" '${r'\'}';
+var b = r'''
+text \ $ \\
+\ $ \\
+''';
+""");
+ }
+}
+
+@reflectiveTest
+class ConvertToRawStringTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.CONVERT_TO_RAW_STRING;
+
+ @override
+ String get lintCode => LintNames.use_raw_strings;
+
+ Future<void> test_doubleQuotes() async {
+ await resolveTestCode(r'var a = "text \\ \$ \\\\";');
+ await assertHasFix(r'var a = r"text \ $ \\";');
+ }
+
+ Future<void> test_multiLines() async {
+ await resolveTestCode(r"""
+var a = '''
+text \\ \$ \\\\
+\\ \$ \\\\
+''';
+""");
+ await assertHasFix(r"""
+var a = r'''
+text \ $ \\
+\ $ \\
+''';
+""");
+ }
+
+ Future<void> test_singleQuotes() async {
+ await resolveTestCode(r"var a = 'text \\ \$ \\\\';");
+ await assertHasFix(r"var a = r'text \ $ \\';");
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index 001e243..41969f1 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -75,6 +75,7 @@
import 'convert_to_null_aware_test.dart' as convert_to_null_aware;
import 'convert_to_on_type_test.dart' as convert_to_on_type;
import 'convert_to_package_import_test.dart' as convert_to_package_import;
+import 'convert_to_raw_string_test.dart' as convert_to_raw_string;
import 'convert_to_relative_import_test.dart' as convert_to_relative_import;
import 'convert_to_set_literal_test.dart' as convert_to_set_literal;
import 'convert_to_single_quoted_string_test.dart'
@@ -278,6 +279,7 @@
convert_to_null_aware_spread.main();
convert_to_on_type.main();
convert_to_package_import.main();
+ convert_to_raw_string.main();
convert_to_relative_import.main();
convert_to_set_literal.main();
convert_to_single_quoted_string.main();
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 a8355e8..5a6fc48 100644
--- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart
+++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
@@ -9,7 +9,7 @@
show DiagnosticMessage, DiagnosticMessageHandler;
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
-import 'package:kernel/ast.dart' show Version;
+import 'package:kernel/ast.dart' show Component, Version;
import 'package:kernel/default_language_version.dart' as kernel
show defaultLanguageVersion;
@@ -113,16 +113,32 @@
/// Function that creates a [MacroExecutor] if supported.
///
- /// This is an experimental feature.
+ /// This is part of the experimental macro feature.
Future<MacroExecutor> Function() macroExecutorProvider =
() async => throw 'Macro execution is not supported.';
/// Map from [MacroClass] to [Uri] for the precompiled dill that contains
/// the macro code.
///
- /// This is an experimental feature.
+ /// This is part of the experimental macro feature.
Map<MacroClass, Uri>? precompiledMacroUris;
+ /// The [Target] used for compiling macros.
+ ///
+ /// If `null`, macro declarations will not be precompiled, even when other
+ /// libraries depend on them.
+ /// This is part of the experimental macro feature.
+ Target? macroTarget;
+
+ /// Function that can create a [Uri] for the serialized result of a
+ /// [Component].
+ ///
+ /// This is used to turn a precompiled macro into a [Uri] that can be loaded
+ /// by the macro executor provided by [macroExecutorProvider].
+ ///
+ /// This is part of the experimental macro feature.
+ Future<Uri> Function(Component)? macroSerializer;
+
/// Whether to generate code for the SDK.
///
/// By default the front end resolves components using a prebuilt SDK summary.
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index e083a04..89836a7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1664,11 +1664,11 @@
return annotation;
}
- Arguments parseArguments(Token token) {
+ ArgumentsImpl parseArguments(Token token) {
Parser parser = new Parser(this,
useImplicitCreationExpression: useImplicitCreationExpressionInCfe);
token = parser.parseArgumentsRest(token);
- Arguments arguments = pop() as Arguments;
+ ArgumentsImpl arguments = pop() as ArgumentsImpl;
checkEmpty(token.charOffset);
return arguments;
}
@@ -1751,15 +1751,21 @@
} else if (initializers.last is RedirectingInitializer) {
RedirectingInitializer redirectingInitializer =
initializers.last as RedirectingInitializer;
- if (libraryBuilder.enableEnhancedEnumsInLibrary) {
- redirectingInitializer.arguments.positional.insertAll(0, [
+ if (sourceClassBuilder is SourceEnumBuilder &&
+ libraryBuilder.enableEnhancedEnumsInLibrary) {
+ ArgumentsImpl arguments =
+ redirectingInitializer.arguments as ArgumentsImpl;
+ List<Expression> enumSyntheticArguments = [
new VariableGetImpl(constructor.function.positionalParameters[0],
forNullGuardedAccess: false)
..parent = redirectingInitializer.arguments,
new VariableGetImpl(constructor.function.positionalParameters[1],
forNullGuardedAccess: false)
..parent = redirectingInitializer.arguments
- ]);
+ ];
+ arguments.positional.insertAll(0, enumSyntheticArguments);
+ arguments.argumentsOriginalOrder
+ ?.insertAll(0, enumSyntheticArguments);
}
}
@@ -1905,10 +1911,12 @@
List<Expression> positional;
List<NamedExpression> named;
if (libraryBuilder.enableNamedArgumentsAnywhereInLibrary) {
- positional =
- new List<Expression>.filled(positionalCount, dummyExpression);
+ positional = new List<Expression>.filled(
+ positionalCount, dummyExpression,
+ growable: true);
named = new List<NamedExpression>.filled(
- arguments.length - positionalCount, dummyNamedExpression);
+ arguments.length - positionalCount, dummyNamedExpression,
+ growable: true);
int positionalIndex = 0;
int namedIndex = 0;
for (int i = 0; i < arguments.length; i++) {
@@ -7337,11 +7345,13 @@
abstract class EnsureLoaded {
void ensureLoaded(Member? member);
+
bool isLoaded(Member? member);
}
class Operator {
final Token token;
+
String get name => token.stringValue!;
final int charOffset;
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index 88168b6..7d665b8 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -2810,7 +2810,9 @@
templateConstEvalGetterNotFound
.withArguments(variable.name ?? ''));
} else {
- if (variable.parent is Let || _isFormalParameter(variable)) {
+ if (variable.parent is Let ||
+ variable.parent is LocalInitializer ||
+ _isFormalParameter(variable)) {
return env.lookupVariable(node.variable) ??
createEvaluationErrorConstant(
node,
@@ -4117,6 +4119,7 @@
final EvaluationEnvironment? _parent;
EvaluationEnvironment() : _parent = null;
+
EvaluationEnvironment.withParent(this._parent);
/// Whether the current environment is empty.
@@ -4214,18 +4217,21 @@
/// Status that the statement returned a valid [Constant] value.
class ReturnStatus extends ExecutionStatus {
final Constant? value;
+
ReturnStatus(this.value);
}
/// Status with an exception or error that the statement has thrown.
class AbortStatus extends ExecutionStatus {
final AbortConstant error;
+
AbortStatus(this.error);
}
/// Status that the statement breaks out of an enclosing [LabeledStatement].
class BreakStatus extends ExecutionStatus {
final LabeledStatement target;
+
BreakStatus(this.target);
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 534c8bf..d01d2d8 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -391,13 +391,38 @@
builder.mixedInTypeBuilder = null;
}
- Future<BuildResult> buildOutlines({CanonicalName? nameRoot}) async {
- if (loader.first == null) return new BuildResult();
- return withCrashReporting<BuildResult>(() async {
+ bool _hasComputedNeededPrecompilations = false;
+
+ Future<NeededPrecompilations?> computeNeededPrecompilations() async {
+ assert(!_hasComputedNeededPrecompilations,
+ "Needed precompilations have already been computed.");
+ _hasComputedNeededPrecompilations = true;
+ if (loader.first == null) return null;
+ return withCrashReporting<NeededPrecompilations?>(() async {
await loader.buildOutlines();
loader.coreLibrary.becomeCoreLibrary();
loader.resolveParts();
- loader.computeMacroDeclarations();
+ return loader.computeMacroDeclarations();
+ }, () => loader.currentUriForCrashReporting);
+ }
+
+ Future<BuildResult> buildOutlines({CanonicalName? nameRoot}) async {
+ if (loader.first == null) return new BuildResult();
+ return withCrashReporting<BuildResult>(() async {
+ if (!_hasComputedNeededPrecompilations) {
+ NeededPrecompilations? neededPrecompilations =
+ await computeNeededPrecompilations();
+ // To support macros, the needed macro libraries must be compiled be
+ // they are applied. Any supporting pipeline must therefore call
+ // [computeNeededPrecompilations] before calling [buildOutlines] in
+ // order to perform any need compilation in advance.
+ //
+ // If [neededPrecompilations] is non-null here, it means that macro
+ // compilation was needed but not performed.
+ if (neededPrecompilations != null) {
+ throw new UnsupportedError('Macro precompilation is not supported.');
+ }
+ }
loader.computeLibraryScopes();
MacroApplications? macroApplications =
await loader.computeMacroApplications();
@@ -1587,7 +1612,9 @@
class BuildResult {
final Component? component;
+ final NeededPrecompilations? neededPrecompilations;
final MacroApplications? macroApplications;
- BuildResult({this.component, this.macroApplications});
+ BuildResult(
+ {this.component, this.macroApplications, this.neededPrecompilations});
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/macro.dart b/pkg/front_end/lib/src/fasta/kernel/macro.dart
index 3ec39e6..995a036 100644
--- a/pkg/front_end/lib/src/fasta/kernel/macro.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/macro.dart
@@ -98,6 +98,16 @@
Map<MemberBuilder, List<MacroApplication>> memberApplications = {};
}
+/// Macro classes that need to be precompiled.
+class NeededPrecompilations {
+ /// Map from library uris to macro class names and the names of constructor
+ /// their constructors is returned for macro classes that need to be
+ /// precompiled.
+ final Map<Uri, Map<String, List<String>>> macroDeclarations;
+
+ NeededPrecompilations(this.macroDeclarations);
+}
+
class MacroApplications {
final macro.MacroExecutor _macroExecutor;
final Map<SourceLibraryBuilder, LibraryMacroApplicationData> libraryData;
diff --git a/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart b/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
index b6040af..b6a5104 100644
--- a/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
@@ -590,7 +590,7 @@
MemberBuilder? constructorBuilder =
constructorScopeBuilder[constructorName];
- Arguments arguments;
+ ArgumentsImpl arguments;
List<Expression> enumSyntheticArguments = <Expression>[
new IntLiteral(index++),
new StringLiteral(constant),
@@ -623,11 +623,13 @@
bodyBuilder.performBacklogComputations(delayedActionPerformers);
arguments.positional.insertAll(0, enumSyntheticArguments);
+ arguments.argumentsOriginalOrder
+ ?.insertAll(0, enumSyntheticArguments);
} else {
arguments = new ArgumentsImpl(enumSyntheticArguments);
}
- if (typeArguments != null && arguments is ArgumentsImpl) {
+ if (typeArguments != null) {
ArgumentsImpl.setNonInferrableArgumentTypes(
arguments, typeArguments);
} else if (cls.typeParameters.isNotEmpty) {
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 c46a77f..e90cf3d 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -1358,10 +1358,8 @@
/// Computes which macro declarations that needs to be precompiled in order
/// to support macro application during compilation.
///
- /// If no macros need precompilation, `null` is returned. Otherwise a map
- /// from library uris to macro class names and the names of constructor their
- /// constructors is returned.
- Map<Uri, Map<String, List<String>>>? computeMacroDeclarations() {
+ /// If no macros need precompilation, `null` is returned.
+ NeededPrecompilations? computeMacroDeclarations() {
if (!enableMacros) return null;
LibraryBuilder? macroLibraryBuilder = lookupLibraryBuilder(macroLibraryUri);
@@ -1526,7 +1524,7 @@
// be more layers but we'll compute these at the next attempt at
// compilation, when this layer has been precompiled.
// TODO(johnniwinther): Use this to trigger a precompile step.
- return neededPrecompilations;
+ return new NeededPrecompilations(neededPrecompilations);
}
}
}
diff --git a/pkg/front_end/lib/src/kernel_generator_impl.dart b/pkg/front_end/lib/src/kernel_generator_impl.dart
index 948c756..990e8ed 100644
--- a/pkg/front_end/lib/src/kernel_generator_impl.dart
+++ b/pkg/front_end/lib/src/kernel_generator_impl.dart
@@ -5,37 +5,29 @@
/// Defines the front-end API for converting source code to Dart Kernel objects.
library front_end.kernel_generator_impl;
+import 'package:_fe_analyzer_shared/src/macros/bootstrap.dart';
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
-
import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/core_types.dart';
-import 'base/nnbd_mode.dart';
-
-import 'base/processed_options.dart' show ProcessedOptions;
-
-import 'fasta/compiler_context.dart' show CompilerContext;
-
-import 'fasta/crash.dart' show withCrashReporting;
-
-import 'fasta/dill/dill_target.dart' show DillTarget;
-
-import 'fasta/fasta_codes.dart' show LocatedMessage;
-
-import 'fasta/kernel/kernel_target.dart' show BuildResult, KernelTarget;
-
-import 'fasta/kernel/utils.dart' show printComponentText, serializeComponent;
-
-import 'fasta/kernel/verifier.dart' show verifyComponent;
-
-import 'fasta/source/source_loader.dart' show SourceLoader;
-
-import 'fasta/uri_translator.dart' show UriTranslator;
-
-import 'api_prototype/front_end.dart' show CompilerResult;
-
import 'api_prototype/file_system.dart' show FileSystem;
+import 'api_prototype/front_end.dart' show CompilerOptions, CompilerResult;
+import 'api_prototype/kernel_generator.dart';
+import 'api_prototype/memory_file_system.dart';
+import 'base/nnbd_mode.dart';
+import 'base/processed_options.dart' show ProcessedOptions;
+import 'fasta/compiler_context.dart' show CompilerContext;
+import 'fasta/crash.dart' show withCrashReporting;
+import 'fasta/dill/dill_target.dart' show DillTarget;
+import 'fasta/fasta_codes.dart' show LocatedMessage;
+import 'fasta/hybrid_file_system.dart';
+import 'fasta/kernel/kernel_target.dart' show BuildResult, KernelTarget;
+import 'fasta/kernel/macro.dart';
+import 'fasta/kernel/utils.dart' show printComponentText, serializeComponent;
+import 'fasta/kernel/verifier.dart' show verifyComponent;
+import 'fasta/source/source_loader.dart' show SourceLoader;
+import 'fasta/uri_translator.dart' show UriTranslator;
/// Implementation for the
/// `package:front_end/src/api_prototype/kernel_generator.dart` and
@@ -69,6 +61,7 @@
SourceLoader? sourceLoader;
return withCrashReporting<CompilerResult>(() async {
+ // TODO(johnniwinther): How much can we reuse between iterations?
UriTranslator uriTranslator = await options.getUriTranslator();
DillTarget dillTarget =
@@ -96,98 +89,138 @@
new KernelTarget(fs, false, dillTarget, uriTranslator);
sourceLoader = kernelTarget.loader;
kernelTarget.setEntryPoints(options.inputs);
- BuildResult buildResult =
- await kernelTarget.buildOutlines(nameRoot: nameRoot);
- Component summaryComponent = buildResult.component!;
- List<int>? summary = null;
- if (buildSummary) {
- if (options.verify) {
- for (LocatedMessage error
- in verifyComponent(summaryComponent, options.target)) {
- options.report(error, Severity.error);
+ NeededPrecompilations? neededPrecompilations =
+ await kernelTarget.computeNeededPrecompilations();
+ if (neededPrecompilations != null) {
+ if (enableMacros) {
+ // TODO(johnniwinther): Avoid using [rawOptionsForTesting] to compute
+ // the compiler options for the precompilation.
+ if (options.rawOptionsForTesting.macroTarget != null) {
+ await _compileMacros(
+ neededPrecompilations, options.rawOptionsForTesting);
}
+ } else {
+ throw new UnsupportedError('Macro precompilation is not supported');
}
- if (options.debugDump) {
- printComponentText(summaryComponent,
- libraryFilter: kernelTarget.isSourceLibraryForDebugging);
- }
-
- // Create the requested component ("truncating" or not).
- //
- // Note: we don't pass the library argument to the constructor to
- // preserve the libraries parent pointer (it should continue to point
- // to the component within KernelTarget).
- Component trimmedSummaryComponent =
- new Component(nameRoot: summaryComponent.root)
- ..libraries.addAll(truncateSummary
- ? kernelTarget.loader.libraries
- : summaryComponent.libraries);
- trimmedSummaryComponent.metadata.addAll(summaryComponent.metadata);
- trimmedSummaryComponent.uriToSource.addAll(summaryComponent.uriToSource);
-
- NonNullableByDefaultCompiledMode compiledMode =
- NonNullableByDefaultCompiledMode.Weak;
- switch (options.nnbdMode) {
- case NnbdMode.Weak:
- compiledMode = NonNullableByDefaultCompiledMode.Weak;
- break;
- case NnbdMode.Strong:
- compiledMode = NonNullableByDefaultCompiledMode.Strong;
- break;
- case NnbdMode.Agnostic:
- compiledMode = NonNullableByDefaultCompiledMode.Agnostic;
- break;
- }
- if (kernelTarget.loader.hasInvalidNnbdModeLibrary) {
- compiledMode = NonNullableByDefaultCompiledMode.Invalid;
- }
-
- trimmedSummaryComponent.setMainMethodAndMode(
- trimmedSummaryComponent.mainMethodName, false, compiledMode);
-
- // As documented, we only run outline transformations when we are building
- // summaries without building a full component (at this time, that's
- // the only need we have for these transformations).
- if (!buildComponent) {
- options.target.performOutlineTransformations(trimmedSummaryComponent);
- options.ticker.logMs("Transformed outline");
- }
- // Don't include source (but do add it above to include importUris).
- summary = serializeComponent(trimmedSummaryComponent,
- includeSources: false, includeOffsets: includeOffsets);
- options.ticker.logMs("Generated outline");
}
-
- Component? component;
- if (buildComponent) {
- buildResult = await kernelTarget.buildComponent(
- macroApplications: buildResult.macroApplications,
- verify: options.verify);
- component = buildResult.component;
- if (options.debugDump) {
- printComponentText(component,
- libraryFilter: kernelTarget.isSourceLibraryForDebugging);
- }
- options.ticker.logMs("Generated component");
- }
- // TODO(johnniwinther): Should we reuse the macro executor on subsequent
- // compilations where possible?
- buildResult.macroApplications?.close();
-
- return new InternalCompilerResult(
- summary: summary,
- component: component,
- sdkComponent: sdkSummary,
+ return _buildInternal(
+ options: options,
+ kernelTarget: kernelTarget,
+ nameRoot: nameRoot,
+ sdkSummary: sdkSummary,
loadedComponents: loadedComponents,
- classHierarchy:
- includeHierarchyAndCoreTypes ? kernelTarget.loader.hierarchy : null,
- coreTypes:
- includeHierarchyAndCoreTypes ? kernelTarget.loader.coreTypes : null,
- deps: new List<Uri>.of(CompilerContext.current.dependencies),
- kernelTargetForTesting: retainDataForTesting ? kernelTarget : null);
+ buildSummary: buildSummary,
+ truncateSummary: truncateSummary,
+ buildComponent: buildComponent,
+ includeOffsets: includeOffsets,
+ includeHierarchyAndCoreTypes: includeHierarchyAndCoreTypes,
+ retainDataForTesting: retainDataForTesting);
}, () => sourceLoader?.currentUriForCrashReporting ?? options.inputs.first);
}
+Future<CompilerResult> _buildInternal(
+ {required ProcessedOptions options,
+ required KernelTarget kernelTarget,
+ required CanonicalName nameRoot,
+ required Component? sdkSummary,
+ required List<Component> loadedComponents,
+ required bool buildSummary,
+ required bool truncateSummary,
+ required bool buildComponent,
+ required bool includeOffsets,
+ required bool includeHierarchyAndCoreTypes,
+ required bool retainDataForTesting}) async {
+ BuildResult buildResult =
+ await kernelTarget.buildOutlines(nameRoot: nameRoot);
+ Component summaryComponent = buildResult.component!;
+ List<int>? summary = null;
+ if (buildSummary) {
+ if (options.verify) {
+ for (LocatedMessage error
+ in verifyComponent(summaryComponent, options.target)) {
+ options.report(error, Severity.error);
+ }
+ }
+ if (options.debugDump) {
+ printComponentText(summaryComponent,
+ libraryFilter: kernelTarget.isSourceLibraryForDebugging);
+ }
+
+ // Create the requested component ("truncating" or not).
+ //
+ // Note: we don't pass the library argument to the constructor to
+ // preserve the libraries parent pointer (it should continue to point
+ // to the component within KernelTarget).
+ Component trimmedSummaryComponent =
+ new Component(nameRoot: summaryComponent.root)
+ ..libraries.addAll(truncateSummary
+ ? kernelTarget.loader.libraries
+ : summaryComponent.libraries);
+ trimmedSummaryComponent.metadata.addAll(summaryComponent.metadata);
+ trimmedSummaryComponent.uriToSource.addAll(summaryComponent.uriToSource);
+
+ NonNullableByDefaultCompiledMode compiledMode =
+ NonNullableByDefaultCompiledMode.Weak;
+ switch (options.nnbdMode) {
+ case NnbdMode.Weak:
+ compiledMode = NonNullableByDefaultCompiledMode.Weak;
+ break;
+ case NnbdMode.Strong:
+ compiledMode = NonNullableByDefaultCompiledMode.Strong;
+ break;
+ case NnbdMode.Agnostic:
+ compiledMode = NonNullableByDefaultCompiledMode.Agnostic;
+ break;
+ }
+ if (kernelTarget.loader.hasInvalidNnbdModeLibrary) {
+ compiledMode = NonNullableByDefaultCompiledMode.Invalid;
+ }
+
+ trimmedSummaryComponent.setMainMethodAndMode(
+ trimmedSummaryComponent.mainMethodName, false, compiledMode);
+
+ // As documented, we only run outline transformations when we are building
+ // summaries without building a full component (at this time, that's
+ // the only need we have for these transformations).
+ if (!buildComponent) {
+ options.target.performOutlineTransformations(trimmedSummaryComponent);
+ options.ticker.logMs("Transformed outline");
+ }
+ // Don't include source (but do add it above to include importUris).
+ summary = serializeComponent(trimmedSummaryComponent,
+ includeSources: false, includeOffsets: includeOffsets);
+ options.ticker.logMs("Generated outline");
+ }
+
+ Component? component;
+ if (buildComponent) {
+ buildResult = await kernelTarget.buildComponent(
+ macroApplications: buildResult.macroApplications,
+ verify: options.verify);
+ component = buildResult.component;
+ if (options.debugDump) {
+ printComponentText(component,
+ libraryFilter: kernelTarget.isSourceLibraryForDebugging);
+ }
+ options.ticker.logMs("Generated component");
+ }
+ // TODO(johnniwinther): Should we reuse the macro executor on subsequent
+ // compilations where possible?
+ buildResult.macroApplications?.close();
+
+ return new InternalCompilerResult(
+ summary: summary,
+ component: component,
+ sdkComponent: sdkSummary,
+ loadedComponents: loadedComponents,
+ classHierarchy:
+ includeHierarchyAndCoreTypes ? kernelTarget.loader.hierarchy : null,
+ coreTypes:
+ includeHierarchyAndCoreTypes ? kernelTarget.loader.coreTypes : null,
+ deps: new List<Uri>.from(CompilerContext.current.dependencies),
+ kernelTargetForTesting: retainDataForTesting ? kernelTarget : null);
+}
+
/// Result object of [generateKernel].
class InternalCompilerResult implements CompilerResult {
/// The generated summary bytes, if it was requested.
@@ -232,3 +265,52 @@
this.coreTypes,
this.kernelTargetForTesting});
}
+
+/// A fake absolute directory used as the root of a memory-file system in the
+/// compilation below.
+Uri _defaultDir = Uri.parse('org-dartlang-macro:///a/b/c/');
+
+Future<void> _compileMacros(NeededPrecompilations neededPrecompilations,
+ CompilerOptions options) async {
+ assert(options.macroSerializer != null);
+ CompilerOptions precompilationOptions = new CompilerOptions();
+ precompilationOptions.target = options.macroTarget;
+ precompilationOptions.explicitExperimentalFlags =
+ options.explicitExperimentalFlags;
+ // TODO(johnniwinther): What is the right environment when it isn't passed
+ // by the caller? Dart2js calls the CFE without an environment, but it's
+ // macros likely need them.
+ precompilationOptions.environmentDefines = options.environmentDefines ?? {};
+ precompilationOptions.packagesFileUri = options.packagesFileUri;
+ precompilationOptions.precompiledMacroUris = options.precompiledMacroUris;
+ // TODO(johnniwinther): What if sdk root isn't set? How do we then get the
+ // right sdk?
+ precompilationOptions.sdkRoot = options.sdkRoot;
+ precompilationOptions.macroExecutorProvider = options.macroExecutorProvider;
+
+ Map<String, Map<String, List<String>>> macroDeclarations = {};
+ neededPrecompilations.macroDeclarations
+ .forEach((Uri uri, Map<String, List<String>> macroClasses) {
+ macroDeclarations[uri.toString()] = macroClasses;
+ });
+
+ Uri uri = _defaultDir.resolve('main.dart');
+ MemoryFileSystem fs = new MemoryFileSystem(_defaultDir);
+ fs
+ .entityForUri(uri)
+ .writeAsStringSync(bootstrapMacroIsolate(macroDeclarations));
+
+ precompilationOptions..fileSystem = new HybridFileSystem(fs);
+ CompilerResult? compilerResult =
+ await kernelForProgramInternal(uri, precompilationOptions);
+ Uri precompiledUri =
+ await options.macroSerializer!(compilerResult!.component!);
+ Map<MacroClass, Uri> precompiledMacroUris =
+ options.precompiledMacroUris ??= {};
+ neededPrecompilations.macroDeclarations
+ .forEach((Uri uri, Map<String, List<String>> macroClasses) {
+ for (String macroClass in macroClasses.keys) {
+ precompiledMacroUris[new MacroClass(uri, macroClass)] = precompiledUri;
+ }
+ });
+}
diff --git a/pkg/front_end/test/macro_application/macro_application_test.dart b/pkg/front_end/test/macro_application/macro_application_test.dart
index 42cbb6a..a32cae5 100644
--- a/pkg/front_end/test/macro_application/macro_application_test.dart
+++ b/pkg/front_end/test/macro_application/macro_application_test.dart
@@ -5,7 +5,6 @@
import 'dart:io' show Directory, Platform;
import 'package:_fe_analyzer_shared/src/macros/api.dart';
-import 'package:_fe_analyzer_shared/src/macros/bootstrap.dart';
import 'package:_fe_analyzer_shared/src/macros/executor.dart';
import 'package:_fe_analyzer_shared/src/macros/isolated_executor/isolated_executor.dart'
as isolatedExecutor;
@@ -14,13 +13,11 @@
import 'package:_fe_analyzer_shared/src/testing/id_testing.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/fasta/builder/field_builder.dart';
import 'package:front_end/src/fasta/builder/member_builder.dart';
import 'package:front_end/src/fasta/kernel/macro.dart';
import 'package:front_end/src/fasta/kernel/utils.dart';
import 'package:front_end/src/fasta/source/source_class_builder.dart';
-import 'package:front_end/src/testing/compiler_common.dart';
import 'package:front_end/src/testing/id_extractor.dart';
import 'package:front_end/src/testing/id_testing_helper.dart';
import 'package:kernel/ast.dart' hide Arguments;
@@ -28,67 +25,32 @@
import 'package:kernel/target/targets.dart';
import 'package:vm/target/vm.dart';
-const Map<String, Map<String, List<String>>> macroDeclarations = {
- 'package:macro/macro.dart': {
- 'FunctionDefinitionMacro1': [''],
- 'FunctionDefinitionMacro2': [''],
- 'FunctionTypesMacro1': [''],
- 'FunctionDeclarationsMacro1': [''],
- 'FunctionDeclarationsMacro2': [''],
- 'MethodDeclarationsMacro1': [''],
- 'VariableDeclarationsMacro1': [''],
- 'FieldDeclarationsMacro1': [''],
- 'ClassDeclarationsMacro1': [''],
- 'ConstructorDeclarationsMacro1': [''],
- }
-};
-
-Future<Uri> compileMacros(Directory directory) async {
- CompilerOptions options = new CompilerOptions();
- options.target = new VmTarget(new TargetFlags());
- options.explicitExperimentalFlags[ExperimentalFlag.macros] = true;
- options.environmentDefines = {};
- options.packagesFileUri = Platform.script.resolve('data/package_config.json');
-
- CompilerResult? compilerResult = await compileScript(
- {'main.dart': bootstrapMacroIsolate(macroDeclarations)},
- options: options, requireMain: false);
- Uri uri = directory.absolute.uri.resolve('macros.dill');
- await writeComponentToFile(compilerResult!.component!, uri);
- return uri;
-}
-
Future<void> main(List<String> args) async {
enableMacros = true;
Directory tempDirectory =
await Directory.systemTemp.createTemp('macro_application');
-
- Uri macrosUri = await compileMacros(tempDirectory);
- Map<MacroClass, Uri> precompiledMacroUris = {};
- macroDeclarations
- .forEach((String macroUri, Map<String, List<String>> macroClasses) {
- macroClasses.forEach((String macroClass, List<String> constructorNames) {
- precompiledMacroUris[new MacroClass(Uri.parse(macroUri), macroClass)] =
- macrosUri;
- });
- });
-
- Directory dataDir =
- new Directory.fromUri(Platform.script.resolve('data/tests'));
- await runTests<String>(dataDir,
- args: args,
- createUriForFileName: createUriForFileName,
- onFailure: onFailure,
- runTest: runTestFor(const MacroDataComputer(),
- [new MacroTestConfig(precompiledMacroUris)]),
- preserveWhitespaceInAnnotations: true);
+ try {
+ Directory dataDir =
+ new Directory.fromUri(Platform.script.resolve('data/tests'));
+ await runTests<String>(dataDir,
+ args: args,
+ createUriForFileName: createUriForFileName,
+ onFailure: onFailure,
+ runTest: runTestFor(
+ const MacroDataComputer(), [new MacroTestConfig(tempDirectory)]),
+ preserveWhitespaceInAnnotations: true);
+ } finally {
+ await tempDirectory.delete(recursive: true);
+ }
}
class MacroTestConfig extends TestConfig {
- final Map<MacroClass, Uri> precompiledMacroUris;
+ final Directory tempDirectory;
+ int precompiledCount = 0;
+ final Map<MacroClass, Uri> precompiledMacroUris = {};
- MacroTestConfig(this.precompiledMacroUris)
+ MacroTestConfig(this.tempDirectory)
: super(cfeMarker, 'cfe',
explicitExperimentalFlags: {ExperimentalFlag.macros: true},
packageConfigUri:
@@ -100,6 +62,13 @@
return await isolatedExecutor.start();
};
options.precompiledMacroUris = precompiledMacroUris;
+ options.macroTarget = new VmTarget(new TargetFlags());
+ options.macroSerializer = (Component component) async {
+ Uri uri = tempDirectory.absolute.uri
+ .resolve('macros${precompiledCount++}.dill');
+ await writeComponentToFile(component, uri);
+ return uri;
+ };
}
}
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 5226583..7ddc634 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -901,6 +901,7 @@
precompilations
precompile
precompiled
+precompiling
preexisted
preexisting
prefixing
diff --git a/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart b/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart
new file mode 100644
index 0000000..47f596b
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2022, 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.
+
+class C {
+ String log = "";
+
+ C(int x, int y, {int z = 42}) {
+ log = "x=$x, y=$y, z=$z";
+ }
+
+ C.named1(int x, int y, int z) : this(x, y, z: z);
+}
+
+main() {
+ expect("x=1, y=2, z=3", C(1, 2, z: 3).log);
+ expect("x=1, y=2, z=3", C.named1(1, 2, 3).log);
+}
+
+expect(expected, actual) {
+ if (expected != actual) throw 'Expected $expected, actual $actual';
+}
diff --git a/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.strong.expect b/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.strong.expect
new file mode 100644
index 0000000..b3c69f0
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.strong.expect
@@ -0,0 +1,26 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ field core::String log = "";
+ constructor •(core::int x, core::int y, {core::int z = #C1}) → self::C
+ : super core::Object::•() {
+ this.{self::C::log} = "x=${x}, y=${y}, z=${z}";
+ }
+ constructor named1(core::int x, core::int y, core::int z) → self::C
+ : this self::C::•(x, y, z: z)
+ ;
+}
+static method main() → dynamic {
+ self::expect("x=1, y=2, z=3", new self::C::•(1, 2, z: 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named1(1, 2, 3).{self::C::log}{core::String});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = 42
+}
diff --git a/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.strong.transformed.expect
new file mode 100644
index 0000000..b3c69f0
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.strong.transformed.expect
@@ -0,0 +1,26 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ field core::String log = "";
+ constructor •(core::int x, core::int y, {core::int z = #C1}) → self::C
+ : super core::Object::•() {
+ this.{self::C::log} = "x=${x}, y=${y}, z=${z}";
+ }
+ constructor named1(core::int x, core::int y, core::int z) → self::C
+ : this self::C::•(x, y, z: z)
+ ;
+}
+static method main() → dynamic {
+ self::expect("x=1, y=2, z=3", new self::C::•(1, 2, z: 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named1(1, 2, 3).{self::C::log}{core::String});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = 42
+}
diff --git a/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..88d946e
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class C {
+ String log = "";
+ C(int x, int y, {int z = 42}) {}
+ C.named1(int x, int y, int z) : this(x, y, z: z);
+}
+
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..055fa68
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class C {
+ C(int x, int y, {int z = 42}) {}
+ C.named1(int x, int y, int z) : this(x, y, z: z);
+ String log = "";
+}
+
+expect(expected, actual) {}
+main() {}
diff --git a/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.weak.expect b/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.weak.expect
new file mode 100644
index 0000000..b3c69f0
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.weak.expect
@@ -0,0 +1,26 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ field core::String log = "";
+ constructor •(core::int x, core::int y, {core::int z = #C1}) → self::C
+ : super core::Object::•() {
+ this.{self::C::log} = "x=${x}, y=${y}, z=${z}";
+ }
+ constructor named1(core::int x, core::int y, core::int z) → self::C
+ : this self::C::•(x, y, z: z)
+ ;
+}
+static method main() → dynamic {
+ self::expect("x=1, y=2, z=3", new self::C::•(1, 2, z: 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named1(1, 2, 3).{self::C::log}{core::String});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = 42
+}
diff --git a/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.weak.modular.expect b/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.weak.modular.expect
new file mode 100644
index 0000000..b3c69f0
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.weak.modular.expect
@@ -0,0 +1,26 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ field core::String log = "";
+ constructor •(core::int x, core::int y, {core::int z = #C1}) → self::C
+ : super core::Object::•() {
+ this.{self::C::log} = "x=${x}, y=${y}, z=${z}";
+ }
+ constructor named1(core::int x, core::int y, core::int z) → self::C
+ : this self::C::•(x, y, z: z)
+ ;
+}
+static method main() → dynamic {
+ self::expect("x=1, y=2, z=3", new self::C::•(1, 2, z: 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named1(1, 2, 3).{self::C::log}{core::String});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = 42
+}
diff --git a/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.weak.outline.expect b/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.weak.outline.expect
new file mode 100644
index 0000000..36d2092
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.weak.outline.expect
@@ -0,0 +1,15 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ field core::String log;
+ constructor •(core::int x, core::int y, {core::int z = 42}) → self::C
+ ;
+ constructor named1(core::int x, core::int y, core::int z) → self::C
+ ;
+}
+static method main() → dynamic
+ ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.weak.transformed.expect
new file mode 100644
index 0000000..b3c69f0
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/class_redirecting_initializer.dart.weak.transformed.expect
@@ -0,0 +1,26 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ field core::String log = "";
+ constructor •(core::int x, core::int y, {core::int z = #C1}) → self::C
+ : super core::Object::•() {
+ this.{self::C::log} = "x=${x}, y=${y}, z=${z}";
+ }
+ constructor named1(core::int x, core::int y, core::int z) → self::C
+ : this self::C::•(x, y, z: z)
+ ;
+}
+static method main() → dynamic {
+ self::expect("x=1, y=2, z=3", new self::C::•(1, 2, z: 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named1(1, 2, 3).{self::C::log}{core::String});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = 42
+}
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/folder.options b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/folder.options
new file mode 100644
index 0000000..c0139f7
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/folder.options
@@ -0,0 +1 @@
+--enable-experiment=enhanced-enums,named-arguments-anywhere
\ No newline at end of file
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart
new file mode 100644
index 0000000..73290e0
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2022, 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.
+
+class C {
+ String log = "";
+
+ C(int x, int y, {int z = 42}) {
+ log = "x=$x, y=$y, z=$z";
+ }
+
+ C.named1(int x, int y, int z) : this(x, y, z: z);
+ C.named2(int x, int y, int z) : this(x, z: z, y);
+ C.named3(int x, int y, int z) : this(z: z, x, y);
+}
+
+main() {
+ expect("x=1, y=2, z=3", C(1, 2, z: 3).log);
+ expect("x=1, y=2, z=3", C(z: 3, 1, 2).log);
+ expect("x=1, y=2, z=3", C(1, z: 3, 2).log);
+ expect("x=1, y=2, z=3", C.named1(1, 2, 3).log);
+ expect("x=1, y=2, z=3", C.named2(1, 2, 3).log);
+ expect("x=1, y=2, z=3", C.named3(1, 2, 3).log);
+}
+
+expect(expected, actual) {
+ if (expected != actual) throw 'Expected $expected, actual $actual';
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.strong.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.strong.expect
new file mode 100644
index 0000000..af3e1a4
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.strong.expect
@@ -0,0 +1,36 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ field core::String log = "";
+ constructor •(core::int x, core::int y, {core::int z = #C1}) → self::C
+ : super core::Object::•() {
+ this.{self::C::log} = "x=${x}, y=${y}, z=${z}";
+ }
+ constructor named1(core::int x, core::int y, core::int z) → self::C
+ : this self::C::•(x, y, z: z)
+ ;
+ constructor named2(core::int x, core::int y, core::int z) → self::C
+ : final core::int #t1 = x, final core::int #t2 = z, this self::C::•(#t1, y, z: #t2)
+ ;
+ constructor named3(core::int x, core::int y, core::int z) → self::C
+ : final core::int #t3 = z, this self::C::•(x, y, z: #t3)
+ ;
+}
+static method main() → dynamic {
+ self::expect("x=1, y=2, z=3", new self::C::•(1, 2, z: 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", (let final core::int #t4 = 3 in new self::C::•(1, 2, z: #t4)).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", (let final core::int #t5 = 1 in let final core::int #t6 = 3 in new self::C::•(#t5, 2, z: #t6)).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named1(1, 2, 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named2(1, 2, 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named3(1, 2, 3).{self::C::log}{core::String});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = 42
+}
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.strong.transformed.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.strong.transformed.expect
new file mode 100644
index 0000000..233e403
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.strong.transformed.expect
@@ -0,0 +1,42 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ field core::String log = "";
+ constructor •(core::int x, core::int y, {core::int z = #C1}) → self::C
+ : super core::Object::•() {
+ this.{self::C::log} = "x=${x}, y=${y}, z=${z}";
+ }
+ constructor named1(core::int x, core::int y, core::int z) → self::C
+ : this self::C::•(x, y, z: z)
+ ;
+ constructor named2(core::int x, core::int y, core::int z) → self::C
+ : final core::int #t1 = x, final core::int #t2 = z, this self::C::•(#t1, y, z: #t2)
+ ;
+ constructor named3(core::int x, core::int y, core::int z) → self::C
+ : final core::int #t3 = z, this self::C::•(x, y, z: #t3)
+ ;
+}
+static method main() → dynamic {
+ self::expect("x=1, y=2, z=3", new self::C::•(1, 2, z: 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", (let final core::int #t4 = 3 in new self::C::•(1, 2, z: #t4)).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", (let final core::int #t5 = 1 in let final core::int #t6 = 3 in new self::C::•(#t5, 2, z: #t6)).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named1(1, 2, 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named2(1, 2, 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named3(1, 2, 3).{self::C::log}{core::String});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = 42
+}
+
+Extra constant evaluation status:
+Evaluated: VariableGet @ org-dartlang-testcase:///issue48276.dart:19:32 -> IntConstant(3)
+Evaluated: VariableGet @ org-dartlang-testcase:///issue48276.dart:20:29 -> IntConstant(1)
+Evaluated: VariableGet @ org-dartlang-testcase:///issue48276.dart:20:35 -> IntConstant(3)
+Extra constant evaluation: evaluated: 50, effectively constant: 3
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.textual_outline.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.textual_outline.expect
new file mode 100644
index 0000000..ecd5096
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class C {
+ String log = "";
+ C(int x, int y, {int z = 42}) {}
+ C.named1(int x, int y, int z) : this(x, y, z: z);
+ C.named2(int x, int y, int z) : this(x, z: z, y);
+ C.named3(int x, int y, int z) : this(z: z, x, y);
+}
+
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6df982e
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class C {
+ C(int x, int y, {int z = 42}) {}
+ C.named1(int x, int y, int z) : this(x, y, z: z);
+ C.named2(int x, int y, int z) : this(x, z: z, y);
+ C.named3(int x, int y, int z) : this(z: z, x, y);
+ String log = "";
+}
+
+expect(expected, actual) {}
+main() {}
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.weak.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.weak.expect
new file mode 100644
index 0000000..af3e1a4
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.weak.expect
@@ -0,0 +1,36 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ field core::String log = "";
+ constructor •(core::int x, core::int y, {core::int z = #C1}) → self::C
+ : super core::Object::•() {
+ this.{self::C::log} = "x=${x}, y=${y}, z=${z}";
+ }
+ constructor named1(core::int x, core::int y, core::int z) → self::C
+ : this self::C::•(x, y, z: z)
+ ;
+ constructor named2(core::int x, core::int y, core::int z) → self::C
+ : final core::int #t1 = x, final core::int #t2 = z, this self::C::•(#t1, y, z: #t2)
+ ;
+ constructor named3(core::int x, core::int y, core::int z) → self::C
+ : final core::int #t3 = z, this self::C::•(x, y, z: #t3)
+ ;
+}
+static method main() → dynamic {
+ self::expect("x=1, y=2, z=3", new self::C::•(1, 2, z: 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", (let final core::int #t4 = 3 in new self::C::•(1, 2, z: #t4)).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", (let final core::int #t5 = 1 in let final core::int #t6 = 3 in new self::C::•(#t5, 2, z: #t6)).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named1(1, 2, 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named2(1, 2, 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named3(1, 2, 3).{self::C::log}{core::String});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = 42
+}
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.weak.modular.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.weak.modular.expect
new file mode 100644
index 0000000..af3e1a4
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.weak.modular.expect
@@ -0,0 +1,36 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ field core::String log = "";
+ constructor •(core::int x, core::int y, {core::int z = #C1}) → self::C
+ : super core::Object::•() {
+ this.{self::C::log} = "x=${x}, y=${y}, z=${z}";
+ }
+ constructor named1(core::int x, core::int y, core::int z) → self::C
+ : this self::C::•(x, y, z: z)
+ ;
+ constructor named2(core::int x, core::int y, core::int z) → self::C
+ : final core::int #t1 = x, final core::int #t2 = z, this self::C::•(#t1, y, z: #t2)
+ ;
+ constructor named3(core::int x, core::int y, core::int z) → self::C
+ : final core::int #t3 = z, this self::C::•(x, y, z: #t3)
+ ;
+}
+static method main() → dynamic {
+ self::expect("x=1, y=2, z=3", new self::C::•(1, 2, z: 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", (let final core::int #t4 = 3 in new self::C::•(1, 2, z: #t4)).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", (let final core::int #t5 = 1 in let final core::int #t6 = 3 in new self::C::•(#t5, 2, z: #t6)).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named1(1, 2, 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named2(1, 2, 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named3(1, 2, 3).{self::C::log}{core::String});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = 42
+}
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.weak.outline.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.weak.outline.expect
new file mode 100644
index 0000000..3724069
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.weak.outline.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ field core::String log;
+ constructor •(core::int x, core::int y, {core::int z = 42}) → self::C
+ ;
+ constructor named1(core::int x, core::int y, core::int z) → self::C
+ ;
+ constructor named2(core::int x, core::int y, core::int z) → self::C
+ ;
+ constructor named3(core::int x, core::int y, core::int z) → self::C
+ ;
+}
+static method main() → dynamic
+ ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.weak.transformed.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.weak.transformed.expect
new file mode 100644
index 0000000..233e403
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/issue48276.dart.weak.transformed.expect
@@ -0,0 +1,42 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ field core::String log = "";
+ constructor •(core::int x, core::int y, {core::int z = #C1}) → self::C
+ : super core::Object::•() {
+ this.{self::C::log} = "x=${x}, y=${y}, z=${z}";
+ }
+ constructor named1(core::int x, core::int y, core::int z) → self::C
+ : this self::C::•(x, y, z: z)
+ ;
+ constructor named2(core::int x, core::int y, core::int z) → self::C
+ : final core::int #t1 = x, final core::int #t2 = z, this self::C::•(#t1, y, z: #t2)
+ ;
+ constructor named3(core::int x, core::int y, core::int z) → self::C
+ : final core::int #t3 = z, this self::C::•(x, y, z: #t3)
+ ;
+}
+static method main() → dynamic {
+ self::expect("x=1, y=2, z=3", new self::C::•(1, 2, z: 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", (let final core::int #t4 = 3 in new self::C::•(1, 2, z: #t4)).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", (let final core::int #t5 = 1 in let final core::int #t6 = 3 in new self::C::•(#t5, 2, z: #t6)).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named1(1, 2, 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named2(1, 2, 3).{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", new self::C::named3(1, 2, 3).{self::C::log}{core::String});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = 42
+}
+
+Extra constant evaluation status:
+Evaluated: VariableGet @ org-dartlang-testcase:///issue48276.dart:19:32 -> IntConstant(3)
+Evaluated: VariableGet @ org-dartlang-testcase:///issue48276.dart:20:29 -> IntConstant(1)
+Evaluated: VariableGet @ org-dartlang-testcase:///issue48276.dart:20:35 -> IntConstant(3)
+Extra constant evaluation: evaluated: 50, effectively constant: 3
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart
new file mode 100644
index 0000000..e5f467c
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2022, 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.
+
+enum C {
+ a(1, 2, z: 3),
+ b(z: 3, 1, 2),
+ c(1, z: 3, 2),
+ d.named1(1, 2, 3),
+ e.named2(1, 2, 3),
+ f.named3(1, 2, 3),
+ ;
+
+ final String log;
+
+ const C(int x, int y, {int z = 42})
+ : this.log = "x=$x, y=$y, z=$z";
+
+ const C.named1(int x, int y, int z) : this(x, y, z: z);
+ const C.named2(int x, int y, int z) : this(x, z: z, y);
+ const C.named3(int x, int y, int z) : this(z: z, x, y);
+}
+
+main() {
+ expect("x=1, y=2, z=3", C.a.log);
+ expect("x=1, y=2, z=3", C.b.log);
+ expect("x=1, y=2, z=3", C.c.log);
+ expect("x=1, y=2, z=3", C.d.log);
+ expect("x=1, y=2, z=3", C.e.log);
+ expect("x=1, y=2, z=3", C.f.log);
+}
+
+expect(expected, actual) {
+ if (expected != actual) throw 'Expected $expected, actual $actual';
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.strong.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.strong.expect
new file mode 100644
index 0000000..6b5605e
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.strong.expect
@@ -0,0 +1,74 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::C> values = #C20;
+ static const field self::C a = #C4;
+ static const field self::C b = #C7;
+ static const field self::C c = #C10;
+ static const field self::C d = #C13;
+ static const field self::C e = #C16;
+ static const field self::C f = #C19;
+ final field core::String log;
+ const constructor •(core::int index, core::String name, core::int x, core::int y, {core::int z = #C21}) → self::C
+ : self::C::log = "x=${x}, y=${y}, z=${z}", super core::_Enum::•(index, name)
+ ;
+ const constructor named1(core::int index, core::String name, core::int x, core::int y, core::int z) → self::C
+ : this self::C::•(index, name, x, y, z: z)
+ ;
+ const constructor named2(core::int index, core::String name, core::int x, core::int y, core::int z) → self::C
+ : final core::int #t1 = index, final core::String #t2 = name, final core::int #t3 = x, final core::int #t4 = z, this self::C::•(#t1, #t2, #t3, y, z: #t4)
+ ;
+ const constructor named3(core::int index, core::String name, core::int x, core::int y, core::int z) → self::C
+ : final core::int #t5 = index, final core::String #t6 = name, final core::int #t7 = z, this self::C::•(#t5, #t6, x, y, z: #t7)
+ ;
+ method toString() → core::String
+ return "C.${this.{core::_Enum::_name}{core::String}}";
+}
+static method main() → dynamic {
+ self::expect("x=1, y=2, z=3", #C4.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C7.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C10.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C13.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C16.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C19.{self::C::log}{core::String});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = "x=1, y=2, z=3"
+ #C2 = 0
+ #C3 = "a"
+ #C4 = self::C {log:#C1, index:#C2, _name:#C3}
+ #C5 = 1
+ #C6 = "b"
+ #C7 = self::C {log:#C1, index:#C5, _name:#C6}
+ #C8 = 2
+ #C9 = "c"
+ #C10 = self::C {log:#C1, index:#C8, _name:#C9}
+ #C11 = 3
+ #C12 = "d"
+ #C13 = self::C {log:#C1, index:#C11, _name:#C12}
+ #C14 = 4
+ #C15 = "e"
+ #C16 = self::C {log:#C1, index:#C14, _name:#C15}
+ #C17 = 5
+ #C18 = "f"
+ #C19 = self::C {log:#C1, index:#C17, _name:#C18}
+ #C20 = <self::C>[#C4, #C7, #C10, #C13, #C16, #C19]
+ #C21 = 42
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///redirecting_constructor.dart:
+- C. (from org-dartlang-testcase:///redirecting_constructor.dart:16:9)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+- C.named1 (from org-dartlang-testcase:///redirecting_constructor.dart:19:9)
+- C.named2 (from org-dartlang-testcase:///redirecting_constructor.dart:20:9)
+- C.named3 (from org-dartlang-testcase:///redirecting_constructor.dart:21:9)
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.strong.transformed.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.strong.transformed.expect
new file mode 100644
index 0000000..6b5605e
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.strong.transformed.expect
@@ -0,0 +1,74 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::C> values = #C20;
+ static const field self::C a = #C4;
+ static const field self::C b = #C7;
+ static const field self::C c = #C10;
+ static const field self::C d = #C13;
+ static const field self::C e = #C16;
+ static const field self::C f = #C19;
+ final field core::String log;
+ const constructor •(core::int index, core::String name, core::int x, core::int y, {core::int z = #C21}) → self::C
+ : self::C::log = "x=${x}, y=${y}, z=${z}", super core::_Enum::•(index, name)
+ ;
+ const constructor named1(core::int index, core::String name, core::int x, core::int y, core::int z) → self::C
+ : this self::C::•(index, name, x, y, z: z)
+ ;
+ const constructor named2(core::int index, core::String name, core::int x, core::int y, core::int z) → self::C
+ : final core::int #t1 = index, final core::String #t2 = name, final core::int #t3 = x, final core::int #t4 = z, this self::C::•(#t1, #t2, #t3, y, z: #t4)
+ ;
+ const constructor named3(core::int index, core::String name, core::int x, core::int y, core::int z) → self::C
+ : final core::int #t5 = index, final core::String #t6 = name, final core::int #t7 = z, this self::C::•(#t5, #t6, x, y, z: #t7)
+ ;
+ method toString() → core::String
+ return "C.${this.{core::_Enum::_name}{core::String}}";
+}
+static method main() → dynamic {
+ self::expect("x=1, y=2, z=3", #C4.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C7.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C10.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C13.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C16.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C19.{self::C::log}{core::String});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = "x=1, y=2, z=3"
+ #C2 = 0
+ #C3 = "a"
+ #C4 = self::C {log:#C1, index:#C2, _name:#C3}
+ #C5 = 1
+ #C6 = "b"
+ #C7 = self::C {log:#C1, index:#C5, _name:#C6}
+ #C8 = 2
+ #C9 = "c"
+ #C10 = self::C {log:#C1, index:#C8, _name:#C9}
+ #C11 = 3
+ #C12 = "d"
+ #C13 = self::C {log:#C1, index:#C11, _name:#C12}
+ #C14 = 4
+ #C15 = "e"
+ #C16 = self::C {log:#C1, index:#C14, _name:#C15}
+ #C17 = 5
+ #C18 = "f"
+ #C19 = self::C {log:#C1, index:#C17, _name:#C18}
+ #C20 = <self::C>[#C4, #C7, #C10, #C13, #C16, #C19]
+ #C21 = 42
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///redirecting_constructor.dart:
+- C. (from org-dartlang-testcase:///redirecting_constructor.dart:16:9)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+- C.named1 (from org-dartlang-testcase:///redirecting_constructor.dart:19:9)
+- C.named2 (from org-dartlang-testcase:///redirecting_constructor.dart:20:9)
+- C.named3 (from org-dartlang-testcase:///redirecting_constructor.dart:21:9)
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..03be650
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+enum C { a(1, 2, z: 3), b(z: 3, 1, 2), c(1, z: 3, 2), d.named1(1, 2, 3), e.named2(1, 2, 3), f.named3(1, 2, 3), ; final String log; const C(int x, int y, {int z = 42}) : this.log = "x=$x, y=$y, z=$z"; const C.named1(int x, int y, int z) : this(x, y, z: z); const C.named2(int x, int y, int z) : this(x, z: z, y); const C.named3(int x, int y, int z) : this(z: z, x, y); }
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.weak.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.weak.expect
new file mode 100644
index 0000000..e8052bd
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.weak.expect
@@ -0,0 +1,74 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::C> values = #C20;
+ static const field self::C a = #C4;
+ static const field self::C b = #C7;
+ static const field self::C c = #C10;
+ static const field self::C d = #C13;
+ static const field self::C e = #C16;
+ static const field self::C f = #C19;
+ final field core::String log;
+ const constructor •(core::int index, core::String name, core::int x, core::int y, {core::int z = #C21}) → self::C
+ : self::C::log = "x=${x}, y=${y}, z=${z}", super core::_Enum::•(index, name)
+ ;
+ const constructor named1(core::int index, core::String name, core::int x, core::int y, core::int z) → self::C
+ : this self::C::•(index, name, x, y, z: z)
+ ;
+ const constructor named2(core::int index, core::String name, core::int x, core::int y, core::int z) → self::C
+ : final core::int #t1 = index, final core::String #t2 = name, final core::int #t3 = x, final core::int #t4 = z, this self::C::•(#t1, #t2, #t3, y, z: #t4)
+ ;
+ const constructor named3(core::int index, core::String name, core::int x, core::int y, core::int z) → self::C
+ : final core::int #t5 = index, final core::String #t6 = name, final core::int #t7 = z, this self::C::•(#t5, #t6, x, y, z: #t7)
+ ;
+ method toString() → core::String
+ return "C.${this.{core::_Enum::_name}{core::String}}";
+}
+static method main() → dynamic {
+ self::expect("x=1, y=2, z=3", #C4.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C7.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C10.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C13.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C16.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C19.{self::C::log}{core::String});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = "x=1, y=2, z=3"
+ #C2 = 0
+ #C3 = "a"
+ #C4 = self::C {log:#C1, index:#C2, _name:#C3}
+ #C5 = 1
+ #C6 = "b"
+ #C7 = self::C {log:#C1, index:#C5, _name:#C6}
+ #C8 = 2
+ #C9 = "c"
+ #C10 = self::C {log:#C1, index:#C8, _name:#C9}
+ #C11 = 3
+ #C12 = "d"
+ #C13 = self::C {log:#C1, index:#C11, _name:#C12}
+ #C14 = 4
+ #C15 = "e"
+ #C16 = self::C {log:#C1, index:#C14, _name:#C15}
+ #C17 = 5
+ #C18 = "f"
+ #C19 = self::C {log:#C1, index:#C17, _name:#C18}
+ #C20 = <self::C*>[#C4, #C7, #C10, #C13, #C16, #C19]
+ #C21 = 42
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///redirecting_constructor.dart:
+- C. (from org-dartlang-testcase:///redirecting_constructor.dart:16:9)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+- C.named1 (from org-dartlang-testcase:///redirecting_constructor.dart:19:9)
+- C.named2 (from org-dartlang-testcase:///redirecting_constructor.dart:20:9)
+- C.named3 (from org-dartlang-testcase:///redirecting_constructor.dart:21:9)
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.weak.modular.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.weak.modular.expect
new file mode 100644
index 0000000..e8052bd
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.weak.modular.expect
@@ -0,0 +1,74 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::C> values = #C20;
+ static const field self::C a = #C4;
+ static const field self::C b = #C7;
+ static const field self::C c = #C10;
+ static const field self::C d = #C13;
+ static const field self::C e = #C16;
+ static const field self::C f = #C19;
+ final field core::String log;
+ const constructor •(core::int index, core::String name, core::int x, core::int y, {core::int z = #C21}) → self::C
+ : self::C::log = "x=${x}, y=${y}, z=${z}", super core::_Enum::•(index, name)
+ ;
+ const constructor named1(core::int index, core::String name, core::int x, core::int y, core::int z) → self::C
+ : this self::C::•(index, name, x, y, z: z)
+ ;
+ const constructor named2(core::int index, core::String name, core::int x, core::int y, core::int z) → self::C
+ : final core::int #t1 = index, final core::String #t2 = name, final core::int #t3 = x, final core::int #t4 = z, this self::C::•(#t1, #t2, #t3, y, z: #t4)
+ ;
+ const constructor named3(core::int index, core::String name, core::int x, core::int y, core::int z) → self::C
+ : final core::int #t5 = index, final core::String #t6 = name, final core::int #t7 = z, this self::C::•(#t5, #t6, x, y, z: #t7)
+ ;
+ method toString() → core::String
+ return "C.${this.{core::_Enum::_name}{core::String}}";
+}
+static method main() → dynamic {
+ self::expect("x=1, y=2, z=3", #C4.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C7.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C10.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C13.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C16.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C19.{self::C::log}{core::String});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = "x=1, y=2, z=3"
+ #C2 = 0
+ #C3 = "a"
+ #C4 = self::C {log:#C1, index:#C2, _name:#C3}
+ #C5 = 1
+ #C6 = "b"
+ #C7 = self::C {log:#C1, index:#C5, _name:#C6}
+ #C8 = 2
+ #C9 = "c"
+ #C10 = self::C {log:#C1, index:#C8, _name:#C9}
+ #C11 = 3
+ #C12 = "d"
+ #C13 = self::C {log:#C1, index:#C11, _name:#C12}
+ #C14 = 4
+ #C15 = "e"
+ #C16 = self::C {log:#C1, index:#C14, _name:#C15}
+ #C17 = 5
+ #C18 = "f"
+ #C19 = self::C {log:#C1, index:#C17, _name:#C18}
+ #C20 = <self::C*>[#C4, #C7, #C10, #C13, #C16, #C19]
+ #C21 = 42
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///redirecting_constructor.dart:
+- C. (from org-dartlang-testcase:///redirecting_constructor.dart:16:9)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+- C.named1 (from org-dartlang-testcase:///redirecting_constructor.dart:19:9)
+- C.named2 (from org-dartlang-testcase:///redirecting_constructor.dart:20:9)
+- C.named3 (from org-dartlang-testcase:///redirecting_constructor.dart:21:9)
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.weak.outline.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.weak.outline.expect
new file mode 100644
index 0000000..4a9962c
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.weak.outline.expect
@@ -0,0 +1,43 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::C> values = const <self::C>[self::C::a, self::C::b, self::C::c, self::C::d, self::C::e, self::C::f];
+ static const field self::C a = const self::C::•(0, "a", 1, 2, z: 3);
+ static const field self::C b = let final core::int #t1 = 1 in let final core::String #t2 = "b" in let final core::int #t3 = 3 in const self::C::•(#t1, #t2, 1, 2, z: #t3);
+ static const field self::C c = let final core::int #t4 = 2 in let final core::String #t5 = "c" in let final core::int #t6 = 1 in let final core::int #t7 = 3 in const self::C::•(#t4, #t5, #t6, 2, z: #t7);
+ static const field self::C d = const self::C::named1(3, "d", 1, 2, 3);
+ static const field self::C e = const self::C::named2(4, "e", 1, 2, 3);
+ static const field self::C f = const self::C::named3(5, "f", 1, 2, 3);
+ final field core::String log;
+ const constructor •(core::int index, core::String name, core::int x, core::int y, {core::int z = 42}) → self::C
+ : self::C::log = "x=${x}, y=${y}, z=${z}", super core::_Enum::•(index, name)
+ ;
+ const constructor named1(core::int index, core::String name, core::int x, core::int y, core::int z) → self::C
+ : this self::C::•(index, name, x, y, z: z)
+ ;
+ const constructor named2(core::int index, core::String name, core::int x, core::int y, core::int z) → self::C
+ : final core::int #t8 = index, final core::String #t9 = name, final core::int #t10 = x, final core::int #t11 = z, this self::C::•(#t8, #t9, #t10, y, z: #t11)
+ ;
+ const constructor named3(core::int index, core::String name, core::int x, core::int y, core::int z) → self::C
+ : final core::int #t12 = index, final core::String #t13 = name, final core::int #t14 = z, this self::C::•(#t12, #t13, x, y, z: #t14)
+ ;
+ method toString() → core::String
+ return "C.${this.{core::_Enum::_name}{core::String}}";
+}
+static method main() → dynamic
+ ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+ ;
+
+
+Extra constant evaluation status:
+Evaluated: ListLiteral @ org-dartlang-testcase:///redirecting_constructor.dart:5:6 -> ListConstant(const <C*>[const C{C.log: "x=1, y=2, z=3", _Enum.index: 0, _Enum._name: "a"}, const C{C.log: "x=1, y=2, z=3", _Enum.index: 1, _Enum._name: "b"}, const C{C.log: "x=1, y=2, z=3", _Enum.index: 2, _Enum._name: "c"}, const C{C.log: "x=1, y=2, z=3", _Enum.index: 3, _Enum._name: "d"}, const C{C.log: "x=1, y=2, z=3", _Enum.index: 4, _Enum._name: "e"}, const C{C.log: "x=1, y=2, z=3", _Enum.index: 5, _Enum._name: "f"}])
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///redirecting_constructor.dart:6:3 -> InstanceConstant(const C{C.log: "x=1, y=2, z=3", _Enum.index: 0, _Enum._name: "a"})
+Evaluated: Let @ org-dartlang-testcase:///redirecting_constructor.dart:7:3 -> InstanceConstant(const C{C.log: "x=1, y=2, z=3", _Enum.index: 1, _Enum._name: "b"})
+Evaluated: Let @ org-dartlang-testcase:///redirecting_constructor.dart:8:3 -> InstanceConstant(const C{C.log: "x=1, y=2, z=3", _Enum.index: 2, _Enum._name: "c"})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///redirecting_constructor.dart:9:3 -> InstanceConstant(const C{C.log: "x=1, y=2, z=3", _Enum.index: 3, _Enum._name: "d"})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///redirecting_constructor.dart:10:3 -> InstanceConstant(const C{C.log: "x=1, y=2, z=3", _Enum.index: 4, _Enum._name: "e"})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///redirecting_constructor.dart:11:3 -> InstanceConstant(const C{C.log: "x=1, y=2, z=3", _Enum.index: 5, _Enum._name: "f"})
+Extra constant evaluation: evaluated: 38, effectively constant: 7
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.weak.transformed.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.weak.transformed.expect
new file mode 100644
index 0000000..e8052bd
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments_anywhere/redirecting_constructor.dart.weak.transformed.expect
@@ -0,0 +1,74 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::C> values = #C20;
+ static const field self::C a = #C4;
+ static const field self::C b = #C7;
+ static const field self::C c = #C10;
+ static const field self::C d = #C13;
+ static const field self::C e = #C16;
+ static const field self::C f = #C19;
+ final field core::String log;
+ const constructor •(core::int index, core::String name, core::int x, core::int y, {core::int z = #C21}) → self::C
+ : self::C::log = "x=${x}, y=${y}, z=${z}", super core::_Enum::•(index, name)
+ ;
+ const constructor named1(core::int index, core::String name, core::int x, core::int y, core::int z) → self::C
+ : this self::C::•(index, name, x, y, z: z)
+ ;
+ const constructor named2(core::int index, core::String name, core::int x, core::int y, core::int z) → self::C
+ : final core::int #t1 = index, final core::String #t2 = name, final core::int #t3 = x, final core::int #t4 = z, this self::C::•(#t1, #t2, #t3, y, z: #t4)
+ ;
+ const constructor named3(core::int index, core::String name, core::int x, core::int y, core::int z) → self::C
+ : final core::int #t5 = index, final core::String #t6 = name, final core::int #t7 = z, this self::C::•(#t5, #t6, x, y, z: #t7)
+ ;
+ method toString() → core::String
+ return "C.${this.{core::_Enum::_name}{core::String}}";
+}
+static method main() → dynamic {
+ self::expect("x=1, y=2, z=3", #C4.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C7.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C10.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C13.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C16.{self::C::log}{core::String});
+ self::expect("x=1, y=2, z=3", #C19.{self::C::log}{core::String});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = "x=1, y=2, z=3"
+ #C2 = 0
+ #C3 = "a"
+ #C4 = self::C {log:#C1, index:#C2, _name:#C3}
+ #C5 = 1
+ #C6 = "b"
+ #C7 = self::C {log:#C1, index:#C5, _name:#C6}
+ #C8 = 2
+ #C9 = "c"
+ #C10 = self::C {log:#C1, index:#C8, _name:#C9}
+ #C11 = 3
+ #C12 = "d"
+ #C13 = self::C {log:#C1, index:#C11, _name:#C12}
+ #C14 = 4
+ #C15 = "e"
+ #C16 = self::C {log:#C1, index:#C14, _name:#C15}
+ #C17 = 5
+ #C18 = "f"
+ #C19 = self::C {log:#C1, index:#C17, _name:#C18}
+ #C20 = <self::C*>[#C4, #C7, #C10, #C13, #C16, #C19]
+ #C21 = 42
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///redirecting_constructor.dart:
+- C. (from org-dartlang-testcase:///redirecting_constructor.dart:16:9)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+- C.named1 (from org-dartlang-testcase:///redirecting_constructor.dart:19:9)
+- C.named2 (from org-dartlang-testcase:///redirecting_constructor.dart:20:9)
+- C.named3 (from org-dartlang-testcase:///redirecting_constructor.dart:21:9)
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 5a838fa..1dbaebd 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -9,6 +9,8 @@
constructor_tearoffs/call_instantiation: TypeCheckError
constructor_tearoffs/lowering/invalid_redirect: VerificationError
enhanced_enums/simple_mixins: RuntimeError
+enhanced_enums/named_arguments_anywhere/issue48276: TextSerializationFailure # Issue 47524.
+enhanced_enums/named_arguments_anywhere/redirecting_constructor: TextSerializationFailure # Issue 47524.
extension_types/access_setter_as_getter: ExpectationFileMismatchSerialized # Expected.
extension_types/call_not_get: ExpectationFileMismatchSerialized # Expected.
extension_types/extension_on_nullable: ExpectationFileMismatchSerialized # Expected.
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index 5c09d8e..8c015e4 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -38,6 +38,7 @@
enhanced_enums/malformed_constructors: FormatterCrash
enhanced_enums/members: FormatterCrash
enhanced_enums/named_arguments: FormatterCrash
+enhanced_enums/named_arguments_anywhere/redirecting_constructor: FormatterCrash
enhanced_enums/qualified_names_with_no_type_arguments: FormatterCrash
enhanced_enums/redirecting_initializers: FormatterCrash
enhanced_enums/simple_fields: FormatterCrash
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect
index 1443d95..7a6dc01 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect
@@ -22,6 +22,6 @@
synthetic constructor •() → self::Class
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3384,getterSelectorId:3385] method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::Enum e) → core::int
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3396,getterSelectorId:3397] method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::Enum e) → core::int
return [@vm.inferred-type.metadata=!] e.{core::_Enum::index}{core::int};
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect
index c16c8ac..5bebd25 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect
@@ -51,6 +51,6 @@
synthetic constructor •() → self::ConstClass
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3388,getterSelectorId:3389] method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::ConstEnum e) → core::int
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3400,getterSelectorId:3401] method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::ConstEnum e) → core::int
return [@vm.inferred-type.metadata=!] e.{core::_Enum::index}{core::int};
}
diff --git a/runtime/vm/compiler/backend/linearscan.cc b/runtime/vm/compiler/backend/linearscan.cc
index c6767a5..19191d1 100644
--- a/runtime/vm/compiler/backend/linearscan.cc
+++ b/runtime/vm/compiler/backend/linearscan.cc
@@ -321,6 +321,16 @@
}
void LiveRange::AddSafepoint(intptr_t pos, LocationSummary* locs) {
+ if (spill_slot().IsConstant() &&
+ (locs->always_calls() && !locs->callee_safe_call())) {
+ // Constants have pseudo spill slot assigned to them from
+ // the very beginning. This means that we don't need to associate
+ // "always_calls" safepoints with these ranges, because they will never
+ // be spilled. We still need to associate slow-path safepoints because
+ // a value might be allocated to a register across a slow-path call.
+ return;
+ }
+
ASSERT(IsInstructionStartPosition(pos));
SafepointPosition* safepoint =
new SafepointPosition(ToInstructionEnd(pos), locs);
diff --git a/sdk/lib/_internal/vm/lib/compact_hash.dart b/sdk/lib/_internal/vm/lib/compact_hash.dart
index f2b6fc0..6ed0c80 100644
--- a/sdk/lib/_internal/vm/lib/compact_hash.dart
+++ b/sdk/lib/_internal/vm/lib/compact_hash.dart
@@ -325,6 +325,11 @@
// Publish new index, uses store release semantics.
_index = newIndex;
}
+
+ Iterable<K> get keys =>
+ new _CompactIterableImmutable<K>(this, _data, _usedData, -2, 2);
+ Iterable<V> get values =>
+ new _CompactIterableImmutable<V>(this, _data, _usedData, -1, 2);
}
// Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
@@ -628,6 +633,7 @@
// and checks for concurrent modification.
class _CompactIterable<E> extends Iterable<E> {
final _HashBase _table;
+ // dart:core#_List (sdk/lib/_internal/vm/lib/array.dart).
final List _data;
final int _len;
final int _offset;
@@ -646,6 +652,7 @@
class _CompactIterator<E> implements Iterator<E> {
final _HashBase _table;
+ // dart:core#_List (sdk/lib/_internal/vm/lib/array.dart).
final List _data;
final int _len;
int _offset;
@@ -677,6 +684,58 @@
E get current => _current as E;
}
+// Iterates through _data[_offset + _step], _data[_offset + 2*_step], ...
+// and checks for concurrent modification.
+class _CompactIterableImmutable<E> extends Iterable<E> {
+ // _HashBase with _HashVMImmutableBase.
+ final _HashBase _table;
+ // dart:core#_ImmutableList (sdk/lib/_internal/vm/lib/array.dart).
+ final List _data;
+ final int _len;
+ final int _offset;
+ final int _step;
+
+ _CompactIterableImmutable(
+ this._table, this._data, this._len, this._offset, this._step);
+
+ Iterator<E> get iterator =>
+ new _CompactIteratorImmutable<E>(_table, _data, _len, _offset, _step);
+
+ int get length => _table.length;
+ bool get isEmpty => length == 0;
+ bool get isNotEmpty => !isEmpty;
+}
+
+class _CompactIteratorImmutable<E> implements Iterator<E> {
+ // _HashBase with _HashVMImmutableBase.
+ final _HashBase _table;
+ // dart:core#_ImmutableList (sdk/lib/_internal/vm/lib/array.dart).
+ final List _data;
+ final int _len;
+ int _offset;
+ final int _step;
+ final int _checkSum;
+ E? _current;
+
+ _CompactIteratorImmutable(
+ _HashBase table, this._data, this._len, this._offset, this._step)
+ : _table = table,
+ _checkSum = table._checkSum;
+
+ bool moveNext() {
+ _offset += _step;
+ if (_offset < _len) {
+ _current = internal.unsafeCast<E>(_data[_offset]);
+ return true;
+ } else {
+ _current = null;
+ return false;
+ }
+ }
+
+ E get current => _current as E;
+}
+
abstract class _LinkedHashSetMixin<E> implements _HashBase {
int _hashCode(e);
bool _equals(e1, e2);
@@ -959,6 +1018,9 @@
// Returns a mutable set.
Set<E> toSet() => new _CompactLinkedHashSet<E>()..addAll(this);
+
+ Iterator<E> get iterator =>
+ new _CompactIteratorImmutable<E>(this, _data, _usedData, -1, 1);
}
class _CompactLinkedIdentityHashSet<E> extends _HashFieldBase
diff --git a/tools/VERSION b/tools/VERSION
index 18e7a2b..f4a203c 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 17
PATCH 0
-PRERELEASE 82
+PRERELEASE 83
PRERELEASE_PATCH 0
\ No newline at end of file