Version 2.18.0-225.0.dev
Merge commit 'c97f7b7fadca5b6a3e220a20dbefd4eaa3b442ba' into 'dev'
diff --git a/DEPS b/DEPS
index 1c07751..9821742 100644
--- a/DEPS
+++ b/DEPS
@@ -109,7 +109,7 @@
"dart_style_rev": "d7b73536a8079331c888b7da539b80e6825270ea", # manually rev'd
"dartdoc_rev": "58348a98b992ce99b95d23131b67227bdb2b4875",
- "devtools_rev": "51ac983d2db7eb19b3ce5956cb70b769d74fe784",
+ "devtools_rev": "0aa619c42a68d6db4c94a7838121811aba8f5eb1",
"ffi_rev": "18b2b549d55009ff594600b04705ff6161681e07",
"file_rev": "0132eeedea2933513bf230513a766a8baeab0c4f",
"fixnum_rev": "164712f6547cdfb2709b752188186baf31fd1730",
diff --git a/pkg/analysis_server/benchmark/perf/flutter_completion_benchmark.dart b/pkg/analysis_server/benchmark/perf/flutter_completion_benchmark.dart
index a2fe460..e3af6d6 100644
--- a/pkg/analysis_server/benchmark/perf/flutter_completion_benchmark.dart
+++ b/pkg/analysis_server/benchmark/perf/flutter_completion_benchmark.dart
@@ -95,7 +95,7 @@
);
if (!quick) {
- // This scenario is relatively easy - the file is small, less then 3KB.
+ // This scenario is relatively easy - the file is small, less than 3KB.
// But we don't have any prefix to filter, so if we don't restrict the
// number of suggestions, we might spend too much time serializing into
// JSON in the server, and deserializing on the client.
diff --git a/pkg/analysis_server/lib/src/analytics/google_analytics_manager.dart b/pkg/analysis_server/lib/src/analytics/google_analytics_manager.dart
index d9f99f0..d3907ec 100644
--- a/pkg/analysis_server/lib/src/analytics/google_analytics_manager.dart
+++ b/pkg/analysis_server/lib/src/analytics/google_analytics_manager.dart
@@ -41,6 +41,11 @@
/// was enabled.
final Map<String, int> _lintUsageCounts = {};
+ /// A map from the name of a diagnostic to a map whose values are the number
+ /// of times that the severity of the diagnostic was changed to the severity
+ /// represented by the key.
+ final Map<String, Map<String, int>> _severityAdjustments = {};
+
/// Initialize a newly created analytics manager to report to the [analytics]
/// service.
GoogleAnalyticsManager(this.analytics);
@@ -66,12 +71,12 @@
var name = rule.name;
_lintUsageCounts[name] = (_lintUsageCounts[name] ?? 0) + 1;
}
- // TODO(brianwilkerson) Collect other context-dependent information, such
- // as which codes have a different severity assigned to them:
- // for (var processor in context.analysisOptions.errorProcessors) {
- // processor.code;
- // processor.severity;
- // }
+ for (var processor in context.analysisOptions.errorProcessors) {
+ var severity = processor.severity?.name ?? 'ignore';
+ var severityCounts =
+ _severityAdjustments.putIfAbsent(processor.code, () => {});
+ severityCounts[severity] = (severityCounts[severity] ?? 0) + 1;
+ }
}
}
@@ -140,6 +145,7 @@
_sendPluginResponseTimes();
_sendNotificationHandlingTimes();
_sendLintUsageCounts();
+ _sendSeverityAdjustments();
analytics.waitForLastPing(timeout: Duration(milliseconds: 200)).then((_) {
analytics.close();
@@ -227,9 +233,11 @@
}
void _sendLintUsageCounts() {
- analytics.sendEvent('language_server', 'lintUsageCounts', parameters: {
- 'usageCounts': _lintUsageCounts.toString(),
- });
+ if (_lintUsageCounts.isNotEmpty) {
+ analytics.sendEvent('language_server', 'lintUsageCounts', parameters: {
+ 'usageCounts': json.encode(_lintUsageCounts),
+ });
+ }
}
/// Send information about the notifications handled by the server.
@@ -286,6 +294,15 @@
'plugins': _pluginData.usageCountData,
});
}
+
+ void _sendSeverityAdjustments() {
+ if (_severityAdjustments.isNotEmpty) {
+ analytics
+ .sendEvent('language_server', 'severityAdjustments', parameters: {
+ 'adjustmentCounts': json.encode(_severityAdjustments),
+ });
+ }
+ }
}
/// Data about a request that was received and is being handled.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart
index 9bf265c..d95deb7 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart
@@ -88,6 +88,8 @@
} else if (node is VariableDeclaration &&
parent is VariableDeclarationList) {
list = parent;
+ } else if (node is VariableDeclarationList) {
+ list = node;
} else {
return;
}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_final.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_final.dart
new file mode 100644
index 0000000..73078a5
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_final.dart
@@ -0,0 +1,41 @@
+// 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/dart/ast/token.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class RemoveUnnecessaryFinal extends CorrectionProducer {
+ @override
+ bool get canBeAppliedInBulk => true;
+
+ @override
+ bool get canBeAppliedToFile => true;
+
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_UNNECESSARY_FINAL;
+
+ @override
+ FixKind get multiFixKind => DartFixKind.REMOVE_UNNECESSARY_FINAL_MULTI;
+
+ @override
+ Future<void> compute(ChangeBuilder builder) async {
+ var node = this.node;
+ Token? keyword;
+ if (node is FieldFormalParameter) {
+ keyword = node.keyword;
+ } else if (node is SuperFormalParameter) {
+ keyword = node.keyword;
+ }
+ if (keyword == null) return;
+
+ await builder.addDartFileEdit(file, (builder) {
+ builder.addDeletion(range.startStart(keyword!, keyword.next!));
+ });
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
index 5adb652..cba9147 100644
--- a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
+++ b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
@@ -1456,7 +1456,7 @@
HintCode.UNNECESSARY_CAST:
status: hasFix
HintCode.UNNECESSARY_FINAL:
- status: needsEvaluation
+ status: hasFix
HintCode.UNNECESSARY_IGNORE:
status: needsEvaluation
HintCode.UNNECESSARY_IMPORT:
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index ed8f791..e5e3585 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -1128,6 +1128,16 @@
DartFixKindPriority.IN_FILE,
'Remove all unnecessary casts in file',
);
+ static const REMOVE_UNNECESSARY_FINAL = FixKind(
+ 'dart.fix.remove.unnecessaryFinal',
+ DartFixKindPriority.DEFAULT,
+ "Remove unnecessary 'final'",
+ );
+ static const REMOVE_UNNECESSARY_FINAL_MULTI = FixKind(
+ 'dart.fix.remove.unnecessaryFinal.multi',
+ DartFixKindPriority.IN_FILE,
+ "Remove all unnecessary 'final's in file",
+ );
static const REMOVE_UNNECESSARY_CONST = FixKind(
'dart.fix.remove.unnecessaryConst',
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 c79ab5f..61583a8 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -139,6 +139,7 @@
import 'package:analysis_server/src/services/correction/dart/remove_type_annotation.dart';
import 'package:analysis_server/src/services/correction/dart/remove_type_arguments.dart';
import 'package:analysis_server/src/services/correction/dart/remove_unnecessary_cast.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_unnecessary_final.dart';
import 'package:analysis_server/src/services/correction/dart/remove_unnecessary_late.dart';
import 'package:analysis_server/src/services/correction/dart/remove_unnecessary_new.dart';
import 'package:analysis_server/src/services/correction/dart/remove_unnecessary_parentheses.dart';
@@ -1326,6 +1327,9 @@
HintCode.UNNECESSARY_CAST: [
RemoveUnnecessaryCast.new,
],
+ HintCode.UNNECESSARY_FINAL: [
+ RemoveUnnecessaryFinal.new,
+ ],
HintCode.UNNECESSARY_IMPORT: [
RemoveUnusedImport.new,
],
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
index 5867145..ac4fb50 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
@@ -230,7 +230,7 @@
}
if (selectionOffset + selectionLength >= resolveResult.content.length) {
return RefactoringStatus.fatal(
- 'The selection end offset must be less then the length of the file.');
+ 'The selection end offset must be less than the length of the file.');
}
var selectionStr = utils.getRangeText(selectionRange);
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index 5b43952..44e901d 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -458,7 +458,7 @@
}
if (selectionOffset + selectionLength >= resolveResult.content.length) {
return RefactoringStatus.fatal(
- 'The selection end offset must be less then the length of the file.');
+ 'The selection end offset must be less than the length of the file.');
}
// Check for implicitly selected closure.
@@ -989,10 +989,19 @@
if (element is FunctionElement || element is MethodElement) {
invalidSelection('Cannot extract a single method name.');
}
- // name in property access
- if (node.parent is PrefixedIdentifier &&
- (node.parent as PrefixedIdentifier).identifier == node) {
- invalidSelection('Can not extract name part of a property access.');
+ var parent = node.parent;
+ if (parent is PrefixedIdentifier) {
+ if (parent.identifier == node) {
+ // name in property access
+ invalidSelection('Cannot extract name part of a property access.');
+ } else if (parent.prefix == node && parent.parent is NamedType) {
+ // prefix in a named type (for example `io` in `io.File`)
+ invalidSelection('Cannot extract prefix part of a type reference.');
+ }
+ }
+ // part of a named type (for example `int` in `int?`)
+ if (node.parent is NamedType) {
+ invalidSelection('Cannot extract a single type reference.');
}
}
}
diff --git a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
index d580d4e..06ad142b 100644
--- a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
@@ -364,6 +364,22 @@
expect(codeAction, isNull);
}
+ Future<void> test_invalidLocation_importPrefix() async {
+ const content = '''
+import 'dart:io' as io;
+
+i^o.File a;
+ ''';
+ newFile(mainFilePath, withoutMarkers(content));
+ await initialize();
+
+ final codeActions = await getCodeActions(mainFileUri.toString(),
+ position: positionFromMarker(content));
+ final codeAction =
+ findCommand(codeActions, Commands.performRefactor, extractMethodTitle);
+ expect(codeAction, isNull);
+ }
+
Future<void> test_progress_clientProvided() async {
const content = '''
void f() {
diff --git a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
index 865fbcb..b6ae4c4 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
@@ -438,7 +438,7 @@
''');
_createRefactoringWithSuffix('fff', ' = 1');
return _assertConditionsFatal(
- 'Can not extract name part of a property access.');
+ 'Cannot extract name part of a property access.');
}
Future<void> test_bad_newMethodName_notIdentifier() async {
@@ -752,6 +752,27 @@
return _assertConditionsFatal('Cannot extract a single type reference.');
}
+ Future<void> test_bad_typeReference_nullable() async {
+ await indexTestUnit('''
+// Dummy comment ("The selection offset must be greater than zero")
+int? f;
+''');
+ _createRefactoringForString('int');
+ return _assertConditionsFatal('Cannot extract a single type reference.');
+ }
+
+ Future<void> test_bad_typeReference_prefix() async {
+ await indexTestUnit('''
+import 'dart:io' as io;
+void f() {
+ io.File f = io.File('');
+}
+''');
+ _createRefactoringWithSuffix('io', '.File f');
+ return _assertConditionsFatal(
+ 'Cannot extract prefix part of a type reference.');
+ }
+
Future<void> test_bad_variableDeclarationFragment() async {
await indexTestUnit('''
void f() {
@@ -1251,6 +1272,29 @@
expect(refactoring.lengths, unorderedEquals([5, 6]));
}
+ Future<void> test_prefixPartOfQualified() async {
+ await indexTestUnit('''
+class A {
+ var fff;
+}
+void f(A a) {
+ a.fff = 5;
+}
+''');
+ _createRefactoringForStringOffset('a.fff');
+ // apply refactoring
+ return _assertSuccessfulRefactoring('''
+class A {
+ var fff;
+}
+void f(A a) {
+ res(a).fff = 5;
+}
+
+A res(A a) => a;
+''');
+ }
+
Future<void> test_returnType_closure() async {
await indexTestUnit('''
process(f(x)) {}
diff --git a/pkg/analysis_server/test/src/analytics/google_analytics_manager_test.dart b/pkg/analysis_server/test/src/analytics/google_analytics_manager_test.dart
index 32a5783..1f8dba5 100644
--- a/pkg/analysis_server/test/src/analytics/google_analytics_manager_test.dart
+++ b/pkg/analysis_server/test/src/analytics/google_analytics_manager_test.dart
@@ -12,7 +12,10 @@
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/dart/analysis/context_root.dart' as analyzer;
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:linter/src/rules.dart';
import 'package:telemetry/telemetry.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -28,23 +31,43 @@
final analytics = _MockAnalytics();
late final manager = GoogleAnalyticsManager(analytics);
- String get testPackageRootPath => '/home/package';
+ Folder get testPackageRoot => getFolder('/home/package');
- void test_createAnalysisContexts_single() {
+ String get testPackageRootPath => testPackageRoot.path;
+
+ void test_createAnalysisContexts_lints() {
_createAnalysisOptionsFile(lints: [
'avoid_dynamic_calls',
'await_only_futures',
'unawaited_futures'
]);
- var collection =
- AnalysisContextCollection(includedPaths: [testPackageRootPath]);
+ var collection = _createContexts();
_defaultStartup();
manager.createdAnalysisContexts(collection.contexts);
manager.shutdown();
analytics.assertEvents([
_ExpectedEvent.session(),
_ExpectedEvent.lintUsageCounts(parameters: {
- 'usageCounts': '{}',
+ 'usageCounts':
+ '{"avoid_dynamic_calls":1,"await_only_futures":1,"unawaited_futures":1}',
+ }),
+ ]);
+ }
+
+ void test_createAnalysisContexts_severityAdjustments() {
+ _createAnalysisOptionsFile(errors: {
+ 'avoid_dynamic_calls': 'error',
+ 'await_only_futures': 'ignore',
+ });
+ var collection = _createContexts();
+ _defaultStartup();
+ manager.createdAnalysisContexts(collection.contexts);
+ manager.shutdown();
+ analytics.assertEvents([
+ _ExpectedEvent.session(),
+ _ExpectedEvent.severityAdjustments(parameters: {
+ 'adjustmentCounts':
+ '{"AVOID_DYNAMIC_CALLS":{"ERROR":1},"AWAIT_ONLY_FUTURES":{"ignore":1}}',
}),
]);
}
@@ -62,7 +85,6 @@
'method': 'analysis.getNavigation',
'duration': _IsPercentiles(),
}),
- _ExpectedEvent.lintUsageCounts(),
]);
PluginManager.pluginResponseTimes.clear();
}
@@ -84,7 +106,6 @@
'method': Method.workspace_didCreateFiles.toString(),
'duration': _IsPercentiles(),
}),
- _ExpectedEvent.lintUsageCounts(),
]);
}
@@ -114,7 +135,6 @@
'removed':
'{"count":1,"percentiles":[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]}',
}),
- _ExpectedEvent.lintUsageCounts(),
]);
}
@@ -138,7 +158,6 @@
ANALYSIS_REQUEST_SET_ANALYSIS_ROOTS_EXCLUDED:
'{"count":1,"percentiles":[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]}',
}),
- _ExpectedEvent.lintUsageCounts(),
]);
}
@@ -160,7 +179,6 @@
ANALYSIS_REQUEST_SET_PRIORITY_FILES_FILES:
'{"count":1,"percentiles":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]}',
}),
- _ExpectedEvent.lintUsageCounts(),
]);
}
@@ -181,7 +199,6 @@
'duration': _IsPercentiles(),
EDIT_REQUEST_GET_REFACTORING_KIND: '{"RENAME":1}',
}),
- _ExpectedEvent.lintUsageCounts(),
]);
}
@@ -201,7 +218,6 @@
'parameters':
'closingLabels,onlyAnalyzeProjectsWithOpenFiles,suggestFromUnimportedLibraries',
}),
- _ExpectedEvent.lintUsageCounts(),
]);
}
@@ -227,7 +243,6 @@
'openWorkspacePaths':
'{"count":1,"percentiles":[3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]}',
}),
- _ExpectedEvent.lintUsageCounts(),
]);
}
@@ -244,7 +259,6 @@
'method': SERVER_REQUEST_SHUTDOWN,
'duration': _IsPercentiles(),
}),
- _ExpectedEvent.lintUsageCounts(),
]);
}
@@ -272,7 +286,6 @@
'sdkVersion': sdkVersion,
'duration': _IsStringEncodedPositiveInt(),
}),
- _ExpectedEvent.lintUsageCounts(),
]);
}
@@ -289,7 +302,6 @@
_ExpectedEvent.session(parameters: {
'plugins': '{"recordCount":1,"rootCounts":{"a":$counts,"b":$counts}}'
}),
- _ExpectedEvent.lintUsageCounts(),
]);
}
@@ -314,13 +326,13 @@
'sdkVersion': sdkVersion,
'duration': _IsStringEncodedPositiveInt(),
}),
- _ExpectedEvent.lintUsageCounts(),
]);
}
/// Create an analysis options file based on the given arguments.
void _createAnalysisOptionsFile({
String? path,
+ Map<String, String>? errors,
List<String>? experiments,
bool? implicitCasts,
List<String>? lints,
@@ -328,10 +340,17 @@
path ??= '$testPackageRootPath/analysis_options.yaml';
var buffer = StringBuffer();
- if (experiments != null || implicitCasts != null) {
+ if (errors != null || experiments != null || implicitCasts != null) {
buffer.writeln('analyzer:');
}
+ if (errors != null) {
+ buffer.writeln(' errors:');
+ for (var entry in errors.entries) {
+ buffer.writeln(' ${entry.key}: ${entry.value}');
+ }
+ }
+
if (experiments != null) {
buffer.writeln(' enable-experiment:');
for (var experiment in experiments) {
@@ -355,6 +374,16 @@
newFile(path, buffer.toString());
}
+ AnalysisContextCollection _createContexts() {
+ var sdkRoot = getFolder('/sdk');
+ createMockSdk(resourceProvider: resourceProvider, root: sdkRoot);
+ registerLintRules();
+ return AnalysisContextCollection(
+ resourceProvider: resourceProvider,
+ includedPaths: [testPackageRootPath],
+ sdkPath: sdkRoot.path);
+ }
+
void _defaultStartup() {
manager.startUp(
time: DateTime.now(),
@@ -406,6 +435,9 @@
_ExpectedEvent.session({Map<String, Object>? parameters})
: this('language_server', 'session', parameters: parameters);
+ _ExpectedEvent.severityAdjustments({Map<String, Object>? parameters})
+ : this('language_server', 'severityAdjustments', parameters: parameters);
+
/// Compare the expected event with the [actual] event, failing if the actual
/// doesn't match the expected.
void matches(_Event actual) {
@@ -430,6 +462,27 @@
}
}
}
+
+ @override
+ String toString() {
+ var buffer = StringBuffer();
+ buffer.write('category: ');
+ buffer.writeln(category);
+ buffer.write('action: ');
+ buffer.writeln(action);
+ buffer.write('label: ');
+ buffer.writeln(label);
+ buffer.write('value: ');
+ buffer.writeln(value);
+ var parameterMap = parameters;
+ if (parameterMap != null) {
+ for (var entry in parameterMap.entries) {
+ buffer.write('value: ');
+ buffer.writeln('${entry.key}: ${entry.value}');
+ }
+ }
+ return buffer.toString();
+ }
}
/// A matcher for strings containing positive integer values.
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_final_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_final_test.dart
new file mode 100644
index 0000000..70f9035f
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_final_test.dart
@@ -0,0 +1,122 @@
+// 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:analyzer/src/error/codes.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(RemoveUnnecessaryFinalBulkTest);
+ defineReflectiveTests(RemoveUnnecessaryFinalMultiTest);
+ defineReflectiveTests(RemoveUnnecessaryFinalTest);
+ });
+}
+
+@reflectiveTest
+class RemoveUnnecessaryFinalBulkTest extends BulkFixProcessorTest {
+ Future<void> test_assignment() async {
+ await resolveTestCode('''
+class A {
+ A(final this.value);
+ int value;
+}
+class B extends A {
+ B(final super.value);
+}
+''');
+ await assertHasFix('''
+class A {
+ A(this.value);
+ int value;
+}
+class B extends A {
+ B(super.value);
+}
+''');
+ }
+}
+
+@reflectiveTest
+class RemoveUnnecessaryFinalMultiTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_UNNECESSARY_FINAL_MULTI;
+
+ Future<void> test_multi() async {
+ await resolveTestCode('''
+class A {
+ A(final this.v1, final this.v2);
+ int v1;
+ int v2;
+}
+''');
+ await assertHasFixAllFix(HintCode.UNNECESSARY_FINAL, '''
+class A {
+ A(this.v1, this.v2);
+ int v1;
+ int v2;
+}
+''');
+ }
+}
+
+@reflectiveTest
+class RemoveUnnecessaryFinalTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_UNNECESSARY_FINAL;
+
+ Future<void> test_positional() async {
+ await resolveTestCode('''
+class C {
+ C([final this.value = 0]);
+ int value;
+}
+''');
+ await assertHasFix('''
+class C {
+ C([this.value = 0]);
+ int value;
+}
+''');
+ }
+
+ Future<void> test_super() async {
+ await resolveTestCode('''
+class A {
+ A(this.value);
+ int value;
+}
+class B extends A {
+ B(final super.value);
+}
+''');
+ await assertHasFix('''
+class A {
+ A(this.value);
+ int value;
+}
+class B extends A {
+ B(super.value);
+}
+''');
+ }
+
+ Future<void> test_this() async {
+ await resolveTestCode('''
+class C {
+ C(final this.value);
+ int value;
+}
+''');
+ await assertHasFix('''
+class C {
+ C(this.value);
+ int value;
+}
+''');
+ }
+}
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 768c4c6..291306b 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
@@ -169,6 +169,7 @@
import 'remove_type_arguments_test.dart' as remove_type_arguments;
import 'remove_unnecessary_cast_test.dart' as remove_unnecessary_cast;
import 'remove_unnecessary_const_test.dart' as remove_unnecessary_const;
+import 'remove_unnecessary_final_test.dart' as remove_unnecessary_final;
import 'remove_unnecessary_late_test.dart' as remove_unnecessary_late;
import 'remove_unnecessary_new_test.dart' as remove_unnecessary_new;
import 'remove_unnecessary_parentheses_test.dart'
@@ -383,6 +384,7 @@
remove_type_arguments.main();
remove_unnecessary_cast.main();
remove_unnecessary_const.main();
+ remove_unnecessary_final.main();
remove_unnecessary_late.main();
remove_unnecessary_new.main();
remove_unnecessary_parentheses.main();
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index d40a6e6..ed113f0 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -2,6 +2,7 @@
* Update SDK constraints to `>=2.17.0 <3.0.0`.
* Deprecated `ImportDirective.COMPARATOR`, use appropriate custom logic, if necessary.
* Deprecated `Element.isAccessibleIn()`, use `isAccessibleIn2()` instead.
+* Bug fixes: 49225.
## 4.1.0
* Deprecated `ParameterElement.isNotOptional`, use `isRequired` instead.
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 679555e..07c1d2a 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -1084,8 +1084,7 @@
return null;
}
- return ParameterMember(
- _typeProvider, superConstructorParameter, _substitution, isLegacy);
+ return ParameterMember.from(superConstructorParameter, substitution);
}
@override
diff --git a/pkg/analyzer/test/src/dart/resolution/super_formal_parameter_test.dart b/pkg/analyzer/test/src/dart/resolution/super_formal_parameter_test.dart
index 42db1a5..1e9388a 100644
--- a/pkg/analyzer/test/src/dart/resolution/super_formal_parameter_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/super_formal_parameter_test.dart
@@ -2,6 +2,7 @@
// 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:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/test_utilities/find_element.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -16,6 +17,50 @@
@reflectiveTest
class SuperFormalParameterTest extends PubPackageResolutionTest {
+ test_element_typeParameterSubstitution_chained() async {
+ await assertNoErrorsInCode(r'''
+class A<T> {
+ A({int? key});
+}
+
+class B<U> extends A<U> {
+ B({super.key});
+}
+
+class C<V> extends B<V> {
+ C({super.key});
+}
+''');
+
+ final C = findElement.unnamedConstructor('C');
+ final C_key = C.superFormalParameter('key');
+
+ final B_key_member = C_key.superConstructorParameter;
+ B_key_member as SuperFormalParameterMember;
+
+ final B = findElement.unnamedConstructor('B');
+ final B_key = B.superFormalParameter('key');
+ assertElement2(
+ B_key_member,
+ declaration: B_key,
+ substitution: {'U': 'V'},
+ );
+
+ final A_key_member = B_key_member.superConstructorParameter;
+ A_key_member as ParameterMember;
+
+ final A = findElement.unnamedConstructor('A');
+ final A_key = A.parameter('key');
+ assertElement2(
+ A_key_member,
+ declaration: A_key,
+ substitution: {
+ 'T': 'V',
+ 'U': 'V',
+ },
+ );
+ }
+
test_functionTyped() async {
await assertNoErrorsInCode(r'''
class A {
diff --git a/pkg/compiler/lib/src/ir/impact.dart b/pkg/compiler/lib/src/ir/impact.dart
index aee4e69..08df41c 100644
--- a/pkg/compiler/lib/src/ir/impact.dart
+++ b/pkg/compiler/lib/src/ir/impact.dart
@@ -7,7 +7,7 @@
import 'package:kernel/ast.dart' as ir;
import 'package:kernel/type_environment.dart' as ir;
-import '../serialization/serialization.dart';
+import '../serialization/serialization_interfaces.dart';
import 'class_relation.dart';
import 'constants.dart';
import 'impact_data.dart';
diff --git a/pkg/compiler/lib/src/ir/impact_data.dart b/pkg/compiler/lib/src/ir/impact_data.dart
index 25cb12d..8453739 100644
--- a/pkg/compiler/lib/src/ir/impact_data.dart
+++ b/pkg/compiler/lib/src/ir/impact_data.dart
@@ -13,9 +13,9 @@
import '../elements/entities.dart';
import '../elements/types.dart';
import '../ir/scope.dart';
-import '../kernel/element_map.dart';
+import '../kernel/element_map.dart' show KernelToElementMap;
import '../options.dart';
-import '../serialization/serialization.dart';
+import '../serialization/serialization_interfaces.dart';
import '../util/enumset.dart';
import 'class_relation.dart';
import 'constants.dart';
@@ -1103,12 +1103,12 @@
_typeUses = source.readListOrNull(() => _TypeUse.fromDataSource(source));
_redirectingInitializers = source
.readListOrNull(() => _RedirectingInitializer.fromDataSource(source));
- _fieldInitializers = source.readMemberNodes<ir.Field>(emptyAsNull: true);
+ _fieldInitializers = source.readMemberNodesOrNull<ir.Field>();
_fieldConstantInitializers =
- source.readMemberNodeMap(source.readTreeNodes, emptyAsNull: true);
+ source.readMemberNodeMapOrNull(source.readTreeNodes);
_typeLiterals =
source.readListOrNull(() => _TypeLiteral.fromDataSource(source));
- _localFunctions = source.readTreeNodes(emptyAsNull: true);
+ _localFunctions = source.readTreeNodesOrNull();
_genericInstantiations = source
.readListOrNull(() => _GenericInstantiation.fromDataSource(source));
_staticSets =
@@ -1135,14 +1135,11 @@
_forInData = source.readListOrNull(() => _ForInData.fromDataSource(source));
// TODO(johnniwinther): Remove these when CFE provides constants.
- _constructorNodes =
- source.readMemberNodes<ir.Constructor>(emptyAsNull: true);
- _fieldNodes = source.readMemberNodes<ir.Field>(emptyAsNull: true);
- _procedureNodes = source.readMemberNodes<ir.Procedure>(emptyAsNull: true);
- _switchStatementNodes =
- source.readTreeNodes<ir.SwitchStatement>(emptyAsNull: true);
- _staticInvocationNodes =
- source.readTreeNodes<ir.StaticInvocation>(emptyAsNull: true);
+ _constructorNodes = source.readMemberNodesOrNull<ir.Constructor>();
+ _fieldNodes = source.readMemberNodesOrNull<ir.Field>();
+ _procedureNodes = source.readMemberNodesOrNull<ir.Procedure>();
+ _switchStatementNodes = source.readTreeNodesOrNull<ir.SwitchStatement>();
+ _staticInvocationNodes = source.readTreeNodesOrNull<ir.StaticInvocation>();
_hasConstSymbolConstructorInvocation = source.readBool();
source.end(tag);
}
diff --git a/pkg/compiler/lib/src/js_backend/backend_usage.dart b/pkg/compiler/lib/src/js_backend/backend_usage.dart
index 9b41b8e..37662b2 100644
--- a/pkg/compiler/lib/src/js_backend/backend_usage.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_usage.dart
@@ -2,14 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart = 2.10
-
import '../common.dart';
import '../common/elements.dart';
import '../elements/entities.dart';
import '../elements/types.dart';
import '../ir/runtime_type_analysis.dart';
-import '../kernel/kernel_strategy.dart' show KernelFrontendStrategy;
+import '../kernel/kernel_strategy_migrated.dart'
+ show KernelFrontendStrategyForBackendUsage;
import '../serialization/serialization_interfaces.dart';
import '../universe/feature.dart';
import '../util/util.dart' show Setlet;
@@ -23,8 +22,8 @@
/// Serializes this [BackendUsage] to [sink].
void writeToDataSink(DataSinkWriter sink);
- bool needToInitializeIsolateAffinityTag;
- bool needToInitializeDispatchProperty;
+ abstract bool needToInitializeIsolateAffinityTag;
+ abstract bool needToInitializeDispatchProperty;
/// Returns `true` if [element] is a function called by the backend.
bool isFunctionUsedByBackend(FunctionEntity element);
@@ -94,10 +93,10 @@
void registerRuntimeTypeUse(RuntimeTypeUse runtimeTypeUse);
/// `true` if `Function.apply` is used.
- bool isFunctionApplyUsed;
+ abstract bool isFunctionApplyUsed;
/// `true` if `noSuchMethod` is used.
- bool isNoSuchMethodUsed;
+ abstract bool isNoSuchMethodUsed;
/// Register that `dart:html` is loaded.
void registerHtmlIsLoaded();
@@ -106,10 +105,10 @@
}
class BackendUsageBuilderImpl implements BackendUsageBuilder {
- final KernelFrontendStrategy _frontendStrategy;
+ final KernelFrontendStrategyForBackendUsage _frontendStrategy;
// TODO(johnniwinther): Remove the need for these.
- Setlet<FunctionEntity> _globalFunctionDependencies;
- Setlet<ClassEntity> _globalClassDependencies;
+ Setlet<FunctionEntity>? _globalFunctionDependencies;
+ Setlet<ClassEntity>? _globalClassDependencies;
/// List of methods that the backend may use.
final Set<FunctionEntity> _helperFunctionsUsed = {};
@@ -210,11 +209,11 @@
@override
void processBackendImpact(BackendImpact backendImpact) {
for (FunctionEntity staticUse in backendImpact.staticUses) {
- assert(staticUse != null);
+ assert((staticUse as dynamic) != null); // TODO(48820): Remove when sound.
_processBackendStaticUse(staticUse);
}
for (FunctionEntity staticUse in backendImpact.globalUses) {
- assert(staticUse != null);
+ assert((staticUse as dynamic) != null); // TODO(48820): Remove when sound.
_processBackendStaticUse(staticUse, isGlobal: true);
}
for (InterfaceType instantiatedType in backendImpact.instantiatedTypes) {
@@ -258,16 +257,16 @@
@override
void registerGlobalFunctionDependency(FunctionEntity element) {
- assert(element != null);
+ assert((element as dynamic) != null); // TODO(48820): Remove when sound.
_globalFunctionDependencies ??= Setlet();
- _globalFunctionDependencies.add(element);
+ _globalFunctionDependencies!.add(element);
}
@override
void registerGlobalClassDependency(ClassEntity element) {
- assert(element != null);
+ assert((element as dynamic) != null); // TODO(48820): Remove when sound.
_globalClassDependencies ??= Setlet();
- _globalClassDependencies.add(element);
+ _globalClassDependencies!.add(element);
}
@override
@@ -305,8 +304,8 @@
static const String tag = 'backend-usage';
// TODO(johnniwinther): Remove the need for these.
- final Set<FunctionEntity> _globalFunctionDependencies;
- final Set<ClassEntity> _globalClassDependencies;
+ final Set<FunctionEntity>? _globalFunctionDependencies;
+ final Set<ClassEntity>? _globalClassDependencies;
/// Set of functions called by the backend.
final Set<FunctionEntity> _helperFunctionsUsed;
@@ -340,19 +339,19 @@
final bool isHtmlLoaded;
BackendUsageImpl(
- {Set<FunctionEntity> globalFunctionDependencies,
- Set<ClassEntity> globalClassDependencies,
- Set<FunctionEntity> helperFunctionsUsed,
- Set<ClassEntity> helperClassesUsed,
- this.needToInitializeIsolateAffinityTag,
- this.needToInitializeDispatchProperty,
- this.requiresPreamble,
- this.requiresStartupMetrics,
- Set<RuntimeTypeUse> runtimeTypeUses,
- this.isFunctionApplyUsed,
- this.isMirrorsUsed,
- this.isNoSuchMethodUsed,
- this.isHtmlLoaded})
+ {required Set<FunctionEntity>? globalFunctionDependencies,
+ required Set<ClassEntity>? globalClassDependencies,
+ required Set<FunctionEntity> helperFunctionsUsed,
+ required Set<ClassEntity> helperClassesUsed,
+ required this.needToInitializeIsolateAffinityTag,
+ required this.needToInitializeDispatchProperty,
+ required this.requiresPreamble,
+ required this.requiresStartupMetrics,
+ required Set<RuntimeTypeUse> runtimeTypeUses,
+ required this.isFunctionApplyUsed,
+ required this.isMirrorsUsed,
+ required this.isNoSuchMethodUsed,
+ required this.isHtmlLoaded})
: this._globalFunctionDependencies = globalFunctionDependencies,
this._globalClassDependencies = globalClassDependencies,
this._helperFunctionsUsed = helperFunctionsUsed,
@@ -370,7 +369,7 @@
Set<RuntimeTypeUse> runtimeTypeUses = source.readList(() {
RuntimeTypeUseKind kind = source.readEnum(RuntimeTypeUseKind.values);
DartType receiverType = source.readDartType();
- DartType /*?*/ argumentType = source.readDartTypeOrNull();
+ DartType? argumentType = source.readDartTypeOrNull();
return RuntimeTypeUse(kind, receiverType, argumentType);
}).toSet();
bool needToInitializeIsolateAffinityTag = source.readBool();
@@ -401,8 +400,8 @@
@override
void writeToDataSink(DataSinkWriter sink) {
sink.begin(tag);
- sink.writeMembers(_globalFunctionDependencies);
- sink.writeClasses(_globalClassDependencies);
+ sink.writeMembers(_globalFunctionDependencies, allowNull: true);
+ sink.writeClasses(_globalClassDependencies, allowNull: true);
sink.writeMembers(_helperFunctionsUsed);
sink.writeClasses(_helperClassesUsed);
sink.writeList(runtimeTypeUses, (RuntimeTypeUse runtimeTypeUse) {
diff --git a/pkg/compiler/lib/src/js_backend/field_analysis.dart b/pkg/compiler/lib/src/js_backend/field_analysis.dart
index f2ba357..976fbf3 100644
--- a/pkg/compiler/lib/src/js_backend/field_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/field_analysis.dart
@@ -15,8 +15,7 @@
import '../ir/scope_visitor.dart';
import '../js_model/elements.dart' show JField;
import '../js_model/js_to_frontend_map.dart' show JsToFrontendMap;
-import '../kernel/element_map.dart';
-import '../kernel/kernel_strategy.dart';
+import '../kernel/element_map.dart' show KernelToElementMap;
import '../kernel/kelements.dart' show KClass, KField, KConstructor;
import '../kernel/kernel_world.dart';
import '../options.dart';
@@ -45,8 +44,7 @@
final Map<KClass, ClassData> _classData = {};
final Map<KField, StaticFieldData> _staticFieldData = {};
- KFieldAnalysis(KernelFrontendStrategy kernelStrategy)
- : _elementMap = kernelStrategy.elementMap;
+ KFieldAnalysis(this._elementMap);
// Register class during resolution. Use simple syntactic analysis to find
// null-initialized fields.
diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart
index a08b941..23de9f0 100644
--- a/pkg/compiler/lib/src/js_model/closure.dart
+++ b/pkg/compiler/lib/src/js_model/closure.dart
@@ -1361,51 +1361,6 @@
ClassTypeVariableAccess.none;
}
-class ClosureMemberDefinition implements MemberDefinition {
- /// Tag used for identifying serialized [ClosureMemberDefinition] objects in a
- /// debugging data stream.
- static const String tag = 'closure-member-definition';
-
- @override
- final SourceSpan location;
- @override
- final MemberKind kind;
- @override
- ir.TreeNode get node => _node.loaded();
- final Deferrable<ir.TreeNode> _node;
-
- ClosureMemberDefinition(this.location, this.kind, ir.TreeNode node)
- : _node = Deferrable.eager(node),
- assert(
- kind == MemberKind.closureCall || kind == MemberKind.closureField);
-
- ClosureMemberDefinition._deserialized(this.location, this.kind, this._node)
- : assert(
- kind == MemberKind.closureCall || kind == MemberKind.closureField);
-
- factory ClosureMemberDefinition.readFromDataSource(
- DataSourceReader source, MemberKind kind) {
- source.begin(tag);
- SourceSpan location = source.readSourceSpan();
- Deferrable<ir.TreeNode> node =
- source.readDeferrable(() => source.readTreeNode());
- source.end(tag);
- return ClosureMemberDefinition._deserialized(location, kind, node);
- }
-
- @override
- void writeToDataSink(DataSinkWriter sink) {
- sink.writeEnum(kind);
- sink.begin(tag);
- sink.writeSourceSpan(location);
- sink.writeDeferrable(() => sink.writeTreeNode(node));
- sink.end(tag);
- }
-
- @override
- String toString() => 'ClosureMemberDefinition(kind:$kind,location:$location)';
-}
-
class RecordContainerDefinition implements ClassDefinition {
/// Tag used for identifying serialized [RecordContainerDefinition] objects in
/// a debugging data stream.
diff --git a/pkg/compiler/lib/src/js_model/element_map.dart b/pkg/compiler/lib/src/js_model/element_map.dart
index 5de2c8d..7ec2a72 100644
--- a/pkg/compiler/lib/src/js_model/element_map.dart
+++ b/pkg/compiler/lib/src/js_model/element_map.dart
@@ -422,6 +422,11 @@
SpecialMemberDefinition(ir.TreeNode node, this.kind)
: _node = Deferrable.eager(node);
+ SpecialMemberDefinition.from(MemberDefinition baseMember, this.kind)
+ : _node = baseMember is ClosureMemberDefinition
+ ? baseMember._node
+ : Deferrable.eager(baseMember.node);
+
SpecialMemberDefinition._deserialized(this._node, this.kind);
factory SpecialMemberDefinition.readFromDataSource(
@@ -449,6 +454,51 @@
'node:$node,location:$location)';
}
+class ClosureMemberDefinition implements MemberDefinition {
+ /// Tag used for identifying serialized [ClosureMemberDefinition] objects in a
+ /// debugging data stream.
+ static const String tag = 'closure-member-definition';
+
+ @override
+ final SourceSpan location;
+ @override
+ final MemberKind kind;
+ @override
+ ir.TreeNode get node => _node.loaded();
+ final Deferrable<ir.TreeNode> _node;
+
+ ClosureMemberDefinition(this.location, this.kind, ir.TreeNode node)
+ : _node = Deferrable.eager(node),
+ assert(
+ kind == MemberKind.closureCall || kind == MemberKind.closureField);
+
+ ClosureMemberDefinition._deserialized(this.location, this.kind, this._node)
+ : assert(
+ kind == MemberKind.closureCall || kind == MemberKind.closureField);
+
+ factory ClosureMemberDefinition.readFromDataSource(
+ DataSourceReader source, MemberKind kind) {
+ source.begin(tag);
+ SourceSpan location = source.readSourceSpan();
+ Deferrable<ir.TreeNode> node =
+ source.readDeferrable(() => source.readTreeNode());
+ source.end(tag);
+ return ClosureMemberDefinition._deserialized(location, kind, node);
+ }
+
+ @override
+ void writeToDataSink(DataSinkWriter sink) {
+ sink.writeEnum(kind);
+ sink.begin(tag);
+ sink.writeSourceSpan(location);
+ sink.writeDeferrable(() => sink.writeTreeNode(node));
+ sink.end(tag);
+ }
+
+ @override
+ String toString() => 'ClosureMemberDefinition(kind:$kind,location:$location)';
+}
+
/// Definition information for a [ClassEntity].
abstract class ClassDefinition {
/// The kind of the defined class. This determines the semantics of [node].
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index d23fd743..aa4e6c3 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -1380,7 +1380,7 @@
return lookup;
}
- String /*?*/ _getStringArgument(ir.StaticInvocation node, int index) {
+ String _getStringArgument(ir.StaticInvocation node, int index) {
return node.arguments.positional[index].accept(Stringifier());
}
@@ -2161,14 +2161,15 @@
JGeneratorBody generatorBody = _generatorBodies[function];
if (generatorBody == null) {
FunctionData functionData = members.getData(function);
- ir.TreeNode node = functionData.definition.node;
DartType elementType =
elementEnvironment.getFunctionAsyncOrSyncStarElementType(function);
generatorBody = createGeneratorBody(function, elementType);
members.register<IndexedFunction, FunctionData>(
generatorBody,
- GeneratorBodyFunctionData(functionData,
- SpecialMemberDefinition(node, MemberKind.generatorBody)));
+ GeneratorBodyFunctionData(
+ functionData,
+ SpecialMemberDefinition.from(
+ functionData.definition, MemberKind.generatorBody)));
if (function.enclosingClass != null) {
// TODO(sra): Integrate this with ClassEnvImpl.addConstructorBody ?
diff --git a/pkg/compiler/lib/src/js_model/locals.dart b/pkg/compiler/lib/src/js_model/locals.dart
index 7cdd82c..7412239 100644
--- a/pkg/compiler/lib/src/js_model/locals.dart
+++ b/pkg/compiler/lib/src/js_model/locals.dart
@@ -15,7 +15,7 @@
import '../elements/jumps.dart';
import '../elements/types.dart';
import '../serialization/deferrable.dart';
-import '../serialization/serialization.dart';
+import '../serialization/serialization_interfaces.dart';
import 'element_map.dart';
import 'elements.dart' show JGeneratorBody;
diff --git a/pkg/compiler/lib/src/kernel/kernel_strategy.dart b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
index cd1467f..80486a8 100644
--- a/pkg/compiler/lib/src/kernel/kernel_strategy.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
@@ -46,11 +46,12 @@
import '../util/enumset.dart';
import 'element_map.dart';
import 'element_map_impl.dart';
+import 'kernel_strategy_migrated.dart'; // TODO(48820): Remove when migrated.
import 'native_basic_data.dart';
/// Front end strategy that loads '.dill' files and builds a resolved element
/// model from kernel IR nodes.
-class KernelFrontendStrategy {
+class KernelFrontendStrategy implements KernelFrontendStrategyForBackendUsage {
final CompilerOptions _options;
final CompilerTask _compilerTask;
/*late*/ KernelToElementMap _elementMap;
@@ -146,7 +147,7 @@
commonElements,
nativeBasicData,
_backendUsageBuilder);
- _fieldAnalysis = KFieldAnalysis(this);
+ _fieldAnalysis = KFieldAnalysis(elementMap);
ClassHierarchyBuilder classHierarchyBuilder =
ClassHierarchyBuilder(commonElements, elementMap);
AnnotationsDataBuilder annotationsDataBuilder = AnnotationsDataBuilder();
@@ -249,6 +250,7 @@
/// Returns the [CommonElements] for the element model used in this
/// strategy.
+ @override
KCommonElements get commonElements => _elementMap.commonElements;
KernelToElementMap get elementMap => _elementMap;
@@ -273,6 +275,7 @@
_runtimeTypesNeedBuilder;
/// Creates a [SourceSpan] from [spannable] in context of [currentElement].
+ @override
SourceSpan spanFromSpannable(Spannable spannable, Entity currentElement) {
return _elementMap.getSourceSpan(spannable, currentElement);
}
diff --git a/pkg/compiler/lib/src/kernel/kernel_strategy_migrated.dart b/pkg/compiler/lib/src/kernel/kernel_strategy_migrated.dart
new file mode 100644
index 0000000..25dfcf4
--- /dev/null
+++ b/pkg/compiler/lib/src/kernel/kernel_strategy_migrated.dart
@@ -0,0 +1,17 @@
+// 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.
+
+/// Facades for kernel_strategy.dart.
+// TODO(48820): Remove when frontend_strategy.dart is migrated.
+library dart2js.kernel.frontend_strategy.facades;
+
+import '../common.dart' show SourceSpan, Spannable;
+import '../common/elements.dart' show KCommonElements;
+import '../elements/entities.dart' show Entity;
+
+/// Facade interface for KernelFrontendStrategy.
+abstract class KernelFrontendStrategyForBackendUsage {
+ KCommonElements get commonElements;
+ SourceSpan spanFromSpannable(Spannable spannable, Entity currentElement);
+}
diff --git a/pkg/compiler/lib/src/serialization/deferrable.dart b/pkg/compiler/lib/src/serialization/deferrable.dart
index 9b84e93..a2074aa 100644
--- a/pkg/compiler/lib/src/serialization/deferrable.dart
+++ b/pkg/compiler/lib/src/serialization/deferrable.dart
@@ -55,7 +55,6 @@
/// }
abstract class Deferrable<E> {
E loaded();
- static int count = 0;
factory Deferrable.deferred(DataSourceReader reader, E f(), int offset,
{bool cacheData = true}) =>
diff --git a/pkg/compiler/lib/src/serialization/serialization_interfaces.dart b/pkg/compiler/lib/src/serialization/serialization_interfaces.dart
index dfc601b..9f36a86 100644
--- a/pkg/compiler/lib/src/serialization/serialization_interfaces.dart
+++ b/pkg/compiler/lib/src/serialization/serialization_interfaces.dart
@@ -2,7 +2,8 @@
// 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:kernel/ast.dart' as ir show DartType, Member, TreeNode;
+import 'package:kernel/ast.dart' as ir
+ show DartType, LibraryDependency, Member, Name, TreeNode;
import '../constants/values.dart' show ConstantValue;
import '../elements/entities.dart';
@@ -49,6 +50,19 @@
void writeEnum(dynamic value);
void writeUri(Uri value);
+ void writeMemberNode(ir.Member nvalue);
+ void writeMemberNodes(Iterable<ir.Member>? values, {bool allowNull = false});
+ void writeMemberNodeMap<V>(Map<ir.Member, V>? map, void f(V value),
+ {bool allowNull = false});
+
+ void writeName(ir.Name value);
+ void writeLibraryDependencyNode(ir.LibraryDependency value);
+ void writeLibraryDependencyNodeOrNull(ir.LibraryDependency? value);
+
+ void writeTreeNode(ir.TreeNode value);
+ void writeTreeNodeOrNull(ir.TreeNode value);
+ void writeTreeNodes(Iterable<ir.TreeNode>? values, {bool allowNull = false});
+
// TODO(48820): 'covariant ClassEntity' is used below because the
// implementation takes IndexedClass. What this means is that in pre-NNBD
// code, the call site to the implementation DataSinkWriter has an implicit
@@ -63,7 +77,7 @@
void writeClass(covariant ClassEntity value); // IndexedClass
void writeClassOrNull(covariant ClassEntity? value); // IndexedClass
- void writeClasses(Iterable<ClassEntity> values, {bool allowNull = false});
+ void writeClasses(Iterable<ClassEntity>? values, {bool allowNull = false});
void writeClassMap<V>(Map<ClassEntity, V>? map, void f(V value),
{bool allowNull = false});
@@ -85,6 +99,8 @@
void writeDartTypeNode(ir.DartType value);
void writeDartTypeNodeOrNull(ir.DartType? value);
+ void writeDartTypeNodes(Iterable<ir.DartType>? values,
+ {bool allowNull = false});
void writeDartType(DartType value);
void writeDartTypeOrNull(DartType? value);
@@ -107,6 +123,9 @@
void writeValueOrNull<E>(E? value, void f(E value));
+ void writeDoubleValue(double value);
+ void writeIntegerValue(int value);
+
void writeImport(ImportEntity import);
void writeImportOrNull(ImportEntity? import);
void writeImports(Iterable<ImportEntity>? values, {bool allowNull = false});
@@ -137,6 +156,21 @@
E readEnum<E>(List<E> values);
Uri readUri();
+ ir.Member readMemberNode();
+ List<E> readMemberNodes<E extends ir.Member>();
+ List<E>? readMemberNodesOrNull<E extends ir.Member>();
+ Map<K, V> readMemberNodeMap<K extends ir.Member, V>(V f());
+ Map<K, V>? readMemberNodeMapOrNull<K extends ir.Member, V>(V f());
+
+ ir.Name readName();
+ ir.LibraryDependency readLibraryDependencyNode();
+ ir.LibraryDependency readLibraryDependencyNodeOrNull();
+
+ ir.TreeNode readTreeNode();
+ ir.TreeNode? readTreeNodeOrNull();
+ List<E> readTreeNodes<E extends ir.TreeNode>();
+ List<E>? readTreeNodesOrNull<E extends ir.TreeNode>();
+
ClassEntity readClass(); // IndexedClass
ClassEntity? readClassOrNull(); // IndexedClass
List<E> readClasses<E extends ClassEntity>();
@@ -161,6 +195,8 @@
ir.DartType readDartTypeNode();
ir.DartType? readDartTypeNodeOrNull();
+ List<ir.DartType> readDartTypeNodes();
+ List<ir.DartType>? readDartTypeNodesOrNull();
DartType readDartType();
DartType? readDartTypeOrNull();
@@ -184,6 +220,9 @@
E? readValueOrNull<E>(E f());
+ double readDoubleValue();
+ int readIntegerValue();
+
ImportEntity readImport();
ImportEntity? readImportOrNull();
List<ImportEntity> readImports();
diff --git a/pkg/compiler/lib/src/serialization/sink.dart b/pkg/compiler/lib/src/serialization/sink.dart
index f1ae16d..dd92d56 100644
--- a/pkg/compiler/lib/src/serialization/sink.dart
+++ b/pkg/compiler/lib/src/serialization/sink.dart
@@ -340,6 +340,7 @@
}
/// Writes a reference to the kernel member node [value] to this data sink.
+ @override
void writeMemberNode(ir.Member value) {
_writeDataKind(DataKind.memberNode);
_writeMemberNode(value);
@@ -367,6 +368,7 @@
///
/// This is a convenience method to be used together with
/// [DataSourceReader.readMemberNodes].
+ @override
void writeMemberNodes(Iterable<ir.Member> values, {bool allowNull = false}) {
if (values == null) {
assert(allowNull);
@@ -385,6 +387,7 @@
///
/// This is a convenience method to be used together with
/// [DataSourceReader.readMemberNodeMap].
+ @override
void writeMemberNodeMap<V>(Map<ir.Member, V> map, void f(V value),
{bool allowNull = false}) {
if (map == null) {
@@ -400,12 +403,14 @@
}
/// Writes a kernel name node to this data sink.
+ @override
void writeName(ir.Name value) {
writeString(value.text);
writeValueOrNull(value.library, writeLibraryNode);
}
/// Writes a kernel library dependency node [value] to this data sink.
+ @override
void writeLibraryDependencyNode(ir.LibraryDependency value) {
ir.Library library = value.parent;
writeLibraryNode(library);
@@ -414,11 +419,13 @@
/// Writes a potentially `null` kernel library dependency node [value] to
/// this data sink.
+ @override
void writeLibraryDependencyNodeOrNull(ir.LibraryDependency value) {
writeValueOrNull(value, writeLibraryDependencyNode);
}
/// Writes a reference to the kernel tree node [value] to this data sink.
+ @override
void writeTreeNode(ir.TreeNode value) {
_writeDataKind(DataKind.treeNode);
_writeTreeNode(value, null);
@@ -465,6 +472,7 @@
///
/// This is a convenience method to be used together with
/// [DataSourceReader.readTreeNodeOrNull].
+ @override
void writeTreeNodeOrNull(ir.TreeNode value) {
writeBool(value != null);
if (value != null) {
@@ -477,6 +485,7 @@
///
/// This is a convenience method to be used together with
/// [DataSourceReader.readTreeNodes].
+ @override
void writeTreeNodes(Iterable<ir.TreeNode> values, {bool allowNull = false}) {
if (values == null) {
assert(allowNull);
@@ -692,6 +701,7 @@
///
/// This is a convenience method to be used together with
/// [DataSourceReader.readDartTypeNodes].
+ @override
void writeDartTypeNodes(Iterable<ir.DartType> values,
{bool allowNull = false}) {
if (values == null) {
@@ -1112,6 +1122,7 @@
}
/// Writes a double value to this data sink.
+ @override
void writeDoubleValue(double value) {
_writeDataKind(DataKind.double);
_writeDoubleValue(value);
@@ -1130,6 +1141,7 @@
///
/// This is should only when the value is not known to be a non-negative
/// 30 bit integer. Otherwise [writeInt] should be used.
+ @override
void writeIntegerValue(int value) {
_writeDataKind(DataKind.int);
_writeBigInt(BigInt.from(value));
diff --git a/pkg/compiler/lib/src/serialization/source.dart b/pkg/compiler/lib/src/serialization/source.dart
index c512786..e2d1e6b 100644
--- a/pkg/compiler/lib/src/serialization/source.dart
+++ b/pkg/compiler/lib/src/serialization/source.dart
@@ -481,6 +481,7 @@
}
/// Reads a reference to a kernel member node from this data source.
+ @override
ir.Member readMemberNode() {
_checkDataKind(DataKind.memberNode);
return _readMemberData().node;
@@ -506,31 +507,47 @@
}
/// Reads a list of references to kernel member nodes from this data source.
- /// If [emptyAsNull] is `true`, `null` is returned instead of an empty list.
///
/// This is a convenience method to be used together with
/// [DataSinkWriter.writeMemberNodes].
- List<E> readMemberNodes<E extends ir.Member>({bool emptyAsNull = false}) {
+ @override
+ List<E> readMemberNodes<E extends ir.Member>() {
+ return readMemberNodesOrNull<E>() ?? List.empty();
+ }
+
+ /// Reads a list of references to kernel member nodes from this data source.
+ /// `null` is returned instead of an empty list.
+ ///
+ /// This is a convenience method to be used together with
+ /// [DataSinkWriter.writeMemberNodes].
+ @override
+ List<E> readMemberNodesOrNull<E extends ir.Member>() {
int count = readInt();
- if (count == 0 && emptyAsNull) return null;
- List<E> list = List<E>.filled(count, null);
- for (int i = 0; i < count; i++) {
- ir.Member value = readMemberNode();
- list[i] = value;
- }
- return list;
+ if (count == 0) return null;
+ return List<E>.generate(count, (_) => readMemberNode() as E,
+ growable: false);
}
/// Reads a map from kernel member nodes to [V] values from this data source,
- /// calling [f] to read each value from the data source. If [emptyAsNull] is
- /// `true`, `null` is returned instead of an empty map.
+ /// calling [f] to read each value from the data source.
///
/// This is a convenience method to be used together with
/// [DataSinkWriter.writeMemberNodeMap].
- Map<K, V> readMemberNodeMap<K extends ir.Member, V>(V f(),
- {bool emptyAsNull = false}) {
+ @override
+ Map<K, V> readMemberNodeMap<K extends ir.Member, V>(V f()) {
+ return readMemberNodeMapOrNull<K, V>(f) ?? {};
+ }
+
+ /// Reads a map from kernel member nodes to [V] values from this data source,
+ /// calling [f] to read each value from the data source. `null` is returned
+ /// instead of an empty map.
+ ///
+ /// This is a convenience method to be used together with
+ /// [DataSinkWriter.writeMemberNodeMap].
+ @override
+ Map<K, V> /*?*/ readMemberNodeMapOrNull<K extends ir.Member, V>(V f()) {
int count = readInt();
- if (count == 0 && emptyAsNull) return null;
+ if (count == 0) return null;
Map<K, V> map = {};
for (int i = 0; i < count; i++) {
ir.Member node = readMemberNode();
@@ -541,6 +558,7 @@
}
/// Reads a kernel name node from this data source.
+ @override
ir.Name readName() {
String text = readString();
ir.Library library = readValueOrNull(readLibraryNode);
@@ -548,6 +566,7 @@
}
/// Reads a kernel library dependency node from this data source.
+ @override
ir.LibraryDependency readLibraryDependencyNode() {
ir.Library library = readLibraryNode();
int index = readInt();
@@ -556,11 +575,13 @@
/// Reads a potentially `null` kernel library dependency node from this data
/// source.
+ @override
ir.LibraryDependency readLibraryDependencyNodeOrNull() {
return readValueOrNull(readLibraryDependencyNode);
}
/// Reads a reference to a kernel tree node from this data source.
+ @override
ir.TreeNode readTreeNode() {
_checkDataKind(DataKind.treeNode);
return _readTreeNode(null);
@@ -601,6 +622,7 @@
/// Reads a reference to a potentially `null` kernel tree node from this data
/// source.
+ @override
ir.TreeNode readTreeNodeOrNull() {
bool hasValue = readBool();
if (hasValue) {
@@ -610,19 +632,24 @@
}
/// Reads a list of references to kernel tree nodes from this data source.
- /// If [emptyAsNull] is `true`, `null` is returned instead of an empty list.
///
/// This is a convenience method to be used together with
/// [DataSinkWriter.writeTreeNodes].
- List<E> readTreeNodes<E extends ir.TreeNode>({bool emptyAsNull = false}) {
+ @override
+ List<E> readTreeNodes<E extends ir.TreeNode>() {
+ return readTreeNodesOrNull<E>() ?? List.empty();
+ }
+
+ /// Reads a list of references to kernel tree nodes from this data source.
+ /// `null` is returned instead of an empty list.
+ ///
+ /// This is a convenience method to be used together with
+ /// [DataSinkWriter.writeTreeNodes].
+ @override
+ List<E> readTreeNodesOrNull<E extends ir.TreeNode>() {
int count = readInt();
- if (count == 0 && emptyAsNull) return null;
- List<E> list = List<E>.filled(count, null);
- for (int i = 0; i < count; i++) {
- ir.TreeNode node = readTreeNode();
- list[i] = node;
- }
- return list;
+ if (count == 0) return null;
+ return List<E>.generate(count, (i) => readTreeNode() as E, growable: false);
}
/// Reads a map from kernel tree nodes to [V] values from this data source,
@@ -906,14 +933,24 @@
throw UnsupportedError("Unexpected DartTypeKind $kind");
}
- /// Reads a list of kernel type nodes from this data source. If [emptyAsNull]
- /// is `true`, `null` is returned instead of an empty list.
+ /// Reads a list of kernel type nodes from this data source.
///
/// This is a convenience method to be used together with
/// [DataSinkWriter.writeDartTypeNodes].
- List<ir.DartType> readDartTypeNodes({bool emptyAsNull = false}) {
+ @override
+ List<ir.DartType> readDartTypeNodes() {
+ return readDartTypeNodesOrNull() ?? const [];
+ }
+
+ /// Reads a list of kernel type nodes from this data source. `null` is
+ /// returned instead of an empty list.
+ ///
+ /// This is a convenience method to be used together with
+ /// [DataSinkWriter.writeDartTypeNodes].
+ @override
+ List<ir.DartType> readDartTypeNodesOrNull() {
int count = readInt();
- if (count == 0 && emptyAsNull) return null;
+ if (count == 0) return null;
List<ir.DartType> list = List<ir.DartType>.filled(count, null);
for (int i = 0; i < count; i++) {
list[i] = readDartTypeNode();
@@ -1366,6 +1403,7 @@
}
/// Reads a double value from this data source.
+ @override
double readDoubleValue() {
_checkDataKind(DataKind.double);
return _readDoubleValue();
@@ -1384,6 +1422,7 @@
///
/// This is should only when the value is not known to be a non-negative
/// 30 bit integer. Otherwise [readInt] should be used.
+ @override
int readIntegerValue() {
_checkDataKind(DataKind.int);
return _readBigInt().toInt();
diff --git a/pkg/compiler/lib/src/source_file_provider.dart b/pkg/compiler/lib/src/source_file_provider.dart
index 41fe730..df9763b 100644
--- a/pkg/compiler/lib/src/source_file_provider.dart
+++ b/pkg/compiler/lib/src/source_file_provider.dart
@@ -502,8 +502,9 @@
///
/// To handle bazel's special layout:
///
-/// * We specify a .packages configuration file that expands packages to their
-/// corresponding bazel location. This way there is no need to create a pub
+/// * We specify a .dart_tool/package_config.json configuration file that
+/// expands packages to their corresponding bazel location.
+/// This way there is no need to create a pub
/// cache prior to invoking dart2js.
///
/// * We provide an implicit mapping that can make all urls relative to the
diff --git a/pkg/compiler/lib/src/universe/feature.dart b/pkg/compiler/lib/src/universe/feature.dart
index f133cca..8dac144 100644
--- a/pkg/compiler/lib/src/universe/feature.dart
+++ b/pkg/compiler/lib/src/universe/feature.dart
@@ -186,9 +186,12 @@
final DartType receiverType;
/// The static type of the argument if [kind] is `RuntimeTypeUseKind.equals`.
- final DartType argumentType;
+ final DartType? argumentType;
- RuntimeTypeUse(this.kind, this.receiverType, this.argumentType);
+ RuntimeTypeUse(this.kind, this.receiverType, this.argumentType) {
+ // TODO(48820): Remove assertions when sound.
+ (receiverType as dynamic)!;
+ }
@override
int get hashCode =>
diff --git a/pkg/compiler/test/end_to_end/modular_loader_test.dart b/pkg/compiler/test/end_to_end/modular_loader_test.dart
index 11132f9..1a136a0 100644
--- a/pkg/compiler/test/end_to_end/modular_loader_test.dart
+++ b/pkg/compiler/test/end_to_end/modular_loader_test.dart
@@ -81,13 +81,15 @@
List<Uri> additionalDills = [
computePlatformBinariesLocation().resolve("dart2js_platform.dill"),
]..addAll(deps.map(toTestUri));
- fs.entityForUri(toTestUri('.packages')).writeAsStringSync('');
+ fs
+ .entityForUri(toTestUri('.dart_tool/package_config.json'))
+ .writeAsStringSync('{"configVersion": 2, "packages": []}');
var options = CompilerOptions()
..target = Dart2jsTarget("dart2js", TargetFlags(enableNullSafety: true))
..fileSystem = TestFileSystem(fs)
..nnbdMode = NnbdMode.Strong
..additionalDills = additionalDills
- ..packagesFileUri = toTestUri('.packages')
+ ..packagesFileUri = toTestUri('.dart_tool/package_config.json')
..explicitExperimentalFlags = {ExperimentalFlag.nonNullable: true};
var inputUris = inputs.map(toTestUri).toList();
var inputUriSet = inputUris.toSet();
diff --git a/pkg/compiler/test/equivalence/id_equivalence_helper.dart b/pkg/compiler/test/equivalence/id_equivalence_helper.dart
index f0e6458..1f740d3 100644
--- a/pkg/compiler/test/equivalence/id_equivalence_helper.dart
+++ b/pkg/compiler/test/equivalence/id_equivalence_helper.dart
@@ -135,7 +135,8 @@
OutputCollector outputCollector = new OutputCollector();
DiagnosticCollector diagnosticCollector = new DiagnosticCollector();
Uri packageConfig;
- Uri wantedPackageConfig = createUriForFileName(".packages");
+ Uri wantedPackageConfig =
+ createUriForFileName(".dart_tool/package_config.json");
for (String key in memorySourceFiles.keys) {
if (key == wantedPackageConfig.path) {
packageConfig = wantedPackageConfig;
diff --git a/pkg/dds/CHANGELOG.md b/pkg/dds/CHANGELOG.md
index d1f139e..8885b43 100644
--- a/pkg/dds/CHANGELOG.md
+++ b/pkg/dds/CHANGELOG.md
@@ -1,3 +1,6 @@
+# 2.2.5
+- Updated `devtools_shared` version to 2.14.1.
+
# 2.2.4
- Fix an issue where DAP adapters could try to remove the same breakpoint multiple times.
diff --git a/pkg/dds/pubspec.yaml b/pkg/dds/pubspec.yaml
index bf4a249..b8b0c65 100644
--- a/pkg/dds/pubspec.yaml
+++ b/pkg/dds/pubspec.yaml
@@ -1,5 +1,5 @@
name: dds
-version: 2.2.4
+version: 2.2.5
description: >-
A library used to spawn the Dart Developer Service, used to communicate with
a Dart VM Service instance.
@@ -14,7 +14,7 @@
browser_launcher: ^1.0.0
collection: ^1.15.0
dds_service_extensions: ^1.3.0
- devtools_shared: ^2.12.1
+ devtools_shared: ^2.14.1
http_multi_server: ^3.0.0
json_rpc_2: ^3.0.0
meta: ^1.1.8
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index becb100..e0a61f3 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -235,7 +235,7 @@
}
}
- /// The .packages file path provided by the user.
+ /// The .dart_tool/package_config.json file path provided by the user.
//
// TODO(jmesserly): the default location is based on the current working
// directory, to match the behavior of dartanalyzer/dartdevc. However the
@@ -244,8 +244,9 @@
// Ultimately this is just the default behavior; in practice users call DDC
// through a build tool, which generally passes in `--packages=`.
//
- // TODO(jmesserly): conceptually CFE should not need a .packages file to
- // resolve package URIs that are in the input summaries, but it seems to.
+ // TODO(jmesserly): conceptually CFE should not need a
+ // .dart_tool/package_config.json file to resolve package URIs that are in the
+ // input summaries, but it seems to.
// This needs further investigation.
var packageFile =
argResults['packages'] as String? ?? _findPackagesFilePath();
@@ -856,7 +857,8 @@
String? _findPackagesFilePath() {
// TODO(jmesserly): this was copied from package:package_config/discovery.dart
// Unfortunately the relevant function is not public. CFE APIs require a URI
- // to the .packages file, rather than letting us provide the package map data.
+ // to the .dart_tool/package_config.json file, rather than letting us provide
+ // the package map data.
var dir = Directory.current;
if (!dir.isAbsolute) dir = dir.absolute;
if (!dir.existsSync()) return null;
diff --git a/pkg/dev_compiler/test/modular_suite.dart b/pkg/dev_compiler/test/modular_suite.dart
index dee5a05..6113349 100644
--- a/pkg/dev_compiler/test/modular_suite.dart
+++ b/pkg/dev_compiler/test/modular_suite.dart
@@ -92,7 +92,10 @@
assert(transitiveDependencies.isEmpty);
} else {
sources = module.sources.map(sourceToImportUri).toList();
- extraArgs = ['--packages-file', '$rootScheme:/.packages'];
+ extraArgs = [
+ '--packages-file',
+ '$rootScheme:/.dart_tool/package_config.json'
+ ];
}
var sdkModule =
@@ -185,14 +188,14 @@
'--dart-sdk-summary',
'${toUri(sdkModule, dillId)}',
'--packages',
- '.packages',
+ '.dart_tool/package_config.json',
];
}
var output = toUri(module, jsId);
var args = [
- '--packages=${sdkRoot.toFilePath()}/.packages',
+ '--packages=${sdkRoot.toFilePath()}/.dart_tool/package_config.json',
_dartdevcScript,
'--kernel',
'--modules=es6',
diff --git a/pkg/dev_compiler/test/modular_suite_nnbd.dart b/pkg/dev_compiler/test/modular_suite_nnbd.dart
index c5c0567..5b3b5f7 100644
--- a/pkg/dev_compiler/test/modular_suite_nnbd.dart
+++ b/pkg/dev_compiler/test/modular_suite_nnbd.dart
@@ -91,7 +91,10 @@
assert(transitiveDependencies.isEmpty);
} else {
sources = module.sources.map(sourceToImportUri).toList();
- extraArgs = ['--packages-file', '$rootScheme:/.packages'];
+ extraArgs = [
+ '--packages-file',
+ '$rootScheme:/.dart_tool/package_config.json'
+ ];
}
var sdkModule =
@@ -184,14 +187,14 @@
'--dart-sdk-summary',
'${toUri(sdkModule, dillId)}',
'--packages',
- '.packages',
+ '.dart_tool/package_config.json',
];
}
var output = toUri(module, jsId);
var args = [
- '--packages=${sdkRoot.toFilePath()}/.packages',
+ '--packages=${sdkRoot.toFilePath()}/.dart_tool/package_config.json',
_dartdevcScript,
'--kernel',
'--modules=es6',
diff --git a/pkg/dev_compiler/test/nullable_inference_test.dart b/pkg/dev_compiler/test/nullable_inference_test.dart
index e8b30e9..b8ad050 100644
--- a/pkg/dev_compiler/test/nullable_inference_test.dart
+++ b/pkg/dev_compiler/test/nullable_inference_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
+import 'dart:convert' show jsonEncode;
import 'dart:io';
import 'package:dev_compiler/src/kernel/command.dart' show getSdkPath;
@@ -665,10 +666,18 @@
var librariesJson = p.join(getSdkPath(), 'lib', 'libraries.json');
librariesFile.writeAsBytesSync(File(librariesJson).readAsBytesSync());
}
- var packagesUri = Uri.file('/memory/.packages');
+ var packagesUri = Uri.file('/memory/.dart_tool/package_config.json');
var packagesFile = _fileSystem.entityForUri(packagesUri);
if (!await packagesFile.exists()) {
- packagesFile.writeAsStringSync('meta:/memory/meta/lib');
+ packagesFile.writeAsStringSync(jsonEncode({
+ 'configVersion': 2,
+ 'packages': [
+ {
+ 'name': 'meta',
+ 'rootUri': '/memory/meta/lib',
+ },
+ ],
+ }));
_fileSystem
.entityForUri(Uri.file('/memory/meta/lib/meta.dart'))
.writeAsStringSync('''
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 3543755..c94d998 100644
--- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart
+++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
@@ -64,18 +64,16 @@
DiagnosticMessageHandler? onDiagnostic;
- /// URI of the ".dart_tool/package_config.json" or ".packages" file
+ /// URI of the ".dart_tool/package_config.json" file
/// (typically a "file:" URI).
///
- /// If a ".packages" file is given and a ".dart_tool/package_config.json" file
- /// exists next to it, the ".dart_tool/package_config.json" file is used
- /// instead.
- ///
/// If `null`, the file will be found via the standard package_config search
/// algorithm.
///
/// If the URI's path component is empty (e.g. `new Uri()`), no packages file
/// will be used.
+ ///
+ /// If an old ".packages" file is given an error is issued.
Uri? packagesFileUri;
/// URIs of additional dill files.
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index 2a6e8f6..a6c12a0 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -101,8 +101,9 @@
/// not been computed yet.
PackageConfig? _packages;
- /// The uri for .packages derived from the options, or `null` if the package
- /// map has not been computed yet or there is no .packages in effect.
+ /// The uri for package_config.json derived from the options, or `null` if the
+ /// package map has not been computed yet or there is no package_config.json
+ /// in effect.
Uri? _packagesUri;
Uri? get packagesUri => _packagesUri;
@@ -541,7 +542,7 @@
if (inputs.length > 1) {
// TODO(sigmund): consider not reporting an error if we would infer
- // the same .packages file from all of the inputs.
+ // the same `package_config.json` file from all of the inputs.
reportWithoutLocation(
messageCantInferPackagesFromManyInputs, Severity.error);
return _packages = PackageConfig.empty;
@@ -560,11 +561,10 @@
return _packages = await _findPackages(input);
}
- Future<Uint8List?> _readFile(Uri uri, bool reportError) async {
+ Future<Uint8List?> _readFile(Uri uri) async {
try {
// TODO(ahe): We need to compute line endings for this file.
FileSystemEntity entityForUri = fileSystem.entityForUri(uri);
- if (!reportError && !await entityForUri.exists()) return null;
List<int> fileContents = await entityForUri.readAsBytes();
if (fileContents is Uint8List) {
return fileContents;
@@ -572,10 +572,8 @@
return new Uint8List.fromList(fileContents);
}
} on FileSystemException catch (e) {
- if (reportError) {
- reportWithoutLocation(
- templateCantReadFile.withArguments(uri, e.message), Severity.error);
- }
+ reportWithoutLocation(
+ templateCantReadFile.withArguments(uri, e.message), Severity.error);
} catch (e) {
Message message = templateExceptionReadingFile.withArguments(uri, '$e');
reportWithoutLocation(message, Severity.error);
@@ -587,22 +585,16 @@
return null;
}
- /// Create a [PackageConfig] given the Uri to a `.packages` or
- /// `package_config.json` file.
+ /// Create a [PackageConfig] given the Uri to a `package_config.json` file.
///
- /// If the file doesn't exist, it returns null (and an error is reported
- /// based in [forceCreation]).
- /// If the file does exist but is invalid an error is always reported and an
- /// empty package config is returned.
- Future<PackageConfig?> _createPackagesFromFile(
- Uri requestedUri, bool forceCreation, bool requireJson) async {
- Uint8List? contents = await _readFile(requestedUri, forceCreation);
+ /// If the file doesn't exist, it returns null (and an error is reported).
+ /// If the file does exist but is invalid (e.g. if it's an old `.packages`
+ /// file) an error is always reported and an empty package config is returned.
+ Future<PackageConfig?> _createPackagesFromFile(Uri requestedUri) async {
+ Uint8List? contents = await _readFile(requestedUri);
if (contents == null) {
- if (forceCreation) {
- _packagesUri = null;
- return PackageConfig.empty;
- }
- return null;
+ _packagesUri = null;
+ return PackageConfig.empty;
}
_packagesUri = requestedUri;
@@ -620,18 +612,7 @@
Severity.error);
}
};
- if (requireJson) {
- return PackageConfig.parseBytes(contents, requestedUri,
- onError: onError);
- }
- return await loadPackageConfigUri(requestedUri, preferNewest: false,
- loader: (uri) {
- if (uri != requestedUri) {
- throw new StateError(
- "Unexpected request from package config package");
- }
- return new Future.value(contents);
- }, onError: onError);
+ return PackageConfig.parseBytes(contents, requestedUri, onError: onError);
} on FormatException catch (e) {
report(
templatePackagesFileFormat
@@ -647,24 +628,11 @@
return PackageConfig.empty;
}
- /// Create a [PackageConfig] given the Uri to a `.packages` or
- /// `package_config.json` file.
+ /// Create a [PackageConfig] given the Uri to a `package_config.json` file.
///
- /// Note that if a `.packages` file is provided and an appropriately placed
- /// (relative to the .packages file) `package_config.json` file exists, the
- /// `package_config.json` file will be used instead.
+ /// Note that if an old `.packages` file is provided an error will be issued.
Future<PackageConfig> createPackagesFromFile(Uri file) async {
- // If the input is a ".packages" file we assume the standard layout, and
- // if a ".dart_tool/package_config.json" exists, we'll use that (and require
- // it to be a json file).
- PackageConfig? result;
- if (file.path.endsWith("/.packages")) {
- // .packages -> try the package_config first.
- Uri tryFirst = file.resolve(".dart_tool/package_config.json");
- result = await _createPackagesFromFile(tryFirst, false, true);
- if (result != null) return result;
- }
- result = await _createPackagesFromFile(file, true, false);
+ PackageConfig? result = await _createPackagesFromFile(file);
return result ?? PackageConfig.empty;
}
@@ -673,8 +641,8 @@
/// The [scriptUri] points to a Dart script with a valid scheme accepted by
/// the [FileSystem].
///
- /// This function first tries to locate a `.dart_tool/package_config.json`
- /// (then a `.packages`) file in the `scriptUri` directory.
+ /// This function tries to locate a `.dart_tool/package_config.json` file in
+ /// the `scriptUri` directory.
/// If that is not found, it starts checking parent directories, and stops if
/// it finds it. Otherwise it gives up and returns [PackageConfig.empty].
///
@@ -695,8 +663,6 @@
try {
candidate = dir.resolve('.dart_tool/package_config.json');
if (await fileSystem.entityForUri(candidate).exists()) return candidate;
- candidate = dir.resolve('.packages');
- if (await fileSystem.entityForUri(candidate).exists()) return candidate;
return null;
} catch (e) {
Message message =
@@ -709,11 +675,11 @@
}
}
- // Check for $cwd/.packages
+ // Check for $cwd/.dart_tool/package_config.json
Uri? candidate = await checkInDir(dir);
if (candidate != null) return createPackagesFromFile(candidate);
- // Check for cwd(/..)+/.packages
+ // Check for cwd(/..)+/.dart_tool/package_config.json
Uri parentDir = dir.resolve('..');
while (parentDir.path != dir.path) {
candidate = await checkInDir(parentDir);
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 496be18..a88180b 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
@@ -11,6 +11,7 @@
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/reference_from_index.dart' show IndexedClass;
+import 'package:kernel/transformations/flags.dart';
import '../builder/builder.dart';
import '../builder/class_builder.dart';
@@ -800,20 +801,35 @@
SourceProcedureBuilder toStringBuilder =
firstMemberNamed("toString") as SourceProcedureBuilder;
- ClassBuilder enumClass =
- _computeEnumSupertype()!.declaration as ClassBuilder;
- MemberBuilder? nameFieldBuilder =
- enumClass.lookupLocalMember("_name") as MemberBuilder?;
- assert(nameFieldBuilder != null);
- Field nameField = nameFieldBuilder!.member as Field;
+ Name toStringName = new Name("toString");
+ Member? superToString = cls.superclass != null
+ ? classHierarchy.getDispatchTarget(cls.superclass!, toStringName)
+ : null;
+ Procedure? toStringSuperTarget = superToString is Procedure &&
+ superToString.enclosingClass != classHierarchy.coreTypes.objectClass
+ ? superToString
+ : null;
- toStringBuilder.body = new ReturnStatement(new StringConcatenation([
- new StringLiteral("${cls.demangledName}."),
- new InstanceGet.byReference(
- InstanceAccessKind.Instance, new ThisExpression(), nameField.name,
- interfaceTargetReference: nameField.getterReference,
- resultType: nameField.getterType),
- ]));
+ if (toStringSuperTarget != null) {
+ toStringBuilder.member.transformerFlags |= TransformerFlag.superCalls;
+ toStringBuilder.body = new ReturnStatement(new SuperMethodInvocation(
+ toStringName, new Arguments([]), toStringSuperTarget));
+ } else {
+ ClassBuilder enumClass =
+ _computeEnumSupertype()!.declaration as ClassBuilder;
+ MemberBuilder? nameFieldBuilder =
+ enumClass.lookupLocalMember("_name") as MemberBuilder?;
+ assert(nameFieldBuilder != null);
+ Field nameField = nameFieldBuilder!.member as Field;
+
+ toStringBuilder.body = new ReturnStatement(new StringConcatenation([
+ new StringLiteral("${cls.demangledName}."),
+ new InstanceGet.byReference(
+ InstanceAccessKind.Instance, new ThisExpression(), nameField.name,
+ interfaceTargetReference: nameField.getterReference,
+ resultType: nameField.getterType),
+ ]));
+ }
super.buildOutlineExpressions(
classHierarchy, delayedActionPerformers, delayedDefaultValueCloners);
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 626c3c3..f7c0b5c 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -547,9 +547,9 @@
/// Set the language version to an explicit major and minor version.
///
- /// The default language version specified by the .packages file is passed
- /// to the constructor, but the library can have source code that specifies
- /// another one which should be supported.
+ /// The default language version specified by the `package_config.json` file
+ /// is passed to the constructor, but the library can have source code that
+ /// specifies another one which should be supported.
///
/// Only the first registered language version is used.
///
diff --git a/pkg/front_end/lib/src/testing/compiler_common.dart b/pkg/front_end/lib/src/testing/compiler_common.dart
index f8cebf7..4f8a481 100644
--- a/pkg/front_end/lib/src/testing/compiler_common.dart
+++ b/pkg/front_end/lib/src/testing/compiler_common.dart
@@ -81,7 +81,8 @@
/// contain either source files (value is [String]) or .dill files (value
/// is [List<int>]).
///
-/// * define an empty .packages file (if one isn't defined in sources)
+/// * define an empty `package_config.json` file (if one isn't defined in
+/// sources).
///
/// * specify the location of the sdk summaries.
Future<Null> setup(CompilerOptions options, Map<String, dynamic> sources,
@@ -95,9 +96,11 @@
entity.writeAsBytesSync(data);
}
});
- MemoryFileSystemEntity dotPackagesFile =
- fs.entityForUri(toTestUri('.packages'));
- if (!await dotPackagesFile.exists()) dotPackagesFile.writeAsStringSync('');
+ MemoryFileSystemEntity packageConfigFile =
+ fs.entityForUri(toTestUri('.dart_tool/package_config.json'));
+ if (!await packageConfigFile.exists()) {
+ packageConfigFile.writeAsStringSync('{"configVersion": 2, "packages": []}');
+ }
fs
.entityForUri(invalidCoreLibsSpecUri)
.writeAsStringSync(_invalidLibrariesSpec);
@@ -106,7 +109,7 @@
..fileSystem = new HybridFileSystem(fs)
..additionalDills = additionalDills.map(toTestUri).toList();
if (options.packagesFileUri == null) {
- options.packagesFileUri = toTestUri('.packages');
+ options.packagesFileUri = toTestUri('.dart_tool/package_config.json');
}
if (options.sdkSummary == null) {
diff --git a/pkg/front_end/test/hot_reload_e2e_test.dart b/pkg/front_end/test/hot_reload_e2e_test.dart
index aa8e855..0adcb12c 100644
--- a/pkg/front_end/test/hot_reload_e2e_test.dart
+++ b/pkg/front_end/test/hot_reload_e2e_test.dart
@@ -73,7 +73,8 @@
writeFile(fs, 'a.dart', sourceA);
writeFile(fs, 'b.dart', sourceB);
writeFile(fs, 'c.dart', sourceC);
- writeFile(fs, '.packages', '');
+ writeFile(fs, '.dart_tool/package_config.json',
+ '{"configVersion": 2, "packages": []}');
compiler = createIncrementalCompiler(
'org-dartlang-test:///a.dart', new HybridFileSystem(fs));
await rebuild(compiler, outputUri); // this is a full compile.
diff --git a/pkg/front_end/test/id_testing/data/directory_testing/.packages b/pkg/front_end/test/id_testing/data/directory_testing/.packages
deleted file mode 100644
index 554a99c..0000000
--- a/pkg/front_end/test/id_testing/data/directory_testing/.packages
+++ /dev/null
@@ -1 +0,0 @@
-foo:lib/
\ No newline at end of file
diff --git a/pkg/front_end/test/language_versioning/data/allowed_experiments_with_packages/.packages b/pkg/front_end/test/language_versioning/data/allowed_experiments_with_packages/.packages
deleted file mode 100644
index 00d3dbb..0000000
--- a/pkg/front_end/test/language_versioning/data/allowed_experiments_with_packages/.packages
+++ /dev/null
@@ -1 +0,0 @@
-collection:foo/lib/
\ No newline at end of file
diff --git a/pkg/front_end/test/language_versioning/data/allowed_experiments_with_packages/foo/bin/bin_file.dart b/pkg/front_end/test/language_versioning/data/allowed_experiments_with_packages/foo/bin/bin_file.dart
deleted file mode 100644
index 1046332..0000000
--- a/pkg/front_end/test/language_versioning/data/allowed_experiments_with_packages/foo/bin/bin_file.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*library:
- languageVersion=2.7,
- packageUri=package:collection
-*/
-
-method1() {}
diff --git a/pkg/front_end/test/language_versioning/data/allowed_experiments_with_packages/foo/lib/foo.dart b/pkg/front_end/test/language_versioning/data/allowed_experiments_with_packages/foo/lib/foo.dart
deleted file mode 100644
index e72d3b0..0000000
--- a/pkg/front_end/test/language_versioning/data/allowed_experiments_with_packages/foo/lib/foo.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*library: languageVersion=2.7*/
-
-method2() {}
diff --git a/pkg/front_end/test/language_versioning/data/allowed_experiments_with_packages/foo/test/test_file.dart b/pkg/front_end/test/language_versioning/data/allowed_experiments_with_packages/foo/test/test_file.dart
deleted file mode 100644
index 4c47d9b..0000000
--- a/pkg/front_end/test/language_versioning/data/allowed_experiments_with_packages/foo/test/test_file.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*library:
- languageVersion=2.7,
- packageUri=package:collection
-*/
-
-method3() {}
diff --git a/pkg/front_end/test/language_versioning/data/allowed_experiments_with_packages/main.dart b/pkg/front_end/test/language_versioning/data/allowed_experiments_with_packages/main.dart
deleted file mode 100644
index cb6feec..0000000
--- a/pkg/front_end/test/language_versioning/data/allowed_experiments_with_packages/main.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*library: languageVersion=2.8*/
-
-import 'foo/bin/bin_file.dart';
-import 'foo/test/test_file.dart';
-import 'package:collection/foo.dart';
-
-main() {}
diff --git a/pkg/front_end/test/language_versioning/data/language_version_in_packages/.packages b/pkg/front_end/test/language_versioning/data/language_version_in_packages/.packages
deleted file mode 100644
index 6bfeac3..0000000
--- a/pkg/front_end/test/language_versioning/data/language_version_in_packages/.packages
+++ /dev/null
@@ -1 +0,0 @@
-foo:lib//*error: errors=PackagesFileFormat*/#dart=2.6
\ No newline at end of file
diff --git a/pkg/front_end/test/language_versioning/data/language_version_in_packages/lib/foo.dart b/pkg/front_end/test/language_versioning/data/language_version_in_packages/lib/foo.dart
deleted file mode 100644
index 6d45456..0000000
--- a/pkg/front_end/test/language_versioning/data/language_version_in_packages/lib/foo.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-/*library: languageVersion=2.7*/
-
-String foo() {
- return "42";
-}
diff --git a/pkg/front_end/test/language_versioning/data/language_version_in_packages/main.dart b/pkg/front_end/test/language_versioning/data/language_version_in_packages/main.dart
deleted file mode 100644
index 13b6127..0000000
--- a/pkg/front_end/test/language_versioning/data/language_version_in_packages/main.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Set version of this file (not technically in package) explicitly to test as
-// much as possibly separately.
-
-// @dart = 2.4
-
-import 'package:foo/foo.dart';
-
-/*library:
- languageVersion=2.4,
- packageUri=package:foo
-*/
-
-main() {
- var result = foo();
- print(result);
-}
diff --git a/pkg/front_end/test/language_versioning/data/library_with_no_version.dart b/pkg/front_end/test/language_versioning/data/library_with_no_version.dart
index 3b64d66..66a962f 100644
--- a/pkg/front_end/test/language_versioning/data/library_with_no_version.dart
+++ b/pkg/front_end/test/language_versioning/data/library_with_no_version.dart
@@ -2,7 +2,8 @@
// 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.
-// If no language version is specified, and none if given in a .packages file,
+// If no language version is specified, and none if given in a
+// .dart_tool/package_config.json file,
// we default to the most reason one. In the tests this is hard-coded to 2.8.
/*library: languageVersion=2.8*/
diff --git a/pkg/front_end/test/language_versioning/data/package_default_version/lib/foo3.dart b/pkg/front_end/test/language_versioning/data/package_default_version/lib/foo3.dart
index 6ffcfd9..7f23410 100644
--- a/pkg/front_end/test/language_versioning/data/package_default_version/lib/foo3.dart
+++ b/pkg/front_end/test/language_versioning/data/package_default_version/lib/foo3.dart
@@ -2,7 +2,8 @@
// 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.
-// .packages specifies 2.5, this library tries to go above that, which is fine.
+// .dart_tool/package_config.json specifies 2.5, this library tries to go above
+// that, which is fine.
// @dart = 2.6
diff --git a/pkg/front_end/test/language_versioning/data/package_default_version/lib/foo4.dart b/pkg/front_end/test/language_versioning/data/package_default_version/lib/foo4.dart
index 3d3297c..c946e69 100644
--- a/pkg/front_end/test/language_versioning/data/package_default_version/lib/foo4.dart
+++ b/pkg/front_end/test/language_versioning/data/package_default_version/lib/foo4.dart
@@ -2,9 +2,10 @@
// 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.
-// .packages specifies 2.5, this library tries to go above that, which is fine,
-// except it still has to be within the range of the sdk. The library stays on
-// the .packages specified one (2.5) and an error is issued.
+// .dart_tool/package_config.json specifies 2.5, this library tries to go above
+// that, which is fine, except it still has to be within the range of the sdk.
+// The library stays on the .dart_tool/package_config.json specified one (2.5)
+// and an error is issued.
/*error: errors=LanguageVersionTooHigh*/
// @dart = 2.9
diff --git a/pkg/front_end/test/language_versioning/data/package_no_default_version/lib/foo.dart b/pkg/front_end/test/language_versioning/data/package_no_default_version/lib/foo.dart
index c5ecb8b..e731015 100644
--- a/pkg/front_end/test/language_versioning/data/package_no_default_version/lib/foo.dart
+++ b/pkg/front_end/test/language_versioning/data/package_no_default_version/lib/foo.dart
@@ -2,7 +2,8 @@
// 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.
-// If no language version is specified, and none if given in a .packages file,
+// If no language version is specified, and none if given in a
+// .dart_tool/package_config.json file,
// we default to the most reason one. In the tests this is hard-coded to 2.8.
/*library: languageVersion=2.8*/
diff --git a/pkg/front_end/test/language_versioning/data/package_with_test_packages/.packages b/pkg/front_end/test/language_versioning/data/package_with_test_packages/.packages
deleted file mode 100644
index 91fa8dd..0000000
--- a/pkg/front_end/test/language_versioning/data/package_with_test_packages/.packages
+++ /dev/null
@@ -1 +0,0 @@
-foo:foo/lib/
\ No newline at end of file
diff --git a/pkg/front_end/test/language_versioning/data/package_with_test_packages/foo/bin/bin_file.dart b/pkg/front_end/test/language_versioning/data/package_with_test_packages/foo/bin/bin_file.dart
deleted file mode 100644
index 8f4889a..0000000
--- a/pkg/front_end/test/language_versioning/data/package_with_test_packages/foo/bin/bin_file.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*library:
- languageVersion=2.7,
- packageUri=package:foo
-*/
-
-method1() {}
diff --git a/pkg/front_end/test/language_versioning/data/package_with_test_packages/foo/lib/foo.dart b/pkg/front_end/test/language_versioning/data/package_with_test_packages/foo/lib/foo.dart
deleted file mode 100644
index e72d3b0..0000000
--- a/pkg/front_end/test/language_versioning/data/package_with_test_packages/foo/lib/foo.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*library: languageVersion=2.7*/
-
-method2() {}
diff --git a/pkg/front_end/test/language_versioning/data/package_with_test_packages/foo/test/test_file.dart b/pkg/front_end/test/language_versioning/data/package_with_test_packages/foo/test/test_file.dart
deleted file mode 100644
index f58d00c..0000000
--- a/pkg/front_end/test/language_versioning/data/package_with_test_packages/foo/test/test_file.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*library:
- languageVersion=2.7,
- packageUri=package:foo
-*/
-
-method3() {}
diff --git a/pkg/front_end/test/language_versioning/data/package_with_test_packages/main.dart b/pkg/front_end/test/language_versioning/data/package_with_test_packages/main.dart
deleted file mode 100644
index b29bc24..0000000
--- a/pkg/front_end/test/language_versioning/data/package_with_test_packages/main.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*library: languageVersion=2.8*/
-
-import 'foo/bin/bin_file.dart';
-import 'foo/test/test_file.dart';
-import 'package:foo/foo.dart';
-
-main() {}
diff --git a/pkg/front_end/test/language_versioning/data/specified_packages_01/test.options b/pkg/front_end/test/language_versioning/data/specified_packages_01/test.options
index 9044751..7279cca 100644
--- a/pkg/front_end/test/language_versioning/data/specified_packages_01/test.options
+++ b/pkg/front_end/test/language_versioning/data/specified_packages_01/test.options
@@ -1,2 +1 @@
-# Point to .packages => Standard layout; redirect to .dart_tool/package_config.json
---packages=.packages
+# No packages specified. It finds .dart_tool/package_config.json automatically.
diff --git a/pkg/front_end/test/language_versioning/data/specified_packages_02/.packagesX b/pkg/front_end/test/language_versioning/data/specified_packages_02/.packagesX
index a0a43fc..2983e0b 100644
--- a/pkg/front_end/test/language_versioning/data/specified_packages_02/.packagesX
+++ b/pkg/front_end/test/language_versioning/data/specified_packages_02/.packagesX
@@ -1 +1 @@
-foo:foo1/
\ No newline at end of file
+/*error: errors=PackagesFileFormat*/foo:foo1/
\ No newline at end of file
diff --git a/pkg/front_end/test/language_versioning/data/specified_packages_02/foo1/foo.dart b/pkg/front_end/test/language_versioning/data/specified_packages_02/foo1/foo.dart
index 2873e02..c434df6 100644
--- a/pkg/front_end/test/language_versioning/data/specified_packages_02/foo1/foo.dart
+++ b/pkg/front_end/test/language_versioning/data/specified_packages_02/foo1/foo.dart
@@ -1,4 +1,4 @@
-/*library: languageVersion=2.7*/
+// This file shouldn't even be compiled.
int notNamedFoo() {
return 42;
diff --git a/pkg/front_end/test/language_versioning/data/specified_packages_02/foo2/foo.dart b/pkg/front_end/test/language_versioning/data/specified_packages_02/foo2/foo.dart
index 449c3f0..c41a2b7 100644
--- a/pkg/front_end/test/language_versioning/data/specified_packages_02/foo2/foo.dart
+++ b/pkg/front_end/test/language_versioning/data/specified_packages_02/foo2/foo.dart
@@ -1,4 +1,4 @@
-// No language version --- this file shouldn't even be compiled.
+// This file shouldn't even be compiled.
String foo() {
return "42";
diff --git a/pkg/front_end/test/language_versioning/data/specified_packages_02/main.dart b/pkg/front_end/test/language_versioning/data/specified_packages_02/main.dart
index 3dc5e95..b36e8ea 100644
--- a/pkg/front_end/test/language_versioning/data/specified_packages_02/main.dart
+++ b/pkg/front_end/test/language_versioning/data/specified_packages_02/main.dart
@@ -7,11 +7,11 @@
// @dart = 2.4
-import 'package:foo/foo.dart';
+import /*error: errors=UntranslatableUri*/ 'package:foo/foo.dart';
/*library: languageVersion=2.4*/
main() {
- var result = notNamedFoo();
+ var result = /*error: errors=MethodNotFound*/ notNamedFoo();
print(result);
}
diff --git a/pkg/front_end/test/language_versioning/data/specified_packages_02/null b/pkg/front_end/test/language_versioning/data/specified_packages_02/null
new file mode 100644
index 0000000..5b039db
--- /dev/null
+++ b/pkg/front_end/test/language_versioning/data/specified_packages_02/null
@@ -0,0 +1 @@
+/*error: errors=PackageNotFound*/
\ No newline at end of file
diff --git a/pkg/front_end/test/language_versioning/data/specified_packages_02/test.options b/pkg/front_end/test/language_versioning/data/specified_packages_02/test.options
index d3ccc47..23d4c8b 100644
--- a/pkg/front_end/test/language_versioning/data/specified_packages_02/test.options
+++ b/pkg/front_end/test/language_versioning/data/specified_packages_02/test.options
@@ -1,2 +1,2 @@
-# Point to .packagesX => non-standard layout; use it directly
+# Point to a non-json file. Try to use it, it should give an error.
--packages=.packagesX
diff --git a/pkg/front_end/test/language_versioning/data/specified_packages_04/test.options b/pkg/front_end/test/language_versioning/data/specified_packages_04/test.options
index 5c8ed21..7279cca 100644
--- a/pkg/front_end/test/language_versioning/data/specified_packages_04/test.options
+++ b/pkg/front_end/test/language_versioning/data/specified_packages_04/test.options
@@ -1,2 +1 @@
-# Point to .packages => Standard layout; redirect to .dart_tool/package_config.json which in this case isn't a json file. That's an error!
---packages=.packages
+# No packages specified. It finds .dart_tool/package_config.json automatically.
diff --git a/pkg/front_end/test/src/base/processed_options_test.dart b/pkg/front_end/test/src/base/processed_options_test.dart
index a0282ba..512751f 100644
--- a/pkg/front_end/test/src/base/processed_options_test.dart
+++ b/pkg/front_end/test/src/base/processed_options_test.dart
@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:convert' show jsonEncode;
+
import 'package:front_end/src/api_prototype/compiler_options.dart';
import 'package:front_end/src/api_prototype/memory_file_system.dart';
import 'package:front_end/src/base/processed_options.dart';
@@ -20,6 +22,39 @@
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+final String emptyPackageConfig = jsonEncode({
+ "configVersion": 2,
+ "packages": [],
+});
+
+final String fooBarPackageConfig = jsonEncode({
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": "bar",
+ },
+ ],
+});
+final String fooBazPackageConfig = jsonEncode({
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": "baz",
+ },
+ ],
+});
+final String fooBazDotDotPackageConfig = jsonEncode({
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": "../baz",
+ },
+ ],
+});
+
void main() {
CompilerContext.runWithDefaultOptions((_) {
defineReflectiveSuite(() {
@@ -117,13 +152,15 @@
Future<void> test_getUriTranslator_explicitLibrariesSpec() async {
fileSystem
- .entityForUri(Uri.parse('org-dartlang-test:///.packages'))
- .writeAsStringSync('');
+ .entityForUri(
+ Uri.parse('org-dartlang-test:///.dart_tool/package_config.json'))
+ .writeAsStringSync(emptyPackageConfig);
fileSystem
.entityForUri(Uri.parse('org-dartlang-test:///libraries.json'))
.writeAsStringSync('{"none":{"libraries":{"foo":{"uri":"bar.dart"}}}}');
var raw = new CompilerOptions()
- ..packagesFileUri = Uri.parse('org-dartlang-test:///.packages')
+ ..packagesFileUri =
+ Uri.parse('org-dartlang-test:///.dart_tool/package_config.json')
..fileSystem = fileSystem
..librariesSpecificationUri =
Uri.parse('org-dartlang-test:///libraries.json');
@@ -135,15 +172,17 @@
Future<void> test_getUriTranslator_inferredLibrariesSpec() async {
fileSystem
- .entityForUri(Uri.parse('org-dartlang-test:///.packages'))
- .writeAsStringSync('');
+ .entityForUri(
+ Uri.parse('org-dartlang-test:///.dart_tool/package_config.json'))
+ .writeAsStringSync(emptyPackageConfig);
fileSystem
.entityForUri(
Uri.parse('org-dartlang-test:///mysdk/lib/libraries.json'))
.writeAsStringSync('{"none":{"libraries":{"foo":{"uri":"bar.dart"}}}}');
var raw = new CompilerOptions()
..fileSystem = fileSystem
- ..packagesFileUri = Uri.parse('org-dartlang-test:///.packages')
+ ..packagesFileUri =
+ Uri.parse('org-dartlang-test:///.dart_tool/package_config.json')
..compileSdk = true
..sdkRoot = Uri.parse('org-dartlang-test:///mysdk/');
var processed = new ProcessedOptions(options: raw);
@@ -154,15 +193,17 @@
Future<void> test_getUriTranslator_notInferredLibrariesSpec() async {
fileSystem
- .entityForUri(Uri.parse('org-dartlang-test:///.packages'))
- .writeAsStringSync('');
+ .entityForUri(
+ Uri.parse('org-dartlang-test:///.dart_tool/package_config.json'))
+ .writeAsStringSync(emptyPackageConfig);
fileSystem
.entityForUri(
Uri.parse('org-dartlang-test:///mysdk/lib/libraries.json'))
.writeAsStringSync('{"none":{"libraries":{"foo":{"uri":"bar.dart"}}}}');
var raw = new CompilerOptions()
..fileSystem = fileSystem
- ..packagesFileUri = Uri.parse('org-dartlang-test:///.packages')
+ ..packagesFileUri =
+ Uri.parse('org-dartlang-test:///.dart_tool/package_config.json')
..compileSdk = false // libraries.json is only inferred if true
..sdkRoot = Uri.parse('org-dartlang-test:///mysdk/');
var processed = new ProcessedOptions(options: raw);
@@ -178,17 +219,18 @@
}
Future<void> test_getUriTranslator_explicitPackagesFile() async {
- // This .packages file should be ignored.
+ // This .dart_tool/package_config.json file should be ignored.
fileSystem
- .entityForUri(Uri.parse('org-dartlang-test:///.packages'))
- .writeAsStringSync('foo:bar\n');
+ .entityForUri(
+ Uri.parse('org-dartlang-test:///.dart_tool/package_config.json'))
+ .writeAsStringSync(fooBarPackageConfig);
// This one should be used.
fileSystem
- .entityForUri(Uri.parse('org-dartlang-test:///explicit.packages'))
- .writeAsStringSync('foo:baz\n');
+ .entityForUri(Uri.parse('org-dartlang-test:///explicit.json'))
+ .writeAsStringSync(fooBazPackageConfig);
var raw = new CompilerOptions()
..fileSystem = fileSystem
- ..packagesFileUri = Uri.parse('org-dartlang-test:///explicit.packages');
+ ..packagesFileUri = Uri.parse('org-dartlang-test:///explicit.json');
var processed = new ProcessedOptions(options: raw);
var uriTranslator = await processed.getUriTranslator();
checkPackageExpansion('foo', 'baz', uriTranslator.packages);
@@ -196,36 +238,38 @@
Future<void>
test_getUriTranslator_explicitPackagesFile_withBaseLocation() async {
- // This .packages file should be ignored.
+ // This .dart_tool/package_config.json file should be ignored.
fileSystem
- .entityForUri(Uri.parse('org-dartlang-test:///.packages'))
- .writeAsStringSync('foo:bar\n');
+ .entityForUri(
+ Uri.parse('org-dartlang-test:///.dart_tool/package_config.json'))
+ .writeAsStringSync(fooBarPackageConfig);
// This one should be used.
fileSystem
.entityForUri(
- Uri.parse('org-dartlang-test:///base/location/explicit.packages'))
- .writeAsStringSync('foo:baz\n');
+ Uri.parse('org-dartlang-test:///base/location/explicit.json'))
+ .writeAsStringSync(fooBazPackageConfig);
var raw = new CompilerOptions()
..fileSystem = fileSystem
..packagesFileUri =
- Uri.parse('org-dartlang-test:///base/location/explicit.packages');
+ Uri.parse('org-dartlang-test:///base/location/explicit.json');
var processed = new ProcessedOptions(options: raw);
var uriTranslator = await processed.getUriTranslator();
checkPackageExpansion('foo', 'base/location/baz', uriTranslator.packages);
}
Future<void> test_getUriTranslator_implicitPackagesFile_ambiguous() async {
- // This .packages file should be ignored.
+ // This .dart_tool/package_config.json file should be ignored.
fileSystem
- .entityForUri(Uri.parse('org-dartlang-test:///.packages'))
- .writeAsStringSync('foo:bar\n');
+ .entityForUri(
+ Uri.parse('org-dartlang-test:///.dart_tool/package_config.json'))
+ .writeAsStringSync(fooBarPackageConfig);
// This one should be used.
fileSystem
- .entityForUri(Uri.parse('org-dartlang-test:///explicit.packages'))
- .writeAsStringSync('foo:baz\n');
+ .entityForUri(Uri.parse('org-dartlang-test:///explicit.json'))
+ .writeAsStringSync(fooBazPackageConfig);
var raw = new CompilerOptions()
..fileSystem = fileSystem
- ..packagesFileUri = Uri.parse('org-dartlang-test:///explicit.packages');
+ ..packagesFileUri = Uri.parse('org-dartlang-test:///explicit.json');
var processed = new ProcessedOptions(options: raw);
var uriTranslator = await processed.getUriTranslator();
checkPackageExpansion('foo', 'baz', uriTranslator.packages);
@@ -236,18 +280,29 @@
fileSystem
.entityForUri(Uri.parse('org-dartlang-test:///base/location/'))
.createDirectory();
- // Packages directory should be ignored (.packages file takes precedence).
+ // Packages directory should be ignored (.dart_tool/package_config.json is
+ // the only one that will be automatically found).
fileSystem
.entityForUri(Uri.parse('org-dartlang-test:///base/location/packages/'))
.createDirectory();
// This .packages file should be ignored.
fileSystem
.entityForUri(Uri.parse('org-dartlang-test:///.packages'))
- .writeAsStringSync('foo:bar\n');
- // This one should be used.
+ .writeAsStringSync("foo:packages1");
+ // This .packages file should be ignored.
fileSystem
.entityForUri(Uri.parse('org-dartlang-test:///base/location/.packages'))
- .writeAsStringSync('foo:baz\n');
+ .writeAsStringSync("foo:packages2");
+ // This .dart_tool/package_config.json file should be ignored.
+ fileSystem
+ .entityForUri(
+ Uri.parse('org-dartlang-test:///.dart_tool/package_config.json'))
+ .writeAsStringSync(fooBarPackageConfig);
+ // This one should be used.
+ fileSystem
+ .entityForUri(Uri.parse(
+ 'org-dartlang-test:///base/location/.dart_tool/package_config.json'))
+ .writeAsStringSync(fooBazDotDotPackageConfig);
var raw = new CompilerOptions()..fileSystem = fileSystem;
var processed = new ProcessedOptions(
options: raw,
@@ -261,14 +316,16 @@
fileSystem
.entityForUri(Uri.parse('org-dartlang-test:///base/location/'))
.createDirectory();
- // This .packages file should be ignored.
+ // This .dart_tool/package_config.json file should be ignored.
fileSystem
- .entityForUri(Uri.parse('org-dartlang-test:///.packages'))
- .writeAsStringSync('foo:bar\n');
+ .entityForUri(
+ Uri.parse('org-dartlang-test:///.dart_tool/package_config.json'))
+ .writeAsStringSync(fooBarPackageConfig);
// This one should be used.
fileSystem
- .entityForUri(Uri.parse('org-dartlang-test:///base/.packages'))
- .writeAsStringSync('foo:baz\n');
+ .entityForUri(Uri.parse(
+ 'org-dartlang-test:///base/.dart_tool/package_config.json'))
+ .writeAsStringSync(fooBazDotDotPackageConfig);
var raw = new CompilerOptions()..fileSystem = fileSystem;
var processed = new ProcessedOptions(
options: raw,
@@ -289,12 +346,23 @@
.entityForUri(Uri.parse('org-dartlang-test:///base/location/packages/'))
.createDirectory();
+ // .packages is deprecated and should be ignored.
fileSystem
.entityForUri(Uri.parse('org-dartlang-test:///.packages'))
- .writeAsStringSync('foo:bar\n');
+ .writeAsStringSync('foo:packages1\n');
fileSystem
.entityForUri(Uri.parse('org-dartlang-test:///base/.packages'))
- .writeAsStringSync('foo:baz\n');
+ .writeAsStringSync('foo:packages2\n');
+
+ // .dart_tool/package_config.json
+ fileSystem
+ .entityForUri(
+ Uri.parse('org-dartlang-test:///.dart_tool/package_config.json'))
+ .writeAsStringSync(fooBarPackageConfig);
+ fileSystem
+ .entityForUri(Uri.parse(
+ 'org-dartlang-test:///base/.dart_tool/package_config.json'))
+ .writeAsStringSync(fooBazDotDotPackageConfig);
var raw = new CompilerOptions()..fileSystem = fileSystem;
var processed = new ProcessedOptions(
options: raw,
@@ -309,7 +377,7 @@
.entityForUri(Uri.parse('org-dartlang-test:///base/location/'))
.createDirectory();
var errors = [];
- // .packages file should be ignored.
+ // There is no .dart_tool/package_config.json file.
var raw = new CompilerOptions()
..fileSystem = fileSystem
..onDiagnostic = errors.add;
@@ -323,10 +391,12 @@
Future<void> test_getUriTranslator_noPackages() async {
var errors = <DiagnosticMessage>[];
- // .packages file should be ignored.
+ // .dart_tool/package_config.json file should be ignored when specifying
+ // empty Uri.
fileSystem
- .entityForUri(Uri.parse('org-dartlang-test:///.packages'))
- .writeAsStringSync('foo:bar\n');
+ .entityForUri(
+ Uri.parse('org-dartlang-test:///.dart_tool/package_config.json'))
+ .writeAsStringSync(fooBarPackageConfig);
var raw = new CompilerOptions()
..fileSystem = fileSystem
..packagesFileUri = new Uri()
diff --git a/pkg/front_end/testcases/enhanced_enums/issue49236.dart b/pkg/front_end/testcases/enhanced_enums/issue49236.dart
new file mode 100644
index 0000000..076a34d
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/issue49236.dart
@@ -0,0 +1,67 @@
+// 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.
+
+mixin M {
+ String toString() => "M";
+}
+
+abstract class A {
+ String toString() => "A";
+}
+
+abstract class B implements Enum {
+ String toString() => "B";
+}
+
+enum E1 with M {
+ element
+}
+
+enum E2 with M {
+ element;
+
+ String toString() => "E2";
+}
+
+enum E3 {
+ element;
+
+ String toString() => "E3";
+}
+
+enum E4 implements B {
+ element
+}
+
+enum E5 implements B {
+ element;
+
+ String toString() => "E5";
+}
+
+enum E6 with A {
+ element
+}
+
+enum E7 with A {
+ element;
+
+ String toString() => "E7";
+}
+
+checkEqual(x, y) {
+ if (x != y) {
+ throw "Expected '${x}' and '${y}' to be equal.";
+ }
+}
+
+main() {
+ checkEqual("${E1.element}", "M");
+ checkEqual("${E2.element}", "E2");
+ checkEqual("${E3.element}", "E3");
+ checkEqual("${E4.element}", "E4.element");
+ checkEqual("${E5.element}", "E5");
+ checkEqual("${E6.element}", "A");
+ checkEqual("${E7.element}", "E7");
+}
diff --git a/pkg/front_end/testcases/enhanced_enums/issue49236.dart.strong.expect b/pkg/front_end/testcases/enhanced_enums/issue49236.dart.strong.expect
new file mode 100644
index 0000000..bf8ee4f
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/issue49236.dart.strong.expect
@@ -0,0 +1,163 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class M extends core::Object /*isMixinDeclaration*/ {
+ method toString() → core::String
+ return "M";
+}
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method toString() → core::String
+ return "A";
+}
+abstract class B extends core::Object implements core::Enum {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ method toString() → core::String
+ return "B";
+}
+abstract class _E1&_Enum&M = core::_Enum with self::M /*isAnonymousMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E1&_Enum&M
+ : super core::_Enum::•(index, _name)
+ ;
+ mixin-super-stub method toString() → core::String
+ return super.{self::M::toString}();
+}
+class E1 extends self::_E1&_Enum&M /*isEnum*/ {
+ static const field core::List<self::E1> values = #C4;
+ static const field self::E1 element = #C3;
+ const constructor •(core::int #index, core::String #name) → self::E1
+ : super self::_E1&_Enum&M::•(#index, #name)
+ ;
+ method toString() → core::String
+ return super.{self::_E1&_Enum&M::toString}();
+}
+abstract class _E2&_Enum&M = core::_Enum with self::M /*isAnonymousMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E2&_Enum&M
+ : super core::_Enum::•(index, _name)
+ ;
+ mixin-super-stub method toString() → core::String
+ return super.{self::M::toString}();
+}
+class E2 extends self::_E2&_Enum&M /*isEnum*/ {
+ static const field core::List<self::E2> values = #C6;
+ static const field self::E2 element = #C5;
+ const constructor •(core::int #index, core::String #name) → self::E2
+ : super self::_E2&_Enum&M::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E2";
+}
+class E3 extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E3> values = #C8;
+ static const field self::E3 element = #C7;
+ const constructor •(core::int #index, core::String #name) → self::E3
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E3";
+}
+class E4 extends core::_Enum implements self::B /*isEnum*/ {
+ static const field core::List<self::E4> values = #C10;
+ static const field self::E4 element = #C9;
+ const constructor •(core::int #index, core::String #name) → self::E4
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E4.${this.{core::_Enum::_name}{core::String}}";
+}
+class E5 extends core::_Enum implements self::B /*isEnum*/ {
+ static const field core::List<self::E5> values = #C12;
+ static const field self::E5 element = #C11;
+ const constructor •(core::int #index, core::String #name) → self::E5
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E5";
+}
+abstract class _E6&_Enum&A = core::_Enum with self::A /*isAnonymousMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E6&_Enum&A
+ : super core::_Enum::•(index, _name)
+ ;
+ mixin-super-stub method toString() → core::String
+ return super.{self::A::toString}();
+}
+class E6 extends self::_E6&_Enum&A /*isEnum*/ {
+ static const field core::List<self::E6> values = #C14;
+ static const field self::E6 element = #C13;
+ const constructor •(core::int #index, core::String #name) → self::E6
+ : super self::_E6&_Enum&A::•(#index, #name)
+ ;
+ method toString() → core::String
+ return super.{self::_E6&_Enum&A::toString}();
+}
+abstract class _E7&_Enum&A = core::_Enum with self::A /*isAnonymousMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E7&_Enum&A
+ : super core::_Enum::•(index, _name)
+ ;
+ mixin-super-stub method toString() → core::String
+ return super.{self::A::toString}();
+}
+class E7 extends self::_E7&_Enum&A /*isEnum*/ {
+ static const field core::List<self::E7> values = #C16;
+ static const field self::E7 element = #C15;
+ const constructor •(core::int #index, core::String #name) → self::E7
+ : super self::_E7&_Enum&A::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E7";
+}
+static method checkEqual(dynamic x, dynamic y) → dynamic {
+ if(!(x =={core::Object::==}{(core::Object) → core::bool} y)) {
+ throw "Expected '${x}' and '${y}' to be equal.";
+ }
+}
+static method main() → dynamic {
+ self::checkEqual("${#C3}", "M");
+ self::checkEqual("${#C5}", "E2");
+ self::checkEqual("${#C7}", "E3");
+ self::checkEqual("${#C9}", "E4.element");
+ self::checkEqual("${#C11}", "E5");
+ self::checkEqual("${#C13}", "A");
+ self::checkEqual("${#C15}", "E7");
+}
+
+constants {
+ #C1 = 0
+ #C2 = "element"
+ #C3 = self::E1 {index:#C1, _name:#C2}
+ #C4 = <self::E1>[#C3]
+ #C5 = self::E2 {index:#C1, _name:#C2}
+ #C6 = <self::E2>[#C5]
+ #C7 = self::E3 {index:#C1, _name:#C2}
+ #C8 = <self::E3>[#C7]
+ #C9 = self::E4 {index:#C1, _name:#C2}
+ #C10 = <self::E4>[#C9]
+ #C11 = self::E5 {index:#C1, _name:#C2}
+ #C12 = <self::E5>[#C11]
+ #C13 = self::E6 {index:#C1, _name:#C2}
+ #C14 = <self::E6>[#C13]
+ #C15 = self::E7 {index:#C1, _name:#C2}
+ #C16 = <self::E7>[#C15]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue49236.dart:
+- E1. (from org-dartlang-testcase:///issue49236.dart:17:6)
+- _E1&_Enum&M. (from org-dartlang-testcase:///issue49236.dart:17:6)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+- E2. (from org-dartlang-testcase:///issue49236.dart:21:6)
+- _E2&_Enum&M. (from org-dartlang-testcase:///issue49236.dart:21:6)
+- E3. (from org-dartlang-testcase:///issue49236.dart:27:6)
+- E4. (from org-dartlang-testcase:///issue49236.dart:33:6)
+- E5. (from org-dartlang-testcase:///issue49236.dart:37:6)
+- E6. (from org-dartlang-testcase:///issue49236.dart:43:6)
+- _E6&_Enum&A. (from org-dartlang-testcase:///issue49236.dart:43:6)
+- E7. (from org-dartlang-testcase:///issue49236.dart:47:6)
+- _E7&_Enum&A. (from org-dartlang-testcase:///issue49236.dart:47:6)
diff --git a/pkg/front_end/testcases/enhanced_enums/issue49236.dart.strong.transformed.expect b/pkg/front_end/testcases/enhanced_enums/issue49236.dart.strong.transformed.expect
new file mode 100644
index 0000000..b1cce1b
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/issue49236.dart.strong.transformed.expect
@@ -0,0 +1,163 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class M extends core::Object /*isMixinDeclaration*/ {
+ method toString() → core::String
+ return "M";
+}
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method toString() → core::String
+ return "A";
+}
+abstract class B extends core::Object implements core::Enum {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ method toString() → core::String
+ return "B";
+}
+abstract class _E1&_Enum&M extends core::_Enum implements self::M /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E1&_Enum&M
+ : super core::_Enum::•(index, _name)
+ ;
+ method toString() → core::String
+ return "M";
+}
+class E1 extends self::_E1&_Enum&M /*isEnum*/ {
+ static const field core::List<self::E1> values = #C4;
+ static const field self::E1 element = #C3;
+ const constructor •(core::int #index, core::String #name) → self::E1
+ : super self::_E1&_Enum&M::•(#index, #name)
+ ;
+ method toString() → core::String
+ return super.{self::_E1&_Enum&M::toString}();
+}
+abstract class _E2&_Enum&M extends core::_Enum implements self::M /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E2&_Enum&M
+ : super core::_Enum::•(index, _name)
+ ;
+ method toString() → core::String
+ return "M";
+}
+class E2 extends self::_E2&_Enum&M /*isEnum*/ {
+ static const field core::List<self::E2> values = #C6;
+ static const field self::E2 element = #C5;
+ const constructor •(core::int #index, core::String #name) → self::E2
+ : super self::_E2&_Enum&M::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E2";
+}
+class E3 extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E3> values = #C8;
+ static const field self::E3 element = #C7;
+ const constructor •(core::int #index, core::String #name) → self::E3
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E3";
+}
+class E4 extends core::_Enum implements self::B /*isEnum*/ {
+ static const field core::List<self::E4> values = #C10;
+ static const field self::E4 element = #C9;
+ const constructor •(core::int #index, core::String #name) → self::E4
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E4.${this.{core::_Enum::_name}{core::String}}";
+}
+class E5 extends core::_Enum implements self::B /*isEnum*/ {
+ static const field core::List<self::E5> values = #C12;
+ static const field self::E5 element = #C11;
+ const constructor •(core::int #index, core::String #name) → self::E5
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E5";
+}
+abstract class _E6&_Enum&A extends core::_Enum implements self::A /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E6&_Enum&A
+ : super core::_Enum::•(index, _name)
+ ;
+ method toString() → core::String
+ return "A";
+}
+class E6 extends self::_E6&_Enum&A /*isEnum*/ {
+ static const field core::List<self::E6> values = #C14;
+ static const field self::E6 element = #C13;
+ const constructor •(core::int #index, core::String #name) → self::E6
+ : super self::_E6&_Enum&A::•(#index, #name)
+ ;
+ method toString() → core::String
+ return super.{self::_E6&_Enum&A::toString}();
+}
+abstract class _E7&_Enum&A extends core::_Enum implements self::A /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E7&_Enum&A
+ : super core::_Enum::•(index, _name)
+ ;
+ method toString() → core::String
+ return "A";
+}
+class E7 extends self::_E7&_Enum&A /*isEnum*/ {
+ static const field core::List<self::E7> values = #C16;
+ static const field self::E7 element = #C15;
+ const constructor •(core::int #index, core::String #name) → self::E7
+ : super self::_E7&_Enum&A::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E7";
+}
+static method checkEqual(dynamic x, dynamic y) → dynamic {
+ if(!(x =={core::Object::==}{(core::Object) → core::bool} y)) {
+ throw "Expected '${x}' and '${y}' to be equal.";
+ }
+}
+static method main() → dynamic {
+ self::checkEqual("${#C3}", "M");
+ self::checkEqual("${#C5}", "E2");
+ self::checkEqual("${#C7}", "E3");
+ self::checkEqual("${#C9}", "E4.element");
+ self::checkEqual("${#C11}", "E5");
+ self::checkEqual("${#C13}", "A");
+ self::checkEqual("${#C15}", "E7");
+}
+
+constants {
+ #C1 = 0
+ #C2 = "element"
+ #C3 = self::E1 {index:#C1, _name:#C2}
+ #C4 = <self::E1>[#C3]
+ #C5 = self::E2 {index:#C1, _name:#C2}
+ #C6 = <self::E2>[#C5]
+ #C7 = self::E3 {index:#C1, _name:#C2}
+ #C8 = <self::E3>[#C7]
+ #C9 = self::E4 {index:#C1, _name:#C2}
+ #C10 = <self::E4>[#C9]
+ #C11 = self::E5 {index:#C1, _name:#C2}
+ #C12 = <self::E5>[#C11]
+ #C13 = self::E6 {index:#C1, _name:#C2}
+ #C14 = <self::E6>[#C13]
+ #C15 = self::E7 {index:#C1, _name:#C2}
+ #C16 = <self::E7>[#C15]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue49236.dart:
+- E1. (from org-dartlang-testcase:///issue49236.dart:17:6)
+- _E1&_Enum&M. (from org-dartlang-testcase:///issue49236.dart:17:6)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+- E2. (from org-dartlang-testcase:///issue49236.dart:21:6)
+- _E2&_Enum&M. (from org-dartlang-testcase:///issue49236.dart:21:6)
+- E3. (from org-dartlang-testcase:///issue49236.dart:27:6)
+- E4. (from org-dartlang-testcase:///issue49236.dart:33:6)
+- E5. (from org-dartlang-testcase:///issue49236.dart:37:6)
+- E6. (from org-dartlang-testcase:///issue49236.dart:43:6)
+- _E6&_Enum&A. (from org-dartlang-testcase:///issue49236.dart:43:6)
+- E7. (from org-dartlang-testcase:///issue49236.dart:47:6)
+- _E7&_Enum&A. (from org-dartlang-testcase:///issue49236.dart:47:6)
diff --git a/pkg/front_end/testcases/enhanced_enums/issue49236.dart.textual_outline.expect b/pkg/front_end/testcases/enhanced_enums/issue49236.dart.textual_outline.expect
new file mode 100644
index 0000000..55f4471
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/issue49236.dart.textual_outline.expect
@@ -0,0 +1,44 @@
+mixin M {
+ String toString() => "M";
+}
+
+abstract class A {
+ String toString() => "A";
+}
+
+abstract class B implements Enum {
+ String toString() => "B";
+}
+
+enum E1 with M { element }
+
+enum E2 with M {
+ element;
+
+ String toString() => "E2";
+}
+
+enum E3 {
+ element;
+
+ String toString() => "E3";
+}
+
+enum E4 implements B { element }
+
+enum E5 implements B {
+ element;
+
+ String toString() => "E5";
+}
+
+enum E6 with A { element }
+
+enum E7 with A {
+ element;
+
+ String toString() => "E7";
+}
+
+checkEqual(x, y) {}
+main() {}
diff --git a/pkg/front_end/testcases/enhanced_enums/issue49236.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/enhanced_enums/issue49236.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..76eb999
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/issue49236.dart.textual_outline_modelled.expect
@@ -0,0 +1,44 @@
+abstract class A {
+ String toString() => "A";
+}
+
+abstract class B implements Enum {
+ String toString() => "B";
+}
+
+checkEqual(x, y) {}
+
+enum E1 with M { element }
+
+enum E2 with M {
+ element;
+
+ String toString() => "E2";
+}
+
+enum E3 {
+ element;
+
+ String toString() => "E3";
+}
+
+enum E4 implements B { element }
+
+enum E5 implements B {
+ element;
+
+ String toString() => "E5";
+}
+
+enum E6 with A { element }
+
+enum E7 with A {
+ element;
+
+ String toString() => "E7";
+}
+
+main() {}
+mixin M {
+ String toString() => "M";
+}
diff --git a/pkg/front_end/testcases/enhanced_enums/issue49236.dart.weak.expect b/pkg/front_end/testcases/enhanced_enums/issue49236.dart.weak.expect
new file mode 100644
index 0000000..e3996a0
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/issue49236.dart.weak.expect
@@ -0,0 +1,163 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class M extends core::Object /*isMixinDeclaration*/ {
+ method toString() → core::String
+ return "M";
+}
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method toString() → core::String
+ return "A";
+}
+abstract class B extends core::Object implements core::Enum {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ method toString() → core::String
+ return "B";
+}
+abstract class _E1&_Enum&M = core::_Enum with self::M /*isAnonymousMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E1&_Enum&M
+ : super core::_Enum::•(index, _name)
+ ;
+ mixin-super-stub method toString() → core::String
+ return super.{self::M::toString}();
+}
+class E1 extends self::_E1&_Enum&M /*isEnum*/ {
+ static const field core::List<self::E1> values = #C4;
+ static const field self::E1 element = #C3;
+ const constructor •(core::int #index, core::String #name) → self::E1
+ : super self::_E1&_Enum&M::•(#index, #name)
+ ;
+ method toString() → core::String
+ return super.{self::_E1&_Enum&M::toString}();
+}
+abstract class _E2&_Enum&M = core::_Enum with self::M /*isAnonymousMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E2&_Enum&M
+ : super core::_Enum::•(index, _name)
+ ;
+ mixin-super-stub method toString() → core::String
+ return super.{self::M::toString}();
+}
+class E2 extends self::_E2&_Enum&M /*isEnum*/ {
+ static const field core::List<self::E2> values = #C6;
+ static const field self::E2 element = #C5;
+ const constructor •(core::int #index, core::String #name) → self::E2
+ : super self::_E2&_Enum&M::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E2";
+}
+class E3 extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E3> values = #C8;
+ static const field self::E3 element = #C7;
+ const constructor •(core::int #index, core::String #name) → self::E3
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E3";
+}
+class E4 extends core::_Enum implements self::B /*isEnum*/ {
+ static const field core::List<self::E4> values = #C10;
+ static const field self::E4 element = #C9;
+ const constructor •(core::int #index, core::String #name) → self::E4
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E4.${this.{core::_Enum::_name}{core::String}}";
+}
+class E5 extends core::_Enum implements self::B /*isEnum*/ {
+ static const field core::List<self::E5> values = #C12;
+ static const field self::E5 element = #C11;
+ const constructor •(core::int #index, core::String #name) → self::E5
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E5";
+}
+abstract class _E6&_Enum&A = core::_Enum with self::A /*isAnonymousMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E6&_Enum&A
+ : super core::_Enum::•(index, _name)
+ ;
+ mixin-super-stub method toString() → core::String
+ return super.{self::A::toString}();
+}
+class E6 extends self::_E6&_Enum&A /*isEnum*/ {
+ static const field core::List<self::E6> values = #C14;
+ static const field self::E6 element = #C13;
+ const constructor •(core::int #index, core::String #name) → self::E6
+ : super self::_E6&_Enum&A::•(#index, #name)
+ ;
+ method toString() → core::String
+ return super.{self::_E6&_Enum&A::toString}();
+}
+abstract class _E7&_Enum&A = core::_Enum with self::A /*isAnonymousMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E7&_Enum&A
+ : super core::_Enum::•(index, _name)
+ ;
+ mixin-super-stub method toString() → core::String
+ return super.{self::A::toString}();
+}
+class E7 extends self::_E7&_Enum&A /*isEnum*/ {
+ static const field core::List<self::E7> values = #C16;
+ static const field self::E7 element = #C15;
+ const constructor •(core::int #index, core::String #name) → self::E7
+ : super self::_E7&_Enum&A::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E7";
+}
+static method checkEqual(dynamic x, dynamic y) → dynamic {
+ if(!(x =={core::Object::==}{(core::Object) → core::bool} y)) {
+ throw "Expected '${x}' and '${y}' to be equal.";
+ }
+}
+static method main() → dynamic {
+ self::checkEqual("${#C3}", "M");
+ self::checkEqual("${#C5}", "E2");
+ self::checkEqual("${#C7}", "E3");
+ self::checkEqual("${#C9}", "E4.element");
+ self::checkEqual("${#C11}", "E5");
+ self::checkEqual("${#C13}", "A");
+ self::checkEqual("${#C15}", "E7");
+}
+
+constants {
+ #C1 = 0
+ #C2 = "element"
+ #C3 = self::E1 {index:#C1, _name:#C2}
+ #C4 = <self::E1*>[#C3]
+ #C5 = self::E2 {index:#C1, _name:#C2}
+ #C6 = <self::E2*>[#C5]
+ #C7 = self::E3 {index:#C1, _name:#C2}
+ #C8 = <self::E3*>[#C7]
+ #C9 = self::E4 {index:#C1, _name:#C2}
+ #C10 = <self::E4*>[#C9]
+ #C11 = self::E5 {index:#C1, _name:#C2}
+ #C12 = <self::E5*>[#C11]
+ #C13 = self::E6 {index:#C1, _name:#C2}
+ #C14 = <self::E6*>[#C13]
+ #C15 = self::E7 {index:#C1, _name:#C2}
+ #C16 = <self::E7*>[#C15]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue49236.dart:
+- E1. (from org-dartlang-testcase:///issue49236.dart:17:6)
+- _E1&_Enum&M. (from org-dartlang-testcase:///issue49236.dart:17:6)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+- E2. (from org-dartlang-testcase:///issue49236.dart:21:6)
+- _E2&_Enum&M. (from org-dartlang-testcase:///issue49236.dart:21:6)
+- E3. (from org-dartlang-testcase:///issue49236.dart:27:6)
+- E4. (from org-dartlang-testcase:///issue49236.dart:33:6)
+- E5. (from org-dartlang-testcase:///issue49236.dart:37:6)
+- E6. (from org-dartlang-testcase:///issue49236.dart:43:6)
+- _E6&_Enum&A. (from org-dartlang-testcase:///issue49236.dart:43:6)
+- E7. (from org-dartlang-testcase:///issue49236.dart:47:6)
+- _E7&_Enum&A. (from org-dartlang-testcase:///issue49236.dart:47:6)
diff --git a/pkg/front_end/testcases/enhanced_enums/issue49236.dart.weak.modular.expect b/pkg/front_end/testcases/enhanced_enums/issue49236.dart.weak.modular.expect
new file mode 100644
index 0000000..e3996a0
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/issue49236.dart.weak.modular.expect
@@ -0,0 +1,163 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class M extends core::Object /*isMixinDeclaration*/ {
+ method toString() → core::String
+ return "M";
+}
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method toString() → core::String
+ return "A";
+}
+abstract class B extends core::Object implements core::Enum {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ method toString() → core::String
+ return "B";
+}
+abstract class _E1&_Enum&M = core::_Enum with self::M /*isAnonymousMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E1&_Enum&M
+ : super core::_Enum::•(index, _name)
+ ;
+ mixin-super-stub method toString() → core::String
+ return super.{self::M::toString}();
+}
+class E1 extends self::_E1&_Enum&M /*isEnum*/ {
+ static const field core::List<self::E1> values = #C4;
+ static const field self::E1 element = #C3;
+ const constructor •(core::int #index, core::String #name) → self::E1
+ : super self::_E1&_Enum&M::•(#index, #name)
+ ;
+ method toString() → core::String
+ return super.{self::_E1&_Enum&M::toString}();
+}
+abstract class _E2&_Enum&M = core::_Enum with self::M /*isAnonymousMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E2&_Enum&M
+ : super core::_Enum::•(index, _name)
+ ;
+ mixin-super-stub method toString() → core::String
+ return super.{self::M::toString}();
+}
+class E2 extends self::_E2&_Enum&M /*isEnum*/ {
+ static const field core::List<self::E2> values = #C6;
+ static const field self::E2 element = #C5;
+ const constructor •(core::int #index, core::String #name) → self::E2
+ : super self::_E2&_Enum&M::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E2";
+}
+class E3 extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E3> values = #C8;
+ static const field self::E3 element = #C7;
+ const constructor •(core::int #index, core::String #name) → self::E3
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E3";
+}
+class E4 extends core::_Enum implements self::B /*isEnum*/ {
+ static const field core::List<self::E4> values = #C10;
+ static const field self::E4 element = #C9;
+ const constructor •(core::int #index, core::String #name) → self::E4
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E4.${this.{core::_Enum::_name}{core::String}}";
+}
+class E5 extends core::_Enum implements self::B /*isEnum*/ {
+ static const field core::List<self::E5> values = #C12;
+ static const field self::E5 element = #C11;
+ const constructor •(core::int #index, core::String #name) → self::E5
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E5";
+}
+abstract class _E6&_Enum&A = core::_Enum with self::A /*isAnonymousMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E6&_Enum&A
+ : super core::_Enum::•(index, _name)
+ ;
+ mixin-super-stub method toString() → core::String
+ return super.{self::A::toString}();
+}
+class E6 extends self::_E6&_Enum&A /*isEnum*/ {
+ static const field core::List<self::E6> values = #C14;
+ static const field self::E6 element = #C13;
+ const constructor •(core::int #index, core::String #name) → self::E6
+ : super self::_E6&_Enum&A::•(#index, #name)
+ ;
+ method toString() → core::String
+ return super.{self::_E6&_Enum&A::toString}();
+}
+abstract class _E7&_Enum&A = core::_Enum with self::A /*isAnonymousMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E7&_Enum&A
+ : super core::_Enum::•(index, _name)
+ ;
+ mixin-super-stub method toString() → core::String
+ return super.{self::A::toString}();
+}
+class E7 extends self::_E7&_Enum&A /*isEnum*/ {
+ static const field core::List<self::E7> values = #C16;
+ static const field self::E7 element = #C15;
+ const constructor •(core::int #index, core::String #name) → self::E7
+ : super self::_E7&_Enum&A::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E7";
+}
+static method checkEqual(dynamic x, dynamic y) → dynamic {
+ if(!(x =={core::Object::==}{(core::Object) → core::bool} y)) {
+ throw "Expected '${x}' and '${y}' to be equal.";
+ }
+}
+static method main() → dynamic {
+ self::checkEqual("${#C3}", "M");
+ self::checkEqual("${#C5}", "E2");
+ self::checkEqual("${#C7}", "E3");
+ self::checkEqual("${#C9}", "E4.element");
+ self::checkEqual("${#C11}", "E5");
+ self::checkEqual("${#C13}", "A");
+ self::checkEqual("${#C15}", "E7");
+}
+
+constants {
+ #C1 = 0
+ #C2 = "element"
+ #C3 = self::E1 {index:#C1, _name:#C2}
+ #C4 = <self::E1*>[#C3]
+ #C5 = self::E2 {index:#C1, _name:#C2}
+ #C6 = <self::E2*>[#C5]
+ #C7 = self::E3 {index:#C1, _name:#C2}
+ #C8 = <self::E3*>[#C7]
+ #C9 = self::E4 {index:#C1, _name:#C2}
+ #C10 = <self::E4*>[#C9]
+ #C11 = self::E5 {index:#C1, _name:#C2}
+ #C12 = <self::E5*>[#C11]
+ #C13 = self::E6 {index:#C1, _name:#C2}
+ #C14 = <self::E6*>[#C13]
+ #C15 = self::E7 {index:#C1, _name:#C2}
+ #C16 = <self::E7*>[#C15]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue49236.dart:
+- E1. (from org-dartlang-testcase:///issue49236.dart:17:6)
+- _E1&_Enum&M. (from org-dartlang-testcase:///issue49236.dart:17:6)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+- E2. (from org-dartlang-testcase:///issue49236.dart:21:6)
+- _E2&_Enum&M. (from org-dartlang-testcase:///issue49236.dart:21:6)
+- E3. (from org-dartlang-testcase:///issue49236.dart:27:6)
+- E4. (from org-dartlang-testcase:///issue49236.dart:33:6)
+- E5. (from org-dartlang-testcase:///issue49236.dart:37:6)
+- E6. (from org-dartlang-testcase:///issue49236.dart:43:6)
+- _E6&_Enum&A. (from org-dartlang-testcase:///issue49236.dart:43:6)
+- E7. (from org-dartlang-testcase:///issue49236.dart:47:6)
+- _E7&_Enum&A. (from org-dartlang-testcase:///issue49236.dart:47:6)
diff --git a/pkg/front_end/testcases/enhanced_enums/issue49236.dart.weak.outline.expect b/pkg/front_end/testcases/enhanced_enums/issue49236.dart.weak.outline.expect
new file mode 100644
index 0000000..6e652e5
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/issue49236.dart.weak.outline.expect
@@ -0,0 +1,129 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class M extends core::Object /*isMixinDeclaration*/ {
+ method toString() → core::String
+ ;
+}
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ ;
+ method toString() → core::String
+ ;
+}
+abstract class B extends core::Object implements core::Enum {
+ synthetic constructor •() → self::B
+ ;
+ method toString() → core::String
+ ;
+}
+abstract class _E1&_Enum&M = core::_Enum with self::M /*isAnonymousMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E1&_Enum&M
+ : super core::_Enum::•(index, _name)
+ ;
+ mixin-super-stub method toString() → core::String
+ return super.{self::M::toString}();
+}
+class E1 extends self::_E1&_Enum&M /*isEnum*/ {
+ static const field core::List<self::E1> values = const <self::E1>[self::E1::element];
+ static const field self::E1 element = const self::E1::•(0, "element");
+ const constructor •(core::int #index, core::String #name) → self::E1
+ ;
+ method toString() → core::String
+ return super.{self::_E1&_Enum&M::toString}();
+}
+abstract class _E2&_Enum&M = core::_Enum with self::M /*isAnonymousMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E2&_Enum&M
+ : super core::_Enum::•(index, _name)
+ ;
+ mixin-super-stub method toString() → core::String
+ return super.{self::M::toString}();
+}
+class E2 extends self::_E2&_Enum&M /*isEnum*/ {
+ static const field core::List<self::E2> values = const <self::E2>[self::E2::element];
+ static const field self::E2 element = const self::E2::•(0, "element");
+ const constructor •(core::int #index, core::String #name) → self::E2
+ ;
+ method toString() → core::String
+ return super.{self::_E2&_Enum&M::toString}();
+}
+class E3 extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E3> values = const <self::E3>[self::E3::element];
+ static const field self::E3 element = const self::E3::•(0, "element");
+ const constructor •(core::int #index, core::String #name) → self::E3
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E3.${this.{core::_Enum::_name}{core::String}}";
+}
+class E4 extends core::_Enum implements self::B /*isEnum*/ {
+ static const field core::List<self::E4> values = const <self::E4>[self::E4::element];
+ static const field self::E4 element = const self::E4::•(0, "element");
+ const constructor •(core::int #index, core::String #name) → self::E4
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E4.${this.{core::_Enum::_name}{core::String}}";
+}
+class E5 extends core::_Enum implements self::B /*isEnum*/ {
+ static const field core::List<self::E5> values = const <self::E5>[self::E5::element];
+ static const field self::E5 element = const self::E5::•(0, "element");
+ const constructor •(core::int #index, core::String #name) → self::E5
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E5.${this.{core::_Enum::_name}{core::String}}";
+}
+abstract class _E6&_Enum&A = core::_Enum with self::A /*isAnonymousMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E6&_Enum&A
+ : super core::_Enum::•(index, _name)
+ ;
+ mixin-super-stub method toString() → core::String
+ return super.{self::A::toString}();
+}
+class E6 extends self::_E6&_Enum&A /*isEnum*/ {
+ static const field core::List<self::E6> values = const <self::E6>[self::E6::element];
+ static const field self::E6 element = const self::E6::•(0, "element");
+ const constructor •(core::int #index, core::String #name) → self::E6
+ ;
+ method toString() → core::String
+ return super.{self::_E6&_Enum&A::toString}();
+}
+abstract class _E7&_Enum&A = core::_Enum with self::A /*isAnonymousMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E7&_Enum&A
+ : super core::_Enum::•(index, _name)
+ ;
+ mixin-super-stub method toString() → core::String
+ return super.{self::A::toString}();
+}
+class E7 extends self::_E7&_Enum&A /*isEnum*/ {
+ static const field core::List<self::E7> values = const <self::E7>[self::E7::element];
+ static const field self::E7 element = const self::E7::•(0, "element");
+ const constructor •(core::int #index, core::String #name) → self::E7
+ ;
+ method toString() → core::String
+ return super.{self::_E7&_Enum&A::toString}();
+}
+static method checkEqual(dynamic x, dynamic y) → dynamic
+ ;
+static method main() → dynamic
+ ;
+
+
+Extra constant evaluation status:
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue49236.dart:17:6 -> ListConstant(const <E1*>[const E1{}])
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue49236.dart:18:3 -> InstanceConstant(const E1{})
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue49236.dart:21:6 -> ListConstant(const <E2*>[const E2{}])
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue49236.dart:22:3 -> InstanceConstant(const E2{})
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue49236.dart:27:6 -> ListConstant(const <E3*>[const E3{_Enum.index: 0, _Enum._name: "element"}])
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue49236.dart:28:3 -> InstanceConstant(const E3{_Enum.index: 0, _Enum._name: "element"})
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue49236.dart:33:6 -> ListConstant(const <E4*>[const E4{_Enum.index: 0, _Enum._name: "element"}])
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue49236.dart:34:3 -> InstanceConstant(const E4{_Enum.index: 0, _Enum._name: "element"})
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue49236.dart:37:6 -> ListConstant(const <E5*>[const E5{_Enum.index: 0, _Enum._name: "element"}])
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue49236.dart:38:3 -> InstanceConstant(const E5{_Enum.index: 0, _Enum._name: "element"})
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue49236.dart:43:6 -> ListConstant(const <E6*>[const E6{}])
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue49236.dart:44:3 -> InstanceConstant(const E6{})
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue49236.dart:47:6 -> ListConstant(const <E7*>[const E7{}])
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue49236.dart:48:3 -> InstanceConstant(const E7{})
+Extra constant evaluation: evaluated: 45, effectively constant: 14
diff --git a/pkg/front_end/testcases/enhanced_enums/issue49236.dart.weak.transformed.expect b/pkg/front_end/testcases/enhanced_enums/issue49236.dart.weak.transformed.expect
new file mode 100644
index 0000000..c6df72d
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/issue49236.dart.weak.transformed.expect
@@ -0,0 +1,163 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class M extends core::Object /*isMixinDeclaration*/ {
+ method toString() → core::String
+ return "M";
+}
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method toString() → core::String
+ return "A";
+}
+abstract class B extends core::Object implements core::Enum {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ method toString() → core::String
+ return "B";
+}
+abstract class _E1&_Enum&M extends core::_Enum implements self::M /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E1&_Enum&M
+ : super core::_Enum::•(index, _name)
+ ;
+ method toString() → core::String
+ return "M";
+}
+class E1 extends self::_E1&_Enum&M /*isEnum*/ {
+ static const field core::List<self::E1> values = #C4;
+ static const field self::E1 element = #C3;
+ const constructor •(core::int #index, core::String #name) → self::E1
+ : super self::_E1&_Enum&M::•(#index, #name)
+ ;
+ method toString() → core::String
+ return super.{self::_E1&_Enum&M::toString}();
+}
+abstract class _E2&_Enum&M extends core::_Enum implements self::M /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E2&_Enum&M
+ : super core::_Enum::•(index, _name)
+ ;
+ method toString() → core::String
+ return "M";
+}
+class E2 extends self::_E2&_Enum&M /*isEnum*/ {
+ static const field core::List<self::E2> values = #C6;
+ static const field self::E2 element = #C5;
+ const constructor •(core::int #index, core::String #name) → self::E2
+ : super self::_E2&_Enum&M::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E2";
+}
+class E3 extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E3> values = #C8;
+ static const field self::E3 element = #C7;
+ const constructor •(core::int #index, core::String #name) → self::E3
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E3";
+}
+class E4 extends core::_Enum implements self::B /*isEnum*/ {
+ static const field core::List<self::E4> values = #C10;
+ static const field self::E4 element = #C9;
+ const constructor •(core::int #index, core::String #name) → self::E4
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E4.${this.{core::_Enum::_name}{core::String}}";
+}
+class E5 extends core::_Enum implements self::B /*isEnum*/ {
+ static const field core::List<self::E5> values = #C12;
+ static const field self::E5 element = #C11;
+ const constructor •(core::int #index, core::String #name) → self::E5
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E5";
+}
+abstract class _E6&_Enum&A extends core::_Enum implements self::A /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E6&_Enum&A
+ : super core::_Enum::•(index, _name)
+ ;
+ method toString() → core::String
+ return "A";
+}
+class E6 extends self::_E6&_Enum&A /*isEnum*/ {
+ static const field core::List<self::E6> values = #C14;
+ static const field self::E6 element = #C13;
+ const constructor •(core::int #index, core::String #name) → self::E6
+ : super self::_E6&_Enum&A::•(#index, #name)
+ ;
+ method toString() → core::String
+ return super.{self::_E6&_Enum&A::toString}();
+}
+abstract class _E7&_Enum&A extends core::_Enum implements self::A /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ {
+ const synthetic constructor •(core::int index, core::String _name) → self::_E7&_Enum&A
+ : super core::_Enum::•(index, _name)
+ ;
+ method toString() → core::String
+ return "A";
+}
+class E7 extends self::_E7&_Enum&A /*isEnum*/ {
+ static const field core::List<self::E7> values = #C16;
+ static const field self::E7 element = #C15;
+ const constructor •(core::int #index, core::String #name) → self::E7
+ : super self::_E7&_Enum&A::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E7";
+}
+static method checkEqual(dynamic x, dynamic y) → dynamic {
+ if(!(x =={core::Object::==}{(core::Object) → core::bool} y)) {
+ throw "Expected '${x}' and '${y}' to be equal.";
+ }
+}
+static method main() → dynamic {
+ self::checkEqual("${#C3}", "M");
+ self::checkEqual("${#C5}", "E2");
+ self::checkEqual("${#C7}", "E3");
+ self::checkEqual("${#C9}", "E4.element");
+ self::checkEqual("${#C11}", "E5");
+ self::checkEqual("${#C13}", "A");
+ self::checkEqual("${#C15}", "E7");
+}
+
+constants {
+ #C1 = 0
+ #C2 = "element"
+ #C3 = self::E1 {index:#C1, _name:#C2}
+ #C4 = <self::E1*>[#C3]
+ #C5 = self::E2 {index:#C1, _name:#C2}
+ #C6 = <self::E2*>[#C5]
+ #C7 = self::E3 {index:#C1, _name:#C2}
+ #C8 = <self::E3*>[#C7]
+ #C9 = self::E4 {index:#C1, _name:#C2}
+ #C10 = <self::E4*>[#C9]
+ #C11 = self::E5 {index:#C1, _name:#C2}
+ #C12 = <self::E5*>[#C11]
+ #C13 = self::E6 {index:#C1, _name:#C2}
+ #C14 = <self::E6*>[#C13]
+ #C15 = self::E7 {index:#C1, _name:#C2}
+ #C16 = <self::E7*>[#C15]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue49236.dart:
+- E1. (from org-dartlang-testcase:///issue49236.dart:17:6)
+- _E1&_Enum&M. (from org-dartlang-testcase:///issue49236.dart:17:6)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+- E2. (from org-dartlang-testcase:///issue49236.dart:21:6)
+- _E2&_Enum&M. (from org-dartlang-testcase:///issue49236.dart:21:6)
+- E3. (from org-dartlang-testcase:///issue49236.dart:27:6)
+- E4. (from org-dartlang-testcase:///issue49236.dart:33:6)
+- E5. (from org-dartlang-testcase:///issue49236.dart:37:6)
+- E6. (from org-dartlang-testcase:///issue49236.dart:43:6)
+- _E6&_Enum&A. (from org-dartlang-testcase:///issue49236.dart:43:6)
+- E7. (from org-dartlang-testcase:///issue49236.dart:47:6)
+- _E7&_Enum&A. (from org-dartlang-testcase:///issue49236.dart:47:6)
diff --git a/pkg/frontend_server/lib/frontend_server.dart b/pkg/frontend_server/lib/frontend_server.dart
index 8015039..a3f6508 100644
--- a/pkg/frontend_server/lib/frontend_server.dart
+++ b/pkg/frontend_server/lib/frontend_server.dart
@@ -93,7 +93,8 @@
..addOption('depfile',
help: 'Path to output Ninja depfile. Only used in batch mode.')
..addOption('packages',
- help: '.packages file to use for compilation', defaultsTo: null)
+ help: '.dart_tool/package_config.json file to use for compilation',
+ defaultsTo: null)
..addMultiOption('source',
help: 'List additional source files to include into compilation.',
defaultsTo: const <String>[])
@@ -670,7 +671,8 @@
Future<void> writeJavascriptBundle(KernelCompilationResults results,
String filename, String fileSystemScheme, String moduleFormat) async {
var packageConfig = await loadPackageConfigUri(
- _compilerOptions.packagesFileUri ?? File('.packages').absolute.uri);
+ _compilerOptions.packagesFileUri ??
+ File('.dart_tool/package_config.json').absolute.uri);
var soundNullSafety = _compilerOptions.nnbdMode == NnbdMode.Strong;
final Component component = results.component;
// Compute strongly connected components.
diff --git a/pkg/frontend_server/test/frontend_server_test.dart b/pkg/frontend_server/test/frontend_server_test.dart
index 12004ad..d9d8b6f 100644
--- a/pkg/frontend_server/test/frontend_server_test.dart
+++ b/pkg/frontend_server/test/frontend_server_test.dart
@@ -486,7 +486,8 @@
Directory tempDir;
setUp(() {
var systemTempDir = Directory.systemTemp;
- tempDir = systemTempDir.createTempSync('foo bar');
+ tempDir = systemTempDir.createTempSync('frontendServerTest');
+ new Directory('${tempDir.path}/.dart_tool').createSync();
});
tearDown(() {
@@ -1349,9 +1350,21 @@
]
}
''');
- file = File('${tempDir.path}/app/.packages')..createSync(recursive: true);
- file.writeAsStringSync("pkgA:../pkgA\n"
- "pkgB:../pkgB");
+ file = File('${tempDir.path}/app/.dart_tool/package_config.json')
+ ..createSync(recursive: true);
+ file.writeAsStringSync(jsonEncode({
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "pkgA",
+ "rootUri": "../../pkgA",
+ },
+ {
+ "name": "pkgB",
+ "rootUri": "../../pkgB",
+ },
+ ],
+ }));
// Entry point A uses both package A and B.
file = File('${tempDir.path}/app/a.dart')..createSync(recursive: true);
@@ -1441,9 +1454,17 @@
test('incremental-serialization with reject', () async {
// Basically a reproduction of
// https://github.com/flutter/flutter/issues/44384.
- var file = File('${tempDir.path}/pkgA/.packages')
+ var file = File('${tempDir.path}/pkgA/.dart_tool/package_config.json')
..createSync(recursive: true);
- file.writeAsStringSync("pkgA:.");
+ file.writeAsStringSync(jsonEncode({
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "pkgA",
+ "rootUri": "..",
+ },
+ ],
+ }));
file = File('${tempDir.path}/pkgA/a.dart')..createSync(recursive: true);
file.writeAsStringSync("pkgA() {}");
@@ -1629,9 +1650,9 @@
test('compile and recompile with MultiRootFileSystem', () async {
var file = File('${tempDir.path}/foo.dart')..createSync();
file.writeAsStringSync("main() {}\n");
- File('${tempDir.path}/.packages')
+ File('${tempDir.path}/.dart_tool/package_config.json')
..createSync()
- ..writeAsStringSync("\n");
+ ..writeAsStringSync('{"configVersion": 2, "packages": []}');
var dillFile = File('${tempDir.path}/app.dill');
expect(dillFile.existsSync(), equals(false));
final List<String> args = <String>[
@@ -1639,7 +1660,7 @@
'--incremental',
'--platform=${platformKernel.path}',
'--output-dill=${dillFile.path}',
- '--packages=test-scheme:///.packages',
+ '--packages=test-scheme:///.dart_tool/package_config.json',
'--filesystem-root=${tempDir.path}',
'--filesystem-scheme=test-scheme',
'test-scheme:///foo.dart'
@@ -1657,9 +1678,10 @@
final src3 = File('${tempDir.path}/src3.dart')
..createSync()
..writeAsStringSync("entryPoint3() {}\n");
- final packagesFile = File('${tempDir.path}/.packages')
- ..createSync()
- ..writeAsStringSync("\n");
+ final packagesFile =
+ File('${tempDir.path}/.dart_tool/package_config.json')
+ ..createSync()
+ ..writeAsStringSync('{"configVersion": 2, "packages": []}');
final dillFile = File('${tempDir.path}/app.dill');
expect(dillFile.existsSync(), equals(false));
final List<String> args = <String>[
@@ -1766,7 +1788,7 @@
'--platform=${platformKernel.path}',
'--output-dill=${dillFile.path}',
'--enable-http-uris',
- '--packages=http://$host:$port/.packages',
+ '--packages=http://$host:$port/.dart_tool/package_config.json',
'http://$host:$port/foo.dart',
];
expect(await starter(args), 0);
@@ -1781,7 +1803,7 @@
'--platform=${platformKernel.path}',
'--output-dill=${dillFile.path}',
'--enable-http-uris',
- '--packages=test-app:///.packages',
+ '--packages=test-app:///.dart_tool/package_config.json',
'--filesystem-root=http://$host:$port/',
'--filesystem-scheme=test-app',
'test-app:///foo.dart',
@@ -2037,9 +2059,17 @@
test('compile to JavaScript with package scheme', () async {
var file = File('${tempDir.path}/foo.dart')..createSync();
file.writeAsStringSync("main() {\n}\n");
- var packages = File('${tempDir.path}/.packages')
+ var packages = File('${tempDir.path}/.dart_tool/package_config.json')
..createSync()
- ..writeAsStringSync("hello:${tempDir.uri}\n");
+ ..writeAsStringSync(jsonEncode({
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "hello",
+ "rootUri": "${tempDir.uri}",
+ },
+ ],
+ }));
var dillFile = File('${tempDir.path}/app.dill');
expect(dillFile.existsSync(), false);
@@ -2060,9 +2090,17 @@
test('compile to JavaScript weak null safety', () async {
var file = File('${tempDir.path}/foo.dart')..createSync();
file.writeAsStringSync("// @dart = 2.9\nmain() {\n}\n");
- var packages = File('${tempDir.path}/.packages')
+ var packages = File('${tempDir.path}/.dart_tool/package_config.json')
..createSync()
- ..writeAsStringSync("hello:${tempDir.uri}\n");
+ ..writeAsStringSync(jsonEncode({
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "hello",
+ "rootUri": "${tempDir.uri}",
+ },
+ ],
+ }));
var dillFile = File('${tempDir.path}/app.dill');
expect(dillFile.existsSync(), false);
@@ -2084,9 +2122,17 @@
() async {
var file = File('${tempDir.path}/foo.dart')..createSync();
file.writeAsStringSync("// @dart = 2.9\nmain() {\n}\n");
- var packages = File('${tempDir.path}/.packages')
+ var packages = File('${tempDir.path}/.dart_tool/package_config.json')
..createSync()
- ..writeAsStringSync("hello:${tempDir.uri}\n");
+ ..writeAsStringSync(jsonEncode({
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "hello",
+ "rootUri": "${tempDir.uri}",
+ },
+ ],
+ }));
var dillFile = File('${tempDir.path}/app.dill');
expect(dillFile.existsSync(), false);
@@ -2844,9 +2890,17 @@
File('${lib.path}/foo.dart')
..createSync()
..writeAsStringSync("main() {}\n");
- File packages = File('${tempDir.path}/.packages')
+ File packages = File('${tempDir.path}/.dart_tool/package_config.json')
..createSync()
- ..writeAsStringSync('test:lib/\n');
+ ..writeAsStringSync(jsonEncode({
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "test",
+ "rootUri": "../lib",
+ },
+ ],
+ }));
var dillFile = File('${tempDir.path}/app.dill');
expect(dillFile.existsSync(), equals(false));
var depFile = File('${tempDir.path}/the depfile');
diff --git a/pkg/js_shared/analysis_options.yaml b/pkg/js_shared/analysis_options.yaml
new file mode 100644
index 0000000..c36c2c5
--- /dev/null
+++ b/pkg/js_shared/analysis_options.yaml
@@ -0,0 +1 @@
+include: package:lints/core.yaml
diff --git a/pkg/js_shared/lib/synced/recipe_syntax.dart b/pkg/js_shared/lib/synced/recipe_syntax.dart
index b24e7c2..51b8358 100644
--- a/pkg/js_shared/lib/synced/recipe_syntax.dart
+++ b/pkg/js_shared/lib/synced/recipe_syntax.dart
@@ -131,7 +131,9 @@
static const int _at = 0x40;
static const String _atString = '@';
+ // ignore: unused_field
static const int _uppercaseA = 0x41;
+ // ignore: unused_field
static const int _uppercaseZ = 0x5A;
static const int _leftBracket = 0x5B;
@@ -148,6 +150,7 @@
static const String _backtickString = '`';
static const int _lowercaseA = 0x61;
+ // ignore: unused_field
static const int _lowercaseZ = 0x7A;
static const int _leftBrace = 0x7B;
diff --git a/pkg/js_shared/pubspec.yaml b/pkg/js_shared/pubspec.yaml
index 3503f25..f2cad2e 100644
--- a/pkg/js_shared/pubspec.yaml
+++ b/pkg/js_shared/pubspec.yaml
@@ -9,3 +9,4 @@
dev_dependencies:
_fe_analyzer_shared: any
expect: any
+ lints: any
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index 0bc4b59..ed2255b 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -49,7 +49,7 @@
final bool verbose = new bool.fromEnvironment('DFE_VERBOSE');
final bool dumpKernel = new bool.fromEnvironment('DFE_DUMP_KERNEL');
const String platformKernelFile = 'virtual_platform_kernel.dill';
-const String dotPackagesFile = '.packages';
+const String packageConfigFile = '.dart_tool/package_config.json';
// NOTE: Any changes to these tags need to be reflected in kernel_isolate.cc
// Tags used to indicate different requests to the dart frontend.
@@ -599,7 +599,7 @@
}
FileSystem fileSystem =
- _buildFileSystem([dotPackagesFile, <int>[]], null, null, null);
+ _buildFileSystem([packageConfigFile, <int>[]], null, null, null);
// TODO(aam): IncrementalCompilerWrapper instance created below have to be
// destroyed when corresponding isolate is shut down. To achieve that
@@ -610,7 +610,7 @@
component, isolateGroupId, fileSystem, null,
enableAsserts: enableAsserts,
experimentalFlags: experimentalFlags,
- packageConfig: dotPackagesFile,
+ packageConfig: packageConfigFile,
enableMirrors: enableMirrors);
isolateCompilers[isolateGroupId] = compiler;
await compiler.compile(
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 03ffe27..8a380dc 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -69,7 +69,8 @@
void declareCompilerOptions(ArgParser args) {
args.addOption('platform',
help: 'Path to vm_platform_strong.dill file', defaultsTo: null);
- args.addOption('packages', help: 'Path to .packages file', defaultsTo: null);
+ args.addOption('packages',
+ help: 'Path to .dart_tool/package_config.json file', defaultsTo: null);
args.addOption('output',
abbr: 'o', help: 'Path to resulting dill file', defaultsTo: null);
args.addFlag('aot',
@@ -95,7 +96,7 @@
defaultsTo: true);
args.addMultiOption('filesystem-root',
help: 'A base path for the multi-root virtual file system.'
- ' If multi-root file system is used, the input script and .packages file should be specified using URI.');
+ ' If multi-root file system is used, the input script and .dart_tool/package_config.json file should be specified using URI.');
args.addOption('filesystem-scheme',
help: 'The URI scheme for the multi-root virtual filesystem.');
args.addMultiOption('source',
diff --git a/pkg/vm/test/incremental_compiler_test.dart b/pkg/vm/test/incremental_compiler_test.dart
index aaf4463..8bfa4e40 100644
--- a/pkg/vm/test/incremental_compiler_test.dart
+++ b/pkg/vm/test/incremental_compiler_test.dart
@@ -1029,8 +1029,20 @@
});
test('compile, reject, compile again', () async {
- var packageUri = Uri.file('${mytest.path}/.packages');
- new File(packageUri.toFilePath()).writeAsStringSync('foo:lib/\n');
+ new Directory(mytest.path + "/.dart_tool").createSync();
+ var packageUri =
+ Uri.file('${mytest.path}/.dart_tool/package_config.json');
+ new File(packageUri.toFilePath()).writeAsStringSync(jsonEncode({
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": "..",
+ "packageUri": "lib",
+ "languageVersion": "2.7",
+ },
+ ],
+ }));
new Directory(mytest.path + "/lib").createSync();
var fooUri = Uri.file('${mytest.path}/lib/foo.dart');
new File(fooUri.toFilePath())
@@ -1581,7 +1593,7 @@
});
test('from dill with package uri', () async {
- // 2 iterations: One where the .packages file is deleted, and one where
+ // 2 iterations: One where the package_config.json file is deleted, and one where
// it is not.
for (int i = 0; i < 2; i++) {
Directory dir = mytest.createTempSync();
@@ -1595,8 +1607,18 @@
int extra() { return 22; }
""");
- File packagesFile = new File.fromUri(dir.uri.resolve(".packages"));
- packagesFile.writeAsStringSync("foo:.");
+ File packagesFile =
+ new File.fromUri(dir.uri.resolve("package_config.json"));
+ packagesFile.writeAsStringSync(jsonEncode({
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": ".",
+ "languageVersion": "2.7",
+ },
+ ],
+ }));
Uri mainUri = Uri.parse("package:foo/main.dart");
diff --git a/pkg/vm/test/kernel_front_end_test.dart b/pkg/vm/test/kernel_front_end_test.dart
index 037a610c..9151eea 100644
--- a/pkg/vm/test/kernel_front_end_test.dart
+++ b/pkg/vm/test/kernel_front_end_test.dart
@@ -19,7 +19,6 @@
const String mainScript = 'pkg/vm/bin/gen_kernel.dart';
const String mainScriptPackageUri = 'package:vm/kernel_front_end.dart';
-const String packagesFile = '.packages';
const String packageConfigFile = '.dart_tool/package_config.json';
Future<void> testCompile(List<String> args) async {
@@ -56,7 +55,7 @@
'--platform',
platformPath(),
'--packages',
- '$sdkDir/$packagesFile',
+ '$sdkDir/$packageConfigFile',
'--output',
outputDill(),
'$sdkDir/$mainScript',
@@ -72,7 +71,7 @@
'--filesystem-root',
sdkDir,
'--packages',
- 'test-filesystem-scheme:///$packagesFile',
+ 'test-filesystem-scheme:///$packageConfigFile',
'--output',
outputDill(),
'test-filesystem-scheme:///$mainScript',
@@ -88,7 +87,7 @@
'--filesystem-root',
sdkDir,
'--packages',
- 'test-filesystem-scheme:///$packagesFile',
+ 'test-filesystem-scheme:///$packageConfigFile',
'--output',
outputDill(),
'$mainScriptPackageUri',
@@ -100,7 +99,7 @@
'--platform',
platformPath(),
'--packages',
- '$sdkDir/$packagesFile',
+ '$sdkDir/$packageConfigFile',
'--output',
outputDill(),
'--split-output-by-packages',
diff --git a/pkg/vm/test/modular_kernel_plus_aot_test.dart b/pkg/vm/test/modular_kernel_plus_aot_test.dart
index 8e05c6c..0b08a37 100644
--- a/pkg/vm/test/modular_kernel_plus_aot_test.dart
+++ b/pkg/vm/test/modular_kernel_plus_aot_test.dart
@@ -25,7 +25,7 @@
}
// Tests are run in the root directory of the sdk checkout.
- final Uri packagesFile = sdkRootFile('.packages');
+ final Uri packagesFile = sdkRootFile('.dart_tool/package_config.json');
final Uri librariesFile = sdkRootFile('sdk/lib/libraries.json');
final vmTarget = VmTarget(TargetFlags(supportMirrors: false));
diff --git a/pkg/vm_snapshot_analysis/test/utils.dart b/pkg/vm_snapshot_analysis/test/utils.dart
index cea4a7f..ea0216f 100644
--- a/pkg/vm_snapshot_analysis/test/utils.dart
+++ b/pkg/vm_snapshot_analysis/test/utils.dart
@@ -46,7 +46,15 @@
await File(path.join(dir, file.key)).writeAsString(file.value);
}
await File(packages).writeAsString('''
-input:./
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "input",
+ "rootUri": "./"
+ }
+ ]
+}
''');
await File(mainDart).writeAsString('''
import 'package:input/input.dart' as input;
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 2196982..2d8b531 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -1378,6 +1378,12 @@
if (should_run_user_program) {
try_load_snapshots_lambda();
}
+ } else if (script_name == nullptr &&
+ Options::gen_snapshot_kind() != SnapshotKind::kNone) {
+ Syslog::PrintErr(
+ "Snapshot generation should be done using the 'dart compile' "
+ "command.\n");
+ Platform::Exit(kErrorExitCode);
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/tests/concurrency/stress_test_list.json b/runtime/tests/concurrency/stress_test_list.json
index 486220a..c40bb0d 100644
--- a/runtime/tests/concurrency/stress_test_list.json
+++ b/runtime/tests/concurrency/stress_test_list.json
@@ -6705,7 +6705,7 @@
"../../../tests/standalone_2/no_support_service_test.dart",
"../../../tests/standalone_2/no_support_timeline_test.dart",
"../../../tests/standalone_2/number_identity_test.dart",
- "../../../tests/standalone_2/package/scenarios/both_dir_and_file/both_dir_and_file_noimports_test.dart",
+ "../../../tests/standalone_2/package/scenarios/both_dir_dot_packages_and_package_config/both_dir_dot_packages_and_package_config_noimports_test.dart",
"../../../tests/standalone_2/package/scenarios/empty_packages_file/empty_packages_file_noimports_test.dart",
"../../../tests/standalone_2/package/scenarios/invalid/invalid_utf8_test.dart",
"../../../tests/standalone_2/package/scenarios/invalid/non_existent_packages_file_test.dart",
diff --git a/runtime/tests/vm/dart/gen_snapshot_include_resolved_urls_test.dart b/runtime/tests/vm/dart/gen_snapshot_include_resolved_urls_test.dart
index 9b6d74d..d9072ee 100644
--- a/runtime/tests/vm/dart/gen_snapshot_include_resolved_urls_test.dart
+++ b/runtime/tests/vm/dart/gen_snapshot_include_resolved_urls_test.dart
@@ -42,7 +42,7 @@
// Compile script to Kernel IR.
await run('pkg/vm/tool/gen_kernel', <String>[
'--aot',
- '--packages=$sdkDir/.packages',
+ '--packages=$sdkDir/.dart_tool/package_config.json',
'--platform=$platformDill',
'-o',
scriptDill,
diff --git a/runtime/tests/vm/dart/issue32950_test.dart b/runtime/tests/vm/dart/issue32950_test.dart
index 7e14a7f..7e24a33 100644
--- a/runtime/tests/vm/dart/issue32950_test.dart
+++ b/runtime/tests/vm/dart/issue32950_test.dart
@@ -15,7 +15,7 @@
var exitPort = new ReceivePort();
await Isolate.spawnUri(p.toUri(p.absolute(path)), [], null,
- packageConfig: p.toUri(p.absolute(".packages")),
+ packageConfig: p.toUri(p.absolute(".dart_tool/package_config.json")),
onExit: exitPort.sendPort);
await exitPort.first;
await sourceFile.delete();
diff --git a/runtime/tests/vm/dart_2/gen_snapshot_include_resolved_urls_test.dart b/runtime/tests/vm/dart_2/gen_snapshot_include_resolved_urls_test.dart
index 5310fcd..3221cb5 100644
--- a/runtime/tests/vm/dart_2/gen_snapshot_include_resolved_urls_test.dart
+++ b/runtime/tests/vm/dart_2/gen_snapshot_include_resolved_urls_test.dart
@@ -44,7 +44,7 @@
// Compile script to Kernel IR.
await run('pkg/vm/tool/gen_kernel', <String>[
'--aot',
- '--packages=$sdkDir/.packages',
+ '--packages=$sdkDir/.dart_tool/package_config.json',
'--platform=$platformDill',
'-o',
scriptDill,
diff --git a/runtime/tests/vm/dart_2/isolates/reload_utils.dart b/runtime/tests/vm/dart_2/isolates/reload_utils.dart
index f41c52f..c721d01 100644
--- a/runtime/tests/vm/dart_2/isolates/reload_utils.dart
+++ b/runtime/tests/vm/dart_2/isolates/reload_utils.dart
@@ -97,7 +97,7 @@
Future compile(String from, String to) async {
final executable = Platform.executable;
final command = [
- '--packages=.packages',
+ '--packages=.dart_tool/package_config.json',
'--snapshot-kind=kernel',
'--snapshot=$to',
from,
diff --git a/runtime/tests/vm/dart_2/issue32950_test.dart b/runtime/tests/vm/dart_2/issue32950_test.dart
index b3f38fc..1f3ec6e 100644
--- a/runtime/tests/vm/dart_2/issue32950_test.dart
+++ b/runtime/tests/vm/dart_2/issue32950_test.dart
@@ -17,7 +17,7 @@
var exitPort = new ReceivePort();
await Isolate.spawnUri(p.toUri(p.absolute(path)), [], null,
- packageConfig: p.toUri(p.absolute(".packages")),
+ packageConfig: p.toUri(p.absolute(".dart_tool/package_config.json")),
onExit: exitPort.sendPort);
await exitPort.first;
await sourceFile.delete();
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index a13f06a7..ea47f52 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -2144,7 +2144,7 @@
void RestoreCodePointer();
// Restores the values of the registers that are blocked to cache some values
- // e.g. BARRIER_MASK and NULL_REG.
+ // e.g. HEAP_BITS and NULL_REG.
void RestorePinnedRegisters();
void SetupGlobalPoolAndDispatchTable();
diff --git a/runtime/vm/compiler/assembler/assembler_riscv.cc b/runtime/vm/compiler/assembler/assembler_riscv.cc
index cdfa87a..862bf92 100644
--- a/runtime/vm/compiler/assembler/assembler_riscv.cc
+++ b/runtime/vm/compiler/assembler/assembler_riscv.cc
@@ -3019,6 +3019,7 @@
// in progress
// If so, call the WriteBarrier stub, which will either add object to the
// store buffer (case 1) or add value to the marking stack (case 2).
+ // See RestorePinnedRegisters for why this can be `ble`.
// Compare UntaggedObject::StorePointer.
Label done;
if (can_value_be_smi == kValueCanBeSmi) {
@@ -3028,8 +3029,7 @@
lbu(TMP2, FieldAddress(value, target::Object::tags_offset()));
srli(TMP, TMP, target::UntaggedObject::kBarrierOverlapShift);
and_(TMP, TMP, TMP2);
- and_(TMP, TMP, WRITE_BARRIER_MASK);
- beqz(TMP, &done, kNearJump);
+ ble(TMP, WRITE_BARRIER_STATE, &done, kNearJump);
Register objectForCall = object;
if (value != kWriteBarrierValueReg) {
@@ -3091,6 +3091,7 @@
// in progress
// If so, call the WriteBarrier stub, which will either add object to the
// store buffer (case 1) or add value to the marking stack (case 2).
+ // See RestorePinnedRegisters for why this can be `ble`.
// Compare UntaggedObject::StorePointer.
Label done;
if (can_value_be_smi == kValueCanBeSmi) {
@@ -3100,8 +3101,7 @@
lbu(TMP2, FieldAddress(value, target::Object::tags_offset()));
srli(TMP, TMP, target::UntaggedObject::kBarrierOverlapShift);
and_(TMP, TMP, TMP2);
- and_(TMP, TMP, WRITE_BARRIER_MASK);
- beqz(TMP, &done, kNearJump);
+ ble(TMP, WRITE_BARRIER_STATE, &done, kNearJump);
if (spill_lr) {
PushRegister(RA);
}
@@ -3672,12 +3672,46 @@
subi(PP, PP, kHeapObjectTag); // Pool in PP is untagged!
}
-// Restores the values of the registers that are blocked to cache some values
-// e.g. BARRIER_MASK and NULL_REG.
void Assembler::RestorePinnedRegisters() {
- lx(WRITE_BARRIER_MASK,
+ lx(WRITE_BARRIER_STATE,
Address(THR, target::Thread::write_barrier_mask_offset()));
lx(NULL_REG, Address(THR, target::Thread::object_null_offset()));
+
+ // Our write barrier usually uses mask-and-test,
+ // 01b6f6b3 and tmp, tmp, mask
+ // c689 beqz tmp, +10
+ // but on RISC-V compare-and-branch is shorter,
+ // 00ddd663 ble tmp, wbs, +12
+ //
+ // TMP bit 4+ = 0
+ // TMP bit 3 = object is old-and-not-remembered AND value is new (genr bit)
+ // TMP bit 2 = object is old AND value is old-and-not-marked (incr bit)
+ // TMP bit 1 = garbage
+ // TMP bit 0 = garbage
+ //
+ // Thread::wbm | WRITE_BARRIER_STATE | TMP/combined headers | result
+ // generational only
+ // 0b1000 0b0111 0b11xx impossible
+ // 0b10xx call stub
+ // 0b01xx skip
+ // 0b00xx skip
+ // generational and incremental
+ // 0b1100 0b0011 0b11xx impossible
+ // 0b10xx call stub
+ // 0b01xx call stub
+ // 0b00xx skip
+ xori(WRITE_BARRIER_STATE, WRITE_BARRIER_STATE,
+ (target::UntaggedObject::kGenerationalBarrierMask << 1) - 1);
+
+ // Generational bit must be higher than incremental bit, with no other bits
+ // between.
+ ASSERT(target::UntaggedObject::kGenerationalBarrierMask ==
+ (target::UntaggedObject::kIncrementalBarrierMask << 1));
+ // Other header bits must be lower.
+ ASSERT(target::UntaggedObject::kIncrementalBarrierMask >
+ target::UntaggedObject::kCanonicalBit);
+ ASSERT(target::UntaggedObject::kIncrementalBarrierMask >
+ target::UntaggedObject::kCardRememberedBit);
}
void Assembler::SetupGlobalPoolAndDispatchTable() {
@@ -3816,7 +3850,7 @@
// Or would need to save above.
COMPILE_ASSERT(IsCalleeSavedRegister(THR));
COMPILE_ASSERT(IsCalleeSavedRegister(NULL_REG));
- COMPILE_ASSERT(IsCalleeSavedRegister(WRITE_BARRIER_MASK));
+ COMPILE_ASSERT(IsCalleeSavedRegister(WRITE_BARRIER_STATE));
COMPILE_ASSERT(IsCalleeSavedRegister(DISPATCH_TABLE_REG));
}
@@ -3859,7 +3893,7 @@
// Already saved.
COMPILE_ASSERT(IsCalleeSavedRegister(THR));
COMPILE_ASSERT(IsCalleeSavedRegister(NULL_REG));
- COMPILE_ASSERT(IsCalleeSavedRegister(WRITE_BARRIER_MASK));
+ COMPILE_ASSERT(IsCalleeSavedRegister(WRITE_BARRIER_STATE));
COMPILE_ASSERT(IsCalleeSavedRegister(DISPATCH_TABLE_REG));
// Need to save.
COMPILE_ASSERT(!IsCalleeSavedRegister(PP));
diff --git a/runtime/vm/compiler/assembler/assembler_riscv.h b/runtime/vm/compiler/assembler/assembler_riscv.h
index f62f545..cefa220 100644
--- a/runtime/vm/compiler/assembler/assembler_riscv.h
+++ b/runtime/vm/compiler/assembler/assembler_riscv.h
@@ -1257,7 +1257,7 @@
void RestorePoolPointer();
// Restores the values of the registers that are blocked to cache some values
- // e.g. BARRIER_MASK and NULL_REG.
+ // e.g. WRITE_BARRIER_STATE and NULL_REG.
void RestorePinnedRegisters();
void SetupGlobalPoolAndDispatchTable();
diff --git a/runtime/vm/compiler/assembler/assembler_riscv_test.cc b/runtime/vm/compiler/assembler/assembler_riscv_test.cc
index ff2bfb3..8616410 100644
--- a/runtime/vm/compiler/assembler/assembler_riscv_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_riscv_test.cc
@@ -32,7 +32,7 @@
__ PushNativeCalleeSavedRegisters();
__ mv(THR, A2);
- __ lx(WRITE_BARRIER_MASK, Address(THR, Thread::write_barrier_mask_offset()));
+ __ RestorePinnedRegisters(); // Setup WRITE_BARRIER_STATE.
__ StoreIntoObject(A1, FieldAddress(A1, GrowableObjectArray::data_offset()),
A0);
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index abf5464..2490c68 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -355,6 +355,8 @@
const word UntaggedObject::kCardRememberedBit =
dart::UntaggedObject::kCardRememberedBit;
+const word UntaggedObject::kCanonicalBit = dart::UntaggedObject::kCanonicalBit;
+
const word UntaggedObject::kOldAndNotRememberedBit =
dart::UntaggedObject::kOldAndNotRememberedBit;
@@ -397,6 +399,9 @@
const word UntaggedObject::kGenerationalBarrierMask =
dart::UntaggedObject::kGenerationalBarrierMask;
+const word UntaggedObject::kIncrementalBarrierMask =
+ dart::UntaggedObject::kIncrementalBarrierMask;
+
bool IsTypedDataClassId(intptr_t cid) {
return dart::IsTypedDataClassId(cid);
}
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index 723e277..5f8ec14 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -410,6 +410,7 @@
class UntaggedObject : public AllStatic {
public:
static const word kCardRememberedBit;
+ static const word kCanonicalBit;
static const word kOldAndNotRememberedBit;
static const word kOldAndNotMarkedBit;
static const word kSizeTagPos;
@@ -422,6 +423,7 @@
static const word kTagBitsSizeTagPos;
static const word kBarrierOverlapShift;
static const word kGenerationalBarrierMask;
+ static const word kIncrementalBarrierMask;
static bool IsTypedDataClassId(intptr_t cid);
};
diff --git a/runtime/vm/constants_riscv.cc b/runtime/vm/constants_riscv.cc
index 7c9b6ed..481d83f 100644
--- a/runtime/vm/constants_riscv.cc
+++ b/runtime/vm/constants_riscv.cc
@@ -18,9 +18,9 @@
#endif
const char* const cpu_reg_names[kNumberOfCpuRegisters] = {
- "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "fp", "thr", "a0",
- "a1", "a2", "tmp", "tmp2", "pp", "a6", "a7", "s2", "s3", "s4", "s5",
- "s6", "s7", "s8", "s9", "null", "mask", "t3", "t4", "t5", "t6",
+ "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "fp", "thr", "a0",
+ "a1", "a2", "tmp", "tmp2", "pp", "a6", "a7", "s2", "s3", "s4", "s5",
+ "s6", "s7", "s8", "s9", "null", "wbs", "t3", "t4", "t5", "t6",
};
const char* const cpu_reg_abi_names[kNumberOfCpuRegisters] = {
diff --git a/runtime/vm/constants_riscv.h b/runtime/vm/constants_riscv.h
index 7c2a2b9..e073037 100644
--- a/runtime/vm/constants_riscv.h
+++ b/runtime/vm/constants_riscv.h
@@ -70,7 +70,7 @@
S8 = 24, // CALLEE_SAVED_TEMP / FAR_TMP
S9 = 25, // DISPATCH_TABLE_REG
S10 = 26, // NULL
- S11 = 27, // WRITE_BARRIER_MASK
+ S11 = 27, // WRITE_BARRIER_STATE
T3 = 28,
T4 = 29,
T5 = 30,
@@ -162,7 +162,7 @@
constexpr Register THR = S1; // Caches current thread in generated code.
constexpr Register CALLEE_SAVED_TEMP = S8;
constexpr Register CALLEE_SAVED_TEMP2 = S7;
-constexpr Register WRITE_BARRIER_MASK = S11;
+constexpr Register WRITE_BARRIER_STATE = S11;
constexpr Register NULL_REG = S10; // Caches NullObject() value.
// ABI for catch-clause entry point.
@@ -450,13 +450,13 @@
// We rely on that any calls into C++ also preserve X18.
constexpr intptr_t kReservedCpuRegisters =
R(ZR) | R(TP) | R(GP) | R(SP) | R(FP) | R(TMP) | R(TMP2) | R(PP) | R(THR) |
- R(RA) | R(WRITE_BARRIER_MASK) | R(NULL_REG) | R(DISPATCH_TABLE_REG) |
+ R(RA) | R(WRITE_BARRIER_STATE) | R(NULL_REG) | R(DISPATCH_TABLE_REG) |
R(FAR_TMP) | R(18);
constexpr intptr_t kNumberOfReservedCpuRegisters = 15;
#else
constexpr intptr_t kReservedCpuRegisters =
R(ZR) | R(TP) | R(GP) | R(SP) | R(FP) | R(TMP) | R(TMP2) | R(PP) | R(THR) |
- R(RA) | R(WRITE_BARRIER_MASK) | R(NULL_REG) | R(DISPATCH_TABLE_REG) |
+ R(RA) | R(WRITE_BARRIER_STATE) | R(NULL_REG) | R(DISPATCH_TABLE_REG) |
R(FAR_TMP);
constexpr intptr_t kNumberOfReservedCpuRegisters = 14;
#endif
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index abc979e..2e4ad32 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -158,11 +158,11 @@
// bit fields for storing tags.
enum TagBits {
kCardRememberedBit = 0,
- kOldAndNotMarkedBit = 1, // Incremental barrier target.
- kNewBit = 2, // Generational barrier target.
- kOldBit = 3, // Incremental barrier source.
- kOldAndNotRememberedBit = 4, // Generational barrier source.
- kCanonicalBit = 5,
+ kCanonicalBit = 1,
+ kOldAndNotMarkedBit = 2, // Incremental barrier target.
+ kNewBit = 3, // Generational barrier target.
+ kOldBit = 4, // Incremental barrier source.
+ kOldAndNotRememberedBit = 5, // Generational barrier source.
kReservedTagPos = 6,
kReservedTagSize = 2,
diff --git a/runtime/vm/simulator_riscv.cc b/runtime/vm/simulator_riscv.cc
index 3b2034f..937c314 100644
--- a/runtime/vm/simulator_riscv.cc
+++ b/runtime/vm/simulator_riscv.cc
@@ -463,7 +463,9 @@
pp -= kHeapObjectTag; // In the PP register, the pool pointer is untagged.
set_xreg(CODE_REG, code);
set_xreg(PP, pp);
- set_xreg(WRITE_BARRIER_MASK, thread->write_barrier_mask());
+ set_xreg(WRITE_BARRIER_STATE,
+ thread->write_barrier_mask() ^
+ ((UntaggedObject::kGenerationalBarrierMask << 1) - 1));
set_xreg(NULL_REG, static_cast<uintx_t>(Object::null()));
if (FLAG_precompiled_mode) {
set_xreg(DISPATCH_TABLE_REG,
diff --git a/sdk/lib/_internal/js_shared/lib/synced/recipe_syntax.dart b/sdk/lib/_internal/js_shared/lib/synced/recipe_syntax.dart
index b24e7c2..51b8358 100644
--- a/sdk/lib/_internal/js_shared/lib/synced/recipe_syntax.dart
+++ b/sdk/lib/_internal/js_shared/lib/synced/recipe_syntax.dart
@@ -131,7 +131,9 @@
static const int _at = 0x40;
static const String _atString = '@';
+ // ignore: unused_field
static const int _uppercaseA = 0x41;
+ // ignore: unused_field
static const int _uppercaseZ = 0x5A;
static const int _leftBracket = 0x5B;
@@ -148,6 +150,7 @@
static const String _backtickString = '`';
static const int _lowercaseA = 0x61;
+ // ignore: unused_field
static const int _lowercaseZ = 0x7A;
static const int _leftBrace = 0x7B;
diff --git a/sdk/lib/async/async.dart b/sdk/lib/async/async.dart
index bd41381..f4da9ca 100644
--- a/sdk/lib/async/async.dart
+++ b/sdk/lib/async/async.dart
@@ -109,7 +109,9 @@
CastStreamTransformer,
checkNotNullable,
EmptyIterator,
+ isNullFuture,
IterableElementError,
+ nullFuture,
printToZone,
printToConsole,
Since,
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index 117465c..bb942d9 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -515,7 +515,7 @@
controller
..onCancel = () {
timer.cancel();
- return Zone._current._nullFuture;
+ return nullFuture;
}
..onPause = () {
watch.stop();
diff --git a/sdk/lib/async/stream_controller.dart b/sdk/lib/async/stream_controller.dart
index 1f34d76..2d381c5 100644
--- a/sdk/lib/async/stream_controller.dart
+++ b/sdk/lib/async/stream_controller.dart
@@ -590,7 +590,7 @@
Future<void> _ensureDoneFuture() =>
_doneFuture ??
(_isCanceled
- ? Zone._current._nullFuture as Future<void>
+ ? nullFuture as Future<void>
: _doneFuture = _Future<void>());
/// Send or enqueue a data event.
@@ -922,7 +922,7 @@
var cancel = addSubscription.cancel();
if (cancel == null) {
addStreamFuture._asyncComplete(null);
- return Zone._current._nullFuture;
+ return nullFuture;
}
return cancel.whenComplete(() {
addStreamFuture._asyncComplete(null);
diff --git a/sdk/lib/async/stream_impl.dart b/sdk/lib/async/stream_impl.dart
index b5a40cb..9065c46 100644
--- a/sdk/lib/async/stream_impl.dart
+++ b/sdk/lib/async/stream_impl.dart
@@ -197,7 +197,7 @@
if (!_isCanceled) {
_cancel();
}
- return _cancelFuture ?? Zone._current._nullFuture;
+ return _cancelFuture ?? nullFuture;
}
Future<E> asFuture<E>([E? futureValue]) {
@@ -217,7 +217,7 @@
};
_onError = (Object error, StackTrace stackTrace) {
Future cancelFuture = cancel();
- if (!identical(Zone._current._nullFuture, cancelFuture)) {
+ if (!isNullFuture(Zone._current, cancelFuture)) {
cancelFuture.whenComplete(() {
result._completeError(error, stackTrace);
});
@@ -365,8 +365,7 @@
_state |= _STATE_WAIT_FOR_CANCEL;
_cancel();
var cancelFuture = _cancelFuture;
- if (cancelFuture != null &&
- !identical(Zone._current._nullFuture, cancelFuture)) {
+ if (cancelFuture != null && !isNullFuture(Zone._current, cancelFuture)) {
cancelFuture.whenComplete(sendError);
} else {
sendError();
@@ -395,8 +394,7 @@
_cancel();
_state |= _STATE_WAIT_FOR_CANCEL;
var cancelFuture = _cancelFuture;
- if (cancelFuture != null &&
- !identical(Zone._current._nullFuture, cancelFuture)) {
+ if (cancelFuture != null && !isNullFuture(Zone._current, cancelFuture)) {
cancelFuture.whenComplete(sendDone);
} else {
sendDone();
@@ -672,7 +670,7 @@
}
}
- Future cancel() => Zone._current._nullFuture;
+ Future cancel() => nullFuture;
Future<E> asFuture<E>([E? futureValue]) {
E resultValue;
@@ -819,7 +817,7 @@
Future cancel() {
_stream._cancelSubscription();
- return Zone._current._nullFuture;
+ return nullFuture;
}
bool get isPaused {
@@ -963,7 +961,7 @@
}
return subscription.cancel();
}
- return Zone._current._nullFuture;
+ return nullFuture;
}
void _onData(T data) {
diff --git a/sdk/lib/async/stream_pipe.dart b/sdk/lib/async/stream_pipe.dart
index 2caa84b..78ad675 100644
--- a/sdk/lib/async/stream_pipe.dart
+++ b/sdk/lib/async/stream_pipe.dart
@@ -26,8 +26,7 @@
void _cancelAndError(StreamSubscription subscription, _Future future,
Object error, StackTrace stackTrace) {
var cancelFuture = subscription.cancel();
- if (cancelFuture != null &&
- !identical(Zone._current._nullFuture, cancelFuture)) {
+ if (cancelFuture != null && !isNullFuture(Zone._current, cancelFuture)) {
cancelFuture.whenComplete(() => future._completeError(error, stackTrace));
} else {
future._completeError(error, stackTrace);
@@ -56,8 +55,7 @@
before completing with a value. */
void _cancelAndValue(StreamSubscription subscription, _Future future, value) {
var cancelFuture = subscription.cancel();
- if (cancelFuture != null &&
- !identical(Zone._current._nullFuture, cancelFuture)) {
+ if (cancelFuture != null && !isNullFuture(Zone._current, cancelFuture)) {
cancelFuture.whenComplete(() => future._complete(value));
} else {
future._complete(value);
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index 42e0c76..b9bcd19 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -1078,28 +1078,6 @@
implZone, e, identical(error, e) ? stackTrace : s);
}
}
-
- /// A reusable `null`-valued future per zone used by `dart:async`.
- ///
- /// **DO NOT USE.**
- ///
- /// This future is used in situations where a future is expected,
- /// but no asynchronous computation actually happens,
- /// like cancelling a stream from a controller with no `onCancel` callback.
- /// *Some code depends on recognizing this future in order to react
- /// synchronously.*
- /// It does so to avoid changing event interleaving during the null safety
- /// migration where, for example, the [StreamSubscription.cancel] method
- /// stopped being able to return `null`.
- /// The code that would be broken by such a timing change is fragile,
- /// but we are not able to simply change it.
- /// For better or worse, code depends on the precise timing
- /// that our libraries have so far exhibited.
- ///
- /// This future will be removed again if we can ever do so.
- /// Do not use it for anything other than preserving timing
- /// during the null safety migration.
- _Future<Null> get _nullFuture;
}
class _CustomZone extends _Zone {
@@ -1127,9 +1105,6 @@
/// The parent zone.
final _Zone parent;
- /// Cached value for [_nullFuture];
- _Future<Null>? _nullFutureCache;
-
/// The zone's scoped value declaration map.
///
/// This is always a [HashMap].
@@ -1221,18 +1196,6 @@
/// parent's error-zone.
Zone get errorZone => _handleUncaughtError.zone;
- _Future<Null> get _nullFuture {
- _Future<Null>? result = _nullFutureCache;
- if (result != null) return result;
- // We only care about the zone of the null future
- // because of the zone it schedules microtasks in.
- var microtaskZone = _scheduleMicrotask.zone;
- if (!identical(microtaskZone, this)) {
- return _nullFutureCache = microtaskZone._nullFuture;
- }
- return _nullFutureCache = _Future<Null>.value(null);
- }
-
void runGuarded(void f()) {
try {
run(f);
@@ -1546,8 +1509,6 @@
}
class _RootZone extends _Zone {
- static final _nullFutureCache = _Future<Null>.zoneValue(null, _rootZone);
-
const _RootZone();
_ZoneFunction<RunHandler> get _run =>
@@ -1586,8 +1547,6 @@
// The parent zone.
_Zone? get parent => null;
- _Future<Null> get _nullFuture => _nullFutureCache;
-
/// The zone's scoped value declaration map.
///
/// This is always a [HashMap].
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 91224f6..671f68a 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -37302,13 +37302,13 @@
}
Future cancel() {
- if (!_canceled) {
- _unlisten();
- // Clear out the target to indicate this is complete.
- _target = null;
- _onData = null;
- }
- return Future<void>.value(null);
+ if (_canceled) return nullFuture;
+
+ _unlisten();
+ // Clear out the target to indicate this is complete.
+ _target = null;
+ _onData = null;
+ return nullFuture;
}
bool get _canceled => _target == null;
diff --git a/sdk/lib/internal/internal.dart b/sdk/lib/internal/internal.dart
index 0353c71..92f7a34 100644
--- a/sdk/lib/internal/internal.dart
+++ b/sdk/lib/internal/internal.dart
@@ -136,6 +136,33 @@
return digit1 * 16 + digit2 - (digit2 & 256);
}
+/// A reusable `null`-valued future per zone used by `dart:async`.
+///
+/// **DO NOT USE.**
+///
+/// This future is used in situations where a future is expected,
+/// but no asynchronous computation actually happens,
+/// like cancelling a stream from a controller with no `onCancel` callback.
+/// *Some code depends on recognizing this future in order to react
+/// synchronously.*
+/// It does so to avoid changing event interleaving during the null safety
+/// migration where, for example, the [StreamSubscription.cancel] method
+/// stopped being able to return `null`.
+/// The code that would be broken by such a timing change is fragile,
+/// but we are not able to simply change it.
+/// For better or worse, code depends on the precise timing that our libraries
+/// have so far exhibited.
+///
+/// This future will be removed again if we can ever do so.
+/// Do not use it for anything other than preserving timing
+/// during the null safety migration.
+Future<Null> get nullFuture =>
+ _nullFutures[Zone.current] ??= Future<Null>.value(null);
+
+/// Whether [future] is the null future of the current zone.
+bool isNullFuture(Zone zone, Future future) =>
+ identical(_nullFutures[zone], future);
+
final Expando<Future<Null>> _nullFutures = Expando<Future<Null>>();
/// A default hash function used by the platform in various places.
diff --git a/tests/lib/async/null_future_zone_test.dart b/tests/lib/async/null_future_zone_test.dart
index 34201e7..c74554b 100644
--- a/tests/lib/async/null_future_zone_test.dart
+++ b/tests/lib/async/null_future_zone_test.dart
@@ -16,6 +16,7 @@
bool nullFutureZoneUsed = false;
runZoned(() {
+ // Known code that exposes the special "nullFuture".
nullFuture = (new StreamController()..stream.listen(null).cancel()).done;
}, zoneSpecification: new ZoneSpecification(scheduleMicrotask:
(Zone self, ZoneDelegate parent, Zone zone, void f()) {
diff --git a/tests/lib/isolate/package_resolve_test.dart b/tests/lib/isolate/package_resolve_test.dart
index 3199de7..22740d9 100644
--- a/tests/lib/isolate/package_resolve_test.dart
+++ b/tests/lib/isolate/package_resolve_test.dart
@@ -8,11 +8,6 @@
final packageUriToResolve = "package:foo/bar.dart";
final packageResolvedUri = "file:///no/such/directory/lib/bar.dart";
-final dotPackages = """
-# This is the content of a .packages file.
-foo:file:///no/such/directory/lib/
-""";
-
final packageConfigJson = """
{
"configVersion": 2,
@@ -32,7 +27,6 @@
testPackageResolution(port);
return;
}
- await runTest(dotPackages);
await runTest(packageConfigJson);
}
diff --git a/tests/lib/isolate/scenarios/package_data_uri_spec/package_resolve_test.dart b/tests/lib/isolate/scenarios/package_data_uri_spec/package_resolve_test.dart
index 3199de7..22740d9 100644
--- a/tests/lib/isolate/scenarios/package_data_uri_spec/package_resolve_test.dart
+++ b/tests/lib/isolate/scenarios/package_data_uri_spec/package_resolve_test.dart
@@ -8,11 +8,6 @@
final packageUriToResolve = "package:foo/bar.dart";
final packageResolvedUri = "file:///no/such/directory/lib/bar.dart";
-final dotPackages = """
-# This is the content of a .packages file.
-foo:file:///no/such/directory/lib/
-""";
-
final packageConfigJson = """
{
"configVersion": 2,
@@ -32,7 +27,6 @@
testPackageResolution(port);
return;
}
- await runTest(dotPackages);
await runTest(packageConfigJson);
}
diff --git a/tests/lib/isolate/spawn_uri__package_uri__test.dart b/tests/lib/isolate/spawn_uri__package_uri__test.dart
index b212874..b502a5f 100644
--- a/tests/lib/isolate/spawn_uri__package_uri__test.dart
+++ b/tests/lib/isolate/spawn_uri__package_uri__test.dart
@@ -21,8 +21,6 @@
print('TEST spawnWithPackageConfig = $spawnWithPackageConfig ');
final bool checkForResolveUri =
runWithPackagesArg || !spawnWithPackageConfig;
- futures.add(runDotPackagesTest(
- runWithPackagesArg, spawnWithPackageConfig, checkForResolveUri));
for (final optionalPackageUri in const [true, false]) {
print('TEST optionalPackageUri = $optionalPackageUri');
futures.add(runPackageConfigTest(runWithPackagesArg,
@@ -42,41 +40,6 @@
}, spawnWithArg, optionalPackageUri, checkForResolveUri);
}
-Future runDotPackagesTest(
- bool withPackagesArg, bool spawnWithArg, bool checkForResolveUri) async {
- await withApplicationDirAndDotPackages(
- (String tempDir, String dotPackagesFile, String mainFile) async {
- final args = [
- if (withPackagesArg) '--packages=$dotPackagesFile',
- mainFile,
- ];
- await run(executable, args);
- }, spawnWithArg, checkForResolveUri);
-}
-
-Future withApplicationDirAndDotPackages(
- Future fn(String tempDir, String packagesDir, String mainFile),
- bool spawnWithArg,
- bool checkForResolveUri) async {
- await withTempDir((String tempDir) async {
- // Setup ".packages"
- final dotPackagesFile =
- path.join(tempDir, spawnWithArg ? 'baz.packages' : '.packages');
- await File(dotPackagesFile).writeAsString(buildDotPackages('foo'));
-
- final mainFile = path.join(tempDir, 'main.dart');
- final childIsolateFile = path.join(tempDir, 'child_isolate.dart');
- final importUri = 'package:foo/child_isolate.dart';
- await File(childIsolateFile).writeAsString(buildChildIsolate());
- await File(mainFile).writeAsString(buildMainIsolate(
- importUri,
- spawnWithArg ? dotPackagesFile : null,
- checkForResolveUri ? childIsolateFile : null));
-
- await fn(tempDir, dotPackagesFile, mainFile);
- });
-}
-
Future withApplicationDirAndDotDartToolPackageConfig(
Future fn(String tempDir, String packageJson, String mainFile),
bool spawnWithArg,
diff --git a/tests/lib_2/isolate/package_resolve_test.dart b/tests/lib_2/isolate/package_resolve_test.dart
index 057c5df..b315b40 100644
--- a/tests/lib_2/isolate/package_resolve_test.dart
+++ b/tests/lib_2/isolate/package_resolve_test.dart
@@ -10,11 +10,6 @@
final packageUriToResolve = "package:foo/bar.dart";
final packageResolvedUri = "file:///no/such/directory/lib/bar.dart";
-final dotPackages = """
-# This is the content of a .packages file.
-foo:file:///no/such/directory/lib/
-""";
-
final packageConfigJson = """
{
"configVersion": 2,
@@ -34,7 +29,6 @@
testPackageResolution(port);
return;
}
- await runTest(dotPackages);
await runTest(packageConfigJson);
}
diff --git a/tests/lib_2/isolate/scenarios/package_data_uri_spec/package_resolve_test.dart b/tests/lib_2/isolate/scenarios/package_data_uri_spec/package_resolve_test.dart
index 057c5df..b315b40 100644
--- a/tests/lib_2/isolate/scenarios/package_data_uri_spec/package_resolve_test.dart
+++ b/tests/lib_2/isolate/scenarios/package_data_uri_spec/package_resolve_test.dart
@@ -10,11 +10,6 @@
final packageUriToResolve = "package:foo/bar.dart";
final packageResolvedUri = "file:///no/such/directory/lib/bar.dart";
-final dotPackages = """
-# This is the content of a .packages file.
-foo:file:///no/such/directory/lib/
-""";
-
final packageConfigJson = """
{
"configVersion": 2,
@@ -34,7 +29,6 @@
testPackageResolution(port);
return;
}
- await runTest(dotPackages);
await runTest(packageConfigJson);
}
diff --git a/tests/lib_2/isolate/scenarios/package_relative_root/.dart_tool/package_config.json b/tests/lib_2/isolate/scenarios/package_relative_root/.dart_tool/package_config.json
new file mode 100644
index 0000000..899389f
--- /dev/null
+++ b/tests/lib_2/isolate/scenarios/package_relative_root/.dart_tool/package_config.json
@@ -0,0 +1,13 @@
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": "../packages/foo"
+ },
+ {
+ "name": "bar",
+ "rootUri": "../packages/bar"
+ }
+ ]
+}
diff --git a/tests/lib_2/isolate/scenarios/package_relative_root/.packages b/tests/lib_2/isolate/scenarios/package_relative_root/.packages
deleted file mode 100644
index 32bc5eee..0000000
--- a/tests/lib_2/isolate/scenarios/package_relative_root/.packages
+++ /dev/null
@@ -1,2 +0,0 @@
-foo:packages/foo
-bar:packages/bar
diff --git a/tests/lib_2/isolate/scenarios/package_relative_spec/.dart_tool/package_config.json b/tests/lib_2/isolate/scenarios/package_relative_spec/.dart_tool/package_config.json
new file mode 100644
index 0000000..96d8ed7
--- /dev/null
+++ b/tests/lib_2/isolate/scenarios/package_relative_spec/.dart_tool/package_config.json
@@ -0,0 +1,13 @@
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": "../foo_package"
+ },
+ {
+ "name": "bar",
+ "rootUri": "../bar1_package"
+ }
+ ]
+}
diff --git a/tests/lib_2/isolate/scenarios/package_relative_spec/.packages b/tests/lib_2/isolate/scenarios/package_relative_spec/.packages
deleted file mode 100644
index d7a0d92..0000000
--- a/tests/lib_2/isolate/scenarios/package_relative_spec/.packages
+++ /dev/null
@@ -1,4 +0,0 @@
-# This is the package spec for the spawning isolate.
-
-foo:foo_package/
-bar:bar1_package/
diff --git a/tests/lib_2/isolate/scenarios/package_relative_spec/bar1_package/package.config b/tests/lib_2/isolate/scenarios/package_relative_spec/bar1_package/package.config
index b580fe3..b72b9b3 100644
--- a/tests/lib_2/isolate/scenarios/package_relative_spec/bar1_package/package.config
+++ b/tests/lib_2/isolate/scenarios/package_relative_spec/bar1_package/package.config
@@ -1,4 +1,13 @@
-# This is the package spec for the spawned isolate.
-
-foo:../foo_package/
-bar:../bar2_package/
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": "../foo_package"
+ },
+ {
+ "name": "bar",
+ "rootUri": "../bar2_package"
+ }
+ ]
+}
diff --git a/tests/lib_2/isolate/scenarios/short_package/.dart_tool/package_config.json b/tests/lib_2/isolate/scenarios/short_package/.dart_tool/package_config.json
new file mode 100644
index 0000000..a806459
--- /dev/null
+++ b/tests/lib_2/isolate/scenarios/short_package/.dart_tool/package_config.json
@@ -0,0 +1,9 @@
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "flu",
+ "rootUri": "../flu_package"
+ }
+ ]
+}
diff --git a/tests/lib_2/isolate/scenarios/short_package/.packages b/tests/lib_2/isolate/scenarios/short_package/.packages
deleted file mode 100644
index 324934c..0000000
--- a/tests/lib_2/isolate/scenarios/short_package/.packages
+++ /dev/null
@@ -1 +0,0 @@
-flu:flu_package/
diff --git a/tests/lib_2/isolate/spawn_uri__package_uri__test.dart b/tests/lib_2/isolate/spawn_uri__package_uri__test.dart
index 23d4707..c06ea40 100644
--- a/tests/lib_2/isolate/spawn_uri__package_uri__test.dart
+++ b/tests/lib_2/isolate/spawn_uri__package_uri__test.dart
@@ -23,8 +23,6 @@
print('TEST spawnWithPackageConfig = $spawnWithPackageConfig ');
final bool checkForResolveUri =
runWithPackagesArg || !spawnWithPackageConfig;
- futures.add(runDotPackagesTest(
- runWithPackagesArg, spawnWithPackageConfig, checkForResolveUri));
for (final optionalPackageUri in const [true, false]) {
print('TEST optionalPackageUri = $optionalPackageUri');
futures.add(runPackageConfigTest(runWithPackagesArg,
@@ -44,41 +42,6 @@
}, spawnWithArg, optionalPackageUri, checkForResolveUri);
}
-Future runDotPackagesTest(
- bool withPackagesArg, bool spawnWithArg, bool checkForResolveUri) async {
- await withApplicationDirAndDotPackages(
- (String tempDir, String dotPackagesFile, String mainFile) async {
- final args = [
- if (withPackagesArg) '--packages=$dotPackagesFile',
- mainFile,
- ];
- await run(executable, args);
- }, spawnWithArg, checkForResolveUri);
-}
-
-Future withApplicationDirAndDotPackages(
- Future fn(String tempDir, String packagesDir, String mainFile),
- bool spawnWithArg,
- bool checkForResolveUri) async {
- await withTempDir((String tempDir) async {
- // Setup ".packages"
- final dotPackagesFile =
- path.join(tempDir, spawnWithArg ? 'baz.packages' : '.packages');
- await File(dotPackagesFile).writeAsString(buildDotPackages('foo'));
-
- final mainFile = path.join(tempDir, 'main.dart');
- final childIsolateFile = path.join(tempDir, 'child_isolate.dart');
- final importUri = 'package:foo/child_isolate.dart';
- await File(childIsolateFile).writeAsString(buildChildIsolate());
- await File(mainFile).writeAsString(buildMainIsolate(
- importUri,
- spawnWithArg ? dotPackagesFile : null,
- checkForResolveUri ? childIsolateFile : null));
-
- await fn(tempDir, dotPackagesFile, mainFile);
- });
-}
-
Future withApplicationDirAndDotDartToolPackageConfig(
Future fn(String tempDir, String packageJson, String mainFile),
bool spawnWithArg,
diff --git a/tests/standalone/package/scenarios/empty_packages_file/.dart_tool/package_config.json b/tests/standalone/package/scenarios/empty_packages_file/.dart_tool/package_config.json
new file mode 100644
index 0000000..a774220
--- /dev/null
+++ b/tests/standalone/package/scenarios/empty_packages_file/.dart_tool/package_config.json
@@ -0,0 +1,4 @@
+{
+ "configVersion": 2,
+ "packages": []
+}
diff --git a/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_noimports_test.dart b/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_noimports_test.dart
index af76de8..ee85f40 100644
--- a/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_noimports_test.dart
+++ b/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_noimports_test.dart
@@ -2,7 +2,7 @@
// 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.
-// Packages=.packages
+// Packages=.dart_tool/package_config.json
// We expect this to not cause any errors. An empty packages file is valid,
// you should only run into problems if you try to resolve a package import.
diff --git a/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_option_test.dart b/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_option_test.dart
index fbde79f..93a1612 100644
--- a/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_option_test.dart
+++ b/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_option_test.dart
@@ -2,7 +2,7 @@
// 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.
-// Packages=.packages
+// Packages=.dart_tool/package_config.json
library empty_packages_file_option_test;
diff --git a/tests/standalone/package/scenarios/invalid/invalid_package_name.packages b/tests/standalone/package/scenarios/invalid/invalid_package_name.packages
index d74d280..664189c 100644
--- a/tests/standalone/package/scenarios/invalid/invalid_package_name.packages
+++ b/tests/standalone/package/scenarios/invalid/invalid_package_name.packages
@@ -1,2 +1,13 @@
-..:nonexistent/
-foo:foo/
\ No newline at end of file
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "..",
+ "rootUri": "nonexistent"
+ },
+ {
+ "name": "foo",
+ "rootUri": "foo"
+ }
+ ]
+}
diff --git a/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_lines.packages b/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_lines.packages
index e81099e..a8d6618 100644
--- a/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_lines.packages
+++ b/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_lines.packages
@@ -1,11 +1,18 @@
+{
+ "configVersion": 2,
+ "packages": [
+ {
+"name": "foo",
-foo:foo/
+"rootUri":"foo"},{"name":
-bar:bar/
+"bar"
+
+, "rootUri":"bar"},
@@ -13,8 +20,4 @@
-
-baz:baz/
-
-
-
+{"name": "baz", "rootUri": "baz"}]}
diff --git a/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_package_dir.packages b/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_package_dir.packages
index 0152a79..57c7d4e 100644
--- a/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_package_dir.packages
+++ b/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_package_dir.packages
@@ -1 +1,9 @@
-foo:
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": ""
+ }
+ ]
+}
diff --git a/tests/standalone/package/scenarios/packages_file_strange_formatting/mixed_line_ends.packages b/tests/standalone/package/scenarios/packages_file_strange_formatting/mixed_line_ends.packages
index c3d3e75..e5e63a7 100644
--- a/tests/standalone/package/scenarios/packages_file_strange_formatting/mixed_line_ends.packages
+++ b/tests/standalone/package/scenarios/packages_file_strange_formatting/mixed_line_ends.packages
@@ -1,3 +1,17 @@
-foo:foo/
-bar:bar/
-baz:baz/
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": "foo"
+ },
+ {
+ "name": "bar",
+ "rootUri": "bar"
+ },
+ {
+ "name": "baz",
+ "rootUri": "baz"
+ }
+ ]
+}
diff --git a/tests/standalone/package/scenarios/packages_option_only/sub/.packages b/tests/standalone/package/scenarios/packages_option_only/sub/.packages
index 17ae735..46389c5 100644
--- a/tests/standalone/package/scenarios/packages_option_only/sub/.packages
+++ b/tests/standalone/package/scenarios/packages_option_only/sub/.packages
@@ -1 +1,9 @@
-foo:foo/
\ No newline at end of file
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": "foo"
+ }
+ ]
+}
diff --git a/tests/standalone_2/http_launch_data/.dart_tool/package_config.json b/tests/standalone_2/http_launch_data/.dart_tool/package_config.json
new file mode 100644
index 0000000..6ff2893
--- /dev/null
+++ b/tests/standalone_2/http_launch_data/.dart_tool/package_config.json
@@ -0,0 +1,9 @@
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "simple",
+ "rootUri": "../the_packages/simple"
+ }
+ ]
+}
diff --git a/tests/standalone_2/http_launch_data/.packages b/tests/standalone_2/http_launch_data/.packages
deleted file mode 100644
index 4d7ff27..0000000
--- a/tests/standalone_2/http_launch_data/.packages
+++ /dev/null
@@ -1 +0,0 @@
-simple:the_packages/simple
diff --git a/tests/standalone_2/http_launch_test.dart b/tests/standalone_2/http_launch_test.dart
index 8a6d37be..15b7eda 100644
--- a/tests/standalone_2/http_launch_test.dart
+++ b/tests/standalone_2/http_launch_test.dart
@@ -9,7 +9,7 @@
// OtherResources=http_launch_data/http_launch_main.dart
// OtherResources=http_launch_data/http_spawn_main.dart
// OtherResources=http_launch_data/the_packages/simple/simple.dart
-// OtherResources=http_launch_data/.packages
+// OtherResources=http_launch_data/.dart_tool/package_config.json
//
// Test:
// *) Launching a script fetched over HTTP.
diff --git a/tests/standalone_2/package/scenarios/both_dir_dot_packages_and_package_config/.dart_tool/package_config.json b/tests/standalone_2/package/scenarios/both_dir_dot_packages_and_package_config/.dart_tool/package_config.json
new file mode 100644
index 0000000..fe79168
--- /dev/null
+++ b/tests/standalone_2/package/scenarios/both_dir_dot_packages_and_package_config/.dart_tool/package_config.json
@@ -0,0 +1,10 @@
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": "../foo2"
+ }
+ ]
+}
+
diff --git a/tests/standalone_2/package/scenarios/both_dir_and_file/.packages b/tests/standalone_2/package/scenarios/both_dir_dot_packages_and_package_config/.packages
similarity index 100%
rename from tests/standalone_2/package/scenarios/both_dir_and_file/.packages
rename to tests/standalone_2/package/scenarios/both_dir_dot_packages_and_package_config/.packages
diff --git a/tests/standalone_2/package/scenarios/both_dir_and_file/both_dir_and_file_noimports_test.dart b/tests/standalone_2/package/scenarios/both_dir_dot_packages_and_package_config/both_dir_dot_packages_and_package_config_noimports_test.dart
similarity index 79%
rename from tests/standalone_2/package/scenarios/both_dir_and_file/both_dir_and_file_noimports_test.dart
rename to tests/standalone_2/package/scenarios/both_dir_dot_packages_and_package_config/both_dir_dot_packages_and_package_config_noimports_test.dart
index 03fa700..6732641 100644
--- a/tests/standalone_2/package/scenarios/both_dir_and_file/both_dir_and_file_noimports_test.dart
+++ b/tests/standalone_2/package/scenarios/both_dir_dot_packages_and_package_config/both_dir_dot_packages_and_package_config_noimports_test.dart
@@ -6,6 +6,6 @@
// Packages=none
-library both_dir_and_file_noimports_test;
+library both_dir_dot_packages_and_package_config_noimports_test;
main() {}
diff --git a/tests/standalone_2/package/scenarios/both_dir_and_file/both_dir_and_file_noimports_test.dart b/tests/standalone_2/package/scenarios/both_dir_dot_packages_and_package_config/foo/foo.dart
similarity index 76%
copy from tests/standalone_2/package/scenarios/both_dir_and_file/both_dir_and_file_noimports_test.dart
copy to tests/standalone_2/package/scenarios/both_dir_dot_packages_and_package_config/foo/foo.dart
index 03fa700..7b46a78 100644
--- a/tests/standalone_2/package/scenarios/both_dir_and_file/both_dir_and_file_noimports_test.dart
+++ b/tests/standalone_2/package/scenarios/both_dir_dot_packages_and_package_config/foo/foo.dart
@@ -4,8 +4,6 @@
// @dart = 2.9
-// Packages=none
+library foo;
-library both_dir_and_file_noimports_test;
-
-main() {}
+String bar = 'dot packages';
diff --git a/tests/standalone_2/package/scenarios/both_dir_and_file/foo/foo.dart b/tests/standalone_2/package/scenarios/both_dir_dot_packages_and_package_config/foo2/foo.dart
similarity index 100%
rename from tests/standalone_2/package/scenarios/both_dir_and_file/foo/foo.dart
rename to tests/standalone_2/package/scenarios/both_dir_dot_packages_and_package_config/foo2/foo.dart
diff --git a/tests/standalone_2/package/scenarios/both_dir_and_file/packages/foo/foo.dart b/tests/standalone_2/package/scenarios/both_dir_dot_packages_and_package_config/packages/foo/foo.dart
similarity index 100%
rename from tests/standalone_2/package/scenarios/both_dir_and_file/packages/foo/foo.dart
rename to tests/standalone_2/package/scenarios/both_dir_dot_packages_and_package_config/packages/foo/foo.dart
diff --git a/tests/standalone_2/package/scenarios/both_dir_and_file/prefers_packages_file_test.dart b/tests/standalone_2/package/scenarios/both_dir_dot_packages_and_package_config/prefers_package_config_file_test.dart
similarity index 89%
rename from tests/standalone_2/package/scenarios/both_dir_and_file/prefers_packages_file_test.dart
rename to tests/standalone_2/package/scenarios/both_dir_dot_packages_and_package_config/prefers_package_config_file_test.dart
index fb5d6db..2dac68a 100644
--- a/tests/standalone_2/package/scenarios/both_dir_and_file/prefers_packages_file_test.dart
+++ b/tests/standalone_2/package/scenarios/both_dir_dot_packages_and_package_config/prefers_package_config_file_test.dart
@@ -6,7 +6,7 @@
// Packages=none
-library prefers_packages_file_test;
+library prefers_package_config_file_test;
import 'package:foo/foo.dart' as foo;
diff --git a/tests/standalone_2/package/scenarios/empty_packages_file/.dart_tool/package_config.json b/tests/standalone_2/package/scenarios/empty_packages_file/.dart_tool/package_config.json
new file mode 100644
index 0000000..a774220
--- /dev/null
+++ b/tests/standalone_2/package/scenarios/empty_packages_file/.dart_tool/package_config.json
@@ -0,0 +1,4 @@
+{
+ "configVersion": 2,
+ "packages": []
+}
diff --git a/tests/standalone_2/package/scenarios/empty_packages_file/.packages b/tests/standalone_2/package/scenarios/empty_packages_file/.packages
deleted file mode 100644
index e69de29..0000000
--- a/tests/standalone_2/package/scenarios/empty_packages_file/.packages
+++ /dev/null
diff --git a/tests/standalone_2/package/scenarios/empty_packages_file/empty_packages_file_noimports_test.dart b/tests/standalone_2/package/scenarios/empty_packages_file/empty_packages_file_noimports_test.dart
index d539707..ffbc43a 100644
--- a/tests/standalone_2/package/scenarios/empty_packages_file/empty_packages_file_noimports_test.dart
+++ b/tests/standalone_2/package/scenarios/empty_packages_file/empty_packages_file_noimports_test.dart
@@ -4,7 +4,7 @@
// @dart = 2.9
-// Packages=.packages
+// Packages=.dart_tool/package_config.json
// We expect this to not cause any errors. An empty packages file is valid,
// you should only run into problems if you try to resolve a package import.
diff --git a/tests/standalone_2/package/scenarios/empty_packages_file/empty_packages_file_option_test.dart b/tests/standalone_2/package/scenarios/empty_packages_file/empty_packages_file_option_test.dart
index 708d8bb..9fd360b 100644
--- a/tests/standalone_2/package/scenarios/empty_packages_file/empty_packages_file_option_test.dart
+++ b/tests/standalone_2/package/scenarios/empty_packages_file/empty_packages_file_option_test.dart
@@ -4,7 +4,7 @@
// @dart = 2.9
-// Packages=.packages
+// Packages=.dart_tool/package_config.json
library empty_packages_file_option_test;
diff --git a/tests/standalone_2/package/scenarios/invalid/invalid_package_name.packages b/tests/standalone_2/package/scenarios/invalid/invalid_package_name.packages
index d74d280..664189c 100644
--- a/tests/standalone_2/package/scenarios/invalid/invalid_package_name.packages
+++ b/tests/standalone_2/package/scenarios/invalid/invalid_package_name.packages
@@ -1,2 +1,13 @@
-..:nonexistent/
-foo:foo/
\ No newline at end of file
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "..",
+ "rootUri": "nonexistent"
+ },
+ {
+ "name": "foo",
+ "rootUri": "foo"
+ }
+ ]
+}
diff --git a/tests/standalone_2/package/scenarios/packages_file_in_parent/.dart_tool/package_config.json b/tests/standalone_2/package/scenarios/packages_file_in_parent/.dart_tool/package_config.json
new file mode 100644
index 0000000..5eeda62
--- /dev/null
+++ b/tests/standalone_2/package/scenarios/packages_file_in_parent/.dart_tool/package_config.json
@@ -0,0 +1,9 @@
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": "../foo"
+ }
+ ]
+}
diff --git a/tests/standalone_2/package/scenarios/packages_file_in_parent/.packages b/tests/standalone_2/package/scenarios/packages_file_in_parent/.packages
deleted file mode 100644
index 17ae735..0000000
--- a/tests/standalone_2/package/scenarios/packages_file_in_parent/.packages
+++ /dev/null
@@ -1 +0,0 @@
-foo:foo/
\ No newline at end of file
diff --git a/tests/standalone_2/package/scenarios/packages_file_only/.dart_tool/package_config.json b/tests/standalone_2/package/scenarios/packages_file_only/.dart_tool/package_config.json
new file mode 100644
index 0000000..5eeda62
--- /dev/null
+++ b/tests/standalone_2/package/scenarios/packages_file_only/.dart_tool/package_config.json
@@ -0,0 +1,9 @@
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": "../foo"
+ }
+ ]
+}
diff --git a/tests/standalone_2/package/scenarios/packages_file_only/.packages b/tests/standalone_2/package/scenarios/packages_file_only/.packages
deleted file mode 100644
index 17ae735..0000000
--- a/tests/standalone_2/package/scenarios/packages_file_only/.packages
+++ /dev/null
@@ -1 +0,0 @@
-foo:foo/
\ No newline at end of file
diff --git a/tests/standalone_2/package/scenarios/packages_file_strange_formatting/empty_lines.packages b/tests/standalone_2/package/scenarios/packages_file_strange_formatting/empty_lines.packages
index e81099e..a8d6618 100644
--- a/tests/standalone_2/package/scenarios/packages_file_strange_formatting/empty_lines.packages
+++ b/tests/standalone_2/package/scenarios/packages_file_strange_formatting/empty_lines.packages
@@ -1,11 +1,18 @@
+{
+ "configVersion": 2,
+ "packages": [
+ {
+"name": "foo",
-foo:foo/
+"rootUri":"foo"},{"name":
-bar:bar/
+"bar"
+
+, "rootUri":"bar"},
@@ -13,8 +20,4 @@
-
-baz:baz/
-
-
-
+{"name": "baz", "rootUri": "baz"}]}
diff --git a/tests/standalone_2/package/scenarios/packages_file_strange_formatting/empty_package_dir.packages b/tests/standalone_2/package/scenarios/packages_file_strange_formatting/empty_package_dir.packages
index 0152a79..57c7d4e 100644
--- a/tests/standalone_2/package/scenarios/packages_file_strange_formatting/empty_package_dir.packages
+++ b/tests/standalone_2/package/scenarios/packages_file_strange_formatting/empty_package_dir.packages
@@ -1 +1,9 @@
-foo:
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": ""
+ }
+ ]
+}
diff --git a/tests/standalone_2/package/scenarios/packages_file_strange_formatting/mixed_line_ends.packages b/tests/standalone_2/package/scenarios/packages_file_strange_formatting/mixed_line_ends.packages
index c3d3e75..e5e63a7 100644
--- a/tests/standalone_2/package/scenarios/packages_file_strange_formatting/mixed_line_ends.packages
+++ b/tests/standalone_2/package/scenarios/packages_file_strange_formatting/mixed_line_ends.packages
@@ -1,3 +1,17 @@
-foo:foo/
-bar:bar/
-baz:baz/
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": "foo"
+ },
+ {
+ "name": "bar",
+ "rootUri": "bar"
+ },
+ {
+ "name": "baz",
+ "rootUri": "baz"
+ }
+ ]
+}
diff --git a/tests/standalone_2/package/scenarios/packages_option_only/sub/.packages b/tests/standalone_2/package/scenarios/packages_option_only/sub/.packages
index 17ae735..46389c5 100644
--- a/tests/standalone_2/package/scenarios/packages_option_only/sub/.packages
+++ b/tests/standalone_2/package/scenarios/packages_option_only/sub/.packages
@@ -1 +1,9 @@
-foo:foo/
\ No newline at end of file
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": "foo"
+ }
+ ]
+}
diff --git a/tools/VERSION b/tools/VERSION
index cc2dd56..5671960 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 18
PATCH 0
-PRERELEASE 224
+PRERELEASE 225
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/dom/src/EventStreamProvider.dart b/tools/dom/src/EventStreamProvider.dart
index 1ae6268..90b19aa 100644
--- a/tools/dom/src/EventStreamProvider.dart
+++ b/tools/dom/src/EventStreamProvider.dart
@@ -248,13 +248,13 @@
}
Future cancel() {
- if (!_canceled) {
- _unlisten();
- // Clear out the target to indicate this is complete.
- _target = null;
- _onData = null;
- }
- return Future<void>.value(null);
+ if (_canceled) return nullFuture;
+
+ _unlisten();
+ // Clear out the target to indicate this is complete.
+ _target = null;
+ _onData = null;
+ return nullFuture;
}
bool get _canceled => _target == null;