[cfe] Don't serialize an empty show/hide clause

TEST=existing

Change-Id: Ie63444c4dbeaa45b38fd195e554780f14fed878e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/213767
Commit-Queue: Chloe Stefantsova <dmitryas@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index ab32dae..1a0a3a2 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -147,7 +147,7 @@
 
 type ComponentFile {
   UInt32 magic = 0x90ABCDEF;
-  UInt32 formatVersion = 71;
+  UInt32 formatVersion = 72;
   Byte[10] shortSdkHash;
   List<String> problemsAsJson; // Described in problems.md.
   Library[] libraries;
@@ -346,6 +346,10 @@
   Byte flags (isExtensionTypeDeclaration);
   List<TypeParameter> typeParameters;
   DartType onType;
+  Option<ExtensionTypeShowHideClause> showHideClause;
+}
+
+type ExtensionTypeShowHideClause {
   List<DartType> shownSupertypes;
   List<CanonicalNameReference> shownMembers;
   List<CanonicalNameReference> shownGetters;
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 14eb7b8..1423d0d 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -529,14 +529,15 @@
         growable: useGrowableLists);
   }
 
-  List<Reference> readNonNullReferenceList() {
+  List<Reference> readNonNullReferenceList(List<Reference> result) {
     int length = readUInt30();
     if (!useGrowableLists && length == 0) {
       return emptyListOfReference;
     }
-    return new List<Reference>.generate(
-        length, (_) => readNonNullMemberReference(),
-        growable: useGrowableLists);
+    for (int i = 0; i < length; ++i) {
+      result.add(readNonNullMemberReference());
+    }
+    return result;
   }
 
   String? readStringOrNullIfEmpty() {
@@ -1458,32 +1459,27 @@
 
     readAndPushTypeParameterList(node.typeParameters, node);
     DartType onType = readDartType();
-    List<Supertype> shownSupertypes = readSupertypeList();
-    List<Reference> shownMembers = readNonNullReferenceList();
-    List<Reference> shownGetters = readNonNullReferenceList();
-    List<Reference> shownSetters = readNonNullReferenceList();
-    List<Reference> shownOperators = readNonNullReferenceList();
-    List<Supertype> hiddenSupertypes = readSupertypeList();
-    List<Reference> hiddenMembers = readNonNullReferenceList();
-    List<Reference> hiddenGetters = readNonNullReferenceList();
-    List<Reference> hiddenSetters = readNonNullReferenceList();
-    List<Reference> hiddenOperators = readNonNullReferenceList();
+
+    if (readAndCheckOptionTag()) {
+      ExtensionTypeShowHideClause showHideClause =
+          node.showHideClause = new ExtensionTypeShowHideClause();
+      readSupertypeList(showHideClause.shownSupertypes);
+      readNonNullReferenceList(showHideClause.shownMethods);
+      readNonNullReferenceList(showHideClause.shownGetters);
+      readNonNullReferenceList(showHideClause.shownSetters);
+      readNonNullReferenceList(showHideClause.shownOperators);
+      readSupertypeList(showHideClause.hiddenSupertypes);
+      readNonNullReferenceList(showHideClause.hiddenMethods);
+      readNonNullReferenceList(showHideClause.hiddenGetters);
+      readNonNullReferenceList(showHideClause.hiddenSetters);
+      readNonNullReferenceList(showHideClause.hiddenOperators);
+    }
+
     typeParameterStack.length = 0;
 
     node.name = name;
     node.fileUri = fileUri;
     node.onType = onType;
-    node.showHideClause = new ExtensionTypeShowHideClause()
-      ..shownSupertypes.addAll(shownSupertypes)
-      ..shownMethods.addAll(shownMembers)
-      ..shownGetters.addAll(shownGetters)
-      ..shownSetters.addAll(shownSetters)
-      ..shownOperators.addAll(shownOperators)
-      ..hiddenSupertypes.addAll(hiddenSupertypes)
-      ..hiddenMethods.addAll(hiddenMembers)
-      ..hiddenGetters.addAll(hiddenGetters)
-      ..hiddenSetters.addAll(hiddenSetters)
-      ..hiddenOperators.addAll(hiddenOperators);
 
     node.members = _readExtensionMemberDescriptorList();
 
@@ -2949,15 +2945,22 @@
     return readAndCheckOptionTag() ? readSupertype() : null;
   }
 
-  List<Supertype> readSupertypeList() {
+  List<Supertype> readSupertypeList([List<Supertype>? result]) {
     int length = readUInt30();
     if (!useGrowableLists && length == 0) {
       // When lists don't have to be growable anyway, we might as well use an
       // almost constant one for the empty list.
       return emptyListOfSupertype;
     }
-    return new List<Supertype>.generate(length, (_) => readSupertype(),
-        growable: useGrowableLists);
+    if (result != null) {
+      for (int i = 0; i < length; ++i) {
+        result.add(readSupertype());
+      }
+      return result;
+    } else {
+      return new List<Supertype>.generate(length, (_) => readSupertype(),
+          growable: useGrowableLists);
+    }
   }
 
   List<DartType> readDartTypeList() {
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index b0de73c..6cb1bd7 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -2451,18 +2451,24 @@
     enterScope(typeParameters: node.typeParameters);
     writeNodeList(node.typeParameters);
     writeDartType(node.onType);
-    ExtensionTypeShowHideClause showHideClause =
-        node.showHideClause ?? new ExtensionTypeShowHideClause();
-    writeNodeList(showHideClause.shownSupertypes);
-    writeList(showHideClause.shownMethods, writeNonNullReference);
-    writeList(showHideClause.shownGetters, writeNonNullReference);
-    writeList(showHideClause.shownSetters, writeNonNullReference);
-    writeList(showHideClause.shownOperators, writeNonNullReference);
-    writeNodeList(showHideClause.hiddenSupertypes);
-    writeList(showHideClause.hiddenMethods, writeNonNullReference);
-    writeList(showHideClause.hiddenGetters, writeNonNullReference);
-    writeList(showHideClause.hiddenSetters, writeNonNullReference);
-    writeList(showHideClause.hiddenOperators, writeNonNullReference);
+
+    ExtensionTypeShowHideClause? showHideClause = node.showHideClause;
+    if (showHideClause == null) {
+      writeByte(Tag.Nothing);
+    } else {
+      writeByte(Tag.Something);
+      writeNodeList(showHideClause.shownSupertypes);
+      writeList(showHideClause.shownMethods, writeNonNullReference);
+      writeList(showHideClause.shownGetters, writeNonNullReference);
+      writeList(showHideClause.shownSetters, writeNonNullReference);
+      writeList(showHideClause.shownOperators, writeNonNullReference);
+      writeNodeList(showHideClause.hiddenSupertypes);
+      writeList(showHideClause.hiddenMethods, writeNonNullReference);
+      writeList(showHideClause.hiddenGetters, writeNonNullReference);
+      writeList(showHideClause.hiddenSetters, writeNonNullReference);
+      writeList(showHideClause.hiddenOperators, writeNonNullReference);
+    }
+
     leaveScope(typeParameters: node.typeParameters);
 
     final int len = node.members.length;
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index 2fe1841..b628f87 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -176,7 +176,7 @@
   /// Internal version of kernel binary format.
   /// Bump it when making incompatible changes in kernel binaries.
   /// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
-  static const int BinaryFormatVersion = 71;
+  static const int BinaryFormatVersion = 72;
 }
 
 abstract class ConstantTag {
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 653c0fd..13f777c 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -20,8 +20,8 @@
 static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
 
 // Both version numbers are inclusive.
-static const uint32_t kMinSupportedKernelFormatVersion = 71;
-static const uint32_t kMaxSupportedKernelFormatVersion = 71;
+static const uint32_t kMinSupportedKernelFormatVersion = 72;
+static const uint32_t kMaxSupportedKernelFormatVersion = 72;
 
 // Keep in sync with package:kernel/lib/binary/tag.dart
 #define KERNEL_TAG_LIST(V)                                                     \
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index 6efc565..6236cf3 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -1089,16 +1089,19 @@
       helper_.ReadByte();                    // skip flags.
       helper_.SkipTypeParametersList();      // skip type parameter list.
       helper_.SkipDartType();                // skip on-type.
-      helper_.SkipListOfDartTypes();         // skip shown types.
-      helper_.SkipListOfCanonicalNameReferences();  // skip shown members.
-      helper_.SkipListOfCanonicalNameReferences();  // skip shown getters.
-      helper_.SkipListOfCanonicalNameReferences();  // skip shown setters.
-      helper_.SkipListOfCanonicalNameReferences();  // skip shown operators.
-      helper_.SkipListOfDartTypes();                // skip hidden types.
-      helper_.SkipListOfCanonicalNameReferences();  // skip hidden members.
-      helper_.SkipListOfCanonicalNameReferences();  // skip hidden getters.
-      helper_.SkipListOfCanonicalNameReferences();  // skip hidden setters.
-      helper_.SkipListOfCanonicalNameReferences();  // skip hidden operators.
+      Tag tag = helper_.ReadTag();
+      if (tag != kNothing) {
+        helper_.SkipListOfDartTypes();                // skip shown types.
+        helper_.SkipListOfCanonicalNameReferences();  // skip shown members.
+        helper_.SkipListOfCanonicalNameReferences();  // skip shown getters.
+        helper_.SkipListOfCanonicalNameReferences();  // skip shown setters.
+        helper_.SkipListOfCanonicalNameReferences();  // skip shown operators.
+        helper_.SkipListOfDartTypes();                // skip hidden types.
+        helper_.SkipListOfCanonicalNameReferences();  // skip hidden members.
+        helper_.SkipListOfCanonicalNameReferences();  // skip hidden getters.
+        helper_.SkipListOfCanonicalNameReferences();  // skip hidden setters.
+        helper_.SkipListOfCanonicalNameReferences();  // skip hidden operators.
+      }
 
       const intptr_t extension_member_count = helper_.ReadListLength();
       for (intptr_t j = 0; j < extension_member_count; ++j) {