Version 2.17.0-56.0.dev

Merge commit '1708703d159b97d950b152a698afb53317cf2f78' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_matcher.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_matcher.dart
index 252ccf6..acceb63 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_matcher.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_matcher.dart
@@ -144,12 +144,26 @@
   _MatcherBuilder(this.importedUris);
 
   void buildMatchersForNode(AstNode? node) {
-    var components = _componentsForNode(node);
-    if (components == null) {
-      return;
+    if (node is ArgumentList) {
+      _buildFromArgumentList(node);
+    } else if (node is BinaryExpression) {
+      _buildFromBinaryExpression(node);
+    } else if (node is ConstructorName) {
+      _buildFromConstructorName(node);
+    } else if (node is Literal) {
+      var parent = node.parent;
+      if (parent is ArgumentList) {
+        _buildFromArgumentList(parent);
+      }
+    } else if (node is NamedType) {
+      _buildFromNamedType(node);
+    } else if (node is PrefixedIdentifier) {
+      _buildFromPrefixedIdentifier(node);
+    } else if (node is SimpleIdentifier) {
+      _buildFromSimpleIdentifier(node);
+    } else if (node is TypeArgumentList) {
+      _buildFromTypeArgumentList(node);
     }
-    var kinds = _kindsForNode(node) ?? [];
-    _addMatcher(components: components, kinds: kinds);
   }
 
   void _addMatcher(
@@ -158,58 +172,311 @@
         importedUris: importedUris, components: components, kinds: kinds));
   }
 
