Version 2.16.0-63.0.dev
Merge commit 'c39b2434358298d92572eb758ba1ecd88d427a5a' into 'dev'
diff --git a/pkg/dartdev/test/utils.dart b/pkg/dartdev/test/utils.dart
index 3f97d71..fe656a5 100644
--- a/pkg/dartdev/test/utils.dart
+++ b/pkg/dartdev/test/utils.dart
@@ -113,15 +113,14 @@
],
workingDirectory: workingDir ?? dir.path,
environment: {if (logAnalytics) '_DARTDEV_LOG_ANALYTICS': 'true'});
-
- final stdoutContents = await _process.stdout.transform(utf8.decoder).join();
- final stderrContents = await _process.stderr.transform(utf8.decoder).join();
+ final stdoutContents = _process.stdout.transform(utf8.decoder).join();
+ final stderrContents = _process.stderr.transform(utf8.decoder).join();
final code = await _process.exitCode;
return ProcessResult(
_process.pid,
code,
- stdoutContents,
- stderrContents,
+ await stdoutContents,
+ await stderrContents,
);
}
diff --git a/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart b/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
index 329ca69..9c67a7c 100644
--- a/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
@@ -138,8 +138,8 @@
if (a != null && b != null) {
ReferenceName thisName = ReferenceName.fromReference(a)!;
ReferenceName otherName = ReferenceName.fromReference(b)!;
- if (thisName.kind == ReferenceNameKind.Member &&
- otherName.kind == ReferenceNameKind.Member &&
+ if (thisName.isMember &&
+ otherName.isMember &&
thisName.memberName == otherName.memberName) {
String? thisClassName = thisName.declarationName;
String? otherClassName = otherName.declarationName;
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 5927e03..2320613 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -158,6 +158,7 @@
cc
ccc
cell
+certificate
cf
characteristics
charset
diff --git a/pkg/front_end/testcases/dart2js/conditional_import.dart b/pkg/front_end/testcases/dart2js/conditional_import.dart
new file mode 100644
index 0000000..6122451
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/conditional_import.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// All three libraries have an HttpRequest class.
+import "conditional_import.dart"
+ if (dart.library.io) "dart:io"
+ if (dart.library.html) "dart:html" as a;
+
+// All three libraries have an HttpRequest class.
+import "conditional_import.dart" if (dart.library.foo) "dart:foo" as b;
+
+class HttpRequest {}
+
+testA(a.HttpRequest request) {
+ request.certificate; // error (from dart:io)
+ request.response; // ok (from dart:io and dart:html)
+ request.readyState; // ok (from dart:html)
+ request.hashCode; // ok
+}
+
+testB(b.HttpRequest request) {
+ request.certificate; // error
+ request.response; // error
+ request.readyState; // error
+ request.hashCode; // ok
+}
+
+void main() {
+ expect(false, const bool.fromEnvironment("dart.library.io"));
+ expect(true, const bool.fromEnvironment("dart.library.html"));
+ expect(false, const bool.fromEnvironment("dart.library.foo"));
+}
+
+expect(expected, actual) {
+ if (expected != actual) throw 'Expected $expected, actual $actual';
+}
diff --git a/pkg/front_end/testcases/dart2js/conditional_import.dart.strong.expect b/pkg/front_end/testcases/dart2js/conditional_import.dart.strong.expect
new file mode 100644
index 0000000..5f33ec1
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/conditional_import.dart.strong.expect
@@ -0,0 +1,84 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'dart:_http'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // ok (from dart:html)
+// ^^^^^^^^^^
+//
+// pkg/front_end/testcases/dart2js/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+// request.certificate; // error
+// ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/dart2js/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+// request.response; // error
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/dart2js/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // error
+// ^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:_http" as _ht;
+import "dart:io" as io;
+
+import "dart:io" as a;
+import "org-dartlang-testcase:///conditional_import.dart" as b;
+
+class HttpRequest extends core::Object {
+ synthetic constructor •() → self::HttpRequest
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → self::HttpRequest
+ return new self::HttpRequest::•();
+}
+static method testA(_ht::HttpRequest request) → dynamic {
+ request.{_ht::HttpRequest::certificate}{io::X509Certificate?};
+ request.{_ht::HttpRequest::response}{_ht::HttpResponse};
+ invalid-expression "pkg/front_end/testcases/dart2js/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'dart:_http'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // ok (from dart:html)
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method testB(self::HttpRequest request) → dynamic {
+ invalid-expression "pkg/front_end/testcases/dart2js/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+ request.certificate; // error
+ ^^^^^^^^^^^" in request{<unresolved>}.certificate;
+ invalid-expression "pkg/front_end/testcases/dart2js/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+ request.response; // error
+ ^^^^^^^^" in request{<unresolved>}.response;
+ invalid-expression "pkg/front_end/testcases/dart2js/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // error
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method main() → void {
+ self::expect(false, #C1);
+ self::expect(true, #C1);
+ self::expect(false, #C1);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = false
+}
diff --git a/pkg/front_end/testcases/dart2js/conditional_import.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/conditional_import.dart.strong.transformed.expect
new file mode 100644
index 0000000..5f33ec1
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/conditional_import.dart.strong.transformed.expect
@@ -0,0 +1,84 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'dart:_http'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // ok (from dart:html)
+// ^^^^^^^^^^
+//
+// pkg/front_end/testcases/dart2js/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+// request.certificate; // error
+// ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/dart2js/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+// request.response; // error
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/dart2js/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // error
+// ^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:_http" as _ht;
+import "dart:io" as io;
+
+import "dart:io" as a;
+import "org-dartlang-testcase:///conditional_import.dart" as b;
+
+class HttpRequest extends core::Object {
+ synthetic constructor •() → self::HttpRequest
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → self::HttpRequest
+ return new self::HttpRequest::•();
+}
+static method testA(_ht::HttpRequest request) → dynamic {
+ request.{_ht::HttpRequest::certificate}{io::X509Certificate?};
+ request.{_ht::HttpRequest::response}{_ht::HttpResponse};
+ invalid-expression "pkg/front_end/testcases/dart2js/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'dart:_http'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // ok (from dart:html)
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method testB(self::HttpRequest request) → dynamic {
+ invalid-expression "pkg/front_end/testcases/dart2js/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+ request.certificate; // error
+ ^^^^^^^^^^^" in request{<unresolved>}.certificate;
+ invalid-expression "pkg/front_end/testcases/dart2js/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+ request.response; // error
+ ^^^^^^^^" in request{<unresolved>}.response;
+ invalid-expression "pkg/front_end/testcases/dart2js/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // error
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method main() → void {
+ self::expect(false, #C1);
+ self::expect(true, #C1);
+ self::expect(false, #C1);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = false
+}
diff --git a/pkg/front_end/testcases/dart2js/conditional_import.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/conditional_import.dart.textual_outline.expect
new file mode 100644
index 0000000..dc10727
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/conditional_import.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+import "conditional_import.dart"
+ if (dart.library.io) "dart:io"
+ if (dart.library.html) "dart:html" as a;
+import "conditional_import.dart" if (dart.library.foo) "dart:foo" as b;
+
+class HttpRequest {}
+
+testA(a.HttpRequest request) {}
+testB(b.HttpRequest request) {}
+void main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/dart2js/conditional_import.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/conditional_import.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6e90f3d
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/conditional_import.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import "conditional_import.dart" if (dart.library.foo) "dart:foo" as b;
+import "conditional_import.dart"
+ if (dart.library.io) "dart:io"
+ if (dart.library.html) "dart:html" as a;
+
+class HttpRequest {}
+
+expect(expected, actual) {}
+testA(a.HttpRequest request) {}
+testB(b.HttpRequest request) {}
+void main() {}
diff --git a/pkg/front_end/testcases/dart2js/conditional_import.dart.weak.expect b/pkg/front_end/testcases/dart2js/conditional_import.dart.weak.expect
new file mode 100644
index 0000000..5f33ec1
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/conditional_import.dart.weak.expect
@@ -0,0 +1,84 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'dart:_http'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // ok (from dart:html)
+// ^^^^^^^^^^
+//
+// pkg/front_end/testcases/dart2js/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+// request.certificate; // error
+// ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/dart2js/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+// request.response; // error
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/dart2js/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // error
+// ^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:_http" as _ht;
+import "dart:io" as io;
+
+import "dart:io" as a;
+import "org-dartlang-testcase:///conditional_import.dart" as b;
+
+class HttpRequest extends core::Object {
+ synthetic constructor •() → self::HttpRequest
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → self::HttpRequest
+ return new self::HttpRequest::•();
+}
+static method testA(_ht::HttpRequest request) → dynamic {
+ request.{_ht::HttpRequest::certificate}{io::X509Certificate?};
+ request.{_ht::HttpRequest::response}{_ht::HttpResponse};
+ invalid-expression "pkg/front_end/testcases/dart2js/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'dart:_http'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // ok (from dart:html)
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method testB(self::HttpRequest request) → dynamic {
+ invalid-expression "pkg/front_end/testcases/dart2js/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+ request.certificate; // error
+ ^^^^^^^^^^^" in request{<unresolved>}.certificate;
+ invalid-expression "pkg/front_end/testcases/dart2js/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+ request.response; // error
+ ^^^^^^^^" in request{<unresolved>}.response;
+ invalid-expression "pkg/front_end/testcases/dart2js/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // error
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method main() → void {
+ self::expect(false, #C1);
+ self::expect(true, #C1);
+ self::expect(false, #C1);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = false
+}
diff --git a/pkg/front_end/testcases/dart2js/conditional_import.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/conditional_import.dart.weak.outline.expect
new file mode 100644
index 0000000..8e7ea0f
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/conditional_import.dart.weak.outline.expect
@@ -0,0 +1,22 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_http" as _ht;
+
+import "dart:io" as a;
+import "org-dartlang-testcase:///conditional_import.dart" as b;
+
+class HttpRequest extends core::Object {
+ synthetic constructor •() → self::HttpRequest
+ ;
+ static method _#new#tearOff() → self::HttpRequest
+ return new self::HttpRequest::•();
+}
+static method testA(_ht::HttpRequest request) → dynamic
+ ;
+static method testB(self::HttpRequest request) → dynamic
+ ;
+static method main() → void
+ ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/dart2js/conditional_import.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/conditional_import.dart.weak.transformed.expect
new file mode 100644
index 0000000..5f33ec1
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/conditional_import.dart.weak.transformed.expect
@@ -0,0 +1,84 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'dart:_http'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // ok (from dart:html)
+// ^^^^^^^^^^
+//
+// pkg/front_end/testcases/dart2js/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+// request.certificate; // error
+// ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/dart2js/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+// request.response; // error
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/dart2js/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // error
+// ^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:_http" as _ht;
+import "dart:io" as io;
+
+import "dart:io" as a;
+import "org-dartlang-testcase:///conditional_import.dart" as b;
+
+class HttpRequest extends core::Object {
+ synthetic constructor •() → self::HttpRequest
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → self::HttpRequest
+ return new self::HttpRequest::•();
+}
+static method testA(_ht::HttpRequest request) → dynamic {
+ request.{_ht::HttpRequest::certificate}{io::X509Certificate?};
+ request.{_ht::HttpRequest::response}{_ht::HttpResponse};
+ invalid-expression "pkg/front_end/testcases/dart2js/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'dart:_http'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // ok (from dart:html)
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method testB(self::HttpRequest request) → dynamic {
+ invalid-expression "pkg/front_end/testcases/dart2js/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+ request.certificate; // error
+ ^^^^^^^^^^^" in request{<unresolved>}.certificate;
+ invalid-expression "pkg/front_end/testcases/dart2js/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+ request.response; // error
+ ^^^^^^^^" in request{<unresolved>}.response;
+ invalid-expression "pkg/front_end/testcases/dart2js/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dart2js/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // error
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method main() → void {
+ self::expect(false, #C1);
+ self::expect(true, #C1);
+ self::expect(false, #C1);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = false
+}
diff --git a/pkg/front_end/testcases/dartdevc/conditional_import.dart b/pkg/front_end/testcases/dartdevc/conditional_import.dart
new file mode 100644
index 0000000..6122451
--- /dev/null
+++ b/pkg/front_end/testcases/dartdevc/conditional_import.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// All three libraries have an HttpRequest class.
+import "conditional_import.dart"
+ if (dart.library.io) "dart:io"
+ if (dart.library.html) "dart:html" as a;
+
+// All three libraries have an HttpRequest class.
+import "conditional_import.dart" if (dart.library.foo) "dart:foo" as b;
+
+class HttpRequest {}
+
+testA(a.HttpRequest request) {
+ request.certificate; // error (from dart:io)
+ request.response; // ok (from dart:io and dart:html)
+ request.readyState; // ok (from dart:html)
+ request.hashCode; // ok
+}
+
+testB(b.HttpRequest request) {
+ request.certificate; // error
+ request.response; // error
+ request.readyState; // error
+ request.hashCode; // ok
+}
+
+void main() {
+ expect(false, const bool.fromEnvironment("dart.library.io"));
+ expect(true, const bool.fromEnvironment("dart.library.html"));
+ expect(false, const bool.fromEnvironment("dart.library.foo"));
+}
+
+expect(expected, actual) {
+ if (expected != actual) throw 'Expected $expected, actual $actual';
+}
diff --git a/pkg/front_end/testcases/dartdevc/conditional_import.dart.strong.expect b/pkg/front_end/testcases/dartdevc/conditional_import.dart.strong.expect
new file mode 100644
index 0000000..3b668f7
--- /dev/null
+++ b/pkg/front_end/testcases/dartdevc/conditional_import.dart.strong.expect
@@ -0,0 +1,84 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dartdevc/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'dart:_http'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // ok (from dart:html)
+// ^^^^^^^^^^
+//
+// pkg/front_end/testcases/dartdevc/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+// request.certificate; // error
+// ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/dartdevc/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+// request.response; // error
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/dartdevc/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // error
+// ^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:_http" as _ht;
+import "dart:io" as io;
+
+import "dart:io" as a;
+import "org-dartlang-testcase:///conditional_import.dart" as b;
+
+class HttpRequest extends core::Object {
+ synthetic constructor •() → self::HttpRequest
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → self::HttpRequest
+ return new self::HttpRequest::•();
+}
+static method testA(_ht::HttpRequest request) → dynamic {
+ request.{_ht::HttpRequest::certificate}{io::X509Certificate?};
+ request.{_ht::HttpRequest::response}{_ht::HttpResponse};
+ invalid-expression "pkg/front_end/testcases/dartdevc/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'dart:_http'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // ok (from dart:html)
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method testB(self::HttpRequest request) → dynamic {
+ invalid-expression "pkg/front_end/testcases/dartdevc/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+ request.certificate; // error
+ ^^^^^^^^^^^" in request{<unresolved>}.certificate;
+ invalid-expression "pkg/front_end/testcases/dartdevc/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+ request.response; // error
+ ^^^^^^^^" in request{<unresolved>}.response;
+ invalid-expression "pkg/front_end/testcases/dartdevc/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // error
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method main() → void {
+ self::expect(false, #C1);
+ self::expect(true, #C1);
+ self::expect(false, #C1);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = false
+}
diff --git a/pkg/front_end/testcases/dartdevc/conditional_import.dart.strong.transformed.expect b/pkg/front_end/testcases/dartdevc/conditional_import.dart.strong.transformed.expect
new file mode 100644
index 0000000..3b668f7
--- /dev/null
+++ b/pkg/front_end/testcases/dartdevc/conditional_import.dart.strong.transformed.expect
@@ -0,0 +1,84 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dartdevc/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'dart:_http'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // ok (from dart:html)
+// ^^^^^^^^^^
+//
+// pkg/front_end/testcases/dartdevc/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+// request.certificate; // error
+// ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/dartdevc/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+// request.response; // error
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/dartdevc/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // error
+// ^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:_http" as _ht;
+import "dart:io" as io;
+
+import "dart:io" as a;
+import "org-dartlang-testcase:///conditional_import.dart" as b;
+
+class HttpRequest extends core::Object {
+ synthetic constructor •() → self::HttpRequest
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → self::HttpRequest
+ return new self::HttpRequest::•();
+}
+static method testA(_ht::HttpRequest request) → dynamic {
+ request.{_ht::HttpRequest::certificate}{io::X509Certificate?};
+ request.{_ht::HttpRequest::response}{_ht::HttpResponse};
+ invalid-expression "pkg/front_end/testcases/dartdevc/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'dart:_http'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // ok (from dart:html)
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method testB(self::HttpRequest request) → dynamic {
+ invalid-expression "pkg/front_end/testcases/dartdevc/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+ request.certificate; // error
+ ^^^^^^^^^^^" in request{<unresolved>}.certificate;
+ invalid-expression "pkg/front_end/testcases/dartdevc/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+ request.response; // error
+ ^^^^^^^^" in request{<unresolved>}.response;
+ invalid-expression "pkg/front_end/testcases/dartdevc/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // error
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method main() → void {
+ self::expect(false, #C1);
+ self::expect(true, #C1);
+ self::expect(false, #C1);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = false
+}
diff --git a/pkg/front_end/testcases/dartdevc/conditional_import.dart.textual_outline.expect b/pkg/front_end/testcases/dartdevc/conditional_import.dart.textual_outline.expect
new file mode 100644
index 0000000..dc10727
--- /dev/null
+++ b/pkg/front_end/testcases/dartdevc/conditional_import.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+import "conditional_import.dart"
+ if (dart.library.io) "dart:io"
+ if (dart.library.html) "dart:html" as a;
+import "conditional_import.dart" if (dart.library.foo) "dart:foo" as b;
+
+class HttpRequest {}
+
+testA(a.HttpRequest request) {}
+testB(b.HttpRequest request) {}
+void main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/dartdevc/conditional_import.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dartdevc/conditional_import.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6e90f3d
--- /dev/null
+++ b/pkg/front_end/testcases/dartdevc/conditional_import.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import "conditional_import.dart" if (dart.library.foo) "dart:foo" as b;
+import "conditional_import.dart"
+ if (dart.library.io) "dart:io"
+ if (dart.library.html) "dart:html" as a;
+
+class HttpRequest {}
+
+expect(expected, actual) {}
+testA(a.HttpRequest request) {}
+testB(b.HttpRequest request) {}
+void main() {}
diff --git a/pkg/front_end/testcases/dartdevc/conditional_import.dart.weak.expect b/pkg/front_end/testcases/dartdevc/conditional_import.dart.weak.expect
new file mode 100644
index 0000000..3b668f7
--- /dev/null
+++ b/pkg/front_end/testcases/dartdevc/conditional_import.dart.weak.expect
@@ -0,0 +1,84 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dartdevc/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'dart:_http'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // ok (from dart:html)
+// ^^^^^^^^^^
+//
+// pkg/front_end/testcases/dartdevc/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+// request.certificate; // error
+// ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/dartdevc/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+// request.response; // error
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/dartdevc/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // error
+// ^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:_http" as _ht;
+import "dart:io" as io;
+
+import "dart:io" as a;
+import "org-dartlang-testcase:///conditional_import.dart" as b;
+
+class HttpRequest extends core::Object {
+ synthetic constructor •() → self::HttpRequest
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → self::HttpRequest
+ return new self::HttpRequest::•();
+}
+static method testA(_ht::HttpRequest request) → dynamic {
+ request.{_ht::HttpRequest::certificate}{io::X509Certificate?};
+ request.{_ht::HttpRequest::response}{_ht::HttpResponse};
+ invalid-expression "pkg/front_end/testcases/dartdevc/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'dart:_http'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // ok (from dart:html)
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method testB(self::HttpRequest request) → dynamic {
+ invalid-expression "pkg/front_end/testcases/dartdevc/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+ request.certificate; // error
+ ^^^^^^^^^^^" in request{<unresolved>}.certificate;
+ invalid-expression "pkg/front_end/testcases/dartdevc/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+ request.response; // error
+ ^^^^^^^^" in request{<unresolved>}.response;
+ invalid-expression "pkg/front_end/testcases/dartdevc/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // error
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method main() → void {
+ self::expect(false, #C1);
+ self::expect(true, #C1);
+ self::expect(false, #C1);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = false
+}
diff --git a/pkg/front_end/testcases/dartdevc/conditional_import.dart.weak.outline.expect b/pkg/front_end/testcases/dartdevc/conditional_import.dart.weak.outline.expect
new file mode 100644
index 0000000..8e7ea0f
--- /dev/null
+++ b/pkg/front_end/testcases/dartdevc/conditional_import.dart.weak.outline.expect
@@ -0,0 +1,22 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_http" as _ht;
+
+import "dart:io" as a;
+import "org-dartlang-testcase:///conditional_import.dart" as b;
+
+class HttpRequest extends core::Object {
+ synthetic constructor •() → self::HttpRequest
+ ;
+ static method _#new#tearOff() → self::HttpRequest
+ return new self::HttpRequest::•();
+}
+static method testA(_ht::HttpRequest request) → dynamic
+ ;
+static method testB(self::HttpRequest request) → dynamic
+ ;
+static method main() → void
+ ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/dartdevc/conditional_import.dart.weak.transformed.expect b/pkg/front_end/testcases/dartdevc/conditional_import.dart.weak.transformed.expect
new file mode 100644
index 0000000..3b668f7
--- /dev/null
+++ b/pkg/front_end/testcases/dartdevc/conditional_import.dart.weak.transformed.expect
@@ -0,0 +1,84 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dartdevc/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'dart:_http'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // ok (from dart:html)
+// ^^^^^^^^^^
+//
+// pkg/front_end/testcases/dartdevc/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+// request.certificate; // error
+// ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/dartdevc/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+// request.response; // error
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/dartdevc/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // error
+// ^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:_http" as _ht;
+import "dart:io" as io;
+
+import "dart:io" as a;
+import "org-dartlang-testcase:///conditional_import.dart" as b;
+
+class HttpRequest extends core::Object {
+ synthetic constructor •() → self::HttpRequest
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → self::HttpRequest
+ return new self::HttpRequest::•();
+}
+static method testA(_ht::HttpRequest request) → dynamic {
+ request.{_ht::HttpRequest::certificate}{io::X509Certificate?};
+ request.{_ht::HttpRequest::response}{_ht::HttpResponse};
+ invalid-expression "pkg/front_end/testcases/dartdevc/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'dart:_http'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // ok (from dart:html)
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method testB(self::HttpRequest request) → dynamic {
+ invalid-expression "pkg/front_end/testcases/dartdevc/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+ request.certificate; // error
+ ^^^^^^^^^^^" in request{<unresolved>}.certificate;
+ invalid-expression "pkg/front_end/testcases/dartdevc/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+ request.response; // error
+ ^^^^^^^^" in request{<unresolved>}.response;
+ invalid-expression "pkg/front_end/testcases/dartdevc/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/dartdevc/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // error
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method main() → void {
+ self::expect(false, #C1);
+ self::expect(true, #C1);
+ self::expect(false, #C1);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = false
+}
diff --git a/pkg/front_end/testcases/general/conditional_import.dart b/pkg/front_end/testcases/general/conditional_import.dart
new file mode 100644
index 0000000..067c784
--- /dev/null
+++ b/pkg/front_end/testcases/general/conditional_import.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// All three libraries have an HttpRequest class.
+import "conditional_import.dart"
+ if (dart.library.io) "dart:io"
+ if (dart.library.html) "dart:html" as a;
+
+// All three libraries have an HttpRequest class.
+import "conditional_import.dart" if (dart.library.foo) "dart:foo" as b;
+
+class HttpRequest {}
+
+testA(a.HttpRequest request) {
+ request.certificate; // ok (from dart:io)
+ request.response; // ok (from dart:io and dart:html)
+ request.readyState; // error (from dart:html)
+ request.hashCode; // ok
+}
+
+testB(b.HttpRequest request) {
+ request.certificate; // error
+ request.response; // error
+ request.readyState; // error
+ request.hashCode; // ok
+}
+
+void main() {
+ expect(true, const bool.fromEnvironment("dart.library.io"));
+ expect(false, const bool.fromEnvironment("dart.library.html"));
+ expect(false, const bool.fromEnvironment("dart.library.foo"));
+}
+
+expect(expected, actual) {
+ if (expected != actual) throw 'Expected $expected, actual $actual';
+}
diff --git a/pkg/front_end/testcases/general/conditional_import.dart.textual_outline.expect b/pkg/front_end/testcases/general/conditional_import.dart.textual_outline.expect
new file mode 100644
index 0000000..dc10727
--- /dev/null
+++ b/pkg/front_end/testcases/general/conditional_import.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+import "conditional_import.dart"
+ if (dart.library.io) "dart:io"
+ if (dart.library.html) "dart:html" as a;
+import "conditional_import.dart" if (dart.library.foo) "dart:foo" as b;
+
+class HttpRequest {}
+
+testA(a.HttpRequest request) {}
+testB(b.HttpRequest request) {}
+void main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/general/conditional_import.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/conditional_import.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6e90f3d
--- /dev/null
+++ b/pkg/front_end/testcases/general/conditional_import.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import "conditional_import.dart" if (dart.library.foo) "dart:foo" as b;
+import "conditional_import.dart"
+ if (dart.library.io) "dart:io"
+ if (dart.library.html) "dart:html" as a;
+
+class HttpRequest {}
+
+expect(expected, actual) {}
+testA(a.HttpRequest request) {}
+testB(b.HttpRequest request) {}
+void main() {}
diff --git a/pkg/front_end/testcases/general/conditional_import.dart.weak.expect b/pkg/front_end/testcases/general/conditional_import.dart.weak.expect
new file mode 100644
index 0000000..0ae3432
--- /dev/null
+++ b/pkg/front_end/testcases/general/conditional_import.dart.weak.expect
@@ -0,0 +1,82 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'dart:_http'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // error (from dart:html)
+// ^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/general/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+// request.certificate; // error
+// ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/general/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+// request.response; // error
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/general/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/general/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // error
+// ^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:_http" as _ht;
+import "dart:io" as io;
+
+import "dart:io" as a;
+import "org-dartlang-testcase:///conditional_import.dart" as b;
+
+class HttpRequest extends core::Object {
+ synthetic constructor •() → self::HttpRequest
+ : super core::Object::•()
+ ;
+}
+static method testA(_ht::HttpRequest request) → dynamic {
+ request.{_ht::HttpRequest::certificate}{io::X509Certificate?};
+ request.{_ht::HttpRequest::response}{_ht::HttpResponse};
+ invalid-expression "pkg/front_end/testcases/general/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'dart:_http'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // error (from dart:html)
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method testB(self::HttpRequest request) → dynamic {
+ invalid-expression "pkg/front_end/testcases/general/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/general/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+ request.certificate; // error
+ ^^^^^^^^^^^" in request{<unresolved>}.certificate;
+ invalid-expression "pkg/front_end/testcases/general/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/general/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+ request.response; // error
+ ^^^^^^^^" in request{<unresolved>}.response;
+ invalid-expression "pkg/front_end/testcases/general/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/general/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // error
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method main() → void {
+ self::expect(true, #C1);
+ self::expect(false, #C1);
+ self::expect(false, #C1);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = false
+}
diff --git a/pkg/front_end/testcases/general/conditional_import.dart.weak.outline.expect b/pkg/front_end/testcases/general/conditional_import.dart.weak.outline.expect
new file mode 100644
index 0000000..17e396c
--- /dev/null
+++ b/pkg/front_end/testcases/general/conditional_import.dart.weak.outline.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_http" as _ht;
+
+import "dart:io" as a;
+import "org-dartlang-testcase:///conditional_import.dart" as b;
+
+class HttpRequest extends core::Object {
+ synthetic constructor •() → self::HttpRequest
+ ;
+}
+static method testA(_ht::HttpRequest request) → dynamic
+ ;
+static method testB(self::HttpRequest request) → dynamic
+ ;
+static method main() → void
+ ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/conditional_import.dart.weak.transformed.expect b/pkg/front_end/testcases/general/conditional_import.dart.weak.transformed.expect
new file mode 100644
index 0000000..0ae3432
--- /dev/null
+++ b/pkg/front_end/testcases/general/conditional_import.dart.weak.transformed.expect
@@ -0,0 +1,82 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'dart:_http'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // error (from dart:html)
+// ^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/general/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+// request.certificate; // error
+// ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/general/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+// request.response; // error
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/general/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+// - 'HttpRequest' is from 'pkg/front_end/testcases/general/conditional_import.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+// request.readyState; // error
+// ^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:_http" as _ht;
+import "dart:io" as io;
+
+import "dart:io" as a;
+import "org-dartlang-testcase:///conditional_import.dart" as b;
+
+class HttpRequest extends core::Object {
+ synthetic constructor •() → self::HttpRequest
+ : super core::Object::•()
+ ;
+}
+static method testA(_ht::HttpRequest request) → dynamic {
+ request.{_ht::HttpRequest::certificate}{io::X509Certificate?};
+ request.{_ht::HttpRequest::response}{_ht::HttpResponse};
+ invalid-expression "pkg/front_end/testcases/general/conditional_import.dart:18:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'dart:_http'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // error (from dart:html)
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method testB(self::HttpRequest request) → dynamic {
+ invalid-expression "pkg/front_end/testcases/general/conditional_import.dart:23:11: Error: The getter 'certificate' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/general/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'certificate'.
+ request.certificate; // error
+ ^^^^^^^^^^^" in request{<unresolved>}.certificate;
+ invalid-expression "pkg/front_end/testcases/general/conditional_import.dart:24:11: Error: The getter 'response' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/general/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.
+ request.response; // error
+ ^^^^^^^^" in request{<unresolved>}.response;
+ invalid-expression "pkg/front_end/testcases/general/conditional_import.dart:25:11: Error: The getter 'readyState' isn't defined for the class 'HttpRequest'.
+ - 'HttpRequest' is from 'pkg/front_end/testcases/general/conditional_import.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'readyState'.
+ request.readyState; // error
+ ^^^^^^^^^^" in request{<unresolved>}.readyState;
+ request.{core::Object::hashCode}{core::int};
+}
+static method main() → void {
+ self::expect(true, #C1);
+ self::expect(false, #C1);
+ self::expect(false, #C1);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = false
+}
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index a2cb1d7..8d551bb 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -33,6 +33,7 @@
general/bug31124: RuntimeError
general/call: RuntimeError
general/cascade: RuntimeError
+general/conditional_import: RuntimeError # Issue 47814
general/constructor_initializer_invalid: RuntimeError
general/covariant_field: TypeCheckError
general/covariant_generic: RuntimeError
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index a4258c6..9c9ea5e 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -46,6 +46,7 @@
general/bug31124: RuntimeError # Test has no main method (and we shouldn't add one).
general/call: RuntimeError
general/cascade: RuntimeError
+general/conditional_import: RuntimeError # Issue 47814
general/constructor_initializer_invalid: RuntimeError # Fails execution after recovery
general/covariant_field: TypeCheckError
general/covariant_generic: RuntimeError
diff --git a/pkg/kernel/lib/src/equivalence_helpers.dart b/pkg/kernel/lib/src/equivalence_helpers.dart
index a36ee07..bb7bf62 100644
--- a/pkg/kernel/lib/src/equivalence_helpers.dart
+++ b/pkg/kernel/lib/src/equivalence_helpers.dart
@@ -236,8 +236,20 @@
/// A reference name of a class or extension.
Declaration,
- /// A reference name of a typedef or member.
- Member,
+ /// A reference name of a typedef.
+ Typedef,
+
+ /// A reference name of a method or constructor.
+ Function,
+
+ /// A reference name of a field.
+ Field,
+
+ /// A reference name of a getter.
+ Getter,
+
+ /// A reference name of a setter.
+ Setter,
}
/// Abstract representation of a [Reference] or [CanonicalName].
@@ -251,25 +263,29 @@
final String? name;
final String? uri;
- ReferenceName.internal(this.kind, this.name, [this.parent, this.uri]);
+ ReferenceName.internal(this.kind, this.name, {this.parent, this.uri});
- factory ReferenceName.fromNamedNode(NamedNode node) {
+ factory ReferenceName.fromNamedNode(NamedNode node,
+ [ReferenceNameKind? memberKind]) {
if (node is Library) {
return new ReferenceName.internal(
ReferenceNameKind.Library, node.importUri.toString());
} else if (node is Extension) {
- return new ReferenceName.internal(ReferenceNameKind.Declaration,
- node.name, new ReferenceName.fromNamedNode(node.enclosingLibrary));
+ return new ReferenceName.internal(
+ ReferenceNameKind.Declaration, node.name,
+ parent: new ReferenceName.fromNamedNode(node.enclosingLibrary));
} else if (node is Class) {
- return new ReferenceName.internal(ReferenceNameKind.Declaration,
- node.name, new ReferenceName.fromNamedNode(node.enclosingLibrary));
+ return new ReferenceName.internal(
+ ReferenceNameKind.Declaration, node.name,
+ parent: new ReferenceName.fromNamedNode(node.enclosingLibrary));
} else if (node is Typedef) {
- return new ReferenceName.internal(ReferenceNameKind.Member, node.name,
- new ReferenceName.fromNamedNode(node.enclosingLibrary));
+ return new ReferenceName.internal(ReferenceNameKind.Typedef, node.name,
+ parent: new ReferenceName.fromNamedNode(node.enclosingLibrary));
} else if (node is Member) {
TreeNode? parent = node.parent;
Reference? libraryReference = node.name.libraryName;
String? uri;
+
if (libraryReference != null) {
Library? library = libraryReference.node as Library?;
if (library != null) {
@@ -278,15 +294,31 @@
uri = libraryReference.canonicalName?.name;
}
}
+
+ String name = node.name.text;
+ if (memberKind == null) {
+ if (node is Procedure) {
+ if (node.isGetter) {
+ memberKind = ReferenceNameKind.Getter;
+ } else if (node.isSetter) {
+ memberKind = ReferenceNameKind.Setter;
+ } else {
+ memberKind = ReferenceNameKind.Function;
+ }
+ } else if (node is Constructor) {
+ memberKind = ReferenceNameKind.Function;
+ } else {
+ memberKind = ReferenceNameKind.Field;
+ }
+ }
if (parent is Class) {
- return new ReferenceName.internal(ReferenceNameKind.Member,
- node.name.text, new ReferenceName.fromNamedNode(parent), uri);
+ return new ReferenceName.internal(memberKind, name,
+ parent: new ReferenceName.fromNamedNode(parent), uri: uri);
} else if (parent is Library) {
- return new ReferenceName.internal(ReferenceNameKind.Member,
- node.name.text, new ReferenceName.fromNamedNode(parent), uri);
+ return new ReferenceName.internal(memberKind, name,
+ parent: new ReferenceName.fromNamedNode(parent), uri: uri);
} else {
- return new ReferenceName.internal(
- ReferenceNameKind.Member, node.name.text, null, uri);
+ return new ReferenceName.internal(memberKind, name, uri: uri);
}
} else {
throw new ArgumentError(
@@ -305,22 +337,24 @@
ReferenceName? referenceName;
ReferenceNameKind kind = ReferenceNameKind.Declaration;
for (int index = 1; index < parents.length; index++) {
+ String name = parents[index].name;
if (index == 1) {
// Library reference.
- referenceName = new ReferenceName.internal(
- ReferenceNameKind.Library, parents[index].name);
- } else if (CanonicalName.isSymbolicName(parents[index].name)) {
+ referenceName =
+ new ReferenceName.internal(ReferenceNameKind.Library, name);
+ } else if (CanonicalName.isSymbolicName(name)) {
// Skip symbolic names
- kind = ReferenceNameKind.Member;
+ kind = kindFromSymbolicName(name);
} else {
if (index + 2 == parents.length) {
// This is a private name.
- referenceName = new ReferenceName.internal(ReferenceNameKind.Member,
- parents[index + 1].name, referenceName, parents[index].name);
+ referenceName = new ReferenceName.internal(
+ kind, parents[index + 1].name,
+ parent: referenceName, uri: name);
break;
} else {
- referenceName = new ReferenceName.internal(
- kind, parents[index].name, referenceName);
+ referenceName =
+ new ReferenceName.internal(kind, name, parent: referenceName);
}
}
}
@@ -328,6 +362,21 @@
new ReferenceName.internal(ReferenceNameKind.Unknown, null);
}
+ static ReferenceNameKind kindFromSymbolicName(String name) {
+ assert(CanonicalName.isSymbolicName(name));
+ if (name == CanonicalName.typedefsName) {
+ return ReferenceNameKind.Typedef;
+ } else if (name == CanonicalName.fieldsName) {
+ return ReferenceNameKind.Field;
+ } else if (name == CanonicalName.gettersName) {
+ return ReferenceNameKind.Getter;
+ } else if (name == CanonicalName.settersName) {
+ return ReferenceNameKind.Setter;
+ } else {
+ return ReferenceNameKind.Function;
+ }
+ }
+
String? get libraryUri {
if (kind == ReferenceNameKind.Library) {
return name;
@@ -344,15 +393,30 @@
}
}
+ bool get isMember {
+ switch (kind) {
+ case ReferenceNameKind.Unknown:
+ case ReferenceNameKind.Library:
+ case ReferenceNameKind.Declaration:
+ return false;
+ case ReferenceNameKind.Typedef:
+ case ReferenceNameKind.Function:
+ case ReferenceNameKind.Field:
+ case ReferenceNameKind.Getter:
+ case ReferenceNameKind.Setter:
+ return true;
+ }
+ }
+
String? get memberName {
- if (kind == ReferenceNameKind.Member) {
+ if (isMember) {
return name;
}
return null;
}
String? get memberUri {
- if (kind == ReferenceNameKind.Member) {
+ if (isMember) {
return uri;
}
return null;
@@ -364,7 +428,18 @@
}
NamedNode? node = reference.node;
if (node != null) {
- return new ReferenceName.fromNamedNode(node);
+ ReferenceNameKind? memberKind;
+ if (node is Field) {
+ if (node.getterReference == reference) {
+ memberKind = ReferenceNameKind.Getter;
+ } else if (node.setterReference == reference) {
+ memberKind = ReferenceNameKind.Setter;
+ } else {
+ assert(node.fieldReference == reference);
+ memberKind = ReferenceNameKind.Field;
+ }
+ }
+ return new ReferenceName.fromNamedNode(node, memberKind);
}
CanonicalName? canonicalName = reference.canonicalName;
if (canonicalName != null) {
@@ -375,19 +450,22 @@
@override
int get hashCode =>
- name.hashCode * 13 + uri.hashCode * 17 + parent.hashCode * 19;
+ kind.hashCode * 11 +
+ name.hashCode * 13 +
+ uri.hashCode * 17 +
+ parent.hashCode * 19;
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is ReferenceName &&
+ kind == other.kind &&
name == other.name &&
uri == other.uri &&
parent == other.parent;
}
- @override
- String toString() {
+ String _toStringInternal() {
if (parent != null) {
return '${parent}/$name';
} else if (name != null) {
@@ -396,4 +474,15 @@
return '<null>';
}
}
+
+ @override
+ String toString() {
+ if (parent != null) {
+ return '${kind}:${parent!._toStringInternal()}/$name';
+ } else if (name != null) {
+ return '${kind}:/$name';
+ } else {
+ return '<null>';
+ }
+ }
}
diff --git a/pkg/kernel/test/clone_test.dart b/pkg/kernel/test/clone_test.dart
index 5501551..51ee518 100644
--- a/pkg/kernel/test/clone_test.dart
+++ b/pkg/kernel/test/clone_test.dart
@@ -155,7 +155,8 @@
if (reference1 != null && reference2 != null) {
ReferenceName referenceName1 = ReferenceName.fromNamedNode(member1);
ReferenceName referenceName2 = ReferenceName.fromNamedNode(member2);
- if (referenceName1.memberName == referenceName2.memberName &&
+ if (referenceName1.kind == referenceName2.kind &&
+ referenceName1.memberName == referenceName2.memberName &&
referenceName1.memberUri == referenceName2.memberUri &&
referenceName2.declarationName == null ||
referenceName2.libraryUri == null) {
diff --git a/pkg/kernel/test/reference_name_test.dart b/pkg/kernel/test/reference_name_test.dart
new file mode 100644
index 0000000..23c7b97
--- /dev/null
+++ b/pkg/kernel/test/reference_name_test.dart
@@ -0,0 +1,333 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'package:kernel/ast.dart';
+import 'package:kernel/src/equivalence.dart';
+
+void testReferenceNames(Map<ReferenceNameKind, List<ReferenceNameObject>> map1,
+ Map<ReferenceNameKind, List<ReferenceNameObject>> map2) {
+ Expect.setEquals(map1.keys, map2.keys);
+ map1.forEach((ReferenceNameKind kind1, List<ReferenceNameObject> list1) {
+ map1.forEach((ReferenceNameKind kind2, List<ReferenceNameObject> list2) {
+ for (int index1 = 0; index1 < list1.length; index1++) {
+ for (int index2 = 0; index2 < list2.length; index2++) {
+ ReferenceName name1 = list1[index1].referenceName;
+ Object object1 = list1[index1].object;
+ ReferenceName name2 = list2[index2].referenceName;
+ Object object2 = list2[index2].object;
+ if (kind1 == kind2 && index1 == index2) {
+ Expect.equals(
+ name1,
+ name2,
+ "Expected $name1 for ${object1} (${object1.runtimeType}) and "
+ "$name2 for $object2 (${object2.runtimeType}) to be equal.");
+ } else {
+ Expect.notEquals(
+ name1,
+ name2,
+ "Expected $name1 for ${object1} (${object1.runtimeType}) and "
+ "$name2 for $object2 (${object2.runtimeType}) to be unequal.");
+ }
+ }
+ }
+ });
+ });
+}
+
+void main() {
+ Component component1 = createComponent();
+ Map<ReferenceNameKind, List<ReferenceNameObject>> referenceNames1 =
+ computeReferenceNamesFromComponent(component1);
+
+ Component component2 = createComponent();
+ Map<ReferenceNameKind, List<ReferenceNameObject>> referenceNames2 =
+ computeReferenceNamesFromComponent(component2);
+
+ Component component3 = createComponent();
+ component3.computeCanonicalNames();
+ CanonicalName root3 = component3.root;
+ Map<ReferenceNameKind, List<ReferenceNameObject>> referenceNames3 =
+ computeReferenceNamesFromCanonicalName(root3);
+
+ Component component4 = createComponent();
+ component4.computeCanonicalNames();
+ CanonicalName root4 = component3.root;
+ Map<ReferenceNameKind, List<ReferenceNameObject>> referenceNames4 =
+ computeReferenceNamesFromCanonicalName(root4);
+
+ testReferenceNames(referenceNames1, referenceNames2);
+ testReferenceNames(referenceNames1, referenceNames3);
+ testReferenceNames(referenceNames3, referenceNames4);
+}
+
+Component createComponent() {
+ Component component = new Component();
+ Library library1 = new Library(Uri.parse('test:library1'), fileUri: dummyUri);
+ component.libraries.add(library1);
+ Library library2 = new Library(Uri.parse('test:library2'), fileUri: dummyUri);
+ component.libraries.add(library2);
+
+ library1.addProcedure(new Procedure(
+ new Name('foo'), ProcedureKind.Method, new FunctionNode(null),
+ fileUri: dummyUri));
+ library1.addProcedure(new Procedure(
+ new Name('bar'), ProcedureKind.Operator, new FunctionNode(null),
+ fileUri: dummyUri));
+ library1.addProcedure(new Procedure(
+ new Name('baz'), ProcedureKind.Factory, new FunctionNode(null),
+ fileUri: dummyUri));
+ library1.addProcedure(new Procedure(
+ new Name('boz'), ProcedureKind.Getter, new FunctionNode(null),
+ fileUri: dummyUri));
+ // The setter should be distinct from the getter even when they have the same
+ // name.
+ library1.addProcedure(new Procedure(
+ new Name('boz'), ProcedureKind.Setter, new FunctionNode(null),
+ fileUri: dummyUri));
+
+ library1.addProcedure(new Procedure(
+ new Name('_boz', library2), ProcedureKind.Getter, new FunctionNode(null),
+ fileUri: dummyUri));
+ // The setter should be distinct from the getter even when they have the same
+ // name.
+ library1.addProcedure(new Procedure(
+ new Name('_boz', library2), ProcedureKind.Setter, new FunctionNode(null),
+ fileUri: dummyUri));
+
+ library1.addField(
+ new Field.immutable(new Name('_foo', library1), fileUri: dummyUri));
+ library1.addField(
+ new Field.mutable(new Name('_bar', library2), fileUri: dummyUri));
+
+ Class class1 = new Class(name: 'Foo', fileUri: dummyUri);
+ library2.addClass(class1);
+ Class class2 = new Class(name: 'Bar', fileUri: dummyUri);
+ library2.addClass(class2);
+
+ class2.addConstructor(new Constructor(new FunctionNode(null),
+ name: new Name(''), fileUri: dummyUri));
+ class2.addConstructor(new Constructor(new FunctionNode(null),
+ name: new Name('_', library1), fileUri: dummyUri));
+
+ class2.addProcedure(new Procedure(
+ new Name('foo'), ProcedureKind.Method, new FunctionNode(null),
+ fileUri: dummyUri));
+ class2.addProcedure(new Procedure(
+ new Name('bar'), ProcedureKind.Operator, new FunctionNode(null),
+ fileUri: dummyUri));
+ class2.addProcedure(new Procedure(
+ new Name('baz'), ProcedureKind.Factory, new FunctionNode(null),
+ fileUri: dummyUri));
+ class2.addProcedure(new Procedure(
+ new Name('boz'), ProcedureKind.Getter, new FunctionNode(null),
+ fileUri: dummyUri));
+ // The setter should be distinct from the getter even when they have the same
+ // name.
+ class2.addProcedure(new Procedure(
+ new Name('boz'), ProcedureKind.Setter, new FunctionNode(null),
+ fileUri: dummyUri));
+
+ class2.addProcedure(new Procedure(
+ new Name('_boz', library2), ProcedureKind.Getter, new FunctionNode(null),
+ fileUri: dummyUri));
+ // The setter should be distinct from the getter even when they have the same
+ // name.
+ class2.addProcedure(new Procedure(
+ new Name('_boz', library2), ProcedureKind.Setter, new FunctionNode(null),
+ fileUri: dummyUri));
+
+ class2.addField(
+ new Field.immutable(new Name('_foo', library1), fileUri: dummyUri));
+ class2.addField(
+ new Field.mutable(new Name('_bar', library2), fileUri: dummyUri));
+
+ class2.addRedirectingFactory(new RedirectingFactory(null,
+ name: new Name('_boz', library1),
+ function: new FunctionNode(null),
+ fileUri: dummyUri));
+
+ library1.addExtension(new Extension(name: 'Baz', fileUri: dummyUri));
+
+ library1.addTypedef(new Typedef('Boz', dummyDartType, fileUri: dummyUri));
+
+ return component;
+}
+
+void sortReferenceNames(Map<ReferenceNameKind, List<ReferenceNameObject>> map) {
+ map.forEach((key, value) {
+ value.sort(
+ (n1, n2) => n1.referenceName.name!.compareTo(n2.referenceName.name!));
+ });
+}
+
+Map<ReferenceNameKind, List<ReferenceNameObject>>
+ computeReferenceNamesFromComponent(Component component) {
+ Map<ReferenceNameKind, List<ReferenceNameObject>> map = {};
+ void add(ReferenceNameKind kind, ReferenceNameObject object) {
+ (map[kind] ??= []).add(object);
+ }
+
+ for (Library library in component.libraries) {
+ add(ReferenceNameKind.Library,
+ new ReferenceNameObject(ReferenceName.fromNamedNode(library), library));
+ for (Typedef typedef in library.typedefs) {
+ add(
+ ReferenceNameKind.Typedef,
+ new ReferenceNameObject(
+ ReferenceName.fromNamedNode(typedef), typedef));
+ }
+ for (Field field in library.fields) {
+ add(
+ ReferenceNameKind.Field,
+ new ReferenceNameObject(
+ ReferenceName.fromNamedNode(field, ReferenceNameKind.Field),
+ field));
+ add(
+ ReferenceNameKind.Getter,
+ new ReferenceNameObject(
+ ReferenceName.fromNamedNode(field, ReferenceNameKind.Getter),
+ field));
+ if (field.hasSetter) {
+ add(
+ ReferenceNameKind.Setter,
+ new ReferenceNameObject(
+ ReferenceName.fromNamedNode(field, ReferenceNameKind.Setter),
+ field));
+ }
+ }
+ for (Procedure procedure in library.procedures) {
+ ReferenceNameKind kind;
+ if (procedure.isGetter) {
+ kind = ReferenceNameKind.Getter;
+ } else if (procedure.isSetter) {
+ kind = ReferenceNameKind.Setter;
+ } else {
+ kind = ReferenceNameKind.Function;
+ }
+ add(
+ kind,
+ new ReferenceNameObject(
+ ReferenceName.fromNamedNode(procedure), procedure));
+ }
+ for (Class cls in library.classes) {
+ add(ReferenceNameKind.Declaration,
+ new ReferenceNameObject(ReferenceName.fromNamedNode(cls), cls));
+
+ for (Constructor constructor in cls.constructors) {
+ add(
+ ReferenceNameKind.Function,
+ new ReferenceNameObject(
+ ReferenceName.fromNamedNode(constructor), constructor));
+ }
+ for (Procedure procedure in cls.procedures) {
+ ReferenceNameKind kind;
+ if (procedure.isGetter) {
+ kind = ReferenceNameKind.Getter;
+ } else if (procedure.isSetter) {
+ kind = ReferenceNameKind.Setter;
+ } else {
+ kind = ReferenceNameKind.Function;
+ }
+ add(
+ kind,
+ new ReferenceNameObject(
+ ReferenceName.fromNamedNode(procedure), procedure));
+ }
+ for (Field field in cls.fields) {
+ add(ReferenceNameKind.Field,
+ new ReferenceNameObject(ReferenceName.fromNamedNode(field), field));
+ add(
+ ReferenceNameKind.Getter,
+ new ReferenceNameObject(
+ ReferenceName.fromNamedNode(field, ReferenceNameKind.Getter),
+ field));
+ if (field.hasSetter) {
+ add(
+ ReferenceNameKind.Setter,
+ new ReferenceNameObject(
+ ReferenceName.fromNamedNode(field, ReferenceNameKind.Setter),
+ field));
+ }
+ }
+ for (RedirectingFactory redirectingFactory in cls.redirectingFactories) {
+ add(
+ ReferenceNameKind.Function,
+ new ReferenceNameObject(
+ ReferenceName.fromNamedNode(redirectingFactory),
+ redirectingFactory));
+ }
+ }
+ for (Extension extension in library.extensions) {
+ add(
+ ReferenceNameKind.Declaration,
+ new ReferenceNameObject(
+ ReferenceName.fromNamedNode(extension), extension));
+ }
+ }
+ sortReferenceNames(map);
+ return map;
+}
+
+Map<ReferenceNameKind, List<ReferenceNameObject>>
+ computeReferenceNamesFromCanonicalName(CanonicalName root) {
+ Map<ReferenceNameKind, List<ReferenceNameObject>> map = {};
+
+ void visit(CanonicalName canonicalName, ReferenceNameKind kind) {
+ void addObject() {
+ (map[kind] ??= []).add(new ReferenceNameObject(
+ ReferenceName.fromCanonicalName(canonicalName), canonicalName));
+ }
+
+ switch (kind) {
+ case ReferenceNameKind.Unknown:
+ for (CanonicalName child in canonicalName.children) {
+ visit(child, ReferenceNameKind.Library);
+ }
+ break;
+ case ReferenceNameKind.Library:
+ addObject();
+ for (CanonicalName child in canonicalName.children) {
+ ReferenceNameKind childKind = ReferenceNameKind.Declaration;
+ if (CanonicalName.isSymbolicName(child.name)) {
+ childKind = ReferenceName.kindFromSymbolicName(child.name);
+ }
+ visit(child, childKind);
+ }
+ break;
+ case ReferenceNameKind.Declaration:
+ addObject();
+ for (CanonicalName child in canonicalName.children) {
+ visit(child, ReferenceName.kindFromSymbolicName(child.name));
+ }
+ break;
+ case ReferenceNameKind.Typedef:
+ case ReferenceNameKind.Function:
+ case ReferenceNameKind.Field:
+ case ReferenceNameKind.Getter:
+ case ReferenceNameKind.Setter:
+ if (canonicalName.childrenOrNull != null) {
+ // Private name
+ for (CanonicalName child in canonicalName.children) {
+ visit(child, kind);
+ }
+ } else {
+ addObject();
+ }
+ break;
+ }
+ }
+
+ visit(root, ReferenceNameKind.Unknown);
+
+ sortReferenceNames(map);
+ return map;
+}
+
+class ReferenceNameObject {
+ final ReferenceName referenceName;
+ final Object object;
+
+ ReferenceNameObject(this.referenceName, this.object);
+}
diff --git a/tools/VERSION b/tools/VERSION
index 57dc5ff..e453e6c 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 16
PATCH 0
-PRERELEASE 62
+PRERELEASE 63
PRERELEASE_PATCH 0
\ No newline at end of file