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