-  /// Return the components of the path of the element associated with the given
-  /// [node]. The components are ordered from the most local to the most global.
-  /// For example, for a constructor this would be the name of the constructor
-  /// followed by the name of the class in which the constructor is declared
-  /// (with an empty string for the unnamed constructor).
-  static List<String>? _componentsForNode(AstNode? node) {
-    if (node is SimpleIdentifier) {
-      var parent = node.parent;
-      if (parent is Label && parent.parent is NamedExpression) {
-        // The parent of the named expression is an argument list. Because we
-        // don't represent parameters as elements, the element we need to match
-        // against is the invocation containing those arguments.
-        return _componentsFromParent(parent.parent!.parent!);
-      } else if (parent is NamedType && parent.parent is ConstructorName) {
-        return ['', node.name];
-      } else if (parent is MethodDeclaration && node == parent.name) {
-        return [node.name];
-      } else if ((parent is MethodInvocation &&
-              node == parent.methodName &&
-              !_isPrefix(parent.target)) ||
-          (parent is PrefixedIdentifier &&
-              node == parent.identifier &&
-              !_isPrefix(parent.prefix)) ||
-          (parent is PropertyAccess &&
-              node == parent.propertyName &&
-              !_isPrefix(parent.target))) {
-        return _componentsFromParent(node);
+  /// Build a matcher for the element being invoked.
+  void _buildFromArgumentList(ArgumentList node) {
+    var parent = node.parent;
+    if (parent is Annotation) {
+      _addMatcher(
+        components: [parent.constructorName?.name ?? '', parent.name.name],
+        kinds: [ElementKind.constructorKind],
+      );
+      // } else if (parent is ExtensionOverride) {
+      //   // TODO(brianwilkerson) Determine whether this branch can be reached.
+      //   _buildFromExtensionOverride(parent);
+    } else if (parent is FunctionExpressionInvocation) {
+      _buildFromFunctionExpressionInvocation(parent);
+    } else if (parent is InstanceCreationExpression) {
+      _buildFromInstanceCreationExpression(parent);
+    } else if (parent is MethodInvocation) {
+      _buildFromMethodInvocation(parent);
+    } else if (parent is RedirectingConstructorInvocation) {
+      var grandparent = parent.parent;
+      if (grandparent is ConstructorDeclaration) {
+        _addMatcher(
+          components: [
+            parent.constructorName?.name ?? '',
+            grandparent.returnType.name
+          ],
+          kinds: [ElementKind.constructorKind],
+        );
       }
-      return _componentsFromIdentifier(node);
-    } else if (node is PrefixedIdentifier) {
-      var parent = node.parent;
-      if (parent is NamedType && parent.parent is ConstructorName) {
-        return ['', node.identifier.name];
+    } else if (parent is SuperConstructorInvocation) {
+      var superclassName = parent.staticElement?.enclosingElement.name;
+      if (superclassName != null) {
+        _addMatcher(
+          components: [parent.constructorName?.name ?? '', superclassName],
+          kinds: [ElementKind.constructorKind],
+        );
       }
-      return [node.identifier.name];
-    } else if (node is ConstructorName) {
-      var constructorName = node.name;
-      if (constructorName != null) {
-        return [constructorName.name];
-      }
-    } else if (node is NamedType) {
-      return [node.name.name];
-    } else if (node is TypeArgumentList) {
-      return _componentsFromParent(node);
-    } else if (node is ArgumentList) {
-      return _componentsFromParent(node);
     }
-    var parent = node?.parent;
-    if (parent is ArgumentList) {
-      return _componentsFromParent(parent);
+  }
+
+  /// Build a matcher for the operator being invoked.
+  void _buildFromBinaryExpression(BinaryExpression node) {
+    // TODO(brianwilkerson) Implement this method in order to support changes to
+    //  operators.
+  }
+
+  /// Build a matcher for the constructor being referenced.
+  void _buildFromConstructorName(ConstructorName node) {
+    // TODO(brianwilkerson) Use the static element, if there is one, in order to
+    //  get a more exact matcher.
+    // TODO(brianwilkerson) Use 'new' for the name of the unnamed constructor.
+    var constructorName = node.name?.name ?? ''; // ?? 'new';
+    var className = node.type2.name.simpleName;
+    _addMatcher(
+      components: [constructorName, className],
+      kinds: const [ElementKind.constructorKind],
+    );
+    _addMatcher(
+      components: [className],
+      kinds: const [ElementKind.classKind],
+    );
+  }
+
+  /// Build a matcher for the extension.
+  void _buildFromExtensionOverride(ExtensionOverride node) {
+    _addMatcher(
+      components: [node.extensionName.name],
+      kinds: [ElementKind.extensionKind],
+    );
+  }
+
+  /// Build a matcher for the function being invoked.
+  void _buildFromFunctionExpressionInvocation(
+      FunctionExpressionInvocation node) {
+    // TODO(brianwilkerson) This case was missed in the original implementation
+    //  and there are no tests for it at this point, but it ought to be supported.
+  }
+
+  /// Build a matcher for the constructor being invoked.
+  void _buildFromInstanceCreationExpression(InstanceCreationExpression node) {
+    _buildFromConstructorName(node.constructorName);
+  }
+
+  /// Build a matcher for the method being declared.
+  void _buildFromMethodDeclaration(MethodDeclaration node) {
+    _addMatcher(
+      components: [node.name.name],
+      kinds: [ElementKind.methodKind],
+    );
+  }
+
+  /// Build a matcher for the method being invoked.
+  void _buildFromMethodInvocation(MethodInvocation node) {
+    // TODO(brianwilkerson) Use the static element, if there is one, in order to
+    //  get a more exact matcher.
+    // var element = node.methodName.staticElement;
+    // if (element != null) {
+    //   return _buildFromElement(element);
+    // }
+    var methodName = node.methodName;
+    var targetName = _nameOfTarget(node.realTarget);
+    if (targetName != null) {
+      // If there is a target, and we know the type of the target, then we know
+      // that a method is being invoked.
+      _addMatcher(
+        components: [methodName.name, targetName],
+        kinds: [
+          ElementKind.constructorKind,
+          ElementKind.methodKind,
+        ],
+      );
+    } else if (node.realTarget != null) {
+      // If there is a target, but we don't know the type of the target, then
+      // the target type might be undefined and this might have been either a
+      // method invocation, an invocation of a function returned by a getter, or
+      // a constructor invocation prior to the type having been deleted.
+      _addMatcher(
+        components: _componentsFromIdentifier(methodName),
+        kinds: [
+          ElementKind.constructorKind,
+          ElementKind.getterKind,
+          ElementKind.methodKind,
+        ],
+      );
+    } else {
+      // If there is no target, then this might have been either a method
+      // invocation, a function invocation (of either a function or a function
+      // returned from a getter), a constructor invocation, or an extension
+      // override. If it's a constructor, then the change might have been to the
+      // class rather than an individual constructor.
+      _addMatcher(
+        components: _componentsFromIdentifier(methodName),
+        kinds: [
+          ElementKind.classKind,
+          ElementKind.constructorKind,
+          ElementKind.extensionKind,
+          ElementKind.functionKind,
+          ElementKind.getterKind,
+          ElementKind.methodKind,
+        ],
+      );
     }
-    return null;
+  }
+
+  /// Build a matcher for the type.
+  void _buildFromNamedType(NamedType node) {
+    var parent = node.parent;
+    if (parent is ConstructorName) {
+      return _buildFromConstructorName(parent);
+    }
+    // TODO(brianwilkerson) Use the static element, if there is one, in order to
+    //  get a more exact matcher.
+    _addMatcher(
+      components: [node.name.simpleName],
+      kinds: const [
+        ElementKind.classKind,
+        ElementKind.enumKind,
+        ElementKind.mixinKind,
+        ElementKind.typedefKind
+      ],
+    );
+    // TODO(brianwilkerson) Determine whether we can ever get here as a result
+    //  of having a removed unnamed constructor.
+    // _addMatcher(
+    //   components: ['', node.name.name],
+    //   kinds: const [ElementKind.constructorKind],
+    // );
+  }
+
+  /// Build a matcher for the element represented by the prefixed identifier.
+  void _buildFromPrefixedIdentifier(PrefixedIdentifier node) {
+    var parent = node.parent;
+    if (parent is NamedType) {
+      return _buildFromNamedType(parent);
+    }
+    // TODO(brianwilkerson) Use the static element, if there is one, in order to
+    //  get a more exact matcher.
+    var prefix = node.prefix;
+    if (prefix.staticElement is PrefixElement) {
+      var parent = node.parent;
+      if ((parent is NamedType && parent.parent is! ConstructorName) ||
+          (parent is PropertyAccess && parent.target == node)) {
+        _addMatcher(components: [
+          node.identifier.name
+        ], kinds: const [
+          ElementKind.classKind,
+          ElementKind.enumKind,
+          ElementKind.extensionKind,
+          ElementKind.mixinKind,
+          ElementKind.typedefKind
+        ]);
+      }
+      _addMatcher(components: [
+        node.identifier.name
+      ], kinds: const [
+        // If the old class has been removed then this might have been a
+        // constructor invocation.
+        ElementKind.constructorKind,
+        ElementKind.functionKind, // tear-off
+        ElementKind.getterKind,
+        ElementKind.setterKind,
+        ElementKind.variableKind
+      ]);
+    }
+    // It looks like we're accessing a member, so try to figure out the
+    // name of the type defining the member.
+    var targetType = node.prefix.staticType;
+    if (targetType is InterfaceType) {
+      _addMatcher(
+        components: [node.identifier.name, targetType.element.name],
+        kinds: const [
+          ElementKind.constantKind,
+          ElementKind.fieldKind,
+          ElementKind.functionKind, // tear-off
+          ElementKind.getterKind,
+          ElementKind.methodKind, // tear-off
+          ElementKind.setterKind
+        ],
+      );
+    }
+    // It looks like we're accessing a member, but we don't know what kind of
+    // member, so we include all of the member kinds.
+    var container = node.prefix.staticElement;
+    if (container is ClassElement) {
+      _addMatcher(
+        components: [node.identifier.name, container.name],
+        kinds: const [
+          ElementKind.constantKind,
+          ElementKind.fieldKind,
+          ElementKind.functionKind, // tear-off
+          ElementKind.getterKind,
+          ElementKind.methodKind, // tear-off
+          ElementKind.setterKind
+        ],
+      );
+    }
+  }
+
+  /// Build a matcher for the property being accessed.
+  void _buildFromPropertyAccess(PropertyAccess node) {
+    // TODO(brianwilkerson) Use the static element, if there is one, in order to
+    //  get a more exact matcher.
+    var propertyName = node.propertyName;
+    var targetName = _nameOfTarget(node.realTarget);
+    List<String> components;
+    if (targetName != null) {
+      components = [propertyName.name, targetName];
+    } else {
+      components = _componentsFromIdentifier(propertyName);
+    }
+    _addMatcher(
+      components: components,
+      kinds: const [
+        ElementKind.constantKind,
+        ElementKind.fieldKind,
+        ElementKind.functionKind, // tear-off, prefixed
+        ElementKind.getterKind,
+        ElementKind.methodKind, // tear-off, prefixed
+        ElementKind.setterKind
+      ],
+    );
+  }
+
+  /// Build a matcher for the element referenced by the identifier.
+  void _buildFromSimpleIdentifier(SimpleIdentifier node) {
+    // TODO(brianwilkerson) Use the static element, if there is one, in order to
+    //  get a more exact matcher.
+    var parent = node.parent;
+    if (parent is Label && parent.parent is NamedExpression) {
+      // The parent of the named expression is an argument list. Because we
+      // don't represent parameters as elements, the element we need to match
+      // against is the invocation containing those arguments.
+      _buildFromArgumentList(parent.parent!.parent as ArgumentList);
+    } else if (parent is NamedType) {
+      _buildFromNamedType(parent);
+    } else if (parent is MethodDeclaration && node == parent.name) {
+      _buildFromMethodDeclaration(parent);
+    } else if (parent is MethodInvocation &&
+        node == parent.methodName &&
+        !_isPrefix(parent.target)) {
+      _buildFromMethodInvocation(parent);
+    } else if (parent is PrefixedIdentifier && node == parent.identifier) {
+      _buildFromPrefixedIdentifier(parent);
+    } else if (parent is PropertyAccess &&
+        node == parent.propertyName &&
+        !_isPrefix(parent.target)) {
+      _buildFromPropertyAccess(parent);
+    } else {
+      // TODO(brianwilkerson) See whether the list of kinds can be specified.
+      _addMatcher(components: [node.name], kinds: []);
+    }
+  }
+
+  /// Build a matcher for the element with which the type arguments are
+  /// associated.
+  void _buildFromTypeArgumentList(TypeArgumentList node) {
+    var parent = node.parent;
+    if (parent is ExtensionOverride) {
+      _buildFromExtensionOverride(parent);
+    } else if (parent is FunctionExpressionInvocation) {
+      _buildFromFunctionExpressionInvocation(parent);
+    } else if (parent is InstanceCreationExpression) {
+      _buildFromInstanceCreationExpression(parent);
+    } else if (parent is MethodInvocation) {
+      _buildFromMethodInvocation(parent);
+    }
   }
 
   /// Return the components associated with the [identifier] when there is no
@@ -236,162 +503,11 @@
     return [identifier.name];
   }
 
-  /// Return the components for the element associated with the given [node] by
-  /// looking at the parent of the [node].
-  static List<String>? _componentsFromParent(AstNode node) {
-    var parent = node.parent;
-    if (parent is ArgumentList) {
-      parent = parent.parent;
-    }
-    if (parent is Annotation) {
-      return [parent.constructorName?.name ?? '', parent.name.name];
-    } else if (parent is ExtensionOverride) {
-      return [parent.extensionName.name];
-    } else if (parent is InstanceCreationExpression) {
-      var constructorName = parent.constructorName;
-      return [
-        constructorName.name?.name ?? '',
-        constructorName.type2.name.name
-      ];
-    } else if (parent is MethodInvocation) {
-      var methodName = parent.methodName;
-      var targetName = _nameOfTarget(parent.realTarget);
-      if (targetName != null) {
-        return [methodName.name, targetName];
-      }
-      return _componentsFromIdentifier(methodName);
-    } else if (parent is PrefixedIdentifier) {
-      var identifier = parent.identifier;
-      var targetName = _nameOfTarget(parent.prefix);
-      if (targetName != null) {
-        return [identifier.name, targetName];
-      }
-      return _componentsFromIdentifier(identifier);
-    } else if (parent is PropertyAccess) {
-      var propertyName = parent.propertyName;
-      var targetName = _nameOfTarget(parent.realTarget);
-      if (targetName != null) {
-        return [propertyName.name, targetName];
-      }
-      return _componentsFromIdentifier(propertyName);
-    } else if (parent is RedirectingConstructorInvocation) {
-      var ancestor = parent.parent;
-      if (ancestor is ConstructorDeclaration) {
-        return [parent.constructorName?.name ?? '', ancestor.returnType.name];
-      }
-    } else if (parent is SuperConstructorInvocation) {
-      var ancestor = parent.parent;
-      if (ancestor is ConstructorDeclaration) {
-        return [parent.constructorName?.name ?? '', ancestor.returnType.name];
-      }
-    }
-    return null;
-  }
-
   /// Return `true` if the [node] is a prefix
   static bool _isPrefix(AstNode? node) {
     return node is SimpleIdentifier && node.staticElement is PrefixElement;
   }
 
-  /// Return the kinds of elements that could reasonably be referenced at the
-  /// location of the [node]. If [child] is not `null` then the [node] is a
-  /// parent of the [child].
-  static List<ElementKind>? _kindsForNode(AstNode? node, {AstNode? child}) {
-    if (node is ConstructorName) {
-      return const [ElementKind.constructorKind];
-    } else if (node is ExtensionOverride) {
-      return const [ElementKind.extensionKind];
-    } else if (node is InstanceCreationExpression) {
-      return const [ElementKind.constructorKind];
-    } else if (node is Label) {
-      var argumentList = node.parent?.parent;
-      return _kindsForNode(argumentList?.parent, child: argumentList);
-    } else if (node is MethodInvocation) {
-      assert(child != null);
-      if (node.target == child) {
-        return const [
-          ElementKind.classKind,
-          ElementKind.enumKind,
-          ElementKind.mixinKind
-        ];
-      }
-      var realTarget = node.realTarget;
-      if (realTarget != null && !_isPrefix(realTarget)) {
-        return const [ElementKind.constructorKind, ElementKind.methodKind];
-      }
-      return const [
-        ElementKind.classKind,
-        ElementKind.extensionKind,
-        ElementKind.functionKind,
-        ElementKind.methodKind
-      ];
-    } else if (node is NamedType) {
-      var parent = node.parent;
-      if (parent is ConstructorName && parent.name == null) {
-        return const [ElementKind.classKind, ElementKind.constructorKind];
-      }
-      return const [
-        ElementKind.classKind,
-//        ElementKind.constructorKind,
-        ElementKind.enumKind,
-        ElementKind.mixinKind,
-        ElementKind.typedefKind
-      ];
-    } else if (node is PrefixedIdentifier) {
-      var prefix = node.prefix;
-      if (prefix == child) {
-        return const [
-          ElementKind.classKind,
-          ElementKind.enumKind,
-          ElementKind.extensionKind,
-          ElementKind.mixinKind,
-          ElementKind.typedefKind
-        ];
-      } else if (prefix.staticElement is PrefixElement) {
-        var parent = node.parent;
-        if ((parent is NamedType && parent.parent is! ConstructorName) ||
-            (parent is PropertyAccess && parent.target == node)) {
-          return const [
-            ElementKind.classKind,
-            ElementKind.enumKind,
-            ElementKind.extensionKind,
-            ElementKind.mixinKind,
-            ElementKind.typedefKind
-          ];
-        }
-        return const [
-          // If the old class has been removed then this might have been a
-          // constructor invocation.
-          ElementKind.constructorKind,
-          ElementKind.functionKind, // tear-off
-          ElementKind.getterKind,
-          ElementKind.setterKind,
-          ElementKind.variableKind
-        ];
-      }
-      return const [
-        ElementKind.constantKind,
-        ElementKind.fieldKind,
-        ElementKind.functionKind, // tear-off
-        ElementKind.getterKind,
-        ElementKind.methodKind, // tear-off
-        ElementKind.setterKind
-      ];
-    } else if (node is PropertyAccess) {
-      return const [
-        ElementKind.constantKind,
-        ElementKind.fieldKind,
-        ElementKind.functionKind, // tear-off, prefixed
-        ElementKind.getterKind,
-        ElementKind.methodKind, // tear-off, prefixed
-        ElementKind.setterKind
-      ];
-    } else if (node is SimpleIdentifier) {
-      return _kindsForNode(node.parent, child: node);
-    }
-    return null;
-  }
-
   /// Return the name of the class associated with the given [target].
   static String? _nameOfTarget(Expression? target) {
     if (target is SimpleIdentifier) {
@@ -416,3 +532,14 @@
     return null;
   }
 }
+
+extension on Identifier {
+  String get simpleName {
+    var identifier = this;
+    if (identifier is PrefixedIdentifier) {
+      // The prefix isn't part of the name of the class.
+      return identifier.identifier.name;
+    }
+    return name;
+  }
+}
diff --git a/pkg/analysis_server/test/analysis/get_hover_test.dart b/pkg/analysis_server/test/analysis/get_hover_test.dart
index 980ec6e..6d19ce9 100644
--- a/pkg/analysis_server/test/analysis/get_hover_test.dart
+++ b/pkg/analysis_server/test/analysis/get_hover_test.dart
@@ -933,6 +933,54 @@
     expect(hover.elementKind, 'parameter');
   }
 
+  Future<void>
+      test_parameter_ofConstructor_optionalPositional_super_defaultValue_explicit() async {
+    addTestFile('''
+class A {
+  A([int a = 1]);
+}
+class B extends A {
+  B([super.a = 2]);
+}
+''');
+    var hover = await prepareHover('a = 2]');
+    // element
+    expect(hover.elementDescription, '[int a = 2]');
+    expect(hover.elementKind, 'parameter');
+  }
+
+  Future<void>
+      test_parameter_ofConstructor_optionalPositional_super_defaultValue_inherited() async {
+    addTestFile('''
+class A {
+  A([int a = 1]);
+}
+class B extends A {
+  B([super.a]);
+}
+''');
+    var hover = await prepareHover('a]');
+    // element
+    expect(hover.elementDescription, '[int a = 1]');
+    expect(hover.elementKind, 'parameter');
+  }
+
+  Future<void>
+      test_parameter_ofConstructor_optionalPositional_super_defaultValue_inherited2() async {
+    addTestFile('''
+class A {
+  A([num a = 1.2]);
+}
+class B extends A{
+  B([int super.a]);
+}
+''');
+    var hover = await prepareHover('a]');
+    // element
+    expect(hover.elementDescription, '[int a]');
+    expect(hover.elementKind, 'parameter');
+  }
+
   Future<void> test_parameter_reference_fieldFormal() async {
     addTestFile('''
 class A {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/add_type_parameter_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/add_type_parameter_test.dart
index dff9c05..6839e8f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/add_type_parameter_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/add_type_parameter_test.dart
@@ -33,7 +33,7 @@
   void C() {}
 }
 ''');
-    setPackageData(_add(0, components: ['C', 'C']));
+    setPackageData(_add(0, components: ['C']));
     await resolveTestCode('''
 import '$importUri';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/element_matcher_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/element_matcher_test.dart
index 716cd55..e7a0f03 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/element_matcher_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/element_matcher_test.dart
@@ -54,8 +54,10 @@
   /// The kinds that are expected where an invocation is allowed.
   static List<ElementKind> invocationKinds = [
     ElementKind.classKind,
+    ElementKind.constructorKind,
     ElementKind.extensionKind,
     ElementKind.functionKind,
+    ElementKind.getterKind,
     ElementKind.methodKind,
   ];
 
@@ -109,7 +111,7 @@
   }
 }
 ''');
-    _assertMatcher('g;', expectedComponents: ['g', 'C']);
+    _assertMatcher('g;', expectedComponents: ['g']);
   }
 
   Future<void> test_getter_withoutTarget_unresolved() async {
@@ -149,17 +151,7 @@
   s.length;
 }
 ''');
-    // TODO(brianwilkerson) Several of these kinds don't seem to be appropriate,
-    //  so we might want to narrow down the list.
-    _assertMatcher('s', expectedComponents: [
-      's'
-    ], expectedKinds: [
-      ElementKind.classKind,
-      ElementKind.enumKind,
-      ElementKind.extensionKind,
-      ElementKind.mixinKind,
-      ElementKind.typedefKind,
-    ]);
+    _assertMatcher('s', expectedComponents: ['s'], expectedKinds: []);
   }
 
   Future<void> test_method_withoutTarget_resolved() async {
@@ -217,7 +209,7 @@
   }
 }
 ''');
-    _assertMatcher('s =', expectedComponents: ['s', 'C']);
+    _assertMatcher('s =', expectedComponents: ['s']);
   }
 
   Future<void> test_setter_withoutTarget_unresolved() async {
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 6101710..b1d7dd6 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -130,6 +130,16 @@
   }
 
   @override
+  ConstructorElement? get unnamedConstructor {
+    for (ConstructorElement element in constructors) {
+      if (element.name.isEmpty) {
+        return element;
+      }
+    }
+    return null;
+  }
+
+  @override
   T? accept<T>(ElementVisitor<T> visitor) => visitor.visitClassElement(this);
 
   @override
@@ -778,16 +788,6 @@
   }
 
   @override
