Version 2.17.0-141.0.dev

Merge commit '49f23164f3690f42f521746a730e517db896dcd6' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
index 1ab0674..0fdb8cc 100644
--- a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
@@ -543,18 +543,24 @@
     return methodInvocation;
   }
 
-  MethodInvocation _toMethodInvocationOfFunctionReference({
+  AstNode _toMethodInvocationOfFunctionReference({
     required InstanceCreationExpression node,
     required Identifier function,
   }) {
+    var period = node.constructorName.period;
+    var constructorId = node.constructorName.name;
+    if (period == null || constructorId == null) {
+      return node;
+    }
+
     var functionReference = astFactory.functionReference(
       function: function,
       typeArguments: node.constructorName.type.typeArguments,
     );
     var methodInvocation = astFactory.methodInvocation(
       functionReference,
-      node.constructorName.period,
-      node.constructorName.name!,
+      period,
+      constructorId,
       null,
       node.argumentList,
     );
diff --git a/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart b/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart
index e9d4b77..3ac61b3 100644
--- a/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart
+++ b/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart
@@ -101,6 +101,12 @@
   }
 
   @override
+  void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+    usedElements.addElement(node.constructorElement?.declaration);
+    super.visitEnumConstantDeclaration(node);
+  }
+
+  @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
     var enclosingExecOld = _enclosingExec;
     try {
@@ -251,8 +257,10 @@
           element.name == 'values') {
         // If the 'values' static accessor of the enum is accessed, then all of
         // the enum values have been read.
-        for (var value in enclosingElement.fields) {
-          usedElements.readMembers.add(value.getter!);
+        for (var field in enclosingElement.fields) {
+          if (field.isEnumConstant) {
+            usedElements.readMembers.add(field.getter!);
+          }
         }
       } else if ((enclosingElement is ClassElement ||
               enclosingElement is ExtensionElement) &&
@@ -492,14 +500,24 @@
       return false;
     }
     var enclosingElement = element.enclosingElement;
-    if (enclosingElement is ClassElement &&
-        enclosingElement.isPrivate &&
-        (element.isStatic || element is ConstructorElement)) {
-      return false;
-    } else if (enclosingElement is ExtensionElement &&
-        enclosingElement.isPrivate) {
-      return false;
+
+    if (enclosingElement is ClassElement) {
+      if (enclosingElement.isEnum) {
+        if (element is ConstructorElement && element.isGenerative) {
+          return false;
+        }
+      }
+      if (enclosingElement.isPrivate) {
+        if (element.isStatic || element is ConstructorElement) {
+          return false;
+        }
+      }
     }
+
+    if (enclosingElement is ExtensionElement) {
+      return enclosingElement.isPublic;
+    }
+
     return true;
   }
 
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart
index a3d32ce..617acb2 100644
--- a/pkg/analyzer/lib/src/summary2/element_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -240,7 +240,7 @@
       );
 
       var constructorSelector = constant.arguments?.constructorSelector;
-      var constructorName = constructorSelector?.name.name ?? '';
+      var constructorName = constructorSelector?.name.name;
 
       var initializer = astFactory.instanceCreationExpression(
         null,
@@ -251,10 +251,12 @@
             ),
             typeArguments: constant.arguments?.typeArguments,
           ),
-          Tokens.period(),
-          astFactory.simpleIdentifier(
-            StringToken(TokenType.STRING, constructorName, -1),
-          ),
+          constructorName != null ? Tokens.period() : null,
+          constructorName != null
+              ? astFactory.simpleIdentifier(
+                  StringToken(TokenType.STRING, constructorName, -1),
+                )
+              : null,
         ),
         astFactory.argumentList(
           Tokens.openParenthesis(),
diff --git a/pkg/analyzer/test/src/diagnostics/enum_constant_with_non_const_constructor_test.dart b/pkg/analyzer/test/src/diagnostics/enum_constant_with_non_const_constructor_test.dart
index 0134e87..a113a8a 100644
--- a/pkg/analyzer/test/src/diagnostics/enum_constant_with_non_const_constructor_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/enum_constant_with_non_const_constructor_test.dart
@@ -33,7 +33,6 @@
 enum E {
   v();
   factory E() => throw 0;
-  const E.named(); 
 }
 ''', [
       error(
@@ -46,7 +45,6 @@
 enum E {
   v;
   factory E() => throw 0;
-  const E.named(); 
 }
 ''', [
       error(
diff --git a/pkg/analyzer/test/src/diagnostics/extra_positional_arguments_test.dart b/pkg/analyzer/test/src/diagnostics/extra_positional_arguments_test.dart
index 152ae4c..038a4ef 100644
--- a/pkg/analyzer/test/src/diagnostics/extra_positional_arguments_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/extra_positional_arguments_test.dart
@@ -69,6 +69,7 @@
 ''', [
       error(CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED, 13,
           1),
+      error(HintCode.UNUSED_ELEMENT_PARAMETER, 33, 1),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/initializing_formal_for_non_existent_field_test.dart b/pkg/analyzer/test/src/diagnostics/initializing_formal_for_non_existent_field_test.dart
index cc82ccb..01c03c3 100644
--- a/pkg/analyzer/test/src/diagnostics/initializing_formal_for_non_existent_field_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/initializing_formal_for_non_existent_field_test.dart
@@ -83,6 +83,7 @@
 ''', [
       error(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, 25,
           6),
+      error(HintCode.UNUSED_ELEMENT_PARAMETER, 30, 1),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_reference_to_generative_enum_constructor_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_reference_to_generative_enum_constructor_test.dart
index f0b91f9..4ea7470 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_reference_to_generative_enum_constructor_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_reference_to_generative_enum_constructor_test.dart
@@ -183,7 +183,8 @@
   test_generative_unnamed_redirectingConstructorInvocation() async {
     await assertNoErrorsInCode('''
 enum E {
-  v;
+  v1,
+  v2.named();
 
   const E();
   const E.named() : this();
diff --git a/pkg/analyzer/test/src/diagnostics/unused_element_test.dart b/pkg/analyzer/test/src/diagnostics/unused_element_test.dart
index b1d7f0a..b61a659 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_element_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_element_test.dart
@@ -267,6 +267,587 @@
     ]);
   }
 
+  test_privateEnum_privateConstructor_isUsed_redirect() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v._foo();
+  const _E._foo() : this._bar();
+  const _E._bar();
+}
+
+void f() {
+  _E.v;
+}
+''');
+  }
+
+  test_privateEnum_privateConstructor_notUsed() async {
+    await assertErrorsInCode(r'''
+enum _E {
+  v._foo();
+  const _E._foo();
+  const _E._bar();
+}
+
+void f() {
+  _E.v;
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 52, 4),
+    ]);
+  }
+
+  test_privateEnum_privateInstanceGetter_isUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+  int get _foo => 0;
+}
+
+void f() {
+  _E.v._foo;
+}
+''');
+  }
+
+  test_privateEnum_privateInstanceGetter_notUsed() async {
+    await assertErrorsInCode(r'''
+enum _E {
+  v;
+  int get _foo => 0;
+}
+
+void f() {
+  _E.v;
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 25, 4),
+    ]);
+  }
+
+  test_privateEnum_privateInstanceMethod_isUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+  void _foo() {}
+}
+
+void f() {
+  _E.v._foo();
+}
+''');
+  }
+
+  test_privateEnum_privateInstanceMethod_notUsed() async {
+    await assertErrorsInCode(r'''
+enum _E {
+  v;
+  void _foo() {}
+}
+
+void f() {
+  _E.v;
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 22, 4),
+    ]);
+  }
+
+  test_privateEnum_privateInstanceMethod_optionalNamedParameter_isUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+  void _foo({int? a}) {}
+}
+
+void f() {
+  _E.v._foo(a: 0);
+}
+''');
+  }
+
+  test_privateEnum_privateInstanceMethod_optionalNamedParameter_notUsed() async {
+    await assertErrorsInCode(r'''
+enum _E {
+  v;
+  void _foo({int? a}) {}
+}
+
+void f() {
+  _E.v._foo();
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT_PARAMETER, 33, 1),
+    ]);
+  }
+
+  test_privateEnum_privateInstanceMethod_optionalPositionalParameter_isUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+  void _foo([int? a]) {}
+}
+
+void f() {
+  _E.v._foo(0);
+}
+''');
+  }
+
+  test_privateEnum_privateInstanceMethod_optionalPositionalParameter_notUsed() async {
+    await assertErrorsInCode(r'''
+enum _E {
+  v;
+  void _foo([int? a]) {}
+}
+
+void f() {
+  _E.v._foo();
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT_PARAMETER, 33, 1),
+    ]);
+  }
+
+  test_privateEnum_privateInstanceSetter_isUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+  set _foo(int _) {}
+}
+
+void f() {
+  _E.v._foo = 0;
+}
+''');
+  }
+
+  test_privateEnum_privateInstanceSetter_notUsed() async {
+    await assertErrorsInCode(r'''
+enum _E {
+  v;
+  set _foo(int _) {}
+}
+
+void f() {
+  _E.v;
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 21, 4),
+    ]);
+  }
+
+  test_privateEnum_privateStaticGetter_isUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+  static int get _foo => 0;
+}
+
+void f() {
+  _E.v;
+  _E._foo;
+}
+''');
+  }
+
+  test_privateEnum_privateStaticGetter_notUsed() async {
+    await assertErrorsInCode(r'''
+enum _E {
+  v;
+  static int get _foo => 0;
+}
+
+void f() {
+  _E.v;
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 32, 4),
+    ]);
+  }
+
+  test_privateEnum_privateStaticMethod_isUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+  static void _foo() {}
+}
+
+void f() {
+  _E.v;
+  _E._foo();
+}
+''');
+  }
+
+  test_privateEnum_privateStaticMethod_notUsed() async {
+    await assertErrorsInCode(r'''
+enum _E {
+  v;
+  static void _foo() {}
+}
+
+void f() {
+  _E.v;
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 29, 4),
+    ]);
+  }
+
+  test_privateEnum_privateStaticSetter_isUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+  static set _foo(int _) {}
+}
+
+void f() {
+  _E.v;
+  _E._foo = 0;
+}
+''');
+  }
+
+  test_privateEnum_privateStaticSetter_notUsed() async {
+    await assertErrorsInCode(r'''
+enum _E {
+  v;
+  static set _foo(int _) {}
+}
+
+void f() {
+  _E.v;
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 28, 4),
+    ]);
+  }
+
+  test_privateEnum_publicConstructor_notUsed() async {
+    await assertErrorsInCode(r'''
+enum _E {
+  v.foo();
+  const _E.foo();
+  const _E.bar();
+}
+
+void f() {
+  _E.v;
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 50, 3),
+    ]);
+  }
+
+  test_privateEnum_publicInstanceGetter_notUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+  int get foo => 0;
+}
+
+void f() {
+  _E.v;
+}
+''');
+  }
+
+  test_privateEnum_publicInstanceMethod_notUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+  void foo() {}
+}
+
+void f() {
+  _E.v;
+}
+''');
+  }
+
+  test_privateEnum_publicInstanceMethod_optionalNamedParameter_notUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+  void foo({int? a}) {}
+}
+
+void f() {
+  _E.v.foo();
+}
+''');
+  }
+
+  test_privateEnum_publicInstanceMethod_optionalPositionalParameter_notUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+  void foo([int? a]) {}
+}
+
+void f() {
+  _E.v.foo();
+}
+''');
+  }
+
+  test_privateEnum_publicInstanceSetter_notUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+  set foo(int _) {}
+}
+
+void f() {
+  _E.v;
+}
+''');
+  }
+
+  test_privateEnum_publicStaticGetter_isUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+  static int get foo => 0;
+}
+
+void f() {
+  _E.v;
+  _E.foo;
+}
+''');
+  }
+
+  test_privateEnum_publicStaticGetter_notUsed() async {
+    await assertErrorsInCode(r'''
+enum _E {
+  v;
+  static int get foo => 0;
+}
+
+void f() {
+  _E.v;
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 32, 3),
+    ]);
+  }
+
+  test_privateEnum_publicStaticMethod_isUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+  static void foo() {}
+}
+
+void f() {
+  _E.v;
+  _E.foo();
+}
+''');
+  }
+
+  test_privateEnum_publicStaticMethod_notUsed() async {
+    await assertErrorsInCode(r'''
+enum _E {
+  v;
+  static void foo() {}
+}
+
+void f() {
+  _E.v;
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 29, 3),
+    ]);
+  }
+
+  test_privateEnum_publicStaticSetter_isUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+  static set foo(int _) {}
+}
+
+void f() {
+  _E.v;
+  _E.foo = 0;
+}
+''');
+  }
+
+  test_privateEnum_publicStaticSetter_notUsed() async {
+    await assertErrorsInCode(r'''
+enum _E {
+  v;
+  static set foo(int _) {}
+}
+
+void f() {
+  _E.v;
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 28, 3),
+    ]);
+  }
+
+  test_publicEnum_privateConstructor_isUsed_redirect() async {
+    await assertNoErrorsInCode(r'''
+enum E {
+  v._foo();
+  const E._foo() : this._bar();
+  const E._bar();
+}
+''');
+  }
+
+  test_publicEnum_privateConstructor_notUsed() async {
+    await assertErrorsInCode(r'''
+enum E {
+  v._foo();
+  const E._foo();
+  const E._bar();
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 49, 4),
+    ]);
+  }
+
+  test_publicEnum_privateStaticGetter_isUsed() async {
+    await assertNoErrorsInCode(r'''
+enum E {
+  v;
+  static int get _foo => 0;
+}
+
+void f() {
+  E._foo;
+}
+''');
+  }
+
+  test_publicEnum_privateStaticGetter_notUsed() async {
+    await assertErrorsInCode(r'''
+enum E {
+  v;
+  static int get _foo => 0;
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 31, 4),
+    ]);
+  }
+
+  test_publicEnum_privateStaticMethod_isUsed() async {
+    await assertNoErrorsInCode(r'''
+enum E {
+  v;
+  static void _foo() {}
+}
+
+void f() {
+  E._foo();
+}
+''');
+  }
+
+  test_publicEnum_privateStaticMethod_notUsed() async {
+    await assertErrorsInCode(r'''
+enum E {
+  v;
+  static void _foo() {}
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 28, 4),
+    ]);
+  }
+
+  test_publicEnum_privateStaticSetter_isUsed() async {
+    await assertNoErrorsInCode(r'''
+enum E {
+  v;
+  static set _foo(int _) {}
+}
+
+void f() {
+  E._foo = 0;
+}
+''');
+  }
+
+  test_publicEnum_privateStaticSetter_notUsed() async {
+    await assertErrorsInCode(r'''
+enum E {
+  v;
+  static set _foo(int _) {}
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 27, 4),
+    ]);
+  }
+
+  test_publicEnum_publicConstructor_isUsed_generic() async {
+    await assertNoErrorsInCode(r'''
+enum E<T> {
+  v1<int>.named(),
+  v2<int>.renamed();
+
+  const E.named();
+  const E.renamed() : this.named();
+}
+''');
+  }
+
+  test_publicEnum_publicConstructor_isUsed_redirect() async {
+    await assertNoErrorsInCode(r'''
+enum E {
+  v.foo();
+  const E.foo() : this.bar();
+  const E.bar();
+}
+''');
+  }
+
+  test_publicEnum_publicConstructor_notUsed() async {
+    await assertErrorsInCode(r'''
+enum E {
+  v.foo();
+  const E.foo();
+  const E.bar();
+  factory E.baz() => throw 0;
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 47, 3),
+    ]);
+  }
+
+  test_publicEnum_publicStaticGetter_notUsed() async {
+    await assertNoErrorsInCode(r'''
+enum E {
+  v;
+  static int get foo => 0;
+}
+''');
+  }
+
+  test_publicEnum_publicStaticMethod_notUsed() async {
+    await assertNoErrorsInCode(r'''
+enum E {
+  v;
+  static void foo() {}
+}
+''');
+  }
+
+  test_publicEnum_publicStaticSetter_notUsed() async {
+    await assertNoErrorsInCode(r'''
+enum E {
+  v;
+  static set foo(int _) {}
+}
+''');
+  }
+
   test_typeAlias_interfaceType_isUsed_typeName_isExpression() async {
     await assertNoErrorsInCode(r'''
 typedef _A = List<int>;
diff --git a/pkg/analyzer/test/src/diagnostics/unused_field_test.dart b/pkg/analyzer/test/src/diagnostics/unused_field_test.dart
index 5896e6a..adef7a0 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_field_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_field_test.dart
@@ -85,27 +85,6 @@
 ''');
   }
 
