Version 2.12.0-203.0.dev
Merge commit '5c174c8d8c7ccbbbd0678f3f4d73ea3654fafa5a' into 'dev'
diff --git a/DEPS b/DEPS
index b286e0e..70da9eb 100644
--- a/DEPS
+++ b/DEPS
@@ -161,7 +161,7 @@
"typed_data_tag": "f94fc57b8e8c0e4fe4ff6cfd8290b94af52d3719",
"usage_rev": "6c64d9e7b6b3758d06d030efcb5afe20bfc04dde",
"vector_math_rev": "0c9f5d68c047813a6dcdeb88ba7a42daddf25025",
- "watcher_rev": "1e154d0900eabd5aed4b540e0416b8367e5c0248",
+ "watcher_rev": "14706140b3670ca1dfeca73480bdd3091b728ce9",
"webdriver_rev": "5a8d6805d9cf8a3cbb4fcd64849b538b7491e50e",
"web_components_rev": "8f57dac273412a7172c8ade6f361b407e2e4ed02",
"web_socket_channel_rev": "680358915e331fda823908234f80beba1ed4ec83",
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 04dc79d..2929cc2 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -72,9 +72,7 @@
static const CONVERT_INTO_IS_NOT =
AssistKind('dart.assist.convert.isNot', 30, 'Convert to is!');
static const CONVERT_INTO_IS_NOT_EMPTY = AssistKind(
- 'dart.assist.convert.isNotEmpty', 30, "Convert to 'isNotEmpty'",
- // todo (pq): unify w/ fix
- associatedErrorCodes: <String>['prefer_is_not_empty']);
+ 'dart.assist.convert.isNotEmpty', 30, "Convert to 'isNotEmpty'");
static const CONVERT_PART_OF_TO_URI = AssistKind(
'dart.assist.convert.partOfToPartUri', 30, 'Convert to use a URI');
static const CONVERT_TO_DOUBLE_QUOTED_STRING = AssistKind(
@@ -92,11 +90,9 @@
static const CONVERT_TO_INT_LITERAL = AssistKind(
'dart.assist.convert.toIntLiteral', 30, 'Convert to an int literal');
static const CONVERT_TO_LIST_LITERAL = AssistKind(
- 'dart.assist.convert.toListLiteral', 30, 'Convert to list literal',
- associatedErrorCodes: <String>['prefer_collection_literals']);
+ 'dart.assist.convert.toListLiteral', 30, 'Convert to list literal');
static const CONVERT_TO_MAP_LITERAL = AssistKind(
- 'dart.assist.convert.toMapLiteral', 30, 'Convert to map literal',
- associatedErrorCodes: <String>['prefer_collection_literals']);
+ 'dart.assist.convert.toMapLiteral', 30, 'Convert to map literal');
static const CONVERT_TO_MULTILINE_STRING = AssistKind(
'dart.assist.convert.toMultilineString',
30,
@@ -116,8 +112,7 @@
30,
'Convert to a relative import');
static const CONVERT_TO_SET_LITERAL = AssistKind(
- 'dart.assist.convert.toSetLiteral', 30, 'Convert to set literal',
- associatedErrorCodes: <String>['prefer_collection_literals']);
+ 'dart.assist.convert.toSetLiteral', 30, 'Convert to set literal');
static const CONVERT_TO_SINGLE_QUOTED_STRING = AssistKind(
'dart.assist.convert.toSingleQuotedString',
30,
diff --git a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
index 48fae93..f7fc919 100644
--- a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
@@ -39,6 +39,7 @@
import 'package:analysis_server/src/services/correction/dart/remove_empty_constructor_body.dart';
import 'package:analysis_server/src/services/correction/dart/remove_empty_else.dart';
import 'package:analysis_server/src/services/correction/dart/remove_empty_statement.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_if_null_operator.dart';
import 'package:analysis_server/src/services/correction/dart/remove_initializer.dart';
import 'package:analysis_server/src/services/correction/dart/remove_interpolation_braces.dart';
import 'package:analysis_server/src/services/correction/dart/remove_method_declaration.dart';
@@ -243,6 +244,9 @@
LintNames.unnecessary_new: [
RemoveUnnecessaryNew.newInstance,
],
+ LintNames.unnecessary_null_in_if_null_operators: [
+ RemoveIfNullOperator.newInstance,
+ ],
LintNames.unnecessary_overrides: [
RemoveMethodDeclaration.newInstance,
],
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_if_null_operator_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_if_null_operator_test.dart
new file mode 100644
index 0000000..0003079
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_if_null_operator_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2021, 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/linter/lint_names.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(UnnecessaryNullInIfNullOperatorsTest);
+ });
+}
+
+@reflectiveTest
+class UnnecessaryNullInIfNullOperatorsTest extends BulkFixProcessorTest {
+ @override
+ String get lintCode => LintNames.unnecessary_null_in_if_null_operators;
+
+ @failingTest
+ Future<void> test_null_null_left() async {
+ // The fix only addresses one null and results in:
+ //
+ // var b = null ?? a;
+ //
+ // (not incorrect but not complete).
+ await resolveTestCode('''
+var a = '';
+var b = null ?? null ?? a;
+''');
+ await assertHasFix('''
+var a = '';
+var b = a;
+''');
+ }
+
+ Future<void> test_singleFile() async {
+ await resolveTestCode('''
+var a = '';
+var b = null ?? a ?? null;
+var c = a ?? null ?? null;
+''');
+ await assertHasFix('''
+var a = '';
+var b = a;
+var c = a;
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
index 14012da..0f66ec9 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
@@ -41,6 +41,7 @@
as remove_empty_constructor_body;
import 'remove_empty_else_test.dart' as remove_empty_else;
import 'remove_empty_statement_test.dart' as remove_empty_statement;
+import 'remove_if_null_operator_test.dart' as remove_if_null_operator;
import 'remove_initializer_test.dart' as remove_initializer;
import 'remove_interpolation_braces_test.dart' as remove_interpolation_braces;
import 'remove_method_declaration_test.dart' as remove_method_declaration;
@@ -99,6 +100,7 @@
remove_empty_constructor_body.main();
remove_empty_else.main();
remove_empty_statement.main();
+ remove_if_null_operator.main();
remove_interpolation_braces.main();
remove_method_declaration.main();
remove_non_null_assertion.main();
diff --git a/pkg/analyzer_plugin/lib/utilities/assist/assist.dart b/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
index d6fa2a4..28ff7fe 100644
--- a/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
+++ b/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
@@ -78,14 +78,9 @@
/// message `"Create a component named '{0}' in '{1}'"` contains two parameters.
final String message;
- /// A list of any associated error codes. Assists with associated error codes
- /// can be presented as "fixes" for the associated errors by clients.
- final List<String> associatedErrorCodes;
-
/// Initialize a newly created kind of assist to have the given [id],
- /// [priority], [message] and optionally any [associatedErrorCodes].
- const AssistKind(this.id, this.priority, this.message,
- {this.associatedErrorCodes});
+ /// [priority] and [message].
+ const AssistKind(this.id, this.priority, this.message);
@override
String toString() => id;
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index fea201a..0098e51 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -5934,7 +5934,10 @@
@override
js_ast.Expression visitLoadLibrary(LoadLibrary node) =>
- runtimeCall('loadLibrary()');
+ runtimeCall('loadLibrary(#, #)', [
+ js.string(jsLibraryName(node.import.enclosingLibrary)),
+ js.string(node.import.name)
+ ]);
// TODO(jmesserly): DDC loads all libraries eagerly.
// See
@@ -5942,7 +5945,10 @@
// https://github.com/dart-lang/sdk/issues/27777
@override
js_ast.Expression visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) =>
- js.boolean(true);
+ runtimeCall('checkDeferredIsLoaded(#, #)', [
+ js.string(jsLibraryName(node.import.enclosingLibrary)),
+ js.string(node.import.name)
+ ]);
bool _reifyFunctionType(FunctionNode f) {
if (_currentLibrary.importUri.scheme != 'dart') return true;
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index cecf9b1..4e038ae 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -2510,14 +2510,14 @@
String::Handle(String::New("get:platformScript"))));
Object& result = Object::Handle(
DartEntry::InvokeFunction(func, Object::empty_array()));
- if (result.IsUnwindError()) {
+ if (result.IsError()) {
Exceptions::PropagateError(Error::Cast(result));
}
if (!result.IsInstance()) {
FATAL1("Bad script uri hook: %s", result.ToCString());
}
result = DartLibraryCalls::ToString(Instance::Cast(result));
- if (result.IsUnwindError()) {
+ if (result.IsError()) {
Exceptions::PropagateError(Error::Cast(result));
}
if (!result.IsString()) {
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
index fd80d9c..36ebdf8 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
@@ -17,6 +17,11 @@
throw UnimplementedError(message);
}
+throwDeferredIsLoadedError(
+ @notNull String enclosingLibrary, @notNull String importPrefix) {
+ throw DeferredNotLoadedError(enclosingLibrary, importPrefix);
+}
+
// TODO(nshahan) Cleanup embeded strings and extract file location at runtime
// from the stacktrace.
assertFailed(String? message,
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
index 4a224cd..af8e2e1 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
@@ -759,11 +759,34 @@
return name;
}
+/// A map from libraries to a set of import prefixes that have been loaded.
+///
+/// Used to validate deferred library conventions.
+final deferredImports = JS<Object>('!', 'new Map()');
+
/// Emulates the implicit "loadLibrary" function provided by a deferred library.
///
-/// Libraries are not actually deferred in DDC, so this just returns a future
-/// that completes immediately.
-Future loadLibrary() => Future.value();
+/// Libraries are not actually deferred in DDC, so this just records the import
+/// for runtime validation, then returns a future that completes immediately.
+Future loadLibrary(
+ @notNull String enclosingLibrary, @notNull String importPrefix) {
+ var result = JS('', '#.get(#)', deferredImports, enclosingLibrary);
+ if (JS<bool>('', '# === void 0', result)) {
+ JS('', '#.set(#, # = new Set())', deferredImports, enclosingLibrary,
+ result);
+ }
+ JS('', '#.add(#)', result, importPrefix);
+ return Future.value();
+}
+
+void checkDeferredIsLoaded(
+ @notNull String enclosingLibrary, @notNull String importPrefix) {
+ var loaded = JS('', '#.get(#)', deferredImports, enclosingLibrary);
+ if (JS<bool>('', '# === void 0', loaded) ||
+ JS<bool>('', '!#.has(#)', loaded, importPrefix)) {
+ throwDeferredIsLoadedError(enclosingLibrary, importPrefix);
+ }
+}
/// Defines lazy statics.
///
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
index 21c6f31..e4afbf4 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
@@ -18,6 +18,7 @@
BooleanConversionAssertionError,
CastErrorImpl,
DartIterator,
+ DeferredNotLoadedError,
TypeErrorImpl,
JsLinkedHashMap,
ImmutableMap,
@@ -204,6 +205,7 @@
_cacheMaps.clear();
JS('', '#.clear()', _nullComparisonSet);
JS('', '#.clear()', constantMaps);
+ JS('', '#.clear()', deferredImports);
}
/// Marks enqueuing an async operation.
diff --git a/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart b/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart
index 94d7cf8..51eb666 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart
@@ -725,6 +725,17 @@
String toString() => "RuntimeError: $message";
}
+class DeferredNotLoadedError extends Error implements NoSuchMethodError {
+ String enclosingLibrary;
+ String importPrefix;
+
+ DeferredNotLoadedError(this.enclosingLibrary, this.importPrefix);
+
+ String toString() {
+ return 'Deferred import $importPrefix (from $enclosingLibrary) was not loaded.';
+ }
+}
+
/// Error thrown by DDC when an `assert()` fails (with or without a message).
class AssertionErrorImpl extends AssertionError {
final String? _fileUri;
diff --git a/tools/VERSION b/tools/VERSION
index 959ece6..947dc6d 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 202
+PRERELEASE 203
PRERELEASE_PATCH 0
\ No newline at end of file