-  ConstructorElement? get unnamedConstructor {
-    for (ConstructorElement element in constructors) {
-      if (element.name.isEmpty) {
-        return element;
-      }
-    }
-    return null;
-  }
-
-  @override
   void appendTo(ElementDisplayStringBuilder builder) {
     builder.writeClassElement(this);
   }
@@ -1584,23 +1584,19 @@
 
   @override
   String? get defaultValueCode {
-    return constantInitializer?.toSource();
-  }
-
-  @override
-  bool get hasDefaultValue {
-    if (super.hasDefaultValue) {
-      return true;
-    }
-    return computeConstantValue() != null;
-  }
-
-  @override
-  DartObject? computeConstantValue() {
+    final constantInitializer = this.constantInitializer;
     if (constantInitializer != null) {
-      return super.computeConstantValue();
+      return constantInitializer.toSource();
     }
 
+    if (_superConstructorParameterDefaultValue != null) {
+      return superConstructorParameter?.defaultValueCode;
+    }
+
+    return null;
+  }
+
+  DartObject? get _superConstructorParameterDefaultValue {
     var superDefault = superConstructorParameter?.computeConstantValue();
     var superDefaultType = superDefault?.type;
     var libraryElement = library;
@@ -1612,6 +1608,15 @@
 
     return null;
   }
