Fixes for enum constants in available declarations.

R=brianwilkerson@google.com

Change-Id: Ic1ad3846ecf82cdd5f1f0b0d0d5a69b0d5c43d81
Reviewed-on: https://dart-review.googlesource.com/c/92763
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/services/available_declarations.dart b/pkg/analyzer/lib/src/services/available_declarations.dart
index e70747d..0dea690 100644
--- a/pkg/analyzer/lib/src/services/available_declarations.dart
+++ b/pkg/analyzer/lib/src/services/available_declarations.dart
@@ -78,9 +78,9 @@
   @override
   String toString() {
     if (name2 == null) {
-      return '($name, $kind)';
+      return '($kind, $name)';
     } else {
-      return '($name, $name2, $kind)';
+      return '($kind, $name, $name2)';
     }
   }
 }
@@ -832,6 +832,9 @@
     if (d.docComplete != null) {
       fieldMask |= fieldDocMask;
     }
+    if (d.name2 != null) {
+      fieldMask |= fieldName2Mask;
+    }
     if (d.parameters != null) {
       fieldMask |= fieldParametersMask;
     }
@@ -878,12 +881,13 @@
 
   Iterable<Declaration> filter(List<Declaration> declarations) {
     return declarations.where((d) {
+      var name = d.name2 ?? d.name;
       for (var combinator in combinators) {
         if (combinator.shows.isNotEmpty) {
-          if (!combinator.shows.contains(d.name)) return false;
+          if (!combinator.shows.contains(name)) return false;
         }
         if (combinator.hides.isNotEmpty) {
-          if (combinator.hides.contains(d.name)) return false;
+          if (combinator.hides.contains(name)) return false;
         }
       }
       return true;
@@ -1451,7 +1455,7 @@
   static Set<Declaration> _newDeclarationSet() {
     return HashSet<Declaration>(
       hashCode: (e) => e.name.hashCode,
-      equals: (a, b) => a.name == b.name,
+      equals: (a, b) => a.name == b.name && a.name2 == b.name2,
     );
   }
 }
diff --git a/pkg/analyzer/test/src/services/available_declarations_test.dart b/pkg/analyzer/test/src/services/available_declarations_test.dart
index aa2d4a4..9b07610 100644
--- a/pkg/analyzer/test/src/services/available_declarations_test.dart
+++ b/pkg/analyzer/test/src/services/available_declarations_test.dart
@@ -187,6 +187,7 @@
 export 'a.dart' show A;
 part 'b.dart';
 class C {}
+enum E {v}
 ''');
 
     // The byte store is empty, fill it.
@@ -202,6 +203,8 @@
       _ExpectedDeclaration.class_('A'),
       _ExpectedDeclaration.class_('B'),
       _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.enum_('E'),
+      _ExpectedDeclaration.enumConstant('v', 'E'),
     ]);
   }
 
@@ -234,15 +237,15 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration('A', DeclarationKind.CLASS),
-      _ExpectedDeclaration('B', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
     ]);
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration('B', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('B'),
     ]);
     _assertHasNoLibrary('package:test/c.dart');
     _assertHasLibrary('package:test/d.dart', declarations: [
-      _ExpectedDeclaration('D', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('D'),
     ]);
 
     newFile(c, content: r'''
@@ -252,19 +255,19 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration('A', DeclarationKind.CLASS),
-      _ExpectedDeclaration('B', DeclarationKind.CLASS),
-      _ExpectedDeclaration('C', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C'),
     ]);
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration('B', DeclarationKind.CLASS),
-      _ExpectedDeclaration('C', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C'),
     ]);
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration('C', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('C'),
     ]);
     _assertHasLibrary('package:test/d.dart', declarations: [
-      _ExpectedDeclaration('D', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('D'),
     ]);
   }
 
@@ -279,7 +282,7 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration('A', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('A'),
     ]);
     _assertHasNoLibrary('package:test/b.dart');
 
@@ -290,10 +293,10 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration('A', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('A'),
     ]);
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration('B', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('B'),
     ]);
 
     var librariesObject = declarationsContext.getLibraries(
@@ -321,11 +324,11 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration('A', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('A'),
     ]);
     _assertHasNoLibrary('package:test/b.dart');
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration('C', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('C'),
     ]);
 
     newFile(b, content: r'''
@@ -336,12 +339,12 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration('A', DeclarationKind.CLASS),
-      _ExpectedDeclaration('B', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
     ]);
     _assertHasNoLibrary('package:test/b.dart');
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration('C', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('C'),
     ]);
   }
 
@@ -481,19 +484,19 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration('A', DeclarationKind.CLASS),
-      _ExpectedDeclaration('B', DeclarationKind.CLASS),
-      _ExpectedDeclaration('C', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C'),
     ]);
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration('B', DeclarationKind.CLASS),
-      _ExpectedDeclaration('C', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C'),
     ]);
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration('C', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('C'),
     ]);
     _assertHasLibrary('package:test/d.dart', declarations: [
-      _ExpectedDeclaration('D', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('D'),
     ]);
 
     deleteFile(c);
@@ -501,15 +504,15 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration('A', DeclarationKind.CLASS),
-      _ExpectedDeclaration('B', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
     ]);
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration('B', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('B'),
     ]);
     _assertHasNoLibrary('package:test/c.dart');
     _assertHasLibrary('package:test/d.dart', declarations: [
-      _ExpectedDeclaration('D', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('D'),
     ]);
   }
 
@@ -553,11 +556,11 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration('A', DeclarationKind.CLASS),
-      _ExpectedDeclaration('B', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
     ]);
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration('C', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('C'),
     ]);
 
     deleteFile(b);
@@ -565,10 +568,10 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration('A', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('A'),
     ]);
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration('C', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('C'),
     ]);
   }
 
@@ -596,19 +599,19 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration('A', DeclarationKind.CLASS),
-      _ExpectedDeclaration('B', DeclarationKind.CLASS),
-      _ExpectedDeclaration('C', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C'),
     ]);
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration('B', DeclarationKind.CLASS),
-      _ExpectedDeclaration('C', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C'),
     ]);
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration('C', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('C'),
     ]);
     _assertHasLibrary('package:test/d.dart', declarations: [
-      _ExpectedDeclaration('D', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('D'),
     ]);
 
     newFile(c, content: r'''
@@ -618,19 +621,19 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration('A', DeclarationKind.CLASS),
-      _ExpectedDeclaration('B', DeclarationKind.CLASS),
-      _ExpectedDeclaration('C2', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C2'),
     ]);
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration('B', DeclarationKind.CLASS),
-      _ExpectedDeclaration('C2', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C2'),
     ]);
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration('C2', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('C2'),
     ]);
     _assertHasLibrary('package:test/d.dart', declarations: [
-      _ExpectedDeclaration('D', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('D'),
     ]);
   }
 