-  test_isUsed_privateEnum_publicValue() async {
-    await assertNoErrorsInCode(r'''
-enum _Foo {a, b}
-f() => print('${_Foo.a}${_Foo.b}');
-''');
-  }
-
-  test_isUsed_privateEnum_values() async {
-    await assertNoErrorsInCode(r'''
-enum _Foo {a}
-f() => _Foo.values;
-''');
-  }
-
-  test_isUsed_publicEnum_privateValue() async {
-    await assertNoErrorsInCode(r'''
-enum Foo {_a, _b}
-f() => print('${Foo._a}${Foo._b}');
-''');
-  }
-
   test_isUsed_publicStaticField_privateClass() async {
     await assertNoErrorsInCode(r'''
 class _A {
@@ -323,23 +302,6 @@
     ]);
   }
 
-  test_notUsed_privateEnum_publicValue() async {
-    await assertErrorsInCode(r'''
-enum _Foo {a}
-f() => _Foo;
-''', [
-      error(HintCode.UNUSED_FIELD, 11, 1),
-    ]);
-  }
-
-  test_notUsed_publicEnum_privateValue() async {
-    await assertErrorsInCode(r'''
-enum Foo {_a}
-''', [
-      error(HintCode.UNUSED_FIELD, 10, 2),
-    ]);
-  }
-
   test_notUsed_publicStaticField_privateClass() async {
     await assertErrorsInCode(r'''
 class _A {
@@ -398,4 +360,143 @@
       error(HintCode.UNUSED_FIELD, 16, 2),
     ]);
   }
+
+  test_privateEnum_publicConstant_isUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+}
+
+void f() {
+ _E.v;
+}
+''');
+  }
+
+  test_privateEnum_publicConstant_notUsed() async {
+    await assertErrorsInCode(r'''
+enum _E {
+  v;
+}
+
+void f() {
+  _E;
+}
+''', [
+      error(HintCode.UNUSED_FIELD, 12, 1),
+    ]);
+  }
+
+  test_privateEnum_publicInstanceField_notUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+  final int foo = 0;
+}
+
+void f() {
+  _E.v;
+}
+''');
+  }
+
+  test_privateEnum_publicStaticField_isUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+  static final int foo = 0;
+}
+
+void f() {
+  _E.v;
+  _E.foo;
+}
+''');
+  }
+
+  test_privateEnum_publicStaticField_notUsed() async {
+    await assertErrorsInCode(r'''
+enum _E {
+  v;
+  static final int foo = 0;
+}
+
+void f() {
+  _E.v;
+}
+''', [
+      error(HintCode.UNUSED_FIELD, 34, 3),
+    ]);
+  }
+
+  test_privateEnum_values_isUsed() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v
+}
+
+void f() {
+  _E.values;
+}
+''');
+  }
+
+  test_privateEnum_values_isUsed_hasSetter() async {
+    await assertNoErrorsInCode(r'''
+enum _E {
+  v;
+  set foo(int _) {}
+}
+
+void f() {
+  _E.values;
+}
+''');
+  }
+
+  test_publicEnum_privateConstant_isUsed() async {
+    await assertNoErrorsInCode(r'''
+enum E {
+  _v
+}
+
+void f() {
+  E._v;
+}
+''');
+  }
+
+  test_publicEnum_privateConstant_notUsed() async {
+    await assertErrorsInCode(r'''
+enum E {
+  _v
+}
+''', [
+      error(HintCode.UNUSED_FIELD, 11, 2),
+    ]);
+  }
+
+  test_publicEnum_privateInstanceField_isUsed() async {
+    await assertNoErrorsInCode(r'''
+enum E {
+  v;
+  final int _foo = 0;
+}
+
+void f() {
+  E.v._foo;
+}
+''');
+  }
+
+  test_publicEnum_privateInstanceField_notUsed() async {
+    await assertErrorsInCode(r'''
+enum E {
+  v;
+  final int _foo = 0;
+}
+''', [
+      error(HintCode.UNUSED_FIELD, 26, 4),
+    ]);
+  }
 }
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 31e8b0f..bc151cc 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -8316,11 +8316,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -8339,11 +8334,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -8362,11 +8352,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -13553,11 +13538,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -13574,11 +13554,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -13595,11 +13570,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -15838,11 +15808,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -15859,11 +15824,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -15880,11 +15840,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -15961,11 +15916,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -16955,11 +16905,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -16976,11 +16921,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -17025,11 +16965,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -17046,11 +16981,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -17067,11 +16997,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -17354,13 +17279,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E<int>
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: ConstructorMember
-                      base: self::@enum::E::@constructor::•
-                      substitution: {T: int}
-                    staticType: null
                   staticElement: ConstructorMember
                     base: self::@enum::E::@constructor::•
                     substitution: {T: int}