+
+  @override
+  DartObject? computeConstantValue() {
+    if (constantInitializer != null) {
+      return super.computeConstantValue();
+    }
+
+    return _superConstructorParameterDefaultValue;
+  }
 }
 
 /// The synthetic element representing the declaration of the type `dynamic`.
@@ -2768,9 +2773,6 @@
   }
 
   @override
-  ConstructorElement? get unnamedConstructor => null;
-
-  @override
   void appendTo(ElementDisplayStringBuilder builder) {
     builder.writeEnumElement(this);
   }
diff --git a/pkg/analyzer/lib/src/dart/element/extensions.dart b/pkg/analyzer/lib/src/dart/element/extensions.dart
index ad00f5e..decbd59 100644
--- a/pkg/analyzer/lib/src/dart/element/extensions.dart
+++ b/pkg/analyzer/lib/src/dart/element/extensions.dart
@@ -103,6 +103,12 @@
   }
 }
 
+extension ExecutableElementExtension on ExecutableElement {
+  bool get isEnumConstructor {
+    return this is ConstructorElement && enclosingElement is EnumElementImpl;
+  }
+}
+
 extension ParameterElementExtensions on ParameterElement {
   /// Return [ParameterElement] with the specified properties replaced.
   ParameterElement copyWith({
diff --git a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
index 0f6da71..7145bd0 100644
--- a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
@@ -394,6 +394,15 @@
 
     node.metadata.accept(this);
     _setElementAnnotations(node.metadata, element.metadata);
+
+    var arguments = node.arguments;
+    if (arguments != null) {
+      _withElementWalker(null, () {
+        _withElementHolder(ElementHolder(element), () {
+          arguments.accept(this);
+        });
+      });
+    }
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
index 650fde4..19b68b9 100644
--- a/pkg/analyzer/lib/src/generated/declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
@@ -4,6 +4,7 @@
 
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/extensions.dart';
 
 /// Keeps track of the set of non-synthetic child elements of an element,
 /// yielding them one at a time in response to "get" method calls.
@@ -67,7 +68,9 @@
   ElementWalker.forExecutable(ExecutableElement element)
       : element = element,
         _functions = const <ExecutableElement>[],
-        _parameters = element.parameters,
+        _parameters = element.isEnumConstructor
+            ? element.parameters.skip(2).toList()
+            : element.parameters,
         _typeParameters = element.typeParameters;
 
   /// Creates an [ElementWalker] which walks the child elements of an extension
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 1e84b07..d7284f2 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1539,9 +1539,39 @@
 
   @override
   void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+    node as EnumConstantDeclarationImpl;
+
+    node.documentationComment?.accept(this);
     node.metadata.accept(this);
     checkUnreachableNode(node);
-    node.visitChildren(this);
+
+    var element = node.declaredElement as ConstFieldElementImpl;
+    var initializer = element.constantInitializer;
+    if (initializer is InstanceCreationExpression) {
+      var constructor = initializer.constructorName.staticElement;
+      node.constructorElement = constructor;
+      var arguments = node.arguments;
+      if (arguments != null) {
+        var argumentList = arguments.argumentList;
+        if (constructor != null) {
+          InferenceContext.setType(argumentList, constructor.type);
+          argumentList.correspondingStaticParameters =
+              ResolverVisitor.resolveArgumentsToParameters(
+            argumentList: argumentList,
+            parameters: constructor.parameters.skip(2).toList(),
+          );
+          for (var argument in argumentList.arguments) {
+            var parameter = argument.staticParameterElement;
+            if (parameter != null) {
+              InferenceContext.setType(argument, parameter.type);
+            }
+            argument.accept(this);
+          }
+        }
+        arguments.typeArguments?.accept(this);
+      }
+    }
+
     elementResolver.visitEnumConstantDeclaration(node);
   }
 
@@ -3039,6 +3069,7 @@
   void visitEnumMembersInScope(EnumDeclaration node) {
     node.documentationComment?.accept(this);
     node.constants.accept(this);
+    node.members.accept(this);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart
index 8bad34e..e201c44 100644
--- a/pkg/analyzer/lib/src/summary2/element_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -268,6 +268,7 @@
             name: astFactory.simpleIdentifier(
               StringToken(TokenType.STRING, element.name, -1),
             ),
+            typeArguments: constant.arguments?.typeArguments,
           ),
           Tokens.period(),
           astFactory.simpleIdentifier(
diff --git a/pkg/analyzer/lib/src/summary2/informative_data.dart b/pkg/analyzer/lib/src/summary2/informative_data.dart
index 1ae0a1c..c7f58df 100644
--- a/pkg/analyzer/lib/src/summary2/informative_data.dart
+++ b/pkg/analyzer/lib/src/summary2/informative_data.dart
@@ -1299,7 +1299,7 @@
       _writeDocumentationComment(node);
       _writeOffsets(
         metadata: node.metadata,
-        enumConstantArguments: node.arguments?.argumentList,
+        enumConstantArguments: node.arguments,
       );
     }
 
@@ -1433,7 +1433,7 @@
     NodeList<ConstructorInitializer>? constructorInitializers,
     NodeList<EnumConstantDeclaration>? enumConstants,
     TypeAnnotation? aliasedType,
-    ArgumentList? enumConstantArguments,
+    EnumConstantArguments? enumConstantArguments,
   }) {
     var collector = _OffsetsCollector();
 
@@ -1485,7 +1485,8 @@
       addTypeParameters(aliasedType.typeParameters);
       addFormalParameters(aliasedType.parameters);
     }
