Version 2.9.0-5.0.dev
Merge commit '8c96812bec49947e2e70c788568fac9e36d33814' into dev
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 9a6403f..35fc3b9 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,7 @@
"constraint, update this by running tools/generate_package_config.dart."
],
"configVersion": 2,
- "generated": "2020-03-11T09:16:09.767708",
+ "generated": "2020-04-21T17:36:03.446742",
"generator": "tools/generate_package_config.dart",
"packages": [
{
@@ -66,19 +66,18 @@
"name": "args",
"rootUri": "../third_party/pkg/args",
"packageUri": "lib/",
- "languageVersion": "2.0"
+ "languageVersion": "2.3"
},
{
"name": "async",
"rootUri": "../third_party/pkg/async",
"packageUri": "lib/",
- "languageVersion": "2.0"
+ "languageVersion": "2.2"
},
{
"name": "async_helper",
"rootUri": "../pkg/async_helper",
- "packageUri": "lib/",
- "languageVersion": "2.7"
+ "packageUri": "lib/"
},
{
"name": "bazel_worker",
@@ -117,12 +116,6 @@
"languageVersion": "2.0"
},
{
- "name": "code_transformers",
- "rootUri": "../third_party/pkg/code_transformers",
- "packageUri": "lib/",
- "languageVersion": "1.0"
- },
- {
"name": "collection",
"rootUri": "../third_party/pkg/collection",
"packageUri": "lib/",
@@ -180,7 +173,7 @@
"name": "dart_style",
"rootUri": "../third_party/pkg_tested/dart_style",
"packageUri": "lib/",
- "languageVersion": "2.3"
+ "languageVersion": "2.7"
},
{
"name": "dartdev",
@@ -192,7 +185,7 @@
"name": "dartdoc",
"rootUri": "../third_party/pkg/dartdoc",
"packageUri": "lib/",
- "languageVersion": "2.6"
+ "languageVersion": "2.7"
},
{
"name": "dartfix",
@@ -204,7 +197,7 @@
"name": "dds",
"rootUri": "../pkg/dds",
"packageUri": "lib/",
- "languageVersion": "2.3"
+ "languageVersion": "2.6"
},
{
"name": "dev_compiler",
@@ -221,8 +214,7 @@
{
"name": "expect",
"rootUri": "../pkg/expect",
- "packageUri": "lib/",
- "languageVersion": "2.0"
+ "packageUri": "lib/"
},
{
"name": "ffi",
@@ -274,12 +266,6 @@
"languageVersion": "2.7"
},
{
- "name": "func",
- "rootUri": "../third_party/pkg/func",
- "packageUri": "lib/",
- "languageVersion": "1.9"
- },
- {
"name": "gardening",
"rootUri": "../tools/gardening",
"packageUri": "lib/",
@@ -334,16 +320,10 @@
"languageVersion": "2.0"
},
{
- "name": "initialize",
- "rootUri": "../third_party/pkg/initialize",
- "packageUri": "lib/",
- "languageVersion": "1.9"
- },
- {
"name": "intl",
"rootUri": "../third_party/pkg/intl",
"packageUri": "lib/",
- "languageVersion": "2.0"
+ "languageVersion": "2.5"
},
{
"name": "js",
@@ -379,7 +359,7 @@
"name": "linter",
"rootUri": "../third_party/pkg/linter",
"packageUri": "lib/",
- "languageVersion": "2.2"
+ "languageVersion": "2.6"
},
{
"name": "logging",
@@ -406,12 +386,6 @@
"languageVersion": "1.12"
},
{
- "name": "metatest",
- "rootUri": "../third_party/pkg/metatest",
- "packageUri": "lib/",
- "languageVersion": "1.8"
- },
- {
"name": "mime",
"rootUri": "../third_party/pkg/mime",
"packageUri": "lib/",
@@ -454,12 +428,6 @@
"languageVersion": "2.0"
},
{
- "name": "observable",
- "rootUri": "../third_party/pkg/observable",
- "packageUri": "lib/",
- "languageVersion": "1.19"
- },
- {
"name": "observatory",
"rootUri": "../runtime/observatory",
"packageUri": "lib/",
@@ -471,12 +439,6 @@
"languageVersion": "2.7"
},
{
- "name": "observe",
- "rootUri": "../third_party/pkg/observe",
- "packageUri": "lib/",
- "languageVersion": "1.9"
- },
- {
"name": "package_config",
"rootUri": "../third_party/pkg_tested/package_config",
"packageUri": "lib/",
@@ -495,30 +457,12 @@
"languageVersion": "2.1"
},
{
- "name": "platform",
- "rootUri": "../third_party/pkg/platform",
- "packageUri": "lib/",
- "languageVersion": "1.24"
- },
- {
- "name": "plugin",
- "rootUri": "../third_party/pkg/plugin",
- "packageUri": "lib/",
- "languageVersion": "1.0"
- },
- {
"name": "pool",
"rootUri": "../third_party/pkg/pool",
"packageUri": "lib/",
"languageVersion": "2.0"
},
{
- "name": "process",
- "rootUri": "../third_party/pkg/process",
- "packageUri": "lib/",
- "languageVersion": "2.0"
- },
- {
"name": "protobuf",
"rootUri": "../third_party/pkg/protobuf/protobuf",
"packageUri": "lib/",
@@ -534,7 +478,7 @@
"name": "pub_semver",
"rootUri": "../third_party/pkg/pub_semver",
"packageUri": "lib/",
- "languageVersion": "1.0"
+ "languageVersion": "2.0"
},
{
"name": "quiver",
@@ -549,12 +493,6 @@
"languageVersion": "2.0"
},
{
- "name": "scheduled_test",
- "rootUri": "../third_party/pkg/scheduled_test",
- "packageUri": "lib/",
- "languageVersion": "1.22"
- },
- {
"name": "sdk_library_metadata",
"rootUri": "../sdk/lib/_internal/sdk_library_metadata",
"packageUri": "lib/",
@@ -570,13 +508,13 @@
"name": "shelf_packages_handler",
"rootUri": "../third_party/pkg/shelf_packages_handler",
"packageUri": "lib/",
- "languageVersion": "1.22"
+ "languageVersion": "2.0"
},
{
"name": "shelf_proxy",
"rootUri": "../third_party/pkg/shelf_proxy",
"packageUri": "lib/",
- "languageVersion": "2.3"
+ "languageVersion": "2.0"
},
{
"name": "shelf_static",
@@ -597,16 +535,10 @@
"languageVersion": "2.3"
},
{
- "name": "smoke",
- "rootUri": "../third_party/pkg/smoke",
- "packageUri": "lib/",
- "languageVersion": "1.12"
- },
- {
"name": "source_map_stack_trace",
"rootUri": "../third_party/pkg/source_map_stack_trace",
"packageUri": "lib/",
- "languageVersion": "1.8"
+ "languageVersion": "2.7"
},
{
"name": "source_maps",
@@ -672,19 +604,19 @@
"name": "test",
"rootUri": "../third_party/pkg/test/pkgs/test",
"packageUri": "lib/",
- "languageVersion": "2.2"
+ "languageVersion": "2.7"
},
{
"name": "test_api",
"rootUri": "../third_party/pkg/test/pkgs/test_api",
"packageUri": "lib/",
- "languageVersion": "2.1"
+ "languageVersion": "2.7"
},
{
"name": "test_core",
"rootUri": "../third_party/pkg/test/pkgs/test_core",
"packageUri": "lib/",
- "languageVersion": "2.1"
+ "languageVersion": "2.7"
},
{
"name": "test_descriptor",
@@ -723,12 +655,6 @@
"languageVersion": "2.6"
},
{
- "name": "tuple",
- "rootUri": "../third_party/pkg/tuple",
- "packageUri": "lib/",
- "languageVersion": "1.6"
- },
- {
"name": "typed_data",
"rootUri": "../third_party/pkg/typed_data",
"packageUri": "lib/",
@@ -741,12 +667,6 @@
"languageVersion": "2.0"
},
{
- "name": "utf",
- "rootUri": "../third_party/pkg/utf",
- "packageUri": "lib/",
- "languageVersion": "2.0"
- },
- {
"name": "vm",
"rootUri": "../pkg/vm",
"packageUri": "lib/",
@@ -762,7 +682,7 @@
"name": "watcher",
"rootUri": "../third_party/pkg/watcher",
"packageUri": "lib/",
- "languageVersion": "2.0"
+ "languageVersion": "2.2"
},
{
"name": "web_components",
@@ -783,4 +703,4 @@
"languageVersion": "2.0"
}
]
-}
+}
\ No newline at end of file
diff --git a/DEPS b/DEPS
index 13150cf..c9b6ebe 100644
--- a/DEPS
+++ b/DEPS
@@ -90,7 +90,7 @@
"ffi_tag": "ea88d71b043ee14b268c3aedff14e9eb32e20959",
"fixnum_tag": "eb3748663dc979271ff6a3d014fbe522543b1d91",
"glob_tag": "e9f4e6b7ae8abe5071461cf8f47191bb19cf7ef6",
- "html_tag" : "0.14.0+1",
+ "html_tag": "083a36cd801a4b787ba156b7c6e4c8b2e2daed4a",
"http_io_rev": "2fa188caf7937e313026557713f7feffedd4978b",
"http_multi_server_rev" : "ea269f79321d659208402088f3297e8920a88ee6",
"http_parser_tag" : "3.1.3",
@@ -109,13 +109,13 @@
"matcher_tag": "af4fe7daf8e94a46981e4f072872be550a6969e9",
"mime_tag": "179b5e6a88f4b63f36dc1b8fcbc1e83e5e0cd3a7",
"mockito_tag": "d39ac507483b9891165e422ec98d9fb480037c8b",
- "mustache_tag" : "5e81b12215566dbe2473b2afd01a8a8aedd56ad9",
- "oauth2_tag": "1.2.1",
+ "mustache_tag": "664737ecad027e6b96d0d1e627257efa0e46fcb1",
+ "oauth2_tag": "1.6.0",
"package_config_tag": "v1.9.2",
"path_tag": "1.7.0",
"pedantic_tag": "v1.9.0",
"ply_rev": "604b32590ffad5cbb82e4afef1d305512d06ae93",
- "pool_tag": "1.3.6",
+ "pool_tag": "86fbb2cde9bbc66c8d159909d2f65a5981ea5b50",
"protobuf_rev": "3746c8fd3f2b0147623a8e3db89c3ff4330de760",
"pub_rev": "3606265962da4248d34d352aa3d170aae4496a90",
"pub_semver_tag": "v1.4.4",
@@ -130,7 +130,7 @@
"shelf_web_socket_tag": "0.2.2+3",
"source_map_stack_trace_tag": "2.0.0",
"source_maps-0.9.4_rev": "38524",
- "source_maps_tag": "8af7cc1a1c3a193c1fba5993ce22a546a319c40e",
+ "source_maps_tag": "87b4fd9027378bbd51b02e9d7df794eee8a82b7a",
"source_span_tag": "1.7.0",
"stack_trace_tag": "1.9.3",
"stagehand_tag": "v3.3.7",
@@ -138,7 +138,7 @@
"string_scanner_tag": "1.0.3",
"test_descriptor_tag": "1.1.1",
"test_process_tag": "1.0.3",
- "term_glyph_tag": "1.0.1",
+ "term_glyph_tag": "b3da31e9684a99cfe5f192b89914492018b44da7",
"test_reflective_loader_tag": "0.1.9",
"test_tag": "test_core-v0.3.2",
"tflite_native_rev": "3c777c40608a2a9f1427bfe0028ab48e7116b4c1",
@@ -146,9 +146,9 @@
"usage_tag": "3.4.0",
"watcher_rev": "fc3c9aae5d31d707b3013b42634dde8d8a1161b4",
"web_components_rev": "8f57dac273412a7172c8ade6f361b407e2e4ed02",
- "web_socket_channel_tag": "1.1.0",
+ "web_socket_channel_tag": "490061ef0e22d3c8460ad2802f9948219365ad6b",
"WebCore_rev": "fb11e887f77919450e497344da570d780e078bc8",
- "yaml_tag": "2.2.0",
+ "yaml_tag": "62e9f6b3a933b1f76dd3007d1a5ce0be8e429b2d",
"zlib_rev": "c44fb7248079cc3d5563b14b3f758aee60d6b415",
"crashpad_rev": "bf327d8ceb6a669607b0dbab5a83a275d03f99ed",
"minichromium_rev": "8d641e30a8b12088649606b912c2bc4947419ccc",
diff --git a/benchmarks/RuntimeType/dart/RuntimeType.dart b/benchmarks/RuntimeType/dart/RuntimeType.dart
new file mode 100644
index 0000000..fe21b30
--- /dev/null
+++ b/benchmarks/RuntimeType/dart/RuntimeType.dart
@@ -0,0 +1,176 @@
+// 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.
+//
+// Benchmark for runtimeType patterns as used in Flutter.
+
+// ignore_for_file: prefer_const_constructors
+// ignore_for_file: avoid_function_literals_in_foreach_calls
+
+import 'dart:typed_data';
+
+import 'package:benchmark_harness/benchmark_harness.dart';
+
+abstract class Key {
+ const factory Key(String value) = ValueKey<String>;
+ const Key.empty();
+}
+
+abstract class LocalKey extends Key {
+ const LocalKey() : super.empty();
+}
+
+class ValueKey<T> extends LocalKey {
+ const ValueKey(this.value);
+ final T value;
+ @override
+ bool operator ==(Object other) {
+ if (other.runtimeType != runtimeType) return false;
+ return other is ValueKey<T> && other.value == value;
+ }
+
+ @override
+ int get hashCode => value.hashCode;
+}
+
+abstract class Widget {
+ const Widget({this.key});
+ final Key key;
+
+ @pragma('dart2js:noInline')
+ static bool canUpdate(Widget oldWidget, Widget newWidget) {
+ return oldWidget.runtimeType == newWidget.runtimeType &&
+ oldWidget.key == newWidget.key;
+ }
+}
+
+class AWidget extends Widget {
+ const AWidget({Key key}) : super(key: key);
+}
+
+class BWidget extends Widget {
+ const BWidget({Key key}) : super(key: key);
+}
+
+class CWidget extends Widget {
+ const CWidget({Key key}) : super(key: key);
+}
+
+class DWidget extends Widget {
+ const DWidget({Key key}) : super(key: key);
+}
+
+class EWidget extends Widget {
+ const EWidget({Key key}) : super(key: key);
+}
+
+class FWidget extends Widget {
+ const FWidget({Key key}) : super(key: key);
+}
+
+class WWidget<W extends Widget> extends Widget {
+ final W /*?*/ ref;
+ const WWidget({this.ref, Key key}) : super(key: key);
+}
+
+class WidgetCanUpdateBenchmark extends BenchmarkBase {
+ WidgetCanUpdateBenchmark() : super('RuntimeType.Widget.canUpdate.byType');
+
+ // All widgets have different types.
+ static List<Widget> _widgets() => [
+ AWidget(),
+ BWidget(),
+ CWidget(),
+ DWidget(),
+ EWidget(),
+ FWidget(),
+ WWidget<AWidget>(),
+ WWidget<BWidget>(ref: const BWidget()),
+ WWidget<CWidget>(ref: CWidget()),
+ const WWidget<DWidget>(ref: DWidget()),
+ ];
+ // Bulk up list to reduce loop overheads.
+ final List<Widget> widgets = _widgets() + _widgets() + _widgets();
+
+ @override
+ void exercise() => run();
+
+ @override
+ void run() {
+ for (var w1 in widgets) {
+ for (var w2 in widgets) {
+ if (Widget.canUpdate(w1, w2) != Widget.canUpdate(w2, w1)) {
+ throw 'Hmm $w1 $w2';
+ }
+ }
+ }
+ }
+
+ // Normalize by number of calls to [Widgets.canUpdate].
+ @override
+ double measure() => super.measure() / (widgets.length * widgets.length * 2);
+}
+
+class ValueKeyEqualBenchmark extends BenchmarkBase {
+ ValueKeyEqualBenchmark() : super('RuntimeType.Widget.canUpdate.byKey');
+
+ // All widgets the same class but distinguished on keys.
+ static List<Widget> _widgets() => [
+ AWidget(),
+ AWidget(key: ValueKey(1)),
+ AWidget(key: ValueKey(1)),
+ AWidget(key: ValueKey(2)),
+ AWidget(key: ValueKey(2)),
+ AWidget(key: ValueKey(3)),
+ AWidget(key: ValueKey('one')),
+ AWidget(key: ValueKey('two')),
+ AWidget(key: ValueKey('three')),
+ AWidget(key: ValueKey(Duration(seconds: 5))),
+ ];
+ // Bulk up list to reduce loop overheads.
+ final List<Widget> widgets = _widgets() + _widgets() + _widgets();
+
+ @override
+ void exercise() => run();
+
+ @override
+ void run() {
+ for (var w1 in widgets) {
+ for (var w2 in widgets) {
+ if (Widget.canUpdate(w1, w2) != Widget.canUpdate(w2, w1)) {
+ throw 'Hmm $w1 $w2';
+ }
+ }
+ }
+ }
+
+ // Normalize by number of calls to [Widgets.canUpdate].
+ @override
+ double measure() => super.measure() / (widgets.length * widgets.length * 2);
+}
+
+void pollute() {
+ // Various bits of code to make environment less unrealistic.
+ void check(dynamic a, dynamic b) {
+ if (a.runtimeType != b.runtimeType) throw 'mismatch $a $b';
+ }
+
+ check(Uint8List(1), Uint8List(2)); // dart2js needs native interceptors.
+ check(Int16List(1), Int16List(2));
+ check([], []);
+ check(<bool>{}, <bool>{});
+}
+
+void main() {
+ pollute();
+
+ final benchmarks = [
+ WidgetCanUpdateBenchmark(),
+ ValueKeyEqualBenchmark(),
+ ];
+
+ // Warm up all benchmarks before running any.
+ benchmarks.forEach((bm) => bm.run());
+
+ benchmarks.forEach((bm) => bm.report());
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/factory_type_test_helper.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/factory_type_test_helper.dart
index cc28dc3..1980d46 100644
--- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/factory_type_test_helper.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/factory_type_test_helper.dart
@@ -6,6 +6,7 @@
Type futureNone(Type type);
Type futureOrNone(Type type);
+ Type get dynamicType;
Type get intNone;
Type get intQuestion;
Type get intStar;
@@ -19,6 +20,11 @@
Type get stringQuestion;
Type get stringStar;
Type get nullNone;
+ Type get voidType;
+
+ void test_dynamic() {
+ check(dynamicType, intNone, 'dynamic');
+ }
void test_futureOr() {
check(futureOrNone(intNone), intNone, 'Future<int>');
@@ -95,6 +101,10 @@
check(intStar, stringStar, 'int');
}
+ void test_void() {
+ check(voidType, intNone, 'void');
+ }
+
Type factor(Type T, Type S);
void expect(Type T, Type S, String actualResult, String expectedResult);
diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
index fbacec0..b274629 100644
--- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
@@ -1376,26 +1376,65 @@
if (info.writeCaptured) {
return new ExpressionInfo<Variable, Type>(this, this, this);
}
+
Type previousType = info.promotedTypes?.last;
previousType ??= typeOperations.variableType(variable);
- Type type = typeOperations.promoteToNonNull(previousType);
- if (typeOperations.isSameType(type, previousType)) {
+
+ Type newType = typeOperations.promoteToNonNull(previousType);
+ if (typeOperations.isSameType(newType, previousType)) {
return new ExpressionInfo<Variable, Type>(this, this, this);
}
- assert(typeOperations.isSubtypeOf(type, previousType));
- return _finishTypeTest(typeOperations, variable, info, type);
+ assert(typeOperations.isSubtypeOf(newType, previousType));
+
+ FlowModel<Variable, Type> modelIfSuccessful =
+ _finishTypeTest(typeOperations, variable, info, null, newType);
+
+ FlowModel<Variable, Type> modelIfFailed = this;
+
+ return new ExpressionInfo<Variable, Type>(
+ this, modelIfSuccessful, modelIfFailed);
}
- /// Returns an [ExpressionInfo] indicating the result of checking whether the
- /// given [variable] satisfies the given [type], e.g. as a consequence of an
- /// `is` expression as the condition of an `if` statement.
+ /// Returns an [ExpressionInfo] indicating the result of casting the given
+ /// [variable] to the given [type], as a consequence of an `as` expression.
///
/// Note that the state is only changed if [type] is a subtype of the
/// variable's previous (possibly promoted) type.
///
/// TODO(paulberry): if the type is non-nullable, should this method mark the
/// variable as definitely assigned? Does it matter?
- ExpressionInfo<Variable, Type> tryPromote(
+ FlowModel<Variable, Type> tryPromoteForTypeCast(
+ TypeOperations<Variable, Type> typeOperations,
+ Variable variable,
+ Type type) {
+ VariableModel<Type> info = infoFor(variable);
+ if (info.writeCaptured) {
+ return this;
+ }
+
+ Type previousType = info.promotedTypes?.last;
+ previousType ??= typeOperations.variableType(variable);
+
+ Type newType = typeOperations.tryPromoteToType(type, previousType);
+ if (newType == null || typeOperations.isSameType(newType, previousType)) {
+ return this;
+ }
+
+ assert(typeOperations.isSubtypeOf(newType, previousType),
+ "Expected $newType to be a subtype of $previousType.");
+ return _finishTypeTest(typeOperations, variable, info, type, newType);
+ }
+
+ /// Returns an [ExpressionInfo] indicating the result of checking whether the
+ /// given [variable] satisfies the given [type], e.g. as a consequence of an
+ /// `is` expression as the condition of an `if` statement.
+ ///
+ /// Note that the "ifTrue" state is only changed if [type] is a subtype of
+ /// the variable's previous (possibly promoted) type.
+ ///
+ /// TODO(paulberry): if the type is non-nullable, should this method mark the
+ /// variable as definitely assigned? Does it matter?
+ ExpressionInfo<Variable, Type> tryPromoteForTypeCheck(
TypeOperations<Variable, Type> typeOperations,
Variable variable,
Type type) {
@@ -1403,16 +1442,29 @@
if (info.writeCaptured) {
return new ExpressionInfo<Variable, Type>(this, this, this);
}
+
Type previousType = info.promotedTypes?.last;
previousType ??= typeOperations.variableType(variable);
- Type newType = typeOperations.tryPromoteToType(type, previousType);
- if (newType == null || typeOperations.isSameType(newType, previousType)) {
- return new ExpressionInfo<Variable, Type>(this, this, this);
+ FlowModel<Variable, Type> modelIfSuccessful = this;
+ Type typeIfSuccess = typeOperations.tryPromoteToType(type, previousType);
+ if (typeIfSuccess != null &&
+ !typeOperations.isSameType(typeIfSuccess, previousType)) {
+ assert(typeOperations.isSubtypeOf(typeIfSuccess, previousType),
+ "Expected $typeIfSuccess to be a subtype of $previousType.");
+ modelIfSuccessful =
+ _finishTypeTest(typeOperations, variable, info, type, typeIfSuccess);
}
- assert(typeOperations.isSubtypeOf(newType, previousType),
- "Expected $newType to be a subtype of $previousType.");
- return _finishTypeTest(typeOperations, variable, info, newType);
+
+ Type factoredType = typeOperations.factor(previousType, type);
+ Type typeIfFailed = typeOperations.isSameType(factoredType, previousType)
+ ? null
+ : factoredType;
+ FlowModel<Variable, Type> modelIfFailed =
+ _finishTypeTest(typeOperations, variable, info, type, typeIfFailed);
+
+ return new ExpressionInfo<Variable, Type>(
+ this, modelIfSuccessful, modelIfFailed);
}
/// Updates the state to indicate that an assignment was made to the given
@@ -1431,38 +1483,43 @@
return _updateVariableInfo(variable, newInfoForVar);
}
- /// Common algorithm for [tryMarkNonNullable] and [tryPromote]. Builds an
- /// [ExpressionInfo] object describing the effect of trying to promote
- /// [variable] to [testedType], under the following preconditions:
+ /// Common algorithm for [tryMarkNonNullable], [tryPromoteForTypeCast],
+ /// and [tryPromoteForTypeCheck]. Builds a [FlowModel] object describing the
+ /// effect of updating the [variable] by adding the [testedType] to the
+ /// list of tested types (if not `null`, and not there already), adding the
+ /// [promotedType] to the chain of promoted types.
+ ///
+ /// Preconditions:
/// - [info] should be the result of calling `infoFor(variable)`
- /// - [testedType] should be a subtype of the currently-promoted type (i.e.
+ /// - [promotedType] should be a subtype of the currently-promoted type (i.e.
/// no redundant or side-promotions)
/// - The variable should not be write-captured.
- ExpressionInfo<Variable, Type> _finishTypeTest(
- TypeOperations<Variable, Type> typeOperations,
- Variable variable,
- VariableModel<Type> info,
- Type testedType) {
- List<Type> newPromotedTypes =
- VariableModel._addToPromotedTypes(info.promotedTypes, testedType);
- List<Type> newTested = VariableModel._addTypeToUniqueList(
- info.tested, testedType, typeOperations);
- FlowModel<Variable, Type> modelIfFailed = identical(newTested, info.tested)
+ FlowModel<Variable, Type> _finishTypeTest(
+ TypeOperations<Variable, Type> typeOperations,
+ Variable variable,
+ VariableModel<Type> info,
+ Type testedType,
+ Type promotedType,
+ ) {
+ List<Type> newTested = info.tested;
+ if (testedType != null) {
+ newTested = VariableModel._addTypeToUniqueList(
+ info.tested, testedType, typeOperations);
+ }
+
+ List<Type> newPromotedTypes = info.promotedTypes;
+ if (promotedType != null) {
+ newPromotedTypes =
+ VariableModel._addToPromotedTypes(info.promotedTypes, promotedType);
+ }
+
+ return identical(newTested, info.tested) &&
+ identical(newPromotedTypes, info.promotedTypes)
? this
: _updateVariableInfo(
variable,
- new VariableModel<Type>(info.promotedTypes, newTested,
- info.assigned, info.unassigned, info.writeCaptured));
- FlowModel<Variable, Type> modelIfSuccessful =
- identical(newPromotedTypes, info.promotedTypes) &&
- identical(newTested, info.tested)
- ? this
- : _updateVariableInfo(
- variable,
- new VariableModel<Type>(newPromotedTypes, newTested,
- info.assigned, info.unassigned, info.writeCaptured));
- return new ExpressionInfo<Variable, Type>(
- this, modelIfSuccessful, modelIfFailed);
+ new VariableModel<Type>(newPromotedTypes, newTested, info.assigned,
+ info.unassigned, info.writeCaptured));
}
/// Returns a new [FlowModel] where the information for [variable] is replaced
@@ -1579,6 +1636,10 @@
/// Operations on types, abstracted from concrete type interfaces.
abstract class TypeOperations<Variable, Type> {
+ /// Returns the "remainder" of [from] when [what] has been removed from
+ /// consideration by an instance check.
+ Type factor(Type from, Type what);
+
/// Returns `true` if [type1] and [type2] are the same type.
bool isSameType(Type type1, Type type2);
@@ -2160,7 +2221,7 @@
} else {
return;
}
- _current = _current.tryPromote(typeOperations, variable, type).ifTrue;
+ _current = _current.tryPromoteForTypeCast(typeOperations, variable, type);
}
@override
@@ -2468,7 +2529,7 @@
return;
}
ExpressionInfo<Variable, Type> expressionInfo =
- _current.tryPromote(typeOperations, variable, type);
+ _current.tryPromoteForTypeCheck(typeOperations, variable, type);
_storeExpressionInfo(isExpression,
isNot ? ExpressionInfo.invert(expressionInfo) : expressionInfo);
}
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index ae5b0e2..4c34d93 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -2908,29 +2908,33 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(
+ String string,
String
- string)> templateExperimentNotEnabled = const Template<
- Message Function(String string)>(
+ string2)> templateExperimentNotEnabled = const Template<
+ Message Function(String string, String string2)>(
messageTemplate:
- r"""This requires the '#string' experiment to be enabled.""",
+ r"""This requires the '#string' language feature to be enabled.""",
tipTemplate:
- r"""Try enabling this experiment by adding it to the command line when compiling and running.""",
+ r"""Try updating your pubspec.yaml to set the minimum SDK constraint to #string2 or higher, and running 'pub get'.""",
withArguments: _withArgumentsExperimentNotEnabled);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String string)> codeExperimentNotEnabled =
- const Code<Message Function(String string)>(
+const Code<Message Function(String string, String string2)>
+ codeExperimentNotEnabled =
+ const Code<Message Function(String string, String string2)>(
"ExperimentNotEnabled", templateExperimentNotEnabled,
index: 48);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsExperimentNotEnabled(String string) {
+Message _withArgumentsExperimentNotEnabled(String string, String string2) {
if (string.isEmpty) throw 'No string provided';
+ if (string2.isEmpty) throw 'No string provided';
return new Message(codeExperimentNotEnabled,
- message: """This requires the '${string}' experiment to be enabled.""",
+ message:
+ """This requires the '${string}' language feature to be enabled.""",
tip:
- """Try enabling this experiment by adding it to the command line when compiling and running.""",
- arguments: {'string': string});
+ """Try updating your pubspec.yaml to set the minimum SDK constraint to ${string2} or higher, and running 'pub get'.""",
+ arguments: {'string': string, 'string2': string2});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
index 45ed3dbd0..0877766 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
@@ -1213,7 +1213,7 @@
void reportVarianceModifierNotEnabled(Token variance) {
if (variance != null) {
handleRecoverableError(
- templateExperimentNotEnabled.withArguments('variance'),
+ templateExperimentNotEnabled.withArguments('variance', '2.9'),
variance,
variance);
}
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
index b3ad6f5..13ab757 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -2482,7 +2482,7 @@
reportRecoverableError(
beforeType.next,
codes.templateExperimentNotEnabled
- .withArguments('extension-methods'));
+ .withArguments('extension-methods', '2.6'));
token = rewriter.insertSyntheticToken(token, TokenType.SEMICOLON);
} else {
token = ensureSemicolon(token);
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
index 8676e22..16800f0 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
@@ -789,10 +789,14 @@
});
});
- void _checkIs(String declaredType, String tryPromoteType,
- String expectedPromotedType) {
+ void _checkIs(
+ String declaredType,
+ String tryPromoteType,
+ String expectedPromotedTypeThen,
+ String expectedPromotedTypeElse,
+ ) {
var h = _Harness();
- var x = h.addVar('x', 'int?');
+ var x = h.addVar('x', declaredType);
h.run((flow) {
h.declare(x, initialized: true);
var read = _Expression();
@@ -800,27 +804,31 @@
var expr = _Expression();
flow.isExpression_end(expr, read, false, _Type(tryPromoteType));
flow.ifStatement_thenBegin(expr);
- if (expectedPromotedType == null) {
+ if (expectedPromotedTypeThen == null) {
expect(flow.promotedType(x), isNull);
} else {
- expect(flow.promotedType(x).type, expectedPromotedType);
+ expect(flow.promotedType(x).type, expectedPromotedTypeThen);
}
flow.ifStatement_elseBegin();
- expect(flow.promotedType(x), isNull);
+ if (expectedPromotedTypeElse == null) {
+ expect(flow.promotedType(x), isNull);
+ } else {
+ expect(flow.promotedType(x).type, expectedPromotedTypeElse);
+ }
flow.ifStatement_end(true);
});
}
test('isExpression_end promotes to a subtype', () {
- _checkIs('int?', 'int', 'int');
+ _checkIs('int?', 'int', 'int', 'Never?');
});
test('isExpression_end does not promote to a supertype', () {
- _checkIs('int', 'int?', null);
+ _checkIs('int', 'int?', null, 'Never');
});
test('isExpression_end does not promote to an unrelated type', () {
- _checkIs('int', 'String', null);
+ _checkIs('int', 'String', null, null);
});
test('isExpression_end() does not promote write-captured vars', () {
@@ -1748,32 +1756,32 @@
});
});
- group('promote', () {
+ group('tryPromoteForTypeCheck', () {
test('unpromoted -> unchanged (same)', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true);
- var s2 = s1.tryPromote(h, intVar, _Type('int')).ifTrue;
+ var s2 = s1.tryPromoteForTypeCheck(h, intVar, _Type('int')).ifTrue;
expect(s2, same(s1));
});
test('unpromoted -> unchanged (supertype)', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true);
- var s2 = s1.tryPromote(h, intVar, _Type('Object')).ifTrue;
+ var s2 = s1.tryPromoteForTypeCheck(h, intVar, _Type('Object')).ifTrue;
expect(s2, same(s1));
});
test('unpromoted -> unchanged (unrelated)', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true);
- var s2 = s1.tryPromote(h, intVar, _Type('String')).ifTrue;
+ var s2 = s1.tryPromoteForTypeCheck(h, intVar, _Type('String')).ifTrue;
expect(s2, same(s1));
});
test('unpromoted -> subtype', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true);
- var s2 = s1.tryPromote(h, intQVar, _Type('int')).ifTrue;
+ var s2 = s1.tryPromoteForTypeCheck(h, intQVar, _Type('int')).ifTrue;
expect(s2.reachable, true);
expect(s2.variableInfo, {
intQVar: _matchVariableModel(chain: ['int'], ofInterest: ['int'])
@@ -1783,36 +1791,38 @@
test('promoted -> unchanged (same)', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
- .tryPromote(h, objectQVar, _Type('int'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
.ifTrue;
- var s2 = s1.tryPromote(h, objectQVar, _Type('int')).ifTrue;
+ var s2 = s1.tryPromoteForTypeCheck(h, objectQVar, _Type('int')).ifTrue;
expect(s2, same(s1));
});
test('promoted -> unchanged (supertype)', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
- .tryPromote(h, objectQVar, _Type('int'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
.ifTrue;
- var s2 = s1.tryPromote(h, objectQVar, _Type('Object')).ifTrue;
+ var s2 =
+ s1.tryPromoteForTypeCheck(h, objectQVar, _Type('Object')).ifTrue;
expect(s2, same(s1));
});
test('promoted -> unchanged (unrelated)', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
- .tryPromote(h, objectQVar, _Type('int'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
.ifTrue;
- var s2 = s1.tryPromote(h, objectQVar, _Type('String')).ifTrue;
+ var s2 =
+ s1.tryPromoteForTypeCheck(h, objectQVar, _Type('String')).ifTrue;
expect(s2, same(s1));
});
test('promoted -> subtype', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
- .tryPromote(h, objectQVar, _Type('int?'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
.ifTrue;
- var s2 = s1.tryPromote(h, objectQVar, _Type('int')).ifTrue;
+ var s2 = s1.tryPromoteForTypeCheck(h, objectQVar, _Type('int')).ifTrue;
expect(s2.reachable, true);
expect(s2.variableInfo, {
objectQVar: _matchVariableModel(
@@ -1857,7 +1867,7 @@
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
.declare(objectQVar, true)
- .tryPromote(h, objectQVar, _Type('int'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
.ifTrue;
expect(s1.variableInfo, contains(objectQVar));
var s2 = s1.write(objectQVar, _Type('int?'), h);
@@ -1875,9 +1885,9 @@
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
.declare(objectQVar, true)
- .tryPromote(h, objectQVar, _Type('num?'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
.ifTrue
- .tryPromote(h, objectQVar, _Type('int'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
.ifTrue;
expect(s1.variableInfo, {
objectQVar: _matchVariableModel(
@@ -1901,11 +1911,11 @@
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
.declare(objectQVar, true)
- .tryPromote(h, objectQVar, _Type('num?'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
.ifTrue
- .tryPromote(h, objectQVar, _Type('num'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('num'))
.ifTrue
- .tryPromote(h, objectQVar, _Type('int'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
.ifTrue;
expect(s1.variableInfo, {
objectQVar: _matchVariableModel(
@@ -1929,9 +1939,9 @@
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
.declare(objectQVar, true)
- .tryPromote(h, objectQVar, _Type('num?'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
.ifTrue
- .tryPromote(h, objectQVar, _Type('num'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('num'))
.ifTrue;
expect(s1.variableInfo, {
objectQVar: _matchVariableModel(
@@ -1949,9 +1959,9 @@
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
.declare(objectQVar, true)
- .tryPromote(h, objectQVar, _Type('num?'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
.ifTrue
- .tryPromote(h, objectQVar, _Type('num'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('num'))
.ifTrue;
expect(s1.variableInfo, {
objectQVar: _matchVariableModel(
@@ -2006,7 +2016,7 @@
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
.declare(objectQVar, true)
- .tryPromote(h, objectQVar, _Type('int?'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
.ifTrue;
expect(s1.variableInfo, {
objectQVar: _matchVariableModel(
@@ -2027,18 +2037,18 @@
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
.declare(objectQVar, true)
- .tryPromote(h, objectQVar, _Type('int?'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
.ifFalse;
expect(s1.variableInfo, {
objectQVar: _matchVariableModel(
- chain: null,
+ chain: ['Object'],
ofInterest: ['int?'],
),
});
var s2 = s1.write(objectQVar, _Type('int'), h);
expect(s2.variableInfo, {
objectQVar: _matchVariableModel(
- chain: ['int'],
+ chain: ['Object', 'int'],
ofInterest: ['int?'],
),
});
@@ -2049,14 +2059,20 @@
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
.declare(objectQVar, true)
- .tryPromote(h, objectQVar, _Type('num?'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
.ifFalse;
expect(s1.variableInfo, {
- objectQVar: _matchVariableModel(chain: null, ofInterest: ['num?'])
+ objectQVar: _matchVariableModel(
+ chain: ['Object'],
+ ofInterest: ['num?'],
+ ),
});
var s2 = s1.write(objectQVar, _Type('num?'), h);
expect(s2.variableInfo, {
- objectQVar: _matchVariableModel(chain: ['num?'], ofInterest: ['num?'])
+ objectQVar: _matchVariableModel(
+ chain: ['num?'],
+ ofInterest: ['num?'],
+ ),
});
});
@@ -2064,18 +2080,22 @@
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
.declare(objectQVar, true)
- .tryPromote(h, objectQVar, _Type('num?'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
.ifTrue
- .tryPromote(h, objectQVar, _Type('int?'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
.ifFalse;
expect(s1.variableInfo, {
- objectQVar:
- _matchVariableModel(chain: ['num?'], ofInterest: ['num?', 'int?'])
+ objectQVar: _matchVariableModel(
+ chain: ['num?', 'num'],
+ ofInterest: ['num?', 'int?'],
+ ),
});
var s2 = s1.write(objectQVar, _Type('int?'), h);
expect(s2.variableInfo, {
objectQVar: _matchVariableModel(
- chain: ['num?', 'int?'], ofInterest: ['num?', 'int?'])
+ chain: ['num?', 'int?'],
+ ofInterest: ['num?', 'int?'],
+ ),
});
});
@@ -2095,6 +2115,7 @@
h.addSubtype(_Type('A'), _Type('Object'), true);
h.addSubtype(_Type('A'), _Type('Object?'), true);
h.addSubtype(_Type('A'), _Type('A?'), true);
+ h.addSubtype(_Type('A'), _Type('B'), false);
h.addSubtype(_Type('A'), _Type('B?'), false);
h.addSubtype(_Type('A?'), _Type('Object'), false);
h.addSubtype(_Type('A?'), _Type('Object?'), true);
@@ -2114,6 +2135,12 @@
h.addSubtype(_Type('C'), _Type('A?'), true);
h.addSubtype(_Type('C'), _Type('B'), true);
h.addSubtype(_Type('C'), _Type('B?'), true);
+
+ h.addFactor(_Type('Object'), _Type('A?'), _Type('Object'));
+ h.addFactor(_Type('Object'), _Type('B?'), _Type('Object'));
+ h.addFactor(_Type('Object?'), _Type('A'), _Type('Object?'));
+ h.addFactor(_Type('Object?'), _Type('A?'), _Type('Object'));
+ h.addFactor(_Type('Object?'), _Type('B?'), _Type('Object'));
});
test('; first', () {
@@ -2121,13 +2148,13 @@
var s1 = FlowModel<_Var, _Type>(true)
.declare(x, true)
- .tryPromote(h, x, _Type('B?'))
+ .tryPromoteForTypeCheck(h, x, _Type('B?'))
.ifFalse
- .tryPromote(h, x, _Type('A?'))
+ .tryPromoteForTypeCheck(h, x, _Type('A?'))
.ifFalse;
expect(s1.variableInfo, {
x: _matchVariableModel(
- chain: null,
+ chain: ['Object'],
ofInterest: ['A?', 'B?'],
),
});
@@ -2135,7 +2162,7 @@
var s2 = s1.write(x, _Type('C'), h);
expect(s2.variableInfo, {
x: _matchVariableModel(
- chain: ['B'],
+ chain: ['Object', 'B'],
ofInterest: ['A?', 'B?'],
),
});
@@ -2146,13 +2173,13 @@
var s1 = FlowModel<_Var, _Type>(true)
.declare(x, true)
- .tryPromote(h, x, _Type('A?'))
+ .tryPromoteForTypeCheck(h, x, _Type('A?'))
.ifFalse
- .tryPromote(h, x, _Type('B?'))
+ .tryPromoteForTypeCheck(h, x, _Type('B?'))
.ifFalse;
expect(s1.variableInfo, {
x: _matchVariableModel(
- chain: null,
+ chain: ['Object'],
ofInterest: ['A?', 'B?'],
),
});
@@ -2160,7 +2187,7 @@
var s2 = s1.write(x, _Type('C'), h);
expect(s2.variableInfo, {
x: _matchVariableModel(
- chain: ['B'],
+ chain: ['Object', 'B'],
ofInterest: ['A?', 'B?'],
),
});
@@ -2171,13 +2198,13 @@
var s1 = FlowModel<_Var, _Type>(true)
.declare(x, true)
- .tryPromote(h, x, _Type('A'))
+ .tryPromoteForTypeCheck(h, x, _Type('A'))
.ifFalse
- .tryPromote(h, x, _Type('A?'))
+ .tryPromoteForTypeCheck(h, x, _Type('A?'))
.ifFalse;
expect(s1.variableInfo, {
x: _matchVariableModel(
- chain: null,
+ chain: ['Object'],
ofInterest: ['A', 'A?'],
),
});
@@ -2185,7 +2212,7 @@
var s2 = s1.write(x, _Type('B'), h);
expect(s2.variableInfo, {
x: _matchVariableModel(
- chain: ['A'],
+ chain: ['Object', 'A'],
ofInterest: ['A', 'A?'],
),
});
@@ -2197,13 +2224,13 @@
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
.declare(objectQVar, true)
- .tryPromote(h, objectQVar, _Type('num?'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
.ifFalse
- .tryPromote(h, objectQVar, _Type('num*'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('num*'))
.ifFalse;
expect(s1.variableInfo, {
objectQVar: _matchVariableModel(
- chain: null,
+ chain: ['Object'],
ofInterest: ['num?', 'num*'],
),
});
@@ -2218,13 +2245,13 @@
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
.declare(objectQVar, true)
- .tryPromote(h, objectQVar, _Type('num?'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
.ifFalse
- .tryPromote(h, objectQVar, _Type('num*'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('num*'))
.ifFalse;
expect(s1.variableInfo, {
objectQVar: _matchVariableModel(
- chain: null,
+ chain: ['Object'],
ofInterest: ['num?', 'num*'],
),
});
@@ -2273,13 +2300,13 @@
var s2 = s1.tryMarkNonNullable(h, intQVar).ifTrue;
expect(s2.reachable, true);
expect(s2.infoFor(intQVar),
- _matchVariableModel(chain: ['int'], ofInterest: ['int']));
+ _matchVariableModel(chain: ['int'], ofInterest: []));
});
test('promoted -> unchanged', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
- .tryPromote(h, objectQVar, _Type('int'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
.ifTrue;
var s2 = s1.tryMarkNonNullable(h, objectQVar).ifTrue;
expect(s2, same(s1));
@@ -2288,13 +2315,13 @@
test('promoted -> re-promoted', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
- .tryPromote(h, objectQVar, _Type('int?'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
.ifTrue;
var s2 = s1.tryMarkNonNullable(h, objectQVar).ifTrue;
expect(s2.reachable, true);
expect(s2.variableInfo, {
- objectQVar: _matchVariableModel(
- chain: ['int?', 'int'], ofInterest: ['int?', 'int'])
+ objectQVar:
+ _matchVariableModel(chain: ['int?', 'int'], ofInterest: ['int?'])
});
});
});
@@ -2412,7 +2439,7 @@
test('unchanged', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
- .tryPromote(h, objectQVar, _Type('int'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
.ifTrue;
var s2 = s1.removePromotedAll([intQVar], []);
expect(s2, same(s1));
@@ -2421,9 +2448,9 @@
test('written', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
- .tryPromote(h, objectQVar, _Type('int'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
.ifTrue
- .tryPromote(h, intQVar, _Type('int'))
+ .tryPromoteForTypeCheck(h, intQVar, _Type('int'))
.ifTrue;
var s2 = s1.removePromotedAll([intQVar], []);
expect(s2.reachable, true);
@@ -2436,9 +2463,9 @@
test('write captured', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
- .tryPromote(h, objectQVar, _Type('int'))
+ .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
.ifTrue
- .tryPromote(h, intQVar, _Type('int'))
+ .tryPromoteForTypeCheck(h, intQVar, _Type('int'))
.ifTrue;
var s2 = s1.removePromotedAll([], [intQVar]);
expect(s2.reachable, true);
@@ -2522,10 +2549,10 @@
var s0 = FlowModel<_Var, _Type>(true).declare(x, true);
var s1 = thisType == null
? s0
- : s0.tryPromote(h, x, _Type(thisType)).ifTrue;
+ : s0.tryPromoteForTypeCheck(h, x, _Type(thisType)).ifTrue;
var s2 = otherType == null
? s0
- : s0.tryPromote(h, x, _Type(otherType)).ifTrue;
+ : s0.tryPromoteForTypeCheck(h, x, _Type(otherType)).ifTrue;
var result = s1.restrict(h, s2, unsafe ? [x].toSet() : Set());
if (expectedChain == null) {
expect(result.variableInfo, contains(x));
@@ -2573,18 +2600,20 @@
var x = _Var('x', _Type('Object?'));
var initialModel = FlowModel<_Var, _Type>(true).declare(x, true);
for (var t in before) {
- initialModel = initialModel.tryPromote(h, x, _Type(t)).ifTrue;
+ initialModel =
+ initialModel.tryPromoteForTypeCheck(h, x, _Type(t)).ifTrue;
}
_checkChain(initialModel.infoFor(x).promotedTypes, before);
var tryModel = initialModel;
for (var t in inTry) {
- tryModel = tryModel.tryPromote(h, x, _Type(t)).ifTrue;
+ tryModel = tryModel.tryPromoteForTypeCheck(h, x, _Type(t)).ifTrue;
}
var expectedTryChain = before.toList()..addAll(inTry);
_checkChain(tryModel.infoFor(x).promotedTypes, expectedTryChain);
var finallyModel = initialModel;
for (var t in inFinally) {
- finallyModel = finallyModel.tryPromote(h, x, _Type(t)).ifTrue;
+ finallyModel =
+ finallyModel.tryPromoteForTypeCheck(h, x, _Type(t)).ifTrue;
}
var expectedFinallyChain = before.toList()..addAll(inFinally);
_checkChain(
@@ -3090,6 +3119,7 @@
'int <: num': true,
'int <: num?': true,
'int <: num*': true,
+ 'int <: Never?': false,
'int <: Object': true,
'int <: Object?': true,
'int <: String': false,
@@ -3121,6 +3151,12 @@
'List <: int': false,
'List <: Iterable': true,
'List <: Object': true,
+ 'Never <: int': true,
+ 'Never <: int?': true,
+ 'Never? <: int': false,
+ 'Never? <: int?': true,
+ 'Never? <: num?': true,
+ 'Never? <: Object?': true,
'Object <: int': false,
'Object <: int?': false,
'Object <: List': false,
@@ -3132,11 +3168,46 @@
'Object? <: int?': false,
'String <: int': false,
'String <: int?': false,
+ 'String <: num?': false,
'String <: Object?': true,
};
+ static final Map<String, _Type> _coreFactors = {
+ 'Object? - int': _Type('Object?'),
+ 'Object? - int?': _Type('Object'),
+ 'Object? - num?': _Type('Object'),
+ 'Object? - Object?': _Type('Never?'),
+ 'Object? - String': _Type('Object?'),
+ 'Object - int': _Type('Object'),
+ 'int - Object': _Type('Never'),
+ 'int - String': _Type('int'),
+ 'int - int': _Type('Never'),
+ 'int - int?': _Type('Never'),
+ 'int? - int': _Type('Never?'),
+ 'int? - int?': _Type('Never'),
+ 'int? - String': _Type('int?'),
+ 'num - int': _Type('num'),
+ 'num? - num': _Type('Never?'),
+ 'num? - int': _Type('num?'),
+ 'num? - int?': _Type('num'),
+ 'num? - Object': _Type('Never?'),
+ 'num? - String': _Type('num?'),
+ 'Object - int?': _Type('Object'),
+ 'Object - num': _Type('Object'),
+ 'Object - num?': _Type('Object'),
+ 'Object - num*': _Type('Object'),
+ 'Object - Iterable': _Type('Object'),
+ 'Object? - Object': _Type('Never?'),
+ 'Object? - Iterable': _Type('Object?'),
+ 'Object? - num': _Type('Object?'),
+ 'Iterable - List': _Type('Iterable'),
+ 'num* - Object': _Type('Never'),
+ };
+
final Map<String, bool> _subtypes = Map.of(_coreSubtypes);
+ final Map<String, _Type> _factorResults = Map.of(_coreFactors);
+
FlowAnalysis<_Node, _Statement, _Expression, _Var, _Type> _flow;
final _assignedVariables = AssignedVariables<_Node, _Var>();
@@ -3151,6 +3222,11 @@
return expr;
};
+ void addFactor(_Type from, _Type what, _Type result) {
+ var query = '$from - $what';
+ _factorResults[query] = result;
+ }
+
void addSubtype(_Type leftType, _Type rightType, bool isSubtype) {
var query = '$leftType <: $rightType';
_subtypes[query] = isSubtype;
@@ -3212,6 +3288,12 @@
};
}
+ @override
+ _Type factor(_Type from, _Type what) {
+ var query = '$from - $what';
+ return _factorResults[query] ?? fail('Unknown factor query: $query');
+ }
+
/// Invokes flow analysis of a nested function.
void function(_Node node, void body()) {
_flow.functionExpression_begin(node);
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/conditional.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/conditional.dart
index b71d9fb..9b8e497 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/conditional.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/conditional.dart
@@ -19,3 +19,13 @@
int conditional_in_expression_function_body(Object o) =>
o is int ? /*int*/ o : 0;
+
+void conditional_factor_Null(int? x) {
+ x is Null ? /*Null*/ x : /*int*/ x;
+ x;
+}
+
+void conditional_factor_nullable(num? x) {
+ x is int? ? /*int?*/ x : /*num*/ x;
+ x;
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/if.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/if.dart
index e150823..de0fa50 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/if.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/if.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:async';
+
class A {}
class B extends A {}
@@ -63,6 +65,60 @@
v;
}
+isType_factor_Null(int? v) {
+ if (v is Null) {
+ /*Null*/ v;
+ } else {
+ /*int*/ v;
+ }
+ v;
+}
+
+isType_factor_nullable(num? v) {
+ if (v is int?) {
+ /*int?*/ v;
+ } else {
+ /*num*/ v;
+ }
+ v;
+}
+
+isType_factor_declaredType(int? v) {
+ if (v is int?) {
+ v;
+ } else {
+ /*Never*/ v;
+ }
+ v;
+}
+
+isType_factor_supertype(int? v) {
+ if (v is num?) {
+ v;
+ } else {
+ /*Never*/ v;
+ }
+ v;
+}
+
+isType_factor_futureOr_future(FutureOr<int> v) {
+ if (v is Future<int>) {
+ /*Future<int>*/ v;
+ } else {
+ /*int*/ v;
+ }
+ v;
+}
+
+isType_factor_futureOr_type(FutureOr<int> v) {
+ if (v is int) {
+ /*int*/ v;
+ } else {
+ /*Future<int>*/ v;
+ }
+ v;
+}
+
isType_thenNonBoolean(Object x) {
if ((x is String) != 3) {
x;
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/infer_parameter_opt_in.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/infer_parameter_opt_in.dart
index ce65245..0ee78c7 100644
--- a/pkg/_fe_analyzer_shared/test/inheritance/data/infer_parameter_opt_in.dart
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/infer_parameter_opt_in.dart
@@ -56,57 +56,49 @@
/*class: F1:A,C,F1,Object*/
class F1 extends A implements C {
- /*cfe|cfe:builder.member: F1.method:void Function(void, {void named})*/
- /*analyzer.member: F1.method:Object? Function(Object?, {Object? named})*/
+ /*member: F1.method:Object? Function(Object?, {Object? named})*/
method(o, {named}) {}
}
/*class: F2:A,C,F2,Object*/
class F2 extends C implements A {
- /*cfe|cfe:builder.member: F2.method:void Function(void, {void named})*/
- /*analyzer.member: F2.method:Object? Function(Object?, {Object? named})*/
+ /*member: F2.method:Object? Function(Object?, {Object? named})*/
method(o, {named}) {}
}
/*class: F3:A,C,F3,Object*/
class F3 implements A, C {
- /*cfe|cfe:builder.member: F3.method:void Function(void, {void named})*/
- /*analyzer.member: F3.method:Object? Function(Object?, {Object? named})*/
+ /*member: F3.method:Object? Function(Object?, {Object? named})*/
method(o, {named}) {}
}
/*class: F4:A,C,F4,Object*/
class F4 implements C, A {
- /*cfe|cfe:builder.member: F4.method:void Function(void, {void named})*/
- /*analyzer.member: F4.method:Object? Function(Object?, {Object? named})*/
+ /*member: F4.method:Object? Function(Object?, {Object? named})*/
method(o, {named}) {}
}
/*class: G1:A,B,C,G1,Object*/
class G1 extends B implements C {
- /*cfe|cfe:builder.member: G1.method:void Function(void, {void named})*/
- /*analyzer.member: G1.method:Object? Function(Object?, {Object? named})*/
+ /*member: G1.method:Object? Function(Object?, {Object? named})*/
method(o, {named}) {}
}
/*class: G2:A,B,C,G2,Object*/
class G2 extends C implements B {
- /*cfe|cfe:builder.member: G2.method:void Function(void, {void named})*/
- /*analyzer.member: G2.method:Object? Function(Object?, {Object? named})*/
+ /*member: G2.method:Object? Function(Object?, {Object? named})*/
method(o, {named}) {}
}
/*class: G3:A,B,C,G3,Object*/
class G3 implements B, C {
- /*cfe|cfe:builder.member: G3.method:void Function(void, {void named})*/
- /*analyzer.member: G3.method:Object? Function(Object?, {Object? named})*/
+ /*member: G3.method:Object? Function(Object?, {Object? named})*/
method(o, {named}) {}
}
/*class: G4:A,B,C,G4,Object*/
class G4 implements C, B {
- /*cfe|cfe:builder.member: G4.method:void Function(void, {void named})*/
- /*analyzer.member: G4.method:Object? Function(Object?, {Object? named})*/
+ /*member: G4.method:Object? Function(Object?, {Object? named})*/
method(o, {named}) {}
}
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/issue40481.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/issue40481.dart
index a388a8d..5b56249 100644
--- a/pkg/_fe_analyzer_shared/test/inheritance/data/issue40481.dart
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/issue40481.dart
@@ -19,8 +19,7 @@
/*class: B1:A<Object?>,A_Object,A_dynamic,B1,Object*/
class B1 extends A_Object implements A_dynamic {}
-/*cfe|cfe:builder.class: B2:A<void>,A_Object,A_void,B2,Object*/
-/*analyzer.class: B2:A<Object?>,A_Object,A_void,B2,Object*/
+/*class: B2:A<Object?>,A_Object,A_void,B2,Object*/
class B2 extends A_Object implements A_void {}
main() {}
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/issue40481/main.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/issue40481/main.dart
index a84f5d1..6468993 100644
--- a/pkg/_fe_analyzer_shared/test/inheritance/data/issue40481/main.dart
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/issue40481/main.dart
@@ -15,8 +15,7 @@
/*class: B1:A<Object?>,A_Object,A_dynamic,B1,Object*/
class B1 extends A_Object implements A_dynamic {}
-/*cfe|cfe:builder.class: B2:A<void>,A_Object,A_void,B2,Object*/
-/*analyzer.class: B2:A<Object?>,A_Object,A_void,B2,Object*/
+/*class: B2:A<Object?>,A_Object,A_void,B2,Object*/
class B2 extends A_Object implements A_void {}
main() {}
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_direct.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_direct.dart
new file mode 100644
index 0000000..bb1b4ab
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_direct.dart
@@ -0,0 +1,47 @@
+// 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: nnbd=true*/
+
+/*class: A:A<T>,Object*/
+class A<T> {
+ /*member: A.member:T Function()*/
+ T member() => throw "Unreachable";
+}
+
+/*class: B:A<T>,B<T>,Object*/
+/*member: B.member:T Function()*/
+class B<T> extends A<T> {}
+
+/*class: D0:A<Object?>,B<Object?>,D0,Object*/
+/*member: D0.member:Object? Function()*/
+class D0 extends A<dynamic> implements B<Object?> {}
+
+/*class: D1:A<Object?>,B<dynamic>,D1,Object*/
+/*member: D1.member:Object? Function()*/
+class D1 extends A<Object?> implements B<dynamic> {}
+
+/*class: D2:A<Object?>,B<Object?>,D2,Object*/
+/*member: D2.member:Object? Function()*/
+class D2 extends A<void> implements B<Object?> {}
+
+/*class: D3:A<Object?>,B<void>,D3,Object*/
+/*member: D3.member:Object? Function()*/
+class D3 extends A<Object?> implements B<void> {}
+
+/*class: D4:A<Object?>,B<dynamic>,D4,Object*/
+/*member: D4.member:Object? Function()*/
+class D4 extends A<void> implements B<dynamic> {}
+
+/*class: D5:A<Object?>,B<void>,D5,Object*/
+/*member: D5.member:Object? Function()*/
+class D5 extends A<dynamic> implements B<void> {}
+
+/*class: D6:A<void>,B<void>,D6,Object*/
+/*member: D6.member:void Function()*/
+class D6 extends A<void> implements B<void> {}
+
+/*class: D7:A<dynamic>,B<dynamic>,D7,Object*/
+/*member: D7.member:dynamic Function()*/
+class D7 extends A<dynamic> implements B<dynamic> {}
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_mixin.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_mixin.dart
new file mode 100644
index 0000000..597a802
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_mixin.dart
@@ -0,0 +1,49 @@
+// 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: nnbd=true*/
+
+/*class: A:A<T>,Object*/
+abstract class A<T> {
+ /*member: A.member:T Function()*/
+ T member();
+}
+
+/*cfe|cfe:builder.class: B:B<T>,Object*/
+/*cfe|cfe:builder.member: B.member:T Function()*/
+mixin B<T> {
+ T member();
+}
+
+/*class: D0:A<dynamic>,B<Object?>,D0,Object*/
+/*member: D0.member:Object? Function()*/
+abstract class D0 extends A<dynamic> with B<Object?> {}
+
+/*class: D1:A<Object?>,B<dynamic>,D1,Object*/
+/*member: D1.member:dynamic Function()*/
+abstract class D1 extends A<Object?> with B<dynamic> {}
+
+/*class: D2:A<void>,B<Object?>,D2,Object*/
+/*member: D2.member:Object? Function()*/
+abstract class D2 extends A<void> with B<Object?> {}
+
+/*class: D3:A<Object?>,B<void>,D3,Object*/
+/*member: D3.member:void Function()*/
+abstract class D3 extends A<Object?> with B<void> {}
+
+/*class: D4:A<void>,B<dynamic>,D4,Object*/
+/*member: D4.member:dynamic Function()*/
+abstract class D4 extends A<void> with B<dynamic> {}
+
+/*class: D5:A<dynamic>,B<void>,D5,Object*/
+/*member: D5.member:void Function()*/
+abstract class D5 extends A<dynamic> with B<void> {}
+
+/*class: D6:A<void>,B<void>,D6,Object*/
+/*member: D6.member:void Function()*/
+abstract class D6 extends A<void> with B<void> {}
+
+/*class: D7:A<dynamic>,B<dynamic>,D7,Object*/
+/*member: D7.member:dynamic Function()*/
+abstract class D7 extends A<dynamic> with B<dynamic> {}
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_opt_in.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_opt_in.dart
index bd4dc1f..3845f87 100644
--- a/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_opt_in.dart
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_opt_in.dart
@@ -32,8 +32,7 @@
/*class: E1:A,B,C,D,E1,Object*/
abstract class E1 implements A, B, C, D {
- /*cfe|cfe:builder.member: E1.method:void Function(void)*/
- /*analyzer.member: E1.method:Object? Function(Object?)*/
+ /*member: E1.method:Object? Function(Object?)*/
}
/*class: E2:A,B,E2,Object*/
@@ -43,14 +42,12 @@
/*class: E3:B,C,E3,Object*/
abstract class E3 implements B, C {
- /*cfe|cfe:builder.member: E3.method:void Function(void)*/
- /*analyzer.member: E3.method:Object? Function(Object?)*/
+ /*member: E3.method:Object? Function(Object?)*/
}
/*class: E4:A,C,E4,Object*/
abstract class E4 implements A, C {
- /*cfe|cfe:builder.member: E4.method:void Function(void)*/
- /*analyzer.member: E4.method:Object? Function(Object?)*/
+ /*member: E4.method:Object? Function(Object?)*/
}
/*class: E5:A,D,E5,Object*/
@@ -71,24 +68,20 @@
/*class: G1:A,C,F,G1,Object*/
abstract class G1 implements A, C, F {
- /*cfe|cfe:builder.member: G1.method:void Function(void)*/
- /*analyzer.member: G1.method:Object? Function(Object?)*/
+ /*member: G1.method:Object? Function(Object?)*/
}
/*class: G2:A,C,F,G2,Object*/
abstract class G2 implements A, F, C {
- /*cfe|cfe:builder.member: G2.method:void Function(void)*/
- /*analyzer.member: G2.method:Object? Function(Object?)*/
+ /*member: G2.method:Object? Function(Object?)*/
}
/*class: G3:A,C,F,G3,Object*/
abstract class G3 implements C, A, F {
- /*cfe|cfe:builder.member: G3.method:void Function(void)*/
- /*analyzer.member: G3.method:Object? Function(Object?)*/
+ /*member: G3.method:Object? Function(Object?)*/
}
/*class: G4:A,C,F,G4,Object*/
abstract class G4 implements C, F, A {
- /*cfe|cfe:builder.member: G4.method:void Function(void)*/
- /*analyzer.member: G4.method:Object? Function(Object?)*/
+ /*member: G4.method:Object? Function(Object?)*/
}
diff --git a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
index 89432f8..1f83281 100644
--- a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
@@ -47,6 +47,9 @@
/// which all included paths share.
final String includedRoot;
+ /// Indicates whether the web preview of migration results should be launched.
+ final bool enablePreview;
+
/// The HTTP server that serves the preview tool.
HttpPreviewServer _server;
@@ -70,7 +73,9 @@
Future<void> Function([List<String>]) rerunFunction;
NonNullableFix(this.listener,
- {List<String> included = const [], this.preferredPort})
+ {List<String> included = const [],
+ this.preferredPort,
+ this.enablePreview = true})
: includedRoot =
_getIncludedRoot(included, listener.server.resourceProvider) {
reset();
@@ -96,7 +101,7 @@
migration, includedRoot, listener, instrumentationListener);
await state.refresh();
- if (_server == null) {
+ if (enablePreview && _server == null) {
_server = HttpPreviewServer(state, rerun, preferredPort);
_server.serveHttp();
port = await _server.boundPort;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
index db8e83f..b559a08 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
@@ -26,12 +26,35 @@
if (directive is NamespaceDirective) {
var library = directive.uriElement as LibraryElement;
if (library != null) {
+ var existingNames = _getCombinatorNames(directive);
for (var element in library.exportNamespace.definedNames.values) {
- builder.suggestElement(element,
- kind: CompletionSuggestionKind.IDENTIFIER);
+ if (!existingNames.contains(element.name)) {
+ builder.suggestElement(element,
+ kind: CompletionSuggestionKind.IDENTIFIER);
+ }
}
}
}
return const <CompletionSuggestion>[];
}
+
+ List<String> _getCombinatorNames(NamespaceDirective directive) {
+ var combinatorNameList = <String>[];
+ for (var combinator in directive.combinators) {
+ if (combinator is ShowCombinator) {
+ for (var simpleId in combinator.shownNames) {
+ if (!simpleId.isSynthetic) {
+ combinatorNameList.add(simpleId.name);
+ }
+ }
+ } else if (combinator is HideCombinator) {
+ for (var simpleId in combinator.hiddenNames) {
+ if (!simpleId.isSynthetic) {
+ combinatorNameList.add(simpleId.name);
+ }
+ }
+ }
+ }
+ return combinatorNameList;
+ }
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
index d7c061b..bcc6898 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
@@ -8,8 +8,6 @@
show CompletionSuggestion, CompletionSuggestionKind;
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
-import 'package:analysis_server/src/services/completion/dart/utilities.dart';
-import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
@@ -80,11 +78,10 @@
}
} else {
if (opType.includeVoidReturnSuggestions) {
- var suggestion = memberBuilder.addSuggestionForMethod(
+ memberBuilder.addSuggestionForMethod(
method: method,
inheritanceDistance: inheritanceDistance,
kind: kind);
- _updateFlutterSuggestions(request, method, suggestion);
}
}
}
@@ -128,35 +125,4 @@
}
return null;
}
-
- void _updateFlutterSuggestions(DartCompletionRequest request, Element element,
- CompletionSuggestion suggestion) {
- if (suggestion == null) {
- return;
- }
- if (element is MethodElement &&
- element.name == 'setState' &&
- Flutter.of(request.result).isExactState(element.enclosingElement)) {
- // Find the line indentation.
- var indent = getRequestLineIndent(request);
-
- // Let the user know that we are going to insert a complete statement.
- suggestion.displayText = 'setState(() {});';
-
- // Build the completion and the selection offset.
- var buffer = StringBuffer();
- buffer.writeln('setState(() {');
- buffer.write('$indent ');
- suggestion.selectionOffset = buffer.length;
- buffer.writeln();
- buffer.write('$indent});');
- suggestion.completion = buffer.toString();
-
- // There are no arguments to fill.
- suggestion.parameterNames = null;
- suggestion.parameterTypes = null;
- suggestion.requiredParameterCount = null;
- suggestion.hasNamedParameters = null;
- }
- }
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index 43ae5ba..e7e5e69 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -13,6 +13,7 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
import 'package:analysis_server/src/services/completion/dart/utilities.dart';
+import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
@@ -293,94 +294,25 @@
}
/// Add a suggestion for the given [method].
- CompletionSuggestion addSuggestionForMethod(
+ void addSuggestionForMethod(
{@required MethodElement method,
String containingMethodName,
CompletionSuggestionKind kind,
@required double inheritanceDistance}) {
- int oldRelevance() {
- if (method.hasDeprecated) {
- return DART_RELEVANCE_LOW;
- } else if (method.name == containingMethodName) {
- // Boost the relevance of a super expression calling a method of the
- // same name as the containing method.
- return DART_RELEVANCE_HIGH;
- }
- var identifier = method.displayName;
- if (identifier != null && identifier.startsWith(r'$')) {
- // Decrease relevance of suggestions starting with $
- // https://github.com/dart-lang/sdk/issues/27303
- return DART_RELEVANCE_LOW;
- }
- return DART_RELEVANCE_DEFAULT;
+ if (method.isAccessibleIn(request.libraryElement) &&
+ _shouldAddSuggestion(method)) {
+ builder.suggestMethod(method,
+ containingMethodName: containingMethodName,
+ kind: kind,
+ inheritanceDistance: inheritanceDistance);
}
-
- if (!method.isAccessibleIn(request.libraryElement)) {
- // Don't suggest private members from imported libraries.
- return null;
- }
- int relevance;
- if (request.useNewRelevance) {
- var featureComputer = request.featureComputer;
- var contextType = featureComputer.contextTypeFeature(
- request.contextType, method.returnType);
- var hasDeprecated = featureComputer.hasDeprecatedFeature(method);
- var startsWithDollar =
- featureComputer.startsWithDollarFeature(method.name);
- var superMatches = featureComputer.superMatchesFeature(
- containingMethodName, method.name);
- relevance = _computeRelevance(
- contextType: contextType,
- hasDeprecated: hasDeprecated,
- inheritanceDistance: inheritanceDistance,
- startsWithDollar: startsWithDollar,
- superMatches: superMatches);
- } else {
- relevance = oldRelevance();
- }
- return _addSuggestion(method, relevance, kind: kind);
}
/// Add a suggestion for the given [element] with the given [relevance],
/// provided that it is not shadowed by a previously added suggestion.
CompletionSuggestion _addSuggestion(Element element, int relevance,
{CompletionSuggestionKind kind}) {
- var identifier = element.displayName;
-
- var alreadyGenerated = _completionTypesGenerated.putIfAbsent(
- identifier, () => _COMPLETION_TYPE_NONE);
- if (element is MethodElement) {
- // Anything shadows a method.
- if (alreadyGenerated != _COMPLETION_TYPE_NONE) {
- return null;
- }
- _completionTypesGenerated[identifier] =
- _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
- } else if (element is PropertyAccessorElement) {
- if (element.isGetter) {
- // Getters, fields, and methods shadow a getter.
- if ((alreadyGenerated & _COMPLETION_TYPE_GETTER) != 0) {
- return null;
- }
- _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_GETTER;
- } else {
- // Setters, fields, and methods shadow a setter.
- if ((alreadyGenerated & _COMPLETION_TYPE_SETTER) != 0) {
- return null;
- }
- _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_SETTER;
- }
- } else if (element is FieldElement) {
- // Fields and methods shadow a field. A getter/setter pair shadows a
- // field, but a getter or setter by itself doesn't.
- if (alreadyGenerated == _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET) {
- return null;
- }
- _completionTypesGenerated[identifier] =
- _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
- } else {
- // Unexpected element type; skip it.
- assert(false);
+ if (!_shouldAddSuggestion(element)) {
return null;
}
var suggestion =
@@ -422,6 +354,49 @@
]);
return toRelevance(score, Relevance.member);
}
+
+ /// Return `true` if a suggestion for the given [element] should be created.
+ bool _shouldAddSuggestion(Element element) {
+ var identifier = element.displayName;
+
+ var alreadyGenerated = _completionTypesGenerated.putIfAbsent(
+ identifier, () => _COMPLETION_TYPE_NONE);
+ if (element is MethodElement) {
+ // Anything shadows a method.
+ if (alreadyGenerated != _COMPLETION_TYPE_NONE) {
+ return false;
+ }
+ _completionTypesGenerated[identifier] =
+ _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
+ } else if (element is PropertyAccessorElement) {
+ if (element.isGetter) {
+ // Getters, fields, and methods shadow a getter.
+ if ((alreadyGenerated & _COMPLETION_TYPE_GETTER) != 0) {
+ return false;
+ }
+ _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_GETTER;
+ } else {
+ // Setters, fields, and methods shadow a setter.
+ if ((alreadyGenerated & _COMPLETION_TYPE_SETTER) != 0) {
+ return false;
+ }
+ _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_SETTER;
+ }
+ } else if (element is FieldElement) {
+ // Fields and methods shadow a field. A getter/setter pair shadows a
+ // field, but a getter or setter by itself doesn't.
+ if (alreadyGenerated == _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET) {
+ return false;
+ }
+ _completionTypesGenerated[identifier] =
+ _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
+ } else {
+ // Unexpected element type; skip it.
+ assert(false);
+ return false;
+ }
+ return true;
+ }
}
/// An object used to build a list of suggestions in response to a single
@@ -442,10 +417,18 @@
/// `false`.
DartType _cachedContextType;
+ /// The cached instance of the flutter utilities, or `null` if it hasn't been
+ /// created yet.
+ Flutter _flutter;
+
/// Initialize a newly created suggestion builder to build suggestions for the
/// given [request].
SuggestionBuilder(this.request);
+ /// Return an object that can answer questions about Flutter code based on the
+ /// flavor of Flutter being used.
+ Flutter get flutter => _flutter ??= Flutter.of(request.result);
+
DartType get _contextType {
if (!_hasContextType) {
_hasContextType = true;
@@ -608,6 +591,82 @@
suggestions.add(createSuggestion(request, function, relevance: relevance));
}
+ void suggestMethod(MethodElement method,
+ {String containingMethodName,
+ CompletionSuggestionKind kind,
+ @required double inheritanceDistance}) {
+ // TODO(brianwilkerson) Refactor callers so that we're passing in the type
+ // of the target (assuming we don't already have that type available via
+ // the [request]) and compute the [inheritanceDistance] in this method.
+ int oldRelevance() {
+ if (method.hasDeprecated) {
+ return DART_RELEVANCE_LOW;
+ } else if (method.name == containingMethodName) {
+ // Boost the relevance of a super expression calling a method of the
+ // same name as the containing method.
+ return DART_RELEVANCE_HIGH;
+ }
+ var identifier = method.displayName;
+ if (identifier != null && identifier.startsWith(r'$')) {
+ // Decrease relevance of suggestions starting with $
+ // https://github.com/dart-lang/sdk/issues/27303
+ return DART_RELEVANCE_LOW;
+ }
+ return DART_RELEVANCE_DEFAULT;
+ }
+
+ int relevance;
+ if (request.useNewRelevance) {
+ var featureComputer = request.featureComputer;
+ var contextType = featureComputer.contextTypeFeature(
+ request.contextType, method.returnType);
+ var hasDeprecated = featureComputer.hasDeprecatedFeature(method);
+ var startsWithDollar =
+ featureComputer.startsWithDollarFeature(method.name);
+ var superMatches = featureComputer.superMatchesFeature(
+ containingMethodName, method.name);
+ relevance = _computeMemberRelevance(
+ contextType: contextType,
+ hasDeprecated: hasDeprecated,
+ inheritanceDistance: inheritanceDistance,
+ startsWithDollar: startsWithDollar,
+ superMatches: superMatches);
+ } else {
+ relevance = oldRelevance();
+ }
+
+ var suggestion =
+ createSuggestion(request, method, kind: kind, relevance: relevance);
+ if (suggestion != null) {
+ if (method.name == 'setState' &&
+ flutter.isExactState(method.enclosingElement)) {
+ // TODO(brianwilkerson) Make this more efficient by creating the correct
+ // suggestion in the first place.
+ // Find the line indentation.
+ var indent = getRequestLineIndent(request);
+
+ // Let the user know that we are going to insert a complete statement.
+ suggestion.displayText = 'setState(() {});';
+
+ // Build the completion and the selection offset.
+ var buffer = StringBuffer();
+ buffer.writeln('setState(() {');
+ buffer.write('$indent ');
+ suggestion.selectionOffset = buffer.length;
+ buffer.writeln();
+ buffer.write('$indent});');
+ suggestion.completion = buffer.toString();
+
+ // There are no arguments to fill.
+ suggestion.parameterNames = null;
+ suggestion.parameterTypes = null;
+ suggestion.requiredParameterCount = null;
+ suggestion.hasNamedParameters = null;
+ }
+ suggestions.add(suggestion);
+ }
+ }
+
/// Add a suggestion for the top-level [function].
void suggestTopLevelFunction(FunctionElement function,
{CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
@@ -657,6 +716,38 @@
createSuggestion(request, variable, kind: kind, relevance: relevance));
}
+ /// Compute a relevance value from the given feature scores:
+ /// - [contextType] is higher if the type of the element matches the context
+ /// type,
+ /// - [hasDeprecated] is higher if the element is not deprecated,
+ /// - [inheritanceDistance] is higher if the element is defined closer to the
+ /// target type,
+ /// - [startsWithDollar] is higher if the element's name doe _not_ start with
+ /// a dollar sign, and
+ /// - [superMatches] is higher if the element is being invoked through `super`
+ /// and the element's name matches the name of the enclosing method.
+ int _computeMemberRelevance(
+ {@required double contextType,
+ @required double hasDeprecated,
+ @required double inheritanceDistance,
+ @required double startsWithDollar,
+ @required double superMatches}) {
+ var score = weightedAverage([
+ contextType,
+ hasDeprecated,
+ inheritanceDistance,
+ startsWithDollar,
+ superMatches
+ ], [
+ 1.0,
+ 0.5,
+ 1.0,
+ 0.5,
+ 1.0
+ ]);
+ return toRelevance(score, Relevance.member);
+ }
+
/// Return the relevance score for a top-level [element].
int _computeTopLevelRelevance(Element element,
{int defaultRelevance = 800, DartType elementType}) {
diff --git a/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
index 04a362b..ec3822e 100644
--- a/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
@@ -74,6 +74,12 @@
assertNotSuggested('Object');
}
+ Future<void> test_Combinator_hide_duplicate() async {
+ addTestSource('import "dart:math" hide PI, ^;');
+ await computeSuggestions();
+ assertNotSuggested('PI');
+ }
+
Future<void> test_Combinator_show() async {
// SimpleIdentifier HideCombinator ImportDirective
addSource('/home/test/lib/ab.dart', '''
@@ -123,6 +129,12 @@
assertNotSuggested('Object');
}
+ Future<void> test_Combinator_show_duplicate() async {
+ addTestSource('import "dart:math" show PI, ^;');
+ await computeSuggestions();
+ assertNotSuggested('PI');
+ }
+
Future<void> test_Combinator_show_export_withShow() async {
addSource('/home/test/lib/a.dart', r'''
class A {}
diff --git a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
index 799104d..b043bd3 100644
--- a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
@@ -1924,7 +1924,7 @@
assertNoSuggestions();
}
- Future<void> test_extendsClause() async {
+ Future<void> test_ExtendsClause() async {
newFile('/home/test/lib/a.dart', content: 'class A {}');
addTestSource('''
import 'a.dart';
@@ -1935,6 +1935,41 @@
assertSuggestClass('A');
}
+ Future<void> test_ExtensionDeclaration_extendedType() async {
+ newFile('/home/test/lib/a.dart', content: 'class A {}');
+ addTestSource('''
+import 'a.dart';
+
+extension E on ^
+''');
+ await computeSuggestions();
+ assertSuggestClass('A');
+ assertNotSuggested('E');
+ }
+
+ Future<void> test_ExtensionDeclaration_extendedType2() async {
+ newFile('/home/test/lib/a.dart', content: 'class A {}');
+ addTestSource('''
+import 'a.dart';
+
+extension E on ^ {}
+''');
+ await computeSuggestions();
+ assertSuggestClass('A');
+ assertNotSuggested('E');
+ }
+
+ Future<void> test_ExtensionDeclaration_member() async {
+ newFile('/home/test/lib/a.dart', content: 'class A {}');
+ addTestSource('''
+import 'a.dart';
+
+extension E on A { ^ }
+''');
+ await computeSuggestions();
+ assertSuggestClass('A');
+ }
+
Future<void> test_FieldDeclaration_name_typed() async {
// SimpleIdentifier VariableDeclaration VariableDeclarationList
// FieldDeclaration
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
index 4ddc388..c9bb123 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -2513,7 +2513,7 @@
assertNoSuggestions();
}
- Future<void> test_extendsClause() async {
+ Future<void> test_ExtendsClause() async {
addTestSource('''
class A {}
mixin M {}
@@ -2524,6 +2524,35 @@
assertNotSuggested('M');
}
+ Future<void> test_ExtensionDeclaration_extendedType() async {
+ addTestSource('''
+class A {}
+extension E on ^
+''');
+ await computeSuggestions();
+ assertSuggestClass('A');
+ assertNotSuggested('E');
+ }
+
+ Future<void> test_ExtensionDeclaration_extendedType2() async {
+ addTestSource('''
+class A {}
+extension E on ^ {}
+''');
+ await computeSuggestions();
+ assertSuggestClass('A');
+ assertNotSuggested('E');
+ }
+
+ Future<void> test_ExtensionDeclaration_member() async {
+ addTestSource('''
+class A {}
+extension E on A { ^ }
+''');
+ await computeSuggestions();
+ assertSuggestClass('A');
+ }
+
Future<void> test_FieldDeclaration_name_typed() async {
// SimpleIdentifier VariableDeclaration VariableDeclarationList
// FieldDeclaration
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
index 85aeefe..ad33ec7 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
@@ -246,9 +246,9 @@
const ParserErrorCode _EXPERIMENT_NOT_ENABLED = ParserErrorCode(
'EXPERIMENT_NOT_ENABLED',
- r"This requires the '#string' experiment to be enabled.",
+ r"This requires the '#string' language feature to be enabled.",
correction:
- "Try enabling this experiment by adding it to the command line when compiling and running.");
+ "Try updating your pubspec.yaml to set the minimum SDK constraint to #string2 or higher, and running 'pub get'.");
const ParserErrorCode _EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE = ParserErrorCode(
'EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE',
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
index c85c898..19c607e 100644
--- a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
@@ -351,6 +351,11 @@
TypeSystemTypeOperations(this.typeSystem);
@override
+ DartType factor(DartType from, DartType what) {
+ return typeSystem.factor(from, what);
+ }
+
+ @override
bool isSameType(covariant TypeImpl type1, covariant TypeImpl type2) {
return type1 == type2;
}
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 770dd99..efc8d42 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -62,6 +62,7 @@
TypeParameterImpl;
import 'package:analyzer/src/fasta/error_converter.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:pub_semver/pub_semver.dart';
const _invalidCollectionElement = _InvalidCollectionElement._();
@@ -603,11 +604,15 @@
reportErrorIfSuper(right);
push(ast.binaryExpression(left, operatorToken, right));
if (!enableTripleShift && operatorToken.type == TokenType.GT_GT_GT) {
+ var feature = ExperimentalFeatures.triple_shift;
handleRecoverableError(
- templateExperimentNotEnabled
- .withArguments(EnableString.triple_shift),
- operatorToken,
- operatorToken);
+ templateExperimentNotEnabled.withArguments(
+ feature.enableString,
+ _versionAsString(ExperimentStatus.currentVersion),
+ ),
+ operatorToken,
+ operatorToken,
+ );
}
}
}
@@ -2292,10 +2297,15 @@
}
push(ast.assignmentExpression(lhs, token, rhs));
if (!enableTripleShift && token.type == TokenType.GT_GT_GT_EQ) {
+ var feature = ExperimentalFeatures.triple_shift;
handleRecoverableError(
- templateExperimentNotEnabled.withArguments(EnableString.triple_shift),
- token,
- token);
+ templateExperimentNotEnabled.withArguments(
+ feature.enableString,
+ _versionAsString(ExperimentStatus.currentVersion),
+ ),
+ token,
+ token,
+ );
}
}
@@ -3328,11 +3338,15 @@
push(ast.spreadElement(
spreadOperator: spreadToken, expression: expression));
} else {
+ var feature = Feature.spread_collections;
handleRecoverableError(
- templateExperimentNotEnabled
- .withArguments(EnableString.spread_collections),
- spreadToken,
- spreadToken);
+ templateExperimentNotEnabled.withArguments(
+ feature.enableString,
+ _versionAsString(feature.firstSupportedVersion),
+ ),
+ spreadToken,
+ spreadToken,
+ );
push(_invalidCollectionElement);
}
}
@@ -3547,11 +3561,15 @@
body: entry as CollectionElement,
));
} else {
+ var feature = Feature.control_flow_collections;
handleRecoverableError(
- templateExperimentNotEnabled
- .withArguments(EnableString.control_flow_collections),
- forToken,
- forToken);
+ templateExperimentNotEnabled.withArguments(
+ feature.enableString,
+ _versionAsString(feature.firstSupportedVersion),
+ ),
+ forToken,
+ forToken,
+ );
push(_invalidCollectionElement);
}
}
@@ -3576,11 +3594,15 @@
elseElement: elseElement,
));
} else {
+ var feature = ExperimentalFeatures.control_flow_collections;
handleRecoverableError(
- templateExperimentNotEnabled
- .withArguments(EnableString.control_flow_collections),
- ifToken,
- ifToken);
+ templateExperimentNotEnabled.withArguments(
+ feature.enableString,
+ _versionAsString(feature.firstSupportedVersion),
+ ),
+ ifToken,
+ ifToken,
+ );
push(_invalidCollectionElement);
}
}
@@ -3588,10 +3610,15 @@
void reportErrorIfNullableType(Token questionMark) {
if (questionMark != null) {
assert(optional('?', questionMark));
+ var feature = ExperimentalFeatures.non_nullable;
handleRecoverableError(
- templateExperimentNotEnabled.withArguments('non-nullable'),
- questionMark,
- questionMark);
+ templateExperimentNotEnabled.withArguments(
+ feature.enableString,
+ _versionAsString(ExperimentStatus.currentVersion),
+ ),
+ questionMark,
+ questionMark,
+ );
}
}
@@ -3605,16 +3632,28 @@
void reportNonNullableModifierError(Token modifierToken) {
if (modifierToken != null) {
+ var feature = ExperimentalFeatures.non_nullable;
handleRecoverableError(
- templateExperimentNotEnabled.withArguments('non-nullable'),
- modifierToken,
- modifierToken);
+ templateExperimentNotEnabled.withArguments(
+ feature.enableString,
+ _versionAsString(ExperimentStatus.currentVersion),
+ ),
+ modifierToken,
+ modifierToken,
+ );
}
}
void reportNonNullAssertExpressionNotEnabled(Token bang) {
+ var feature = ExperimentalFeatures.non_nullable;
handleRecoverableError(
- templateExperimentNotEnabled.withArguments('non-nullable'), bang, bang);
+ templateExperimentNotEnabled.withArguments(
+ feature.enableString,
+ _versionAsString(ExperimentStatus.currentVersion),
+ ),
+ bang,
+ bang,
+ );
}
Comment _findComment(List<Annotation> metadata, Token tokenAfterMetadata) {
@@ -3686,6 +3725,10 @@
return ParameterKind.REQUIRED;
}
}
+
+ static String _versionAsString(Version version) {
+ return '${version.major}.${version.minor}.${version.patch}';
+ }
}
class _ConstructorNameWithInvalidTypeArgs {
diff --git a/pkg/analyzer/test/src/dart/element/factor_type_test.dart b/pkg/analyzer/test/src/dart/element/factor_type_test.dart
index 94a865c..f3ad7cc 100644
--- a/pkg/analyzer/test/src/dart/element/factor_type_test.dart
+++ b/pkg/analyzer/test/src/dart/element/factor_type_test.dart
@@ -33,12 +33,13 @@
);
}
- void setUp() {
- var analysisContext = TestAnalysisContext(
- featureSet: testFeatureSet,
- );
- typeProvider = analysisContext.typeProviderNonNullableByDefault;
- typeSystem = analysisContext.typeSystemNonNullableByDefault;
+ @override
+ DartType get voidType => typeProvider.voidType;
+
+ @override
+ void expect(
+ DartType T, DartType S, String actualResult, String expectedResult) {
+ test.expect(actualResult, expectedResult);
}
@override
@@ -46,10 +47,12 @@
return typeSystem.factor(T, S);
}
- @override
- void expect(
- DartType T, DartType S, String actualResult, String expectedResult) {
- test.expect(actualResult, expectedResult);
+ void setUp() {
+ var analysisContext = TestAnalysisContext(
+ featureSet: testFeatureSet,
+ );
+ typeProvider = analysisContext.typeProviderNonNullableByDefault;
+ typeSystem = analysisContext.typeSystemNonNullableByDefault;
}
@override
diff --git a/pkg/analyzer/tool/summary/mini_ast.dart b/pkg/analyzer/tool/summary/mini_ast.dart
index 144b1a3..7e92f7d 100644
--- a/pkg/analyzer/tool/summary/mini_ast.dart
+++ b/pkg/analyzer/tool/summary/mini_ast.dart
@@ -11,6 +11,8 @@
import 'package:_fe_analyzer_shared/src/parser/parser.dart';
import 'package:_fe_analyzer_shared/src/parser/stack_listener.dart';
import 'package:_fe_analyzer_shared/src/scanner/token.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:pub_semver/pub_semver.dart';
/// "Mini AST" representation of a declaration which can accept annotations.
class AnnotatedNode {
@@ -615,16 +617,32 @@
void reportErrorIfNullableType(Token questionMark) {
if (questionMark != null) {
assert(optional('?', questionMark));
+ var feature = ExperimentalFeatures.non_nullable;
handleRecoverableError(
- templateExperimentNotEnabled.withArguments('non-nullable'),
- questionMark,
- questionMark);
+ templateExperimentNotEnabled.withArguments(
+ feature.enableString,
+ _versionAsString(ExperimentStatus.currentVersion),
+ ),
+ questionMark,
+ questionMark,
+ );
}
}
void reportNonNullAssertExpressionNotEnabled(Token bang) {
+ var feature = ExperimentalFeatures.non_nullable;
handleRecoverableError(
- templateExperimentNotEnabled.withArguments('non-nullable'), bang, bang);
+ templateExperimentNotEnabled.withArguments(
+ feature.enableString,
+ _versionAsString(ExperimentStatus.currentVersion),
+ ),
+ bang,
+ bang,
+ );
+ }
+
+ static String _versionAsString(Version version) {
+ return '${version.major}.${version.minor}.${version.patch}';
}
}
diff --git a/pkg/analyzer_cli/pubspec.yaml b/pkg/analyzer_cli/pubspec.yaml
index cf57798..295f5cf 100644
--- a/pkg/analyzer_cli/pubspec.yaml
+++ b/pkg/analyzer_cli/pubspec.yaml
@@ -1,6 +1,8 @@
name: analyzer_cli
description: Command line interface for the Dart Analyzer.
publish_to: none
+environment:
+ sdk: "^2.7.0"
dependencies:
analyzer: ^0.37.0
args: '>=0.13.0 <2.0.0'
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index adbccee..d138827 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -634,6 +634,7 @@
void visitExtensionDeclaration(ExtensionDeclaration node) {
if (identical(entity, node.extendedType)) {
optype.completionLocation = 'ExtensionDeclaration_extendedType';
+ optype.includeTypeNameSuggestions = true;
} else if (node.members.contains(entity) ||
identical(entity, node.rightBracket)) {
// Make suggestions in the body of the extension declaration
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
index 07ba9b9..c9f6489 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
@@ -1070,6 +1070,14 @@
completionLocation: 'ExtensionDeclaration_member', typeNames: true);
}
+ Future<void> test_extensionDeclaration_extendedType() async {
+ // SimpleIdentifier MethodDeclaration ExtensionDeclaration
+ addTestSource('extension E on ^ {}');
+ await assertOpType(
+ completionLocation: 'ExtensionDeclaration_extendedType',
+ typeNames: true);
+ }
+
Future<void> test_extensionOverride_argumentList() async {
// ExtensionDeclaration CompilationUnit
addTestSource('''
diff --git a/pkg/async_helper/lib/async_helper.dart b/pkg/async_helper/lib/async_helper.dart
index d5bcc08..1f3acb1 100644
--- a/pkg/async_helper/lib/async_helper.dart
+++ b/pkg/async_helper/lib/async_helper.dart
@@ -107,7 +107,10 @@
[bool check(T error) = _pass, String reason = ""]) {
var type = "";
if (T != dynamic && T != Object) type = "<$T>";
- var header = "asyncExpectThrows$type(${reason ?? ''}):";
+ // Handle null being passed in from legacy code while also avoiding producing
+ // an unnecessary null check warning here.
+ if ((reason as dynamic) == null) reason = "";
+ var header = "asyncExpectThrows$type(${reason}):";
// TODO(rnystrom): It might useful to validate that T is not bound to
// ExpectException since that won't work.
@@ -124,7 +127,7 @@
}
asyncStart();
- result.then((_) {
+ result.then<Null>((_) {
throw ExpectException("$header Did not throw.");
}).catchError((error, stack) {
// A test failure doesn't count as throwing.
diff --git a/pkg/async_helper/lib/async_minitest.dart b/pkg/async_helper/lib/async_minitest.dart
index 57a05eb..fa5d319 100644
--- a/pkg/async_helper/lib/async_minitest.dart
+++ b/pkg/async_helper/lib/async_minitest.dart
@@ -310,9 +310,7 @@
bool _initializedTestNameCallback = false;
/// The current combined name of the nesting [group] or [test].
-// TODO(rnystrom): Type this "String?" when this library does not need to be
-// NNBD agnostic.
-dynamic _currentName = null;
+String _currentName = "";
String _pushName(String newName) {
// Look up the current test name from the zone created for the test.
@@ -322,7 +320,7 @@
}
var oldName = _currentName;
- if (oldName == null) {
+ if (oldName == "") {
_currentName = newName;
} else {
_currentName = "$oldName $newName";
diff --git a/pkg/async_helper/pubspec.yaml b/pkg/async_helper/pubspec.yaml
index df92b53..9497752 100644
--- a/pkg/async_helper/pubspec.yaml
+++ b/pkg/async_helper/pubspec.yaml
@@ -7,6 +7,5 @@
language tests.
Third parties are discouraged from using this, and should use
the facilities provided in package:test.
-
dependencies:
expect: any
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index 9916400..874bf6b 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -859,14 +859,17 @@
if (mask != null) return mask;
// TODO(sigmund): ensure that this is only called once per node.
DartType staticType = _getStaticType(receiver);
- // TODO(sigmund): this needs to be adjusted when we enable non-nullable
- // types to handle legacy and nullable wrappers.
+ bool includeNull =
+ _dartTypes.useLegacySubtyping || staticType is NullableType;
+ staticType = staticType.withoutNullability;
if (staticType is InterfaceType) {
ClassEntity cls = staticType.element;
if (receiver is ir.ThisExpression && !_closedWorld.isUsedAsMixin(cls)) {
mask = _closedWorld.abstractValueDomain.createNonNullSubclass(cls);
- } else {
+ } else if (includeNull) {
mask = _closedWorld.abstractValueDomain.createNullableSubtype(cls);
+ } else {
+ mask = _closedWorld.abstractValueDomain.createNonNullSubtype(cls);
}
data.setReceiverTypeMask(node, mask);
return mask;
@@ -1706,7 +1709,7 @@
if (exception != null) {
TypeInformation mask;
DartType type = node.guard != null
- ? _elementMap.getDartType(node.guard)
+ ? _elementMap.getDartType(node.guard).withoutNullability
: _dartTypes.dynamicType();
if (type is InterfaceType) {
InterfaceType interfaceType = type;
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index 75ec907..b1eda7b 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -742,6 +742,8 @@
assert(
node.promotedType == null ||
promotedType == typeEnvironment.nullType ||
+ promotedType is ir.InterfaceType &&
+ promotedType.classNode == typeEnvironment.futureOrClass ||
typeEnvironment.isSubtypeOf(promotedType, node.promotedType,
ir.SubtypeCheckMode.ignoringNullabilities),
"Unexpected promotion of ${node.variable} in ${node.parent}. "
diff --git a/pkg/dart2native/pubspec.yaml b/pkg/dart2native/pubspec.yaml
index feca449..c89834f 100644
--- a/pkg/dart2native/pubspec.yaml
+++ b/pkg/dart2native/pubspec.yaml
@@ -1,6 +1,9 @@
name: dart2native
publish_to: none
+environment:
+ sdk: "^2.7.0"
+
# Add the bin/dart2native.dart script to the scripts pub installs.
executables:
dart2native:
diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart
index 3a3e9c4..5c6cd31 100644
--- a/pkg/dartdev/lib/src/commands/run.dart
+++ b/pkg/dartdev/lib/src/commands/run.dart
@@ -26,6 +26,7 @@
// command pub with no commands or flags.
final command = sdk.dart;
final args = [
+ '--disable-dart-dev',
'--help',
if (verbose) '--verbose',
];
@@ -52,7 +53,8 @@
// Starting in ProcessStartMode.inheritStdio mode means the child process
// can detect support for ansi chars.
- final process = await Process.start(sdk.dart, args,
+ final process = await Process.start(
+ sdk.dart, ['--disable-dart-dev', ...args],
mode: ProcessStartMode.inheritStdio);
return process.exitCode;
}
diff --git a/pkg/expect/lib/expect.dart b/pkg/expect/lib/expect.dart
index 0e993bc..4a177ab 100644
--- a/pkg/expect/lib/expect.dart
+++ b/pkg/expect/lib/expect.dart
@@ -490,7 +490,7 @@
*
* If the objects are iterables or maps, recurses into them.
*/
- static void deepEquals(Object expected, Object actual) {
+ static void deepEquals(dynamic expected, dynamic actual) {
// Early exit check for equality.
if (expected == actual) return;
@@ -560,8 +560,10 @@
// TODO(vsm): Make check and reason nullable or change call sites.
// Existing tests pass null to set a reason and/or pass them through
// via helpers.
- check ??= _defaultCheck;
- reason ??= "";
+ // TODO(rnystrom): Using the strange form below instead of "??=" to avoid
+ // warnings of unnecessary null checks when analyzed as NNBD code.
+ if ((check as dynamic) == null) check = _defaultCheck;
+ if ((reason as dynamic) == null) reason = "";
String msg = reason.isEmpty ? "" : "($reason)";
if (f is! Function()) {
// Only throws from executing the function body should count as throwing.
@@ -570,7 +572,7 @@
}
try {
f();
- } on Object catch (e, s) {
+ } catch (e, s) {
// A test failure doesn't count as throwing.
if (e is ExpectException) rethrow;
if (e is T && check(e as dynamic)) return;
diff --git a/pkg/expect/lib/minitest.dart b/pkg/expect/lib/minitest.dart
index 350b6aa..0021ada 100644
--- a/pkg/expect/lib/minitest.dart
+++ b/pkg/expect/lib/minitest.dart
@@ -26,7 +26,7 @@
import 'package:expect/expect.dart';
typedef dynamic _Action();
-typedef void _ExpectationFunction(Object actual);
+typedef void _ExpectationFunction(dynamic actual);
final List<_Group> _groups = [new _Group()];
@@ -124,7 +124,7 @@
_groups.last.tearDownFunction = body;
}
-void expect(Object actual, Object expected, {String reason = ""}) {
+void expect(dynamic actual, dynamic expected, {String reason = ""}) {
// TODO(rnystrom): Do something useful with reason.
if (expected is! _Expectation) {
expected = equals(expected);
@@ -138,19 +138,19 @@
Expect.fail(message);
}
-Object equals(Object value) => new _Expectation((actual) {
+Object equals(dynamic value) => new _Expectation((actual) {
Expect.deepEquals(value, actual);
});
-Object notEquals(Object value) => new _Expectation((actual) {
+Object notEquals(dynamic value) => new _Expectation((actual) {
Expect.notEquals(value, actual);
});
-Object unorderedEquals(Object value) => new _Expectation((actual) {
+Object unorderedEquals(dynamic value) => new _Expectation((actual) {
Expect.setEquals(value as Iterable, actual as Iterable);
});
-Object predicate(bool fn(Object value), [String description = ""]) =>
+Object predicate(bool fn(dynamic value), [String description = ""]) =>
new _Expectation((actual) {
Expect.isTrue(fn(actual), description);
});
@@ -169,7 +169,7 @@
}
});
-Object same(Object value) => new _Expectation((actual) {
+Object same(dynamic value) => new _Expectation((actual) {
Expect.identical(value, actual);
});
diff --git a/pkg/expect/pubspec.yaml b/pkg/expect/pubspec.yaml
index 5e6beb6..595d26c 100644
--- a/pkg/expect/pubspec.yaml
+++ b/pkg/expect/pubspec.yaml
@@ -6,8 +6,5 @@
Third parties are discouraged from using this, and should use
the expect() function in the unit test library instead for
test assertions.
-environment:
- sdk: ">=2.0.0 <3.0.0"
-
dependencies:
meta: any
diff --git a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
index 597ce2a..734b8b4 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
@@ -346,8 +346,15 @@
parameterIndex < interfaceTypeParameters.length;
parameterIndex++) {
TypeParameter typeParameter = interfaceTypeParameters[parameterIndex];
- bool isGenericCovariantImpl = typeParameter.isGenericCovariantImpl ||
- needsCheck(typeParameter.bound);
+ DartType parameterBound =
+ substitution.substituteType(typeParameter.bound);
+ DartType bound = initialType(_combinedMemberIndex, parameterBound);
+ DartType parameterDefaultType =
+ substitution.substituteType(typeParameter.defaultType);
+ DartType defaultType =
+ initialType(_combinedMemberIndex, parameterDefaultType);
+ bool isGenericCovariantImpl =
+ typeParameter.isGenericCovariantImpl || needsCheck(parameterBound);
TypeParameter superTypeParameter = typeParameter;
for (int candidateIndex = 0;
candidateIndex < _candidates.length;
@@ -374,6 +381,14 @@
true;
}
}
+ if (bound != null && bound != parameterBound) {
+ createStubIfNeeded(forMemberSignature: true);
+ stub.function.typeParameters[parameterIndex].bound = bound;
+ }
+ if (defaultType != null && defaultType != parameterDefaultType) {
+ createStubIfNeeded(forMemberSignature: true);
+ stub.function.typeParameters[parameterIndex].defaultType = defaultType;
+ }
}
DartType returnType =
substitution.substituteType(getReturnType(interfaceMember));
@@ -486,6 +501,8 @@
for (int i = 0; i < typeParameters.length; i++) {
typeParameters[i].bound =
substitution.substituteType(targetTypeParameters[i].bound);
+ typeParameters[i].defaultType =
+ substitution.substituteType(targetTypeParameters[i].defaultType);
}
}
List<VariableDeclaration> positionalParameters =
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index 34c3490..cc122ab 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -2810,7 +2810,8 @@
ExpressionInferenceResult visitSuperIndexSet(
SuperIndexSet node, DartType typeContext) {
ObjectAccessTarget indexSetTarget = node.setter != null
- ? new ObjectAccessTarget.interfaceMember(node.setter)
+ ? new ObjectAccessTarget.interfaceMember(node.setter,
+ isPotentiallyNullable: false)
: const ObjectAccessTarget.missing();
DartType indexType =
@@ -3107,7 +3108,8 @@
ExpressionInferenceResult visitIfNullSuperIndexSet(
IfNullSuperIndexSet node, DartType typeContext) {
ObjectAccessTarget readTarget = node.getter != null
- ? new ObjectAccessTarget.interfaceMember(node.getter)
+ ? new ObjectAccessTarget.interfaceMember(node.getter,
+ isPotentiallyNullable: false)
: const ObjectAccessTarget.missing();
DartType readType = inferrer.getReturnType(readTarget, inferrer.thisType);
@@ -3121,7 +3123,8 @@
.member;
ObjectAccessTarget writeTarget = node.setter != null
- ? new ObjectAccessTarget.interfaceMember(node.setter)
+ ? new ObjectAccessTarget.interfaceMember(node.setter,
+ isPotentiallyNullable: false)
: const ObjectAccessTarget.missing();
DartType writeIndexType =
@@ -3416,11 +3419,9 @@
{bool isNot}) {
assert(isNot != null);
inferrer.flowAnalysis.equalityOp_rightBegin(left);
- ObjectAccessTarget objectEqualsTarget =
- inferrer.getObjectMemberIfNullableReceiver(leftType, equalsName);
- ObjectAccessTarget equalsTarget = objectEqualsTarget ??
- inferrer.findInterfaceMember(leftType, equalsName, fileOffset,
- includeExtensionMethods: true);
+ ObjectAccessTarget equalsTarget = inferrer.findInterfaceMember(
+ leftType, equalsName, fileOffset,
+ includeExtensionMethods: true);
bool typeNeeded = !inferrer.isTopLevel;
ExpressionInferenceResult rightResult = inferrer.inferExpression(
@@ -3515,6 +3516,7 @@
extensionAccessCandidates: binaryTarget.candidates);
break;
case ObjectAccessTargetKind.extensionMember:
+ case ObjectAccessTargetKind.nullableExtensionMember:
assert(binaryTarget.extensionMethodKind != ProcedureKind.Setter);
binary = new StaticInvocation(
binaryTarget.member,
@@ -3526,9 +3528,11 @@
..fileOffset = fileOffset;
break;
case ObjectAccessTargetKind.instanceMember:
+ case ObjectAccessTargetKind.nullableInstanceMember:
case ObjectAccessTargetKind.invalid:
case ObjectAccessTargetKind.unresolved:
case ObjectAccessTargetKind.callFunction:
+ case ObjectAccessTargetKind.nullableCallFunction:
case ObjectAccessTargetKind.dynamic:
case ObjectAccessTargetKind.never:
if (binaryTarget.isInstanceMember &&
@@ -3568,19 +3572,15 @@
}
break;
}
- if (!inferrer.isTopLevel && inferrer.isNonNullableByDefault) {
- if (leftType is! InvalidType &&
- leftType is! DynamicType &&
- isPotentiallyNullable(leftType, inferrer.coreTypes.futureOrClass)) {
- return new ExpressionInferenceResult(
- binaryType,
- inferrer.helper.wrapInProblem(
- binary,
- templateNullableOperatorCallError.withArguments(
- binaryName.name, leftType, inferrer.isNonNullableByDefault),
- binary.fileOffset,
- binaryName.name.length));
- }
+ if (!inferrer.isTopLevel && binaryTarget.isNullable) {
+ return new ExpressionInferenceResult(
+ binaryType,
+ inferrer.helper.wrapInProblem(
+ binary,
+ templateNullableOperatorCallError.withArguments(
+ binaryName.name, leftType, inferrer.isNonNullableByDefault),
+ binary.fileOffset,
+ binaryName.name.length));
}
return new ExpressionInferenceResult(binaryType, binary);
}
@@ -3614,6 +3614,7 @@
extensionAccessCandidates: unaryTarget.candidates);
break;
case ObjectAccessTargetKind.extensionMember:
+ case ObjectAccessTargetKind.nullableExtensionMember:
assert(unaryTarget.extensionMethodKind != ProcedureKind.Setter);
unary = new StaticInvocation(
unaryTarget.member,
@@ -3624,9 +3625,11 @@
..fileOffset = fileOffset;
break;
case ObjectAccessTargetKind.instanceMember:
+ case ObjectAccessTargetKind.nullableInstanceMember:
case ObjectAccessTargetKind.invalid:
case ObjectAccessTargetKind.unresolved:
case ObjectAccessTargetKind.callFunction:
+ case ObjectAccessTargetKind.nullableCallFunction:
case ObjectAccessTargetKind.dynamic:
case ObjectAccessTargetKind.never:
if (unaryTarget.isInstanceMember &&
@@ -3662,22 +3665,17 @@
}
break;
}
- if (!inferrer.isTopLevel && inferrer.isNonNullableByDefault) {
- if (expressionType is! InvalidType &&
- expressionType is! DynamicType &&
- isPotentiallyNullable(
- expressionType, inferrer.coreTypes.futureOrClass)) {
- // TODO(johnniwinther): Special case 'unary-' in messages. It should
- // probably be referred to as "Unary operator '-' ...".
- return new ExpressionInferenceResult(
- unaryType,
- inferrer.helper.wrapInProblem(
- unary,
- templateNullableOperatorCallError.withArguments(unaryName.name,
- expressionType, inferrer.isNonNullableByDefault),
- unary.fileOffset,
- unaryName == unaryMinusName ? 1 : unaryName.name.length));
- }
+ if (!inferrer.isTopLevel && unaryTarget.isNullable) {
+ // TODO(johnniwinther): Special case 'unary-' in messages. It should
+ // probably be referred to as "Unary operator '-' ...".
+ return new ExpressionInferenceResult(
+ unaryType,
+ inferrer.helper.wrapInProblem(
+ unary,
+ templateNullableOperatorCallError.withArguments(unaryName.name,
+ expressionType, inferrer.isNonNullableByDefault),
+ unary.fileOffset,
+ unaryName == unaryMinusName ? 1 : unaryName.name.length));
}
return new ExpressionInferenceResult(unaryType, unary);
}
@@ -3708,6 +3706,7 @@
extensionAccessCandidates: readTarget.candidates);
break;
case ObjectAccessTargetKind.extensionMember:
+ case ObjectAccessTargetKind.nullableExtensionMember:
read = new StaticInvocation(
readTarget.member,
new Arguments(<Expression>[
@@ -3718,9 +3717,11 @@
..fileOffset = fileOffset;
break;
case ObjectAccessTargetKind.instanceMember:
+ case ObjectAccessTargetKind.nullableInstanceMember:
case ObjectAccessTargetKind.invalid:
case ObjectAccessTargetKind.unresolved:
case ObjectAccessTargetKind.callFunction:
+ case ObjectAccessTargetKind.nullableCallFunction:
case ObjectAccessTargetKind.dynamic:
case ObjectAccessTargetKind.never:
read = new MethodInvocation(
@@ -3748,22 +3749,15 @@
}
break;
}
- if (!inferrer.isTopLevel && inferrer.isNonNullableByDefault) {
- if (receiverType is! DynamicType &&
- receiverType is! InvalidType &&
- isPotentiallyNullable(
- receiverType, inferrer.coreTypes.futureOrClass)) {
- return new ExpressionInferenceResult(
- readType,
- inferrer.helper.wrapInProblem(
- read,
- templateNullableOperatorCallError.withArguments(
- indexGetName.name,
- receiverType,
- inferrer.isNonNullableByDefault),
- read.fileOffset,
- noLength));
- }
+ if (!inferrer.isTopLevel && readTarget.isNullable) {
+ return new ExpressionInferenceResult(
+ readType,
+ inferrer.helper.wrapInProblem(
+ read,
+ templateNullableOperatorCallError.withArguments(indexGetName.name,
+ receiverType, inferrer.isNonNullableByDefault),
+ read.fileOffset,
+ noLength));
}
return new ExpressionInferenceResult(readType, read);
}
@@ -3796,6 +3790,7 @@
extensionAccessCandidates: writeTarget.candidates);
break;
case ObjectAccessTargetKind.extensionMember:
+ case ObjectAccessTargetKind.nullableExtensionMember:
assert(writeTarget.extensionMethodKind != ProcedureKind.Setter);
write = new StaticInvocation(
writeTarget.member,
@@ -3805,9 +3800,11 @@
..fileOffset = fileOffset;
break;
case ObjectAccessTargetKind.instanceMember:
+ case ObjectAccessTargetKind.nullableInstanceMember:
case ObjectAccessTargetKind.invalid:
case ObjectAccessTargetKind.unresolved:
case ObjectAccessTargetKind.callFunction:
+ case ObjectAccessTargetKind.nullableCallFunction:
case ObjectAccessTargetKind.dynamic:
case ObjectAccessTargetKind.never:
write = new MethodInvocation(
@@ -3818,18 +3815,13 @@
..fileOffset = fileOffset;
break;
}
- if (!inferrer.isTopLevel && inferrer.isNonNullableByDefault) {
- if (receiverType is! InvalidType &&
- receiverType is! DynamicType &&
- isPotentiallyNullable(
- receiverType, inferrer.coreTypes.futureOrClass)) {
- return inferrer.helper.wrapInProblem(
- write,
- templateNullableOperatorCallError.withArguments(indexSetName.name,
- receiverType, inferrer.isNonNullableByDefault),
- write.fileOffset,
- noLength);
- }
+ if (!inferrer.isTopLevel && writeTarget.isNullable) {
+ return inferrer.helper.wrapInProblem(
+ write,
+ templateNullableOperatorCallError.withArguments(
+ indexSetName.name, receiverType, inferrer.isNonNullableByDefault),
+ write.fileOffset,
+ noLength);
}
return write;
}
@@ -3851,16 +3843,14 @@
{bool isThisReceiver}) {
assert(isThisReceiver != null);
- ObjectAccessTarget objectReadTarget =
- inferrer.getObjectMemberIfNullableReceiver(receiverType, propertyName);
-
- ObjectAccessTarget readTarget = objectReadTarget ??
- inferrer.findInterfaceMember(receiverType, propertyName, fileOffset,
- includeExtensionMethods: true);
+ ObjectAccessTarget readTarget = inferrer.findInterfaceMember(
+ receiverType, propertyName, fileOffset,
+ includeExtensionMethods: true);
DartType readType = inferrer.getGetterType(readTarget, receiverType);
Expression read;
+ ExpressionInferenceResult readResult;
switch (readTarget.kind) {
case ObjectAccessTargetKind.missing:
read = inferrer.createMissingPropertyGet(
@@ -3872,6 +3862,7 @@
extensionAccessCandidates: readTarget.candidates);
break;
case ObjectAccessTargetKind.extensionMember:
+ case ObjectAccessTargetKind.nullableExtensionMember:
switch (readTarget.extensionMethodKind) {
case ProcedureKind.Getter:
read = new StaticInvocation(
@@ -3890,7 +3881,9 @@
], types: readTarget.inferredExtensionTypeArguments)
..fileOffset = fileOffset)
..fileOffset = fileOffset;
- return inferrer.instantiateTearOff(readType, typeContext, read);
+ readResult =
+ inferrer.instantiateTearOff(readType, typeContext, read);
+ break;
case ProcedureKind.Setter:
case ProcedureKind.Factory:
case ProcedureKind.Operator:
@@ -3899,9 +3892,11 @@
}
break;
case ObjectAccessTargetKind.instanceMember:
+ case ObjectAccessTargetKind.nullableInstanceMember:
case ObjectAccessTargetKind.invalid:
case ObjectAccessTargetKind.unresolved:
case ObjectAccessTargetKind.callFunction:
+ case ObjectAccessTargetKind.nullableCallFunction:
case ObjectAccessTargetKind.dynamic:
case ObjectAccessTargetKind.never:
if (readTarget.isInstanceMember &&
@@ -3945,30 +3940,20 @@
}
Member member = readTarget.member;
if (member is Procedure && member.kind == ProcedureKind.Method) {
- return inferrer.instantiateTearOff(readType, typeContext, read);
+ readResult = inferrer.instantiateTearOff(readType, typeContext, read);
}
break;
}
- if (!inferrer.isTopLevel && inferrer.isNonNullableByDefault) {
- if (receiverType is! DynamicType &&
- receiverType is! InvalidType &&
- isPotentiallyNullable(
- receiverType, inferrer.coreTypes.futureOrClass) &&
- !inferrer.matchesObjectMemberCall(
- propertyName, const [], const [], const [])) {
- return new ExpressionInferenceResult(
- readType,
- inferrer.helper.wrapInProblem(
- read,
- templateNullablePropertyAccessError.withArguments(
- propertyName.name,
- receiverType,
- inferrer.isNonNullableByDefault),
- read.fileOffset,
- propertyName.name.length));
- }
+ readResult ??= new ExpressionInferenceResult(readType, read);
+ if (!inferrer.isTopLevel && readTarget.isNullable) {
+ readResult = inferrer.wrapExpressionInferenceResultInProblem(
+ readResult,
+ templateNullablePropertyAccessError.withArguments(
+ propertyName.name, receiverType, inferrer.isNonNullableByDefault),
+ read.fileOffset,
+ propertyName.name.length);
}
- return new ExpressionInferenceResult(readType, read);
+ return readResult;
}
/// Creates a property set operation of [writeTarget] on [receiver] using
@@ -4008,6 +3993,7 @@
extensionAccessCandidates: writeTarget.candidates);
break;
case ObjectAccessTargetKind.extensionMember:
+ case ObjectAccessTargetKind.nullableExtensionMember:
if (forEffect) {
write = new StaticInvocation(
writeTarget.member,
@@ -4032,9 +4018,11 @@
}
break;
case ObjectAccessTargetKind.instanceMember:
+ case ObjectAccessTargetKind.nullableInstanceMember:
case ObjectAccessTargetKind.invalid:
case ObjectAccessTargetKind.unresolved:
case ObjectAccessTargetKind.callFunction:
+ case ObjectAccessTargetKind.nullableCallFunction:
case ObjectAccessTargetKind.dynamic:
case ObjectAccessTargetKind.never:
write =
@@ -4042,17 +4030,13 @@
..fileOffset = fileOffset;
break;
}
- if (!inferrer.isTopLevel && inferrer.isNonNullableByDefault) {
- if (receiverType is! DynamicType &&
- isPotentiallyNullable(
- receiverType, inferrer.coreTypes.futureOrClass)) {
- return inferrer.helper.wrapInProblem(
- write,
- templateNullablePropertyAccessError.withArguments(propertyName.name,
- receiverType, inferrer.isNonNullableByDefault),
- write.fileOffset,
- propertyName.name.length);
- }
+ if (!inferrer.isTopLevel && writeTarget.isNullable) {
+ return inferrer.helper.wrapInProblem(
+ write,
+ templateNullablePropertyAccessError.withArguments(
+ propertyName.name, receiverType, inferrer.isNonNullableByDefault),
+ write.fileOffset,
+ propertyName.name.length);
}
return write;
@@ -4348,7 +4332,8 @@
ExpressionInferenceResult visitCompoundSuperIndexSet(
CompoundSuperIndexSet node, DartType typeContext) {
ObjectAccessTarget readTarget = node.getter != null
- ? new ObjectAccessTarget.interfaceMember(node.getter)
+ ? new ObjectAccessTarget.interfaceMember(node.getter,
+ isPotentiallyNullable: false)
: const ObjectAccessTarget.missing();
DartType readType = inferrer.getReturnType(readTarget, inferrer.thisType);
@@ -4400,7 +4385,8 @@
DartType binaryType = binaryResult.inferredType;
ObjectAccessTarget writeTarget = node.setter != null
- ? new ObjectAccessTarget.interfaceMember(node.setter)
+ ? new ObjectAccessTarget.interfaceMember(node.setter,
+ isPotentiallyNullable: false)
: const ObjectAccessTarget.missing();
DartType writeIndexType =
@@ -5102,7 +5088,8 @@
node,
typeContext,
node.interfaceTarget != null
- ? new ObjectAccessTarget.interfaceMember(node.interfaceTarget)
+ ? new ObjectAccessTarget.interfaceMember(node.interfaceTarget,
+ isPotentiallyNullable: false)
: const ObjectAccessTarget.unresolved());
}
@@ -5120,7 +5107,8 @@
node,
typeContext,
node.interfaceTarget != null
- ? new ObjectAccessTarget.interfaceMember(node.interfaceTarget)
+ ? new ObjectAccessTarget.interfaceMember(node.interfaceTarget,
+ isPotentiallyNullable: false)
: const ObjectAccessTarget.unresolved());
}
diff --git a/pkg/front_end/lib/src/fasta/source/stack_listener_impl.dart b/pkg/front_end/lib/src/fasta/source/stack_listener_impl.dart
index 5e3b43a..26baf64 100644
--- a/pkg/front_end/lib/src/fasta/source/stack_listener_impl.dart
+++ b/pkg/front_end/lib/src/fasta/source/stack_listener_impl.dart
@@ -81,8 +81,10 @@
addProblem(messageNonNullableOptOut, token.charOffset, token.charCount);
}
} else {
- addProblem(templateExperimentNotEnabled.withArguments('non-nullable'),
- token.offset, noLength);
+ addProblem(
+ templateExperimentNotEnabled.withArguments('non-nullable', '2.9'),
+ token.offset,
+ noLength);
}
}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/factor_type.dart b/pkg/front_end/lib/src/fasta/type_inference/factor_type.dart
index 26ea347..6f93a2b 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/factor_type.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/factor_type.dart
@@ -18,6 +18,9 @@
// * Else if T is R? then factor(R, S)?
if (T.nullability == Nullability.nullable) {
DartType R = T.withNullability(Nullability.nonNullable);
+ if (identical(R, T)) {
+ return T;
+ }
DartType factor_RS = factorType(typeEnvironment, R, S);
if (typeEnvironment.isSubtypeOf(
typeEnvironment.nullType, S, SubtypeCheckMode.withNullabilities)) {
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
index b33a2df..018b077 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
@@ -40,6 +40,8 @@
import '../source/source_library_builder.dart' show SourceLibraryBuilder;
+import 'factor_type.dart';
+
import 'type_inferrer.dart';
import 'type_schema_environment.dart' show TypeSchemaEnvironment;
@@ -253,6 +255,11 @@
TypeOperationsCfe(this.typeEnvironment);
+ @override
+ DartType factor(DartType from, DartType what) {
+ return factorType(typeEnvironment, from, what);
+ }
+
// TODO(dmitryas): Consider checking for mutual subtypes instead of ==.
@override
bool isSameType(DartType type1, DartType type2) => type1 == type2;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index d2628dd..3d30680 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -1014,6 +1014,153 @@
return inferredTypes;
}
+ /// Returns the extension member access by the given [name] for a receiver
+ /// with the static [receiverType].
+ ///
+ /// If none is found, [defaultTarget] is returned.
+ ///
+ /// If multiple are found, none more specific, an
+ /// [AmbiguousExtensionAccessTarget] is returned. This access kind results in
+ /// a compile-time error, but is used to provide a better message than just
+ /// reporting that the receiver does not have a member by the given name.
+ ///
+ /// If [isPotentiallyNullableAccess] is `true`, the returned extension member
+ /// is flagged as a nullable extension member access. This access kind results
+ /// in a compile-time error, but is used to provide a better message than just
+ /// reporting that the receiver does not have a member by the given name.
+ ObjectAccessTarget _findExtensionMember(
+ DartType receiverType, Class classNode, Name name, int fileOffset,
+ {bool setter: false,
+ ObjectAccessTarget defaultTarget,
+ bool isPotentiallyNullableAccess: false}) {
+ Name otherName = name;
+ bool otherIsSetter;
+ if (name == indexGetName) {
+ // [] must be checked against []=.
+ otherName = indexSetName;
+ otherIsSetter = false;
+ } else if (name == indexSetName) {
+ // []= must be checked against [].
+ otherName = indexGetName;
+ otherIsSetter = false;
+ } else {
+ otherName = name;
+ otherIsSetter = !setter;
+ }
+
+ Member otherMember =
+ _getInterfaceMember(classNode, otherName, otherIsSetter, fileOffset);
+ if (otherMember != null) {
+ // If we're looking for `foo` and `foo=` can be found or vice-versa then
+ // extension methods should not be found.
+ return defaultTarget;
+ }
+
+ ExtensionAccessCandidate bestSoFar;
+ List<ExtensionAccessCandidate> noneMoreSpecific = [];
+ library.forEachExtensionInScope((ExtensionBuilder extensionBuilder) {
+ MemberBuilder thisBuilder =
+ extensionBuilder.lookupLocalMemberByName(name, setter: setter);
+ MemberBuilder otherBuilder = extensionBuilder
+ .lookupLocalMemberByName(otherName, setter: otherIsSetter);
+ if ((thisBuilder != null && !thisBuilder.isStatic) ||
+ (otherBuilder != null && !otherBuilder.isStatic)) {
+ DartType onType;
+ DartType onTypeInstantiateToBounds;
+ List<DartType> inferredTypeArguments;
+ if (extensionBuilder.extension.typeParameters.isEmpty) {
+ onTypeInstantiateToBounds =
+ onType = extensionBuilder.extension.onType;
+ inferredTypeArguments = const <DartType>[];
+ } else {
+ List<TypeParameter> typeParameters =
+ extensionBuilder.extension.typeParameters;
+ inferredTypeArguments = inferExtensionTypeArguments(
+ extensionBuilder.extension, receiverType);
+ Substitution inferredSubstitution =
+ Substitution.fromPairs(typeParameters, inferredTypeArguments);
+
+ for (int index = 0; index < typeParameters.length; index++) {
+ TypeParameter typeParameter = typeParameters[index];
+ DartType typeArgument = inferredTypeArguments[index];
+ DartType bound =
+ inferredSubstitution.substituteType(typeParameter.bound);
+ if (!typeSchemaEnvironment.isSubtypeOf(
+ typeArgument, bound, SubtypeCheckMode.withNullabilities)) {
+ return;
+ }
+ }
+ onType = inferredSubstitution
+ .substituteType(extensionBuilder.extension.onType);
+ List<DartType> instantiateToBoundTypeArguments = calculateBounds(
+ typeParameters, coreTypes.objectClass, library.library);
+ Substitution instantiateToBoundsSubstitution = Substitution.fromPairs(
+ typeParameters, instantiateToBoundTypeArguments);
+ onTypeInstantiateToBounds = instantiateToBoundsSubstitution
+ .substituteType(extensionBuilder.extension.onType);
+ }
+
+ if (typeSchemaEnvironment.isSubtypeOf(
+ receiverType, onType, SubtypeCheckMode.withNullabilities)) {
+ ExtensionAccessCandidate candidate = new ExtensionAccessCandidate(
+ thisBuilder ?? otherBuilder,
+ onType,
+ onTypeInstantiateToBounds,
+ thisBuilder != null &&
+ !thisBuilder.isField &&
+ !thisBuilder.isStatic
+ ? new ObjectAccessTarget.extensionMember(
+ setter
+ ? thisBuilder.writeTarget
+ : thisBuilder.invokeTarget,
+ thisBuilder.readTarget,
+ thisBuilder.kind,
+ inferredTypeArguments,
+ isPotentiallyNullable: isPotentiallyNullableAccess)
+ : const ObjectAccessTarget.missing(),
+ isPlatform: extensionBuilder.library.importUri.scheme == 'dart');
+ if (noneMoreSpecific.isNotEmpty) {
+ bool isMostSpecific = true;
+ for (ExtensionAccessCandidate other in noneMoreSpecific) {
+ bool isMoreSpecific =
+ candidate.isMoreSpecificThan(typeSchemaEnvironment, other);
+ if (isMoreSpecific != true) {
+ isMostSpecific = false;
+ break;
+ }
+ }
+ if (isMostSpecific) {
+ bestSoFar = candidate;
+ noneMoreSpecific.clear();
+ } else {
+ noneMoreSpecific.add(candidate);
+ }
+ } else if (bestSoFar == null) {
+ bestSoFar = candidate;
+ } else {
+ bool isMoreSpecific =
+ candidate.isMoreSpecificThan(typeSchemaEnvironment, bestSoFar);
+ if (isMoreSpecific == true) {
+ bestSoFar = candidate;
+ } else if (isMoreSpecific == null) {
+ noneMoreSpecific.add(bestSoFar);
+ noneMoreSpecific.add(candidate);
+ bestSoFar = null;
+ }
+ }
+ }
+ }
+ });
+ if (bestSoFar != null) {
+ return bestSoFar.target;
+ } else {
+ if (noneMoreSpecific.isNotEmpty) {
+ return new AmbiguousExtensionAccessTarget(noneMoreSpecific);
+ }
+ }
+ return defaultTarget;
+ }
+
/// Finds a member of [receiverType] called [name], and if it is found,
/// reports it through instrumentation using [fileOffset].
///
@@ -1032,12 +1179,41 @@
bool includeExtensionMethods: false}) {
assert(receiverType != null && isKnown(receiverType));
- receiverType = resolveTypeParameter(receiverType);
+ DartType receiverBound = resolveTypeParameter(receiverType);
- if (receiverType is FunctionType && name == callName) {
- return const ObjectAccessTarget.callFunction();
- } else if (receiverType is NeverType) {
- switch (receiverType.nullability) {
+ bool isReceiverTypePotentiallyNullable = isNonNullableByDefault &&
+ isPotentiallyNullable(receiverType, coreTypes.futureOrClass) &&
+ // Calls to `==` are always on a non-null receiver.
+ name != equalsName;
+
+ Class classNode = receiverBound is InterfaceType
+ ? receiverBound.classNode
+ : coreTypes.objectClass;
+
+ if (isReceiverTypePotentiallyNullable) {
+ Member member =
+ _getInterfaceMember(coreTypes.objectClass, name, setter, fileOffset);
+ if (member != null) {
+ return new ObjectAccessTarget.interfaceMember(member,
+ // Null implements all Object members so this is not considered a
+ // potentially nullable access.
+ isPotentiallyNullable: false);
+ }
+ if (includeExtensionMethods) {
+ ObjectAccessTarget target =
+ _findExtensionMember(receiverBound, classNode, name, fileOffset);
+ if (target != null) {
+ return target;
+ }
+ }
+ }
+
+ if (receiverBound is FunctionType && name == callName) {
+ return isReceiverTypePotentiallyNullable
+ ? const ObjectAccessTarget.nullableCallFunction()
+ : const ObjectAccessTarget.callFunction();
+ } else if (receiverBound is NeverType) {
+ switch (receiverBound.nullability) {
case Nullability.nonNullable:
return const ObjectAccessTarget.never();
case Nullability.nullable:
@@ -1047,332 +1223,65 @@
case Nullability.undetermined:
return internalProblem(
templateInternalProblemUnsupportedNullability.withArguments(
- "${receiverType.nullability}",
- receiverType,
+ "${receiverBound.nullability}",
+ receiverBound,
isNonNullableByDefault),
fileOffset,
library.fileUri);
}
}
- Class classNode = receiverType is InterfaceType
- ? receiverType.classNode
- : coreTypes.objectClass;
+
+ ObjectAccessTarget target;
Member interfaceMember =
_getInterfaceMember(classNode, name, setter, fileOffset);
- ObjectAccessTarget target;
if (interfaceMember != null) {
- target = new ObjectAccessTarget.interfaceMember(interfaceMember);
- } else if (receiverType is DynamicType) {
+ target = new ObjectAccessTarget.interfaceMember(interfaceMember,
+ isPotentiallyNullable: isReceiverTypePotentiallyNullable);
+ } else if (receiverBound is DynamicType) {
target = const ObjectAccessTarget.dynamic();
- } else if (receiverType is InvalidType) {
+ } else if (receiverBound is InvalidType) {
target = const ObjectAccessTarget.invalid();
- } else if (receiverType is InterfaceType &&
- receiverType.classNode == coreTypes.functionClass &&
+ } else if (receiverBound is InterfaceType &&
+ receiverBound.classNode == coreTypes.functionClass &&
name == callName) {
- target = const ObjectAccessTarget.callFunction();
+ target = isReceiverTypePotentiallyNullable
+ ? const ObjectAccessTarget.nullableCallFunction()
+ : const ObjectAccessTarget.callFunction();
} else {
target = const ObjectAccessTarget.missing();
}
if (instrumented &&
- receiverType != const DynamicType() &&
+ receiverBound != const DynamicType() &&
target.isInstanceMember) {
instrumentation?.record(uriForInstrumentation, fileOffset, 'target',
new InstrumentationValueForMember(target.member));
}
if (target.isUnresolved &&
- receiverType is! DynamicType &&
+ receiverBound is! DynamicType &&
includeExtensionMethods) {
- Name otherName = name;
- bool otherIsSetter;
- if (name == indexGetName) {
- // [] must be checked against []=.
- otherName = indexSetName;
- otherIsSetter = false;
- } else if (name == indexSetName) {
- // []= must be checked against [].
- otherName = indexGetName;
- otherIsSetter = false;
+ if (isReceiverTypePotentiallyNullable) {
+ // When the receiver type is potentially nullable we would have found
+ // the extension member above, if available. Therefore we know that we
+ // are in an erroneous case and instead look up the extension member on
+ // the non-nullable receiver bound but flag the found target as a
+ // nullable extension member access. This is done to provide the better
+ // error message that the extension member exists but that the access is
+ // invalid.
+ target = _findExtensionMember(
+ computeNonNullable(receiverBound), classNode, name, fileOffset,
+ setter: setter,
+ defaultTarget: target,
+ isPotentiallyNullableAccess: true);
} else {
- otherName = name;
- otherIsSetter = !setter;
- }
-
- Member otherMember =
- _getInterfaceMember(classNode, otherName, otherIsSetter, fileOffset);
- if (otherMember != null) {
- // If we're looking for `foo` and `foo=` can be found or vice-versa then
- // extension methods should not be found.
- return target;
- }
-
- ExtensionAccessCandidate bestSoFar;
- List<ExtensionAccessCandidate> noneMoreSpecific = [];
- library.forEachExtensionInScope((ExtensionBuilder extensionBuilder) {
- MemberBuilder thisBuilder =
- extensionBuilder.lookupLocalMemberByName(name, setter: setter);
- MemberBuilder otherBuilder = extensionBuilder
- .lookupLocalMemberByName(otherName, setter: otherIsSetter);
- if ((thisBuilder != null && !thisBuilder.isStatic) ||
- (otherBuilder != null && !otherBuilder.isStatic)) {
- DartType onType;
- DartType onTypeInstantiateToBounds;
- List<DartType> inferredTypeArguments;
- if (extensionBuilder.extension.typeParameters.isEmpty) {
- onTypeInstantiateToBounds =
- onType = extensionBuilder.extension.onType;
- inferredTypeArguments = const <DartType>[];
- } else {
- List<TypeParameter> typeParameters =
- extensionBuilder.extension.typeParameters;
- inferredTypeArguments = inferExtensionTypeArguments(
- extensionBuilder.extension, receiverType);
- Substitution inferredSubstitution =
- Substitution.fromPairs(typeParameters, inferredTypeArguments);
-
- for (int index = 0; index < typeParameters.length; index++) {
- TypeParameter typeParameter = typeParameters[index];
- DartType typeArgument = inferredTypeArguments[index];
- DartType bound =
- inferredSubstitution.substituteType(typeParameter.bound);
- if (!typeSchemaEnvironment.isSubtypeOf(
- typeArgument, bound, SubtypeCheckMode.withNullabilities)) {
- return;
- }
- }
- onType = inferredSubstitution
- .substituteType(extensionBuilder.extension.onType);
- List<DartType> instantiateToBoundTypeArguments = calculateBounds(
- typeParameters, coreTypes.objectClass, library.library);
- Substitution instantiateToBoundsSubstitution =
- Substitution.fromPairs(
- typeParameters, instantiateToBoundTypeArguments);
- onTypeInstantiateToBounds = instantiateToBoundsSubstitution
- .substituteType(extensionBuilder.extension.onType);
- }
-
- if (typeSchemaEnvironment.isSubtypeOf(
- receiverType, onType, SubtypeCheckMode.ignoringNullabilities)) {
- ExtensionAccessCandidate candidate = new ExtensionAccessCandidate(
- thisBuilder ?? otherBuilder,
- onType,
- onTypeInstantiateToBounds,
- thisBuilder != null &&
- !thisBuilder.isField &&
- !thisBuilder.isStatic
- ? new ObjectAccessTarget.extensionMember(
- setter
- ? thisBuilder.writeTarget
- : thisBuilder.invokeTarget,
- thisBuilder.readTarget,
- thisBuilder.kind,
- inferredTypeArguments)
- : const ObjectAccessTarget.missing(),
- isPlatform:
- extensionBuilder.library.importUri.scheme == 'dart');
- if (noneMoreSpecific.isNotEmpty) {
- bool isMostSpecific = true;
- for (ExtensionAccessCandidate other in noneMoreSpecific) {
- bool isMoreSpecific =
- candidate.isMoreSpecificThan(typeSchemaEnvironment, other);
- if (isMoreSpecific != true) {
- isMostSpecific = false;
- break;
- }
- }
- if (isMostSpecific) {
- bestSoFar = candidate;
- noneMoreSpecific.clear();
- } else {
- noneMoreSpecific.add(candidate);
- }
- } else if (bestSoFar == null) {
- bestSoFar = candidate;
- } else {
- bool isMoreSpecific = candidate.isMoreSpecificThan(
- typeSchemaEnvironment, bestSoFar);
- if (isMoreSpecific == true) {
- bestSoFar = candidate;
- } else if (isMoreSpecific == null) {
- noneMoreSpecific.add(bestSoFar);
- noneMoreSpecific.add(candidate);
- bestSoFar = null;
- }
- }
- }
- }
- });
- if (bestSoFar != null) {
- target = bestSoFar.target;
- } else {
- if (noneMoreSpecific.isNotEmpty) {
- target = new AmbiguousExtensionAccessTarget(noneMoreSpecific);
- }
+ target = _findExtensionMember(
+ receiverBound, classNode, name, fileOffset,
+ setter: setter, defaultTarget: target);
}
}
return target;
}
- /// Returns the Object member by given [name] if [receiverType] is potentially
- /// nullable.
- ///
- /// This method is used to infer nullable calls to Object member against the
- /// Object member signature and not the overridden signature.
- ///
- /// If the member is procedure that isn't applicable with the provided
- /// [arguments], `null` is returned. This is a special casing that ensures
- /// that calls that wouldn't match the Object member regardless of typing
- /// will be reported as nullable access of the overridden member instead of
- /// inapplicable access to the Object member.
- ObjectAccessTarget getObjectMemberIfNullableReceiver(
- DartType receiverType, Name name,
- [Arguments arguments]) {
- if (isNonNullableByDefault &&
- receiverType is! DynamicType &&
- receiverType is! InvalidType &&
- isPotentiallyNullable(receiverType, coreTypes.futureOrClass)) {
- ObjectAccessTarget target = findInterfaceMember(
- coreTypes.objectNonNullableRawType, name, -1,
- instrumented: false);
- if (target.isUnresolved) {
- // No member found.
- return null;
- }
- Member member = target.member;
- if (arguments != null &&
- member is Procedure &&
- member.kind == ProcedureKind.Method) {
- // A method is called.
- FunctionNode function = member.function;
- if (arguments.positional.length >
- function.positionalParameters.length) {
- // The call is not going to match the Object member so we report
- // a problem on the nullable access instead.
- return null;
- }
- if (arguments.named.isNotEmpty && function.namedParameters.isEmpty) {
- // The call is not going to match the Object member so we report
- // a problem on the nullable access instead.
- return null;
- }
- }
- return target;
- }
- return null;
- }
-
- /// True if [Object]'s member called [name] can be called with the arguments.
- ///
- /// Checks for the arity and the types of the arguments and tells if an
- /// invocation of a method [name] on the receiver with static type [Object]
- /// doesn't lead to a compile-time error.
- bool matchesObjectMemberCall(
- Name name,
- List<DartType> typeArguments,
- List<DartType> positionalArgumentTypes,
- List<NamedType> namedArgumentTypes) {
- ObjectAccessTarget target = findInterfaceMember(
- coreTypes.objectNonNullableRawType, name, -1,
- instrumented: false);
- if (target.isUnresolved) return false;
- return matchesMemberCall(target.member, typeArguments ?? const [],
- positionalArgumentTypes ?? const [], namedArgumentTypes ?? const []);
- }
-
- /// True if [member] can be called with the arguments.
- ///
- /// Checks for the arity and the types of the arguments and tells if an
- /// invocation of [member] doesn't lead to a compile-time error.
- bool matchesMemberCall(
- Member member,
- List<DartType> typeArguments,
- List<DartType> positionalArgumentTypes,
- List<NamedType> namedArgumentTypes) {
- FunctionNode function = member.function;
- List<TypeParameter> typeParameters = function.typeParameters;
- List<VariableDeclaration> positionalParameters =
- function.positionalParameters;
- List<VariableDeclaration> namedParameters = function.namedParameters;
- if (typeParameters.length != typeArguments.length ||
- positionalParameters.length < positionalArgumentTypes.length ||
- namedParameters.length < namedArgumentTypes.length) {
- // The number of arguments isn't compatible.
- return false;
- }
-
- // Assume that both named parameters and named arguments are sorted
- // lexicographically.
- assert(namedParameters.isEmpty ||
- namedParameters.skip(1).fold(
- namedParameters[0],
- (p, n) =>
- p != null && p.name.compareTo(n.name) <= 0 ? n : null) !=
- null);
- assert(namedArgumentTypes.isEmpty ||
- namedArgumentTypes.skip(1).fold(
- namedArgumentTypes[0],
- (p, n) =>
- p != null && p.name.compareTo(n.name) <= 0 ? n : null) !=
- null);
-
- Substitution substitution = typeParameters.isEmpty
- ? Substitution.empty
- : Substitution.fromPairs(typeParameters, typeArguments);
-
- {
- int parameterIndex = 0;
- int argumentIndex = 0;
- while (parameterIndex < namedParameters.length &&
- argumentIndex < namedArgumentTypes.length) {
- VariableDeclaration parameter = namedParameters[parameterIndex];
- NamedType argument = namedArgumentTypes[argumentIndex];
- int compareResult = parameter.name.compareTo(argument.name);
- if (compareResult == 0) {
- if (!isAssignable(
- substitution.substituteType(parameter.type), argument.type)) {
- // Types aren't compatible.
- return false;
- }
- ++parameterIndex;
- ++argumentIndex;
- } else if (compareResult < 0) {
- if (parameter.isRequired) {
- // A required parameter is skipped.
- return false;
- }
- ++parameterIndex;
- } else {
- assert(compareResult > 0);
- // Extra argument.
- return false;
- }
- }
- }
- for (int i = 0; i < positionalArgumentTypes.length; ++i) {
- VariableDeclaration parameter = positionalParameters[i];
- DartType argument = positionalArgumentTypes[i];
- if (!isAssignable(
- substitution.substituteType(parameter.type), argument)) {
- // Types aren't compatible.
- return false;
- }
- }
- for (int i = 0; i < typeArguments.length; ++i) {
- TypeParameter parameter = typeParameters[i];
- DartType argument = typeArguments[i];
- if (!typeSchemaEnvironment.isSubtypeOf(
- argument,
- substitution.substituteType(parameter.bound),
- library.isNonNullableByDefault
- ? SubtypeCheckMode.withNullabilities
- : SubtypeCheckMode.ignoringNullabilities)) {
- // The type argument doesn't conform to the bound.
- return false;
- }
- }
- return true;
- }
-
/// If target is missing on a non-dynamic receiver, an error is reported
/// using [errorTemplate] and an invalid expression is returned.
Expression reportMissingInterfaceMember(
@@ -1413,6 +1322,7 @@
DartType getGetterType(ObjectAccessTarget target, DartType receiverType) {
switch (target.kind) {
case ObjectAccessTargetKind.callFunction:
+ case ObjectAccessTargetKind.nullableCallFunction:
return receiverType;
case ObjectAccessTargetKind.invalid:
return const InvalidType();
@@ -1424,8 +1334,10 @@
case ObjectAccessTargetKind.never:
return const NeverType(Nullability.nonNullable);
case ObjectAccessTargetKind.instanceMember:
+ case ObjectAccessTargetKind.nullableInstanceMember:
return getGetterTypeForMemberTarget(target.member, receiverType);
case ObjectAccessTargetKind.extensionMember:
+ case ObjectAccessTargetKind.nullableExtensionMember:
switch (target.extensionMethodKind) {
case ProcedureKind.Method:
case ProcedureKind.Operator:
@@ -1520,6 +1432,7 @@
ObjectAccessTarget target, DartType receiverType) {
switch (target.kind) {
case ObjectAccessTargetKind.callFunction:
+ case ObjectAccessTargetKind.nullableCallFunction:
return _getFunctionType(receiverType);
case ObjectAccessTargetKind.unresolved:
case ObjectAccessTargetKind.dynamic:
@@ -1529,9 +1442,11 @@
case ObjectAccessTargetKind.ambiguous:
return unknownFunction;
case ObjectAccessTargetKind.instanceMember:
+ case ObjectAccessTargetKind.nullableInstanceMember:
return _getFunctionType(
getGetterTypeForMemberTarget(target.member, receiverType));
case ObjectAccessTargetKind.extensionMember:
+ case ObjectAccessTargetKind.nullableExtensionMember:
switch (target.extensionMethodKind) {
case ProcedureKind.Method:
case ProcedureKind.Operator:
@@ -1567,11 +1482,13 @@
DartType getReturnType(ObjectAccessTarget target, DartType receiverType) {
switch (target.kind) {
case ObjectAccessTargetKind.instanceMember:
+ case ObjectAccessTargetKind.nullableInstanceMember:
FunctionType functionType = _getFunctionType(
getGetterTypeForMemberTarget(target.member, receiverType));
return functionType.returnType;
break;
case ObjectAccessTargetKind.extensionMember:
+ case ObjectAccessTargetKind.nullableExtensionMember:
switch (target.extensionMethodKind) {
case ProcedureKind.Operator:
FunctionType functionType =
@@ -1593,6 +1510,7 @@
case ObjectAccessTargetKind.invalid:
return const InvalidType();
case ObjectAccessTargetKind.callFunction:
+ case ObjectAccessTargetKind.nullableCallFunction:
case ObjectAccessTargetKind.unresolved:
case ObjectAccessTargetKind.dynamic:
case ObjectAccessTargetKind.missing:
@@ -1606,6 +1524,7 @@
ObjectAccessTarget target, DartType receiverType, int index) {
switch (target.kind) {
case ObjectAccessTargetKind.instanceMember:
+ case ObjectAccessTargetKind.nullableInstanceMember:
FunctionType functionType = _getFunctionType(
getGetterTypeForMemberTarget(target.member, receiverType));
if (functionType.positionalParameters.length > index) {
@@ -1613,6 +1532,7 @@
}
break;
case ObjectAccessTargetKind.extensionMember:
+ case ObjectAccessTargetKind.nullableExtensionMember:
FunctionType functionType =
target.member.function.computeFunctionType(library.nonNullable);
if (functionType.positionalParameters.length > index + 1) {
@@ -1629,6 +1549,7 @@
case ObjectAccessTargetKind.invalid:
return const InvalidType();
case ObjectAccessTargetKind.callFunction:
+ case ObjectAccessTargetKind.nullableCallFunction:
case ObjectAccessTargetKind.unresolved:
case ObjectAccessTargetKind.dynamic:
case ObjectAccessTargetKind.never:
@@ -1661,6 +1582,7 @@
DartType getIndexKeyType(ObjectAccessTarget target, DartType receiverType) {
switch (target.kind) {
case ObjectAccessTargetKind.instanceMember:
+ case ObjectAccessTargetKind.nullableInstanceMember:
FunctionType functionType = _getFunctionType(
getGetterTypeForMemberTarget(target.member, receiverType));
if (functionType.positionalParameters.length >= 1) {
@@ -1668,6 +1590,7 @@
}
break;
case ObjectAccessTargetKind.extensionMember:
+ case ObjectAccessTargetKind.nullableExtensionMember:
switch (target.extensionMethodKind) {
case ProcedureKind.Operator:
FunctionType functionType =
@@ -1690,6 +1613,7 @@
case ObjectAccessTargetKind.invalid:
return const InvalidType();
case ObjectAccessTargetKind.callFunction:
+ case ObjectAccessTargetKind.nullableCallFunction:
case ObjectAccessTargetKind.unresolved:
case ObjectAccessTargetKind.dynamic:
case ObjectAccessTargetKind.never:
@@ -1719,6 +1643,7 @@
ObjectAccessTarget target, DartType receiverType) {
switch (target.kind) {
case ObjectAccessTargetKind.instanceMember:
+ case ObjectAccessTargetKind.nullableInstanceMember:
FunctionType functionType = _getFunctionType(
getGetterTypeForMemberTarget(target.member, receiverType));
if (functionType.positionalParameters.length >= 2) {
@@ -1726,6 +1651,7 @@
}
break;
case ObjectAccessTargetKind.extensionMember:
+ case ObjectAccessTargetKind.nullableExtensionMember:
switch (target.extensionMethodKind) {
case ProcedureKind.Operator:
FunctionType functionType =
@@ -1748,6 +1674,7 @@
case ObjectAccessTargetKind.invalid:
return const InvalidType();
case ObjectAccessTargetKind.callFunction:
+ case ObjectAccessTargetKind.nullableCallFunction:
case ObjectAccessTargetKind.unresolved:
case ObjectAccessTargetKind.dynamic:
case ObjectAccessTargetKind.never:
@@ -1812,6 +1739,7 @@
case ObjectAccessTargetKind.invalid:
return const InvalidType();
case ObjectAccessTargetKind.instanceMember:
+ case ObjectAccessTargetKind.nullableInstanceMember:
Member interfaceMember = target.member;
Class memberClass = interfaceMember.enclosingClass;
DartType setterType;
@@ -1840,6 +1768,7 @@
}
return setterType;
case ObjectAccessTargetKind.extensionMember:
+ case ObjectAccessTargetKind.nullableExtensionMember:
switch (target.extensionMethodKind) {
case ProcedureKind.Setter:
FunctionType functionType =
@@ -1861,6 +1790,7 @@
// TODO(johnniwinther): Compute the right setter type.
return const DynamicType();
case ObjectAccessTargetKind.callFunction:
+ case ObjectAccessTargetKind.nullableCallFunction:
break;
}
throw unhandled(target.runtimeType.toString(), 'getSetterType', null, null);
@@ -1946,6 +1876,19 @@
variable, variable.fileOffset, equalsMember, this);
}
+ ExpressionInferenceResult wrapExpressionInferenceResultInProblem(
+ ExpressionInferenceResult result,
+ Message message,
+ int fileOffset,
+ int length,
+ {List<LocatedMessage> context}) {
+ return createNullAwareExpressionInferenceResult(
+ result.inferredType,
+ helper.wrapInProblem(
+ result.nullAwareAction, message, fileOffset, length),
+ result.nullAwareGuards);
+ }
+
ExpressionInferenceResult createNullAwareExpressionInferenceResult(
DartType inferredType,
Expression expression,
@@ -2440,32 +2383,6 @@
"Inferred return type $inferredType contains free variables."
"Inferred function type: $calleeType.");
- if (!isTopLevel && isNonNullableByDefault) {
- if (receiverType != null &&
- receiverType is! DynamicType &&
- isPotentiallyNullable(receiverType, coreTypes.futureOrClass) &&
- !matchesObjectMemberCall(targetName, inferredTypes,
- positionalArgumentTypes, namedArgumentTypes)) {
- if (isImplicitCall) {
- return new WrapInProblemInferenceResult(
- inferredType,
- templateNullableExpressionCallError.withArguments(
- receiverType, isNonNullableByDefault),
- offset,
- noLength,
- helper);
- } else {
- return new WrapInProblemInferenceResult(
- inferredType,
- templateNullableMethodCallError.withArguments(
- targetName.name, receiverType, isNonNullableByDefault),
- offset,
- targetName.name.length,
- helper);
- }
- }
- }
-
return new SuccessfulInferenceResult(inferredType);
}
@@ -2563,12 +2480,15 @@
VariableDeclarationImpl formal = formals[i];
if (formal.isImplicitlyTyped) {
DartType inferredType;
- if (formalTypesFromContext[i] == coreTypes.nullType) {
- inferredType = coreTypes.objectRawType(library.nullable);
- } else if (formalTypesFromContext[i] != null) {
- inferredType = greatestClosure(
- substitution.substituteType(formalTypesFromContext[i]),
- bottomType);
+ if (formalTypesFromContext[i] != null) {
+ if (coreTypes.isBottom(formalTypesFromContext[i]) ||
+ coreTypes.isNull(formalTypesFromContext[i])) {
+ inferredType = coreTypes.objectRawType(library.nullable);
+ } else {
+ inferredType = greatestClosure(
+ substitution.substituteType(formalTypesFromContext[i]),
+ bottomType);
+ }
} else {
inferredType = const DynamicType();
}
@@ -2680,7 +2600,7 @@
StaticInvocation transformExtensionMethodInvocation(int fileOffset,
ObjectAccessTarget target, Expression receiver, Arguments arguments) {
- assert(target.isExtensionMember);
+ assert(target.isExtensionMember || target.isNullableExtensionMember);
Procedure procedure = target.member;
return engine.forest.createStaticInvocation(
fileOffset,
@@ -2788,19 +2708,36 @@
List<VariableDeclaration> hoistedExpressions,
{bool isImplicitCall}) {
assert(isImplicitCall != null);
- assert(target.isExtensionMember);
+ assert(target.isExtensionMember || target.isNullableExtensionMember);
DartType calleeType = getGetterType(target, receiverType);
FunctionType functionType = getFunctionType(target, receiverType);
if (target.extensionMethodKind == ProcedureKind.Getter) {
StaticInvocation staticInvocation = transformExtensionMethodInvocation(
fileOffset, target, receiver, new Arguments.empty());
- return inferMethodInvocation(fileOffset, nullAwareGuards,
- staticInvocation, calleeType, callName, arguments, typeContext,
+ ExpressionInferenceResult result = inferMethodInvocation(
+ fileOffset,
+ nullAwareGuards,
+ staticInvocation,
+ calleeType,
+ callName,
+ arguments,
+ typeContext,
hoistedExpressions: hoistedExpressions,
isExpressionInvocation: false,
isImplicitCall: true,
implicitInvocationPropertyName: name);
+
+ if (!isTopLevel && target.isNullable) {
+ result = wrapExpressionInferenceResultInProblem(
+ result,
+ templateNullableExpressionCallError.withArguments(
+ receiverType, isNonNullableByDefault),
+ fileOffset,
+ noLength);
+ }
+
+ return result;
} else {
StaticInvocation staticInvocation = transformExtensionMethodInvocation(
fileOffset, target, receiver, arguments);
@@ -2814,8 +2751,27 @@
library.checkBoundsInStaticInvocation(staticInvocation,
typeSchemaEnvironment, helper.uri, getTypeArgumentsInfo(arguments));
}
- return createNullAwareExpressionInferenceResult(result.inferredType,
- result.applyResult(staticInvocation), nullAwareGuards);
+
+ Expression replacement = result.applyResult(staticInvocation);
+ if (!isTopLevel && target.isNullable) {
+ if (isImplicitCall) {
+ replacement = helper.wrapInProblem(
+ replacement,
+ templateNullableExpressionCallError.withArguments(
+ receiverType, isNonNullableByDefault),
+ fileOffset,
+ noLength);
+ } else {
+ replacement = helper.wrapInProblem(
+ replacement,
+ templateNullableMethodCallError.withArguments(
+ name.name, receiverType, isNonNullableByDefault),
+ fileOffset,
+ name.name.length);
+ }
+ }
+ return createNullAwareExpressionInferenceResult(
+ result.inferredType, replacement, nullAwareGuards);
}
}
@@ -2830,19 +2786,36 @@
List<VariableDeclaration> hoistedExpressions,
{bool isImplicitCall}) {
assert(isImplicitCall != null);
- assert(target.isCallFunction);
+ assert(target.isCallFunction || target.isNullableCallFunction);
FunctionType functionType = getFunctionType(target, receiverType);
InvocationInferenceResult result = inferInvocation(
typeContext, fileOffset, functionType, arguments, callName,
hoistedExpressions: hoistedExpressions,
receiverType: receiverType,
isImplicitCall: isImplicitCall);
+ Expression replacement = result.applyResult(
+ new MethodInvocation(receiver, callName, arguments)
+ ..fileOffset = fileOffset);
+ if (!isTopLevel && target.isNullableCallFunction) {
+ if (isImplicitCall) {
+ replacement = helper.wrapInProblem(
+ replacement,
+ templateNullableExpressionCallError.withArguments(
+ receiverType, isNonNullableByDefault),
+ fileOffset,
+ noLength);
+ } else {
+ replacement = helper.wrapInProblem(
+ replacement,
+ templateNullableMethodCallError.withArguments(
+ callName.name, receiverType, isNonNullableByDefault),
+ fileOffset,
+ callName.name.length);
+ }
+ }
// TODO(johnniwinther): Check that type arguments against the bounds.
return createNullAwareExpressionInferenceResult(
- result.inferredType,
- result.applyResult(new MethodInvocation(receiver, callName, arguments)
- ..fileOffset = fileOffset),
- nullAwareGuards);
+ result.inferredType, replacement, nullAwareGuards);
}
ExpressionInferenceResult _inferInstanceMethodInvocation(
@@ -2856,7 +2829,7 @@
List<VariableDeclaration> hoistedExpressions,
{bool isImplicitCall}) {
assert(isImplicitCall != null);
- assert(target.isInstanceMember);
+ assert(target.isInstanceMember || target.isNullableInstanceMember);
Procedure method = target.member;
assert(method.kind == ProcedureKind.Method,
"Unexpected instance method $method");
@@ -2924,8 +2897,27 @@
new MethodInvocation(receiver, methodName, arguments, method)
..fileOffset = fileOffset;
+ replacement = result.applyResult(replacement);
+ if (!isTopLevel && target.isNullable) {
+ if (isImplicitCall) {
+ replacement = helper.wrapInProblem(
+ replacement,
+ templateNullableExpressionCallError.withArguments(
+ receiverType, isNonNullableByDefault),
+ fileOffset,
+ noLength);
+ } else {
+ replacement = helper.wrapInProblem(
+ replacement,
+ templateNullableMethodCallError.withArguments(
+ methodName.name, receiverType, isNonNullableByDefault),
+ fileOffset,
+ methodName.name.length);
+ }
+ }
+
return createNullAwareExpressionInferenceResult(
- result.inferredType, result.applyResult(replacement), nullAwareGuards);
+ result.inferredType, replacement, nullAwareGuards);
}
ExpressionInferenceResult _inferInstanceGetterInvocation(
@@ -2939,7 +2931,7 @@
List<VariableDeclaration> hoistedExpressions,
{bool isExpressionInvocation}) {
assert(isExpressionInvocation != null);
- assert(target.isInstanceMember);
+ assert(target.isInstanceMember || target.isNullableInstanceMember);
Procedure getter = target.member;
assert(getter.kind == ProcedureKind.Getter);
@@ -3015,6 +3007,16 @@
noLength);
return new ExpressionInferenceResult(const DynamicType(), error);
}
+
+ if (!isTopLevel && target.isNullable) {
+ invocationResult = wrapExpressionInferenceResultInProblem(
+ invocationResult,
+ templateNullableExpressionCallError.withArguments(
+ receiverType, isNonNullableByDefault),
+ fileOffset,
+ noLength);
+ }
+
if (!library.loader.target.backendTarget.supportsExplicitGetterCalls) {
// TODO(johnniwinther): Remove this when dart2js/ddc supports explicit
// getter calls.
@@ -3074,7 +3076,7 @@
List<VariableDeclaration> hoistedExpressions,
{bool isExpressionInvocation}) {
assert(isExpressionInvocation != null);
- assert(target.isInstanceMember);
+ assert(target.isInstanceMember || target.isNullableInstanceMember);
Field field = target.member;
DartType calleeType = getGetterType(target, receiverType);
@@ -3130,6 +3132,16 @@
noLength);
return new ExpressionInferenceResult(const DynamicType(), error);
}
+
+ if (!isTopLevel && target.isNullable) {
+ invocationResult = wrapExpressionInferenceResultInProblem(
+ invocationResult,
+ templateNullableExpressionCallError.withArguments(
+ receiverType, isNonNullableByDefault),
+ fileOffset,
+ noLength);
+ }
+
if (!library.loader.target.backendTarget.supportsExplicitGetterCalls) {
// TODO(johnniwinther): Remove this when dart2js/ddc supports explicit
// getter calls.
@@ -3170,14 +3182,12 @@
assert(isExpressionInvocation != null);
assert(isImplicitCall != null);
- ObjectAccessTarget objectReadTarget =
- getObjectMemberIfNullableReceiver(receiverType, name, arguments);
-
- ObjectAccessTarget target = objectReadTarget ??
- findInterfaceMember(receiverType, name, fileOffset,
- instrumented: true, includeExtensionMethods: true);
+ ObjectAccessTarget target = findInterfaceMember(
+ receiverType, name, fileOffset,
+ instrumented: true, includeExtensionMethods: true);
switch (target.kind) {
case ObjectAccessTargetKind.instanceMember:
+ case ObjectAccessTargetKind.nullableInstanceMember:
Member member = target.member;
if (member is Procedure) {
if (member.kind == ProcedureKind.Getter) {
@@ -3217,10 +3227,12 @@
}
break;
case ObjectAccessTargetKind.callFunction:
+ case ObjectAccessTargetKind.nullableCallFunction:
return _inferFunctionInvocation(fileOffset, nullAwareGuards, receiver,
receiverType, target, arguments, typeContext, hoistedExpressions,
isImplicitCall: isImplicitCall);
case ObjectAccessTargetKind.extensionMember:
+ case ObjectAccessTargetKind.nullableExtensionMember:
return _inferExtensionInvocation(
fileOffset,
nullAwareGuards,
@@ -3308,7 +3320,7 @@
bool isOverloadedArithmeticOperatorAndType(
ObjectAccessTarget target, DartType receiverType) {
- return target.isInstanceMember &&
+ return (target.isInstanceMember || target.isNullableInstanceMember) &&
target.member is Procedure &&
typeSchemaEnvironment.isOverloadedArithmeticOperatorAndType(
target.member, receiverType);
@@ -4193,14 +4205,48 @@
}
enum ObjectAccessTargetKind {
+ /// A valid access to a statically known instance member. The access is
+ /// either non-nullable or potentially nullable on a `Object` member.
instanceMember,
+
+ /// A potentially nullable access to a statically known instance member. This
+ /// is an erroneous case and a compile-time error is reported.
+ nullableInstanceMember,
+
+ /// A (non-nullable) access to the `.call` method of a function. This is used
+ /// for access on `Function` and on function types.
callFunction,
+
+ /// A potentially nullable access to the `.call` method of a function. This is
+ /// an erroneous case and a compile-time error is reported.
+ nullableCallFunction,
+
+ /// A valid access to an extension member.
extensionMember,
+
+ /// A potentially nullable access to an extension member on an extension of
+ /// a non-nullable type. This is an erroneous case and a compile-time error is
+ /// reported.
+ nullableExtensionMember,
+
+ /// An access on a receiver of type `dynamic`.
dynamic,
+
+ /// An access on a receiver of type `Never`.
never,
+
+ /// An access on a receiver of an invalid type. This case is the result of
+ /// a previously report error and no error is report this case.
invalid,
+
+ /// An access to a statically unknown instance member. This is an erroneous
+ /// case and a compile-time error is reported.
missing,
+
+ /// An access to multiple extension members, none of which are most specific.
+ /// This is an erroneous case and a compile-time error is reported.
ambiguous,
+
// TODO(johnniwinther): Remove this.
unresolved,
}
@@ -4214,10 +4260,15 @@
const ObjectAccessTarget.internal(this.kind, this.member);
/// Creates an access to the instance [member].
- factory ObjectAccessTarget.interfaceMember(Member member) {
+ factory ObjectAccessTarget.interfaceMember(Member member,
+ {bool isPotentiallyNullable}) {
assert(member != null);
+ assert(isPotentiallyNullable != null);
return new ObjectAccessTarget.internal(
- ObjectAccessTargetKind.instanceMember, member);
+ isPotentiallyNullable
+ ? ObjectAccessTargetKind.nullableInstanceMember
+ : ObjectAccessTargetKind.instanceMember,
+ member);
}
/// Creates an access to the extension [member].
@@ -4225,13 +4276,19 @@
Member member,
Member tearoffTarget,
ProcedureKind kind,
- List<DartType> inferredTypeArguments) = ExtensionAccessTarget;
+ List<DartType> inferredTypeArguments,
+ {bool isPotentiallyNullable}) = ExtensionAccessTarget;
/// Creates an access to a 'call' method on a function, i.e. a function
/// invocation.
const ObjectAccessTarget.callFunction()
: this.internal(ObjectAccessTargetKind.callFunction, null);
+ /// Creates an access to a 'call' method on a potentially nullable function,
+ /// i.e. a function invocation.
+ const ObjectAccessTarget.nullableCallFunction()
+ : this.internal(ObjectAccessTargetKind.nullableCallFunction, null);
+
/// Creates an access with no known target.
const ObjectAccessTarget.unresolved()
: this.internal(ObjectAccessTargetKind.unresolved, null);
@@ -4265,6 +4322,11 @@
/// Returns `true` if this is an access to the 'call' method on a function.
bool get isCallFunction => kind == ObjectAccessTargetKind.callFunction;
+ /// Returns `true` if this is an access to the 'call' method on a potentially
+ /// nullable function.
+ bool get isNullableCallFunction =>
+ kind == ObjectAccessTargetKind.nullableCallFunction;
+
/// Returns `true` if this is an access without a known target.
bool get isUnresolved =>
kind == ObjectAccessTargetKind.unresolved ||
@@ -4285,6 +4347,23 @@
/// occurs when an implicit extension access is ambiguous.
bool get isAmbiguous => kind == ObjectAccessTargetKind.ambiguous;
+ /// Returns `true` if this is an access to an instance member on a potentially
+ /// nullable receiver.
+ bool get isNullableInstanceMember =>
+ kind == ObjectAccessTargetKind.nullableInstanceMember;
+
+ /// Returns `true` if this is an access to an instance member on a potentially
+ /// nullable receiver.
+ bool get isNullableExtensionMember =>
+ kind == ObjectAccessTargetKind.nullableExtensionMember;
+
+ /// Returns `true` if this is an access to an instance member on a potentially
+ /// nullable receiver.
+ bool get isNullable =>
+ isNullableInstanceMember ||
+ isNullableCallFunction ||
+ isNullableExtensionMember;
+
/// Returns the candidates for an ambiguous extension access.
List<ExtensionAccessCandidate> get candidates =>
throw new UnsupportedError('ObjectAccessTarget.candidates');
@@ -4322,8 +4401,13 @@
final List<DartType> inferredExtensionTypeArguments;
ExtensionAccessTarget(Member member, this.tearoffTarget,
- this.extensionMethodKind, this.inferredExtensionTypeArguments)
- : super.internal(ObjectAccessTargetKind.extensionMember, member);
+ this.extensionMethodKind, this.inferredExtensionTypeArguments,
+ {bool isPotentiallyNullable: false})
+ : super.internal(
+ isPotentiallyNullable
+ ? ObjectAccessTargetKind.nullableExtensionMember
+ : ObjectAccessTargetKind.extensionMember,
+ member);
@override
String toString() =>
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 81c2a65..bf8b9c1 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -236,8 +236,8 @@
ExperimentNotEnabled:
index: 48
- template: "This requires the '#string' experiment to be enabled."
- tip: "Try enabling this experiment by adding it to the command line when compiling and running."
+ template: "This requires the '#string' language feature to be enabled."
+ tip: "Try updating your pubspec.yaml to set the minimum SDK constraint to #string2 or higher, and running 'pub get'."
analyzerCode: ParserErrorCode.EXPERIMENT_NOT_ENABLED
EmptyNamedParameterList:
diff --git a/pkg/front_end/test/fasta/type_inference/factor_type_test.dart b/pkg/front_end/test/fasta/type_inference/factor_type_test.dart
index 184c9f1..c56155d 100644
--- a/pkg/front_end/test/fasta/type_inference/factor_type_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/factor_type_test.dart
@@ -23,9 +23,11 @@
CoreTypes get coreTypes => typeEnvironment.coreTypes;
void run() {
+ test_dynamic();
test_futureOr();
test_object();
test_subtype();
+ test_void();
}
@override
@@ -49,6 +51,9 @@
coreTypes.futureOrClass, Nullability.nonNullable, [type]);
@override
+ DartType get dynamicType => const DynamicType();
+
+ @override
DartType get intNone => coreTypes.intNonNullableRawType;
@override
@@ -88,6 +93,9 @@
DartType get stringStar => coreTypes.stringLegacyRawType;
@override
+ DartType get voidType => const VoidType();
+
+ @override
String typeString(DartType type) =>
typeToText(type, TypeRepresentation.analyzerNonNullableByDefault);
}
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 88dcde6..5d57d7835 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -369,6 +369,7 @@
f
faced
factor
+factored
fangorn
fasta
favoring
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index 2327236..885f530 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -1170,6 +1170,7 @@
fixes
fixing
flag
+flagged
flags
flat
flatten
diff --git a/pkg/front_end/test/spell_checking_list_messages.txt b/pkg/front_end/test/spell_checking_list_messages.txt
index 1dbcdac..1e01dae 100644
--- a/pkg/front_end/test/spell_checking_list_messages.txt
+++ b/pkg/front_end/test/spell_checking_list_messages.txt
@@ -46,6 +46,7 @@
opts
part(s)
patch(es)
+pubspec.yaml
re
sdksummary
stacktrace
diff --git a/pkg/front_end/testcases/general/vm_type_ops.dart.outline.expect b/pkg/front_end/testcases/general/vm_type_ops.dart.outline.expect
index 3950bfe..441c807 100644
--- a/pkg/front_end/testcases/general/vm_type_ops.dart.outline.expect
+++ b/pkg/front_end/testcases/general/vm_type_ops.dart.outline.expect
@@ -48,7 +48,7 @@
;
method foo8<generic-covariant-impl Q extends self::H::T* = self::H::T*>(self::H::foo8::Q* a, covariant core::int* b, generic-covariant-impl self::H::T* c) → void
;
- forwarding-stub method foo7<generic-covariant-impl Q extends self::H::T*>(self::H::foo7::Q* a, covariant core::num* b, generic-covariant-impl self::H::T* c) → void
+ forwarding-stub method foo7<generic-covariant-impl Q extends self::H::T* = self::H::T*>(self::H::foo7::Q* a, covariant core::num* b, generic-covariant-impl self::H::T* c) → void
return super.{self::G::foo7}<self::H::foo7::Q*>(a, b, c);
}
static field core::List<core::Iterable<dynamic>*>* globalVar;
diff --git a/pkg/front_end/testcases/general/vm_type_ops.dart.strong.expect b/pkg/front_end/testcases/general/vm_type_ops.dart.strong.expect
index ced2c81..1418ee2 100644
--- a/pkg/front_end/testcases/general/vm_type_ops.dart.strong.expect
+++ b/pkg/front_end/testcases/general/vm_type_ops.dart.strong.expect
@@ -68,7 +68,7 @@
: super self::G::•()
;
method foo8<generic-covariant-impl Q extends self::H::T* = self::H::T*>(self::H::foo8::Q* a, covariant core::int* b, generic-covariant-impl self::H::T* c) → void {}
- forwarding-stub method foo7<generic-covariant-impl Q extends self::H::T*>(self::H::foo7::Q* a, covariant core::num* b, generic-covariant-impl self::H::T* c) → void
+ forwarding-stub method foo7<generic-covariant-impl Q extends self::H::T* = self::H::T*>(self::H::foo7::Q* a, covariant core::num* b, generic-covariant-impl self::H::T* c) → void
return super.{self::G::foo7}<self::H::foo7::Q*>(a, b, c);
}
static field core::List<core::Iterable<dynamic>*>* globalVar;
diff --git a/pkg/front_end/testcases/general/vm_type_ops.dart.strong.transformed.expect b/pkg/front_end/testcases/general/vm_type_ops.dart.strong.transformed.expect
index ced2c81..1418ee2 100644
--- a/pkg/front_end/testcases/general/vm_type_ops.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/vm_type_ops.dart.strong.transformed.expect
@@ -68,7 +68,7 @@
: super self::G::•()
;
method foo8<generic-covariant-impl Q extends self::H::T* = self::H::T*>(self::H::foo8::Q* a, covariant core::int* b, generic-covariant-impl self::H::T* c) → void {}
- forwarding-stub method foo7<generic-covariant-impl Q extends self::H::T*>(self::H::foo7::Q* a, covariant core::num* b, generic-covariant-impl self::H::T* c) → void
+ forwarding-stub method foo7<generic-covariant-impl Q extends self::H::T* = self::H::T*>(self::H::foo7::Q* a, covariant core::num* b, generic-covariant-impl self::H::T* c) → void
return super.{self::G::foo7}<self::H::foo7::Q*>(a, b, c);
}
static field core::List<core::Iterable<dynamic>*>* globalVar;
diff --git a/pkg/front_end/testcases/nnbd/covariant_equals.dart b/pkg/front_end/testcases/nnbd/covariant_equals.dart
index bcb77b7..b69bb3e 100644
--- a/pkg/front_end/testcases/nnbd/covariant_equals.dart
+++ b/pkg/front_end/testcases/nnbd/covariant_equals.dart
@@ -69,43 +69,46 @@
a == a; // ok
a == b; // ok
- a == c_dynamic; // ok
- a == c_int; // ok
- a == c_string; // ok
- a == d; // ok
+ // TODO(johnniwinther): Awaiting spec update about `==`. Before NNBD these
+ // would cause an error but with the current (insufficient) specification for
+ // `==` it is ok.
+ a == c_dynamic; // ok or error ?
+ a == c_int; // ok or error ?
+ a == c_string; // ok or error ?
+ a == d; // ok or error ?
b == a; // ok
b == b; // ok
- b == c_dynamic; // ok
- b == c_int; // ok
- b == c_string; // ok
- b == d; // ok
+ b == c_dynamic; // ok or error ?
+ b == c_int; // ok or error ?
+ b == c_string; // ok or error ?
+ b == d; // ok or error ?
- c_dynamic == a; // ok
- c_dynamic == b; // ok
+ c_dynamic == a; // ok or error ?
+ c_dynamic == b; // ok or error ?
c_dynamic == c_dynamic; // ok
c_dynamic == c_int; // ok
c_dynamic == c_string; // ok
c_dynamic == d; // ok
- c_int == a; // ok
- c_int == b; // ok
- c_int == c_dynamic; // ok
+ c_int == a; // ok or error ?
+ c_int == b; // ok or error ?
+ c_int == c_dynamic; // ok or error ?
c_int == c_int; // ok
- c_int == c_string; // ok
+ c_int == c_string; // ok or error ?
c_int == d; // ok}
- c_string == a; // ok
- c_string == b; // ok
- c_string == c_dynamic; // ok
- c_string == c_int; // ok
+ c_string == a; // ok or error ?
+ c_string == b; // ok or error ?
+ c_string == c_dynamic; // ok or error ?
+ c_string == c_int; // ok or error ?
c_string == c_string; // ok
- c_string == d; // ok
+ c_string == d; // ok or error ?
- d == a; // ok
- d == b; // ok
- d == c_dynamic; // ok
+ d == a; // ok or error ?
+ d == b; // ok or error ?
+ d == c_dynamic; // ok or error ?
d == c_int; // ok
- d == c_string; // ok
+ d == c_string; // ok or error ?
d == d; // ok
}
diff --git a/pkg/front_end/testcases/nnbd/covariant_equals.dart.strong.expect b/pkg/front_end/testcases/nnbd/covariant_equals.dart.strong.expect
index 93ef34b..6c746cd 100644
--- a/pkg/front_end/testcases/nnbd/covariant_equals.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/covariant_equals.dart.strong.expect
@@ -134,6 +134,138 @@
// d == c_string; // error
// ^
//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:75:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// a == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:76:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// a == c_int; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:77:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// a == c_string; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:78:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+// - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// a == d; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:82:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// b == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:83:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// b == c_int; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:84:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// b == c_string; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:85:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+// - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// b == d; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:87:16: Error: The argument type 'A?' can't be assigned to the parameter type 'C<dynamic>?'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_dynamic == a; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:88:16: Error: The argument type 'B?' can't be assigned to the parameter type 'C<dynamic>?'.
+// - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_dynamic == b; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:94:12: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_int == a; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:95:12: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+// - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_int == b; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:96:12: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_int == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:98:12: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_int == c_string; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:101:15: Error: The argument type 'A?' can't be assigned to the parameter type 'C<String>?'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == a; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:102:15: Error: The argument type 'B?' can't be assigned to the parameter type 'C<String>?'.
+// - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == b; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:103:15: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<String>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:104:15: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'C<String>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == c_int; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:106:15: Error: The argument type 'D?' can't be assigned to the parameter type 'C<String>?'.
+// - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == d; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:108:8: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// d == a; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:109:8: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+// - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// d == b; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:110:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// d == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:112:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// d == c_string; // ok or error ?
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -289,40 +421,126 @@
d.{self::C::==}(d);
}
static method testNullable(self::A? a, self::B? b, self::C<dynamic>? c_dynamic, self::C<core::int>? c_int, self::C<core::String>? c_string, self::D? d) → dynamic {
- a.{core::Object::==}(a);
- a.{core::Object::==}(b);
- a.{core::Object::==}(c_dynamic);
- a.{core::Object::==}(c_int);
- a.{core::Object::==}(c_string);
- a.{core::Object::==}(d);
- b.{core::Object::==}(a);
- b.{core::Object::==}(b);
- b.{core::Object::==}(c_dynamic);
- b.{core::Object::==}(c_int);
- b.{core::Object::==}(c_string);
- b.{core::Object::==}(d);
- c_dynamic.{core::Object::==}(a);
- c_dynamic.{core::Object::==}(b);
- c_dynamic.{core::Object::==}(c_dynamic);
- c_dynamic.{core::Object::==}(c_int);
- c_dynamic.{core::Object::==}(c_string);
- c_dynamic.{core::Object::==}(d);
- c_int.{core::Object::==}(a);
- c_int.{core::Object::==}(b);
- c_int.{core::Object::==}(c_dynamic);
- c_int.{core::Object::==}(c_int);
- c_int.{core::Object::==}(c_string);
- c_int.{core::Object::==}(d);
- c_string.{core::Object::==}(a);
- c_string.{core::Object::==}(b);
- c_string.{core::Object::==}(c_dynamic);
- c_string.{core::Object::==}(c_int);
- c_string.{core::Object::==}(c_string);
- c_string.{core::Object::==}(d);
- d.{core::Object::==}(a);
- d.{core::Object::==}(b);
- d.{core::Object::==}(c_dynamic);
- d.{core::Object::==}(c_int);
- d.{core::Object::==}(c_string);
- d.{core::Object::==}(d);
+ a.{self::A::==}(a);
+ a.{self::A::==}(b);
+ a.{self::A::==}(let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:75:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ a == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+ a.{self::A::==}(let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:76:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ a == c_int; // ok or error ?
+ ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+ a.{self::A::==}(let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:77:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ a == c_string; // ok or error ?
+ ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+ a.{self::A::==}(let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:78:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ a == d; // ok or error ?
+ ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+ b.{self::B::==}(a);
+ b.{self::B::==}(b);
+ b.{self::B::==}(let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:82:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ b == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+ b.{self::B::==}(let final<BottomType> #t29 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:83:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ b == c_int; // ok or error ?
+ ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+ b.{self::B::==}(let final<BottomType> #t30 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:84:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ b == c_string; // ok or error ?
+ ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+ b.{self::B::==}(let final<BottomType> #t31 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:85:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ b == d; // ok or error ?
+ ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+ c_dynamic.{self::C::==}(let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:87:16: Error: The argument type 'A?' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_dynamic == a; // ok or error ?
+ ^" in a as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+ c_dynamic.{self::C::==}(let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:88:16: Error: The argument type 'B?' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_dynamic == b; // ok or error ?
+ ^" in b as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+ c_dynamic.{self::C::==}(c_dynamic);
+ c_dynamic.{self::C::==}(c_int);
+ c_dynamic.{self::C::==}(c_string);
+ c_dynamic.{self::C::==}(d);
+ c_int.{self::C::==}(let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:94:12: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_int == a; // ok or error ?
+ ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ c_int.{self::C::==}(let final<BottomType> #t35 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:95:12: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_int == b; // ok or error ?
+ ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ c_int.{self::C::==}(let final<BottomType> #t36 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:96:12: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_int == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ c_int.{self::C::==}(c_int);
+ c_int.{self::C::==}(let final<BottomType> #t37 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:98:12: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_int == c_string; // ok or error ?
+ ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ c_int.{self::C::==}(d);
+ c_string.{self::C::==}(let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:101:15: Error: The argument type 'A?' can't be assigned to the parameter type 'C<String>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == a; // ok or error ?
+ ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ c_string.{self::C::==}(let final<BottomType> #t39 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:102:15: Error: The argument type 'B?' can't be assigned to the parameter type 'C<String>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == b; // ok or error ?
+ ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ c_string.{self::C::==}(let final<BottomType> #t40 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:103:15: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ c_string.{self::C::==}(let final<BottomType> #t41 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:104:15: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == c_int; // ok or error ?
+ ^" in c_int as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ c_string.{self::C::==}(c_string);
+ c_string.{self::C::==}(let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:106:15: Error: The argument type 'D?' can't be assigned to the parameter type 'C<String>?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == d; // ok or error ?
+ ^" in d as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ d.{self::C::==}(let final<BottomType> #t43 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:108:8: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ d == a; // ok or error ?
+ ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ d.{self::C::==}(let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:109:8: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ d == b; // ok or error ?
+ ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ d.{self::C::==}(let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:110:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ d == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ d.{self::C::==}(c_int);
+ d.{self::C::==}(let final<BottomType> #t46 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:112:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ d == c_string; // ok or error ?
+ ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ d.{self::C::==}(d);
}
diff --git a/pkg/front_end/testcases/nnbd/covariant_equals.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/covariant_equals.dart.strong.transformed.expect
index 93ef34b..6c746cd 100644
--- a/pkg/front_end/testcases/nnbd/covariant_equals.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/covariant_equals.dart.strong.transformed.expect
@@ -134,6 +134,138 @@
// d == c_string; // error
// ^
//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:75:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// a == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:76:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// a == c_int; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:77:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// a == c_string; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:78:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+// - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// a == d; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:82:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// b == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:83:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// b == c_int; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:84:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// b == c_string; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:85:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+// - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// b == d; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:87:16: Error: The argument type 'A?' can't be assigned to the parameter type 'C<dynamic>?'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_dynamic == a; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:88:16: Error: The argument type 'B?' can't be assigned to the parameter type 'C<dynamic>?'.
+// - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_dynamic == b; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:94:12: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_int == a; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:95:12: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+// - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_int == b; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:96:12: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_int == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:98:12: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_int == c_string; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:101:15: Error: The argument type 'A?' can't be assigned to the parameter type 'C<String>?'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == a; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:102:15: Error: The argument type 'B?' can't be assigned to the parameter type 'C<String>?'.
+// - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == b; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:103:15: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<String>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:104:15: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'C<String>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == c_int; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:106:15: Error: The argument type 'D?' can't be assigned to the parameter type 'C<String>?'.
+// - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == d; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:108:8: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// d == a; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:109:8: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+// - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// d == b; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:110:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// d == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:112:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// d == c_string; // ok or error ?
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -289,40 +421,126 @@
d.{self::C::==}(d);
}
static method testNullable(self::A? a, self::B? b, self::C<dynamic>? c_dynamic, self::C<core::int>? c_int, self::C<core::String>? c_string, self::D? d) → dynamic {
- a.{core::Object::==}(a);
- a.{core::Object::==}(b);
- a.{core::Object::==}(c_dynamic);
- a.{core::Object::==}(c_int);
- a.{core::Object::==}(c_string);
- a.{core::Object::==}(d);
- b.{core::Object::==}(a);
- b.{core::Object::==}(b);
- b.{core::Object::==}(c_dynamic);
- b.{core::Object::==}(c_int);
- b.{core::Object::==}(c_string);
- b.{core::Object::==}(d);
- c_dynamic.{core::Object::==}(a);
- c_dynamic.{core::Object::==}(b);
- c_dynamic.{core::Object::==}(c_dynamic);
- c_dynamic.{core::Object::==}(c_int);
- c_dynamic.{core::Object::==}(c_string);
- c_dynamic.{core::Object::==}(d);
- c_int.{core::Object::==}(a);
- c_int.{core::Object::==}(b);
- c_int.{core::Object::==}(c_dynamic);
- c_int.{core::Object::==}(c_int);
- c_int.{core::Object::==}(c_string);
- c_int.{core::Object::==}(d);
- c_string.{core::Object::==}(a);
- c_string.{core::Object::==}(b);
- c_string.{core::Object::==}(c_dynamic);
- c_string.{core::Object::==}(c_int);
- c_string.{core::Object::==}(c_string);
- c_string.{core::Object::==}(d);
- d.{core::Object::==}(a);
- d.{core::Object::==}(b);
- d.{core::Object::==}(c_dynamic);
- d.{core::Object::==}(c_int);
- d.{core::Object::==}(c_string);
- d.{core::Object::==}(d);
+ a.{self::A::==}(a);
+ a.{self::A::==}(b);
+ a.{self::A::==}(let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:75:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ a == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+ a.{self::A::==}(let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:76:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ a == c_int; // ok or error ?
+ ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+ a.{self::A::==}(let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:77:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ a == c_string; // ok or error ?
+ ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+ a.{self::A::==}(let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:78:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ a == d; // ok or error ?
+ ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+ b.{self::B::==}(a);
+ b.{self::B::==}(b);
+ b.{self::B::==}(let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:82:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ b == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+ b.{self::B::==}(let final<BottomType> #t29 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:83:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ b == c_int; // ok or error ?
+ ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+ b.{self::B::==}(let final<BottomType> #t30 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:84:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ b == c_string; // ok or error ?
+ ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+ b.{self::B::==}(let final<BottomType> #t31 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:85:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ b == d; // ok or error ?
+ ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+ c_dynamic.{self::C::==}(let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:87:16: Error: The argument type 'A?' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_dynamic == a; // ok or error ?
+ ^" in a as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+ c_dynamic.{self::C::==}(let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:88:16: Error: The argument type 'B?' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_dynamic == b; // ok or error ?
+ ^" in b as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+ c_dynamic.{self::C::==}(c_dynamic);
+ c_dynamic.{self::C::==}(c_int);
+ c_dynamic.{self::C::==}(c_string);
+ c_dynamic.{self::C::==}(d);
+ c_int.{self::C::==}(let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:94:12: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_int == a; // ok or error ?
+ ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ c_int.{self::C::==}(let final<BottomType> #t35 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:95:12: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_int == b; // ok or error ?
+ ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ c_int.{self::C::==}(let final<BottomType> #t36 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:96:12: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_int == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ c_int.{self::C::==}(c_int);
+ c_int.{self::C::==}(let final<BottomType> #t37 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:98:12: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_int == c_string; // ok or error ?
+ ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ c_int.{self::C::==}(d);
+ c_string.{self::C::==}(let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:101:15: Error: The argument type 'A?' can't be assigned to the parameter type 'C<String>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == a; // ok or error ?
+ ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ c_string.{self::C::==}(let final<BottomType> #t39 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:102:15: Error: The argument type 'B?' can't be assigned to the parameter type 'C<String>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == b; // ok or error ?
+ ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ c_string.{self::C::==}(let final<BottomType> #t40 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:103:15: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ c_string.{self::C::==}(let final<BottomType> #t41 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:104:15: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == c_int; // ok or error ?
+ ^" in c_int as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ c_string.{self::C::==}(c_string);
+ c_string.{self::C::==}(let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:106:15: Error: The argument type 'D?' can't be assigned to the parameter type 'C<String>?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == d; // ok or error ?
+ ^" in d as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ d.{self::C::==}(let final<BottomType> #t43 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:108:8: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ d == a; // ok or error ?
+ ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ d.{self::C::==}(let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:109:8: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ d == b; // ok or error ?
+ ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ d.{self::C::==}(let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:110:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ d == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ d.{self::C::==}(c_int);
+ d.{self::C::==}(let final<BottomType> #t46 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:112:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ d == c_string; // ok or error ?
+ ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ d.{self::C::==}(d);
}
diff --git a/pkg/front_end/testcases/nnbd/covariant_equals.dart.weak.expect b/pkg/front_end/testcases/nnbd/covariant_equals.dart.weak.expect
index 93ef34b..6c746cd 100644
--- a/pkg/front_end/testcases/nnbd/covariant_equals.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/covariant_equals.dart.weak.expect
@@ -134,6 +134,138 @@
// d == c_string; // error
// ^
//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:75:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// a == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:76:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// a == c_int; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:77:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// a == c_string; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:78:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+// - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// a == d; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:82:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// b == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:83:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// b == c_int; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:84:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// b == c_string; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:85:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+// - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// b == d; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:87:16: Error: The argument type 'A?' can't be assigned to the parameter type 'C<dynamic>?'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_dynamic == a; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:88:16: Error: The argument type 'B?' can't be assigned to the parameter type 'C<dynamic>?'.
+// - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_dynamic == b; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:94:12: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_int == a; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:95:12: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+// - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_int == b; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:96:12: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_int == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:98:12: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_int == c_string; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:101:15: Error: The argument type 'A?' can't be assigned to the parameter type 'C<String>?'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == a; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:102:15: Error: The argument type 'B?' can't be assigned to the parameter type 'C<String>?'.
+// - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == b; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:103:15: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<String>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:104:15: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'C<String>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == c_int; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:106:15: Error: The argument type 'D?' can't be assigned to the parameter type 'C<String>?'.
+// - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == d; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:108:8: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// d == a; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:109:8: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+// - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// d == b; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:110:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// d == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:112:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// d == c_string; // ok or error ?
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -289,40 +421,126 @@
d.{self::C::==}(d);
}
static method testNullable(self::A? a, self::B? b, self::C<dynamic>? c_dynamic, self::C<core::int>? c_int, self::C<core::String>? c_string, self::D? d) → dynamic {
- a.{core::Object::==}(a);
- a.{core::Object::==}(b);
- a.{core::Object::==}(c_dynamic);
- a.{core::Object::==}(c_int);
- a.{core::Object::==}(c_string);
- a.{core::Object::==}(d);
- b.{core::Object::==}(a);
- b.{core::Object::==}(b);
- b.{core::Object::==}(c_dynamic);
- b.{core::Object::==}(c_int);
- b.{core::Object::==}(c_string);
- b.{core::Object::==}(d);
- c_dynamic.{core::Object::==}(a);
- c_dynamic.{core::Object::==}(b);
- c_dynamic.{core::Object::==}(c_dynamic);
- c_dynamic.{core::Object::==}(c_int);
- c_dynamic.{core::Object::==}(c_string);
- c_dynamic.{core::Object::==}(d);
- c_int.{core::Object::==}(a);
- c_int.{core::Object::==}(b);
- c_int.{core::Object::==}(c_dynamic);
- c_int.{core::Object::==}(c_int);
- c_int.{core::Object::==}(c_string);
- c_int.{core::Object::==}(d);
- c_string.{core::Object::==}(a);
- c_string.{core::Object::==}(b);
- c_string.{core::Object::==}(c_dynamic);
- c_string.{core::Object::==}(c_int);
- c_string.{core::Object::==}(c_string);
- c_string.{core::Object::==}(d);
- d.{core::Object::==}(a);
- d.{core::Object::==}(b);
- d.{core::Object::==}(c_dynamic);
- d.{core::Object::==}(c_int);
- d.{core::Object::==}(c_string);
- d.{core::Object::==}(d);
+ a.{self::A::==}(a);
+ a.{self::A::==}(b);
+ a.{self::A::==}(let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:75:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ a == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+ a.{self::A::==}(let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:76:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ a == c_int; // ok or error ?
+ ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+ a.{self::A::==}(let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:77:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ a == c_string; // ok or error ?
+ ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+ a.{self::A::==}(let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:78:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ a == d; // ok or error ?
+ ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+ b.{self::B::==}(a);
+ b.{self::B::==}(b);
+ b.{self::B::==}(let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:82:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ b == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+ b.{self::B::==}(let final<BottomType> #t29 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:83:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ b == c_int; // ok or error ?
+ ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+ b.{self::B::==}(let final<BottomType> #t30 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:84:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ b == c_string; // ok or error ?
+ ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+ b.{self::B::==}(let final<BottomType> #t31 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:85:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ b == d; // ok or error ?
+ ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+ c_dynamic.{self::C::==}(let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:87:16: Error: The argument type 'A?' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_dynamic == a; // ok or error ?
+ ^" in a as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+ c_dynamic.{self::C::==}(let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:88:16: Error: The argument type 'B?' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_dynamic == b; // ok or error ?
+ ^" in b as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+ c_dynamic.{self::C::==}(c_dynamic);
+ c_dynamic.{self::C::==}(c_int);
+ c_dynamic.{self::C::==}(c_string);
+ c_dynamic.{self::C::==}(d);
+ c_int.{self::C::==}(let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:94:12: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_int == a; // ok or error ?
+ ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ c_int.{self::C::==}(let final<BottomType> #t35 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:95:12: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_int == b; // ok or error ?
+ ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ c_int.{self::C::==}(let final<BottomType> #t36 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:96:12: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_int == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ c_int.{self::C::==}(c_int);
+ c_int.{self::C::==}(let final<BottomType> #t37 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:98:12: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_int == c_string; // ok or error ?
+ ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ c_int.{self::C::==}(d);
+ c_string.{self::C::==}(let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:101:15: Error: The argument type 'A?' can't be assigned to the parameter type 'C<String>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == a; // ok or error ?
+ ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ c_string.{self::C::==}(let final<BottomType> #t39 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:102:15: Error: The argument type 'B?' can't be assigned to the parameter type 'C<String>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == b; // ok or error ?
+ ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ c_string.{self::C::==}(let final<BottomType> #t40 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:103:15: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ c_string.{self::C::==}(let final<BottomType> #t41 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:104:15: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == c_int; // ok or error ?
+ ^" in c_int as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ c_string.{self::C::==}(c_string);
+ c_string.{self::C::==}(let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:106:15: Error: The argument type 'D?' can't be assigned to the parameter type 'C<String>?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == d; // ok or error ?
+ ^" in d as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ d.{self::C::==}(let final<BottomType> #t43 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:108:8: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ d == a; // ok or error ?
+ ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ d.{self::C::==}(let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:109:8: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ d == b; // ok or error ?
+ ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ d.{self::C::==}(let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:110:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ d == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ d.{self::C::==}(c_int);
+ d.{self::C::==}(let final<BottomType> #t46 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:112:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ d == c_string; // ok or error ?
+ ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ d.{self::C::==}(d);
}
diff --git a/pkg/front_end/testcases/nnbd/covariant_equals.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/covariant_equals.dart.weak.transformed.expect
index 93ef34b..6c746cd 100644
--- a/pkg/front_end/testcases/nnbd/covariant_equals.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/covariant_equals.dart.weak.transformed.expect
@@ -134,6 +134,138 @@
// d == c_string; // error
// ^
//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:75:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// a == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:76:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// a == c_int; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:77:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// a == c_string; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:78:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+// - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// a == d; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:82:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// b == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:83:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// b == c_int; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:84:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// b == c_string; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:85:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+// - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// b == d; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:87:16: Error: The argument type 'A?' can't be assigned to the parameter type 'C<dynamic>?'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_dynamic == a; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:88:16: Error: The argument type 'B?' can't be assigned to the parameter type 'C<dynamic>?'.
+// - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_dynamic == b; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:94:12: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_int == a; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:95:12: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+// - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_int == b; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:96:12: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_int == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:98:12: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_int == c_string; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:101:15: Error: The argument type 'A?' can't be assigned to the parameter type 'C<String>?'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == a; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:102:15: Error: The argument type 'B?' can't be assigned to the parameter type 'C<String>?'.
+// - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == b; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:103:15: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<String>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:104:15: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'C<String>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == c_int; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:106:15: Error: The argument type 'D?' can't be assigned to the parameter type 'C<String>?'.
+// - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// c_string == d; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:108:8: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// d == a; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:109:8: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+// - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// d == b; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:110:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// d == c_dynamic; // ok or error ?
+// ^
+//
+// pkg/front_end/testcases/nnbd/covariant_equals.dart:112:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+// - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+// d == c_string; // ok or error ?
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -289,40 +421,126 @@
d.{self::C::==}(d);
}
static method testNullable(self::A? a, self::B? b, self::C<dynamic>? c_dynamic, self::C<core::int>? c_int, self::C<core::String>? c_string, self::D? d) → dynamic {
- a.{core::Object::==}(a);
- a.{core::Object::==}(b);
- a.{core::Object::==}(c_dynamic);
- a.{core::Object::==}(c_int);
- a.{core::Object::==}(c_string);
- a.{core::Object::==}(d);
- b.{core::Object::==}(a);
- b.{core::Object::==}(b);
- b.{core::Object::==}(c_dynamic);
- b.{core::Object::==}(c_int);
- b.{core::Object::==}(c_string);
- b.{core::Object::==}(d);
- c_dynamic.{core::Object::==}(a);
- c_dynamic.{core::Object::==}(b);
- c_dynamic.{core::Object::==}(c_dynamic);
- c_dynamic.{core::Object::==}(c_int);
- c_dynamic.{core::Object::==}(c_string);
- c_dynamic.{core::Object::==}(d);
- c_int.{core::Object::==}(a);
- c_int.{core::Object::==}(b);
- c_int.{core::Object::==}(c_dynamic);
- c_int.{core::Object::==}(c_int);
- c_int.{core::Object::==}(c_string);
- c_int.{core::Object::==}(d);
- c_string.{core::Object::==}(a);
- c_string.{core::Object::==}(b);
- c_string.{core::Object::==}(c_dynamic);
- c_string.{core::Object::==}(c_int);
- c_string.{core::Object::==}(c_string);
- c_string.{core::Object::==}(d);
- d.{core::Object::==}(a);
- d.{core::Object::==}(b);
- d.{core::Object::==}(c_dynamic);
- d.{core::Object::==}(c_int);
- d.{core::Object::==}(c_string);
- d.{core::Object::==}(d);
+ a.{self::A::==}(a);
+ a.{self::A::==}(b);
+ a.{self::A::==}(let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:75:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ a == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+ a.{self::A::==}(let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:76:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ a == c_int; // ok or error ?
+ ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+ a.{self::A::==}(let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:77:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ a == c_string; // ok or error ?
+ ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+ a.{self::A::==}(let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:78:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ a == d; // ok or error ?
+ ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+ b.{self::B::==}(a);
+ b.{self::B::==}(b);
+ b.{self::B::==}(let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:82:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ b == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::A?);
+ b.{self::B::==}(let final<BottomType> #t29 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:83:8: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ b == c_int; // ok or error ?
+ ^" in c_int as{TypeError,ForNonNullableByDefault} self::A?);
+ b.{self::B::==}(let final<BottomType> #t30 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:84:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'A?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ b == c_string; // ok or error ?
+ ^" in c_string as{TypeError,ForNonNullableByDefault} self::A?);
+ b.{self::B::==}(let final<BottomType> #t31 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:85:8: Error: The argument type 'D?' can't be assigned to the parameter type 'A?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ b == d; // ok or error ?
+ ^" in d as{TypeError,ForNonNullableByDefault} self::A?);
+ c_dynamic.{self::C::==}(let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:87:16: Error: The argument type 'A?' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_dynamic == a; // ok or error ?
+ ^" in a as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+ c_dynamic.{self::C::==}(let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:88:16: Error: The argument type 'B?' can't be assigned to the parameter type 'C<dynamic>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_dynamic == b; // ok or error ?
+ ^" in b as{TypeError,ForNonNullableByDefault} self::C<dynamic>?);
+ c_dynamic.{self::C::==}(c_dynamic);
+ c_dynamic.{self::C::==}(c_int);
+ c_dynamic.{self::C::==}(c_string);
+ c_dynamic.{self::C::==}(d);
+ c_int.{self::C::==}(let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:94:12: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_int == a; // ok or error ?
+ ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ c_int.{self::C::==}(let final<BottomType> #t35 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:95:12: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_int == b; // ok or error ?
+ ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ c_int.{self::C::==}(let final<BottomType> #t36 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:96:12: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_int == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ c_int.{self::C::==}(c_int);
+ c_int.{self::C::==}(let final<BottomType> #t37 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:98:12: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_int == c_string; // ok or error ?
+ ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ c_int.{self::C::==}(d);
+ c_string.{self::C::==}(let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:101:15: Error: The argument type 'A?' can't be assigned to the parameter type 'C<String>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == a; // ok or error ?
+ ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ c_string.{self::C::==}(let final<BottomType> #t39 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:102:15: Error: The argument type 'B?' can't be assigned to the parameter type 'C<String>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == b; // ok or error ?
+ ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ c_string.{self::C::==}(let final<BottomType> #t40 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:103:15: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ c_string.{self::C::==}(let final<BottomType> #t41 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:104:15: Error: The argument type 'C<int>?' can't be assigned to the parameter type 'C<String>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == c_int; // ok or error ?
+ ^" in c_int as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ c_string.{self::C::==}(c_string);
+ c_string.{self::C::==}(let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:106:15: Error: The argument type 'D?' can't be assigned to the parameter type 'C<String>?'.
+ - 'D' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ c_string == d; // ok or error ?
+ ^" in d as{TypeError,ForNonNullableByDefault} self::C<core::String>?);
+ d.{self::C::==}(let final<BottomType> #t43 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:108:8: Error: The argument type 'A?' can't be assigned to the parameter type 'C<int>?'.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ d == a; // ok or error ?
+ ^" in a as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ d.{self::C::==}(let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:109:8: Error: The argument type 'B?' can't be assigned to the parameter type 'C<int>?'.
+ - 'B' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ d == b; // ok or error ?
+ ^" in b as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ d.{self::C::==}(let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:110:8: Error: The argument type 'C<dynamic>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ d == c_dynamic; // ok or error ?
+ ^" in c_dynamic as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ d.{self::C::==}(c_int);
+ d.{self::C::==}(let final<BottomType> #t46 = invalid-expression "pkg/front_end/testcases/nnbd/covariant_equals.dart:112:8: Error: The argument type 'C<String>?' can't be assigned to the parameter type 'C<int>?'.
+ - 'C' is from 'pkg/front_end/testcases/nnbd/covariant_equals.dart'.
+ d == c_string; // ok or error ?
+ ^" in c_string as{TypeError,ForNonNullableByDefault} self::C<core::int>?);
+ d.{self::C::==}(d);
}
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart b/pkg/front_end/testcases/nnbd/generic_override.dart
index f898600..8a3f194 100644
--- a/pkg/front_end/testcases/nnbd/generic_override.dart
+++ b/pkg/front_end/testcases/nnbd/generic_override.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 'generic_override_lib.dart';
+
abstract class Class1 {
void method1a<T>();
void method1b<T>();
@@ -42,4 +44,24 @@
void method5c<T extends Class1>(); // error
}
+abstract class Class3 extends LegacyClass1 {
+ void method1a<T>();
+ void method1b<T extends Object?>();
+ void method1c<T extends dynamic>();
+ void method2a<T>();
+ void method2b<T extends Object?>();
+ void method2c<T extends dynamic>();
+ void method3a<T>();
+ void method3b<T extends Object?>();
+ void method3c<T extends dynamic>();
+
+ void method4a<T extends Object>();
+ void method4b<T extends Object?>();
+ void method4c<T extends Object>();
+
+ void method5a<T extends Class1>();
+ void method5b<T extends Class1?>();
+ void method5c<T extends Class1>();
+}
+
main() {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart.outline.expect b/pkg/front_end/testcases/nnbd/generic_override.dart.outline.expect
index 7af22c0..1364f7a 100644
--- a/pkg/front_end/testcases/nnbd/generic_override.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart.outline.expect
@@ -2,40 +2,43 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:37:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:39:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
// - 'Object' is from 'dart:core'.
// void method4b<T extends Object?>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:17:8: Context: This is the overridden method ('method4b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:19:8: Context: This is the overridden method ('method4b').
// void method4b<T extends Object>();
// ^
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:38:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:40:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
// - 'Object' is from 'dart:core'.
// void method4c<T extends Object>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:18:8: Context: This is the overridden method ('method4c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:20:8: Context: This is the overridden method ('method4c').
// void method4c<T extends Object?>();
// ^
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:41:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:43:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
// - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
// void method5b<T extends Class1?>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:21:8: Context: This is the overridden method ('method5b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:23:8: Context: This is the overridden method ('method5b').
// void method5b<T extends Class1>();
// ^
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:42:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:44:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
// - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
// void method5c<T extends Class1>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:22:8: Context: This is the overridden method ('method5c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:24:8: Context: This is the overridden method ('method5c').
// void method5c<T extends Class1?>();
// ^
//
import self as self;
import "dart:core" as core;
+import "generic_override_lib.dart" as gen;
+
+import "org-dartlang-testcase:///generic_override_lib.dart";
abstract class Class1 extends core::Object {
synthetic constructor •() → self::Class1
@@ -75,5 +78,88 @@
abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
abstract method method5c<T extends self::Class1 = self::Class1>() → void;
}
+abstract class Class3 extends gen::LegacyClass1 {
+ synthetic constructor •() → self::Class3
+ ;
+ abstract method method1a<T extends core::Object? = dynamic>() → void;
+ abstract method method1b<T extends core::Object? = core::Object?>() → void;
+ abstract method method1c<T extends dynamic = dynamic>() → void;
+ abstract method method2a<T extends core::Object? = dynamic>() → void;
+ abstract method method2b<T extends core::Object? = core::Object?>() → void;
+ abstract method method2c<T extends dynamic = dynamic>() → void;
+ abstract method method3a<T extends core::Object? = dynamic>() → void;
+ abstract method method3b<T extends core::Object? = core::Object?>() → void;
+ abstract method method3c<T extends dynamic = dynamic>() → void;
+ abstract method method4a<T extends core::Object = core::Object>() → void;
+ abstract method method4b<T extends core::Object? = core::Object?>() → void;
+ abstract method method4c<T extends core::Object = core::Object>() → void;
+ abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+ abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
+ abstract method method5c<T extends self::Class1 = self::Class1>() → void;
+}
+static method main() → dynamic
+ ;
+
+library;
+import self as gen;
+import "dart:core" as core;
+import "generic_override.dart" as self;
+
+import "org-dartlang-testcase:///generic_override.dart";
+
+abstract class LegacyClass1 extends core::Object {
+ synthetic constructor •() → gen::LegacyClass1*
+ ;
+ abstract method method1a<T extends core::Object* = dynamic>() → void;
+ abstract method method1b<T extends core::Object* = dynamic>() → void;
+ abstract method method1c<T extends core::Object* = dynamic>() → void;
+ abstract method method2a<T extends core::Object* = core::Object*>() → void;
+ abstract method method2b<T extends core::Object* = core::Object*>() → void;
+ abstract method method2c<T extends core::Object* = core::Object*>() → void;
+ abstract method method3a<T extends dynamic = dynamic>() → void;
+ abstract method method3b<T extends dynamic = dynamic>() → void;
+ abstract method method3c<T extends dynamic = dynamic>() → void;
+ abstract method method4a<T extends core::Object* = core::Object*>() → void;
+ abstract method method4b<T extends core::Object* = core::Object*>() → void;
+ abstract method method4c<T extends core::Object* = core::Object*>() → void;
+ abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass2 extends self::Class1 {
+ synthetic constructor •() → gen::LegacyClass2*
+ ;
+ abstract method method1a<T extends core::Object* = dynamic>() → void;
+ abstract method method1b<T extends core::Object* = core::Object*>() → void;
+ abstract method method1c<T extends dynamic = dynamic>() → void;
+ abstract method method2a<T extends core::Object* = dynamic>() → void;
+ abstract method method2b<T extends core::Object* = core::Object*>() → void;
+ abstract method method2c<T extends dynamic = dynamic>() → void;
+ abstract method method3a<T extends core::Object* = dynamic>() → void;
+ abstract method method3b<T extends core::Object* = core::Object*>() → void;
+ abstract method method3c<T extends dynamic = dynamic>() → void;
+ abstract method method4a<T extends core::Object* = core::Object*>() → void;
+ abstract method method4b<T extends core::Object* = core::Object*>() → void;
+ abstract method method4c<T extends core::Object* = core::Object*>() → void;
+ abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass3 extends self::Class1 {
+ synthetic constructor •() → gen::LegacyClass3*
+ ;
+ abstract member-signature method method1a<T extends core::Object* = dynamic>() → void;
+ abstract member-signature method method1b<T extends core::Object* = dynamic>() → void;
+ abstract member-signature method method1c<T extends core::Object* = dynamic>() → void;
+ abstract member-signature method method2a<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method2b<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method2c<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method4a<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method4b<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method4c<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method5a<T extends self::Class1* = self::Class1*>() → void;
+ abstract member-signature method method5b<T extends self::Class1* = self::Class1*>() → void;
+ abstract member-signature method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart.strong.expect b/pkg/front_end/testcases/nnbd/generic_override.dart.strong.expect
index f9ca321..419cad0 100644
--- a/pkg/front_end/testcases/nnbd/generic_override.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart.strong.expect
@@ -2,40 +2,43 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:37:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:39:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
// - 'Object' is from 'dart:core'.
// void method4b<T extends Object?>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:17:8: Context: This is the overridden method ('method4b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:19:8: Context: This is the overridden method ('method4b').
// void method4b<T extends Object>();
// ^
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:38:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:40:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
// - 'Object' is from 'dart:core'.
// void method4c<T extends Object>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:18:8: Context: This is the overridden method ('method4c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:20:8: Context: This is the overridden method ('method4c').
// void method4c<T extends Object?>();
// ^
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:41:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:43:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
// - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
// void method5b<T extends Class1?>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:21:8: Context: This is the overridden method ('method5b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:23:8: Context: This is the overridden method ('method5b').
// void method5b<T extends Class1>();
// ^
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:42:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:44:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
// - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
// void method5c<T extends Class1>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:22:8: Context: This is the overridden method ('method5c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:24:8: Context: This is the overridden method ('method5c').
// void method5c<T extends Class1?>();
// ^
//
import self as self;
import "dart:core" as core;
+import "generic_override_lib.dart" as gen;
+
+import "org-dartlang-testcase:///generic_override_lib.dart";
abstract class Class1 extends core::Object {
synthetic constructor •() → self::Class1
@@ -77,4 +80,90 @@
abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
abstract method method5c<T extends self::Class1 = self::Class1>() → void;
}
+abstract class Class3 extends gen::LegacyClass1 {
+ synthetic constructor •() → self::Class3
+ : super gen::LegacyClass1::•()
+ ;
+ abstract method method1a<T extends core::Object? = dynamic>() → void;
+ abstract method method1b<T extends core::Object? = core::Object?>() → void;
+ abstract method method1c<T extends dynamic = dynamic>() → void;
+ abstract method method2a<T extends core::Object? = dynamic>() → void;
+ abstract method method2b<T extends core::Object? = core::Object?>() → void;
+ abstract method method2c<T extends dynamic = dynamic>() → void;
+ abstract method method3a<T extends core::Object? = dynamic>() → void;
+ abstract method method3b<T extends core::Object? = core::Object?>() → void;
+ abstract method method3c<T extends dynamic = dynamic>() → void;
+ abstract method method4a<T extends core::Object = core::Object>() → void;
+ abstract method method4b<T extends core::Object? = core::Object?>() → void;
+ abstract method method4c<T extends core::Object = core::Object>() → void;
+ abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+ abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
+ abstract method method5c<T extends self::Class1 = self::Class1>() → void;
+}
+static method main() → dynamic {}
+
+library;
+import self as gen;
+import "dart:core" as core;
+import "generic_override.dart" as self;
+
+import "org-dartlang-testcase:///generic_override.dart";
+
+abstract class LegacyClass1 extends core::Object {
+ synthetic constructor •() → gen::LegacyClass1*
+ : super core::Object::•()
+ ;
+ abstract method method1a<T extends core::Object* = dynamic>() → void;
+ abstract method method1b<T extends core::Object* = dynamic>() → void;
+ abstract method method1c<T extends core::Object* = dynamic>() → void;
+ abstract method method2a<T extends core::Object* = core::Object*>() → void;
+ abstract method method2b<T extends core::Object* = core::Object*>() → void;
+ abstract method method2c<T extends core::Object* = core::Object*>() → void;
+ abstract method method3a<T extends dynamic = dynamic>() → void;
+ abstract method method3b<T extends dynamic = dynamic>() → void;
+ abstract method method3c<T extends dynamic = dynamic>() → void;
+ abstract method method4a<T extends core::Object* = core::Object*>() → void;
+ abstract method method4b<T extends core::Object* = core::Object*>() → void;
+ abstract method method4c<T extends core::Object* = core::Object*>() → void;
+ abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass2 extends self::Class1 {
+ synthetic constructor •() → gen::LegacyClass2*
+ : super self::Class1::•()
+ ;
+ abstract method method1a<T extends core::Object* = dynamic>() → void;
+ abstract method method1b<T extends core::Object* = core::Object*>() → void;
+ abstract method method1c<T extends dynamic = dynamic>() → void;
+ abstract method method2a<T extends core::Object* = dynamic>() → void;
+ abstract method method2b<T extends core::Object* = core::Object*>() → void;
+ abstract method method2c<T extends dynamic = dynamic>() → void;
+ abstract method method3a<T extends core::Object* = dynamic>() → void;
+ abstract method method3b<T extends core::Object* = core::Object*>() → void;
+ abstract method method3c<T extends dynamic = dynamic>() → void;
+ abstract method method4a<T extends core::Object* = core::Object*>() → void;
+ abstract method method4b<T extends core::Object* = core::Object*>() → void;
+ abstract method method4c<T extends core::Object* = core::Object*>() → void;
+ abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass3 extends self::Class1 {
+ synthetic constructor •() → gen::LegacyClass3*
+ : super self::Class1::•()
+ ;
+ abstract member-signature method method1a<T extends core::Object* = dynamic>() → void;
+ abstract member-signature method method1b<T extends core::Object* = dynamic>() → void;
+ abstract member-signature method method1c<T extends core::Object* = dynamic>() → void;
+ abstract member-signature method method2a<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method2b<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method2c<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method4a<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method4b<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method4c<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method5a<T extends self::Class1* = self::Class1*>() → void;
+ abstract member-signature method method5b<T extends self::Class1* = self::Class1*>() → void;
+ abstract member-signature method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/generic_override.dart.strong.transformed.expect
index f9ca321..419cad0 100644
--- a/pkg/front_end/testcases/nnbd/generic_override.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart.strong.transformed.expect
@@ -2,40 +2,43 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:37:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:39:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
// - 'Object' is from 'dart:core'.
// void method4b<T extends Object?>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:17:8: Context: This is the overridden method ('method4b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:19:8: Context: This is the overridden method ('method4b').
// void method4b<T extends Object>();
// ^
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:38:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:40:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
// - 'Object' is from 'dart:core'.
// void method4c<T extends Object>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:18:8: Context: This is the overridden method ('method4c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:20:8: Context: This is the overridden method ('method4c').
// void method4c<T extends Object?>();
// ^
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:41:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:43:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
// - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
// void method5b<T extends Class1?>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:21:8: Context: This is the overridden method ('method5b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:23:8: Context: This is the overridden method ('method5b').
// void method5b<T extends Class1>();
// ^
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:42:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:44:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
// - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
// void method5c<T extends Class1>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:22:8: Context: This is the overridden method ('method5c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:24:8: Context: This is the overridden method ('method5c').
// void method5c<T extends Class1?>();
// ^
//
import self as self;
import "dart:core" as core;
+import "generic_override_lib.dart" as gen;
+
+import "org-dartlang-testcase:///generic_override_lib.dart";
abstract class Class1 extends core::Object {
synthetic constructor •() → self::Class1
@@ -77,4 +80,90 @@
abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
abstract method method5c<T extends self::Class1 = self::Class1>() → void;
}
+abstract class Class3 extends gen::LegacyClass1 {
+ synthetic constructor •() → self::Class3
+ : super gen::LegacyClass1::•()
+ ;
+ abstract method method1a<T extends core::Object? = dynamic>() → void;
+ abstract method method1b<T extends core::Object? = core::Object?>() → void;
+ abstract method method1c<T extends dynamic = dynamic>() → void;
+ abstract method method2a<T extends core::Object? = dynamic>() → void;
+ abstract method method2b<T extends core::Object? = core::Object?>() → void;
+ abstract method method2c<T extends dynamic = dynamic>() → void;
+ abstract method method3a<T extends core::Object? = dynamic>() → void;
+ abstract method method3b<T extends core::Object? = core::Object?>() → void;
+ abstract method method3c<T extends dynamic = dynamic>() → void;
+ abstract method method4a<T extends core::Object = core::Object>() → void;
+ abstract method method4b<T extends core::Object? = core::Object?>() → void;
+ abstract method method4c<T extends core::Object = core::Object>() → void;
+ abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+ abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
+ abstract method method5c<T extends self::Class1 = self::Class1>() → void;
+}
+static method main() → dynamic {}
+
+library;
+import self as gen;
+import "dart:core" as core;
+import "generic_override.dart" as self;
+
+import "org-dartlang-testcase:///generic_override.dart";
+
+abstract class LegacyClass1 extends core::Object {
+ synthetic constructor •() → gen::LegacyClass1*
+ : super core::Object::•()
+ ;
+ abstract method method1a<T extends core::Object* = dynamic>() → void;
+ abstract method method1b<T extends core::Object* = dynamic>() → void;
+ abstract method method1c<T extends core::Object* = dynamic>() → void;
+ abstract method method2a<T extends core::Object* = core::Object*>() → void;
+ abstract method method2b<T extends core::Object* = core::Object*>() → void;
+ abstract method method2c<T extends core::Object* = core::Object*>() → void;
+ abstract method method3a<T extends dynamic = dynamic>() → void;
+ abstract method method3b<T extends dynamic = dynamic>() → void;
+ abstract method method3c<T extends dynamic = dynamic>() → void;
+ abstract method method4a<T extends core::Object* = core::Object*>() → void;
+ abstract method method4b<T extends core::Object* = core::Object*>() → void;
+ abstract method method4c<T extends core::Object* = core::Object*>() → void;
+ abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass2 extends self::Class1 {
+ synthetic constructor •() → gen::LegacyClass2*
+ : super self::Class1::•()
+ ;
+ abstract method method1a<T extends core::Object* = dynamic>() → void;
+ abstract method method1b<T extends core::Object* = core::Object*>() → void;
+ abstract method method1c<T extends dynamic = dynamic>() → void;
+ abstract method method2a<T extends core::Object* = dynamic>() → void;
+ abstract method method2b<T extends core::Object* = core::Object*>() → void;
+ abstract method method2c<T extends dynamic = dynamic>() → void;
+ abstract method method3a<T extends core::Object* = dynamic>() → void;
+ abstract method method3b<T extends core::Object* = core::Object*>() → void;
+ abstract method method3c<T extends dynamic = dynamic>() → void;
+ abstract method method4a<T extends core::Object* = core::Object*>() → void;
+ abstract method method4b<T extends core::Object* = core::Object*>() → void;
+ abstract method method4c<T extends core::Object* = core::Object*>() → void;
+ abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass3 extends self::Class1 {
+ synthetic constructor •() → gen::LegacyClass3*
+ : super self::Class1::•()
+ ;
+ abstract member-signature method method1a<T extends core::Object* = dynamic>() → void;
+ abstract member-signature method method1b<T extends core::Object* = dynamic>() → void;
+ abstract member-signature method method1c<T extends core::Object* = dynamic>() → void;
+ abstract member-signature method method2a<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method2b<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method2c<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method4a<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method4b<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method4c<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method5a<T extends self::Class1* = self::Class1*>() → void;
+ abstract member-signature method method5b<T extends self::Class1* = self::Class1*>() → void;
+ abstract member-signature method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart.weak.expect b/pkg/front_end/testcases/nnbd/generic_override.dart.weak.expect
index f9ca321..419cad0 100644
--- a/pkg/front_end/testcases/nnbd/generic_override.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart.weak.expect
@@ -2,40 +2,43 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:37:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:39:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
// - 'Object' is from 'dart:core'.
// void method4b<T extends Object?>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:17:8: Context: This is the overridden method ('method4b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:19:8: Context: This is the overridden method ('method4b').
// void method4b<T extends Object>();
// ^
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:38:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:40:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
// - 'Object' is from 'dart:core'.
// void method4c<T extends Object>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:18:8: Context: This is the overridden method ('method4c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:20:8: Context: This is the overridden method ('method4c').
// void method4c<T extends Object?>();
// ^
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:41:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:43:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
// - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
// void method5b<T extends Class1?>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:21:8: Context: This is the overridden method ('method5b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:23:8: Context: This is the overridden method ('method5b').
// void method5b<T extends Class1>();
// ^
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:42:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:44:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
// - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
// void method5c<T extends Class1>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:22:8: Context: This is the overridden method ('method5c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:24:8: Context: This is the overridden method ('method5c').
// void method5c<T extends Class1?>();
// ^
//
import self as self;
import "dart:core" as core;
+import "generic_override_lib.dart" as gen;
+
+import "org-dartlang-testcase:///generic_override_lib.dart";
abstract class Class1 extends core::Object {
synthetic constructor •() → self::Class1
@@ -77,4 +80,90 @@
abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
abstract method method5c<T extends self::Class1 = self::Class1>() → void;
}
+abstract class Class3 extends gen::LegacyClass1 {
+ synthetic constructor •() → self::Class3
+ : super gen::LegacyClass1::•()
+ ;
+ abstract method method1a<T extends core::Object? = dynamic>() → void;
+ abstract method method1b<T extends core::Object? = core::Object?>() → void;
+ abstract method method1c<T extends dynamic = dynamic>() → void;
+ abstract method method2a<T extends core::Object? = dynamic>() → void;
+ abstract method method2b<T extends core::Object? = core::Object?>() → void;
+ abstract method method2c<T extends dynamic = dynamic>() → void;
+ abstract method method3a<T extends core::Object? = dynamic>() → void;
+ abstract method method3b<T extends core::Object? = core::Object?>() → void;
+ abstract method method3c<T extends dynamic = dynamic>() → void;
+ abstract method method4a<T extends core::Object = core::Object>() → void;
+ abstract method method4b<T extends core::Object? = core::Object?>() → void;
+ abstract method method4c<T extends core::Object = core::Object>() → void;
+ abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+ abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
+ abstract method method5c<T extends self::Class1 = self::Class1>() → void;
+}
+static method main() → dynamic {}
+
+library;
+import self as gen;
+import "dart:core" as core;
+import "generic_override.dart" as self;
+
+import "org-dartlang-testcase:///generic_override.dart";
+
+abstract class LegacyClass1 extends core::Object {
+ synthetic constructor •() → gen::LegacyClass1*
+ : super core::Object::•()
+ ;
+ abstract method method1a<T extends core::Object* = dynamic>() → void;
+ abstract method method1b<T extends core::Object* = dynamic>() → void;
+ abstract method method1c<T extends core::Object* = dynamic>() → void;
+ abstract method method2a<T extends core::Object* = core::Object*>() → void;
+ abstract method method2b<T extends core::Object* = core::Object*>() → void;
+ abstract method method2c<T extends core::Object* = core::Object*>() → void;
+ abstract method method3a<T extends dynamic = dynamic>() → void;
+ abstract method method3b<T extends dynamic = dynamic>() → void;
+ abstract method method3c<T extends dynamic = dynamic>() → void;
+ abstract method method4a<T extends core::Object* = core::Object*>() → void;
+ abstract method method4b<T extends core::Object* = core::Object*>() → void;
+ abstract method method4c<T extends core::Object* = core::Object*>() → void;
+ abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass2 extends self::Class1 {
+ synthetic constructor •() → gen::LegacyClass2*
+ : super self::Class1::•()
+ ;
+ abstract method method1a<T extends core::Object* = dynamic>() → void;
+ abstract method method1b<T extends core::Object* = core::Object*>() → void;
+ abstract method method1c<T extends dynamic = dynamic>() → void;
+ abstract method method2a<T extends core::Object* = dynamic>() → void;
+ abstract method method2b<T extends core::Object* = core::Object*>() → void;
+ abstract method method2c<T extends dynamic = dynamic>() → void;
+ abstract method method3a<T extends core::Object* = dynamic>() → void;
+ abstract method method3b<T extends core::Object* = core::Object*>() → void;
+ abstract method method3c<T extends dynamic = dynamic>() → void;
+ abstract method method4a<T extends core::Object* = core::Object*>() → void;
+ abstract method method4b<T extends core::Object* = core::Object*>() → void;
+ abstract method method4c<T extends core::Object* = core::Object*>() → void;
+ abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass3 extends self::Class1 {
+ synthetic constructor •() → gen::LegacyClass3*
+ : super self::Class1::•()
+ ;
+ abstract member-signature method method1a<T extends core::Object* = dynamic>() → void;
+ abstract member-signature method method1b<T extends core::Object* = dynamic>() → void;
+ abstract member-signature method method1c<T extends core::Object* = dynamic>() → void;
+ abstract member-signature method method2a<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method2b<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method2c<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method4a<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method4b<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method4c<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method5a<T extends self::Class1* = self::Class1*>() → void;
+ abstract member-signature method method5b<T extends self::Class1* = self::Class1*>() → void;
+ abstract member-signature method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/generic_override.dart.weak.transformed.expect
index f9ca321..419cad0 100644
--- a/pkg/front_end/testcases/nnbd/generic_override.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart.weak.transformed.expect
@@ -2,40 +2,43 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:37:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:39:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
// - 'Object' is from 'dart:core'.
// void method4b<T extends Object?>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:17:8: Context: This is the overridden method ('method4b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:19:8: Context: This is the overridden method ('method4b').
// void method4b<T extends Object>();
// ^
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:38:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:40:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
// - 'Object' is from 'dart:core'.
// void method4c<T extends Object>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:18:8: Context: This is the overridden method ('method4c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:20:8: Context: This is the overridden method ('method4c').
// void method4c<T extends Object?>();
// ^
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:41:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:43:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
// - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
// void method5b<T extends Class1?>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:21:8: Context: This is the overridden method ('method5b').
+// pkg/front_end/testcases/nnbd/generic_override.dart:23:8: Context: This is the overridden method ('method5b').
// void method5b<T extends Class1>();
// ^
//
-// pkg/front_end/testcases/nnbd/generic_override.dart:42:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
+// pkg/front_end/testcases/nnbd/generic_override.dart:44:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
// - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
// void method5c<T extends Class1>(); // error
// ^
-// pkg/front_end/testcases/nnbd/generic_override.dart:22:8: Context: This is the overridden method ('method5c').
+// pkg/front_end/testcases/nnbd/generic_override.dart:24:8: Context: This is the overridden method ('method5c').
// void method5c<T extends Class1?>();
// ^
//
import self as self;
import "dart:core" as core;
+import "generic_override_lib.dart" as gen;
+
+import "org-dartlang-testcase:///generic_override_lib.dart";
abstract class Class1 extends core::Object {
synthetic constructor •() → self::Class1
@@ -77,4 +80,90 @@
abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
abstract method method5c<T extends self::Class1 = self::Class1>() → void;
}
+abstract class Class3 extends gen::LegacyClass1 {
+ synthetic constructor •() → self::Class3
+ : super gen::LegacyClass1::•()
+ ;
+ abstract method method1a<T extends core::Object? = dynamic>() → void;
+ abstract method method1b<T extends core::Object? = core::Object?>() → void;
+ abstract method method1c<T extends dynamic = dynamic>() → void;
+ abstract method method2a<T extends core::Object? = dynamic>() → void;
+ abstract method method2b<T extends core::Object? = core::Object?>() → void;
+ abstract method method2c<T extends dynamic = dynamic>() → void;
+ abstract method method3a<T extends core::Object? = dynamic>() → void;
+ abstract method method3b<T extends core::Object? = core::Object?>() → void;
+ abstract method method3c<T extends dynamic = dynamic>() → void;
+ abstract method method4a<T extends core::Object = core::Object>() → void;
+ abstract method method4b<T extends core::Object? = core::Object?>() → void;
+ abstract method method4c<T extends core::Object = core::Object>() → void;
+ abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+ abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
+ abstract method method5c<T extends self::Class1 = self::Class1>() → void;
+}
+static method main() → dynamic {}
+
+library;
+import self as gen;
+import "dart:core" as core;
+import "generic_override.dart" as self;
+
+import "org-dartlang-testcase:///generic_override.dart";
+
+abstract class LegacyClass1 extends core::Object {
+ synthetic constructor •() → gen::LegacyClass1*
+ : super core::Object::•()
+ ;
+ abstract method method1a<T extends core::Object* = dynamic>() → void;
+ abstract method method1b<T extends core::Object* = dynamic>() → void;
+ abstract method method1c<T extends core::Object* = dynamic>() → void;
+ abstract method method2a<T extends core::Object* = core::Object*>() → void;
+ abstract method method2b<T extends core::Object* = core::Object*>() → void;
+ abstract method method2c<T extends core::Object* = core::Object*>() → void;
+ abstract method method3a<T extends dynamic = dynamic>() → void;
+ abstract method method3b<T extends dynamic = dynamic>() → void;
+ abstract method method3c<T extends dynamic = dynamic>() → void;
+ abstract method method4a<T extends core::Object* = core::Object*>() → void;
+ abstract method method4b<T extends core::Object* = core::Object*>() → void;
+ abstract method method4c<T extends core::Object* = core::Object*>() → void;
+ abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass2 extends self::Class1 {
+ synthetic constructor •() → gen::LegacyClass2*
+ : super self::Class1::•()
+ ;
+ abstract method method1a<T extends core::Object* = dynamic>() → void;
+ abstract method method1b<T extends core::Object* = core::Object*>() → void;
+ abstract method method1c<T extends dynamic = dynamic>() → void;
+ abstract method method2a<T extends core::Object* = dynamic>() → void;
+ abstract method method2b<T extends core::Object* = core::Object*>() → void;
+ abstract method method2c<T extends dynamic = dynamic>() → void;
+ abstract method method3a<T extends core::Object* = dynamic>() → void;
+ abstract method method3b<T extends core::Object* = core::Object*>() → void;
+ abstract method method3c<T extends dynamic = dynamic>() → void;
+ abstract method method4a<T extends core::Object* = core::Object*>() → void;
+ abstract method method4b<T extends core::Object* = core::Object*>() → void;
+ abstract method method4c<T extends core::Object* = core::Object*>() → void;
+ abstract method method5a<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5b<T extends self::Class1* = self::Class1*>() → void;
+ abstract method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
+abstract class LegacyClass3 extends self::Class1 {
+ synthetic constructor •() → gen::LegacyClass3*
+ : super self::Class1::•()
+ ;
+ abstract member-signature method method1a<T extends core::Object* = dynamic>() → void;
+ abstract member-signature method method1b<T extends core::Object* = dynamic>() → void;
+ abstract member-signature method method1c<T extends core::Object* = dynamic>() → void;
+ abstract member-signature method method2a<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method2b<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method2c<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method4a<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method4b<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method4c<T extends core::Object* = core::Object*>() → void;
+ abstract member-signature method method5a<T extends self::Class1* = self::Class1*>() → void;
+ abstract member-signature method method5b<T extends self::Class1* = self::Class1*>() → void;
+ abstract member-signature method method5c<T extends self::Class1* = self::Class1*>() → void;
+}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override_lib.dart b/pkg/front_end/testcases/nnbd/generic_override_lib.dart
new file mode 100644
index 0000000..8a2640df
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/generic_override_lib.dart
@@ -0,0 +1,51 @@
+// 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.
+
+// @dart=2.6
+
+import 'generic_override.dart';
+
+abstract class LegacyClass1 {
+ void method1a<T>();
+ void method1b<T>();
+ void method1c<T>();
+ void method2a<T extends Object>();
+ void method2b<T extends Object>();
+ void method2c<T extends Object>();
+ void method3a<T extends dynamic>();
+ void method3b<T extends dynamic>();
+ void method3c<T extends dynamic>();
+
+ void method4a<T extends Object>();
+ void method4b<T extends Object>();
+ void method4c<T extends Object>();
+
+ void method5a<T extends Class1>();
+ void method5b<T extends Class1>();
+ void method5c<T extends Class1>();
+}
+
+abstract class LegacyClass2 extends Class1 {
+ void method1a<T>();
+ void method1b<T extends Object>();
+ void method1c<T extends dynamic>();
+ void method2a<T>();
+ void method2b<T extends Object>();
+ void method2c<T extends dynamic>();
+ void method3a<T>();
+ void method3b<T extends Object>();
+ void method3c<T extends dynamic>();
+
+ void method4a<T extends Object>();
+ void method4b<T extends Object>();
+ void method4c<T extends Object>();
+
+ void method5a<T extends Class1>();
+ void method5b<T extends Class1>();
+ void method5c<T extends Class1>();
+}
+
+abstract class LegacyClass3 extends Class1 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_method_types.dart.outline.expect b/pkg/front_end/testcases/nnbd/infer_method_types.dart.outline.expect
index 5f8c4b8..f0f39bc4 100644
--- a/pkg/front_end/testcases/nnbd/infer_method_types.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/infer_method_types.dart.outline.expect
@@ -40,7 +40,7 @@
abstract class H extends core::Object implements self::D, self::E, self::F, self::C {
synthetic constructor •() → self::H
;
- abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+ abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
}
abstract class I extends core::Object implements self::D {
synthetic constructor •() → self::I
@@ -50,17 +50,17 @@
abstract class J extends core::Object implements self::H {
synthetic constructor •() → self::J
;
- abstract method m(covariant core::num a) → void;
+ abstract method m(covariant core::num a) → core::Object?;
}
abstract class K extends core::Object implements self::I, self::E, self::G {
synthetic constructor •() → self::K
;
- abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+ abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
}
abstract class L extends core::Object implements self::K {
synthetic constructor •() → self::L
;
- abstract method m(covariant core::num a) → void;
+ abstract method m(covariant core::num a) → core::Object?;
}
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/nnbd/infer_method_types.dart.strong.expect b/pkg/front_end/testcases/nnbd/infer_method_types.dart.strong.expect
index cc03fc1..85e72a0 100644
--- a/pkg/front_end/testcases/nnbd/infer_method_types.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/infer_method_types.dart.strong.expect
@@ -48,7 +48,7 @@
synthetic constructor •() → self::H
: super core::Object::•()
;
- abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+ abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
}
abstract class I extends core::Object implements self::D {
synthetic constructor •() → self::I
@@ -60,18 +60,18 @@
synthetic constructor •() → self::J
: super core::Object::•()
;
- abstract method m(covariant core::num a) → void;
+ abstract method m(covariant core::num a) → core::Object?;
}
abstract class K extends core::Object implements self::I, self::E, self::G {
synthetic constructor •() → self::K
: super core::Object::•()
;
- abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+ abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
}
abstract class L extends core::Object implements self::K {
synthetic constructor •() → self::L
: super core::Object::•()
;
- abstract method m(covariant core::num a) → void;
+ abstract method m(covariant core::num a) → core::Object?;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/infer_method_types.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/infer_method_types.dart.strong.transformed.expect
index cc03fc1..85e72a0 100644
--- a/pkg/front_end/testcases/nnbd/infer_method_types.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/infer_method_types.dart.strong.transformed.expect
@@ -48,7 +48,7 @@
synthetic constructor •() → self::H
: super core::Object::•()
;
- abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+ abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
}
abstract class I extends core::Object implements self::D {
synthetic constructor •() → self::I
@@ -60,18 +60,18 @@
synthetic constructor •() → self::J
: super core::Object::•()
;
- abstract method m(covariant core::num a) → void;
+ abstract method m(covariant core::num a) → core::Object?;
}
abstract class K extends core::Object implements self::I, self::E, self::G {
synthetic constructor •() → self::K
: super core::Object::•()
;
- abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+ abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
}
abstract class L extends core::Object implements self::K {
synthetic constructor •() → self::L
: super core::Object::•()
;
- abstract method m(covariant core::num a) → void;
+ abstract method m(covariant core::num a) → core::Object?;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/infer_method_types.dart.weak.expect b/pkg/front_end/testcases/nnbd/infer_method_types.dart.weak.expect
index cc03fc1..85e72a0 100644
--- a/pkg/front_end/testcases/nnbd/infer_method_types.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/infer_method_types.dart.weak.expect
@@ -48,7 +48,7 @@
synthetic constructor •() → self::H
: super core::Object::•()
;
- abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+ abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
}
abstract class I extends core::Object implements self::D {
synthetic constructor •() → self::I
@@ -60,18 +60,18 @@
synthetic constructor •() → self::J
: super core::Object::•()
;
- abstract method m(covariant core::num a) → void;
+ abstract method m(covariant core::num a) → core::Object?;
}
abstract class K extends core::Object implements self::I, self::E, self::G {
synthetic constructor •() → self::K
: super core::Object::•()
;
- abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+ abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
}
abstract class L extends core::Object implements self::K {
synthetic constructor •() → self::L
: super core::Object::•()
;
- abstract method m(covariant core::num a) → void;
+ abstract method m(covariant core::num a) → core::Object?;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/infer_method_types.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/infer_method_types.dart.weak.transformed.expect
index cc03fc1..85e72a0 100644
--- a/pkg/front_end/testcases/nnbd/infer_method_types.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/infer_method_types.dart.weak.transformed.expect
@@ -48,7 +48,7 @@
synthetic constructor •() → self::H
: super core::Object::•()
;
- abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+ abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
}
abstract class I extends core::Object implements self::D {
synthetic constructor •() → self::I
@@ -60,18 +60,18 @@
synthetic constructor •() → self::J
: super core::Object::•()
;
- abstract method m(covariant core::num a) → void;
+ abstract method m(covariant core::num a) → core::Object?;
}
abstract class K extends core::Object implements self::I, self::E, self::G {
synthetic constructor •() → self::K
: super core::Object::•()
;
- abstract forwarding-stub member-signature method m(covariant core::num a) → void;
+ abstract forwarding-stub member-signature method m(covariant core::num a) → core::Object?;
}
abstract class L extends core::Object implements self::K {
synthetic constructor •() → self::L
: super core::Object::•()
;
- abstract method m(covariant core::num a) → void;
+ abstract method m(covariant core::num a) → core::Object?;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart b/pkg/front_end/testcases/nnbd/issue41349.dart
new file mode 100644
index 0000000..0ded2f1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart
@@ -0,0 +1,41 @@
+// 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.
+
+class A {
+ foo() => 23;
+}
+
+extension B on A? {
+ foo() => 42;
+ bar() => 87;
+}
+
+extension C on A {
+ bar() => 123;
+}
+
+extension D on int Function()? {
+ int call() => 76;
+}
+
+main() {
+ testA(new A());
+ testFunction(() => 53);
+}
+
+testA(A? a) {
+ expect(23, a?.foo()); // A.foo instead of B.foo.
+ expect(42, a.foo()); // B.foo instead of nullable access to A.foo.
+ expect(123, a?.bar()); // C.bar instead of B.bar.
+ expect(87, a.bar()); // B.bar instead of nullable access to C.bar.
+}
+
+testFunction(int Function()? f) {
+ expect(53, f?.call()); // Function.call instead of D.call.
+ expect(76, f.call()); // D.call instead of nullable access to Function.call.
+}
+
+expect(expected, actual) {
+ if (expected != actual) throw 'Expected $expected, actual $actual';
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41349.dart.outline.expect
new file mode 100644
index 0000000..15071a6e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart.outline.expect
@@ -0,0 +1,48 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ ;
+ method foo() → dynamic
+ ;
+}
+extension B on self::A? {
+ method foo = self::B|foo;
+ tearoff foo = self::B|get#foo;
+ method bar = self::B|bar;
+ tearoff bar = self::B|get#bar;
+}
+extension C on self::A {
+ method bar = self::C|bar;
+ tearoff bar = self::C|get#bar;
+}
+extension D on () →? core::int {
+ method call = self::D|call;
+ tearoff call = self::D|get#call;
+}
+static method B|foo(final self::A? #this) → dynamic
+ ;
+static method B|get#foo(final self::A? #this) → () → dynamic
+ return () → dynamic => self::B|foo(#this);
+static method B|bar(final self::A? #this) → dynamic
+ ;
+static method B|get#bar(final self::A? #this) → () → dynamic
+ return () → dynamic => self::B|bar(#this);
+static method C|bar(final self::A #this) → dynamic
+ ;
+static method C|get#bar(final self::A #this) → () → dynamic
+ return () → dynamic => self::C|bar(#this);
+static method D|call(final () →? core::int #this) → core::int
+ ;
+static method D|get#call(final () →? core::int #this) → () → core::int
+ return () → core::int => self::D|call(#this);
+static method main() → dynamic
+ ;
+static method testA(self::A? a) → dynamic
+ ;
+static method testFunction(() →? core::int f) → dynamic
+ ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41349.dart.strong.expect
new file mode 100644
index 0000000..750eec3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart.strong.expect
@@ -0,0 +1,59 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo() → dynamic
+ return 23;
+}
+extension B on self::A? {
+ method foo = self::B|foo;
+ tearoff foo = self::B|get#foo;
+ method bar = self::B|bar;
+ tearoff bar = self::B|get#bar;
+}
+extension C on self::A {
+ method bar = self::C|bar;
+ tearoff bar = self::C|get#bar;
+}
+extension D on () →? core::int {
+ method call = self::D|call;
+ tearoff call = self::D|get#call;
+}
+static method B|foo(final self::A? #this) → dynamic
+ return 42;
+static method B|get#foo(final self::A? #this) → () → dynamic
+ return () → dynamic => self::B|foo(#this);
+static method B|bar(final self::A? #this) → dynamic
+ return 87;
+static method B|get#bar(final self::A? #this) → () → dynamic
+ return () → dynamic => self::B|bar(#this);
+static method C|bar(final self::A #this) → dynamic
+ return 123;
+static method C|get#bar(final self::A #this) → () → dynamic
+ return () → dynamic => self::C|bar(#this);
+static method D|call(final () →? core::int #this) → core::int
+ return 76;
+static method D|get#call(final () →? core::int #this) → () → core::int
+ return () → core::int => self::D|call(#this);
+static method main() → dynamic {
+ self::testA(new self::A::•());
+ self::testFunction(() → core::int => 53);
+}
+static method testA(self::A? a) → dynamic {
+ self::expect(23, let final self::A? #t1 = a in #t1.{core::Object::==}(null) ?{dynamic} null : #t1{self::A}.{self::A::foo}());
+ self::expect(42, self::B|foo(a));
+ self::expect(123, let final self::A? #t2 = a in #t2.{core::Object::==}(null) ?{dynamic} null : self::C|bar(#t2{self::A}));
+ self::expect(87, self::B|bar(a));
+}
+static method testFunction(() →? core::int f) → dynamic {
+ self::expect(53, let final () →? core::int #t3 = f in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{() → core::int}.call());
+ self::expect(76, self::D|call(f));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41349.dart.strong.transformed.expect
new file mode 100644
index 0000000..750eec3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart.strong.transformed.expect
@@ -0,0 +1,59 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo() → dynamic
+ return 23;
+}
+extension B on self::A? {
+ method foo = self::B|foo;
+ tearoff foo = self::B|get#foo;
+ method bar = self::B|bar;
+ tearoff bar = self::B|get#bar;
+}
+extension C on self::A {
+ method bar = self::C|bar;
+ tearoff bar = self::C|get#bar;
+}
+extension D on () →? core::int {
+ method call = self::D|call;
+ tearoff call = self::D|get#call;
+}
+static method B|foo(final self::A? #this) → dynamic
+ return 42;
+static method B|get#foo(final self::A? #this) → () → dynamic
+ return () → dynamic => self::B|foo(#this);
+static method B|bar(final self::A? #this) → dynamic
+ return 87;
+static method B|get#bar(final self::A? #this) → () → dynamic
+ return () → dynamic => self::B|bar(#this);
+static method C|bar(final self::A #this) → dynamic
+ return 123;
+static method C|get#bar(final self::A #this) → () → dynamic
+ return () → dynamic => self::C|bar(#this);
+static method D|call(final () →? core::int #this) → core::int
+ return 76;
+static method D|get#call(final () →? core::int #this) → () → core::int
+ return () → core::int => self::D|call(#this);
+static method main() → dynamic {
+ self::testA(new self::A::•());
+ self::testFunction(() → core::int => 53);
+}
+static method testA(self::A? a) → dynamic {
+ self::expect(23, let final self::A? #t1 = a in #t1.{core::Object::==}(null) ?{dynamic} null : #t1{self::A}.{self::A::foo}());
+ self::expect(42, self::B|foo(a));
+ self::expect(123, let final self::A? #t2 = a in #t2.{core::Object::==}(null) ?{dynamic} null : self::C|bar(#t2{self::A}));
+ self::expect(87, self::B|bar(a));
+}
+static method testFunction(() →? core::int f) → dynamic {
+ self::expect(53, let final () →? core::int #t3 = f in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{() → core::int}.call());
+ self::expect(76, self::D|call(f));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41349.dart.weak.expect
new file mode 100644
index 0000000..750eec3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart.weak.expect
@@ -0,0 +1,59 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo() → dynamic
+ return 23;
+}
+extension B on self::A? {
+ method foo = self::B|foo;
+ tearoff foo = self::B|get#foo;
+ method bar = self::B|bar;
+ tearoff bar = self::B|get#bar;
+}
+extension C on self::A {
+ method bar = self::C|bar;
+ tearoff bar = self::C|get#bar;
+}
+extension D on () →? core::int {
+ method call = self::D|call;
+ tearoff call = self::D|get#call;
+}
+static method B|foo(final self::A? #this) → dynamic
+ return 42;
+static method B|get#foo(final self::A? #this) → () → dynamic
+ return () → dynamic => self::B|foo(#this);
+static method B|bar(final self::A? #this) → dynamic
+ return 87;
+static method B|get#bar(final self::A? #this) → () → dynamic
+ return () → dynamic => self::B|bar(#this);
+static method C|bar(final self::A #this) → dynamic
+ return 123;
+static method C|get#bar(final self::A #this) → () → dynamic
+ return () → dynamic => self::C|bar(#this);
+static method D|call(final () →? core::int #this) → core::int
+ return 76;
+static method D|get#call(final () →? core::int #this) → () → core::int
+ return () → core::int => self::D|call(#this);
+static method main() → dynamic {
+ self::testA(new self::A::•());
+ self::testFunction(() → core::int => 53);
+}
+static method testA(self::A? a) → dynamic {
+ self::expect(23, let final self::A? #t1 = a in #t1.{core::Object::==}(null) ?{dynamic} null : #t1{self::A}.{self::A::foo}());
+ self::expect(42, self::B|foo(a));
+ self::expect(123, let final self::A? #t2 = a in #t2.{core::Object::==}(null) ?{dynamic} null : self::C|bar(#t2{self::A}));
+ self::expect(87, self::B|bar(a));
+}
+static method testFunction(() →? core::int f) → dynamic {
+ self::expect(53, let final () →? core::int #t3 = f in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{() → core::int}.call());
+ self::expect(76, self::D|call(f));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41349.dart.weak.transformed.expect
new file mode 100644
index 0000000..750eec3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart.weak.transformed.expect
@@ -0,0 +1,59 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo() → dynamic
+ return 23;
+}
+extension B on self::A? {
+ method foo = self::B|foo;
+ tearoff foo = self::B|get#foo;
+ method bar = self::B|bar;
+ tearoff bar = self::B|get#bar;
+}
+extension C on self::A {
+ method bar = self::C|bar;
+ tearoff bar = self::C|get#bar;
+}
+extension D on () →? core::int {
+ method call = self::D|call;
+ tearoff call = self::D|get#call;
+}
+static method B|foo(final self::A? #this) → dynamic
+ return 42;
+static method B|get#foo(final self::A? #this) → () → dynamic
+ return () → dynamic => self::B|foo(#this);
+static method B|bar(final self::A? #this) → dynamic
+ return 87;
+static method B|get#bar(final self::A? #this) → () → dynamic
+ return () → dynamic => self::B|bar(#this);
+static method C|bar(final self::A #this) → dynamic
+ return 123;
+static method C|get#bar(final self::A #this) → () → dynamic
+ return () → dynamic => self::C|bar(#this);
+static method D|call(final () →? core::int #this) → core::int
+ return 76;
+static method D|get#call(final () →? core::int #this) → () → core::int
+ return () → core::int => self::D|call(#this);
+static method main() → dynamic {
+ self::testA(new self::A::•());
+ self::testFunction(() → core::int => 53);
+}
+static method testA(self::A? a) → dynamic {
+ self::expect(23, let final self::A? #t1 = a in #t1.{core::Object::==}(null) ?{dynamic} null : #t1{self::A}.{self::A::foo}());
+ self::expect(42, self::B|foo(a));
+ self::expect(123, let final self::A? #t2 = a in #t2.{core::Object::==}(null) ?{dynamic} null : self::C|bar(#t2{self::A}));
+ self::expect(87, self::B|bar(a));
+}
+static method testFunction(() →? core::int f) → dynamic {
+ self::expect(53, let final () →? core::int #t3 = f in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{() → core::int}.call());
+ self::expect(76, self::D|call(f));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart b/pkg/front_end/testcases/nnbd/issue41415.dart
new file mode 100644
index 0000000..60e3258
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2017, 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.
+
+// Requirements=nnbd-strong
+import "package:expect/expect.dart";
+
+main() {
+ // Pre-NNBD bottom type.
+ int Function(Null) f = (x) => 1; // Runtime type is int Function(Object?)
+ // NNBD bottom type.
+ int Function(Never) g = (x) => 1; // Runtime type is int Function(Object?)
+ // NNBD bottom type.
+
+ int Function(Never?) h = (x) => 1; // Runtime type is int Function(Object?)
+
+ int Function(String) i = (x) => 1; // Runtime type is int Function(String)
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41415.dart.outline.expect
new file mode 100644
index 0000000..73b21aa
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart.outline.expect
@@ -0,0 +1,7 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "package:expect/expect.dart";
+
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41415.dart.strong.expect
new file mode 100644
index 0000000..7e85811
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart.strong.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "package:expect/expect.dart";
+
+static method main() → dynamic {
+ (core::Null?) → core::int f = (core::Object? x) → core::int => 1;
+ (Never) → core::int g = (core::Object? x) → core::int => 1;
+ (Never?) → core::int h = (core::Object? x) → core::int => 1;
+ (core::String) → core::int i = (core::String x) → core::int => 1;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41415.dart.strong.transformed.expect
new file mode 100644
index 0000000..7e85811
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "package:expect/expect.dart";
+
+static method main() → dynamic {
+ (core::Null?) → core::int f = (core::Object? x) → core::int => 1;
+ (Never) → core::int g = (core::Object? x) → core::int => 1;
+ (Never?) → core::int h = (core::Object? x) → core::int => 1;
+ (core::String) → core::int i = (core::String x) → core::int => 1;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41415.dart.weak.expect
new file mode 100644
index 0000000..7e85811
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart.weak.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "package:expect/expect.dart";
+
+static method main() → dynamic {
+ (core::Null?) → core::int f = (core::Object? x) → core::int => 1;
+ (Never) → core::int g = (core::Object? x) → core::int => 1;
+ (Never?) → core::int h = (core::Object? x) → core::int => 1;
+ (core::String) → core::int i = (core::String x) → core::int => 1;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41415.dart.weak.transformed.expect
new file mode 100644
index 0000000..7e85811
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart.weak.transformed.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "package:expect/expect.dart";
+
+static method main() → dynamic {
+ (core::Null?) → core::int f = (core::Object? x) → core::int => 1;
+ (Never) → core::int g = (core::Object? x) → core::int => 1;
+ (Never?) → core::int h = (core::Object? x) → core::int => 1;
+ (core::String) → core::int i = (core::String x) → core::int => 1;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41495.dart b/pkg/front_end/testcases/nnbd/issue41495.dart
new file mode 100644
index 0000000..ceaf89a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41495.dart
@@ -0,0 +1,16 @@
+// 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.
+
+class A {
+ int c1 = 1;
+ int test() => 2;
+}
+
+main() {}
+
+errors() {
+ A? a1 = new A();
+ a1.c1;
+ a1.test;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41495.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41495.dart.outline.expect
new file mode 100644
index 0000000..20f3ce6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41495.dart.outline.expect
@@ -0,0 +1,15 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ field core::int c1;
+ synthetic constructor •() → self::A
+ ;
+ method test() → core::int
+ ;
+}
+static method main() → dynamic
+ ;
+static method errors() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/issue41495.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41495.dart.strong.expect
new file mode 100644
index 0000000..ecc36781
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41495.dart.strong.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41495.dart:14:6: Error: Property 'c1' cannot be accessed on 'A?' because it is potentially null.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+// Try accessing using ?. instead.
+// a1.c1;
+// ^^
+//
+// pkg/front_end/testcases/nnbd/issue41495.dart:15:6: Error: Property 'test' cannot be accessed on 'A?' because it is potentially null.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+// Try accessing using ?. instead.
+// a1.test;
+// ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ field core::int c1 = 1;
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method test() → core::int
+ return 2;
+}
+static method main() → dynamic {}
+static method errors() → dynamic {
+ self::A? a1 = new self::A::•();
+ let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41495.dart:14:6: Error: Property 'c1' cannot be accessed on 'A?' because it is potentially null.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+Try accessing using ?. instead.
+ a1.c1;
+ ^^" in a1.{self::A::c1};
+ let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41495.dart:15:6: Error: Property 'test' cannot be accessed on 'A?' because it is potentially null.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+Try accessing using ?. instead.
+ a1.test;
+ ^^^^" in a1.{self::A::test};
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41495.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41495.dart.strong.transformed.expect
new file mode 100644
index 0000000..ecc36781
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41495.dart.strong.transformed.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41495.dart:14:6: Error: Property 'c1' cannot be accessed on 'A?' because it is potentially null.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+// Try accessing using ?. instead.
+// a1.c1;
+// ^^
+//
+// pkg/front_end/testcases/nnbd/issue41495.dart:15:6: Error: Property 'test' cannot be accessed on 'A?' because it is potentially null.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+// Try accessing using ?. instead.
+// a1.test;
+// ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ field core::int c1 = 1;
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method test() → core::int
+ return 2;
+}
+static method main() → dynamic {}
+static method errors() → dynamic {
+ self::A? a1 = new self::A::•();
+ let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41495.dart:14:6: Error: Property 'c1' cannot be accessed on 'A?' because it is potentially null.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+Try accessing using ?. instead.
+ a1.c1;
+ ^^" in a1.{self::A::c1};
+ let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41495.dart:15:6: Error: Property 'test' cannot be accessed on 'A?' because it is potentially null.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+Try accessing using ?. instead.
+ a1.test;
+ ^^^^" in a1.{self::A::test};
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41495.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41495.dart.weak.expect
new file mode 100644
index 0000000..ecc36781
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41495.dart.weak.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41495.dart:14:6: Error: Property 'c1' cannot be accessed on 'A?' because it is potentially null.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+// Try accessing using ?. instead.
+// a1.c1;
+// ^^
+//
+// pkg/front_end/testcases/nnbd/issue41495.dart:15:6: Error: Property 'test' cannot be accessed on 'A?' because it is potentially null.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+// Try accessing using ?. instead.
+// a1.test;
+// ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ field core::int c1 = 1;
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method test() → core::int
+ return 2;
+}
+static method main() → dynamic {}
+static method errors() → dynamic {
+ self::A? a1 = new self::A::•();
+ let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41495.dart:14:6: Error: Property 'c1' cannot be accessed on 'A?' because it is potentially null.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+Try accessing using ?. instead.
+ a1.c1;
+ ^^" in a1.{self::A::c1};
+ let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41495.dart:15:6: Error: Property 'test' cannot be accessed on 'A?' because it is potentially null.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+Try accessing using ?. instead.
+ a1.test;
+ ^^^^" in a1.{self::A::test};
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41495.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41495.dart.weak.transformed.expect
new file mode 100644
index 0000000..ecc36781
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41495.dart.weak.transformed.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41495.dart:14:6: Error: Property 'c1' cannot be accessed on 'A?' because it is potentially null.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+// Try accessing using ?. instead.
+// a1.c1;
+// ^^
+//
+// pkg/front_end/testcases/nnbd/issue41495.dart:15:6: Error: Property 'test' cannot be accessed on 'A?' because it is potentially null.
+// - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+// Try accessing using ?. instead.
+// a1.test;
+// ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ field core::int c1 = 1;
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method test() → core::int
+ return 2;
+}
+static method main() → dynamic {}
+static method errors() → dynamic {
+ self::A? a1 = new self::A::•();
+ let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41495.dart:14:6: Error: Property 'c1' cannot be accessed on 'A?' because it is potentially null.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+Try accessing using ?. instead.
+ a1.c1;
+ ^^" in a1.{self::A::c1};
+ let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41495.dart:15:6: Error: Property 'test' cannot be accessed on 'A?' because it is potentially null.
+ - 'A' is from 'pkg/front_end/testcases/nnbd/issue41495.dart'.
+Try accessing using ?. instead.
+ a1.test;
+ ^^^^" in a1.{self::A::test};
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41567.dart b/pkg/front_end/testcases/nnbd/issue41567.dart
new file mode 100644
index 0000000..9df5590
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41567.dart
@@ -0,0 +1,17 @@
+// 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.
+
+import 'issue41567_lib.dart';
+
+class B extends A {}
+
+class in1 extends out_Object implements B {} // ok
+
+class in2 extends B implements out_Object {} // ok
+
+class in3 extends out_int implements B {} // error
+
+class in4 extends B implements out_int {} // error
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41567.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41567.dart.outline.expect
new file mode 100644
index 0000000..4214a62
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41567.dart.outline.expect
@@ -0,0 +1,58 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/nnbd/issue41567.dart:13:7: Error: 'in3' can't implement both 'A<int>' and 'A<dynamic>'
+// - 'A' is from 'pkg/front_end/testcases/nnbd/issue41567_lib.dart'.
+// class in3 extends out_int implements B {} // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41567.dart:15:7: Error: 'in4' can't implement both 'A<dynamic>' and 'A<int>'
+// - 'A' is from 'pkg/front_end/testcases/nnbd/issue41567_lib.dart'.
+// class in4 extends B implements out_int {} // error
+// ^
+//
+library /*isNonNullableByDefault*/;
+import self as self;
+import "issue41567_lib.dart" as iss;
+
+import "org-dartlang-testcase:///issue41567_lib.dart";
+
+class B extends iss::A<dynamic> {
+ synthetic constructor •() → self::B
+ ;
+}
+class in1 extends iss::out_Object implements self::B {
+ synthetic constructor •() → self::in1
+ ;
+}
+class in2 extends self::B implements iss::out_Object {
+ synthetic constructor •() → self::in2
+ ;
+}
+class in3 extends iss::out_int implements self::B {
+ synthetic constructor •() → self::in3
+ ;
+}
+class in4 extends self::B implements iss::out_int {
+ synthetic constructor •() → self::in4
+ ;
+}
+static method main() → dynamic
+ ;
+
+library;
+import self as iss;
+import "dart:core" as core;
+
+class A<T extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → iss::A<iss::A::T*>*
+ ;
+}
+class out_int extends iss::A<core::int*> {
+ synthetic constructor •() → iss::out_int*
+ ;
+}
+class out_Object extends iss::A<core::Object*> {
+ synthetic constructor •() → iss::out_Object*
+ ;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41567.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41567.dart.strong.expect
new file mode 100644
index 0000000..5ae9d25
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41567.dart.strong.expect
@@ -0,0 +1,65 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/nnbd/issue41567.dart:13:7: Error: 'in3' can't implement both 'A<int>' and 'A<dynamic>'
+// - 'A' is from 'pkg/front_end/testcases/nnbd/issue41567_lib.dart'.
+// class in3 extends out_int implements B {} // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41567.dart:15:7: Error: 'in4' can't implement both 'A<dynamic>' and 'A<int>'
+// - 'A' is from 'pkg/front_end/testcases/nnbd/issue41567_lib.dart'.
+// class in4 extends B implements out_int {} // error
+// ^
+//
+library /*isNonNullableByDefault*/;
+import self as self;
+import "issue41567_lib.dart" as iss;
+
+import "org-dartlang-testcase:///issue41567_lib.dart";
+
+class B extends iss::A<dynamic> {
+ synthetic constructor •() → self::B
+ : super iss::A::•()
+ ;
+}
+class in1 extends iss::out_Object implements self::B {
+ synthetic constructor •() → self::in1
+ : super iss::out_Object::•()
+ ;
+}
+class in2 extends self::B implements iss::out_Object {
+ synthetic constructor •() → self::in2
+ : super self::B::•()
+ ;
+}
+class in3 extends iss::out_int implements self::B {
+ synthetic constructor •() → self::in3
+ : super iss::out_int::•()
+ ;
+}
+class in4 extends self::B implements iss::out_int {
+ synthetic constructor •() → self::in4
+ : super self::B::•()
+ ;
+}
+static method main() → dynamic {}
+
+library;
+import self as iss;
+import "dart:core" as core;
+
+class A<T extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → iss::A<iss::A::T*>*
+ : super core::Object::•()
+ ;
+}
+class out_int extends iss::A<core::int*> {
+ synthetic constructor •() → iss::out_int*
+ : super iss::A::•()
+ ;
+}
+class out_Object extends iss::A<core::Object*> {
+ synthetic constructor •() → iss::out_Object*
+ : super iss::A::•()
+ ;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41567.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41567.dart.weak.expect
new file mode 100644
index 0000000..5ae9d25
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41567.dart.weak.expect
@@ -0,0 +1,65 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/nnbd/issue41567.dart:13:7: Error: 'in3' can't implement both 'A<int>' and 'A<dynamic>'
+// - 'A' is from 'pkg/front_end/testcases/nnbd/issue41567_lib.dart'.
+// class in3 extends out_int implements B {} // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41567.dart:15:7: Error: 'in4' can't implement both 'A<dynamic>' and 'A<int>'
+// - 'A' is from 'pkg/front_end/testcases/nnbd/issue41567_lib.dart'.
+// class in4 extends B implements out_int {} // error
+// ^
+//
+library /*isNonNullableByDefault*/;
+import self as self;
+import "issue41567_lib.dart" as iss;
+
+import "org-dartlang-testcase:///issue41567_lib.dart";
+
+class B extends iss::A<dynamic> {
+ synthetic constructor •() → self::B
+ : super iss::A::•()
+ ;
+}
+class in1 extends iss::out_Object implements self::B {
+ synthetic constructor •() → self::in1
+ : super iss::out_Object::•()
+ ;
+}
+class in2 extends self::B implements iss::out_Object {
+ synthetic constructor •() → self::in2
+ : super self::B::•()
+ ;
+}
+class in3 extends iss::out_int implements self::B {
+ synthetic constructor •() → self::in3
+ : super iss::out_int::•()
+ ;
+}
+class in4 extends self::B implements iss::out_int {
+ synthetic constructor •() → self::in4
+ : super self::B::•()
+ ;
+}
+static method main() → dynamic {}
+
+library;
+import self as iss;
+import "dart:core" as core;
+
+class A<T extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → iss::A<iss::A::T*>*
+ : super core::Object::•()
+ ;
+}
+class out_int extends iss::A<core::int*> {
+ synthetic constructor •() → iss::out_int*
+ : super iss::A::•()
+ ;
+}
+class out_Object extends iss::A<core::Object*> {
+ synthetic constructor •() → iss::out_Object*
+ : super iss::A::•()
+ ;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41567_lib.dart b/pkg/front_end/testcases/nnbd/issue41567_lib.dart
new file mode 100644
index 0000000..e45bcd9
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41567_lib.dart
@@ -0,0 +1,11 @@
+// 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.
+
+// @dart=2.6
+
+class A<T> {}
+
+class out_int extends A<int> {}
+
+class out_Object extends A<Object> {}
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.expect
index 5ef8175..40260d9 100644
--- a/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.expect
@@ -32,21 +32,11 @@
// y.bar; // Error.
// ^^^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
-// Try accessing using ?. instead.
-// y.bar; // Error.
-// ^^^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
// y.baz = 42; // Error.
// ^^^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
-// Try accessing using ?. instead.
-// y.baz = 42; // Error.
-// ^^^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:33:4: Error: The method 'call' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named 'call'.
// y(); // Error.
@@ -57,37 +47,21 @@
// y++; // Error.
// ^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-// y++; // Error.
-// ^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
// Try correcting the operator to an existing operator, or defining a '+' operator.
// y += 1; // Error.
// ^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-// y += 1; // Error.
-// ^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
// Try correcting the operator to an existing operator, or defining a '[]' operator.
// y[42]; // Error.
// ^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
-// y[42]; // Error.
-// ^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
// Try correcting the operator to an existing operator, or defining a '[]=' operator.
// y[42] = 42; // Error.
// ^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
-// y[42] = 42; // Error.
-// ^
-//
import self as self;
import "dart:core" as core;
@@ -117,17 +91,11 @@
Try correcting the name to the name of an existing method, or defining a method named 'foo'.
y.foo(); // Error.
^^^";
- let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
-Try accessing using ?. instead.
- y.bar; // Error.
- ^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: The getter 'bar' isn't defined for the class 'Never'.
+ invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: The getter 'bar' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
y.bar; // Error.
^^^";
- let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
-Try accessing using ?. instead.
- y.baz = 42; // Error.
- ^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
+ invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
y.baz = 42; // Error.
^^^";
@@ -135,27 +103,19 @@
Try correcting the name to the name of an existing method, or defining a method named 'call'.
y(); // Error.
^";
- y = (let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
- y++; // Error.
- ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: The operator '+' isn't defined for the class 'Never'.
+ y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: The operator '+' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '+' operator.
y++; // Error.
- ^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
- y = (let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
- y += 1; // Error.
- ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
+ ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+ y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '+' operator.
y += 1; // Error.
- ^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
- let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
- y[42]; // Error.
- ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
+ ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+ invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '[]' operator.
y[42]; // Error.
^";
- let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
- y[42] = 42; // Error.
- ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
+ invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '[]=' operator.
y[42] = 42; // Error.
^";
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.transformed.expect
index 5ef8175..40260d9 100644
--- a/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.transformed.expect
@@ -32,21 +32,11 @@
// y.bar; // Error.
// ^^^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
-// Try accessing using ?. instead.
-// y.bar; // Error.
-// ^^^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
// y.baz = 42; // Error.
// ^^^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
-// Try accessing using ?. instead.
-// y.baz = 42; // Error.
-// ^^^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:33:4: Error: The method 'call' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named 'call'.
// y(); // Error.
@@ -57,37 +47,21 @@
// y++; // Error.
// ^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-// y++; // Error.
-// ^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
// Try correcting the operator to an existing operator, or defining a '+' operator.
// y += 1; // Error.
// ^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-// y += 1; // Error.
-// ^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
// Try correcting the operator to an existing operator, or defining a '[]' operator.
// y[42]; // Error.
// ^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
-// y[42]; // Error.
-// ^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
// Try correcting the operator to an existing operator, or defining a '[]=' operator.
// y[42] = 42; // Error.
// ^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
-// y[42] = 42; // Error.
-// ^
-//
import self as self;
import "dart:core" as core;
@@ -117,17 +91,11 @@
Try correcting the name to the name of an existing method, or defining a method named 'foo'.
y.foo(); // Error.
^^^";
- let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
-Try accessing using ?. instead.
- y.bar; // Error.
- ^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: The getter 'bar' isn't defined for the class 'Never'.
+ invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: The getter 'bar' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
y.bar; // Error.
^^^";
- let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
-Try accessing using ?. instead.
- y.baz = 42; // Error.
- ^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
+ invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
y.baz = 42; // Error.
^^^";
@@ -135,27 +103,19 @@
Try correcting the name to the name of an existing method, or defining a method named 'call'.
y(); // Error.
^";
- y = (let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
- y++; // Error.
- ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: The operator '+' isn't defined for the class 'Never'.
+ y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: The operator '+' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '+' operator.
y++; // Error.
- ^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
- y = (let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
- y += 1; // Error.
- ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
+ ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+ y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '+' operator.
y += 1; // Error.
- ^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
- let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
- y[42]; // Error.
- ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
+ ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+ invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '[]' operator.
y[42]; // Error.
^";
- let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
- y[42] = 42; // Error.
- ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
+ invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '[]=' operator.
y[42] = 42; // Error.
^";
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.expect
index 5ef8175..40260d9 100644
--- a/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.expect
@@ -32,21 +32,11 @@
// y.bar; // Error.
// ^^^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
-// Try accessing using ?. instead.
-// y.bar; // Error.
-// ^^^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
// y.baz = 42; // Error.
// ^^^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
-// Try accessing using ?. instead.
-// y.baz = 42; // Error.
-// ^^^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:33:4: Error: The method 'call' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named 'call'.
// y(); // Error.
@@ -57,37 +47,21 @@
// y++; // Error.
// ^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-// y++; // Error.
-// ^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
// Try correcting the operator to an existing operator, or defining a '+' operator.
// y += 1; // Error.
// ^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-// y += 1; // Error.
-// ^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
// Try correcting the operator to an existing operator, or defining a '[]' operator.
// y[42]; // Error.
// ^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
-// y[42]; // Error.
-// ^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
// Try correcting the operator to an existing operator, or defining a '[]=' operator.
// y[42] = 42; // Error.
// ^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
-// y[42] = 42; // Error.
-// ^
-//
import self as self;
import "dart:core" as core;
@@ -117,17 +91,11 @@
Try correcting the name to the name of an existing method, or defining a method named 'foo'.
y.foo(); // Error.
^^^";
- let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
-Try accessing using ?. instead.
- y.bar; // Error.
- ^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: The getter 'bar' isn't defined for the class 'Never'.
+ invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: The getter 'bar' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
y.bar; // Error.
^^^";
- let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
-Try accessing using ?. instead.
- y.baz = 42; // Error.
- ^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
+ invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
y.baz = 42; // Error.
^^^";
@@ -135,27 +103,19 @@
Try correcting the name to the name of an existing method, or defining a method named 'call'.
y(); // Error.
^";
- y = (let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
- y++; // Error.
- ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: The operator '+' isn't defined for the class 'Never'.
+ y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: The operator '+' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '+' operator.
y++; // Error.
- ^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
- y = (let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
- y += 1; // Error.
- ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
+ ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+ y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '+' operator.
y += 1; // Error.
- ^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
- let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
- y[42]; // Error.
- ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
+ ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+ invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '[]' operator.
y[42]; // Error.
^";
- let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
- y[42] = 42; // Error.
- ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
+ invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '[]=' operator.
y[42] = 42; // Error.
^";
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect
index 5ef8175..40260d9 100644
--- a/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect
@@ -32,21 +32,11 @@
// y.bar; // Error.
// ^^^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
-// Try accessing using ?. instead.
-// y.bar; // Error.
-// ^^^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
// y.baz = 42; // Error.
// ^^^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
-// Try accessing using ?. instead.
-// y.baz = 42; // Error.
-// ^^^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:33:4: Error: The method 'call' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named 'call'.
// y(); // Error.
@@ -57,37 +47,21 @@
// y++; // Error.
// ^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-// y++; // Error.
-// ^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
// Try correcting the operator to an existing operator, or defining a '+' operator.
// y += 1; // Error.
// ^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
-// y += 1; // Error.
-// ^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
// Try correcting the operator to an existing operator, or defining a '[]' operator.
// y[42]; // Error.
// ^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
-// y[42]; // Error.
-// ^
-//
// pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
// Try correcting the operator to an existing operator, or defining a '[]=' operator.
// y[42] = 42; // Error.
// ^
//
-// pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
-// y[42] = 42; // Error.
-// ^
-//
import self as self;
import "dart:core" as core;
@@ -117,17 +91,11 @@
Try correcting the name to the name of an existing method, or defining a method named 'foo'.
y.foo(); // Error.
^^^";
- let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
-Try accessing using ?. instead.
- y.bar; // Error.
- ^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: The getter 'bar' isn't defined for the class 'Never'.
+ invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:5: Error: The getter 'bar' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
y.bar; // Error.
^^^";
- let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
-Try accessing using ?. instead.
- y.baz = 42; // Error.
- ^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
+ invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:32:5: Error: The setter 'baz' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
y.baz = 42; // Error.
^^^";
@@ -135,27 +103,19 @@
Try correcting the name to the name of an existing method, or defining a method named 'call'.
y(); // Error.
^";
- y = (let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
- y++; // Error.
- ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: The operator '+' isn't defined for the class 'Never'.
+ y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: The operator '+' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '+' operator.
y++; // Error.
- ^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
- y = (let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
- y += 1; // Error.
- ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
+ ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+ y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '+' operator.
y += 1; // Error.
- ^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
- let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
- y[42]; // Error.
- ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
+ ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+ invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '[]' operator.
y[42]; // Error.
^";
- let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
- y[42] = 42; // Error.
- ^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
+ invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:37:4: Error: The operator '[]=' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '[]=' operator.
y[42] = 42; // Error.
^";
diff --git a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart
index fa74007..8452c473 100644
--- a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart
+++ b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart
@@ -6,6 +6,13 @@
import 'nsm_from_opt_in_lib.dart';
+abstract class A2 implements A {
+ @override
+ noSuchMethod(Invocation invocation) {
+ return super.noSuchMethod(invocation);
+ }
+}
+
abstract class B2 extends A implements C2 {
@override
noSuchMethod(Invocation invocation) {
@@ -15,6 +22,9 @@
abstract class C2 {
int method(int i, {optional});
+ T genericMethod1<T>(T t);
+ T genericMethod2<T extends Object>(T t);
+ T genericMethod3<T extends Object>(T t);
}
main() {}
diff --git a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.outline.expect b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.outline.expect
index 00778a8..aff6f51 100644
--- a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.outline.expect
@@ -1,10 +1,21 @@
library;
import self as self;
-import "nsm_from_opt_in_lib.dart" as nsm;
import "dart:core" as core;
+import "nsm_from_opt_in_lib.dart" as nsm;
import "org-dartlang-testcase:///nsm_from_opt_in_lib.dart";
+abstract class A2 extends core::Object implements nsm::A {
+ synthetic constructor •() → self::A2*
+ ;
+ @core::override
+ method noSuchMethod(core::Invocation* invocation) → dynamic
+ ;
+ abstract member-signature method method(core::int* i) → core::int*;
+ abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::A2::genericMethod1::T* t) → self::A2::genericMethod1::T*;
+ abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::A2::genericMethod2::T* t) → self::A2::genericMethod2::T*;
+ abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::A2::genericMethod3::T* t) → self::A2::genericMethod3::T*;
+}
abstract class B2 extends nsm::A implements self::C2 {
synthetic constructor •() → self::B2*
;
@@ -12,11 +23,17 @@
method noSuchMethod(core::Invocation* invocation) → dynamic
;
abstract forwarding-stub method method(core::int* i, {dynamic optional}) → core::int*;
+ abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::B2::genericMethod1::T* t) → self::B2::genericMethod1::T*;
+ abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::B2::genericMethod2::T* t) → self::B2::genericMethod2::T*;
+ abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::B2::genericMethod3::T* t) → self::B2::genericMethod3::T*;
}
abstract class C2 extends core::Object {
synthetic constructor •() → self::C2*
;
abstract method method(core::int* i, {dynamic optional}) → core::int*;
+ abstract method genericMethod1<T extends core::Object* = dynamic>(self::C2::genericMethod1::T* t) → self::C2::genericMethod1::T*;
+ abstract method genericMethod2<T extends core::Object* = core::Object*>(self::C2::genericMethod2::T* t) → self::C2::genericMethod2::T*;
+ abstract method genericMethod3<T extends core::Object* = core::Object*>(self::C2::genericMethod3::T* t) → self::C2::genericMethod3::T*;
}
static method main() → dynamic
;
@@ -30,6 +47,12 @@
;
method method(core::int? i) → core::int
;
+ method genericMethod1<T extends core::Object? = dynamic>(nsm::A::genericMethod1::T% t) → nsm::A::genericMethod1::T%
+ ;
+ method genericMethod2<T extends core::Object? = core::Object?>(nsm::A::genericMethod2::T% t) → nsm::A::genericMethod2::T%
+ ;
+ method genericMethod3<T extends core::Object = core::Object>(nsm::A::genericMethod3::T t) → nsm::A::genericMethod3::T
+ ;
}
abstract class B1 extends nsm::A implements nsm::C1 {
synthetic constructor •() → nsm::B1
@@ -43,4 +66,7 @@
synthetic constructor •() → nsm::C1
;
abstract method method(core::int? i, {dynamic optional}) → core::int;
+ abstract method genericMethod1<T extends core::Object? = dynamic>(nsm::C1::genericMethod1::T% t) → nsm::C1::genericMethod1::T%;
+ abstract method genericMethod2<T extends core::Object? = core::Object?>(nsm::C1::genericMethod2::T% t) → nsm::C1::genericMethod2::T%;
+ abstract method genericMethod3<T extends core::Object = core::Object>(nsm::C1::genericMethod3::T t) → nsm::C1::genericMethod3::T;
}
diff --git a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.strong.expect b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.strong.expect
index 10bcb6e..b04ccd6 100644
--- a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.strong.expect
@@ -1,10 +1,23 @@
library;
import self as self;
-import "nsm_from_opt_in_lib.dart" as nsm;
import "dart:core" as core;
+import "nsm_from_opt_in_lib.dart" as nsm;
import "org-dartlang-testcase:///nsm_from_opt_in_lib.dart";
+abstract class A2 extends core::Object implements nsm::A {
+ synthetic constructor •() → self::A2*
+ : super core::Object::•()
+ ;
+ @#C1
+ method noSuchMethod(core::Invocation* invocation) → dynamic {
+ return super.{core::Object::noSuchMethod}(invocation);
+ }
+ abstract member-signature method method(core::int* i) → core::int*;
+ abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::A2::genericMethod1::T* t) → self::A2::genericMethod1::T*;
+ abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::A2::genericMethod2::T* t) → self::A2::genericMethod2::T*;
+ abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::A2::genericMethod3::T* t) → self::A2::genericMethod3::T*;
+}
abstract class B2 extends nsm::A implements self::C2 {
synthetic constructor •() → self::B2*
: super nsm::A::•()
@@ -14,12 +27,18 @@
return super.{core::Object::noSuchMethod}(invocation);
}
abstract forwarding-stub method method(core::int* i, {dynamic optional = #C2}) → core::int*;
+ abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::B2::genericMethod1::T* t) → self::B2::genericMethod1::T*;
+ abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::B2::genericMethod2::T* t) → self::B2::genericMethod2::T*;
+ abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::B2::genericMethod3::T* t) → self::B2::genericMethod3::T*;
}
abstract class C2 extends core::Object {
synthetic constructor •() → self::C2*
: super core::Object::•()
;
abstract method method(core::int* i, {dynamic optional = #C2}) → core::int*;
+ abstract method genericMethod1<T extends core::Object* = dynamic>(self::C2::genericMethod1::T* t) → self::C2::genericMethod1::T*;
+ abstract method genericMethod2<T extends core::Object* = core::Object*>(self::C2::genericMethod2::T* t) → self::C2::genericMethod2::T*;
+ abstract method genericMethod3<T extends core::Object* = core::Object*>(self::C2::genericMethod3::T* t) → self::C2::genericMethod3::T*;
}
static method main() → dynamic {}
@@ -33,6 +52,12 @@
;
method method(core::int? i) → core::int
return let final core::int? #t1 = i in #t1.{core::num::==}(null) ?{core::int} 0 : #t1{core::int};
+ method genericMethod1<T extends core::Object? = dynamic>(nsm::A::genericMethod1::T% t) → nsm::A::genericMethod1::T%
+ return t;
+ method genericMethod2<T extends core::Object? = core::Object?>(nsm::A::genericMethod2::T% t) → nsm::A::genericMethod2::T%
+ return t;
+ method genericMethod3<T extends core::Object = core::Object>(nsm::A::genericMethod3::T t) → nsm::A::genericMethod3::T
+ return t;
}
abstract class B1 extends nsm::A implements nsm::C1 {
synthetic constructor •() → nsm::B1
@@ -49,6 +74,9 @@
: super core::Object::•()
;
abstract method method(core::int? i, {dynamic optional = #C2}) → core::int;
+ abstract method genericMethod1<T extends core::Object? = dynamic>(nsm::C1::genericMethod1::T% t) → nsm::C1::genericMethod1::T%;
+ abstract method genericMethod2<T extends core::Object? = core::Object?>(nsm::C1::genericMethod2::T% t) → nsm::C1::genericMethod2::T%;
+ abstract method genericMethod3<T extends core::Object = core::Object>(nsm::C1::genericMethod3::T t) → nsm::C1::genericMethod3::T;
}
constants {
diff --git a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.strong.transformed.expect
index 10bcb6e..b04ccd6 100644
--- a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.strong.transformed.expect
@@ -1,10 +1,23 @@
library;
import self as self;
-import "nsm_from_opt_in_lib.dart" as nsm;
import "dart:core" as core;
+import "nsm_from_opt_in_lib.dart" as nsm;
import "org-dartlang-testcase:///nsm_from_opt_in_lib.dart";
+abstract class A2 extends core::Object implements nsm::A {
+ synthetic constructor •() → self::A2*
+ : super core::Object::•()
+ ;
+ @#C1
+ method noSuchMethod(core::Invocation* invocation) → dynamic {
+ return super.{core::Object::noSuchMethod}(invocation);
+ }
+ abstract member-signature method method(core::int* i) → core::int*;
+ abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::A2::genericMethod1::T* t) → self::A2::genericMethod1::T*;
+ abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::A2::genericMethod2::T* t) → self::A2::genericMethod2::T*;
+ abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::A2::genericMethod3::T* t) → self::A2::genericMethod3::T*;
+}
abstract class B2 extends nsm::A implements self::C2 {
synthetic constructor •() → self::B2*
: super nsm::A::•()
@@ -14,12 +27,18 @@
return super.{core::Object::noSuchMethod}(invocation);
}
abstract forwarding-stub method method(core::int* i, {dynamic optional = #C2}) → core::int*;
+ abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::B2::genericMethod1::T* t) → self::B2::genericMethod1::T*;
+ abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::B2::genericMethod2::T* t) → self::B2::genericMethod2::T*;
+ abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::B2::genericMethod3::T* t) → self::B2::genericMethod3::T*;
}
abstract class C2 extends core::Object {
synthetic constructor •() → self::C2*
: super core::Object::•()
;
abstract method method(core::int* i, {dynamic optional = #C2}) → core::int*;
+ abstract method genericMethod1<T extends core::Object* = dynamic>(self::C2::genericMethod1::T* t) → self::C2::genericMethod1::T*;
+ abstract method genericMethod2<T extends core::Object* = core::Object*>(self::C2::genericMethod2::T* t) → self::C2::genericMethod2::T*;
+ abstract method genericMethod3<T extends core::Object* = core::Object*>(self::C2::genericMethod3::T* t) → self::C2::genericMethod3::T*;
}
static method main() → dynamic {}
@@ -33,6 +52,12 @@
;
method method(core::int? i) → core::int
return let final core::int? #t1 = i in #t1.{core::num::==}(null) ?{core::int} 0 : #t1{core::int};
+ method genericMethod1<T extends core::Object? = dynamic>(nsm::A::genericMethod1::T% t) → nsm::A::genericMethod1::T%
+ return t;
+ method genericMethod2<T extends core::Object? = core::Object?>(nsm::A::genericMethod2::T% t) → nsm::A::genericMethod2::T%
+ return t;
+ method genericMethod3<T extends core::Object = core::Object>(nsm::A::genericMethod3::T t) → nsm::A::genericMethod3::T
+ return t;
}
abstract class B1 extends nsm::A implements nsm::C1 {
synthetic constructor •() → nsm::B1
@@ -49,6 +74,9 @@
: super core::Object::•()
;
abstract method method(core::int? i, {dynamic optional = #C2}) → core::int;
+ abstract method genericMethod1<T extends core::Object? = dynamic>(nsm::C1::genericMethod1::T% t) → nsm::C1::genericMethod1::T%;
+ abstract method genericMethod2<T extends core::Object? = core::Object?>(nsm::C1::genericMethod2::T% t) → nsm::C1::genericMethod2::T%;
+ abstract method genericMethod3<T extends core::Object = core::Object>(nsm::C1::genericMethod3::T t) → nsm::C1::genericMethod3::T;
}
constants {
diff --git a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.weak.expect b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.weak.expect
index 10bcb6e..b04ccd6 100644
--- a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.weak.expect
@@ -1,10 +1,23 @@
library;
import self as self;
-import "nsm_from_opt_in_lib.dart" as nsm;
import "dart:core" as core;
+import "nsm_from_opt_in_lib.dart" as nsm;
import "org-dartlang-testcase:///nsm_from_opt_in_lib.dart";
+abstract class A2 extends core::Object implements nsm::A {
+ synthetic constructor •() → self::A2*
+ : super core::Object::•()
+ ;
+ @#C1
+ method noSuchMethod(core::Invocation* invocation) → dynamic {
+ return super.{core::Object::noSuchMethod}(invocation);
+ }
+ abstract member-signature method method(core::int* i) → core::int*;
+ abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::A2::genericMethod1::T* t) → self::A2::genericMethod1::T*;
+ abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::A2::genericMethod2::T* t) → self::A2::genericMethod2::T*;
+ abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::A2::genericMethod3::T* t) → self::A2::genericMethod3::T*;
+}
abstract class B2 extends nsm::A implements self::C2 {
synthetic constructor •() → self::B2*
: super nsm::A::•()
@@ -14,12 +27,18 @@
return super.{core::Object::noSuchMethod}(invocation);
}
abstract forwarding-stub method method(core::int* i, {dynamic optional = #C2}) → core::int*;
+ abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::B2::genericMethod1::T* t) → self::B2::genericMethod1::T*;
+ abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::B2::genericMethod2::T* t) → self::B2::genericMethod2::T*;
+ abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::B2::genericMethod3::T* t) → self::B2::genericMethod3::T*;
}
abstract class C2 extends core::Object {
synthetic constructor •() → self::C2*
: super core::Object::•()
;
abstract method method(core::int* i, {dynamic optional = #C2}) → core::int*;
+ abstract method genericMethod1<T extends core::Object* = dynamic>(self::C2::genericMethod1::T* t) → self::C2::genericMethod1::T*;
+ abstract method genericMethod2<T extends core::Object* = core::Object*>(self::C2::genericMethod2::T* t) → self::C2::genericMethod2::T*;
+ abstract method genericMethod3<T extends core::Object* = core::Object*>(self::C2::genericMethod3::T* t) → self::C2::genericMethod3::T*;
}
static method main() → dynamic {}
@@ -33,6 +52,12 @@
;
method method(core::int? i) → core::int
return let final core::int? #t1 = i in #t1.{core::num::==}(null) ?{core::int} 0 : #t1{core::int};
+ method genericMethod1<T extends core::Object? = dynamic>(nsm::A::genericMethod1::T% t) → nsm::A::genericMethod1::T%
+ return t;
+ method genericMethod2<T extends core::Object? = core::Object?>(nsm::A::genericMethod2::T% t) → nsm::A::genericMethod2::T%
+ return t;
+ method genericMethod3<T extends core::Object = core::Object>(nsm::A::genericMethod3::T t) → nsm::A::genericMethod3::T
+ return t;
}
abstract class B1 extends nsm::A implements nsm::C1 {
synthetic constructor •() → nsm::B1
@@ -49,6 +74,9 @@
: super core::Object::•()
;
abstract method method(core::int? i, {dynamic optional = #C2}) → core::int;
+ abstract method genericMethod1<T extends core::Object? = dynamic>(nsm::C1::genericMethod1::T% t) → nsm::C1::genericMethod1::T%;
+ abstract method genericMethod2<T extends core::Object? = core::Object?>(nsm::C1::genericMethod2::T% t) → nsm::C1::genericMethod2::T%;
+ abstract method genericMethod3<T extends core::Object = core::Object>(nsm::C1::genericMethod3::T t) → nsm::C1::genericMethod3::T;
}
constants {
diff --git a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.weak.transformed.expect
index 10bcb6e..b04ccd6 100644
--- a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.weak.transformed.expect
@@ -1,10 +1,23 @@
library;
import self as self;
-import "nsm_from_opt_in_lib.dart" as nsm;
import "dart:core" as core;
+import "nsm_from_opt_in_lib.dart" as nsm;
import "org-dartlang-testcase:///nsm_from_opt_in_lib.dart";
+abstract class A2 extends core::Object implements nsm::A {
+ synthetic constructor •() → self::A2*
+ : super core::Object::•()
+ ;
+ @#C1
+ method noSuchMethod(core::Invocation* invocation) → dynamic {
+ return super.{core::Object::noSuchMethod}(invocation);
+ }
+ abstract member-signature method method(core::int* i) → core::int*;
+ abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::A2::genericMethod1::T* t) → self::A2::genericMethod1::T*;
+ abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::A2::genericMethod2::T* t) → self::A2::genericMethod2::T*;
+ abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::A2::genericMethod3::T* t) → self::A2::genericMethod3::T*;
+}
abstract class B2 extends nsm::A implements self::C2 {
synthetic constructor •() → self::B2*
: super nsm::A::•()
@@ -14,12 +27,18 @@
return super.{core::Object::noSuchMethod}(invocation);
}
abstract forwarding-stub method method(core::int* i, {dynamic optional = #C2}) → core::int*;
+ abstract member-signature method genericMethod1<T extends core::Object* = dynamic>(self::B2::genericMethod1::T* t) → self::B2::genericMethod1::T*;
+ abstract member-signature method genericMethod2<T extends core::Object* = core::Object*>(self::B2::genericMethod2::T* t) → self::B2::genericMethod2::T*;
+ abstract member-signature method genericMethod3<T extends core::Object* = core::Object*>(self::B2::genericMethod3::T* t) → self::B2::genericMethod3::T*;
}
abstract class C2 extends core::Object {
synthetic constructor •() → self::C2*
: super core::Object::•()
;
abstract method method(core::int* i, {dynamic optional = #C2}) → core::int*;
+ abstract method genericMethod1<T extends core::Object* = dynamic>(self::C2::genericMethod1::T* t) → self::C2::genericMethod1::T*;
+ abstract method genericMethod2<T extends core::Object* = core::Object*>(self::C2::genericMethod2::T* t) → self::C2::genericMethod2::T*;
+ abstract method genericMethod3<T extends core::Object* = core::Object*>(self::C2::genericMethod3::T* t) → self::C2::genericMethod3::T*;
}
static method main() → dynamic {}
@@ -33,6 +52,12 @@
;
method method(core::int? i) → core::int
return let final core::int? #t1 = i in #t1.{core::num::==}(null) ?{core::int} 0 : #t1{core::int};
+ method genericMethod1<T extends core::Object? = dynamic>(nsm::A::genericMethod1::T% t) → nsm::A::genericMethod1::T%
+ return t;
+ method genericMethod2<T extends core::Object? = core::Object?>(nsm::A::genericMethod2::T% t) → nsm::A::genericMethod2::T%
+ return t;
+ method genericMethod3<T extends core::Object = core::Object>(nsm::A::genericMethod3::T t) → nsm::A::genericMethod3::T
+ return t;
}
abstract class B1 extends nsm::A implements nsm::C1 {
synthetic constructor •() → nsm::B1
@@ -49,6 +74,9 @@
: super core::Object::•()
;
abstract method method(core::int? i, {dynamic optional = #C2}) → core::int;
+ abstract method genericMethod1<T extends core::Object? = dynamic>(nsm::C1::genericMethod1::T% t) → nsm::C1::genericMethod1::T%;
+ abstract method genericMethod2<T extends core::Object? = core::Object?>(nsm::C1::genericMethod2::T% t) → nsm::C1::genericMethod2::T%;
+ abstract method genericMethod3<T extends core::Object = core::Object>(nsm::C1::genericMethod3::T t) → nsm::C1::genericMethod3::T;
}
constants {
diff --git a/pkg/front_end/testcases/nnbd/nsm_from_opt_in_lib.dart b/pkg/front_end/testcases/nnbd/nsm_from_opt_in_lib.dart
index 20d29b9..3b74079 100644
--- a/pkg/front_end/testcases/nnbd/nsm_from_opt_in_lib.dart
+++ b/pkg/front_end/testcases/nnbd/nsm_from_opt_in_lib.dart
@@ -4,6 +4,9 @@
class A {
int method(int? i) => i ?? 0;
+ T genericMethod1<T>(T t) => t;
+ T genericMethod2<T extends Object?>(T t) => t;
+ T genericMethod3<T extends Object>(T t) => t;
}
abstract class B1 extends A implements C1 {
@@ -15,4 +18,7 @@
abstract class C1 {
int method(int? i, {optional});
+ T genericMethod1<T>(T t);
+ T genericMethod2<T extends Object?>(T t);
+ T genericMethod3<T extends Object>(T t);
}
diff --git a/pkg/front_end/testcases/nnbd/nullable_object_access.dart b/pkg/front_end/testcases/nnbd/nullable_object_access.dart
index bf88ca3..82729ce 100644
--- a/pkg/front_end/testcases/nnbd/nullable_object_access.dart
+++ b/pkg/front_end/testcases/nnbd/nullable_object_access.dart
@@ -50,7 +50,10 @@
int noSuchMethod2 = c2.noSuchMethod(invocation); // ok
var noSuchMethodVariable2 = c2.noSuchMethod(invocation);
- c2 == ''; // ok
+ // TODO(johnniwinther): Awaiting spec update about `==`. Before NNBD this
+ // would cause an error but with the current (insufficient) specification for
+ // `==` it is ok (even though `c1 == ''` is an error).
+ c2 == ''; // ok or error?
c2 == c1; // ok
String Function({Object o}) toStringTearOff2 = c2.toString; // error
diff --git a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.strong.expect b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.strong.expect
index 81b9a41..ec3535f 100644
--- a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.strong.expect
@@ -29,16 +29,19 @@
// c2.noSuchMethod; // error
// ^
//
-// pkg/front_end/testcases/nnbd/nullable_object_access.dart:56:53: Error: A value of type 'String Function()' can't be assigned to a variable of type 'String Function({Object o})'.
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:56:9: Error: The argument type 'String' can't be assigned to the parameter type 'Class?'.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+// c2 == ''; // ok or error?
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:59:53: Error: A value of type 'String Function()' can't be assigned to a variable of type 'String Function({Object o})'.
// - 'Object' is from 'dart:core'.
// String Function({Object o}) toStringTearOff2 = c2.toString; // error
// ^
//
-// pkg/front_end/testcases/nnbd/nullable_object_access.dart:59:6: Error: Method 'toString' cannot be called on 'Class?' because it is potentially null.
-// - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
-// Try calling using ?. instead.
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:62:15: Error: No named parameter with the name 'o'.
// c2.toString(o: c1); // error
-// ^^^^^^^^
+// ^
//
import self as self;
import "dart:core" as core;
@@ -104,18 +107,19 @@
(core::Invocation) → dynamic noSuchMethodTearOffVariable2 = c2.{core::Object::noSuchMethod};
core::int noSuchMethod2 = c2.{core::Object::noSuchMethod}(invocation) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
dynamic noSuchMethodVariable2 = c2.{core::Object::noSuchMethod}(invocation);
- c2.{core::Object::==}("");
- c2.{core::Object::==}(c1);
- ({o: core::Object}) → core::String toStringTearOff2 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:56:53: Error: A value of type 'String Function()' can't be assigned to a variable of type 'String Function({Object o})'.
+ c2.{self::Class::==}(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:56:9: Error: The argument type 'String' can't be assigned to the parameter type 'Class?'.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+ c2 == ''; // ok or error?
+ ^" in "" as{TypeError,ForNonNullableByDefault} self::Class?);
+ c2.{self::Class::==}(c1);
+ ({o: core::Object}) → core::String toStringTearOff2 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:59:53: Error: A value of type 'String Function()' can't be assigned to a variable of type 'String Function({Object o})'.
- 'Object' is from 'dart:core'.
String Function({Object o}) toStringTearOff2 = c2.toString; // error
^" in c2.{core::Object::toString} as{TypeError,ForNonNullableByDefault} ({o: core::Object}) → core::String;
() → core::String toStringTearOffVariable2 = c2.{core::Object::toString};
- let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:59:6: Error: Method 'toString' cannot be called on 'Class?' because it is potentially null.
- - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
-Try calling using ?. instead.
+ let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:62:15: Error: No named parameter with the name 'o'.
c2.toString(o: c1); // error
- ^^^^^^^^" in c2.{self::Class::toString}(o: c1);
+ ^" in c2.{core::Object::toString}(o: c1);
}
constants {
diff --git a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.expect b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.expect
index 81b9a41..ec3535f 100644
--- a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.expect
@@ -29,16 +29,19 @@
// c2.noSuchMethod; // error
// ^
//
-// pkg/front_end/testcases/nnbd/nullable_object_access.dart:56:53: Error: A value of type 'String Function()' can't be assigned to a variable of type 'String Function({Object o})'.
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:56:9: Error: The argument type 'String' can't be assigned to the parameter type 'Class?'.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+// c2 == ''; // ok or error?
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:59:53: Error: A value of type 'String Function()' can't be assigned to a variable of type 'String Function({Object o})'.
// - 'Object' is from 'dart:core'.
// String Function({Object o}) toStringTearOff2 = c2.toString; // error
// ^
//
-// pkg/front_end/testcases/nnbd/nullable_object_access.dart:59:6: Error: Method 'toString' cannot be called on 'Class?' because it is potentially null.
-// - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
-// Try calling using ?. instead.
+// pkg/front_end/testcases/nnbd/nullable_object_access.dart:62:15: Error: No named parameter with the name 'o'.
// c2.toString(o: c1); // error
-// ^^^^^^^^
+// ^
//
import self as self;
import "dart:core" as core;
@@ -104,18 +107,19 @@
(core::Invocation) → dynamic noSuchMethodTearOffVariable2 = c2.{core::Object::noSuchMethod};
core::int noSuchMethod2 = c2.{core::Object::noSuchMethod}(invocation) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
dynamic noSuchMethodVariable2 = c2.{core::Object::noSuchMethod}(invocation);
- c2.{core::Object::==}("");
- c2.{core::Object::==}(c1);
- ({o: core::Object}) → core::String toStringTearOff2 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:56:53: Error: A value of type 'String Function()' can't be assigned to a variable of type 'String Function({Object o})'.
+ c2.{self::Class::==}(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:56:9: Error: The argument type 'String' can't be assigned to the parameter type 'Class?'.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
+ c2 == ''; // ok or error?
+ ^" in "" as{TypeError,ForNonNullableByDefault} self::Class?);
+ c2.{self::Class::==}(c1);
+ ({o: core::Object}) → core::String toStringTearOff2 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:59:53: Error: A value of type 'String Function()' can't be assigned to a variable of type 'String Function({Object o})'.
- 'Object' is from 'dart:core'.
String Function({Object o}) toStringTearOff2 = c2.toString; // error
^" in c2.{core::Object::toString} as{TypeError,ForNonNullableByDefault} ({o: core::Object}) → core::String;
() → core::String toStringTearOffVariable2 = c2.{core::Object::toString};
- let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:59:6: Error: Method 'toString' cannot be called on 'Class?' because it is potentially null.
- - 'Class' is from 'pkg/front_end/testcases/nnbd/nullable_object_access.dart'.
-Try calling using ?. instead.
+ let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_object_access.dart:62:15: Error: No named parameter with the name 'o'.
c2.toString(o: c1); // error
- ^^^^^^^^" in c2.{self::Class::toString}(o: c1);
+ ^" in c2.{core::Object::toString}(o: c1);
}
constants {
diff --git a/pkg/front_end/testcases/nnbd/nullable_receiver.dart.strong.expect b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.strong.expect
index 380d689..b4de6e7 100644
--- a/pkg/front_end/testcases/nnbd/nullable_receiver.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.strong.expect
@@ -36,11 +36,10 @@
// a();
// ^
//
-// pkg/front_end/testcases/nnbd/nullable_receiver.dart:27:5: Error: Method 'toString' cannot be called on 'B?' because it is potentially null.
-// - 'B' is from 'pkg/front_end/testcases/nnbd/nullable_receiver.dart'.
-// Try calling using ?. instead.
+// pkg/front_end/testcases/nnbd/nullable_receiver.dart:27:13: Error: Too many positional arguments: 0 allowed, but 1 found.
+// Try removing the extra positional arguments.
// b.toString(0);
-// ^^^^^^^^
+// ^
//
// pkg/front_end/testcases/nnbd/nullable_receiver.dart:29:17: Error: Can't tear off method 'call' from a potentially null value.
// Function f1 = a;
@@ -103,11 +102,10 @@
Try calling using ?.call instead.
a();
^" in a.{self::A::call}();
- let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_receiver.dart:27:5: Error: Method 'toString' cannot be called on 'B?' because it is potentially null.
- - 'B' is from 'pkg/front_end/testcases/nnbd/nullable_receiver.dart'.
-Try calling using ?. instead.
+ let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_receiver.dart:27:13: Error: Too many positional arguments: 0 allowed, but 1 found.
+Try removing the extra positional arguments.
b.toString(0);
- ^^^^^^^^" in b.{self::B::toString}(0);
+ ^" in b.{core::Object::toString}(0);
core::Function f1 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_receiver.dart:29:17: Error: Can't tear off method 'call' from a potentially null value.
Function f1 = a;
^" in a as{TypeError} core::Function;
@@ -119,7 +117,7 @@
^" in a as{TypeError} () →? void;
}
static method ok<T extends core::Object? = core::Object?>(core::String? s, self::A? a, self::ok::T% t, self::B? b, core::Invocation i) → dynamic {
- s.{core::Object::==}(s);
+ s.{core::String::==}(s);
a.{core::Object::==}(a);
t.{core::Object::==}(t);
b.{core::Object::==}(b);
diff --git a/pkg/front_end/testcases/nnbd/nullable_receiver.dart.weak.expect b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.weak.expect
index 380d689..b4de6e7 100644
--- a/pkg/front_end/testcases/nnbd/nullable_receiver.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.weak.expect
@@ -36,11 +36,10 @@
// a();
// ^
//
-// pkg/front_end/testcases/nnbd/nullable_receiver.dart:27:5: Error: Method 'toString' cannot be called on 'B?' because it is potentially null.
-// - 'B' is from 'pkg/front_end/testcases/nnbd/nullable_receiver.dart'.
-// Try calling using ?. instead.
+// pkg/front_end/testcases/nnbd/nullable_receiver.dart:27:13: Error: Too many positional arguments: 0 allowed, but 1 found.
+// Try removing the extra positional arguments.
// b.toString(0);
-// ^^^^^^^^
+// ^
//
// pkg/front_end/testcases/nnbd/nullable_receiver.dart:29:17: Error: Can't tear off method 'call' from a potentially null value.
// Function f1 = a;
@@ -103,11 +102,10 @@
Try calling using ?.call instead.
a();
^" in a.{self::A::call}();
- let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_receiver.dart:27:5: Error: Method 'toString' cannot be called on 'B?' because it is potentially null.
- - 'B' is from 'pkg/front_end/testcases/nnbd/nullable_receiver.dart'.
-Try calling using ?. instead.
+ let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_receiver.dart:27:13: Error: Too many positional arguments: 0 allowed, but 1 found.
+Try removing the extra positional arguments.
b.toString(0);
- ^^^^^^^^" in b.{self::B::toString}(0);
+ ^" in b.{core::Object::toString}(0);
core::Function f1 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/nullable_receiver.dart:29:17: Error: Can't tear off method 'call' from a potentially null value.
Function f1 = a;
^" in a as{TypeError} core::Function;
@@ -119,7 +117,7 @@
^" in a as{TypeError} () →? void;
}
static method ok<T extends core::Object? = core::Object?>(core::String? s, self::A? a, self::ok::T% t, self::B? b, core::Invocation i) → dynamic {
- s.{core::Object::==}(s);
+ s.{core::String::==}(s);
a.{core::Object::==}(a);
t.{core::Object::==}(t);
b.{core::Object::==}(b);
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart
index a000d92..3fe3d5f 100644
--- a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart
@@ -11,6 +11,19 @@
void Function() get functionTypeGetter => () {};
}
+extension Extension on Class {
+ int operator +(int value) => 0;
+ int operator -() => 0;
+ int operator [](int index) => 0;
+ void operator []=(int index, int value) {}
+ int call() => 0;
+ int get extensionProperty => 0;
+ void set extensionProperty(int value) {}
+ int extensionMethod() => 0;
+ Function get extensionFunctionGetter => () {};
+ void Function() get extensionFunctionTypeGetter => () {};
+}
+
Function? get nullableFunction => () {};
void Function()? get nullableFunctionType => () {};
@@ -42,6 +55,23 @@
var topLevelFunctionGetter = nullableClass.functionGetter();
var topLevelFunctionTypeGetter = nullableClass.functionTypeGetter();
+var topLevelExtensionBinary = nullableClass + 0;
+var topLevelExtensionUnary = -nullableClass;
+var topLevelExtensionIndexGet = nullableClass[0];
+var topLevelExtensionIndexSet = nullableClass[0] = 1;
+var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+var topLevelExtensionPropertyGet = nullableClass.extensionProperty;
+var topLevelExtensionPropertySet = nullableClass.extensionProperty = 1;
+var topLevelExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+var topLevelExtensionMethodInvocation = nullableClass.extensionMethod();
+var topLevelExtensionMethodTearOff = nullableClass.extensionMethod;
+var topLevelExtensionFunctionTypeImplicitCall = nullableClass();
+var topLevelExtensionFunctionTypeExplicitCall = nullableClass.call();
+var topLevelExtensionFunctionTypeTearOff = nullableClass.call;
+var topLevelExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+var topLevelExtensionFunctionTypeGetter =
+ nullableClass.extensionFunctionTypeGetter();
+
test() {
var localBinary = nullableInt + 0;
var localUnary = -nullableInt;
@@ -63,6 +93,23 @@
var localFunctionTypeField = nullableClass.functionTypeField();
var localFunctionGetter = nullableClass.functionGetter();
var localFunctionTypeGetter = nullableClass.functionTypeGetter();
+
+ var localExtensionBinary = nullableClass + 0;
+ var localExtensionUnary = -nullableClass;
+ var localExtensionIndexGet = nullableClass[0];
+ var localExtensionIndexSet = nullableClass[0] = 1;
+ var localExtensionIndexGetSet = nullableClass[0] += 1;
+ var localExtensionPropertyGet = nullableClass.extensionProperty;
+ var localExtensionPropertySet = nullableClass.extensionProperty = 1;
+ var localExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+ var localExtensionMethodInvocation = nullableClass.extensionMethod();
+ var localExtensionMethodTearOff = nullableClass.extensionMethod;
+ var localExtensionFunctionTypeImplicitCall = nullableClass();
+ var localExtensionFunctionTypeExplicitCall = nullableClass.call();
+ var localExtensionFunctionTypeTearOff = nullableClass.call;
+ var localExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+ var localExtensionFunctionTypeGetter =
+ nullableClass.extensionFunctionTypeGetter();
}
main() {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.outline.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.outline.expect
index e9455e1..7ba4b0f 100644
--- a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.outline.expect
@@ -15,6 +15,20 @@
get functionTypeGetter() → () → void
;
}
+extension Extension on self::Class {
+ operator + = self::Extension|+;
+ operator unary- = self::Extension|unary-;
+ operator [] = self::Extension|[];
+ operator []= = self::Extension|[]=;
+ method call = self::Extension|call;
+ tearoff call = self::Extension|get#call;
+ get extensionProperty = self::Extension|get#extensionProperty;
+ method extensionMethod = self::Extension|extensionMethod;
+ tearoff extensionMethod = self::Extension|get#extensionMethod;
+ get extensionFunctionGetter = self::Extension|get#extensionFunctionGetter;
+ get extensionFunctionTypeGetter = self::Extension|get#extensionFunctionTypeGetter;
+ set extensionProperty = self::Extension|set#extensionProperty;
+}
static field core::int? topLevelBinary;
static field core::int topLevelUnary;
static field dynamic topLevelIndexGet;
@@ -35,6 +49,45 @@
static field void topLevelFunctionTypeField;
static field dynamic topLevelFunctionGetter;
static field void topLevelFunctionTypeGetter;
+static field core::int topLevelExtensionBinary;
+static field core::int topLevelExtensionUnary;
+static field core::int topLevelExtensionIndexGet;
+static field core::int topLevelExtensionIndexSet;
+static field core::int topLevelExtensionIndexGetSet;
+static field core::int topLevelExtensionPropertyGet;
+static field core::int topLevelExtensionPropertySet;
+static field core::int topLevelExtensionPropertyGetSet;
+static field core::int topLevelExtensionMethodInvocation;
+static field () → core::int topLevelExtensionMethodTearOff;
+static field core::int topLevelExtensionFunctionTypeImplicitCall;
+static field core::int topLevelExtensionFunctionTypeExplicitCall;
+static field () → core::int topLevelExtensionFunctionTypeTearOff;
+static field dynamic topLevelExtensionFunctionGetter;
+static field void topLevelExtensionFunctionTypeGetter;
+static method Extension|+(final self::Class #this, core::int value) → core::int
+ ;
+static method Extension|unary-(final self::Class #this) → core::int
+ ;
+static method Extension|[](final self::Class #this, core::int index) → core::int
+ ;
+static method Extension|[]=(final self::Class #this, core::int index, core::int value) → void
+ ;
+static method Extension|call(final self::Class #this) → core::int
+ ;
+static method Extension|get#call(final self::Class #this) → () → core::int
+ return () → core::int => self::Extension|call(#this);
+static method Extension|get#extensionProperty(final self::Class #this) → core::int
+ ;
+static method Extension|set#extensionProperty(final self::Class #this, core::int value) → void
+ ;
+static method Extension|extensionMethod(final self::Class #this) → core::int
+ ;
+static method Extension|get#extensionMethod(final self::Class #this) → () → core::int
+ return () → core::int => self::Extension|extensionMethod(#this);
+static method Extension|get#extensionFunctionGetter(final self::Class #this) → core::Function
+ ;
+static method Extension|get#extensionFunctionTypeGetter(final self::Class #this) → () → void
+ ;
static get nullableFunction() → core::Function?
;
static get nullableFunctionType() → () →? void
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.expect
index eeb102b..7c80c76 100644
--- a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.expect
@@ -2,176 +2,416 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:37:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
// var topLevelBinary = nullableInt + 0;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:25:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
// var topLevelUnary = -nullableInt;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:26:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
// - 'Map' is from 'dart:core'.
// var topLevelIndexGet = nullableMap[0];
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:27:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:40:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
// - 'Map' is from 'dart:core'.
// var topLevelIndexSet = nullableMap[0] = 1;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
// - 'Map' is from 'dart:core'.
// var topLevelIndexGetSet = nullableMap[0] += 1;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
// - 'Map' is from 'dart:core'.
// var topLevelIndexGetSet = nullableMap[0] += 1;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:29:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
// Try accessing using ?. instead.
// var topLevelPropertyGet = nullableClass.property;
// ^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:30:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:43:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
// Try accessing using ?. instead.
// var topLevelPropertySet = nullableClass.property = 1;
// ^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
// Try accessing using ?. instead.
// var topLevelPropertyGetSet = nullableClass.property += 1;
// ^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:32:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:45:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
// Try calling using ?. instead.
// var topLevelMethodInvocation = nullableClass.method();
// ^^^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:34:52: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:43: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelMethodTearOff = nullableClass.method;
+// ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:52: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
// - 'Function' is from 'dart:core'.
// Try calling using ?.call instead.
// var topLevelFunctionImplicitCall = nullableFunction();
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:35:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
// - 'Function' is from 'dart:core'.
// Try calling using ?. instead.
// var topLevelFunctionExplicitCall = nullableFunction.call();
// ^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:36:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
// - 'Function' is from 'dart:core'.
// Try accessing using ?. instead.
// var topLevelFunctionTearOff = nullableFunction.call;
// ^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:37:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
// Try calling using ?.call instead.
// var topLevelFunctionTypeImplicitCall = nullableFunctionType();
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
// Try calling using ?. instead.
// var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
// ^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
// Try accessing using ?. instead.
// var topLevelFunctionTypeTearOff = nullableFunctionType.call;
// ^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelFunctionField = nullableClass.functionField();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:54:47: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelFunctionTypeField = nullableClass.functionTypeField();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:55:44: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelFunctionGetter = nullableClass.functionGetter();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:56:48: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelFunctionTypeGetter = nullableClass.functionTypeGetter();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:58:45: Error: Operator '+' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionBinary = nullableClass + 0;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:59:30: Error: Operator 'unary-' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionUnary = -nullableClass;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:60:46: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionIndexGet = nullableClass[0];
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:61:46: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionIndexSet = nullableClass[0] = 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:62:49: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:62:49: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:63:50: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionPropertyGet = nullableClass.extensionProperty;
+// ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:64:50: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionPropertySet = nullableClass.extensionProperty = 1;
+// ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:65:53: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+// ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:66:55: Error: Method 'extensionMethod' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var topLevelExtensionMethodInvocation = nullableClass.extensionMethod();
+// ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:67:52: Error: Property 'extensionMethod' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionMethodTearOff = nullableClass.extensionMethod;
+// ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:68:62: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelExtensionFunctionTypeImplicitCall = nullableClass();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:69:63: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var topLevelExtensionFunctionTypeExplicitCall = nullableClass.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:70:58: Error: Property 'call' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionFunctionTypeTearOff = nullableClass.call;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:71:53: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:73:19: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// nullableClass.extensionFunctionTypeGetter();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:76:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
// var localBinary = nullableInt + 0;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:77:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
// var localUnary = -nullableInt;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:78:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
// - 'Map' is from 'dart:core'.
// var localIndexGet = nullableMap[0];
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:79:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
// - 'Map' is from 'dart:core'.
// var localIndexSet = nullableMap[0] = 1;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:80:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
// - 'Map' is from 'dart:core'.
// var localIndexGetSet = nullableMap[0] += 1;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:80:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
// - 'Map' is from 'dart:core'.
// var localIndexGetSet = nullableMap[0] += 1;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:81:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
// Try accessing using ?. instead.
// var localPropertyGet = nullableClass.property;
// ^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:82:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
// Try accessing using ?. instead.
// var localPropertySet = nullableClass.property = 1;
// ^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:83:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
// Try accessing using ?. instead.
// var localPropertyGetSet = nullableClass.property += 1;
// ^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:54:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:84:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
// Try calling using ?. instead.
// var localMethodInvocation = nullableClass.method();
// ^^^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:56:51: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:85:42: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localMethodTearOff = nullableClass.method;
+// ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:86:51: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
// - 'Function' is from 'dart:core'.
// Try calling using ?.call instead.
// var localFunctionImplicitCall = nullableFunction();
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:57:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:87:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
// - 'Function' is from 'dart:core'.
// Try calling using ?. instead.
// var localFunctionExplicitCall = nullableFunction.call();
// ^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:58:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:88:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
// - 'Function' is from 'dart:core'.
// Try accessing using ?. instead.
// var localFunctionTearOff = nullableFunction.call;
// ^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:59:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:89:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
// Try calling using ?.call instead.
// var localFunctionTypeImplicitCall = nullableFunctionType();
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:60:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:90:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
// Try calling using ?. instead.
// var localFunctionTypeExplicitCall = nullableFunctionType.call();
// ^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:61:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:91:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
// Try accessing using ?. instead.
// var localFunctionTypeTearOff = nullableFunctionType.call;
// ^^^^
//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:92:42: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var localFunctionField = nullableClass.functionField();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:93:46: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var localFunctionTypeField = nullableClass.functionTypeField();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:94:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var localFunctionGetter = nullableClass.functionGetter();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:95:47: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var localFunctionTypeGetter = nullableClass.functionTypeGetter();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:97:44: Error: Operator '+' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var localExtensionBinary = nullableClass + 0;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:98:29: Error: Operator 'unary-' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var localExtensionUnary = -nullableClass;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:99:45: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var localExtensionIndexGet = nullableClass[0];
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:100:45: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var localExtensionIndexSet = nullableClass[0] = 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:101:48: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var localExtensionIndexGetSet = nullableClass[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:101:48: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var localExtensionIndexGetSet = nullableClass[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:102:49: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localExtensionPropertyGet = nullableClass.extensionProperty;
+// ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:103:49: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localExtensionPropertySet = nullableClass.extensionProperty = 1;
+// ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:104:52: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+// ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:105:54: Error: Method 'extensionMethod' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var localExtensionMethodInvocation = nullableClass.extensionMethod();
+// ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:106:51: Error: Property 'extensionMethod' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localExtensionMethodTearOff = nullableClass.extensionMethod;
+// ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:107:61: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var localExtensionFunctionTypeImplicitCall = nullableClass();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:108:62: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var localExtensionFunctionTypeExplicitCall = nullableClass.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:109:57: Error: Property 'call' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localExtensionFunctionTypeTearOff = nullableClass.call;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:110:52: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var localExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:112:21: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// nullableClass.extensionFunctionTypeGetter();
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -189,83 +429,216 @@
get functionTypeGetter() → () → void
return () → core::Null? {};
}
-static field core::int? topLevelBinary = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+extension Extension on self::Class {
+ operator + = self::Extension|+;
+ operator unary- = self::Extension|unary-;
+ operator [] = self::Extension|[];
+ operator []= = self::Extension|[]=;
+ method call = self::Extension|call;
+ tearoff call = self::Extension|get#call;
+ get extensionProperty = self::Extension|get#extensionProperty;
+ method extensionMethod = self::Extension|extensionMethod;
+ tearoff extensionMethod = self::Extension|get#extensionMethod;
+ get extensionFunctionGetter = self::Extension|get#extensionFunctionGetter;
+ get extensionFunctionTypeGetter = self::Extension|get#extensionFunctionTypeGetter;
+ set extensionProperty = self::Extension|set#extensionProperty;
+}
+static field core::int? topLevelBinary = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:37:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
var topLevelBinary = nullableInt + 0;
^" in self::nullableInt.{core::num::+}(0);
-static field core::int topLevelUnary = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:25:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+static field core::int topLevelUnary = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
var topLevelUnary = -nullableInt;
^" in self::nullableInt.{core::int::unary-}();
-static field dynamic topLevelIndexGet = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:26:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+static field dynamic topLevelIndexGet = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
- 'Map' is from 'dart:core'.
var topLevelIndexGet = nullableMap[0];
^" in self::nullableMap.{core::Map::[]}(0);
-static field core::int topLevelIndexSet = let final core::Map<dynamic, dynamic>? #t4 = self::nullableMap in let final core::int #t5 = 0 in let final core::int #t6 = 1 in let final void #t7 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:27:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+static field core::int topLevelIndexSet = let final core::Map<dynamic, dynamic>? #t4 = self::nullableMap in let final core::int #t5 = 0 in let final core::int #t6 = 1 in let final void #t7 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:40:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
- 'Map' is from 'dart:core'.
var topLevelIndexSet = nullableMap[0] = 1;
^" in #t4.{core::Map::[]=}(#t5, #t6) in #t6;
-static field dynamic topLevelIndexGetSet = let final core::Map<dynamic, dynamic>? #t9 = self::nullableMap in let final core::int #t10 = 0 in let final dynamic #t11 = (let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+static field dynamic topLevelIndexGetSet = let final core::Map<dynamic, dynamic>? #t9 = self::nullableMap in let final core::int #t10 = 0 in let final dynamic #t11 = (let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
- 'Map' is from 'dart:core'.
var topLevelIndexGetSet = nullableMap[0] += 1;
- ^" in #t9.{core::Map::[]}(#t10)).+(1) in let final void #t13 = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ ^" in #t9.{core::Map::[]}(#t10)).+(1) in let final void #t13 = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
- 'Map' is from 'dart:core'.
var topLevelIndexGetSet = nullableMap[0] += 1;
^" in #t9.{core::Map::[]=}(#t10, #t11) in #t11;
-static field core::int topLevelPropertyGet = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:29:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+static field core::int topLevelPropertyGet = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try accessing using ?. instead.
var topLevelPropertyGet = nullableClass.property;
^^^^^^^^" in self::nullableClass.{self::Class::property};
-static field core::int topLevelPropertySet = let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:30:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+static field core::int topLevelPropertySet = let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:43:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try accessing using ?. instead.
var topLevelPropertySet = nullableClass.property = 1;
^^^^^^^^" in self::nullableClass.{self::Class::property} = 1;
-static field core::int topLevelPropertyGetSet = let final self::Class? #t17 = self::nullableClass in let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+static field core::int topLevelPropertyGetSet = let final self::Class? #t17 = self::nullableClass in let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try accessing using ?. instead.
var topLevelPropertyGetSet = nullableClass.property += 1;
- ^^^^^^^^" in #t17.{self::Class::property} = (let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ ^^^^^^^^" in #t17.{self::Class::property} = (let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try accessing using ?. instead.
var topLevelPropertyGetSet = nullableClass.property += 1;
^^^^^^^^" in #t17.{self::Class::property}).{core::num::+}(1);
-static field core::int topLevelMethodInvocation = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:32:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+static field core::int topLevelMethodInvocation = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:45:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try calling using ?. instead.
var topLevelMethodInvocation = nullableClass.method();
^^^^^^" in self::nullableClass.{self::Class::method}();
-static field () → core::int topLevelMethodTearOff = self::nullableClass.{self::Class::method};
-static field dynamic topLevelFunctionImplicitCall = let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:34:52: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+static field () → core::int topLevelMethodTearOff = let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:43: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelMethodTearOff = nullableClass.method;
+ ^^^^^^" in self::nullableClass.{self::Class::method};
+static field dynamic topLevelFunctionImplicitCall = let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:52: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
- 'Function' is from 'dart:core'.
Try calling using ?.call instead.
var topLevelFunctionImplicitCall = nullableFunction();
^" in self::nullableFunction.call();
-static field dynamic topLevelFunctionExplicitCall = let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:35:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+static field dynamic topLevelFunctionExplicitCall = let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
- 'Function' is from 'dart:core'.
Try calling using ?. instead.
var topLevelFunctionExplicitCall = nullableFunction.call();
^^^^" in self::nullableFunction.call();
-static field core::Function? topLevelFunctionTearOff = let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:36:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+static field core::Function? topLevelFunctionTearOff = let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
- 'Function' is from 'dart:core'.
Try accessing using ?. instead.
var topLevelFunctionTearOff = nullableFunction.call;
^^^^" in self::nullableFunction.call;
-static field void topLevelFunctionTypeImplicitCall = let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:37:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+static field void topLevelFunctionTypeImplicitCall = let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
Try calling using ?.call instead.
var topLevelFunctionTypeImplicitCall = nullableFunctionType();
^" in self::nullableFunctionType.call();
-static field void topLevelFunctionTypeExplicitCall = let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+static field void topLevelFunctionTypeExplicitCall = let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
Try calling using ?. instead.
var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
^^^^" in self::nullableFunctionType.call();
-static field () →? void topLevelFunctionTypeTearOff = let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+static field () →? void topLevelFunctionTypeTearOff = let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
Try accessing using ?. instead.
var topLevelFunctionTypeTearOff = nullableFunctionType.call;
^^^^" in self::nullableFunctionType.call;
-static field dynamic topLevelFunctionField = self::nullableClass.{self::Class::functionField}.call();
-static field void topLevelFunctionTypeField = self::nullableClass.{self::Class::functionTypeField}.call();
-static field dynamic topLevelFunctionGetter = self::nullableClass.{self::Class::functionGetter}.call();
-static field void topLevelFunctionTypeGetter = self::nullableClass.{self::Class::functionTypeGetter}.call();
+static field dynamic topLevelFunctionField = let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelFunctionField = nullableClass.functionField();
+ ^" in self::nullableClass.{self::Class::functionField}.call();
+static field void topLevelFunctionTypeField = let final<BottomType> #t29 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:54:47: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelFunctionTypeField = nullableClass.functionTypeField();
+ ^" in self::nullableClass.{self::Class::functionTypeField}.call();
+static field dynamic topLevelFunctionGetter = let final<BottomType> #t30 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:55:44: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelFunctionGetter = nullableClass.functionGetter();
+ ^" in self::nullableClass.{self::Class::functionGetter}.call();
+static field void topLevelFunctionTypeGetter = let final<BottomType> #t31 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:56:48: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelFunctionTypeGetter = nullableClass.functionTypeGetter();
+ ^" in self::nullableClass.{self::Class::functionTypeGetter}.call();
+static field core::int topLevelExtensionBinary = let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:58:45: Error: Operator '+' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionBinary = nullableClass + 0;
+ ^" in self::Extension|+(self::nullableClass, 0);
+static field core::int topLevelExtensionUnary = let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:59:30: Error: Operator 'unary-' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionUnary = -nullableClass;
+ ^" in self::Extension|unary-(self::nullableClass);
+static field core::int topLevelExtensionIndexGet = let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:60:46: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionIndexGet = nullableClass[0];
+ ^" in self::Extension|[](self::nullableClass, 0);
+static field core::int topLevelExtensionIndexSet = let final self::Class? #t35 = self::nullableClass in let final core::int #t36 = 0 in let final core::int #t37 = 1 in let final void #t38 = let final<BottomType> #t39 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:61:46: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionIndexSet = nullableClass[0] = 1;
+ ^" in self::Extension|[]=(#t35, #t36, #t37) in #t37;
+static field core::int topLevelExtensionIndexGetSet = let final self::Class? #t40 = self::nullableClass in let final core::int #t41 = 0 in let final core::int #t42 = (let final<BottomType> #t43 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:62:49: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+ ^" in self::Extension|[](#t40, #t41)).{core::num::+}(1) in let final void #t44 = let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:62:49: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+ ^" in self::Extension|[]=(#t40, #t41, #t42) in #t42;
+static field core::int topLevelExtensionPropertyGet = let final<BottomType> #t46 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:63:50: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionPropertyGet = nullableClass.extensionProperty;
+ ^^^^^^^^^^^^^^^^^" in self::Extension|get#extensionProperty(self::nullableClass);
+static field core::int topLevelExtensionPropertySet = let final<BottomType> #t47 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:64:50: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionPropertySet = nullableClass.extensionProperty = 1;
+ ^^^^^^^^^^^^^^^^^" in let final core::int #t48 = 1 in let final void #t49 = self::Extension|set#extensionProperty(self::nullableClass, #t48) in #t48;
+static field core::int topLevelExtensionPropertyGetSet = let final self::Class? #t50 = self::nullableClass in let final<BottomType> #t51 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:65:53: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+ ^^^^^^^^^^^^^^^^^" in let final core::int #t52 = (let final<BottomType> #t53 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:65:53: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+ ^^^^^^^^^^^^^^^^^" in self::Extension|get#extensionProperty(#t50)).{core::num::+}(1) in let final void #t54 = self::Extension|set#extensionProperty(#t50, #t52) in #t52;
+static field core::int topLevelExtensionMethodInvocation = let final<BottomType> #t55 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:66:55: Error: Method 'extensionMethod' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+var topLevelExtensionMethodInvocation = nullableClass.extensionMethod();
+ ^^^^^^^^^^^^^^^" in self::Extension|extensionMethod(self::nullableClass);
+static field () → core::int topLevelExtensionMethodTearOff = let final<BottomType> #t56 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:67:52: Error: Property 'extensionMethod' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionMethodTearOff = nullableClass.extensionMethod;
+ ^^^^^^^^^^^^^^^" in self::Extension|get#extensionMethod(self::nullableClass);
+static field core::int topLevelExtensionFunctionTypeImplicitCall = let final<BottomType> #t57 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:68:62: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelExtensionFunctionTypeImplicitCall = nullableClass();
+ ^" in self::Extension|call(self::nullableClass);
+static field core::int topLevelExtensionFunctionTypeExplicitCall = let final<BottomType> #t58 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:69:63: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+var topLevelExtensionFunctionTypeExplicitCall = nullableClass.call();
+ ^^^^" in self::Extension|call(self::nullableClass);
+static field () → core::int topLevelExtensionFunctionTypeTearOff = let final<BottomType> #t59 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:70:58: Error: Property 'call' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionFunctionTypeTearOff = nullableClass.call;
+ ^^^^" in self::Extension|get#call(self::nullableClass);
+static field dynamic topLevelExtensionFunctionGetter = let final<BottomType> #t60 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:71:53: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+ ^" in self::Extension|get#extensionFunctionGetter(self::nullableClass).call();
+static field void topLevelExtensionFunctionTypeGetter = let final<BottomType> #t61 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:73:19: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+ nullableClass.extensionFunctionTypeGetter();
+ ^" in self::Extension|get#extensionFunctionTypeGetter(self::nullableClass).call();
+static method Extension|+(final self::Class #this, core::int value) → core::int
+ return 0;
+static method Extension|unary-(final self::Class #this) → core::int
+ return 0;
+static method Extension|[](final self::Class #this, core::int index) → core::int
+ return 0;
+static method Extension|[]=(final self::Class #this, core::int index, core::int value) → void {}
+static method Extension|call(final self::Class #this) → core::int
+ return 0;
+static method Extension|get#call(final self::Class #this) → () → core::int
+ return () → core::int => self::Extension|call(#this);
+static method Extension|get#extensionProperty(final self::Class #this) → core::int
+ return 0;
+static method Extension|set#extensionProperty(final self::Class #this, core::int value) → void {}
+static method Extension|extensionMethod(final self::Class #this) → core::int
+ return 0;
+static method Extension|get#extensionMethod(final self::Class #this) → () → core::int
+ return () → core::int => self::Extension|extensionMethod(#this);
+static method Extension|get#extensionFunctionGetter(final self::Class #this) → core::Function
+ return () → core::Null? {};
+static method Extension|get#extensionFunctionTypeGetter(final self::Class #this) → () → void
+ return () → core::Null? {};
static get nullableFunction() → core::Function?
return () → core::Null? {};
static get nullableFunctionType() → () →? void
@@ -277,82 +650,179 @@
static get nullableClass() → self::Class?
return new self::Class::•();
static method test() → dynamic {
- core::int? localBinary = let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+ core::int? localBinary = let final<BottomType> #t62 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:76:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
var localBinary = nullableInt + 0;
^" in self::nullableInt.{core::num::+}(0);
- core::int localUnary = let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+ core::int localUnary = let final<BottomType> #t63 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:77:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
var localUnary = -nullableInt;
^" in self::nullableInt.{core::int::unary-}();
- dynamic localIndexGet = let final<BottomType> #t29 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ dynamic localIndexGet = let final<BottomType> #t64 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:78:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
- 'Map' is from 'dart:core'.
var localIndexGet = nullableMap[0];
^" in self::nullableMap.{core::Map::[]}(0);
- core::int localIndexSet = let final core::Map<dynamic, dynamic>? #t30 = self::nullableMap in let final core::int #t31 = 0 in let final core::int #t32 = 1 in let final void #t33 = let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ core::int localIndexSet = let final core::Map<dynamic, dynamic>? #t65 = self::nullableMap in let final core::int #t66 = 0 in let final core::int #t67 = 1 in let final void #t68 = let final<BottomType> #t69 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:79:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
- 'Map' is from 'dart:core'.
var localIndexSet = nullableMap[0] = 1;
- ^" in #t30.{core::Map::[]=}(#t31, #t32) in #t32;
- dynamic localIndexGetSet = let final core::Map<dynamic, dynamic>? #t35 = self::nullableMap in let final core::int #t36 = 0 in let final dynamic #t37 = (let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ ^" in #t65.{core::Map::[]=}(#t66, #t67) in #t67;
+ dynamic localIndexGetSet = let final core::Map<dynamic, dynamic>? #t70 = self::nullableMap in let final core::int #t71 = 0 in let final dynamic #t72 = (let final<BottomType> #t73 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:80:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
- 'Map' is from 'dart:core'.
var localIndexGetSet = nullableMap[0] += 1;
- ^" in #t35.{core::Map::[]}(#t36)).+(1) in let final void #t39 = let final<BottomType> #t40 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ ^" in #t70.{core::Map::[]}(#t71)).+(1) in let final void #t74 = let final<BottomType> #t75 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:80:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
- 'Map' is from 'dart:core'.
var localIndexGetSet = nullableMap[0] += 1;
- ^" in #t35.{core::Map::[]=}(#t36, #t37) in #t37;
- core::int localPropertyGet = let final<BottomType> #t41 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ ^" in #t70.{core::Map::[]=}(#t71, #t72) in #t72;
+ core::int localPropertyGet = let final<BottomType> #t76 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:81:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try accessing using ?. instead.
var localPropertyGet = nullableClass.property;
^^^^^^^^" in self::nullableClass.{self::Class::property};
- core::int localPropertySet = let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ core::int localPropertySet = let final<BottomType> #t77 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:82:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try accessing using ?. instead.
var localPropertySet = nullableClass.property = 1;
^^^^^^^^" in self::nullableClass.{self::Class::property} = 1;
- core::int localPropertyGetSet = let final self::Class? #t43 = self::nullableClass in let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ core::int localPropertyGetSet = let final self::Class? #t78 = self::nullableClass in let final<BottomType> #t79 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:83:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try accessing using ?. instead.
var localPropertyGetSet = nullableClass.property += 1;
- ^^^^^^^^" in #t43.{self::Class::property} = (let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ ^^^^^^^^" in #t78.{self::Class::property} = (let final<BottomType> #t80 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:83:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try accessing using ?. instead.
var localPropertyGetSet = nullableClass.property += 1;
- ^^^^^^^^" in #t43.{self::Class::property}).{core::num::+}(1);
- core::int localMethodInvocation = let final<BottomType> #t46 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:54:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+ ^^^^^^^^" in #t78.{self::Class::property}).{core::num::+}(1);
+ core::int localMethodInvocation = let final<BottomType> #t81 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:84:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try calling using ?. instead.
var localMethodInvocation = nullableClass.method();
^^^^^^" in self::nullableClass.{self::Class::method}();
- () → core::int localMethodTearOff = self::nullableClass.{self::Class::method};
- dynamic localFunctionImplicitCall = let final<BottomType> #t47 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:56:51: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+ () → core::int localMethodTearOff = let final<BottomType> #t82 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:85:42: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localMethodTearOff = nullableClass.method;
+ ^^^^^^" in self::nullableClass.{self::Class::method};
+ dynamic localFunctionImplicitCall = let final<BottomType> #t83 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:86:51: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
- 'Function' is from 'dart:core'.
Try calling using ?.call instead.
var localFunctionImplicitCall = nullableFunction();
^" in self::nullableFunction.call();
- dynamic localFunctionExplicitCall = let final<BottomType> #t48 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:57:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ dynamic localFunctionExplicitCall = let final<BottomType> #t84 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:87:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
- 'Function' is from 'dart:core'.
Try calling using ?. instead.
var localFunctionExplicitCall = nullableFunction.call();
^^^^" in self::nullableFunction.call();
- core::Function? localFunctionTearOff = let final<BottomType> #t49 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:58:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+ core::Function? localFunctionTearOff = let final<BottomType> #t85 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:88:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
- 'Function' is from 'dart:core'.
Try accessing using ?. instead.
var localFunctionTearOff = nullableFunction.call;
^^^^" in self::nullableFunction.call;
- void localFunctionTypeImplicitCall = let final<BottomType> #t50 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:59:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+ void localFunctionTypeImplicitCall = let final<BottomType> #t86 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:89:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
Try calling using ?.call instead.
var localFunctionTypeImplicitCall = nullableFunctionType();
^" in self::nullableFunctionType.call();
- void localFunctionTypeExplicitCall = let final<BottomType> #t51 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:60:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+ void localFunctionTypeExplicitCall = let final<BottomType> #t87 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:90:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
Try calling using ?. instead.
var localFunctionTypeExplicitCall = nullableFunctionType.call();
^^^^" in self::nullableFunctionType.call();
- () →? void localFunctionTypeTearOff = let final<BottomType> #t52 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:61:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+ () →? void localFunctionTypeTearOff = let final<BottomType> #t88 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:91:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
Try accessing using ?. instead.
var localFunctionTypeTearOff = nullableFunctionType.call;
^^^^" in self::nullableFunctionType.call;
- dynamic localFunctionField = self::nullableClass.{self::Class::functionField}.call();
- void localFunctionTypeField = self::nullableClass.{self::Class::functionTypeField}.call();
- dynamic localFunctionGetter = self::nullableClass.{self::Class::functionGetter}.call();
- void localFunctionTypeGetter = self::nullableClass.{self::Class::functionTypeGetter}.call();
+ dynamic localFunctionField = let final<BottomType> #t89 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:92:42: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+ var localFunctionField = nullableClass.functionField();
+ ^" in self::nullableClass.{self::Class::functionField}.call();
+ void localFunctionTypeField = let final<BottomType> #t90 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:93:46: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+ var localFunctionTypeField = nullableClass.functionTypeField();
+ ^" in self::nullableClass.{self::Class::functionTypeField}.call();
+ dynamic localFunctionGetter = let final<BottomType> #t91 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:94:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+ var localFunctionGetter = nullableClass.functionGetter();
+ ^" in self::nullableClass.{self::Class::functionGetter}.call();
+ void localFunctionTypeGetter = let final<BottomType> #t92 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:95:47: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+ var localFunctionTypeGetter = nullableClass.functionTypeGetter();
+ ^" in self::nullableClass.{self::Class::functionTypeGetter}.call();
+ core::int localExtensionBinary = let final<BottomType> #t93 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:97:44: Error: Operator '+' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+ var localExtensionBinary = nullableClass + 0;
+ ^" in self::Extension|+(self::nullableClass, 0);
+ core::int localExtensionUnary = let final<BottomType> #t94 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:98:29: Error: Operator 'unary-' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+ var localExtensionUnary = -nullableClass;
+ ^" in self::Extension|unary-(self::nullableClass);
+ core::int localExtensionIndexGet = let final<BottomType> #t95 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:99:45: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+ var localExtensionIndexGet = nullableClass[0];
+ ^" in self::Extension|[](self::nullableClass, 0);
+ core::int localExtensionIndexSet = let final self::Class? #t96 = self::nullableClass in let final core::int #t97 = 0 in let final core::int #t98 = 1 in let final void #t99 = let final<BottomType> #t100 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:100:45: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+ var localExtensionIndexSet = nullableClass[0] = 1;
+ ^" in self::Extension|[]=(#t96, #t97, #t98) in #t98;
+ core::int localExtensionIndexGetSet = let final self::Class? #t101 = self::nullableClass in let final core::int #t102 = 0 in let final core::int #t103 = (let final<BottomType> #t104 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:101:48: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+ var localExtensionIndexGetSet = nullableClass[0] += 1;
+ ^" in self::Extension|[](#t101, #t102)).{core::num::+}(1) in let final void #t105 = let final<BottomType> #t106 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:101:48: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+ var localExtensionIndexGetSet = nullableClass[0] += 1;
+ ^" in self::Extension|[]=(#t101, #t102, #t103) in #t103;
+ core::int localExtensionPropertyGet = let final<BottomType> #t107 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:102:49: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localExtensionPropertyGet = nullableClass.extensionProperty;
+ ^^^^^^^^^^^^^^^^^" in self::Extension|get#extensionProperty(self::nullableClass);
+ core::int localExtensionPropertySet = let final<BottomType> #t108 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:103:49: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localExtensionPropertySet = nullableClass.extensionProperty = 1;
+ ^^^^^^^^^^^^^^^^^" in let final core::int #t109 = 1 in let final void #t110 = self::Extension|set#extensionProperty(self::nullableClass, #t109) in #t109;
+ core::int localExtensionPropertyGetSet = let final self::Class? #t111 = self::nullableClass in let final<BottomType> #t112 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:104:52: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+ ^^^^^^^^^^^^^^^^^" in let final core::int #t113 = (let final<BottomType> #t114 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:104:52: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+ ^^^^^^^^^^^^^^^^^" in self::Extension|get#extensionProperty(#t111)).{core::num::+}(1) in let final void #t115 = self::Extension|set#extensionProperty(#t111, #t113) in #t113;
+ core::int localExtensionMethodInvocation = let final<BottomType> #t116 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:105:54: Error: Method 'extensionMethod' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+ var localExtensionMethodInvocation = nullableClass.extensionMethod();
+ ^^^^^^^^^^^^^^^" in self::Extension|extensionMethod(self::nullableClass);
+ () → core::int localExtensionMethodTearOff = let final<BottomType> #t117 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:106:51: Error: Property 'extensionMethod' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localExtensionMethodTearOff = nullableClass.extensionMethod;
+ ^^^^^^^^^^^^^^^" in self::Extension|get#extensionMethod(self::nullableClass);
+ core::int localExtensionFunctionTypeImplicitCall = let final<BottomType> #t118 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:107:61: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+ var localExtensionFunctionTypeImplicitCall = nullableClass();
+ ^" in self::Extension|call(self::nullableClass);
+ core::int localExtensionFunctionTypeExplicitCall = let final<BottomType> #t119 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:108:62: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+ var localExtensionFunctionTypeExplicitCall = nullableClass.call();
+ ^^^^" in self::Extension|call(self::nullableClass);
+ () → core::int localExtensionFunctionTypeTearOff = let final<BottomType> #t120 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:109:57: Error: Property 'call' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localExtensionFunctionTypeTearOff = nullableClass.call;
+ ^^^^" in self::Extension|get#call(self::nullableClass);
+ dynamic localExtensionFunctionGetter = let final<BottomType> #t121 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:110:52: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+ var localExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+ ^" in self::Extension|get#extensionFunctionGetter(self::nullableClass).call();
+ void localExtensionFunctionTypeGetter = let final<BottomType> #t122 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:112:21: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+ nullableClass.extensionFunctionTypeGetter();
+ ^" in self::Extension|get#extensionFunctionTypeGetter(self::nullableClass).call();
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.expect
index eeb102b..7c80c76 100644
--- a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.expect
@@ -2,176 +2,416 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:37:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
// var topLevelBinary = nullableInt + 0;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:25:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
// var topLevelUnary = -nullableInt;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:26:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
// - 'Map' is from 'dart:core'.
// var topLevelIndexGet = nullableMap[0];
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:27:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:40:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
// - 'Map' is from 'dart:core'.
// var topLevelIndexSet = nullableMap[0] = 1;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
// - 'Map' is from 'dart:core'.
// var topLevelIndexGetSet = nullableMap[0] += 1;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
// - 'Map' is from 'dart:core'.
// var topLevelIndexGetSet = nullableMap[0] += 1;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:29:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
// Try accessing using ?. instead.
// var topLevelPropertyGet = nullableClass.property;
// ^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:30:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:43:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
// Try accessing using ?. instead.
// var topLevelPropertySet = nullableClass.property = 1;
// ^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
// Try accessing using ?. instead.
// var topLevelPropertyGetSet = nullableClass.property += 1;
// ^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:32:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:45:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
// Try calling using ?. instead.
// var topLevelMethodInvocation = nullableClass.method();
// ^^^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:34:52: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:43: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelMethodTearOff = nullableClass.method;
+// ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:52: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
// - 'Function' is from 'dart:core'.
// Try calling using ?.call instead.
// var topLevelFunctionImplicitCall = nullableFunction();
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:35:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
// - 'Function' is from 'dart:core'.
// Try calling using ?. instead.
// var topLevelFunctionExplicitCall = nullableFunction.call();
// ^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:36:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
// - 'Function' is from 'dart:core'.
// Try accessing using ?. instead.
// var topLevelFunctionTearOff = nullableFunction.call;
// ^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:37:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
// Try calling using ?.call instead.
// var topLevelFunctionTypeImplicitCall = nullableFunctionType();
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
// Try calling using ?. instead.
// var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
// ^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
// Try accessing using ?. instead.
// var topLevelFunctionTypeTearOff = nullableFunctionType.call;
// ^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelFunctionField = nullableClass.functionField();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:54:47: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelFunctionTypeField = nullableClass.functionTypeField();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:55:44: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelFunctionGetter = nullableClass.functionGetter();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:56:48: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelFunctionTypeGetter = nullableClass.functionTypeGetter();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:58:45: Error: Operator '+' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionBinary = nullableClass + 0;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:59:30: Error: Operator 'unary-' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionUnary = -nullableClass;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:60:46: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionIndexGet = nullableClass[0];
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:61:46: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionIndexSet = nullableClass[0] = 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:62:49: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:62:49: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:63:50: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionPropertyGet = nullableClass.extensionProperty;
+// ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:64:50: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionPropertySet = nullableClass.extensionProperty = 1;
+// ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:65:53: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+// ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:66:55: Error: Method 'extensionMethod' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var topLevelExtensionMethodInvocation = nullableClass.extensionMethod();
+// ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:67:52: Error: Property 'extensionMethod' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionMethodTearOff = nullableClass.extensionMethod;
+// ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:68:62: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelExtensionFunctionTypeImplicitCall = nullableClass();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:69:63: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var topLevelExtensionFunctionTypeExplicitCall = nullableClass.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:70:58: Error: Property 'call' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var topLevelExtensionFunctionTypeTearOff = nullableClass.call;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:71:53: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var topLevelExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:73:19: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// nullableClass.extensionFunctionTypeGetter();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:76:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
// var localBinary = nullableInt + 0;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:77:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
// var localUnary = -nullableInt;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:78:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
// - 'Map' is from 'dart:core'.
// var localIndexGet = nullableMap[0];
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:79:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
// - 'Map' is from 'dart:core'.
// var localIndexSet = nullableMap[0] = 1;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:80:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
// - 'Map' is from 'dart:core'.
// var localIndexGetSet = nullableMap[0] += 1;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:80:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
// - 'Map' is from 'dart:core'.
// var localIndexGetSet = nullableMap[0] += 1;
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:81:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
// Try accessing using ?. instead.
// var localPropertyGet = nullableClass.property;
// ^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:82:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
// Try accessing using ?. instead.
// var localPropertySet = nullableClass.property = 1;
// ^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:83:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
// Try accessing using ?. instead.
// var localPropertyGetSet = nullableClass.property += 1;
// ^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:54:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:84:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
// Try calling using ?. instead.
// var localMethodInvocation = nullableClass.method();
// ^^^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:56:51: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:85:42: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localMethodTearOff = nullableClass.method;
+// ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:86:51: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
// - 'Function' is from 'dart:core'.
// Try calling using ?.call instead.
// var localFunctionImplicitCall = nullableFunction();
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:57:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:87:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
// - 'Function' is from 'dart:core'.
// Try calling using ?. instead.
// var localFunctionExplicitCall = nullableFunction.call();
// ^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:58:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:88:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
// - 'Function' is from 'dart:core'.
// Try accessing using ?. instead.
// var localFunctionTearOff = nullableFunction.call;
// ^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:59:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:89:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
// Try calling using ?.call instead.
// var localFunctionTypeImplicitCall = nullableFunctionType();
// ^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:60:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:90:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
// Try calling using ?. instead.
// var localFunctionTypeExplicitCall = nullableFunctionType.call();
// ^^^^
//
-// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:61:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:91:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
// Try accessing using ?. instead.
// var localFunctionTypeTearOff = nullableFunctionType.call;
// ^^^^
//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:92:42: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var localFunctionField = nullableClass.functionField();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:93:46: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var localFunctionTypeField = nullableClass.functionTypeField();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:94:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var localFunctionGetter = nullableClass.functionGetter();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:95:47: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var localFunctionTypeGetter = nullableClass.functionTypeGetter();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:97:44: Error: Operator '+' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var localExtensionBinary = nullableClass + 0;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:98:29: Error: Operator 'unary-' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var localExtensionUnary = -nullableClass;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:99:45: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var localExtensionIndexGet = nullableClass[0];
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:100:45: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var localExtensionIndexSet = nullableClass[0] = 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:101:48: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var localExtensionIndexGetSet = nullableClass[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:101:48: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// var localExtensionIndexGetSet = nullableClass[0] += 1;
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:102:49: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localExtensionPropertyGet = nullableClass.extensionProperty;
+// ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:103:49: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localExtensionPropertySet = nullableClass.extensionProperty = 1;
+// ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:104:52: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+// ^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:105:54: Error: Method 'extensionMethod' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var localExtensionMethodInvocation = nullableClass.extensionMethod();
+// ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:106:51: Error: Property 'extensionMethod' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localExtensionMethodTearOff = nullableClass.extensionMethod;
+// ^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:107:61: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var localExtensionFunctionTypeImplicitCall = nullableClass();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:108:62: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?. instead.
+// var localExtensionFunctionTypeExplicitCall = nullableClass.call();
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:109:57: Error: Property 'call' cannot be accessed on 'Class?' because it is potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try accessing using ?. instead.
+// var localExtensionFunctionTypeTearOff = nullableClass.call;
+// ^^^^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:110:52: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// var localExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+// ^
+//
+// pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:112:21: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+// Try calling using ?.call instead.
+// nullableClass.extensionFunctionTypeGetter();
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -189,83 +429,216 @@
get functionTypeGetter() → () → void
return () → core::Null? {};
}
-static field core::int? topLevelBinary = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:24:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+extension Extension on self::Class {
+ operator + = self::Extension|+;
+ operator unary- = self::Extension|unary-;
+ operator [] = self::Extension|[];
+ operator []= = self::Extension|[]=;
+ method call = self::Extension|call;
+ tearoff call = self::Extension|get#call;
+ get extensionProperty = self::Extension|get#extensionProperty;
+ method extensionMethod = self::Extension|extensionMethod;
+ tearoff extensionMethod = self::Extension|get#extensionMethod;
+ get extensionFunctionGetter = self::Extension|get#extensionFunctionGetter;
+ get extensionFunctionTypeGetter = self::Extension|get#extensionFunctionTypeGetter;
+ set extensionProperty = self::Extension|set#extensionProperty;
+}
+static field core::int? topLevelBinary = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:37:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
var topLevelBinary = nullableInt + 0;
^" in self::nullableInt.{core::num::+}(0);
-static field core::int topLevelUnary = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:25:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+static field core::int topLevelUnary = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:21: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
var topLevelUnary = -nullableInt;
^" in self::nullableInt.{core::int::unary-}();
-static field dynamic topLevelIndexGet = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:26:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+static field dynamic topLevelIndexGet = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:35: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
- 'Map' is from 'dart:core'.
var topLevelIndexGet = nullableMap[0];
^" in self::nullableMap.{core::Map::[]}(0);
-static field core::int topLevelIndexSet = let final core::Map<dynamic, dynamic>? #t4 = self::nullableMap in let final core::int #t5 = 0 in let final core::int #t6 = 1 in let final void #t7 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:27:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+static field core::int topLevelIndexSet = let final core::Map<dynamic, dynamic>? #t4 = self::nullableMap in let final core::int #t5 = 0 in let final core::int #t6 = 1 in let final void #t7 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:40:35: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
- 'Map' is from 'dart:core'.
var topLevelIndexSet = nullableMap[0] = 1;
^" in #t4.{core::Map::[]=}(#t5, #t6) in #t6;
-static field dynamic topLevelIndexGetSet = let final core::Map<dynamic, dynamic>? #t9 = self::nullableMap in let final core::int #t10 = 0 in let final dynamic #t11 = (let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+static field dynamic topLevelIndexGetSet = let final core::Map<dynamic, dynamic>? #t9 = self::nullableMap in let final core::int #t10 = 0 in let final dynamic #t11 = (let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:38: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
- 'Map' is from 'dart:core'.
var topLevelIndexGetSet = nullableMap[0] += 1;
- ^" in #t9.{core::Map::[]}(#t10)).+(1) in let final void #t13 = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:28:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ ^" in #t9.{core::Map::[]}(#t10)).+(1) in let final void #t13 = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:41:38: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
- 'Map' is from 'dart:core'.
var topLevelIndexGetSet = nullableMap[0] += 1;
^" in #t9.{core::Map::[]=}(#t10, #t11) in #t11;
-static field core::int topLevelPropertyGet = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:29:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+static field core::int topLevelPropertyGet = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:42:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try accessing using ?. instead.
var topLevelPropertyGet = nullableClass.property;
^^^^^^^^" in self::nullableClass.{self::Class::property};
-static field core::int topLevelPropertySet = let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:30:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+static field core::int topLevelPropertySet = let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:43:41: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try accessing using ?. instead.
var topLevelPropertySet = nullableClass.property = 1;
^^^^^^^^" in self::nullableClass.{self::Class::property} = 1;
-static field core::int topLevelPropertyGetSet = let final self::Class? #t17 = self::nullableClass in let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+static field core::int topLevelPropertyGetSet = let final self::Class? #t17 = self::nullableClass in let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try accessing using ?. instead.
var topLevelPropertyGetSet = nullableClass.property += 1;
- ^^^^^^^^" in #t17.{self::Class::property} = (let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:31:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ ^^^^^^^^" in #t17.{self::Class::property} = (let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:44:44: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try accessing using ?. instead.
var topLevelPropertyGetSet = nullableClass.property += 1;
^^^^^^^^" in #t17.{self::Class::property}).{core::num::+}(1);
-static field core::int topLevelMethodInvocation = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:32:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+static field core::int topLevelMethodInvocation = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:45:46: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try calling using ?. instead.
var topLevelMethodInvocation = nullableClass.method();
^^^^^^" in self::nullableClass.{self::Class::method}();
-static field () → core::int topLevelMethodTearOff = self::nullableClass.{self::Class::method};
-static field dynamic topLevelFunctionImplicitCall = let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:34:52: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+static field () → core::int topLevelMethodTearOff = let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:43: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelMethodTearOff = nullableClass.method;
+ ^^^^^^" in self::nullableClass.{self::Class::method};
+static field dynamic topLevelFunctionImplicitCall = let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:52: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
- 'Function' is from 'dart:core'.
Try calling using ?.call instead.
var topLevelFunctionImplicitCall = nullableFunction();
^" in self::nullableFunction.call();
-static field dynamic topLevelFunctionExplicitCall = let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:35:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+static field dynamic topLevelFunctionExplicitCall = let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:53: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
- 'Function' is from 'dart:core'.
Try calling using ?. instead.
var topLevelFunctionExplicitCall = nullableFunction.call();
^^^^" in self::nullableFunction.call();
-static field core::Function? topLevelFunctionTearOff = let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:36:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+static field core::Function? topLevelFunctionTearOff = let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:48: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
- 'Function' is from 'dart:core'.
Try accessing using ?. instead.
var topLevelFunctionTearOff = nullableFunction.call;
^^^^" in self::nullableFunction.call;
-static field void topLevelFunctionTypeImplicitCall = let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:37:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+static field void topLevelFunctionTypeImplicitCall = let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
Try calling using ?.call instead.
var topLevelFunctionTypeImplicitCall = nullableFunctionType();
^" in self::nullableFunctionType.call();
-static field void topLevelFunctionTypeExplicitCall = let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:38:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+static field void topLevelFunctionTypeExplicitCall = let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:61: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
Try calling using ?. instead.
var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
^^^^" in self::nullableFunctionType.call();
-static field () →? void topLevelFunctionTypeTearOff = let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:39:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+static field () →? void topLevelFunctionTypeTearOff = let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
Try accessing using ?. instead.
var topLevelFunctionTypeTearOff = nullableFunctionType.call;
^^^^" in self::nullableFunctionType.call;
-static field dynamic topLevelFunctionField = self::nullableClass.{self::Class::functionField}.call();
-static field void topLevelFunctionTypeField = self::nullableClass.{self::Class::functionTypeField}.call();
-static field dynamic topLevelFunctionGetter = self::nullableClass.{self::Class::functionGetter}.call();
-static field void topLevelFunctionTypeGetter = self::nullableClass.{self::Class::functionTypeGetter}.call();
+static field dynamic topLevelFunctionField = let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelFunctionField = nullableClass.functionField();
+ ^" in self::nullableClass.{self::Class::functionField}.call();
+static field void topLevelFunctionTypeField = let final<BottomType> #t29 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:54:47: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelFunctionTypeField = nullableClass.functionTypeField();
+ ^" in self::nullableClass.{self::Class::functionTypeField}.call();
+static field dynamic topLevelFunctionGetter = let final<BottomType> #t30 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:55:44: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelFunctionGetter = nullableClass.functionGetter();
+ ^" in self::nullableClass.{self::Class::functionGetter}.call();
+static field void topLevelFunctionTypeGetter = let final<BottomType> #t31 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:56:48: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelFunctionTypeGetter = nullableClass.functionTypeGetter();
+ ^" in self::nullableClass.{self::Class::functionTypeGetter}.call();
+static field core::int topLevelExtensionBinary = let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:58:45: Error: Operator '+' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionBinary = nullableClass + 0;
+ ^" in self::Extension|+(self::nullableClass, 0);
+static field core::int topLevelExtensionUnary = let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:59:30: Error: Operator 'unary-' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionUnary = -nullableClass;
+ ^" in self::Extension|unary-(self::nullableClass);
+static field core::int topLevelExtensionIndexGet = let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:60:46: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionIndexGet = nullableClass[0];
+ ^" in self::Extension|[](self::nullableClass, 0);
+static field core::int topLevelExtensionIndexSet = let final self::Class? #t35 = self::nullableClass in let final core::int #t36 = 0 in let final core::int #t37 = 1 in let final void #t38 = let final<BottomType> #t39 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:61:46: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionIndexSet = nullableClass[0] = 1;
+ ^" in self::Extension|[]=(#t35, #t36, #t37) in #t37;
+static field core::int topLevelExtensionIndexGetSet = let final self::Class? #t40 = self::nullableClass in let final core::int #t41 = 0 in let final core::int #t42 = (let final<BottomType> #t43 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:62:49: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+ ^" in self::Extension|[](#t40, #t41)).{core::num::+}(1) in let final void #t44 = let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:62:49: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+ ^" in self::Extension|[]=(#t40, #t41, #t42) in #t42;
+static field core::int topLevelExtensionPropertyGet = let final<BottomType> #t46 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:63:50: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionPropertyGet = nullableClass.extensionProperty;
+ ^^^^^^^^^^^^^^^^^" in self::Extension|get#extensionProperty(self::nullableClass);
+static field core::int topLevelExtensionPropertySet = let final<BottomType> #t47 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:64:50: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionPropertySet = nullableClass.extensionProperty = 1;
+ ^^^^^^^^^^^^^^^^^" in let final core::int #t48 = 1 in let final void #t49 = self::Extension|set#extensionProperty(self::nullableClass, #t48) in #t48;
+static field core::int topLevelExtensionPropertyGetSet = let final self::Class? #t50 = self::nullableClass in let final<BottomType> #t51 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:65:53: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+ ^^^^^^^^^^^^^^^^^" in let final core::int #t52 = (let final<BottomType> #t53 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:65:53: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+ ^^^^^^^^^^^^^^^^^" in self::Extension|get#extensionProperty(#t50)).{core::num::+}(1) in let final void #t54 = self::Extension|set#extensionProperty(#t50, #t52) in #t52;
+static field core::int topLevelExtensionMethodInvocation = let final<BottomType> #t55 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:66:55: Error: Method 'extensionMethod' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+var topLevelExtensionMethodInvocation = nullableClass.extensionMethod();
+ ^^^^^^^^^^^^^^^" in self::Extension|extensionMethod(self::nullableClass);
+static field () → core::int topLevelExtensionMethodTearOff = let final<BottomType> #t56 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:67:52: Error: Property 'extensionMethod' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionMethodTearOff = nullableClass.extensionMethod;
+ ^^^^^^^^^^^^^^^" in self::Extension|get#extensionMethod(self::nullableClass);
+static field core::int topLevelExtensionFunctionTypeImplicitCall = let final<BottomType> #t57 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:68:62: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelExtensionFunctionTypeImplicitCall = nullableClass();
+ ^" in self::Extension|call(self::nullableClass);
+static field core::int topLevelExtensionFunctionTypeExplicitCall = let final<BottomType> #t58 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:69:63: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+var topLevelExtensionFunctionTypeExplicitCall = nullableClass.call();
+ ^^^^" in self::Extension|call(self::nullableClass);
+static field () → core::int topLevelExtensionFunctionTypeTearOff = let final<BottomType> #t59 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:70:58: Error: Property 'call' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+var topLevelExtensionFunctionTypeTearOff = nullableClass.call;
+ ^^^^" in self::Extension|get#call(self::nullableClass);
+static field dynamic topLevelExtensionFunctionGetter = let final<BottomType> #t60 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:71:53: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+var topLevelExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+ ^" in self::Extension|get#extensionFunctionGetter(self::nullableClass).call();
+static field void topLevelExtensionFunctionTypeGetter = let final<BottomType> #t61 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:73:19: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+ nullableClass.extensionFunctionTypeGetter();
+ ^" in self::Extension|get#extensionFunctionTypeGetter(self::nullableClass).call();
+static method Extension|+(final self::Class #this, core::int value) → core::int
+ return 0;
+static method Extension|unary-(final self::Class #this) → core::int
+ return 0;
+static method Extension|[](final self::Class #this, core::int index) → core::int
+ return 0;
+static method Extension|[]=(final self::Class #this, core::int index, core::int value) → void {}
+static method Extension|call(final self::Class #this) → core::int
+ return 0;
+static method Extension|get#call(final self::Class #this) → () → core::int
+ return () → core::int => self::Extension|call(#this);
+static method Extension|get#extensionProperty(final self::Class #this) → core::int
+ return 0;
+static method Extension|set#extensionProperty(final self::Class #this, core::int value) → void {}
+static method Extension|extensionMethod(final self::Class #this) → core::int
+ return 0;
+static method Extension|get#extensionMethod(final self::Class #this) → () → core::int
+ return () → core::int => self::Extension|extensionMethod(#this);
+static method Extension|get#extensionFunctionGetter(final self::Class #this) → core::Function
+ return () → core::Null? {};
+static method Extension|get#extensionFunctionTypeGetter(final self::Class #this) → () → void
+ return () → core::Null? {};
static get nullableFunction() → core::Function?
return () → core::Null? {};
static get nullableFunctionType() → () →? void
@@ -277,82 +650,179 @@
static get nullableClass() → self::Class?
return new self::Class::•();
static method test() → dynamic {
- core::int? localBinary = let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:46:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+ core::int? localBinary = let final<BottomType> #t62 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:76:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
var localBinary = nullableInt + 0;
^" in self::nullableInt.{core::num::+}(0);
- core::int localUnary = let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:47:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+ core::int localUnary = let final<BottomType> #t63 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:77:20: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
var localUnary = -nullableInt;
^" in self::nullableInt.{core::int::unary-}();
- dynamic localIndexGet = let final<BottomType> #t29 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:48:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ dynamic localIndexGet = let final<BottomType> #t64 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:78:34: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
- 'Map' is from 'dart:core'.
var localIndexGet = nullableMap[0];
^" in self::nullableMap.{core::Map::[]}(0);
- core::int localIndexSet = let final core::Map<dynamic, dynamic>? #t30 = self::nullableMap in let final core::int #t31 = 0 in let final core::int #t32 = 1 in let final void #t33 = let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:49:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ core::int localIndexSet = let final core::Map<dynamic, dynamic>? #t65 = self::nullableMap in let final core::int #t66 = 0 in let final core::int #t67 = 1 in let final void #t68 = let final<BottomType> #t69 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:79:34: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
- 'Map' is from 'dart:core'.
var localIndexSet = nullableMap[0] = 1;
- ^" in #t30.{core::Map::[]=}(#t31, #t32) in #t32;
- dynamic localIndexGetSet = let final core::Map<dynamic, dynamic>? #t35 = self::nullableMap in let final core::int #t36 = 0 in let final dynamic #t37 = (let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ ^" in #t65.{core::Map::[]=}(#t66, #t67) in #t67;
+ dynamic localIndexGetSet = let final core::Map<dynamic, dynamic>? #t70 = self::nullableMap in let final core::int #t71 = 0 in let final dynamic #t72 = (let final<BottomType> #t73 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:80:37: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
- 'Map' is from 'dart:core'.
var localIndexGetSet = nullableMap[0] += 1;
- ^" in #t35.{core::Map::[]}(#t36)).+(1) in let final void #t39 = let final<BottomType> #t40 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
+ ^" in #t70.{core::Map::[]}(#t71)).+(1) in let final void #t74 = let final<BottomType> #t75 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:80:37: Error: Operator '[]=' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
- 'Map' is from 'dart:core'.
var localIndexGetSet = nullableMap[0] += 1;
- ^" in #t35.{core::Map::[]=}(#t36, #t37) in #t37;
- core::int localPropertyGet = let final<BottomType> #t41 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:51:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ ^" in #t70.{core::Map::[]=}(#t71, #t72) in #t72;
+ core::int localPropertyGet = let final<BottomType> #t76 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:81:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try accessing using ?. instead.
var localPropertyGet = nullableClass.property;
^^^^^^^^" in self::nullableClass.{self::Class::property};
- core::int localPropertySet = let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ core::int localPropertySet = let final<BottomType> #t77 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:82:40: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try accessing using ?. instead.
var localPropertySet = nullableClass.property = 1;
^^^^^^^^" in self::nullableClass.{self::Class::property} = 1;
- core::int localPropertyGetSet = let final self::Class? #t43 = self::nullableClass in let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ core::int localPropertyGetSet = let final self::Class? #t78 = self::nullableClass in let final<BottomType> #t79 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:83:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try accessing using ?. instead.
var localPropertyGetSet = nullableClass.property += 1;
- ^^^^^^^^" in #t43.{self::Class::property} = (let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
+ ^^^^^^^^" in #t78.{self::Class::property} = (let final<BottomType> #t80 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:83:43: Error: Property 'property' cannot be accessed on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try accessing using ?. instead.
var localPropertyGetSet = nullableClass.property += 1;
- ^^^^^^^^" in #t43.{self::Class::property}).{core::num::+}(1);
- core::int localMethodInvocation = let final<BottomType> #t46 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:54:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
+ ^^^^^^^^" in #t78.{self::Class::property}).{core::num::+}(1);
+ core::int localMethodInvocation = let final<BottomType> #t81 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:84:45: Error: Method 'method' cannot be called on 'Class?' because it is potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try calling using ?. instead.
var localMethodInvocation = nullableClass.method();
^^^^^^" in self::nullableClass.{self::Class::method}();
- () → core::int localMethodTearOff = self::nullableClass.{self::Class::method};
- dynamic localFunctionImplicitCall = let final<BottomType> #t47 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:56:51: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
+ () → core::int localMethodTearOff = let final<BottomType> #t82 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:85:42: Error: Property 'method' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localMethodTearOff = nullableClass.method;
+ ^^^^^^" in self::nullableClass.{self::Class::method};
+ dynamic localFunctionImplicitCall = let final<BottomType> #t83 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:86:51: Error: Can't use an expression of type 'Function?' as a function because it's potentially null.
- 'Function' is from 'dart:core'.
Try calling using ?.call instead.
var localFunctionImplicitCall = nullableFunction();
^" in self::nullableFunction.call();
- dynamic localFunctionExplicitCall = let final<BottomType> #t48 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:57:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
+ dynamic localFunctionExplicitCall = let final<BottomType> #t84 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:87:52: Error: Method 'call' cannot be called on 'Function?' because it is potentially null.
- 'Function' is from 'dart:core'.
Try calling using ?. instead.
var localFunctionExplicitCall = nullableFunction.call();
^^^^" in self::nullableFunction.call();
- core::Function? localFunctionTearOff = let final<BottomType> #t49 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:58:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
+ core::Function? localFunctionTearOff = let final<BottomType> #t85 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:88:47: Error: Property 'call' cannot be accessed on 'Function?' because it is potentially null.
- 'Function' is from 'dart:core'.
Try accessing using ?. instead.
var localFunctionTearOff = nullableFunction.call;
^^^^" in self::nullableFunction.call;
- void localFunctionTypeImplicitCall = let final<BottomType> #t50 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:59:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+ void localFunctionTypeImplicitCall = let final<BottomType> #t86 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:89:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
Try calling using ?.call instead.
var localFunctionTypeImplicitCall = nullableFunctionType();
^" in self::nullableFunctionType.call();
- void localFunctionTypeExplicitCall = let final<BottomType> #t51 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:60:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+ void localFunctionTypeExplicitCall = let final<BottomType> #t87 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:90:60: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
Try calling using ?. instead.
var localFunctionTypeExplicitCall = nullableFunctionType.call();
^^^^" in self::nullableFunctionType.call();
- () →? void localFunctionTypeTearOff = let final<BottomType> #t52 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:61:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
+ () →? void localFunctionTypeTearOff = let final<BottomType> #t88 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:91:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
Try accessing using ?. instead.
var localFunctionTypeTearOff = nullableFunctionType.call;
^^^^" in self::nullableFunctionType.call;
- dynamic localFunctionField = self::nullableClass.{self::Class::functionField}.call();
- void localFunctionTypeField = self::nullableClass.{self::Class::functionTypeField}.call();
- dynamic localFunctionGetter = self::nullableClass.{self::Class::functionGetter}.call();
- void localFunctionTypeGetter = self::nullableClass.{self::Class::functionTypeGetter}.call();
+ dynamic localFunctionField = let final<BottomType> #t89 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:92:42: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+ var localFunctionField = nullableClass.functionField();
+ ^" in self::nullableClass.{self::Class::functionField}.call();
+ void localFunctionTypeField = let final<BottomType> #t90 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:93:46: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+ var localFunctionTypeField = nullableClass.functionTypeField();
+ ^" in self::nullableClass.{self::Class::functionTypeField}.call();
+ dynamic localFunctionGetter = let final<BottomType> #t91 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:94:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+ var localFunctionGetter = nullableClass.functionGetter();
+ ^" in self::nullableClass.{self::Class::functionGetter}.call();
+ void localFunctionTypeGetter = let final<BottomType> #t92 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:95:47: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+ var localFunctionTypeGetter = nullableClass.functionTypeGetter();
+ ^" in self::nullableClass.{self::Class::functionTypeGetter}.call();
+ core::int localExtensionBinary = let final<BottomType> #t93 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:97:44: Error: Operator '+' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+ var localExtensionBinary = nullableClass + 0;
+ ^" in self::Extension|+(self::nullableClass, 0);
+ core::int localExtensionUnary = let final<BottomType> #t94 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:98:29: Error: Operator 'unary-' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+ var localExtensionUnary = -nullableClass;
+ ^" in self::Extension|unary-(self::nullableClass);
+ core::int localExtensionIndexGet = let final<BottomType> #t95 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:99:45: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+ var localExtensionIndexGet = nullableClass[0];
+ ^" in self::Extension|[](self::nullableClass, 0);
+ core::int localExtensionIndexSet = let final self::Class? #t96 = self::nullableClass in let final core::int #t97 = 0 in let final core::int #t98 = 1 in let final void #t99 = let final<BottomType> #t100 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:100:45: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+ var localExtensionIndexSet = nullableClass[0] = 1;
+ ^" in self::Extension|[]=(#t96, #t97, #t98) in #t98;
+ core::int localExtensionIndexGetSet = let final self::Class? #t101 = self::nullableClass in let final core::int #t102 = 0 in let final core::int #t103 = (let final<BottomType> #t104 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:101:48: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+ var localExtensionIndexGetSet = nullableClass[0] += 1;
+ ^" in self::Extension|[](#t101, #t102)).{core::num::+}(1) in let final void #t105 = let final<BottomType> #t106 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:101:48: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+ var localExtensionIndexGetSet = nullableClass[0] += 1;
+ ^" in self::Extension|[]=(#t101, #t102, #t103) in #t103;
+ core::int localExtensionPropertyGet = let final<BottomType> #t107 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:102:49: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localExtensionPropertyGet = nullableClass.extensionProperty;
+ ^^^^^^^^^^^^^^^^^" in self::Extension|get#extensionProperty(self::nullableClass);
+ core::int localExtensionPropertySet = let final<BottomType> #t108 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:103:49: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localExtensionPropertySet = nullableClass.extensionProperty = 1;
+ ^^^^^^^^^^^^^^^^^" in let final core::int #t109 = 1 in let final void #t110 = self::Extension|set#extensionProperty(self::nullableClass, #t109) in #t109;
+ core::int localExtensionPropertyGetSet = let final self::Class? #t111 = self::nullableClass in let final<BottomType> #t112 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:104:52: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+ ^^^^^^^^^^^^^^^^^" in let final core::int #t113 = (let final<BottomType> #t114 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:104:52: Error: Property 'extensionProperty' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+ ^^^^^^^^^^^^^^^^^" in self::Extension|get#extensionProperty(#t111)).{core::num::+}(1) in let final void #t115 = self::Extension|set#extensionProperty(#t111, #t113) in #t113;
+ core::int localExtensionMethodInvocation = let final<BottomType> #t116 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:105:54: Error: Method 'extensionMethod' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+ var localExtensionMethodInvocation = nullableClass.extensionMethod();
+ ^^^^^^^^^^^^^^^" in self::Extension|extensionMethod(self::nullableClass);
+ () → core::int localExtensionMethodTearOff = let final<BottomType> #t117 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:106:51: Error: Property 'extensionMethod' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localExtensionMethodTearOff = nullableClass.extensionMethod;
+ ^^^^^^^^^^^^^^^" in self::Extension|get#extensionMethod(self::nullableClass);
+ core::int localExtensionFunctionTypeImplicitCall = let final<BottomType> #t118 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:107:61: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+ var localExtensionFunctionTypeImplicitCall = nullableClass();
+ ^" in self::Extension|call(self::nullableClass);
+ core::int localExtensionFunctionTypeExplicitCall = let final<BottomType> #t119 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:108:62: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?. instead.
+ var localExtensionFunctionTypeExplicitCall = nullableClass.call();
+ ^^^^" in self::Extension|call(self::nullableClass);
+ () → core::int localExtensionFunctionTypeTearOff = let final<BottomType> #t120 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:109:57: Error: Property 'call' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try accessing using ?. instead.
+ var localExtensionFunctionTypeTearOff = nullableClass.call;
+ ^^^^" in self::Extension|get#call(self::nullableClass);
+ dynamic localExtensionFunctionGetter = let final<BottomType> #t121 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:110:52: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+ var localExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+ ^" in self::Extension|get#extensionFunctionGetter(self::nullableClass).call();
+ void localExtensionFunctionTypeGetter = let final<BottomType> #t122 = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:112:21: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
+Try calling using ?.call instead.
+ nullableClass.extensionFunctionTypeGetter();
+ ^" in self::Extension|get#extensionFunctionTypeGetter(self::nullableClass).call();
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/outline.status b/pkg/front_end/testcases/outline.status
index ca35b47..8103acb 100644
--- a/pkg/front_end/testcases/outline.status
+++ b/pkg/front_end/testcases/outline.status
@@ -40,6 +40,7 @@
inference/mixin_inference_unification_1: TypeCheckError
inference/mixin_inference_unification_2: TypeCheckError
nnbd/inheritance_from_opt_in: TypeCheckError
+nnbd/issue41567: TypeCheckError
nnbd/messages_with_types_opt_in: TypeCheckError
nnbd/messages_with_types_opt_out: TypeCheckError
nnbd/never_opt_out: TypeCheckError
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index bd6eb1d..907af6e 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -167,9 +167,12 @@
instantiate_to_bound/non_simple_generic_function_in_bound_regress: RuntimeError # Expected
nnbd/inheritance_from_opt_in: TypeCheckError
nnbd/issue41180: RuntimeError # Strong mode runtime checking fails due to mixed strong mode.
+nnbd/issue41567: TypeCheckError
nnbd/messages_with_types_opt_in: TypeCheckError
nnbd/messages_with_types_opt_out: TypeCheckError
nnbd/never_opt_out: TypeCheckError
+nnbd/nullable_object_access: TypeCheckError
+nnbd/nullable_receiver: TypeCheckError
nnbd/potentially_nullable_access: TypeCheckError
rasta/abstract_constructor: RuntimeError
rasta/bad_constructor_redirection: RuntimeError
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index ec59b90..41d9cf9 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -165,9 +165,12 @@
instantiate_to_bound/non_simple_generic_function_in_bound_regress: RuntimeError
nnbd/inheritance_from_opt_in: TypeCheckError
nnbd/issue41180: RuntimeError
+nnbd/issue41567: TypeCheckError
nnbd/messages_with_types_opt_in: TypeCheckError
nnbd/messages_with_types_opt_out: TypeCheckError
nnbd/never_opt_out: TypeCheckError
+nnbd/nullable_object_access: TypeCheckError
+nnbd/nullable_receiver: TypeCheckError
nnbd/potentially_nullable_access: TypeCheckError
rasta/abstract_constructor: RuntimeError
rasta/bad_constructor_redirection: RuntimeError
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index 9be9f1e..4de00b0 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -59,8 +59,11 @@
general_nnbd_opt_out/unsound_promotion: TypeCheckError
general_nnbd_opt_out/void_methods: RuntimeError
nnbd/inheritance_from_opt_in: TypeCheckError
+nnbd/issue41567: TypeCheckError
nnbd/messages_with_types_opt_in: TypeCheckError
nnbd/messages_with_types_opt_out: TypeCheckError
nnbd/never_opt_out: TypeCheckError
+nnbd/nullable_object_access: TypeCheckError
+nnbd/nullable_receiver: TypeCheckError
nnbd/potentially_nullable_access: TypeCheckError
diff --git a/pkg/frontend_server/pubspec.yaml b/pkg/frontend_server/pubspec.yaml
index c14c3b8..2effb3b 100644
--- a/pkg/frontend_server/pubspec.yaml
+++ b/pkg/frontend_server/pubspec.yaml
@@ -3,6 +3,9 @@
# version: do-not-upload
description: A resident kernel compiler
+environment:
+ sdk: "^2.7.0"
+
dependencies:
build_integration:
path: ../build_integration
diff --git a/pkg/kernel/lib/src/nnbd_top_merge.dart b/pkg/kernel/lib/src/nnbd_top_merge.dart
index 317b1df..f0c5b4e 100644
--- a/pkg/kernel/lib/src/nnbd_top_merge.dart
+++ b/pkg/kernel/lib/src/nnbd_top_merge.dart
@@ -55,8 +55,8 @@
// NNBD_TOP_MERGE(Object?, dynamic) = Object?
return coreTypes.objectNullableRawType;
} else if (b is VoidType) {
- // NNBD_TOP_MERGE(Object?, void) = void
- return const VoidType();
+ // NNBD_TOP_MERGE(Object?, void) = Object?
+ return coreTypes.objectNullableRawType;
} else if (b == coreTypes.objectNullableRawType) {
// NNBD_TOP_MERGE(Object?, Object?) = Object?
return coreTypes.objectNullableRawType;
@@ -66,8 +66,8 @@
// NNBD_TOP_MERGE(Object*, dynamic) = Object?
return coreTypes.objectNullableRawType;
} else if (b is VoidType) {
- // NNBD_TOP_MERGE(Object*, void) = void
- return const VoidType();
+ // NNBD_TOP_MERGE(Object*, void) = Object?
+ return coreTypes.objectNullableRawType;
}
} else if (a == coreTypes.nullType &&
b is NeverType &&
@@ -81,17 +81,17 @@
@override
DartType visitVoidType(VoidType a, DartType b) {
if (b is DynamicType) {
- // NNBD_TOP_MERGE(void, dynamic) = void
- return const VoidType();
+ // NNBD_TOP_MERGE(void, dynamic) = Object?
+ return coreTypes.objectNullableRawType;
} else if (b is VoidType) {
// NNBD_TOP_MERGE(void, void) = void
return const VoidType();
} else if (b == coreTypes.objectNullableRawType) {
- // NNBD_TOP_MERGE(void, Object?) = void
- return const VoidType();
+ // NNBD_TOP_MERGE(void, Object?) = Object?
+ return coreTypes.objectNullableRawType;
} else if (b == coreTypes.objectLegacyRawType) {
- // NNBD_TOP_MERGE(void, Object*) = void
- return const VoidType();
+ // NNBD_TOP_MERGE(void, Object*) = Object?
+ return coreTypes.objectNullableRawType;
}
return null;
}
@@ -102,8 +102,8 @@
// NNBD_TOP_MERGE(dynamic, dynamic) = dynamic
return const DynamicType();
} else if (b is VoidType) {
- // NNBD_TOP_MERGE(dynamic, void) = void
- return const VoidType();
+ // NNBD_TOP_MERGE(dynamic, void) = Object?
+ return coreTypes.objectNullableRawType;
} else if (b == coreTypes.objectNullableRawType) {
// NNBD_TOP_MERGE(dynamic, Object?) = Object?
return coreTypes.objectNullableRawType;
diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
index 59cec06..78cd33e 100644
--- a/pkg/kernel/lib/verifier.dart
+++ b/pkg/kernel/lib/verifier.dart
@@ -178,6 +178,10 @@
problem(
currentParent, "Missing bound for type parameter '$parameter'.");
}
+ if (parameter.defaultType == null) {
+ problem(currentParent,
+ "Missing default type for type parameter '$parameter'.");
+ }
if (!typeParametersInScope.add(parameter)) {
problem(parameter, "Type parameter '$parameter' redeclared.");
}
diff --git a/pkg/kernel/test/nnbd_top_merge_test.dart b/pkg/kernel/test/nnbd_top_merge_test.dart
index da9bd8d..4eb5d40 100644
--- a/pkg/kernel/test/nnbd_top_merge_test.dart
+++ b/pkg/kernel/test/nnbd_top_merge_test.dart
@@ -17,10 +17,10 @@
'Object vs Object': 'Object',
'dynamic vs dynamic': 'dynamic',
'void vs void': 'void',
- 'Object? vs void': 'void',
- 'Object* vs void': 'void',
+ 'Object? vs void': 'Object?',
+ 'Object* vs void': 'Object?',
'Object vs void': null,
- 'dynamic vs void': 'void',
+ 'dynamic vs void': 'Object?',
'Object? vs dynamic': 'Object?',
'Object* vs dynamic': 'Object?',
'Object vs dynamic': null,
@@ -41,10 +41,10 @@
'List<Object> vs List<Object>': 'List<Object>',
'List<dynamic> vs List<dynamic>': 'List<dynamic>',
'List<void> vs List<void>': 'List<void>',
- 'List<Object?> vs List<void>': 'List<void>',
- 'List<Object*> vs List<void>': 'List<void>',
+ 'List<Object?> vs List<void>': 'List<Object?>',
+ 'List<Object*> vs List<void>': 'List<Object?>',
'List<Object> vs List<void>': null,
- 'List<dynamic> vs List<void>': 'List<void>',
+ 'List<dynamic> vs List<void>': 'List<Object?>',
'List<Object?> vs List<dynamic>': 'List<Object?>',
'List<Object*> vs List<dynamic>': 'List<Object?>',
'List<Object> vs List<dynamic>': null,
diff --git a/pkg/kernel/test/verify_test.dart b/pkg/kernel/test/verify_test.dart
index 3219f11..905375c 100644
--- a/pkg/kernel/test/verify_test.dart
+++ b/pkg/kernel/test/verify_test.dart
@@ -733,7 +733,7 @@
VariableDeclaration makeVariable() => new VariableDeclaration(null);
TypeParameter makeTypeParameter([String name]) {
- return new TypeParameter(name, objectLegacyRawType);
+ return new TypeParameter(name, objectLegacyRawType, const DynamicType());
}
TestHarness() {
diff --git a/pkg/nnbd_migration/bin/migrate.dart b/pkg/nnbd_migration/bin/migrate.dart
new file mode 100644
index 0000000..1b87fa3
--- /dev/null
+++ b/pkg/nnbd_migration/bin/migrate.dart
@@ -0,0 +1,13 @@
+// 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.
+
+import 'dart:io';
+
+import 'package:nnbd_migration/migration_cli.dart';
+
+main(List<String> args) async {
+ var cli = MigrationCli(binaryName: 'nnbd_migration');
+ await cli.run(args);
+ exit(cli.exitCode ?? 0);
+}
diff --git a/pkg/nnbd_migration/lib/migration_cli.dart b/pkg/nnbd_migration/lib/migration_cli.dart
new file mode 100644
index 0000000..d8d0350
--- /dev/null
+++ b/pkg/nnbd_migration/lib/migration_cli.dart
@@ -0,0 +1,535 @@
+// 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.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:analysis_server/src/edit/fix/fix_code_task.dart';
+import 'package:analysis_server/src/edit/fix/non_nullable_fix.dart';
+import 'package:analyzer/dart/analysis/analysis_context.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/analysis/session.dart';
+import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/util/sdk.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:args/args.dart';
+import 'package:cli_util/cli_logging.dart';
+import 'package:meta/meta.dart';
+import 'package:nnbd_migration/api_for_analysis_server/dartfix_listener_interface.dart';
+import 'package:nnbd_migration/api_for_analysis_server/driver_provider.dart';
+import 'package:path/path.dart' show Context;
+
+String _pluralize(int count, String single, {String multiple}) {
+ return count == 1 ? single : (multiple ?? '${single}s');
+}
+
+/// Data structure recording command-line options for the migration tool that
+/// have been passed in by the client.
+@visibleForTesting
+class CommandLineOptions {
+ static const applyChangesFlag = 'apply-changes';
+ static const helpFlag = 'help';
+ static const previewPortOption = 'preview-port';
+ static const sdkPathOption = 'sdk-path';
+ static const verboseFlag = 'verbose';
+ static const webPreviewFlag = 'web-preview';
+
+ final bool applyChanges;
+
+ final String directory;
+
+ final int previewPort;
+
+ final String sdkPath;
+
+ final bool webPreview;
+
+ CommandLineOptions(
+ {@required this.applyChanges,
+ @required this.directory,
+ @required this.previewPort,
+ @required this.sdkPath,
+ @required this.webPreview});
+}
+
+/// Command-line API for the migration tool, with additional methods exposed for
+/// testing.
+class MigrationCli {
+ /// The name of the executable, for reporting in help messages.
+ final String binaryName;
+
+ /// The SDK path that should be used if none is provided by the user. Used in
+ /// testing to install a mock SDK.
+ final String defaultSdkPathOverride;
+
+ /// Factory to create an appropriate Logger instance to give feedback to the
+ /// user. Used in testing to allow user feedback messages to be tested.
+ final Logger Function(bool isVerbose) loggerFactory;
+
+ /// Resource provider that should be used to access the filesystem. Used in
+ /// testing to redirect to an in-memory filesystem.
+ final ResourceProvider resourceProvider;
+
+ /// Logger instance we use to give feedback to the user.
+ Logger logger;
+
+ /// The result of parsing command-line options.
+ @visibleForTesting
+ /*late*/ CommandLineOptions options;
+
+ /// The exit code that should be used when the process terminates, or `null`
+ /// if there is still more work to do.
+ int exitCode;
+
+ MigrationCli(
+ {@required this.binaryName,
+ @visibleForTesting this.loggerFactory = _defaultLoggerFactory,
+ @visibleForTesting this.defaultSdkPathOverride,
+ @visibleForTesting ResourceProvider resourceProvider})
+ : logger = loggerFactory(false),
+ resourceProvider =
+ resourceProvider ?? PhysicalResourceProvider.INSTANCE;
+
+ Ansi get ansi => logger.ansi;
+
+ Context get pathContext => resourceProvider.pathContext;
+
+ /// Blocks until an interrupt signal (control-C) is received. Tests may
+ /// override this method to simulate control-C.
+ @visibleForTesting
+ Future<void> blockUntilSignalInterrupt() {
+ Stream<ProcessSignal> stream = ProcessSignal.sigint.watch();
+ return stream.first;
+ }
+
+ /// Parses and validates command-line arguments, and stores the results in
+ /// [options].
+ ///
+ /// If no additional work should be done (e.g. because the user asked for
+ /// help, or supplied a bad option), a nonzero value is stored in [exitCode].
+ @visibleForTesting
+ void parseCommandLineArgs(List<String> args) {
+ try {
+ var argResults = _createParser().parse(args);
+ var isVerbose = argResults[CommandLineOptions.verboseFlag] as bool;
+ if (argResults[CommandLineOptions.helpFlag] as bool) {
+ _showUsage(isVerbose);
+ exitCode = 0;
+ return;
+ }
+ var rest = argResults.rest;
+ String migratePath;
+ if (rest.isEmpty) {
+ migratePath = Directory.current.path;
+ } else if (rest.length > 1) {
+ throw _BadArgException('No more than one path may be specified.');
+ } else {
+ migratePath = rest[0];
+ }
+ var applyChanges =
+ argResults[CommandLineOptions.applyChangesFlag] as bool;
+ var previewPortRaw =
+ argResults[CommandLineOptions.previewPortOption] as String;
+ int previewPort;
+ try {
+ previewPort = previewPortRaw == null ? null : int.parse(previewPortRaw);
+ } on FormatException catch (_) {
+ throw _BadArgException(
+ 'Invalid value for --${CommandLineOptions.previewPortOption}');
+ }
+ var webPreview = argResults[CommandLineOptions.webPreviewFlag] as bool;
+ if (applyChanges && webPreview) {
+ throw _BadArgException('--apply-changes requires --no-web-preview');
+ }
+ options = CommandLineOptions(
+ applyChanges: applyChanges,
+ directory: migratePath,
+ previewPort: previewPort,
+ sdkPath: argResults[CommandLineOptions.sdkPathOption] as String ??
+ defaultSdkPathOverride ??
+ getSdkPath(),
+ webPreview: webPreview);
+ if (isVerbose) {
+ logger = loggerFactory(true);
+ }
+ } on Object catch (exception) {
+ String message;
+ if (exception is FormatException) {
+ message = exception.message;
+ } else if (exception is _BadArgException) {
+ message = exception.message;
+ } else {
+ message =
+ 'Exception occurred while parsing command-line options: $exception';
+ }
+ logger.stderr(message);
+ _showUsage(false);
+ exitCode = 1;
+ return;
+ }
+ }
+
+ /// Runs the full migration process.
+ void run(List<String> args) async {
+ parseCommandLineArgs(args);
+ if (exitCode != null) return;
+
+ // TODO(paulberry): if debugging, create instrumentation log
+
+ logger.stdout('Migrating ${options.directory}');
+ logger.stdout('');
+
+ // TODO(paulberry): analyze project and report about any errors found
+
+ List<String> previewUrls;
+ NonNullableFix nonNullableFix;
+ _DartFixListener dartFixListener;
+ await _withProgress(
+ '${ansi.emphasized('Generating migration suggestions')}', () async {
+ var contextCollection = AnalysisContextCollectionImpl(
+ includedPaths: [options.directory],
+ resourceProvider: resourceProvider,
+ sdkPath: options.sdkPath);
+ var context = contextCollection.contexts.single;
+ var fixCodeProcessor = _FixCodeProcessor(context);
+ dartFixListener = _DartFixListener(
+ _DriverProvider(resourceProvider, context.currentSession));
+ nonNullableFix = NonNullableFix(dartFixListener,
+ included: [options.directory],
+ preferredPort: options.previewPort,
+ enablePreview: options.webPreview);
+ fixCodeProcessor.registerCodeTask(nonNullableFix);
+ previewUrls = await fixCodeProcessor.run();
+ });
+
+ if (options.applyChanges) {
+ logger.stdout(ansi.emphasized('Applying changes:'));
+
+ var allEdits = dartFixListener.sourceChange.edits;
+ _applyMigrationSuggestions(allEdits);
+
+ logger.stdout('');
+ logger.stdout(
+ 'Applied ${allEdits.length} ${_pluralize(allEdits.length, 'edit')}.');
+
+ // Note: do not open the web preview if apply-changes is specified, as we
+ // currently cannot tell the web preview to disable the "apply migration"
+ // button.
+ exitCode = 0;
+ return;
+ }
+
+ if (options.webPreview) {
+ String url = previewUrls.first;
+ assert(previewUrls.length <= 1,
+ 'Got unexpected extra preview URLs from server');
+
+ logger.stdout(ansi.emphasized('View migration results:'));
+
+ // TODO(devoncarew): Open a browser automatically.
+ logger.stdout('''
+Visit:
+
+ ${ansi.emphasized(url)}
+
+to see the migration results. Use the interactive web view to review, improve, or apply
+the results (alternatively, to apply the results without using the web preview, re-run
+the tool with --${CommandLineOptions.applyChangesFlag}).
+''');
+
+ logger.stdout('When finished with the preview, hit ctrl-c '
+ 'to terminate this process.');
+
+ // Block until sigint (ctrl-c).
+ await blockUntilSignalInterrupt();
+ nonNullableFix.shutdownServer();
+ } else {
+ logger.stdout(ansi.emphasized('Summary of changes:'));
+
+ _displayChangeSummary(dartFixListener);
+
+ logger.stdout('');
+ logger.stdout('To apply these changes, re-run the tool with '
+ '--${CommandLineOptions.applyChangesFlag}.');
+ }
+ exitCode = 0;
+ }
+
+ /// Perform the indicated source edits to the given source, returning the
+ /// resulting transformed text.
+ String _applyEdits(SourceFileEdit sourceFileEdit, String source) {
+ List<SourceEdit> edits = _sortEdits(sourceFileEdit);
+ return SourceEdit.applySequence(source, edits);
+ }
+
+ void _applyMigrationSuggestions(List<SourceFileEdit> edits) {
+ // Apply the changes to disk.
+ for (SourceFileEdit sourceFileEdit in edits) {
+ String relPath =
+ pathContext.relative(sourceFileEdit.file, from: options.directory);
+ int count = sourceFileEdit.edits.length;
+ logger.stdout(' $relPath ($count ${_pluralize(count, 'change')})');
+
+ String source;
+ var file = resourceProvider.getFile(sourceFileEdit.file);
+ try {
+ source = file.readAsStringSync();
+ } catch (_) {}
+
+ if (source == null) {
+ logger.stdout(' Unable to retrieve source for file.');
+ } else {
+ source = _applyEdits(sourceFileEdit, source);
+
+ try {
+ file.writeAsStringSync(source);
+ } catch (e) {
+ logger.stdout(' Unable to write source for file: $e');
+ }
+ }
+ }
+ }
+
+ ArgParser _createParser({bool hide = true}) {
+ var parser = ArgParser();
+ parser.addFlag(CommandLineOptions.applyChangesFlag,
+ defaultsTo: false,
+ negatable: false,
+ help: 'Apply the proposed null safety changes to the files on disk.');
+ parser.addFlag(CommandLineOptions.helpFlag,
+ abbr: 'h',
+ help:
+ 'Display this help message. Add --verbose to show hidden options.',
+ defaultsTo: false,
+ negatable: false);
+ parser.addOption(CommandLineOptions.previewPortOption,
+ help:
+ 'Run the preview server on the specified port. If not specified, '
+ 'dynamically allocate a port.');
+ parser.addOption(CommandLineOptions.sdkPathOption,
+ help: 'The path to the Dart SDK.', hide: hide);
+ parser.addFlag(CommandLineOptions.verboseFlag,
+ abbr: 'v',
+ defaultsTo: false,
+ help: 'Verbose output.',
+ negatable: false);
+ parser.addFlag(CommandLineOptions.webPreviewFlag,
+ defaultsTo: true,
+ negatable: true,
+ help: 'Show an interactive preview of the proposed null safety changes '
+ 'in a browser window.\n'
+ 'With --no-web-preview, the proposed changes are instead printed to '
+ 'the console.');
+ return parser;
+ }
+
+ void _displayChangeSummary(_DartFixListener migrationResults) {
+ Map<String, List<_DartFixSuggestion>> fileSuggestions = {};
+ for (_DartFixSuggestion suggestion in migrationResults.suggestions) {
+ String file = suggestion.location.file;
+ fileSuggestions.putIfAbsent(file, () => <_DartFixSuggestion>[]);
+ fileSuggestions[file].add(suggestion);
+ }
+
+ // present a diff-like view
+ for (SourceFileEdit sourceFileEdit in migrationResults.sourceChange.edits) {
+ String file = sourceFileEdit.file;
+ String relPath = pathContext.relative(file, from: options.directory);
+ int count = sourceFileEdit.edits.length;
+
+ logger.stdout('');
+ logger.stdout('${ansi.emphasized(relPath)} '
+ '($count ${_pluralize(count, 'change')}):');
+
+ String source;
+ try {
+ source = resourceProvider.getFile(file).readAsStringSync();
+ } catch (_) {}
+
+ if (source == null) {
+ logger.stdout(' (unable to retrieve source for file)');
+ } else {
+ // TODO(paulberry): implement this
+ logger.stdout(' (diff view not yet functional)');
+ }
+ }
+ }
+
+ void _showUsage(bool isVerbose) {
+ logger.stderr('Usage: $binaryName [options...] [<package directory>]');
+
+ logger.stderr('');
+ logger.stderr(_createParser(hide: !isVerbose).usage);
+ if (!isVerbose) {
+ logger.stderr('');
+ logger
+ .stderr('Run "$binaryName -h -v" for verbose help output, including '
+ 'less commonly used options.');
+ }
+ }
+
+ List<SourceEdit> _sortEdits(SourceFileEdit sourceFileEdit) {
+ // Sort edits in reverse offset order.
+ List<SourceEdit> edits = sourceFileEdit.edits.toList();
+ edits.sort((a, b) {
+ return b.offset - a.offset;
+ });
+ return edits;
+ }
+
+ Future<void> _withProgress(String message, FutureOr<void> callback()) async {
+ var progress = logger.progress(message);
+ try {
+ await callback();
+ progress.finish(showTiming: true);
+ } finally {
+ progress.cancel();
+ }
+ }
+
+ static Logger _defaultLoggerFactory(bool isVerbose) {
+ var ansi = Ansi(Ansi.terminalSupportsAnsi);
+ if (isVerbose) {
+ return Logger.verbose(ansi: ansi);
+ } else {
+ return Logger.standard(ansi: ansi);
+ }
+ }
+}
+
+class _BadArgException implements Exception {
+ final String message;
+
+ _BadArgException(this.message);
+}
+
+class _DartFixListener implements DartFixListenerInterface {
+ @override
+ final DriverProvider server;
+
+ @override
+ final SourceChange sourceChange = SourceChange('null safety migration');
+
+ final List<_DartFixSuggestion> suggestions = [];
+
+ _DartFixListener(this.server);
+
+ @override
+ void addDetail(String detail) {
+ throw UnimplementedError('TODO(paulberry)');
+ }
+
+ @override
+ void addEditWithoutSuggestion(Source source, SourceEdit edit) {
+ sourceChange.addEdit(source.fullName, -1, edit);
+ }
+
+ @override
+ void addRecommendation(String description, [Location location]) {
+ throw UnimplementedError('TODO(paulberry)');
+ }
+
+ @override
+ void addSourceFileEdit(
+ String description, Location location, SourceFileEdit fileEdit) {
+ throw UnimplementedError('TODO(paulberry)');
+ }
+
+ @override
+ void addSuggestion(String description, Location location) {
+ suggestions.add(_DartFixSuggestion(description, location: location));
+ }
+}
+
+class _DartFixSuggestion {
+ final String description;
+
+ final Location location;
+
+ _DartFixSuggestion(this.description, {@required this.location});
+}
+
+class _DriverProvider implements DriverProvider {
+ @override
+ final ResourceProvider resourceProvider;
+
+ final AnalysisSession analysisSession;
+
+ _DriverProvider(this.resourceProvider, this.analysisSession);
+
+ @override
+ AnalysisSession getAnalysisSession(String path) => analysisSession;
+}
+
+class _FixCodeProcessor extends Object with FixCodeProcessor {
+ final AnalysisContext context;
+
+ final Set<String> pathsToProcess;
+
+ _FixCodeProcessor(this.context)
+ : pathsToProcess = context.contextRoot
+ .analyzedFiles()
+ .where((s) => s.endsWith('.dart'))
+ .toSet();
+
+ /// Call the supplied [process] function to process each compilation unit.
+ Future processResources(
+ Future<void> Function(ResolvedUnitResult result) process) async {
+ var driver = context.currentSession;
+ var pathsProcessed = <String>{};
+ for (var path in pathsToProcess) {
+ if (pathsProcessed.contains(path)) continue;
+ switch (await driver.getSourceKind(path)) {
+ case SourceKind.PART:
+ // Parts will either be found in a library, below, or if the library
+ // isn't [isIncluded], will be picked up in the final loop.
+ continue;
+ break;
+ case SourceKind.LIBRARY:
+ var result = await driver.getResolvedLibrary(path);
+ if (result != null) {
+ for (var unit in result.units) {
+ if (pathsToProcess.contains(unit.path) &&
+ !pathsProcessed.contains(unit.path)) {
+ await process(unit);
+ pathsProcessed.add(unit.path);
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ for (var path in pathsToProcess.difference(pathsProcessed)) {
+ var result = await driver.getResolvedUnit(path);
+ if (result == null || result.unit == null) {
+ continue;
+ }
+ await process(result);
+ }
+ }
+
+ Future<List<String>> run() async {
+ // TODO(paulberry): do more things from EditDartFix.runAllTasks
+ await processResources((ResolvedUnitResult result) async {
+ // TODO(paulberry): check for errors
+ if (numPhases > 0) {
+ await processCodeTasks(0, result);
+ }
+ });
+ for (var phase = 1; phase < numPhases; phase++) {
+ await processResources((ResolvedUnitResult result) async {
+ await processCodeTasks(phase, result);
+ });
+ }
+ await finishCodeTasks();
+
+ return nonNullableFixTask.previewUrls;
+ }
+}
diff --git a/pkg/nnbd_migration/lib/src/decorated_type_operations.dart b/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
index f69f365..323d579 100644
--- a/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
@@ -20,6 +20,12 @@
this._typeSystem, this._variableRepository, this._graph);
@override
+ DecoratedType factor(DecoratedType from, DecoratedType what) {
+ // TODO(scheglov): https://github.com/dart-lang/sdk/issues/41672
+ return from;
+ }
+
+ @override
bool isSameType(DecoratedType type1, DecoratedType type2) {
return type1 == type2;
}
diff --git a/pkg/nnbd_migration/test/migration_cli_test.dart b/pkg/nnbd_migration/test/migration_cli_test.dart
new file mode 100644
index 0000000..a841013
--- /dev/null
+++ b/pkg/nnbd_migration/test/migration_cli_test.dart
@@ -0,0 +1,337 @@
+// 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.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart' as mock_sdk;
+import 'package:cli_util/cli_logging.dart';
+import 'package:http/http.dart' as http;
+import 'package:meta/meta.dart';
+import 'package:nnbd_migration/migration_cli.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(_MigrationCliTest);
+ });
+}
+
+class _MigrationCli extends MigrationCli {
+ Completer<void> _previewServerStartedCompleter;
+
+ Completer<void> _signalInterruptCompleter;
+
+ _MigrationCli(_MigrationCliTest test)
+ : super(
+ binaryName: 'nnbd_migration',
+ loggerFactory: (isVerbose) => test.logger = _TestLogger(isVerbose),
+ defaultSdkPathOverride: mock_sdk.sdkRoot,
+ resourceProvider: test.resourceProvider);
+
+ @override
+ Future<void> blockUntilSignalInterrupt() {
+ _previewServerStartedCompleter.complete();
+ _signalInterruptCompleter = Completer<void>();
+ return _signalInterruptCompleter.future;
+ }
+
+ Future<void> runWithPreviewServer(
+ List<String> args, Future<void> callback()) async {
+ _previewServerStartedCompleter = Completer<void>();
+ var done = run(args);
+ await _previewServerStartedCompleter.future;
+ await callback();
+ _signalInterruptCompleter.complete();
+ return done;
+ }
+}
+
+@reflectiveTest
+class _MigrationCliTest {
+ /*late*/ _TestLogger logger;
+
+ final hasVerboseHelpMessage = contains('for verbose help output');
+
+ final hasUsageText = contains('Usage: nnbd_migration');
+
+ final resourceProvider = MemoryResourceProvider();
+
+ String assertErrorExit(MigrationCli cli) {
+ expect(cli.exitCode, isNotNull);
+ expect(cli.exitCode, isNot(0));
+ var stderrText = logger.stderrBuffer.toString();
+ expect(stderrText, hasUsageText);
+ expect(stderrText, hasVerboseHelpMessage);
+ return stderrText;
+ }
+
+ Future<String> assertParseArgsFailure(List<String> args) async {
+ var cli = _createCli();
+ await cli.run(args);
+ var stderrText = assertErrorExit(cli);
+ expect(stderrText, isNot(contains('Exception')));
+ return stderrText;
+ }
+
+ CommandLineOptions assertParseArgsSuccess(List<String> args) {
+ var cli = _createCli();
+ cli.parseCommandLineArgs(args);
+ expect(cli.exitCode, isNull);
+ var options = cli.options;
+ return options;
+ }
+
+ void assertProjectContents(String projectDir, Map<String, String> expected) {
+ for (var entry in expected.entries) {
+ var relativePathPosix = entry.key;
+ assert(!path.posix.isAbsolute(relativePathPosix));
+ var filePath = resourceProvider.pathContext
+ .join(projectDir, resourceProvider.convertPath(relativePathPosix));
+ expect(
+ resourceProvider.getFile(filePath).readAsStringSync(), entry.value);
+ }
+ }
+
+ String createProjectDir(Map<String, String> contents) {
+ var projectPathPosix = '/test_project';
+ for (var entry in contents.entries) {
+ var relativePathPosix = entry.key;
+ assert(!path.posix.isAbsolute(relativePathPosix));
+ var filePathPosix = path.posix.join(projectPathPosix, relativePathPosix);
+ resourceProvider.newFile(
+ resourceProvider.convertPath(filePathPosix), entry.value);
+ }
+ return resourceProvider.convertPath(projectPathPosix);
+ }
+
+ Map<String, String> simpleProject({bool migrated: false}) {
+ // TODO(paulberry): pubspec needs to be updated when migrating.
+ return {
+ 'pubspec.yaml': '''
+name: test
+environment:
+sdk: '>=2.6.0 <3.0.0'
+''',
+ 'lib/test.dart': '''
+int${migrated ? '?' : ''} f() => null;
+'''
+ };
+ }
+
+ test_default_logger() {
+ // When running normally, we don't override the logger; make sure it has a
+ // non-null default so that there won't be a crash.
+ expect(MigrationCli(binaryName: 'nnbd_migration').logger, isNotNull);
+ }
+
+ test_flag_apply_changes_default() {
+ expect(assertParseArgsSuccess([]).applyChanges, isFalse);
+ }
+
+ test_flag_apply_changes_disable() async {
+ // "--no-apply-changes" is not an option.
+ await assertParseArgsFailure(['--no-apply-changes']);
+ }
+
+ test_flag_apply_changes_enable() {
+ expect(
+ assertParseArgsSuccess(['--no-web-preview', '--apply-changes'])
+ .applyChanges,
+ isTrue);
+ }
+
+ test_flag_apply_changes_incompatible_with_web_preview() async {
+ expect(await assertParseArgsFailure(['--web-preview', '--apply-changes']),
+ contains('--apply-changes requires --no-web-preview'));
+ }
+
+ test_flag_help() async {
+ var helpText = await _getHelpText(verbose: false);
+ expect(helpText, hasUsageText);
+ expect(helpText, hasVerboseHelpMessage);
+ }
+
+ test_flag_help_verbose() async {
+ var helpText = await _getHelpText(verbose: true);
+ expect(helpText, hasUsageText);
+ expect(helpText, isNot(hasVerboseHelpMessage));
+ }
+
+ test_flag_web_preview_default() {
+ expect(assertParseArgsSuccess([]).webPreview, isTrue);
+ }
+
+ test_flag_web_preview_disable() {
+ expect(assertParseArgsSuccess(['--no-web-preview']).webPreview, isFalse);
+ }
+
+ test_flag_web_preview_enable() {
+ expect(assertParseArgsSuccess(['--web-preview']).webPreview, isTrue);
+ }
+
+ test_lifecycle_apply_changes() async {
+ var projectContents = simpleProject();
+ var projectDir = await createProjectDir(projectContents);
+ var cli = _createCli();
+ await cli.run(['--no-web-preview', '--apply-changes', projectDir]);
+ // Check that a summary was printed
+ expect(logger.stdoutBuffer.toString(), contains('Applying changes'));
+ // And that it refers to test.dart
+ expect(logger.stdoutBuffer.toString(), contains('test.dart'));
+ // And that it does not tell the user they can rerun with `--apply-changes`
+ expect(logger.stdoutBuffer.toString(), isNot(contains('--apply-changes')));
+ // Changes should have been made
+ assertProjectContents(projectDir, simpleProject(migrated: true));
+ }
+
+ test_lifecycle_no_preview() async {
+ var projectContents = simpleProject();
+ var projectDir = await createProjectDir(projectContents);
+ var cli = _createCli();
+ await cli.run(['--no-web-preview', projectDir]);
+ // Check that a summary was printed
+ expect(logger.stdoutBuffer.toString(), contains('Summary'));
+ // And that it refers to test.dart
+ expect(logger.stdoutBuffer.toString(), contains('test.dart'));
+ // And that it tells the user they can rerun with `--apply-changes`
+ expect(logger.stdoutBuffer.toString(), contains('--apply-changes'));
+ // No changes should have been made
+ assertProjectContents(projectDir, projectContents);
+ }
+
+ test_lifecycle_preview() async {
+ var projectContents = simpleProject();
+ var projectDir = await createProjectDir(projectContents);
+ var cli = _createCli();
+ String url;
+ await cli.runWithPreviewServer([projectDir], () async {
+ // Server should be running now
+ url = RegExp('http://.*', multiLine: true)
+ .stringMatch(logger.stdoutBuffer.toString());
+ var response = await http.get(url);
+ expect(response.statusCode, 200);
+ });
+ // Server should be stopped now
+ expect(http.get(url), throwsA(anything));
+ // And no changes should have been made.
+ assertProjectContents(projectDir, projectContents);
+ }
+
+ test_migrate_path_none() {
+ expect(assertParseArgsSuccess([]).directory, Directory.current.path);
+ }
+
+ test_migrate_path_one() {
+ expect(assertParseArgsSuccess(['foo']).directory, 'foo');
+ }
+
+ test_migrate_path_two() async {
+ var cli = _createCli();
+ await cli.run(['foo', 'bar']);
+ var stderrText = assertErrorExit(cli);
+ expect(stderrText, contains('No more than one path may be specified'));
+ }
+
+ test_option_preview_port() {
+ expect(
+ assertParseArgsSuccess(['--preview-port', '4040']).previewPort, 4040);
+ }
+
+ test_option_preview_port_default() {
+ expect(assertParseArgsSuccess([]).previewPort, isNull);
+ }
+
+ test_option_preview_port_format_error() async {
+ expect(await assertParseArgsFailure(['--preview-port', 'abc']),
+ contains('Invalid value for --preview-port'));
+ }
+
+ test_option_sdk() {
+ var path = Uri.parse('file:///foo/bar/baz').toFilePath();
+ expect(assertParseArgsSuccess(['--sdk-path', path]).sdkPath, same(path));
+ }
+
+ test_option_sdk_default() {
+ var cli = MigrationCli(binaryName: 'nnbd_migration');
+ cli.parseCommandLineArgs([]);
+ expect(
+ File(path.join(cli.options.sdkPath, 'version')).existsSync(), isTrue);
+ }
+
+ test_option_sdk_hidden() async {
+ var optionName = '--sdk-path';
+ expect(await _getHelpText(verbose: false), isNot(contains(optionName)));
+ expect(await _getHelpText(verbose: true), contains(optionName));
+ }
+
+ test_option_unrecognized() async {
+ expect(
+ await assertParseArgsFailure(['--this-option-does-not-exist']),
+ contains(
+ 'Could not find an option named "this-option-does-not-exist"'));
+ }
+
+ test_uses_physical_resource_provider_by_default() {
+ var cli = MigrationCli(binaryName: 'nnbd_migration');
+ expect(cli.resourceProvider, same(PhysicalResourceProvider.INSTANCE));
+ }
+
+ _MigrationCli _createCli() {
+ mock_sdk.MockSdk(resourceProvider: resourceProvider);
+ return _MigrationCli(this);
+ }
+
+ Future<String> _getHelpText({@required bool verbose}) async {
+ var cli = _createCli();
+ await cli
+ .run(['--${CommandLineOptions.helpFlag}', if (verbose) '--verbose']);
+ expect(cli.exitCode, 0);
+ var helpText = logger.stderrBuffer.toString();
+ return helpText;
+ }
+}
+
+/// TODO(paulberry): move into cli_util
+class _TestLogger implements Logger {
+ final stderrBuffer = StringBuffer();
+
+ final stdoutBuffer = StringBuffer();
+
+ final bool isVerbose;
+
+ _TestLogger(this.isVerbose);
+
+ @override
+ Ansi get ansi => Ansi(false);
+
+ @override
+ void flush() {
+ throw UnimplementedError('TODO(paulberry)');
+ }
+
+ @override
+ Progress progress(String message) {
+ return SimpleProgress(this, message);
+ }
+
+ @override
+ void stderr(String message) {
+ stderrBuffer.writeln(message);
+ }
+
+ @override
+ void stdout(String message) {
+ stdoutBuffer.writeln(message);
+ }
+
+ @override
+ void trace(String message) {
+ throw UnimplementedError('TODO(paulberry)');
+ }
+}
diff --git a/pkg/vm/pubspec.yaml b/pkg/vm/pubspec.yaml
index ef74ee0..27d6379 100644
--- a/pkg/vm/pubspec.yaml
+++ b/pkg/vm/pubspec.yaml
@@ -3,6 +3,9 @@
# version: do-not-upload
description: VM specific Dart code and helper scripts
+environment:
+ sdk: "^2.7.0"
+
dependencies:
build_integration:
path: ../build_integration
diff --git a/pkg/vm/testcases/bytecode/type_ops.dart.expect b/pkg/vm/testcases/bytecode/type_ops.dart.expect
index 8c81f4d..b78c771 100644
--- a/pkg/vm/testcases/bytecode/type_ops.dart.expect
+++ b/pkg/vm/testcases/bytecode/type_ops.dart.expect
@@ -625,8 +625,13 @@
Bytecode {
Entry 2
CheckFunctionTypeArgs 1, r0
+ JumpIfNotZeroTypeArgs L1
+ Push FP[-8]
+ LoadTypeArgumentsField CP#0
+ PopLocal r0
+L1:
CheckStack 0
- JumpIfUnchecked L1
+ JumpIfUnchecked L2
Push FP[-8]
LoadTypeArgumentsField CP#0
Push r0
@@ -642,7 +647,7 @@
PushConstant CP#4
AssertAssignable 0, CP#5
Drop1
-L1:
+L2:
Push FP[-6]
PushConstant CP#6
PushNull
@@ -660,6 +665,7 @@
}
Parameter flags: [0, 1, 2]
Forwarding stub target: CP#11
+Default function type arguments: CP#12
ConstantPool {
[0] = TypeArgumentsField #lib::H
[1] = Type #lib::H::foo7::TypeParam/0
@@ -673,6 +679,7 @@
[9] = DirectCall '#lib::G::foo7', ArgDesc num-args 4, num-type-args 1, names []
[10] = Reserved
[11] = ObjectRef #lib::G::foo7
+ [12] = ObjectRef < #lib::H::TypeParam/0 >
}
@@ -745,7 +752,7 @@
: super #lib::G::•()
;
method foo8<generic-covariant-impl Q extends #lib::H::T* = #lib::H::T*>(#lib::H::foo8::Q* a, covariant dart.core::int* b, generic-covariant-impl #lib::H::T* c) → void {}
- forwarding-stub method foo7<generic-covariant-impl Q extends #lib::H::T*>(#lib::H::foo7::Q* a, covariant dart.core::num* b, generic-covariant-impl #lib::H::T* c) → void
+ forwarding-stub method foo7<generic-covariant-impl Q extends #lib::H::T* = #lib::H::T*>(#lib::H::foo7::Q* a, covariant dart.core::num* b, generic-covariant-impl #lib::H::T* c) → void
return super.{#lib::G::foo7}<#lib::H::foo7::Q*>(a, b, c);
}
static field dart.core::List<dart.core::Iterable<dynamic>*>* globalVar;
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index a1845c0..0f04e7d 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -442,10 +442,11 @@
// Get the script name.
if (i < argc) {
- // If the script name isn't a valid file or a URL, this might be a DartDev
- // command. Try to find the DartDev snapshot so we can forward the command
- // and its arguments.
- if (!DartDevUtils::ShouldParseCommand(argv[i])) {
+ if (Options::disable_dart_dev() ||
+ !DartDevUtils::ShouldParseCommand(argv[i])) {
+ // If the script name isn't a valid file or a URL, this might be a DartDev
+ // command. Try to find the DartDev snapshot so we can forward the command
+ // and its arguments.
*script_name = strdup(argv[i]);
i++;
} else if (!DartDevUtils::TryResolveDartDevSnapshotPath(script_name)) {
@@ -454,6 +455,13 @@
argv[i]);
Platform::Exit(kErrorExitCode);
}
+ } else if (!Options::disable_dart_dev() &&
+ ((Options::help_option() && !Options::verbose_option()) ||
+ (argc == 1)) &&
+ DartDevUtils::TryResolveDartDevSnapshotPath(script_name)) {
+ // Let DartDev handle the default help message.
+ dart_options->AddArgument("help");
+ return 0;
} else {
return -1;
}
diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h
index 3fe9f74..6493349 100644
--- a/runtime/bin/main_options.h
+++ b/runtime/bin/main_options.h
@@ -46,7 +46,8 @@
V(disable_exit, exit_disabled) \
V(preview_dart_2, nop_option) \
V(suppress_core_dump, suppress_core_dump) \
- V(enable_service_port_fallback, enable_service_port_fallback)
+ V(enable_service_port_fallback, enable_service_port_fallback) \
+ V(disable_dart_dev, disable_dart_dev)
// Boolean flags that have a short form.
#define SHORT_BOOL_OPTIONS_LIST(V) \
diff --git a/runtime/bin/process_win.cc b/runtime/bin/process_win.cc
index 5648867..f2264a3 100644
--- a/runtime/bin/process_win.cc
+++ b/runtime/bin/process_win.cc
@@ -9,6 +9,7 @@
#include <process.h> // NOLINT
#include <psapi.h> // NOLINT
+#include <vector>
#include "bin/builtin.h"
#include "bin/dartutils.h"
@@ -531,14 +532,13 @@
if (!init_proc_thread_attr_list(attribute_list_, 1, 0, &size)) {
return CleanupAndReturnError();
}
- static const int kNumInheritedHandles = 3;
- HANDLE inherited_handles[kNumInheritedHandles] = {
- stdin_handles_[kReadHandle], stdout_handles_[kWriteHandle],
- stderr_handles_[kWriteHandle]};
+ inherited_handles_ = {stdin_handles_[kReadHandle],
+ stdout_handles_[kWriteHandle],
+ stderr_handles_[kWriteHandle]};
if (!update_proc_thread_attr(
attribute_list_, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
- inherited_handles, kNumInheritedHandles * sizeof(HANDLE), NULL,
- NULL)) {
+ inherited_handles_.data(),
+ inherited_handles_.size() * sizeof(HANDLE), NULL, NULL)) {
return CleanupAndReturnError();
}
startup_info.lpAttributeList = attribute_list_;
@@ -664,6 +664,7 @@
const wchar_t* system_working_directory_;
wchar_t* command_line_;
wchar_t* environment_block_;
+ std::vector<HANDLE> inherited_handles_;
LPPROC_THREAD_ATTRIBUTE_LIST attribute_list_;
const char* path_;
diff --git a/runtime/observatory/tests/service/observatory_test_package/pubspec.yaml b/runtime/observatory/tests/service/observatory_test_package/pubspec.yaml
new file mode 100644
index 0000000..db61a01f
--- /dev/null
+++ b/runtime/observatory/tests/service/observatory_test_package/pubspec.yaml
@@ -0,0 +1,4 @@
+name: observatory_test_package
+publish_to: none
+environment:
+ sdk: '^2.7.0'
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index 0d3d961..026478e 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -30,8 +30,8 @@
rewind_test: SkipByDesign # No incremental compiler available.
[ $compiler == dartkp ]
-add_breakpoint_rpc_kernel_test: RuntimeError
-async_generator_breakpoint_test: RuntimeError
+add_breakpoint_rpc_kernel_test: SkipByDesign
+async_generator_breakpoint_test: SkipByDesign
async_next_regession_18877_test: Skip, Timeout
async_next_test: Skip, Timeout
async_scope_test: Skip, Timeout
@@ -43,49 +43,49 @@
async_step_out_test: Skip, Timeout
awaiter_async_stack_contents_2_test: Skip, Timeout
awaiter_async_stack_contents_test: Skip, Timeout
-bad_reload_test: RuntimeError
-break_on_activation_test: RuntimeError
+bad_reload_test: SkipByDesign
+break_on_activation_test: SkipByDesign
break_on_async_function_test: Skip, Timeout
-break_on_default_constructor_test: RuntimeError
+break_on_default_constructor_test: SkipByDesign
break_on_function_test: Skip, Timeout
-breakpoint_async_break_test: RuntimeError
-breakpoint_in_package_parts_class_file_uri_test: RuntimeError
-breakpoint_in_package_parts_class_test: RuntimeError
-breakpoint_in_parts_class_test: RuntimeError
-breakpoint_non_debuggable_library_test: RuntimeError
-breakpoint_on_if_null_1_test: RuntimeError
-breakpoint_on_if_null_2_test: RuntimeError
-breakpoint_on_if_null_3_test: RuntimeError
-breakpoint_on_if_null_4_test: RuntimeError
-breakpoint_partfile_test: RuntimeError
+breakpoint_async_break_test: SkipByDesign
+breakpoint_in_package_parts_class_file_uri_test: SkipByDesign
+breakpoint_in_package_parts_class_test: SkipByDesign
+breakpoint_in_parts_class_test: SkipByDesign
+breakpoint_non_debuggable_library_test: SkipByDesign
+breakpoint_on_if_null_1_test: SkipByDesign
+breakpoint_on_if_null_2_test: SkipByDesign
+breakpoint_on_if_null_3_test: SkipByDesign
+breakpoint_on_if_null_4_test: SkipByDesign
+breakpoint_partfile_test: SkipByDesign
breakpoint_two_args_checked_test: Skip, Timeout
-breakpoints_with_mixin_test: RuntimeError # Debugger is disabled in AOT mode.
+breakpoints_with_mixin_test: SkipByDesign # Debugger is disabled in AOT mode.
capture_stdio_test: Skip, Timeout
causal_async_stack_contents_test: Skip, Timeout
causal_async_stack_presence_test: Skip, Timeout
causal_async_star_stack_contents_test: Skip, Timeout
causal_async_star_stack_presence_test: Skip, Timeout
-client_resume_approvals_reload_test: RuntimeError # Compiler is disabled in AOT mode.
-code_test: RuntimeError
-column_breakpoint_test: RuntimeError
-complex_reload_test: RuntimeError
+client_resume_approvals_reload_test: SkipByDesign # Compiler is disabled in AOT mode.
+code_test: SkipByDesign
+column_breakpoint_test: SkipByDesign
+complex_reload_test: SkipByDesign
coverage_const_field_async_closure_test: Skip, Timeout
coverage_leaf_function_test: Skip, Timeout
coverage_optimized_function_test: Skip, Timeout
-debugger_inspect_test: RuntimeError
+debugger_inspect_test: SkipByDesign
debugger_location_second_test: Skip, Timeout
debugger_location_test: Skip, Timeout
debugging_inlined_finally_test: Skip, Timeout
-debugging_test: RuntimeError
-dev_fs_spawn_test: RuntimeError
+debugging_test: SkipByDesign
+dev_fs_spawn_test: SkipByDesign
developer_extension_test: Skip, Timeout
developer_service_get_isolate_id_test: Skip, Timeout
-eval_internal_class_test: RuntimeError
+eval_internal_class_test: SkipByDesign
eval_regression_flutter20255_test: Skip, Timeout
eval_test: Skip, Timeout
evaluate_activation_in_method_class_test: Skip, Timeout
-evaluate_activation_test: RuntimeError
-evaluate_async_closure_test: RuntimeError
+evaluate_activation_test: SkipByDesign
+evaluate_async_closure_test: SkipByDesign
evaluate_class_type_parameters_test: Skip, Timeout
evaluate_function_type_parameters_test: Skip, Timeout
evaluate_in_async_activation_test: Skip, Timeout
@@ -93,22 +93,22 @@
evaluate_in_frame_rpc_test: Skip, Timeout
evaluate_in_frame_with_scope_test: Skip, Timeout
evaluate_in_sync_star_activation_test: Skip, Timeout
-evaluate_with_escaping_closure_test: RuntimeError
-evaluate_with_scope_test: RuntimeError
-field_script_test: RuntimeError
+evaluate_with_escaping_closure_test: SkipByDesign
+evaluate_with_scope_test: SkipByDesign
+field_script_test: SkipByDesign
get_allocation_samples_test: Skip, Timeout
get_isolate_after_language_error_test: CompileTimeError
-get_object_rpc_test: RuntimeError
+get_object_rpc_test: SkipByDesign
get_source_report_test: Skip, Timeout
get_source_report_with_mixin_test: Skip, Timeout
get_stack_rpc_test: Skip, Timeout
-implicit_getter_setter_test: RuntimeError
+implicit_getter_setter_test: SkipByDesign
invoke_test: Skip, Timeout
-isolate_lifecycle_test: RuntimeError
-issue_25465_test: RuntimeError
+isolate_lifecycle_test: SkipByDesign
+issue_25465_test: SkipByDesign
issue_27238_test: Skip, Timeout
issue_27287_test: Skip, Timeout
-issue_30555_test: RuntimeError
+issue_30555_test: SkipByDesign
kill_paused_test: Skip, Timeout
library_dependency_test: CompileTimeError
local_variable_declaration_test: Skip, Timeout
@@ -116,68 +116,68 @@
mirror_references_test: CompileTimeError
mixin_break_test: Skip, Timeout
network_profiling_test: Skip, Timeout
-next_through_assign_call_test: RuntimeError
-next_through_assign_int_test: RuntimeError
-next_through_await_for_test: RuntimeError
-next_through_call_on_field_in_class_test: RuntimeError
-next_through_call_on_field_test: RuntimeError
-next_through_call_on_static_field_in_class_test: RuntimeError
-next_through_catch_test: RuntimeError
-next_through_closure_test: RuntimeError
-next_through_create_list_and_map_test: RuntimeError
-next_through_for_each_loop_test: RuntimeError
-next_through_for_loop_with_break_and_continue_test: RuntimeError
-next_through_function_expression_test: RuntimeError
-next_through_implicit_call_test: RuntimeError
-next_through_is_and_as_test: RuntimeError
-next_through_multi_catch_test: RuntimeError
-next_through_new_test: RuntimeError
-next_through_operator_bracket_on_super_test: RuntimeError
-next_through_operator_bracket_on_this_test: RuntimeError
-next_through_operator_bracket_test: RuntimeError
-next_through_simple_async_test: RuntimeError
-next_through_simple_async_with_returns_test: RuntimeError
-next_through_simple_linear_2_test: RuntimeError
-next_through_simple_linear_test: RuntimeError
+next_through_assign_call_test: SkipByDesign
+next_through_assign_int_test: SkipByDesign
+next_through_await_for_test: SkipByDesign
+next_through_call_on_field_in_class_test: SkipByDesign
+next_through_call_on_field_test: SkipByDesign
+next_through_call_on_static_field_in_class_test: SkipByDesign
+next_through_catch_test: SkipByDesign
+next_through_closure_test: SkipByDesign
+next_through_create_list_and_map_test: SkipByDesign
+next_through_for_each_loop_test: SkipByDesign
+next_through_for_loop_with_break_and_continue_test: SkipByDesign
+next_through_function_expression_test: SkipByDesign
+next_through_implicit_call_test: SkipByDesign
+next_through_is_and_as_test: SkipByDesign
+next_through_multi_catch_test: SkipByDesign
+next_through_new_test: SkipByDesign
+next_through_operator_bracket_on_super_test: SkipByDesign
+next_through_operator_bracket_on_this_test: SkipByDesign
+next_through_operator_bracket_test: SkipByDesign
+next_through_simple_async_test: SkipByDesign
+next_through_simple_async_with_returns_test: SkipByDesign
+next_through_simple_linear_2_test: SkipByDesign
+next_through_simple_linear_test: SkipByDesign
parameters_in_scope_at_entry_test: Skip, Timeout
pause_idle_isolate_test: Skip, Timeout
-pause_on_exceptions_test: RuntimeError
-pause_on_start_then_step_test: RuntimeError
-pause_on_unhandled_async_exceptions2_test: RuntimeError
-pause_on_unhandled_async_exceptions3_test: RuntimeError
-pause_on_unhandled_async_exceptions_test: RuntimeError
-pause_on_unhandled_exceptions_test: RuntimeError
+pause_on_exceptions_test: SkipByDesign
+pause_on_start_then_step_test: SkipByDesign
+pause_on_unhandled_async_exceptions2_test: SkipByDesign
+pause_on_unhandled_async_exceptions3_test: SkipByDesign
+pause_on_unhandled_async_exceptions_test: SkipByDesign
+pause_on_unhandled_exceptions_test: SkipByDesign
positive_token_pos_test: Skip, Timeout
-regress_28443_test: RuntimeError
-regress_28980_test: RuntimeError
+regress_28443_test: SkipByDesign
+regress_28980_test: SkipByDesign
regress_34841_test: Skip, Timeout
reload_sources_test: Skip, Timeout
rewind_optimized_out_test: Skip, Timeout
rewind_test: Skip, Timeout
set_library_debuggable_test: Skip, Timeout
-simple_reload_test: RuntimeError
-steal_breakpoint_test: RuntimeError
+simple_reload_test: SkipByDesign
+steal_breakpoint_test: SkipByDesign
step_into_async_no_await_test: Skip, Timeout
step_over_await_test: Skip, Timeout
-step_test: RuntimeError
-step_through_arithmetic_test: RuntimeError
-step_through_constructor_calls_test: RuntimeError
-step_through_constructor_test: RuntimeError
-step_through_for_each_sync_star_2_test: RuntimeError
-step_through_for_each_sync_star_test: RuntimeError
-step_through_function_2_test: RuntimeError
-step_through_function_test: RuntimeError
-step_through_getter_test: RuntimeError
-step_through_mixin_from_sdk_test: RuntimeError
-step_through_property_get_test: RuntimeError
-step_through_property_set_test: RuntimeError
-step_through_setter_test: RuntimeError
-step_through_switch_test: RuntimeError
-step_through_switch_with_continue_test: RuntimeError
+step_test: SkipByDesign
+step_through_arithmetic_test: SkipByDesign
+step_through_constructor_calls_test: SkipByDesign
+step_through_constructor_test: SkipByDesign
+step_through_for_each_sync_star_2_test: SkipByDesign
+step_through_for_each_sync_star_test: SkipByDesign
+step_through_function_2_test: SkipByDesign
+step_through_function_test: SkipByDesign
+step_through_getter_test: SkipByDesign
+step_through_mixin_from_sdk_test: SkipByDesign
+step_through_property_get_test: SkipByDesign
+step_through_property_set_test: SkipByDesign
+step_through_setter_test: SkipByDesign
+step_through_switch_test: SkipByDesign
+step_through_switch_with_continue_test: SkipByDesign
valid_source_locations_test: Skip, Timeout
vm_timeline_flags_test: Skip, Timeout
weak_properties_test: CompileTimeError
-yield_positions_with_finally_test: RuntimeError
+yield_positions_with_finally_test: SkipByDesign
[ $fasta ]
get_isolate_after_language_error_test: CompileTimeError
diff --git a/runtime/tests/vm/dart/sendandexit_test.dart b/runtime/tests/vm/dart/sendandexit_test.dart
index cbc617e..f1fb1db 100644
--- a/runtime/tests/vm/dart/sendandexit_test.dart
+++ b/runtime/tests/vm/dart/sendandexit_test.dart
@@ -77,9 +77,32 @@
port.close();
}
+verifyExitMessageIsPostedLast() async {
+ final port = ReceivePort();
+ final inbox = new StreamIterator<dynamic>(port);
+ final isolate = await Isolate.spawn(worker, Message(port.sendPort, add),
+ onExit: port.sendPort);
+
+ final receivedData = Completer<dynamic>();
+ final isolateExited = Completer<bool>();
+ port.listen((dynamic resultData) {
+ if (receivedData.isCompleted) {
+ Expect.equals(
+ resultData, null); // exit message comes after data is receivedData
+ isolateExited.complete(true);
+ } else {
+ receivedData.complete(resultData);
+ }
+ });
+ Expect.equals(await isolateExited.future, true);
+ Expect.equals(await receivedData.future, 5);
+ port.close();
+}
+
main() async {
await verifyCantSendAnonymousClosure();
await verifyCantSendNative();
await verifyCantSendRegexp();
await verifyCanSendStaticMethod();
+ await verifyExitMessageIsPostedLast();
}
diff --git a/runtime/vm/heap/marker.cc b/runtime/vm/heap/marker.cc
index 716d281..44a7031 100644
--- a/runtime/vm/heap/marker.cc
+++ b/runtime/vm/heap/marker.cc
@@ -485,13 +485,7 @@
#ifndef PRODUCT
TIMELINE_FUNCTION_GC_DURATION(thread, "ProcessObjectIdTable");
ObjectIdRingClearPointerVisitor visitor(isolate_group_);
- isolate_group_->ForEachIsolate(
- [&](Isolate* isolate) {
- ObjectIdRing* ring = isolate->object_id_ring();
- ASSERT(ring != NULL);
- ring->VisitPointers(&visitor);
- },
- /*at_safepoint=*/true);
+ isolate_group_->VisitObjectIdRingPointers(&visitor);
#endif // !PRODUCT
}
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index f708317..8278400 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -861,17 +861,6 @@
// All objects in the to space have been copied from the from space at this
// moment.
-
- // Ensure the mutator thread will fail the next allocation. This will force
- // mutator to allocate a new TLAB
- heap_->isolate_group()->ForEachIsolate(
- [&](Isolate* isolate) {
- Thread* mutator_thread = isolate->mutator_thread();
- ASSERT(mutator_thread == nullptr ||
- mutator_thread->tlab().IsAbandoned());
- },
- /*at_safepoint=*/true);
-
double avg_frac = stats_history_.Get(0).PromoCandidatesSuccessFraction();
if (stats_history_.Size() >= 2) {
// Previous scavenge is only given half as much weight.
@@ -1020,11 +1009,7 @@
void Scavenger::IterateObjectIdTable(ObjectPointerVisitor* visitor) {
#ifndef PRODUCT
TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "IterateObjectIdTable");
- heap_->isolate_group()->ForEachIsolate(
- [&](Isolate* isolate) {
- isolate->object_id_ring()->VisitPointers(visitor);
- },
- /*at_safepoint=*/true);
+ heap_->isolate_group()->VisitObjectIdRingPointers(visitor);
#endif // !PRODUCT
}
@@ -1331,18 +1316,6 @@
current = current->next();
}
- // All unscheduled mutator threads should have already abnadoned their TLABs.
- isolate_group->ForEachIsolate(
- [&](Isolate* isolate) {
- Thread* mutator_thread = isolate->mutator_thread();
- if (mutator_thread != NULL) {
- if (isolate->scheduled_mutator_thread_ == nullptr) {
- RELEASE_ASSERT(mutator_thread->tlab().IsAbandoned());
- }
- }
- },
- /*at_safepoint=*/true);
-
for (intptr_t i = 0; i < free_tlabs_.length(); ++i) {
MakeTLABIterable(free_tlabs_[i]);
}
@@ -1361,18 +1334,6 @@
current->set_tlab(TLAB());
current = current->next();
}
- // All unscheduled mutator threads should have already abandoned their TLAB.
- isolate_group->ForEachIsolate(
- [&](Isolate* isolate) {
- Thread* mutator_thread = isolate->mutator_thread();
- if (mutator_thread != NULL) {
- if (isolate->scheduled_mutator_thread_ == nullptr) {
- RELEASE_ASSERT(mutator_thread->tlab().IsAbandoned());
- }
- }
- },
- /*at_safepoint=*/true);
-
while (free_tlabs_.length() > 0) {
const TLAB tlab = free_tlabs_.RemoveLast();
AddAbandonedInBytesLocked(tlab.RemainingSize());
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 1a74498..b8f886b 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -2387,14 +2387,17 @@
// Then, proceed with low-level teardown.
Isolate::UnMarkIsolateReady(this);
- LowLevelShutdown();
+ // Post message before LowLevelShutdown that sends onExit message.
+ // This ensures that exit message comes last.
if (bequest_.get() != nullptr) {
auto beneficiary = bequest_->beneficiary();
PortMap::PostMessage(Message::New(beneficiary, bequest_.release(),
Message::kNormalPriority));
}
+ LowLevelShutdown();
+
// Now we can unregister from the thread, invoke cleanup callback, delete the
// isolate (and possibly the isolate group).
Isolate::LowLevelCleanup(this);
@@ -2646,11 +2649,9 @@
void IsolateGroup::VisitObjectPointers(ObjectPointerVisitor* visitor,
ValidationPolicy validate_frames) {
- ForEachIsolate(
- [&](Isolate* isolate) {
- isolate->VisitObjectPointers(visitor, validate_frames);
- },
- /*at_safepoint=*/true);
+ for (Isolate* isolate : isolates_) {
+ isolate->VisitObjectPointers(visitor, validate_frames);
+ }
api_state()->VisitObjectPointersUnlocked(visitor);
// Visit objects in the object store.
if (object_store() != nullptr) {
@@ -2668,20 +2669,25 @@
// for the mutator threads themselves.
thread_registry()->VisitObjectPointers(this, visitor, validate_frames);
- ForEachIsolate(
- [&](Isolate* isolate) {
- // Visit mutator thread, even if the isolate isn't entered/scheduled
- // (there might be live API handles to visit).
- if (isolate->mutator_thread_ != nullptr) {
- isolate->mutator_thread_->VisitObjectPointers(visitor,
- validate_frames);
- }
- },
- /*at_safepoint=*/true);
+ for (Isolate* isolate : isolates_) {
+ // Visit mutator thread, even if the isolate isn't entered/scheduled
+ // (there might be live API handles to visit).
+ if (isolate->mutator_thread_ != nullptr) {
+ isolate->mutator_thread_->VisitObjectPointers(visitor, validate_frames);
+ }
+ }
visitor->clear_gc_root_type();
}
+void IsolateGroup::VisitObjectIdRingPointers(ObjectPointerVisitor* visitor) {
+#if !defined(PRODUCT)
+ for (Isolate* isolate : isolates_) {
+ isolate->object_id_ring()->VisitPointers(visitor);
+ }
+#endif // !defined(PRODUCT)
+}
+
void IsolateGroup::VisitWeakPersistentHandles(HandleVisitor* visitor) {
api_state()->VisitWeakHandlesUnlocked(visitor);
}
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 7b784b9..3516672 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -475,6 +475,7 @@
ValidationPolicy validate_frames);
void VisitStackPointers(ObjectPointerVisitor* visitor,
ValidationPolicy validate_frames);
+ void VisitObjectIdRingPointers(ObjectPointerVisitor* visitor);
void VisitWeakPersistentHandles(HandleVisitor* visitor);
bool compaction_in_progress() const {
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 48d4884..afbd027 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -1321,13 +1321,13 @@
}
TimelineEventEndlessRecorder::TimelineEventEndlessRecorder()
- : head_(NULL), block_index_(0) {}
+ : head_(nullptr), tail_(nullptr), block_index_(0) {}
TimelineEventEndlessRecorder::~TimelineEventEndlessRecorder() {
TimelineEventBlock* current = head_;
- head_ = NULL;
+ head_ = tail_ = nullptr;
- while (current != NULL) {
+ while (current != nullptr) {
TimelineEventBlock* next = current->next();
delete current;
current = next;
@@ -1374,45 +1374,30 @@
TimelineEventBlock* TimelineEventEndlessRecorder::GetNewBlockLocked() {
TimelineEventBlock* block = new TimelineEventBlock(block_index_++);
- block->set_next(head_);
block->Open();
- head_ = block;
+ if (head_ == nullptr) {
+ head_ = tail_ = block;
+ } else {
+ tail_->set_next(block);
+ tail_ = block;
+ }
if (FLAG_trace_timeline) {
OS::PrintErr("Created new block %p\n", block);
}
- return head_;
+ return block;
}
#ifndef PRODUCT
-static int TimelineEventBlockCompare(TimelineEventBlock* const* a,
- TimelineEventBlock* const* b) {
- return (*a)->LowerTimeBound() - (*b)->LowerTimeBound();
-}
-
void TimelineEventEndlessRecorder::PrintJSONEvents(
JSONArray* events,
TimelineEventFilter* filter) {
MutexLocker ml(&lock_);
ResetTimeTracking();
- // Collect all interesting blocks.
- MallocGrowableArray<TimelineEventBlock*> blocks(8);
- TimelineEventBlock* current = head_;
- while (current != NULL) {
- if (filter->IncludeBlock(current)) {
- blocks.Add(current);
+ for (TimelineEventBlock* current = head_; current != nullptr;
+ current = current->next()) {
+ if (!filter->IncludeBlock(current)) {
+ continue;
}
- current = current->next();
- }
- // Bail early.
- if (blocks.length() == 0) {
- return;
- }
- // Sort the interesting blocks so that blocks with earlier events are
- // outputted first.
- blocks.Sort(TimelineEventBlockCompare);
- // Output blocks in sorted order.
- for (intptr_t block_idx = 0; block_idx < blocks.length(); block_idx++) {
- current = blocks[block_idx];
intptr_t length = current->length();
for (intptr_t i = 0; i < length; i++) {
TimelineEvent* event = current->At(i);
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index e45b144..8841258 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -866,6 +866,7 @@
#endif
TimelineEventBlock* head_;
+ TimelineEventBlock* tail_;
intptr_t block_index_;
friend class TimelineTestHelper;
diff --git a/sdk_nnbd/lib/developer/service.dart b/sdk_nnbd/lib/developer/service.dart
index 9fab7f4..6d90667 100644
--- a/sdk_nnbd/lib/developer/service.dart
+++ b/sdk_nnbd/lib/developer/service.dart
@@ -42,12 +42,12 @@
static Future<ServiceProtocolInfo> getInfo() async {
// Port to receive response from service isolate.
final RawReceivePort receivePort = new RawReceivePort();
- final Completer<Uri> uriCompleter = new Completer<Uri>();
- receivePort.handler = (Uri uri) => uriCompleter.complete(uri);
+ final Completer<Uri?> uriCompleter = new Completer<Uri?>();
+ receivePort.handler = (Uri? uri) => uriCompleter.complete(uri);
// Request the information from the service isolate.
_getServerInfo(receivePort.sendPort);
// Await the response from the service isolate.
- Uri uri = await uriCompleter.future;
+ Uri? uri = await uriCompleter.future;
// Close the port.
receivePort.close();
return new ServiceProtocolInfo(uri);
diff --git a/tests/compiler/dart2js/analyses/analysis_helper.dart b/tests/compiler/dart2js/analyses/analysis_helper.dart
index d70a4bc..ba0e1f5 100644
--- a/tests/compiler/dart2js/analyses/analysis_helper.dart
+++ b/tests/compiler/dart2js/analyses/analysis_helper.dart
@@ -310,6 +310,8 @@
assert(
node is! ir.Expression ||
staticType == typeEnvironment.nullType ||
+ staticType is ir.InterfaceType &&
+ staticType.classNode == typeEnvironment.futureOrClass ||
typeEnvironment.isSubtypeOf(
staticType,
_getStaticTypeFromExpression(node),
diff --git a/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart b/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
index 2f1dcc5..8ca5209 100644
--- a/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
+++ b/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
@@ -57,8 +57,8 @@
i /*invoke: [subclass=JSPositiveInt]*/ ++) {
methods. /*invoke: [exact=JSExtendableArray]*/ add(
/*[null]*/ (int
- /*spec:nnbd-off.[null|subclass=Object]*/
- /*prod:nnbd-off.[null|subclass=JSInt]*/
+ /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
+ /*prod:nnbd-off|prod:nnbd-sdk.[null|subclass=JSInt]*/
x) {
res = x;
sum = x /*invoke: [null|subclass=JSInt]*/ + i;
diff --git a/tests/compiler/dart2js/inference/data/no_such_method.dart b/tests/compiler/dart2js/inference/data/no_such_method.dart
index 792f6eb..671f70c 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method.dart
@@ -17,8 +17,8 @@
/*member: Class1.noSuchMethod:[exact=JSUInt31]*/
noSuchMethod(
Invocation
- /*spec:nnbd-off.[null|subclass=Object]*/
- /*prod:nnbd-off.[null|exact=JSInvocationMirror]*/
+ /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
+ /*prod:nnbd-off|prod:nnbd-sdk.[null|exact=JSInvocationMirror]*/
_) =>
42;
@@ -41,8 +41,8 @@
/*member: Class2.noSuchMethod:[exact=JSUInt31]*/
noSuchMethod(
Invocation
- /*spec:nnbd-off.[null|subclass=Object]*/
- /*prod:nnbd-off.[null|exact=JSInvocationMirror]*/
+ /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
+ /*prod:nnbd-off|prod:nnbd-sdk.[null|exact=JSInvocationMirror]*/
_) =>
42;
@@ -65,8 +65,8 @@
/*member: Class3.noSuchMethod:[null|subclass=Object]*/
noSuchMethod(
Invocation
- /*spec:nnbd-off.[null|subclass=Object]*/
- /*prod:nnbd-off.[null|exact=JSInvocationMirror]*/
+ /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
+ /*prod:nnbd-off|prod:nnbd-sdk.[null|exact=JSInvocationMirror]*/
invocation) {
return invocation
.
@@ -101,8 +101,8 @@
/*member: Class4.noSuchMethod:[null]*/
noSuchMethod(
Invocation
- /*spec:nnbd-off.[null|subclass=Object]*/
- /*prod:nnbd-off.[null|exact=JSInvocationMirror]*/
+ /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
+ /*prod:nnbd-off|prod:nnbd-sdk.[null|exact=JSInvocationMirror]*/
invocation) {
this. /*update: [exact=Class4]*/ field = invocation
.
diff --git a/tests/compiler/dart2js/inference/data/no_such_method1.dart b/tests/compiler/dart2js/inference/data/no_such_method1.dart
index 2c7d7d3..8b37b2c 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method1.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method1.dart
@@ -8,8 +8,8 @@
class A {
/*member: A.noSuchMethod:[exact=JSUInt31]*/
noSuchMethod(
- /*spec:nnbd-off.[null|subclass=Object]*/
- /*prod:nnbd-off.[null|exact=JSInvocationMirror]*/
+ /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
+ /*prod:nnbd-off|prod:nnbd-sdk.[null|exact=JSInvocationMirror]*/
im) =>
42;
}
diff --git a/tests/compiler/dart2js/inference/data/no_such_method2.dart b/tests/compiler/dart2js/inference/data/no_such_method2.dart
index e50ec96..9c5f719 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method2.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method2.dart
@@ -8,8 +8,8 @@
abstract class A {
/*member: A.noSuchMethod:[exact=JSUInt31]*/
noSuchMethod(
- /*spec:nnbd-off.[null|subclass=Object]*/
- /*prod:nnbd-off.[null|exact=JSInvocationMirror]*/
+ /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
+ /*prod:nnbd-off|prod:nnbd-sdk.[null|exact=JSInvocationMirror]*/
im) =>
42;
}
@@ -33,8 +33,8 @@
/*member: D.noSuchMethod:[exact=JSDouble]*/
noSuchMethod(
- /*prod:nnbd-off.[null|exact=JSInvocationMirror]*/
- /*spec:nnbd-off.[null|subclass=Object]*/
+ /*prod:nnbd-off|prod:nnbd-sdk.[null|exact=JSInvocationMirror]*/
+ /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
im) =>
42.5;
}
diff --git a/tests/compiler/dart2js/inference/data/no_such_method3.dart b/tests/compiler/dart2js/inference/data/no_such_method3.dart
index 275d209..473e312 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method3.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method3.dart
@@ -10,8 +10,8 @@
// throws an exception.
/*member: A.noSuchMethod:[empty]*/
noSuchMethod(
- /*spec:nnbd-off.[null|subclass=Object]*/
- /*prod:nnbd-off.[null|exact=JSInvocationMirror]*/
+ /*spec:nnbd-off|spec:nnbd-sdk.[null|subclass=Object]*/
+ /*prod:nnbd-off|prod:nnbd-sdk.[null|exact=JSInvocationMirror]*/
im) =>
throw 'foo';
}
diff --git a/tests/compiler/dart2js/inference/data/parameters_trust.dart b/tests/compiler/dart2js/inference/data/parameters_trust.dart
index ddf89ec..e73c209 100644
--- a/tests/compiler/dart2js/inference/data/parameters_trust.dart
+++ b/tests/compiler/dart2js/inference/data/parameters_trust.dart
@@ -18,8 +18,8 @@
/*member: _trustParameters:[exact=JSUInt31]*/
_trustParameters(
int
- /*spec:nnbd-off.Union([exact=JSString], [exact=JSUInt31])*/
- /*prod:nnbd-off.[exact=JSUInt31]*/
+ /*spec:nnbd-off|spec:nnbd-sdk.Union([exact=JSString], [exact=JSUInt31])*/
+ /*prod:nnbd-off|prod:nnbd-sdk.[exact=JSUInt31]*/
i) {
return i;
}
diff --git a/tests/compiler/dart2js/inference/data/try_catch.dart b/tests/compiler/dart2js/inference/data/try_catch.dart
index 0a3d09a..0a41400 100644
--- a/tests/compiler/dart2js/inference/data/try_catch.dart
+++ b/tests/compiler/dart2js/inference/data/try_catch.dart
@@ -122,7 +122,7 @@
return a;
}
-/*spec:nnbd-off|prod:nnbd-off.member: returnInt6:[subclass=JSInt]*/
+/*member: returnInt6:[subclass=JSInt]*/
returnInt6() {
try {
throw 42;
diff --git a/tests/corelib/regexp/regexp_test.dart b/tests/corelib/regexp/regexp_test.dart
index 1cb8ac7..9f42f43 100644
--- a/tests/corelib/regexp/regexp_test.dart
+++ b/tests/corelib/regexp/regexp_test.dart
@@ -32,10 +32,12 @@
assertEquals("foo:bar:baz", str.split(regexp).join(":"));
}
-void assertEquals(actual, expected, [message]) =>
+void assertEquals(actual, expected, [String message = ""]) =>
Expect.equals(actual, expected, message);
-void assertTrue(actual, [message]) => Expect.isTrue(actual, message);
-void assertFalse(actual, [message]) => Expect.isFalse(actual, message);
+void assertTrue(actual, [String message = ""]) =>
+ Expect.isTrue(actual, message);
+void assertFalse(actual, [String message = ""]) =>
+ Expect.isFalse(actual, message);
void assertThrows(fn) => Expect.throws(fn);
void main() {
diff --git a/tests/corelib/uri_test.dart b/tests/corelib/uri_test.dart
index bb45fe0..550fc57 100644
--- a/tests/corelib/uri_test.dart
+++ b/tests/corelib/uri_test.dart
@@ -470,8 +470,8 @@
});
var params = uri.queryParametersAll;
Expect.equals(2, params.length);
- Expect.listEquals(["42", "37"], params["x"]);
- Expect.listEquals(["43", "38"], params["y"]);
+ Expect.listEquals(["42", "37"], params["x"]!);
+ Expect.listEquals(["43", "38"], params["y"]!);
}
main() {
diff --git a/tests/language_2/variance/syntax/variance_disabled_syntax_test.dart b/tests/language_2/variance/syntax/variance_disabled_syntax_test.dart
index 0ae03df..2811208 100644
--- a/tests/language_2/variance/syntax/variance_disabled_syntax_test.dart
+++ b/tests/language_2/variance/syntax/variance_disabled_syntax_test.dart
@@ -10,25 +10,25 @@
abstract class A<in X> {
// ^^
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
int foo(X bar);
}
class B<out X, in Y, inout Z> {}
// ^^^
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
// ^^
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
// ^^^^^
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
class C<in T> extends A<T> {
// ^^
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
@override
int foo(T bar) {
return 2;
@@ -38,29 +38,29 @@
mixin D<out T> {}
// ^^^
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
class E1 {}
mixin E<in T extends E1> {}
// ^^
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
class F<out T> = Object with D<T>;
// ^^^
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
class G<out out> {}
// ^^^
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
class H<out inout> {}
// ^^^
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
-// [cfe] This requires the 'variance' experiment to be enabled.
+// [cfe] This requires the 'variance' language feature to be enabled.
main() {
B<int, String, bool> b = B();
diff --git a/tests/lib/isolate/function_send_test.dart b/tests/lib/isolate/function_send_test.dart
index 4b22fa1..38b4698 100644
--- a/tests/lib/isolate/function_send_test.dart
+++ b/tests/lib/isolate/function_send_test.dart
@@ -191,10 +191,10 @@
});
Expect.throws(() {
noReply.sendPort.send(func);
- }, null, "send direct");
+ }, (_) => true, "send direct");
Expect.throws(() {
noReply.sendPort.send([func]);
- }, null, "send wrapped");
+ }, (_) => true, "send wrapped");
scheduleMicrotask(() {
noReply.close();
asyncEnd();
diff --git a/tests/lib/math/implement_rectangle_test.dart b/tests/lib/math/implement_rectangle_test.dart
index 3a31ed8..f6f6a91 100644
--- a/tests/lib/math/implement_rectangle_test.dart
+++ b/tests/lib/math/implement_rectangle_test.dart
@@ -25,9 +25,9 @@
Rectangle(this.left, this.top, this.width, this.height);
- T get right => left + width;
+ T get right => (left + width) as T;
- T get bottom => top + height;
+ T get bottom => (top + height) as T;
Point<T> get topLeft => new Point<T>(left, top);
@@ -58,7 +58,8 @@
T rTop = min(top, other.top);
T rRight = max(right, other.right);
T rBottom = max(bottom, other.bottom);
- return new Rectangle<T>(rLeft, rTop, rRight - rLeft, rBottom - rTop);
+ return new Rectangle<T>(
+ rLeft, rTop, (rRight - rLeft) as T, (rBottom - rTop) as T);
}
/// Tests whether `this` entirely contains [another].
@@ -75,6 +76,7 @@
T rTop = max(top, rect.top);
T rRight = min(right, rect.right);
T rBottom = min(bottom, rect.bottom);
- return new Rectangle<T>(rLeft, rTop, rRight - rLeft, rBottom - rTop);
+ return new Rectangle<T>(
+ rLeft, rTop, (rRight - rLeft) as T, (rBottom - rTop) as T);
}
}
diff --git a/tools/VERSION b/tools/VERSION
index 8324ed2..2aa401e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
MAJOR 2
MINOR 9
PATCH 0
-PRERELEASE 4
+PRERELEASE 5
PRERELEASE_PATCH 0
ABI_VERSION 32
OLDEST_SUPPORTED_ABI_VERSION 32
diff --git a/tools/gardening/pubspec.yaml b/tools/gardening/pubspec.yaml
index ca78789..dc6fcca 100644
--- a/tools/gardening/pubspec.yaml
+++ b/tools/gardening/pubspec.yaml
@@ -2,6 +2,8 @@
# gardening by making it a package.
name: gardening
#version: do-not-upload
+environment:
+ sdk: "^2.7.0"
dependencies:
args:
http:
diff --git a/tools/generate_package_config.dart b/tools/generate_package_config.dart
index 19e9c94..e0ddfb8 100755
--- a/tools/generate_package_config.dart
+++ b/tools/generate_package_config.dart
@@ -8,9 +8,6 @@
import 'package:pub_semver/pub_semver.dart';
import 'package:yaml/yaml.dart';
-/// Version to use if a package doesn't constrain the language version.
-final defaultVersion = Version(2, 7, 0);
-
final repoRoot = p.dirname(p.dirname(p.fromUri(Platform.script)));
final configFilePath = p.join(repoRoot, '.dart_tool/package_config.json');
@@ -75,18 +72,14 @@
List<String> packageDirs) sync* {
for (var packageDir in packageDirs) {
var version = pubspecLanguageVersion(packageDir);
- if (version == null) {
- print('Warning: Unknown language version for ${p.basename(packageDir)}.');
- version = defaultVersion;
- }
-
var hasLibDirectory = Directory(p.join(packageDir, 'lib')).existsSync();
yield {
'name': p.basename(packageDir),
'rootUri': p.relative(packageDir, from: p.dirname(configFilePath)),
if (hasLibDirectory) 'packageUri': 'lib/',
- 'languageVersion': '${version.major}.${version.minor}'
+ if (version != null)
+ 'languageVersion': '${version.major}.${version.minor}'
};
}
}