@@ -17383,13 +17301,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E<String>
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: ConstructorMember
-                      base: self::@enum::E::@constructor::•
-                      substitution: {T: String}
-                    staticType: null
                   staticElement: ConstructorMember
                     base: self::@enum::E::@constructor::•
                     substitution: {T: String}
@@ -17456,11 +17367,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -17526,13 +17432,6 @@
                           type: double
                       rightBracket: > @22
                     type: E<double>
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: ConstructorMember
-                      base: self::@enum::E::@constructor::•
-                      substitution: {T: double}
-                    staticType: null
                   staticElement: ConstructorMember
                     base: self::@enum::E::@constructor::•
                     substitution: {T: double}
@@ -17593,11 +17492,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -17650,11 +17544,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -17710,11 +17599,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -17768,11 +17652,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -17838,11 +17717,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -17907,11 +17781,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -17969,11 +17838,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -18035,11 +17899,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -18101,11 +17960,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -18232,11 +18086,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -18297,11 +18146,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -18354,11 +18198,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -18419,11 +18258,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -18486,11 +18320,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -18555,13 +18384,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E<dynamic>
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: ConstructorMember
-                      base: self::@enum::E::@constructor::•
-                      substitution: {U: dynamic}
-                    staticType: null
                   staticElement: ConstructorMember
                     base: self::@enum::E::@constructor::•
                     substitution: {U: dynamic}
@@ -18627,11 +18449,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -18687,13 +18504,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E<dynamic>
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: ConstructorMember
-                      base: self::@enum::E::@constructor::•
-                      substitution: {T: dynamic}
-                    staticType: null
                   staticElement: ConstructorMember
                     base: self::@enum::E::@constructor::•
                     substitution: {T: dynamic}
@@ -18758,11 +18568,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -18820,11 +18625,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -18887,11 +18687,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -18961,11 +18756,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -19027,13 +18817,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E<dynamic>
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: ConstructorMember
-                      base: self::@enum::E::@constructor::•
-                      substitution: {T: dynamic}
-                    staticType: null
                   staticElement: ConstructorMember
                     base: self::@enum::E::@constructor::•
                     substitution: {T: dynamic}
@@ -19094,13 +18877,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E<num, num>
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: ConstructorMember
-                      base: self::@enum::E::@constructor::•
-                      substitution: {T: num, U: num}
-                    staticType: null
                   staticElement: ConstructorMember
                     base: self::@enum::E::@constructor::•
                     substitution: {T: num, U: num}
@@ -19375,11 +19151,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -19397,11 +19168,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -19477,11 +19243,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -19507,11 +19268,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -19575,11 +19331,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -19596,11 +19347,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -19654,11 +19400,6 @@
                       staticElement: self::@enum::E1
                       staticType: null
                     type: E1
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E1::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E1::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -19697,11 +19438,6 @@
                       staticElement: self::@enum::E2
                       staticType: null
                     type: E2
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E2::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E2::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -19807,11 +19543,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -19828,11 +19559,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -19849,11 +19575,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -26740,11 +26461,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -26842,11 +26558,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -26863,11 +26574,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -26899,11 +26605,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -26971,11 +26672,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -28502,11 +28198,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -28523,11 +28214,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -28552,11 +28238,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -29642,13 +29323,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E<dynamic>
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: ConstructorMember
-                      base: self::@enum::E::@constructor::•
-                      substitution: {T: dynamic}
-                    staticType: null
                   staticElement: ConstructorMember
                     base: self::@enum::E::@constructor::•
                     substitution: {T: dynamic}
@@ -29890,11 +29564,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -29911,11 +29580,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -29932,11 +29596,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -31272,11 +30931,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -31294,11 +30948,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -33318,11 +32967,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -33449,11 +33093,6 @@
                         staticElement: self::@enum::E
                         staticType: null
                       type: E