-    enumConstantArguments?.arguments.accept(collector);
+    enumConstantArguments?.typeArguments?.accept(collector);
+    enumConstantArguments?.argumentList.arguments.accept(collector);
     sink.writeUint30List(collector.offsets);
   }
 
@@ -1662,14 +1663,7 @@
 
   void applyToConstantInitializer(Element element) {
     if (element is ConstFieldElementImpl && element.isEnumConstant) {
-      var initializer = element.constantInitializer;
-      if (initializer is InstanceCreationExpression) {
-        var arguments = initializer.argumentList.arguments;
-        // Skip synthetic `index` and `name` arguments.
-        for (var argument in arguments.skip(2)) {
-          argument.accept(this);
-        }
-      }
+      _applyToEnumConstantInitializer(element);
     } else if (element is ConstVariableElement) {
       element.constantInitializer?.accept(this);
     }
@@ -1744,6 +1738,18 @@
       element.nameOffset = identifier.offset;
     }
   }
+
+  void _applyToEnumConstantInitializer(ConstFieldElementImpl element) {
+    var initializer = element.constantInitializer;
+    if (initializer is InstanceCreationExpression) {
+      initializer.constructorName.type2.typeArguments?.accept(this);
+      var arguments = initializer.argumentList.arguments;
+      // Skip synthetic `index` and `name` arguments.
+      for (var argument in arguments.skip(2)) {
+        argument.accept(this);
+      }
+    }
+  }
 }
 
 abstract class _OffsetsAstVisitor extends RecursiveAstVisitor<void> {
diff --git a/pkg/analyzer/lib/src/test_utilities/find_element.dart b/pkg/analyzer/lib/src/test_utilities/find_element.dart
index 25dfccc..7159665 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_element.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_element.dart
@@ -355,21 +355,34 @@
 
   ConstructorElement constructor(String name, {String? of}) {
     assert(name != '');
+
     ConstructorElement? result;
-    for (var class_ in unitElement.classes) {
-      if (of == null || class_.name == of) {
-        for (var constructor in class_.constructors) {
-          if (constructor.name == name) {
-            if (result != null) {
-              throw StateError('Not unique: $name');
-            }
-            result = constructor;
+
+    void findIn(List<ConstructorElement> constructors) {
+      for (var constructor in constructors) {
+        if (constructor.name == name) {
+          if (result != null) {
+            throw StateError('Not unique: $name');
           }
+          result = constructor;
         }
       }
     }
+
+    for (var class_ in unitElement.classes) {
+      if (of == null || class_.name == of) {
+        findIn(class_.constructors);
+      }
+    }
+
+    for (var enum_ in unitElement.enums) {
+      if (of == null || enum_.name == of) {
+        findIn(enum_.constructors);
+      }
+    }
+
     if (result != null) {
-      return result;
+      return result!;
     }
     throw StateError('Not found: $name');
   }
diff --git a/pkg/analyzer/test/src/dart/resolution/enum_test.dart b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
index 1e71eb6..ca17f7c 100644
--- a/pkg/analyzer/test/src/dart/resolution/enum_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
@@ -15,9 +15,212 @@
 
 @reflectiveTest
 class EnumDriverResolutionTest extends PubPackageResolutionTest {
-  test_field() async {
+  test_constructor_argumentList_contextType() async {
+    await assertNoErrorsInCode(r'''
+enum E {
+  v([]);
+  E(List<int> a);
+}
+''');
+
+    assertType(findNode.listLiteral('[]'), 'List<int>');
+  }
+
+  test_constructor_argumentList_namedType() async {
+    await assertNoErrorsInCode(r'''
+enum E {
+  v(<void Function(double)>[]);
+  E(Object a);
+}
+''');
+
+    assertNamedType(
+      findNode.namedType('double'),
+      doubleElement,
+      'double',
+    );
+
+    assertType(
+      findNode.genericFunctionType('void Function'),
+      'void Function(double)',
+    );
+  }
+
+  test_constructor_generic_noTypeArguments_named() async {
     await assertNoErrorsInCode(r'''
 enum E<T> {
+  v.named(42);
+  E.named(T a);
+}
+''');
+
+    assertEnumConstant(
+      findNode.enumConstantDeclaration('v'),
+      element: findElement.field('v'),
+      constructorElement: elementMatcher(
+        findElement.constructor('named'),
+        substitution: {'T': 'int'},
+      ),
+    );
+
+    assertParameterElement(
+      findNode.integerLiteral('42'),
+      elementMatcher(
+        findElement.parameter('a'),
+        substitution: {'T': 'int'},
+      ),
+    );
+  }
+
+  test_constructor_generic_noTypeArguments_unnamed() async {
+    await assertNoErrorsInCode(r'''
+enum E<T> {
+  v(42);
+  E(T a);
+}
+''');
+
+    assertEnumConstant(
+      findNode.enumConstantDeclaration('v'),
+      element: findElement.field('v'),
+      constructorElement: elementMatcher(
+        findElement.enum_('E').unnamedConstructor,
+        substitution: {'T': 'int'},
+      ),
+    );
+
+    assertParameterElement(
+      findNode.integerLiteral('42'),
+      elementMatcher(
+        findElement.parameter('a'),
+        substitution: {'T': 'int'},
+      ),
+    );
+  }
+
+  test_constructor_generic_typeArguments_named() async {
+    await assertNoErrorsInCode(r'''
+enum E<T> {
+  v<double>.named(42);
+  E.named(T a);
+}
+''');
+
+    assertEnumConstant(
+      findNode.enumConstantDeclaration('v'),
+      element: findElement.field('v'),
+      constructorElement: elementMatcher(
+        findElement.constructor('named'),
+        substitution: {'T': 'double'},
+      ),
+    );
+
+    assertNamedType(
+      findNode.namedType('double'),
+      doubleElement,
+      'double',
+    );
+
+    assertParameterElement(
+      findNode.integerLiteral('42'),
+      elementMatcher(
+        findElement.parameter('a'),
+        substitution: {'T': 'double'},
+      ),
+    );
+  }
+
+  test_constructor_notGeneric_named() async {
+    await assertNoErrorsInCode(r'''
+enum E {
+  v.named(42);
+  E.named(int a);
+}
+''');
+
+    assertEnumConstant(
+      findNode.enumConstantDeclaration('v'),
+      element: findElement.field('v'),
+      constructorElement: findElement.constructor('named'),
+    );
+
+    assertParameterElement(
+      findNode.integerLiteral('42'),
+      findElement.parameter('a'),
+    );
+  }
+
+  test_constructor_notGeneric_unnamed() async {
+    await assertNoErrorsInCode(r'''
+enum E {
+  v(42);
+  E(int a);
+}
+''');
+
+    assertEnumConstant(
+      findNode.enumConstantDeclaration('v'),
+      element: findElement.field('v'),
+      constructorElement: findElement.enum_('E').unnamedConstructor,
+    );
+
+    assertParameterElement(
+      findNode.integerLiteral('42'),
+      findElement.parameter('a'),
+    );
+  }
+
+  test_constructor_notGeneric_unnamed_implicit() async {
+    await assertNoErrorsInCode(r'''
+enum E {
+  v
+}
+''');
+
+    assertEnumConstant(
+      findNode.enumConstantDeclaration('v'),
+      element: findElement.field('v'),
+      constructorElement: findElement.enum_('E').unnamedConstructor,
+    );
+  }
+
+  test_constructor_unresolved_named() async {
+    await assertNoErrorsInCode(r'''
+enum E {
+  v.named(42);
+  E(int a);
+}
+''');
+
+    assertEnumConstant(
+      findNode.enumConstantDeclaration('v'),
+      element: findElement.field('v'),
+      constructorElement: null,
+    );
+
+    assertParameterElement(findNode.integerLiteral('42'), null);
+  }
+
+  test_constructor_unresolved_unnamed() async {
+    await assertNoErrorsInCode(r'''
+enum E {
+  v(42);
+  E.named(int a);
+}
+''');
+
+    assertEnumConstant(
+      findNode.enumConstantDeclaration('v'),
+      element: findElement.field('v'),
+      constructorElement: null,
+    );
+
+    assertParameterElement(findNode.integerLiteral('42'), null);
+  }
+
+  test_field() async {
+    await assertNoErrorsInCode(r'''
+enum E {
   v;
   final foo = 42;
 }
@@ -88,7 +291,7 @@
 
   test_method_toString() async {
     await assertNoErrorsInCode(r'''
-enum E<T> {
+enum E {
   v;
   String toString() => 'E';
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
index c02261d..384b9be 100644
--- a/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
@@ -122,7 +122,10 @@
     );
     assertParameterElement(
       indexExpression.index,
-      indexElement.parameters[0],
+      elementMatcher(
+        indexElement.parameters[0],
+        substitution: {'T': 'double'},
+      ),
     );
   }
 
@@ -230,7 +233,10 @@
     }
     assertParameterElement(
       indexExpression.index,
-      indexEqElement.parameters[0],
+      elementMatcher(
+        indexEqElement.parameters[0],
+        substitution: {'T': 'double'},
+      ),
     );
 
     var assignment = indexExpression.parent as AssignmentExpression;
@@ -426,7 +432,10 @@
     }
     assertParameterElement(
       indexExpression.index,
-      indexEqElement.parameters[0],
+      elementMatcher(
+        indexEqElement.parameters[0],
+        substitution: {'T': 'double'},
+      ),
     );
 
     var assignment = indexExpression.parent as AssignmentExpression;
@@ -444,7 +453,10 @@
     );
     assertParameterElement(
       assignment.rightHandSide,
-      indexEqElement.parameters[1],
+      elementMatcher(
+        indexEqElement.parameters[1],
+        substitution: {'T': 'double'},
+      ),
     );
   }
 
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index 35aaf17..e76b324 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -285,6 +285,15 @@
     expect(element.enclosingElement, expectedEnclosing);
   }
 
+  void assertEnumConstant(
+    EnumConstantDeclaration node, {
+    required FieldElement element,
+    required Object? constructorElement,
+  }) {
+    assertElement(node.declaredElement, element);
+    assertElement(node.constructorElement, constructorElement);
+  }
+
   Future<void> assertErrorsInCode(
       String code, List<ExpectedError> expectedErrors) async {
     addTestFile(code);
@@ -627,9 +636,9 @@
 
   void assertParameterElement(
     Expression expression,
-    ParameterElement expected,
+    Object? elementOrMatcher,
   ) {
-    expect(expression.staticParameterElement, expected);
+    assertElement(expression.staticParameterElement, elementOrMatcher);
   }
 
   void assertParameterElementType(FormalParameter node, String expected) {
diff --git a/pkg/analyzer/test/src/diagnostics/instantiate_enum_test.dart b/pkg/analyzer/test/src/diagnostics/instantiate_enum_test.dart
index 0fd804c..4fc7b70 100644
--- a/pkg/analyzer/test/src/diagnostics/instantiate_enum_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/instantiate_enum_test.dart
@@ -22,7 +22,10 @@
   return const E();
 }
 ''', [
+      error(CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, 43, 9),
+      error(CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, 43, 9),
       error(CompileTimeErrorCode.INSTANTIATE_ENUM, 49, 1),
+      error(CompileTimeErrorCode.NOT_ENOUGH_POSITIONAL_ARGUMENTS, 50, 2),
     ]);
   }
 
@@ -34,6 +37,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.INSTANTIATE_ENUM, 47, 1),
+      error(CompileTimeErrorCode.NOT_ENOUGH_POSITIONAL_ARGUMENTS, 48, 2),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 3e35554..4d9cd96 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -17748,6 +17748,109 @@
 ''');
   }
 
+  test_enum_constant_typeArguments() async {
+    var library = await checkLibrary(r'''
+enum E<T> {
+  v<double>(42);
+  E(T a);
+}
+''');
+    checkElementText(library, r'''
+library
+  definingUnit
+    enums
+      enum E @5
+        typeParameters
+          covariant T @7
+            defaultType: dynamic
+        supertype: Enum
+        fields
+          static const enumConstant v @14
+            type: E<double>
+            constantInitializer
+              InstanceCreationExpression
+                argumentList: ArgumentList
+                  arguments
+                    IntegerLiteral
+                      literal: 0 @0
+                      staticType: int
+                    SimpleStringLiteral
+                      literal: 'v' @0
+                    IntegerLiteral
+                      literal: 42 @24
+                      staticType: double
+                  leftParenthesis: ( @0
+                  rightParenthesis: ) @0
+                constructorName: ConstructorName
+                  name: SimpleIdentifier
+                    staticElement: ConstructorMember
+                      base: self::@enum::E::@constructor::•
+                      substitution: {T: double}
+                    staticType: null
+                    token:  @-1
+                  period: . @0
+                  staticElement: ConstructorMember
+                    base: self::@enum::E::@constructor::•
+                    substitution: {T: double}
+                  type: NamedType
+                    name: SimpleIdentifier
+                      staticElement: self::@enum::E
+                      staticType: null
+                      token: E @-1
+                    type: E<double>
+                    typeArguments: TypeArgumentList
+                      arguments
+                        NamedType
+                          name: SimpleIdentifier
+                            staticElement: dart:core::@class::double
+                            staticType: null
+                            token: double @16
+                          type: double
+                      leftBracket: < @15
+                      rightBracket: > @22
+                staticType: E<double>
+          synthetic static const values @-1
+            type: List<E<dynamic>>
+            constantInitializer
+              ListLiteral
+                elements
+                  SimpleIdentifier
+                    staticElement: self::@enum::E::@getter::v
+                    staticType: E<double>
+                    token: v @-1
+                leftBracket: [ @0
+                rightBracket: ] @0
+                staticType: List<E<dynamic>>
+          synthetic final index @-1
+            type: int
+          synthetic final _name @-1
+            type: String
+        constructors
+          @31
+            parameters
+              requiredPositional final this.index @-1
+                type: int
+                field: self::@enum::E::@field::index
+              requiredPositional final this._name @-1
+                type: String
+                field: self::@enum::E::@field::_name
+              requiredPositional a @35
+                type: T
+        accessors
+          synthetic static get v @-1
+            returnType: E<double>
+          synthetic static get values @-1
+            returnType: List<E<dynamic>>
+          synthetic get index @-1
+            returnType: int
+          synthetic get _name @-1
+            returnType: String
+        methods
+          synthetic toString @-1
+            returnType: String
+''');
+  }
+
   test_enum_constant_underscore() async {
     var library = await checkLibrary('''
 enum E {
diff --git a/pkg/analyzer/test/verify_diagnostics_test.dart b/pkg/analyzer/test/verify_diagnostics_test.dart
index 873f700..84ce4b3 100644
--- a/pkg/analyzer/test/verify_diagnostics_test.dart
+++ b/pkg/analyzer/test/verify_diagnostics_test.dart
@@ -50,6 +50,8 @@
     // (such as `JSBool b;`), but that would complicate the example.
     'CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY',
     // Produces two diagnostics when it should only produce one.
+    'CompileTimeErrorCode.INSTANTIATE_ENUM',
+    // Produces two diagnostics when it should only produce one.
     'CompileTimeErrorCode.INVALID_URI',
     // Produces two diagnostics when it should only produce one.
     'CompileTimeErrorCode.INVALID_USE_OF_NULL_VALUE',
diff --git a/tools/VERSION b/tools/VERSION
index a4cf01a..5d43e34 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 55
+PRERELEASE 56
 PRERELEASE_PATCH 0
\ No newline at end of file