[element model] migrate `exhaustive_cases`, `no_default_cases`

Bug: https://github.com/dart-lang/linter/issues/5099
Change-Id: I5f5440d4aa4f4577136b2f015dc3e92e0dd67b4f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/390800
Auto-Submit: Phil Quitslund <pquitslund@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/linter/lib/src/extensions.dart b/pkg/linter/lib/src/extensions.dart
index 5e9cb7d..9939a18 100644
--- a/pkg/linter/lib/src/extensions.dart
+++ b/pkg/linter/lib/src/extensions.dart
@@ -21,11 +21,11 @@
 import 'util/dart_type_utilities.dart';
 
 class EnumLikeClassDescription {
-  final Map<DartObject, Set<FieldElement>> _enumConstants;
+  final Map<DartObject, Set<FieldElement2>> _enumConstants;
   EnumLikeClassDescription(this._enumConstants);
 
   /// Returns a fresh map of the class's enum-like constant values.
-  Map<DartObject, Set<FieldElement>> get enumConstants => {..._enumConstants};
+  Map<DartObject, Set<FieldElement2>> get enumConstants => {..._enumConstants};
 }
 
 extension AstNodeExtension on AstNode {
@@ -161,9 +161,28 @@
   /// Get all mixins, including merged augmentations.
   List<InterfaceType> get allMixins => augmented.mixins;
 
+  /// Returns whether this class is exactly [otherName] declared in
+  /// [otherLibrary].
+  bool isClass(String otherName, String otherLibrary) =>
+      name == otherName && library.name == otherLibrary;
+}
+
+extension ClassElementExtension2 on ClassElement2 {
+  bool get hasImmutableAnnotation {
+    var inheritedAndSelfElements = <InterfaceElement2>[
+      ...allSupertypes.map((t) => t.element3),
+      this,
+    ];
+
+    return inheritedAndSelfElements.any((e) => e.metadata2.hasImmutable);
+
+    // TODO(pq): update when implemented or replace w/ a better has{*} call
+    // https://github.com/dart-lang/linter/issues/4939
+    //return inheritedAndSelfElements.any((e) => e.augmented.metadata.any((e) => e.isImmutable));
+  }
+
   bool get hasSubclassInDefiningCompilationUnit {
-    var compilationUnit = library.definingCompilationUnit;
-    for (var cls in compilationUnit.classes) {
+    for (var cls in library2.classes) {
       InterfaceType? classType = cls.thisType;
       do {
         classType = classType?.superclass;
@@ -201,7 +220,7 @@
     }
 
     // With only private non-factory constructors.
-    for (var constructor in constructors) {
+    for (var constructor in constructors2) {
       if (!constructor.isPrivate || constructor.isFactory) {
         return null;
       }
@@ -211,8 +230,8 @@
 
     // And 2 or more static const fields whose type is the enclosing class.
     var enumConstantCount = 0;
-    var enumConstants = <DartObject, Set<FieldElement>>{};
-    for (var field in fields) {
+    var enumConstants = <DartObject, Set<FieldElement2>>{};
+    for (var field in fields2) {
       // Ensure static const.
       if (field.isSynthetic || !field.isConst || !field.isStatic) {
         continue;
@@ -238,29 +257,9 @@
     return EnumLikeClassDescription(enumConstants);
   }
 
-  /// Returns whether this class is exactly [otherName] declared in
-  /// [otherLibrary].
-  bool isClass(String otherName, String otherLibrary) =>
-      name == otherName && library.name == otherLibrary;
-
   bool isEnumLikeClass() => asEnumLikeClass() != null;
 }
 
-extension ClassElementExtension2 on ClassElement2 {
-  bool get hasImmutableAnnotation {
-    var inheritedAndSelfElements = <InterfaceElement2>[
-      ...allSupertypes.map((t) => t.element3),
-      this,
-    ];
-
-    return inheritedAndSelfElements.any((e) => e.metadata2.hasImmutable);
-
-    // TODO(pq): update when implemented or replace w/ a better has{*} call
-    // https://github.com/dart-lang/linter/issues/4939
-    //return inheritedAndSelfElements.any((e) => e.augmented.metadata.any((e) => e.isImmutable));
-  }
-}
-
 extension ClassMemberListExtension on List<ClassMember> {
   MethodDeclaration? getMethod(String name) => whereType<MethodDeclaration>()
       .firstWhereOrNull((node) => node.name.lexeme == name);
diff --git a/pkg/linter/lib/src/rules/exhaustive_cases.dart b/pkg/linter/lib/src/rules/exhaustive_cases.dart
index 60d98c6..07b59b2 100644
--- a/pkg/linter/lib/src/rules/exhaustive_cases.dart
+++ b/pkg/linter/lib/src/rules/exhaustive_cases.dart
@@ -4,7 +4,7 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/element2.dart';
 import 'package:analyzer/dart/element/type.dart';
 
 import '../analyzer.dart';
@@ -39,9 +39,9 @@
   void visitSwitchStatement(SwitchStatement statement) {
     var expressionType = statement.expression.staticType;
     if (expressionType is InterfaceType) {
-      var interfaceElement = expressionType.element;
+      var interfaceElement = expressionType.element3;
       // Handled in analyzer.
-      if (interfaceElement is! ClassElement) {
+      if (interfaceElement is! ClassElement2) {
         return;
       }
       var enumDescription = interfaceElement.asEnumLikeClass();
@@ -61,13 +61,13 @@
           expression = member.expression.unParenthesized;
         }
         if (expression is Identifier) {
-          var variable = expression.staticElement.variableElement;
-          if (variable is VariableElement) {
+          var variable = expression.element.variableElement;
+          if (variable is VariableElement2) {
             enumConstants.remove(variable.computeConstantValue());
           }
         } else if (expression is PropertyAccess) {
-          var variable = expression.propertyName.staticElement.variableElement;
-          if (variable is VariableElement) {
+          var variable = expression.propertyName.element.variableElement;
+          if (variable is VariableElement2) {
             enumConstants.remove(variable.computeConstantValue());
           }
         }
@@ -82,7 +82,7 @@
         var end = statement.rightParenthesis.end;
         var elements = enumConstants[constant]!;
         var preferredElement = elements.firstWhere(
-            (element) => !element.hasDeprecated,
+            (element) => !element.metadata2.hasDeprecated,
             orElse: () => elements.first);
         rule.reportLintForOffset(
           offset,
@@ -94,11 +94,11 @@
   }
 }
 
-extension on Element? {
-  Element? get variableElement {
+extension on Element2? {
+  Element2? get variableElement {
     var self = this;
-    if (self is PropertyAccessorElement) {
-      var variable = self.variable2;
+    if (self is GetterElement) {
+      var variable = self.variable3;
       if (variable != null) {
         return variable;
       }
diff --git a/pkg/linter/lib/src/rules/no_default_cases.dart b/pkg/linter/lib/src/rules/no_default_cases.dart
index 8d9779d..8d46b49 100644
--- a/pkg/linter/lib/src/rules/no_default_cases.dart
+++ b/pkg/linter/lib/src/rules/no_default_cases.dart
@@ -4,7 +4,7 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/element2.dart';
 import 'package:analyzer/dart/element/type.dart';
 
 import '../analyzer.dart';
@@ -42,9 +42,9 @@
     if (expressionType is InterfaceType) {
       for (var member in statement.members) {
         if (member is SwitchDefault) {
-          var interfaceElement = expressionType.element;
-          if (interfaceElement is EnumElement ||
-              interfaceElement is ClassElement &&
+          var interfaceElement = expressionType.element3;
+          if (interfaceElement is EnumElement2 ||
+              interfaceElement is ClassElement2 &&
                   interfaceElement.isEnumLikeClass()) {
             rule.reportLint(member);
           }