-                    period: . @0
-                    name: SimpleIdentifier
-                      token: <empty> @-1 <synthetic>
-                      staticElement: self::@enum::E::@constructor::•
-                      staticType: null
                     staticElement: self::@enum::E::@constructor::•
                   argumentList: ArgumentList
                     leftParenthesis: ( @0
@@ -33514,11 +33153,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -33616,11 +33250,6 @@
                         staticElement: self::@enum::E
                         staticType: null
                       type: E
-                    period: . @0
-                    name: SimpleIdentifier
-                      token: <empty> @-1 <synthetic>
-                      staticElement: self::@enum::E::@constructor::•
-                      staticType: null
                     staticElement: self::@enum::E::@constructor::•
                   argumentList: ArgumentList
                     leftParenthesis: ( @0
@@ -33716,11 +33345,6 @@
                         staticElement: self::@enum::E
                         staticType: null
                       type: E
-                    period: . @0
-                    name: SimpleIdentifier
-                      token: <empty> @-1 <synthetic>
-                      staticElement: self::@enum::E::@constructor::•
-                      staticType: null
                     staticElement: self::@enum::E::@constructor::•
                   argumentList: ArgumentList
                     leftParenthesis: ( @0
@@ -33884,11 +33508,6 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  period: . @0
-                  name: SimpleIdentifier
-                    token: <empty> @-1 <synthetic>
-                    staticElement: self::@enum::E::@constructor::•
-                    staticType: null
                   staticElement: self::@enum::E::@constructor::•
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
diff --git a/pkg/compiler/lib/src/js_backend/native_data.dart b/pkg/compiler/lib/src/js_backend/native_data.dart
index 2f77a5a..00ee207 100644
--- a/pkg/compiler/lib/src/js_backend/native_data.dart
+++ b/pkg/compiler/lib/src/js_backend/native_data.dart
@@ -10,197 +10,36 @@
 import '../common/elements.dart' show ElementEnvironment;
 import '../elements/entities.dart';
 import '../ir/annotations.dart';
+import '../js_model/js_world_builder.dart' show identity, JsToFrontendMap;
 import '../kernel/element_map.dart';
 import '../native/behavior.dart' show NativeBehavior;
 import '../serialization/serialization.dart';
 import '../util/util.dart';
 
-/// Basic information for native classes and js-interop libraries and classes.
-///
-/// This information is computed during loading using [NativeBasicDataBuilder].
-abstract class NativeBasicData {
-  /// Deserializes a [NativeBasicData] object from [source].
-  factory NativeBasicData.readFromDataSource(
-          DataSource source, ElementEnvironment elementEnvironment) =
-      NativeBasicDataImpl.readFromDataSource;
+class NativeBasicDataBuilder {
+  bool _closed = false;
 
-  /// Serializes this [NativeBasicData] to [sink].
-  void writeToDataSink(DataSink sink);
+  /// Tag info for native JavaScript classes names. See
+  /// [setNativeClassTagInfo].
+  final Map<ClassEntity, NativeClassTag> _nativeClassTagInfo = {};
 
-  /// Returns `true` if [cls] corresponds to a native JavaScript class.
-  ///
-  /// A class is marked as native either through the `@Native(...)` annotation
-  /// allowed for internal libraries or via the typed JavaScriptInterop
-  /// mechanism allowed for user libraries.
-  bool isNativeClass(ClassEntity element);
+  /// The JavaScript libraries implemented via typed JavaScript interop.
+  final Map<LibraryEntity, String> _jsInteropLibraries = {};
 
-  /// Returns the list of non-directive native tag words for [cls].
-  List<String> getNativeTagsOfClass(ClassEntity cls);
+  /// The JavaScript classes implemented via typed JavaScript interop.
+  final Map<ClassEntity, String> _jsInteropClasses = {};
 
-  /// Returns `true` if [cls] has a `!nonleaf` tag word.
-  bool hasNativeTagsForcedNonLeaf(ClassEntity cls);
+  /// JavaScript interop classes annotated with `@anonymous`
+  final Set<ClassEntity> _anonymousJsInteropClasses = {};
 
-  /// Returns `true` if [element] or any of its superclasses is native.
-  bool isNativeOrExtendsNative(ClassEntity element);
+  /// The JavaScript members implemented via typed JavaScript interop.
+  final Map<MemberEntity, String> _jsInteropMembers = {};
 
-  /// Returns `true` if js interop features are used.
-  bool get isJsInteropUsed;
-
-  /// Returns `true` if `allowInterop()` is invoked.
-  bool get isAllowInteropUsed;
-
-  /// Marks `allowInterop()` as used.
-  ///
-  /// [isAllowInteropUsed] is initially false on the closed world, and is only
-  /// set during codegen enqueuing.
-  void registerAllowInterop();
-
-  /// Returns `true` if [element] is a JsInterop library.
-  bool isJsInteropLibrary(LibraryEntity element);
-
-  /// Returns `true` if [element] is a JsInterop class.
-  bool isJsInteropClass(ClassEntity element);
-
-  /// Returns `true` if [element] is a JsInterop member.
-  bool isJsInteropMember(MemberEntity element);
-}
-
-/// Additional element information for native classes and methods and js-interop
-/// methods.
-///
-/// This information is computed during resolution using [NativeDataBuilder].
-abstract class NativeData extends NativeBasicData {
-  /// Deserializes a [NativeData] object from [source].
-  factory NativeData.readFromDataSource(
-          DataSource source, ElementEnvironment elementEnvironment) =
-      NativeDataImpl.readFromDataSource;
-
-  /// Serializes this [NativeData] to [sink].
-  @override
-  void writeToDataSink(DataSink sink);
-
-  /// Returns `true` if [element] corresponds to a native JavaScript member.
-  ///
-  /// A member is marked as native either through the native mechanism
-  /// (`@Native(...)` or the `native` pseudo keyword) allowed for internal
-  /// libraries or via the typed JavaScriptInterop mechanism allowed for user
-  /// libraries.
-  bool isNativeMember(MemberEntity element);
-
-  /// Returns the [NativeBehavior] for calling the native [method].
-  NativeBehavior getNativeMethodBehavior(FunctionEntity method);
-
-  /// Returns the [NativeBehavior] for reading from the native [field].
-  NativeBehavior getNativeFieldLoadBehavior(FieldEntity field);
-
-  /// Returns the [NativeBehavior] for writing to the native [field].
-  NativeBehavior getNativeFieldStoreBehavior(FieldEntity field);
-
-  /// Returns `true` if the name of [element] is fixed for the generated
-  /// JavaScript.
-  bool hasFixedBackendName(MemberEntity element);
-
-  /// Computes the name for [element] to use in the generated JavaScript. This
-  /// is either given through a native annotation or a js interop annotation.
-  String getFixedBackendName(MemberEntity element);
-
-  /// Computes the name prefix for [element] to use in the generated JavaScript.
-  ///
-  /// For static and top-level members and constructors this is based on the
-  /// JavaScript names for the library and/or the enclosing class.
-  String getFixedBackendMethodPath(FunctionEntity element);
-
-  @override
-  bool isJsInteropMember(MemberEntity element);
-
-  /// Returns the explicit js interop name for library [element].
-  String getJsInteropLibraryName(LibraryEntity element);
-
-  /// Returns `true` if [element] has an `@Anonymous` annotation.
-  bool isAnonymousJsInteropClass(ClassEntity element);
-
-  /// Returns the explicit js interop name for class [element].
-  String getJsInteropClassName(ClassEntity element);
-
-  /// Returns the explicit js interop name for member [element].
-  String getJsInteropMemberName(MemberEntity element);
-
-  /// Apply JS$ escaping scheme to convert possible escaped Dart names into
-  /// JS names.
-  String computeUnescapedJSInteropName(String name);
-}
-
-abstract class NativeBasicDataBuilder {
   /// Sets the native tag info for [cls].
   ///
   /// The tag info string contains comma-separated 'words' which are either
   /// dispatch tags (having JavaScript identifier syntax) and directives that
   /// begin with `!`.
-  void setNativeClassTagInfo(ClassEntity cls, String tagInfo);
-
-  /// Marks [element] as an explicit part of js interop.
-  ///
-  /// If [name] is provided, it sets the explicit js interop name for the
-  /// library [element], other the js interop name is expected to be computed
-  /// later.
-  void markAsJsInteropLibrary(LibraryEntity element, {String name});
-
-  /// Marks [element] as an explicit part of js interop.
-  ///
-  /// If [name] is provided, it sets the explicit js interop name for the
-  /// class [element], other the js interop name is expected to be computed
-  /// later.
-  void markAsJsInteropClass(ClassEntity element,
-      {String name, bool isAnonymous = false});
-
-  /// Marks [element] as an explicit part of js interop and sets the explicit js
-  /// interop [name] for the member [element].
-  void markAsJsInteropMember(MemberEntity element, String name);
-
-  /// Creates the [NativeBasicData] object for the data collected in this
-  /// builder.
-  NativeBasicData close(ElementEnvironment environment);
-}
-
-abstract class NativeDataBuilder {
-  /// Registers the [behavior] for calling the native [method].
-  void setNativeMethodBehavior(FunctionEntity method, NativeBehavior behavior);
-
-  /// Registers the [behavior] for reading from the native [field].
-  void setNativeFieldLoadBehavior(FieldEntity field, NativeBehavior behavior);
-
-  /// Registers the [behavior] for writing to the native [field].
-  void setNativeFieldStoreBehavior(FieldEntity field, NativeBehavior behavior);
-
-  /// Sets the native [name] for the member [element].
-  ///
-  /// This name is used for [element] in the generated JavaScript.
-  void setNativeMemberName(MemberEntity element, String name);
-
-  /// Closes this builder and creates the resulting [NativeData] object.
-  NativeData close();
-}
-
-class NativeBasicDataBuilderImpl implements NativeBasicDataBuilder {
-  bool _closed = false;
-
-  /// Tag info for native JavaScript classes names. See
-  /// [setNativeClassTagInfo].
-  Map<ClassEntity, NativeClassTag> nativeClassTagInfo = {};
-
-  /// The JavaScript libraries implemented via typed JavaScript interop.
-  Map<LibraryEntity, String> jsInteropLibraries = {};
-
-  /// The JavaScript classes implemented via typed JavaScript interop.
-  Map<ClassEntity, String> jsInteropClasses = {};
-
-  /// JavaScript interop classes annotated with `@anonymous`
-  Set<ClassEntity> anonymousJsInteropClasses = {};
-
-  /// The JavaScript members implemented via typed JavaScript interop.
-  Map<MemberEntity, String> jsInteropMembers = {};
-
-  @override
   void setNativeClassTagInfo(ClassEntity cls, String tagText) {
     assert(
         !_closed,
@@ -214,17 +53,21 @@
     // [Compiler.onLibraryScanned] and thereby causes multiple calls to this
     // method.
     assert(
-        nativeClassTagInfo[cls] == null ||
-            nativeClassTagInfo[cls].text == tagText,
+        _nativeClassTagInfo[cls] == null ||
+            _nativeClassTagInfo[cls].text == tagText,
         failedAt(
             cls,
             "Native tag info set inconsistently on $cls: "
-            "Existing tag info '${nativeClassTagInfo[cls]}', "
+            "Existing tag info '${_nativeClassTagInfo[cls]}', "
             "new tag info '$tagText'."));
-    nativeClassTagInfo[cls] = NativeClassTag(tagText);
+    _nativeClassTagInfo[cls] = NativeClassTag(tagText);
   }
 
-  @override
+  /// Marks [element] as an explicit part of js interop.
+  ///
+  /// If [name] is provided, it sets the explicit js interop name for the
+  /// library [element], other the js interop name is expected to be computed
+  /// later.
   void markAsJsInteropLibrary(LibraryEntity element, {String name}) {
     assert(
         !_closed,
@@ -232,10 +75,14 @@
             element,
             "NativeBasicDataBuilder is closed. "
             "Trying to mark $element as a js-interop library."));
-    jsInteropLibraries[element] = name;
+    _jsInteropLibraries[element] = name;
   }
 
-  @override
+  /// Marks [element] as an explicit part of js interop.
+  ///
+  /// If [name] is provided, it sets the explicit js interop name for the
+  /// class [element], other the js interop name is expected to be computed
+  /// later.
   void markAsJsInteropClass(ClassEntity element,
       {String name, bool isAnonymous = false}) {
     assert(
@@ -244,13 +91,14 @@
             element,
             "NativeBasicDataBuilder is closed. "
             "Trying to mark $element as a js-interop class."));
-    jsInteropClasses[element] = name;
+    _jsInteropClasses[element] = name;
     if (isAnonymous) {
-      anonymousJsInteropClasses.add(element);
+      _anonymousJsInteropClasses.add(element);
     }
   }
 
-  @override
+  /// Marks [element] as an explicit part of js interop and sets the explicit js
+  /// interop [name] for the member [element].
   void markAsJsInteropMember(MemberEntity element, String name) {
     assert(
         !_closed,
@@ -258,20 +106,21 @@
             element,
             "NativeBasicDataBuilder is closed. "
             "Trying to mark $element as a js-interop member."));
-    jsInteropMembers[element] = name;
+    _jsInteropMembers[element] = name;
   }
 
-  @override
+  /// Creates the [NativeBasicData] object for the data collected in this
+  /// builder.
   NativeBasicData close(ElementEnvironment environment) {
     _closed = true;
-    return NativeBasicDataImpl(
+    return NativeBasicData(
         environment,
         false,
-        nativeClassTagInfo,
-        jsInteropLibraries,
-        jsInteropClasses,
-        anonymousJsInteropClasses,
-        jsInteropMembers);
+        _nativeClassTagInfo,
+        _jsInteropLibraries,
+        _jsInteropClasses,
+        _anonymousJsInteropClasses,
+        _jsInteropMembers);
   }
 
   void reopenForTesting() {
@@ -279,7 +128,10 @@
   }
 }
 
-class NativeBasicDataImpl implements NativeBasicData {
+/// Basic information for native classes and js-interop libraries and classes.
+///
+/// This information is computed during loading using [NativeBasicDataBuilder].
+class NativeBasicData {
   /// Tag used for identifying serialized [NativeBasicData] objects in a
   /// debugging data stream.
   static const String tag = 'native-basic-data';
@@ -290,30 +142,30 @@
 
   /// Tag info for native JavaScript classes names. See
   /// [setNativeClassTagInfo].
-  final Map<ClassEntity, NativeClassTag> nativeClassTagInfo;
+  final Map<ClassEntity, NativeClassTag> _nativeClassTagInfo;
 
   /// The JavaScript libraries implemented via typed JavaScript interop.
-  final Map<LibraryEntity, String> jsInteropLibraries;
+  final Map<LibraryEntity, String> _jsInteropLibraries;
 
   /// The JavaScript classes implemented via typed JavaScript interop.
-  final Map<ClassEntity, String> jsInteropClasses;
+  final Map<ClassEntity, String> _jsInteropClasses;
 
   /// JavaScript interop classes annotated with `@anonymous`
-  final Set<ClassEntity> anonymousJsInteropClasses;
+  final Set<ClassEntity> _anonymousJsInteropClasses;
 
   /// The JavaScript members implemented via typed JavaScript interop.
-  final Map<MemberEntity, String> jsInteropMembers;
+  final Map<MemberEntity, String> _jsInteropMembers;
 
-  NativeBasicDataImpl(
+  NativeBasicData(
       this._env,
       this._isAllowInteropUsed,
-      this.nativeClassTagInfo,
-      this.jsInteropLibraries,
-      this.jsInteropClasses,
-      this.anonymousJsInteropClasses,
-      this.jsInteropMembers);
+      this._nativeClassTagInfo,
+      this._jsInteropLibraries,
+      this._jsInteropClasses,
+      this._anonymousJsInteropClasses,
+      this._jsInteropMembers);
 
-  factory NativeBasicDataImpl.fromIr(
+  factory NativeBasicData.fromIr(
       KernelToElementMap map, IrAnnotationData data) {
     ElementEnvironment env = map.elementEnvironment;
     Map<ClassEntity, NativeClassTag> nativeClassTagInfo = {};
@@ -342,17 +194,12 @@
       jsInteropMembers[map.getMember(node)] = name;
     });
 
-    return NativeBasicDataImpl(
-        env,
-        false,
-        nativeClassTagInfo,
-        jsInteropLibraries,
-        jsInteropClasses,
-        anonymousJsInteropClasses,
-        jsInteropMembers);
+    return NativeBasicData(env, false, nativeClassTagInfo, jsInteropLibraries,
+        jsInteropClasses, anonymousJsInteropClasses, jsInteropMembers);
   }
 
-  factory NativeBasicDataImpl.readFromDataSource(
+  /// Deserializes a [NativeBasicData] object from [source].
+  factory NativeBasicData.readFromDataSource(
       DataSource source, ElementEnvironment elementEnvironment) {
     source.begin(tag);
     bool isAllowInteropUsed = source.readBool();
@@ -370,7 +217,7 @@
     Map<MemberEntity, String> jsInteropMembers =
         source.readMemberMap((MemberEntity member) => source.readString());
     source.end(tag);
-    return NativeBasicDataImpl(
+    return NativeBasicData(
         elementEnvironment,
         isAllowInteropUsed,
         nativeClassTagInfo,
@@ -380,68 +227,75 @@
         jsInteropMembers);
   }
 
-  @override
+  /// Serializes this [NativeBasicData] to [sink].
   void writeToDataSink(DataSink sink) {
     sink.begin(tag);
     sink.writeBool(isAllowInteropUsed);
-    sink.writeClassMap(nativeClassTagInfo, (NativeClassTag tag) {
+    sink.writeClassMap(_nativeClassTagInfo, (NativeClassTag tag) {
       sink.writeStrings(tag.names);
       sink.writeBool(tag.isNonLeaf);
     });
-    sink.writeLibraryMap(jsInteropLibraries, sink.writeString);
-    sink.writeClassMap(jsInteropClasses, sink.writeString);
-    sink.writeClasses(anonymousJsInteropClasses);
-    sink.writeMemberMap(jsInteropMembers,
+    sink.writeLibraryMap(_jsInteropLibraries, sink.writeString);
+    sink.writeClassMap(_jsInteropClasses, sink.writeString);
+    sink.writeClasses(_anonymousJsInteropClasses);
+    sink.writeMemberMap(_jsInteropMembers,
         (MemberEntity member, String name) => sink.writeString(name));
     sink.end(tag);
   }
 
-  @override
+  /// Returns `true` if `allowInterop()` is invoked.
   bool get isAllowInteropUsed => _isAllowInteropUsed;
 
-  @override
+  /// Marks `allowInterop()` as used.
+  ///
+  /// [isAllowInteropUsed] is initially false on the closed world, and is only
+  /// set during codegen enqueuing.
   void registerAllowInterop() {
     _isAllowInteropUsed = true;
   }
 
-  @override
+  /// Returns `true` if [cls] corresponds to a native JavaScript class.
+  ///
+  /// A class is marked as native either through the `@Native(...)` annotation
+  /// allowed for internal libraries or via the typed JavaScriptInterop
+  /// mechanism allowed for user libraries.
   bool isNativeClass(ClassEntity element) {
     if (isJsInteropClass(element)) return true;
-    return nativeClassTagInfo.containsKey(element);
+    return _nativeClassTagInfo.containsKey(element);
   }
 
-  @override
+  /// Returns the list of non-directive native tag words for [cls].
   List<String> getNativeTagsOfClass(ClassEntity cls) {
-    return nativeClassTagInfo[cls].names;
+    return _nativeClassTagInfo[cls].names;
   }
 
-  @override
+  /// Returns `true` if [cls] has a `!nonleaf` tag word.
   bool hasNativeTagsForcedNonLeaf(ClassEntity cls) {
-    return nativeClassTagInfo[cls].isNonLeaf;
+    return _nativeClassTagInfo[cls].isNonLeaf;
   }
 
-  @override
+  /// Returns `true` if js interop features are used.
   bool get isJsInteropUsed =>
-      jsInteropLibraries.isNotEmpty || jsInteropClasses.isNotEmpty;
+      _jsInteropLibraries.isNotEmpty || _jsInteropClasses.isNotEmpty;
 
-  @override
+  /// Returns `true` if [element] is a JsInterop library.
   bool isJsInteropLibrary(LibraryEntity element) {
-    return jsInteropLibraries.containsKey(element);
+    return _jsInteropLibraries.containsKey(element);
   }
 
-  @override
+  /// Returns `true` if [element] is a JsInterop class.
   bool isJsInteropClass(ClassEntity element) {
-    return jsInteropClasses.containsKey(element);
+    return _jsInteropClasses.containsKey(element);
   }
 
   /// Returns `true` if [element] is explicitly marked as part of JsInterop.
   bool _isJsInteropMember(MemberEntity element) {
-    return jsInteropMembers.containsKey(element);
+    return _jsInteropMembers.containsKey(element);
   }
 
-  @override
+  /// Returns `true` if [element] is a JsInterop member.
   bool isJsInteropMember(MemberEntity element) {
-    // TODO(johnniwinther): Share this with [NativeDataImpl.isJsInteropMember].
+    // TODO(johnniwinther): Share this with [NativeData.isJsInteropMember].
     if (element.isFunction ||
         element.isConstructor ||
         element.isGetter ||
@@ -462,7 +316,7 @@
     }
   }
 
-  @override
+  /// Returns `true` if [element] or any of its superclasses is native.
   bool isNativeOrExtendsNative(ClassEntity element) {
     if (element == null) return false;
     if (isNativeClass(element) || isJsInteropClass(element)) {
@@ -470,63 +324,98 @@
     }
     return isNativeOrExtendsNative(_env.getSuperClass(element));
   }
+
+  NativeBasicData convert(JsToFrontendMap map, ElementEnvironment environment) {
+    Map<ClassEntity, NativeClassTag> nativeClassTagInfo =
+        <ClassEntity, NativeClassTag>{};
+    _nativeClassTagInfo.forEach((ClassEntity cls, NativeClassTag tag) {
+      nativeClassTagInfo[map.toBackendClass(cls)] = tag;
+    });
+    Map<LibraryEntity, String> jsInteropLibraries =
+        map.toBackendLibraryMap(_jsInteropLibraries, identity);
+    Map<ClassEntity, String> jsInteropClasses =
+        map.toBackendClassMap(_jsInteropClasses, identity);
+    Set<ClassEntity> anonymousJsInteropClasses =
+        map.toBackendClassSet(_anonymousJsInteropClasses);
+    Map<MemberEntity, String> jsInteropMembers =
+        map.toBackendMemberMap(_jsInteropMembers, identity);
+    return NativeBasicData(
+        environment,
+        isAllowInteropUsed,
+        nativeClassTagInfo,
+        jsInteropLibraries,
+        jsInteropClasses,
+        anonymousJsInteropClasses,
+        jsInteropMembers);
+  }
 }
 
-class NativeDataBuilderImpl implements NativeDataBuilder {
-  final NativeBasicDataImpl _nativeBasicData;
+class NativeDataBuilder {
+  final NativeBasicData _nativeBasicData;
 
   /// The JavaScript names for native JavaScript elements implemented.
-  Map<MemberEntity, String> nativeMemberName = {};
+  final Map<MemberEntity, String> _nativeMemberName = {};
 
   /// Cache for [NativeBehavior]s for calling native methods.
-  Map<FunctionEntity, NativeBehavior> nativeMethodBehavior = {};
+  final Map<FunctionEntity, NativeBehavior> _nativeMethodBehavior = {};
 
   /// Cache for [NativeBehavior]s for reading from native fields.
-  Map<MemberEntity, NativeBehavior> nativeFieldLoadBehavior = {};
+  final Map<MemberEntity, NativeBehavior> _nativeFieldLoadBehavior = {};
 
   /// Cache for [NativeBehavior]s for writing to native fields.
-  Map<MemberEntity, NativeBehavior> nativeFieldStoreBehavior = {};
+  final Map<MemberEntity, NativeBehavior> _nativeFieldStoreBehavior = {};
 
-  NativeDataBuilderImpl(this._nativeBasicData);
+  NativeDataBuilder(this._nativeBasicData);
 
-  @override
+  /// Sets the native [name] for the member [element].
+  ///
+  /// This name is used for [element] in the generated JavaScript.
   void setNativeMemberName(MemberEntity element, String name) {
     // TODO(johnniwinther): Avoid setting this more than once. The enqueuer
     // might enqueue [element] several times (before processing it) and computes
     // name on each call to `internalAddToWorkList`.
     assert(
-        nativeMemberName[element] == null || nativeMemberName[element] == name,
+        _nativeMemberName[element] == null ||
+            _nativeMemberName[element] == name,
         failedAt(
             element,
             "Native member name set inconsistently on $element: "
-            "Existing name '${nativeMemberName[element]}', "
+            "Existing name '${_nativeMemberName[element]}', "
             "new name '$name'."));
-    nativeMemberName[element] = name;
+    _nativeMemberName[element] = name;
   }
 
-  @override
+  /// Registers the [behavior] for calling the native [method].
   void setNativeMethodBehavior(FunctionEntity method, NativeBehavior behavior) {
-    nativeMethodBehavior[method] = behavior;
+    _nativeMethodBehavior[method] = behavior;
   }
 
-  @override
+  /// Registers the [behavior] for reading from the native [field].
   void setNativeFieldLoadBehavior(FieldEntity field, NativeBehavior behavior) {
-    nativeFieldLoadBehavior[field] = behavior;
+    _nativeFieldLoadBehavior[field] = behavior;
   }
 
-  @override
+  /// Registers the [behavior] for writing to the native [field].
   void setNativeFieldStoreBehavior(FieldEntity field, NativeBehavior behavior) {
-    nativeFieldStoreBehavior[field] = behavior;
+    _nativeFieldStoreBehavior[field] = behavior;
   }
 
-  @override
-  NativeData close() => NativeDataImpl(_nativeBasicData, nativeMemberName,
-      nativeMethodBehavior, nativeFieldLoadBehavior, nativeFieldStoreBehavior);
+  /// Closes this builder and creates the resulting [NativeData] object.
+  NativeData close() => NativeData(
+      _nativeBasicData,
+      _nativeMemberName,
+      _nativeMethodBehavior,
+      _nativeFieldLoadBehavior,
+      _nativeFieldStoreBehavior);
 }
 
+/// Additional element information for native classes and methods and js-interop
+/// methods.
+///
+/// This information is computed during resolution using [NativeDataBuilder].
 // TODO(johnniwinther): Remove fields that overlap with [NativeBasicData], like
 // [anonymousJsInteropClasses].
-class NativeDataImpl implements NativeData, NativeBasicDataImpl {
+class NativeData implements NativeBasicData {
   /// Tag used for identifying serialized [NativeData] objects in a
   /// debugging data stream.
   static const String tag = 'native-data';
@@ -535,29 +424,29 @@
   /// when using JSInterop.
   static const String _jsInteropEscapePrefix = r'JS$';
 
-  final NativeBasicDataImpl _nativeBasicData;
+  final NativeBasicData _nativeBasicData;
 
   /// The JavaScript names for native JavaScript elements implemented.
-  final Map<MemberEntity, String> nativeMemberName;
+  final Map<MemberEntity, String> _nativeMemberName;
 
   /// Cache for [NativeBehavior]s for calling native methods.
-  final Map<FunctionEntity, NativeBehavior> nativeMethodBehavior;
+  final Map<FunctionEntity, NativeBehavior> _nativeMethodBehavior;
 
   /// Cache for [NativeBehavior]s for reading from native fields.
-  final Map<MemberEntity, NativeBehavior> nativeFieldLoadBehavior;
+  final Map<MemberEntity, NativeBehavior> _nativeFieldLoadBehavior;
 
   /// Cache for [NativeBehavior]s for writing to native fields.
-  final Map<MemberEntity, NativeBehavior> nativeFieldStoreBehavior;
+  final Map<MemberEntity, NativeBehavior> _nativeFieldStoreBehavior;
 
-  NativeDataImpl(
+  NativeData(
       this._nativeBasicData,
-      this.nativeMemberName,
-      this.nativeMethodBehavior,
-      this.nativeFieldLoadBehavior,
-      this.nativeFieldStoreBehavior);
+      this._nativeMemberName,
+      this._nativeMethodBehavior,
+      this._nativeFieldLoadBehavior,
+      this._nativeFieldStoreBehavior);
 
-  factory NativeDataImpl.fromIr(KernelToElementMap map, IrAnnotationData data) {
-    NativeBasicDataImpl nativeBasicData = NativeBasicDataImpl.fromIr(map, data);
+  factory NativeData.fromIr(KernelToElementMap map, IrAnnotationData data) {
+    NativeBasicData nativeBasicData = NativeBasicData.fromIr(map, data);
     Map<MemberEntity, String> nativeMemberName = {};
     Map<FunctionEntity, NativeBehavior> nativeMethodBehavior = {};
     Map<MemberEntity, NativeBehavior> nativeFieldLoadBehavior = {};
@@ -589,15 +478,12 @@
           map.getNativeBehaviorForFieldStore(node);
     });
 
-    return NativeDataImpl(
-        nativeBasicData,
-        nativeMemberName,
-        nativeMethodBehavior,
-        nativeFieldLoadBehavior,
-        nativeFieldStoreBehavior);
+    return NativeData(nativeBasicData, nativeMemberName, nativeMethodBehavior,
+        nativeFieldLoadBehavior, nativeFieldStoreBehavior);
   }
 
-  factory NativeDataImpl.readFromDataSource(
+  /// Deserializes a [NativeData] object from [source].
+  factory NativeData.readFromDataSource(
       DataSource source, ElementEnvironment elementEnvironment) {
     source.begin(tag);
     NativeBasicData nativeBasicData =
@@ -614,32 +500,29 @@
         source.readMemberMap(
             (MemberEntity member) => NativeBehavior.readFromDataSource(source));
     source.end(tag);
-    return NativeDataImpl(
-        nativeBasicData,
-        nativeMemberName,
-        nativeMethodBehavior,
-        nativeFieldLoadBehavior,
-        nativeFieldStoreBehavior);
+    return NativeData(nativeBasicData, nativeMemberName, nativeMethodBehavior,
+        nativeFieldLoadBehavior, nativeFieldStoreBehavior);
   }
 
+  /// Serializes this [NativeData] to [sink].
   @override
   void writeToDataSink(DataSink sink) {
     sink.begin(tag);
     _nativeBasicData.writeToDataSink(sink);
 
-    sink.writeMemberMap(nativeMemberName,
+    sink.writeMemberMap(_nativeMemberName,
         (MemberEntity member, String name) => sink.writeString(name));
 
-    sink.writeMemberMap(nativeMethodBehavior,
+    sink.writeMemberMap(_nativeMethodBehavior,
         (MemberEntity member, NativeBehavior behavior) {
       behavior.writeToDataSink(sink);
     });
 
-    sink.writeMemberMap(nativeFieldLoadBehavior,
+    sink.writeMemberMap(_nativeFieldLoadBehavior,
         (MemberEntity member, NativeBehavior behavior) {
       behavior.writeToDataSink(sink);
     });
-    sink.writeMemberMap(nativeFieldStoreBehavior,
+    sink.writeMemberMap(_nativeFieldStoreBehavior,
         (MemberEntity member, NativeBehavior behavior) {
       behavior.writeToDataSink(sink);
     });
@@ -661,24 +544,24 @@
   void registerAllowInterop() => _nativeBasicData.registerAllowInterop();
 
   @override
-  Map<LibraryEntity, String> get jsInteropLibraries =>
-      _nativeBasicData.jsInteropLibraries;
+  Map<LibraryEntity, String> get _jsInteropLibraries =>
+      _nativeBasicData._jsInteropLibraries;
 
   @override
-  Set<ClassEntity> get anonymousJsInteropClasses =>
-      _nativeBasicData.anonymousJsInteropClasses;
+  Set<ClassEntity> get _anonymousJsInteropClasses =>
+      _nativeBasicData._anonymousJsInteropClasses;
 
   @override
-  Map<ClassEntity, String> get jsInteropClasses =>
-      _nativeBasicData.jsInteropClasses;
+  Map<ClassEntity, String> get _jsInteropClasses =>
+      _nativeBasicData._jsInteropClasses;
 
   @override
-  Map<MemberEntity, String> get jsInteropMembers =>
-      _nativeBasicData.jsInteropMembers;
+  Map<MemberEntity, String> get _jsInteropMembers =>
+      _nativeBasicData._jsInteropMembers;
 
-  @override
+  /// Returns `true` if [element] has an `@Anonymous` annotation.
   bool isAnonymousJsInteropClass(ClassEntity element) {
-    return anonymousJsInteropClasses.contains(element);
+    return _anonymousJsInteropClasses.contains(element);
   }
 
   @override
@@ -708,24 +591,24 @@
   bool isNativeOrExtendsNative(ClassEntity element) =>
       _nativeBasicData.isNativeOrExtendsNative(element);
 
-  @override
+  /// Returns the explicit js interop name for library [element].
   String getJsInteropLibraryName(LibraryEntity element) {
-    return jsInteropLibraries[element];
+    return _jsInteropLibraries[element];
   }
 
-  @override
+  /// Returns the explicit js interop name for class [element].
   String getJsInteropClassName(ClassEntity element) {
-    return jsInteropClasses[element];
+    return _jsInteropClasses[element];
   }
 
-  @override
+  /// Returns the explicit js interop name for member [element].
   String getJsInteropMemberName(MemberEntity element) {
-    return jsInteropMembers[element];
+    return _jsInteropMembers[element];
   }
 
   @override
   bool _isJsInteropMember(MemberEntity element) {
-    return jsInteropMembers.containsKey(element);
+    return _jsInteropMembers.containsKey(element);
   }
 
   @override
@@ -750,21 +633,23 @@
     }
   }
 
-  @override
+  /// Returns `true` if the name of [element] is fixed for the generated
+  /// JavaScript.
   bool hasFixedBackendName(MemberEntity element) {
-    return isJsInteropMember(element) || nativeMemberName.containsKey(element);
+    return isJsInteropMember(element) || _nativeMemberName.containsKey(element);
   }
 
-  @override
+  /// Computes the name for [element] to use in the generated JavaScript. This
+  /// is either given through a native annotation or a js interop annotation.
   String getFixedBackendName(MemberEntity element) {
-    String name = nativeMemberName[element];
+    String name = _nativeMemberName[element];
     if (name == null && isJsInteropMember(element)) {
       // If an element isJsInterop but _isJsInterop is false that means it is
       // considered interop as the parent class is interop.
       name = element.isConstructor
           ? _jsClassNameHelper(element.enclosingClass)
           : _jsMemberNameHelper(element);
-      nativeMemberName[element] = name;
+      _nativeMemberName[element] = name;
     }
     return name;
   }
@@ -782,9 +667,9 @@
   }
 
   String _jsMemberNameHelper(MemberEntity element) {
-    String jsInteropName = jsInteropMembers[element];
+    String jsInteropName = _jsInteropMembers[element];
     assert(
-        !(jsInteropMembers.containsKey(element) && jsInteropName == null),
+        !(_jsInteropMembers.containsKey(element) && jsInteropName == null),
         failedAt(
             element,
             'Member $element is js interop but js interop name has not yet '
@@ -801,7 +686,6 @@
   /// For example: fixedBackendPath for the static method createMap in the
   /// Map class of the goog.map JavaScript library would have path
   /// "goog.maps.Map".
-  @override
   String getFixedBackendMethodPath(FunctionEntity element) {
     if (!isJsInteropMember(element)) return null;
     if (element.isInstanceMember) return 'this';
@@ -823,42 +707,48 @@
     return _jsLibraryNameHelper(element.library);
   }
 
-  @override
+  /// Returns `true` if [element] corresponds to a native JavaScript member.
+  ///
+  /// A member is marked as native either through the native mechanism
+  /// (`@Native(...)` or the `native` pseudo keyword) allowed for internal
+  /// libraries or via the typed JavaScriptInterop mechanism allowed for user
+  /// libraries.
   bool isNativeMember(MemberEntity element) {
     if (isJsInteropMember(element)) return true;
-    return nativeMemberName.containsKey(element);
+    return _nativeMemberName.containsKey(element);
   }
 
-  @override
+  /// Returns the [NativeBehavior] for calling the native [method].
   NativeBehavior getNativeMethodBehavior(FunctionEntity method) {
     assert(
-        nativeMethodBehavior.containsKey(method),
+        _nativeMethodBehavior.containsKey(method),
         failedAt(method,
             "No native method behavior has been computed for $method."));
-    return nativeMethodBehavior[method];
+    return _nativeMethodBehavior[method];
   }
 
-  @override
+  /// Returns the [NativeBehavior] for reading from the native [field].
   NativeBehavior getNativeFieldLoadBehavior(FieldEntity field) {
     assert(
-        nativeFieldLoadBehavior.containsKey(field),
+        _nativeFieldLoadBehavior.containsKey(field),
         failedAt(
             field,
             "No native field load behavior has been "
             "computed for $field."));
-    return nativeFieldLoadBehavior[field];
+    return _nativeFieldLoadBehavior[field];
   }
 
-  @override
+  /// Returns the [NativeBehavior] for writing to the native [field].
   NativeBehavior getNativeFieldStoreBehavior(FieldEntity field) {
     assert(
-        nativeFieldStoreBehavior.containsKey(field),
+        _nativeFieldStoreBehavior.containsKey(field),
         failedAt(field,
             "No native field store behavior has been computed for $field."));
-    return nativeFieldStoreBehavior[field];
+    return _nativeFieldStoreBehavior[field];
   }
 
-  @override
+  /// Apply JS$ escaping scheme to convert possible escaped Dart names into
+  /// JS names.
   String computeUnescapedJSInteropName(String name) {
     return name.startsWith(_jsInteropEscapePrefix)
         ? name.substring(_jsInteropEscapePrefix.length)
@@ -866,11 +756,37 @@
   }
 
   @override
-  Map<ClassEntity, NativeClassTag> get nativeClassTagInfo =>
-      _nativeBasicData.nativeClassTagInfo;
+  Map<ClassEntity, NativeClassTag> get _nativeClassTagInfo =>
+      _nativeBasicData._nativeClassTagInfo;
 
   @override
   ElementEnvironment get _env => _nativeBasicData._env;
+
+  @override
+  NativeData convert(JsToFrontendMap map, ElementEnvironment environment) {
+    NativeBasicData nativeBasicData =
+        _nativeBasicData.convert(map, environment);
+    Map<MemberEntity, String> nativeMemberName =
+        map.toBackendMemberMap(_nativeMemberName, identity);
+    final nativeMethodBehavior = <FunctionEntity, NativeBehavior>{};
+    _nativeMethodBehavior
+        .forEach((FunctionEntity method, NativeBehavior behavior) {
+      FunctionEntity backendMethod = map.toBackendMember(method);
+      if (backendMethod != null) {
+        // If [method] isn't used it doesn't have a corresponding backend
+        // method.
+        nativeMethodBehavior[backendMethod] = behavior.convert(map);
+      }
+    });
+    NativeBehavior _convertNativeBehavior(NativeBehavior behavior) =>
+        behavior.convert(map);
+    Map<MemberEntity, NativeBehavior> nativeFieldLoadBehavior = map
+        .toBackendMemberMap(_nativeFieldLoadBehavior, _convertNativeBehavior);
+    Map<MemberEntity, NativeBehavior> nativeFieldStoreBehavior = map
+        .toBackendMemberMap(_nativeFieldStoreBehavior, _convertNativeBehavior);
+    return NativeData(nativeBasicData, nativeMemberName, nativeMethodBehavior,
+        nativeFieldLoadBehavior, nativeFieldStoreBehavior);
+  }
 }
 
 class NativeClassTag {
diff --git a/pkg/compiler/lib/src/js_model/js_world_builder.dart b/pkg/compiler/lib/src/js_model/js_world_builder.dart
index fb5e0ef..2faf6e6 100644
--- a/pkg/compiler/lib/src/js_model/js_world_builder.dart
+++ b/pkg/compiler/lib/src/js_model/js_world_builder.dart
@@ -25,7 +25,6 @@
 import '../js_backend/runtime_types_resolution.dart';
 import '../kernel/kelements.dart';
 import '../kernel/kernel_world.dart';
-import '../native/behavior.dart';
 import '../options.dart';
 import '../universe/class_hierarchy.dart';
 import '../universe/class_set.dart';
@@ -59,7 +58,8 @@
       OutputUnitData kOutputUnitData) {
     JsToFrontendMap map = JsToFrontendMapImpl(_elementMap);
 
-    NativeData nativeData = _convertNativeData(map, closedWorld.nativeData);
+    NativeData nativeData =
+        closedWorld.nativeData.convert(map, _elementEnvironment);
     _elementMap.nativeData = nativeData;
     InterceptorData interceptorData =
         _convertInterceptorData(map, nativeData, closedWorld.interceptorData);
@@ -272,93 +272,6 @@
         isHtmlLoaded: backendUsage.isHtmlLoaded);
   }
 
-  NativeBasicData _convertNativeBasicData(
-      JsToFrontendMap map, NativeBasicDataImpl nativeBasicData) {
-    Map<ClassEntity, NativeClassTag> nativeClassTagInfo =
-        <ClassEntity, NativeClassTag>{};
-    nativeBasicData.nativeClassTagInfo
-        .forEach((ClassEntity cls, NativeClassTag tag) {
-      nativeClassTagInfo[map.toBackendClass(cls)] = tag;
-    });
-    Map<LibraryEntity, String> jsInteropLibraries =
-        map.toBackendLibraryMap(nativeBasicData.jsInteropLibraries, identity);
-    Map<ClassEntity, String> jsInteropClasses =
-        map.toBackendClassMap(nativeBasicData.jsInteropClasses, identity);
-    Set<ClassEntity> anonymousJsInteropClasses =
-        map.toBackendClassSet(nativeBasicData.anonymousJsInteropClasses);
-    Map<MemberEntity, String> jsInteropMembers =
-        map.toBackendMemberMap(nativeBasicData.jsInteropMembers, identity);
-    return NativeBasicDataImpl(
-        _elementEnvironment,
-        nativeBasicData.isAllowInteropUsed,
-        nativeClassTagInfo,
-        jsInteropLibraries,
-        jsInteropClasses,
-        anonymousJsInteropClasses,
-        jsInteropMembers);
-  }
-
-  NativeData _convertNativeData(
-      JsToFrontendMap map, NativeDataImpl nativeData) {
-    convertNativeBehaviorType(type) {
-      if (type is DartType) {
-        // TODO(johnniwinther): Avoid free variables in types. If the type
-        // pulled from a generic function type it might contain a function
-        // type variable that should probably have been replaced by its bound.
-        return map.toBackendType(type, allowFreeVariables: true);
-      }
-      assert(type is SpecialType);
-      return type;
-    }
-
-    NativeBehavior convertNativeBehavior(NativeBehavior behavior) {
-      NativeBehavior newBehavior = NativeBehavior();
-
-      for (dynamic type in behavior.typesReturned) {
-        newBehavior.typesReturned.add(convertNativeBehaviorType(type));
-      }
-      for (dynamic type in behavior.typesInstantiated) {
-        newBehavior.typesInstantiated.add(convertNativeBehaviorType(type));
-      }
-
-      newBehavior.codeTemplateText = behavior.codeTemplateText;
-      newBehavior.codeTemplate = behavior.codeTemplate;
-      newBehavior.throwBehavior = behavior.throwBehavior;
-      newBehavior.isAllocation = behavior.isAllocation;
-      newBehavior.useGvn = behavior.useGvn;
-      newBehavior.sideEffects.add(behavior.sideEffects);
-      return newBehavior;
-    }
-
-    NativeBasicData nativeBasicData = _convertNativeBasicData(map, nativeData);
-
-    Map<MemberEntity, String> nativeMemberName =
-        map.toBackendMemberMap(nativeData.nativeMemberName, identity);
-    Map<FunctionEntity, NativeBehavior> nativeMethodBehavior =
-        <FunctionEntity, NativeBehavior>{};
-    nativeData.nativeMethodBehavior
-        .forEach((FunctionEntity method, NativeBehavior behavior) {
-      FunctionEntity backendMethod = map.toBackendMember(method);
-      if (backendMethod != null) {
-        // If [method] isn't used it doesn't have a corresponding backend
-        // method.
-        nativeMethodBehavior[backendMethod] = convertNativeBehavior(behavior);
-      }
-    });
-    Map<MemberEntity, NativeBehavior> nativeFieldLoadBehavior =
-        map.toBackendMemberMap(
-            nativeData.nativeFieldLoadBehavior, convertNativeBehavior);
-    Map<MemberEntity, NativeBehavior> nativeFieldStoreBehavior =
-        map.toBackendMemberMap(
-            nativeData.nativeFieldStoreBehavior, convertNativeBehavior);
-    return NativeDataImpl(
-        nativeBasicData,
-        nativeMemberName,
-        nativeMethodBehavior,
-        nativeFieldLoadBehavior,
-        nativeFieldStoreBehavior);
-  }
-
   InterceptorData _convertInterceptorData(JsToFrontendMap map,
       NativeData nativeData, InterceptorDataImpl interceptorData) {
     Map<String, Set<MemberEntity>> interceptedMembers =
diff --git a/pkg/compiler/lib/src/kernel/kernel_strategy.dart b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
index 64f3b3c..f1a2641 100644
--- a/pkg/compiler/lib/src/kernel/kernel_strategy.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
@@ -50,8 +50,8 @@
 /// Front end strategy that loads '.dill' files and builds a resolved element
 /// model from kernel IR nodes.
 class KernelFrontendStrategy {
-  final NativeBasicDataBuilderImpl nativeBasicDataBuilder =
-      NativeBasicDataBuilderImpl();
+  final NativeBasicDataBuilder nativeBasicDataBuilder =
+      NativeBasicDataBuilder();
   NativeBasicData _nativeBasicData;
   final CompilerOptions _options;
   final CompilerTask _compilerTask;
@@ -65,7 +65,7 @@
   ModularStrategy _modularStrategy;
   IrAnnotationData _irAnnotationData;
 
-  NativeDataBuilderImpl _nativeDataBuilder;
+  NativeDataBuilder _nativeDataBuilder;
   NativeDataBuilder get nativeDataBuilder => _nativeDataBuilder;
 
   BackendUsageBuilder _backendUsageBuilder;
@@ -141,7 +141,7 @@
         commonElements,
         _elementMap.types,
         NativeClassFinder(elementEnvironment, nativeBasicData));
-    _nativeDataBuilder = NativeDataBuilderImpl(nativeBasicData);
+    _nativeDataBuilder = NativeDataBuilder(nativeBasicData);
     _customElementsResolutionAnalysis = CustomElementsResolutionAnalysis(
         elementEnvironment,
         commonElements,
diff --git a/pkg/compiler/lib/src/native/behavior.dart b/pkg/compiler/lib/src/native/behavior.dart
index bfd1de6..94d2312 100644
--- a/pkg/compiler/lib/src/native/behavior.dart
+++ b/pkg/compiler/lib/src/native/behavior.dart
@@ -9,6 +9,7 @@
 import '../elements/types.dart';
 import '../js/js.dart' as js;
 import '../js_backend/native_data.dart' show NativeBasicData;
+import '../js_model/js_world_builder.dart' show JsToFrontendMap;
 import '../options.dart';
 import '../serialization/serialization.dart';
 import '../universe/side_effects.dart' show SideEffects;
@@ -729,6 +730,34 @@
     }
     return dartTypes.dynamicType();
   }
+
+  dynamic _convertNativeBehaviorType(JsToFrontendMap map, dynamic type) {
+    if (type is DartType) {
+      // TODO(johnniwinther): Avoid free variables in types. If the type
+      // pulled from a generic function type it might contain a function
+      // type variable that should probably have been replaced by its bound.
+      return map.toBackendType(type, allowFreeVariables: true);
+    }
+    assert(type is SpecialType);
+    return type;
+  }
+
+  NativeBehavior convert(JsToFrontendMap map) {
+    final newBehavior = NativeBehavior();
+    for (dynamic type in typesReturned) {
+      newBehavior.typesReturned.add(_convertNativeBehaviorType(map, type));
+    }
+    for (dynamic type in typesInstantiated) {
+      newBehavior.typesInstantiated.add(_convertNativeBehaviorType(map, type));
+    }
+    newBehavior.codeTemplateText = codeTemplateText;
+    newBehavior.codeTemplate = codeTemplate;
+    newBehavior.throwBehavior = throwBehavior;
+    newBehavior.isAllocation = isAllocation;
+    newBehavior.useGvn = useGvn;
+    newBehavior.sideEffects.add(sideEffects);
+    return newBehavior;
+  }
 }
 
 class BehaviorBuilder {
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 1d417b8..3f926b2 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -24,18 +24,20 @@
 }
 
 /// A [FeatureOption] is both a set of flags and an option. By default, creating
-/// a [FeatureOption] will create two flags, [--$flag] and [--no-$flag]. The
-/// default behavior for a [FeatureOption] in the [canary] set is to be
-/// disabled by default unless explicity enabled or [--canary] is passed.
-/// When the [FeatureOption] is moved to [staging], the behavior flips, and by
-/// default it is enabled unless explicitly disabled or [--no-shipping] is
-/// passed. The [isNegativeFlag] bool flips things around so while in [canary]
-/// the [FeatureOption] is enabled unless explicitly disabled, and while in
-/// [staging] it is disabled unless explicitly enabled.
+/// a [FeatureOption] will create two flags, `--$flag` and `--no-$flag`. The
+/// default behavior for a [FeatureOption] in the [FeatureOptions.canary] set is
+/// to be disabled by default unless explicity enabled or `--canary` is passed.
+/// When the [FeatureOption] is moved to [FeatureOptions.shipping], the behavior
+/// flips, and by default it is enabled unless explicitly disabled or
+/// `--no-shipping` is passed. The [FeatureOption.isNegativeFlag] bool flips
+/// things around so while in canary the [FeatureOption] is enabled unless
+/// explicitly disabled, and while in [FeatureOptions.shipping] it is disabled
+/// unless explicitly enabled.
 ///
-/// Finally, mature features can be moved to [shipped], at which point we ignore
-/// the flag, but throw if the value of the flag is unexpected(i.e. if a
-/// positive flag is disabled, or a negative flag is enabled).
+/// Finally, mature features can be moved to [FeatureOptions.shipped], at which
+/// point we ignore the flag, but throw if the value of the flag is
+/// unexpected(i.e. if a positive flag is disabled, or a negative flag is
+/// enabled).
 class FeatureOption {
   final String flag;
   final bool isNegativeFlag;
diff --git a/pkg/compiler/test/model/cfe_annotations_test.dart b/pkg/compiler/test/model/cfe_annotations_test.dart
index 4377903..76eb078 100644
--- a/pkg/compiler/test/model/cfe_annotations_test.dart
+++ b/pkg/compiler/test/model/cfe_annotations_test.dart
@@ -455,7 +455,7 @@
         // in the IR component, and not just the ones queried specifically for
         // JS-interop and pragma-like annotations.
         elementMap.envIsClosed = false;
-        testAll(new NativeDataImpl.fromIr(elementMap, annotationData));
+        testAll(NativeData.fromIr(elementMap, annotationData));
       }
     }
 
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_shared.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_shared.dart
index 7eaac57..0e9f780 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_shared.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_shared.dart
@@ -315,6 +315,81 @@
               'Symbol(C.field): 42, Symbol(_field): 0}');
     });
   });
+  group('Named arguments anywhere', () {
+    var source = r'''
+      String topLevelMethod(int param1, String param2,
+              {int param3 = -1, String param4 = 'default'}) =>
+          '$param1, $param2, $param3, $param4';
+
+      class C {
+        int param1;
+        String param2;
+        int param3;
+        String param4;
+        C(this.param1, this.param2,
+            {this.param3 = -1, this.param4 = 'default'});
+
+        static String staticMethod(int param1, String param2,
+              {int param3 = -1, String param4 = 'default'}) =>
+          '$param1, $param2, $param3, $param4';
+
+        String instanceMethod(int param1, String param2,
+              {int param3 = -1, String param4 = 'default'}) =>
+          '$param1, $param2, $param3, $param4';
+
+        String toString() => '$param1, $param2, $param3, $param4';
+      }
+
+      main() {
+        String localMethod(int param1, String param2,
+              {int param3 = -1, String param4 = 'default'}) =>
+          '$param1, $param2, $param3, $param4';
+        var c = C(1, 'two');
+        // Breakpoint: bp
+        print('hello world');
+      }
+        ''';
+
+    setUpAll(() async {
+      await driver.initSource(setup, source,
+          experiments: {'named-arguments-anywhere': true});
+    });
+
+    tearDownAll(() async {
+      await driver.cleanupTest();
+    });
+
+    test('in top level method', () async {
+      await driver.check(
+          breakpointId: 'bp',
+          expression: 'topLevelMethod(param3: 3, 1, param4: "four", "two")',
+          expectedResult: '1, two, 3, four');
+    });
+    test('in local method', () async {
+      await driver.check(
+          breakpointId: 'bp',
+          expression: 'topLevelMethod(param3: 3, 1, param4: "four", "two")',
+          expectedResult: '1, two, 3, four');
+    });
+    test('in class constructor', () async {
+      await driver.check(
+          breakpointId: 'bp',
+          expression: 'C(param3: 3, 1, param4: "four", "two").toString()',
+          expectedResult: '1, two, 3, four');
+    });
+    test('in class static method', () async {
+      await driver.check(
+          breakpointId: 'bp',
+          expression: 'C.staticMethod(param3: 3, 1, param4: "four", "two")',
+          expectedResult: '1, two, 3, four');
+    });
+    test('in class instance method', () async {
+      await driver.check(
+          breakpointId: 'bp',
+          expression: 'c.instanceMethod(param3: 3, 1, param4: "four", "two")',
+          expectedResult: '1, two, 3, four');
+    });
+  });
 }
 
 /// Shared tests that are valid in legacy (before 2.12) and are agnostic to
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart
index 461cf17..c578305 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart
@@ -111,11 +111,17 @@
       this.sourceMap);
 
   static Future<TestCompiler> init(SetupCompilerOptions setup,
-      {Uri input, Uri output, Uri packages}) async {
+      {Uri input,
+      Uri output,
+      Uri packages,
+      Map<String, bool> experiments = const {}}) async {
     // Initialize the incremental compiler and module component.
     // TODO: extend this for multi-module compilations by storing separate
     // compilers/components/names per module.
     setup.options.packagesFileUri = packages;
+    setup.options.explicitExperimentalFlags.addAll(fe.parseExperimentalFlags(
+        experiments,
+        onError: (message) => throw Exception(message)));
     var compiler = DevelopmentIncrementalCompiler(setup.options, input);
     var compilerResult = await compiler.computeDelta();
     var component = compilerResult.component;
@@ -127,6 +133,7 @@
     var compilerOptions = SharedCompilerOptions(
         replCompile: true,
         moduleName: moduleName,
+        experiments: experiments,
         soundNullSafety: setup.soundNullSafety,
         emitDebugMetadata: true);
     var coreTypes = compilerResult.coreTypes;
@@ -271,7 +278,8 @@
   ///
   /// Depends on SDK artifacts (such as the sound and unsound dart_sdk.js
   /// files) generated from the 'dartdevc_test' target.
-  Future<void> initSource(SetupCompilerOptions setup, String source) async {
+  Future<void> initSource(SetupCompilerOptions setup, String source,
+      {Map<String, bool> experiments}) async {
     // Perform setup sanity checks.
     var summaryPath = setup.options.sdkSummary.toFilePath();
     if (!File(summaryPath).existsSync()) {
@@ -310,7 +318,10 @@
 
     // Initialize DDC and the incremental compiler, then perform a full compile.
     compiler = await TestCompiler.init(setup,
-        input: input, output: output, packages: packagesFile);
+        input: input,
+        output: output,
+        packages: packagesFile,
+        experiments: experiments);
 
     htmlBootstrapper = testDir.uri.resolve('bootstrapper.html');
     var bootstrapFile = File(htmlBootstrapper.toFilePath())..createSync();
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md
index 1d09a57..6f14afa 100644
--- a/pkg/vm_service/CHANGELOG.md
+++ b/pkg/vm_service/CHANGELOG.md
@@ -1,6 +1,6 @@
 # Changelog
 
-## 8.2.0-dev
+## 8.2.0
 - Update to version `3.56` of the spec.
 - Added optional `line` and `column` properties to `SourceLocation`.
 - Added a new `SourceReportKind`, `BranchCoverage`, which reports branch level
diff --git a/pkg/vm_service/pubspec.yaml b/pkg/vm_service/pubspec.yaml
index dc91e52..8240e95 100644
--- a/pkg/vm_service/pubspec.yaml
+++ b/pkg/vm_service/pubspec.yaml
@@ -3,7 +3,7 @@
   A library to communicate with a service implementing the Dart VM
   service protocol.
 
-version: 8.2.0-dev
+version: 8.2.0
 
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_service
 
diff --git a/tools/VERSION b/tools/VERSION
index aae6b02..6242ae8 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 140
+PRERELEASE 141
 PRERELEASE_PATCH 0
\ No newline at end of file