@@ -648,10 +651,10 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration('A', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('A'),
     ]);
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration('B', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('B'),
     ]);
 
     newFile(a, content: r'''
@@ -661,10 +664,10 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration('A2', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('A2'),
     ]);
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration('B', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('B'),
     ]);
   }
 
@@ -688,11 +691,11 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration('A', DeclarationKind.CLASS),
-      _ExpectedDeclaration('B', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
     ]);
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration('C', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('C'),
     ]);
 
     newFile(b, content: r'''
@@ -703,11 +706,11 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration('A', DeclarationKind.CLASS),
-      _ExpectedDeclaration('B2', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B2'),
     ]);
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration('C', DeclarationKind.CLASS),
+      _ExpectedDeclaration.class_('C'),
     ]);
   }
 }
@@ -1356,6 +1359,23 @@
     ]);
   }
 
+  test_combinators_show_enum() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+enum E1 {a}
+enum E2 {b}
+''');
+    newFile('/home/test/lib/test.dart', content: r'''
+export 'a.dart' show E1;
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/test.dart', declarations: [
+      _ExpectedDeclaration.enum_('E1'),
+      _ExpectedDeclaration.enumConstant('a', 'E1'),
+    ]);
+  }
+
   test_cycle() async {
     newFile('/home/test/lib/a.dart', content: r'''
 export 'b.dart';
@@ -1390,6 +1410,24 @@
     ]);
   }
 
+  test_enum() async {
+    newFile('/home/test/lib/test.dart', content: r'''
+enum E1 {a, b}
+enum E2 {a, b}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/test.dart', declarations: [
+      _ExpectedDeclaration.enum_('E1'),
+      _ExpectedDeclaration.enumConstant('a', 'E1'),
+      _ExpectedDeclaration.enumConstant('b', 'E1'),
+      _ExpectedDeclaration.enum_('E2'),
+      _ExpectedDeclaration.enumConstant('a', 'E2'),
+      _ExpectedDeclaration.enumConstant('b', 'E2'),
+    ]);
+  }
+
   test_missing() async {
     newFile('/home/test/lib/test.dart', content: r'''
 export 'a.dart';
@@ -2042,7 +2080,9 @@
     expect(
       library.declarations,
       contains(predicate((Declaration d) {
-        return d.name == expected.name && d.kind == expected.kind;
+        return d.name == expected.name &&
+            d.name2 == expected.name2 &&
+            d.kind == expected.kind;
       })),
       reason: '$expected',
     );
@@ -2107,31 +2147,42 @@
 }
 
 class _ExpectedDeclaration {
-  final String name;
   final DeclarationKind kind;
+  final String name;
+  final String name2;
 
-  _ExpectedDeclaration(this.name, this.kind);
+  _ExpectedDeclaration(this.kind, this.name, this.name2);
 
-  _ExpectedDeclaration.class_(String name) : this(name, DeclarationKind.CLASS);
+  _ExpectedDeclaration.class_(String name)
+      : this(DeclarationKind.CLASS, name, null);
 
   _ExpectedDeclaration.classTypeAlias(String name)
-      : this(name, DeclarationKind.CLASS_TYPE_ALIAS);
+      : this(DeclarationKind.CLASS_TYPE_ALIAS, name, null);
 
-  _ExpectedDeclaration.enum_(String name) : this(name, DeclarationKind.ENUM);
+  _ExpectedDeclaration.enum_(String name)
+      : this(DeclarationKind.ENUM, name, null);
+
+  _ExpectedDeclaration.enumConstant(String name, String name2)
+      : this(DeclarationKind.ENUM_CONSTANT, name, name2);
 
   _ExpectedDeclaration.function(String name)
-      : this(name, DeclarationKind.FUNCTION);
+      : this(DeclarationKind.FUNCTION, name, null);
 
   _ExpectedDeclaration.functionTypeAlias(String name)
-      : this(name, DeclarationKind.FUNCTION_TYPE_ALIAS);
+      : this(DeclarationKind.FUNCTION_TYPE_ALIAS, name, null);
 
-  _ExpectedDeclaration.mixin(String name) : this(name, DeclarationKind.MIXIN);
+  _ExpectedDeclaration.mixin(String name)
+      : this(DeclarationKind.MIXIN, name, null);
 
   _ExpectedDeclaration.variable(String name)
-      : this(name, DeclarationKind.VARIABLE);
+      : this(DeclarationKind.VARIABLE, name, null);
 
   @override
   String toString() {
-    return '($name, $kind)';
+    if (name2 != null) {
+      return '($kind, $name, $name2)';
+    } else {
+      return '($kind, $name)';
+    }
   }
 }