From 2fd81ca609b8e47a0a8bfe973d207bdec1f10d85 Mon Sep 17 00:00:00 2001
From: gaaclarke <30870216+gaaclarke@users.noreply.github.com>
Date: Tue, 30 Nov 2021 13:29:07 -0800
Subject: [PATCH] [pigeon] Made using enums in type arguments an error, added
 workaround (#527)

---
 packages/pigeon/CHANGELOG.md              |  7 +++-
 packages/pigeon/lib/generator_tools.dart  |  2 +-
 packages/pigeon/lib/pigeon_lib.dart       | 10 +++--
 packages/pigeon/pubspec.yaml              |  2 +-
 packages/pigeon/test/pigeon_lib_test.dart | 45 +++++++++++++++++++++++
 5 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md
index 81660fd4d3..2fefeff7b4 100644
--- a/packages/pigeon/CHANGELOG.md
+++ b/packages/pigeon/CHANGELOG.md
@@ -1,6 +1,9 @@
-## NEXT
+## 1.0.11
 
-* [ci] Started transitioning to a Dart test runner, added windows support.
+* [ci] Starts transition to a Dart test runner, adds windows support.
+* [front-end] Starts issuing an error if enums are used in type arguments.
+* [front-end] Passes through all enums, referenced or not so they can be used as
+  a work around for direct enum support.
 
 ## 1.0.10
 
diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart
index aa1b9dad8a..4b07ea0f60 100644
--- a/packages/pigeon/lib/generator_tools.dart
+++ b/packages/pigeon/lib/generator_tools.dart
@@ -8,7 +8,7 @@ import 'dart:mirrors';
 import 'ast.dart';
 
 /// The current version of pigeon. This must match the version in pubspec.yaml.
-const String pigeonVersion = '1.0.10';
+const String pigeonVersion = '1.0.11';
 
 /// Read all the content from [stdin] to a String.
 String readStdin() {
diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart
index 439f5cd824..e5b7814ebf 100644
--- a/packages/pigeon/lib/pigeon_lib.dart
+++ b/packages/pigeon/lib/pigeon_lib.dart
@@ -423,6 +423,13 @@ List<Error> _validateAst(Root root, String source) {
               lineNumber: _calculateLineNumberNullable(source, field.offset),
             ));
           }
+          if (customEnums.contains(typeArgument.baseName)) {
+            result.add(Error(
+              message:
+                  'Enum types aren\'t supported in type arguments in "${field.name}" in class "${klass.name}".',
+              lineNumber: _calculateLineNumberNullable(source, field.offset),
+            ));
+          }
         }
       }
       if (!(validTypes.contains(field.type.baseName) ||
@@ -544,9 +551,6 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor<Object?> {
         .removeWhere((Class x) => !referencedTypeNames.contains(x.name));
 
     final List<Enum> referencedEnums = List<Enum>.from(_enums);
-    referencedEnums.removeWhere(
-        (final Enum anEnum) => !referencedTypeNames.contains(anEnum.name));
-
     final Root completeRoot =
         Root(apis: _apis, classes: referencedClasses, enums: referencedEnums);
 
diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml
index 04647a02a9..d0e471aa56 100644
--- a/packages/pigeon/pubspec.yaml
+++ b/packages/pigeon/pubspec.yaml
@@ -2,7 +2,7 @@ name: pigeon
 description: Code generator tool to make communication between Flutter and the host platform type-safe and easier.
 repository: https://github.com/flutter/packages/tree/master/packages/pigeon
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3Apigeon
-version: 1.0.10 # This must match the version in lib/generator_tools.dart
+version: 1.0.11 # This must match the version in lib/generator_tools.dart
 
 environment:
   sdk: '>=2.12.0 <3.0.0'
diff --git a/packages/pigeon/test/pigeon_lib_test.dart b/packages/pigeon/test/pigeon_lib_test.dart
index 63c9498238..e31f68984c 100644
--- a/packages/pigeon/test/pigeon_lib_test.dart
+++ b/packages/pigeon/test/pigeon_lib_test.dart
@@ -901,4 +901,49 @@ abstract class Api {
     final ParseResults results = _parseSource(code);
     expect(results.errors.length, 0);
   });
+
+  test('Enum key not supported', () {
+    const String code = '''
+enum MessageKey {
+  title,
+  subtitle,
+  description,
+}
+
+class Message {
+  int? id;
+  Map<MessageKey?, String?>? additionalProperties;
+}
+
+@HostApi()
+abstract class HostApiBridge {
+  void sendMessage(Message message);
+}
+''';
+    final ParseResults results = _parseSource(code);
+    expect(results.errors.length, 1);
+  });
+
+  test('Export unreferenced enums', () {
+    const String code = '''
+enum MessageKey {
+  title,
+  subtitle,
+  description,
+}
+
+class Message {
+  int? id;
+  Map<int?, String?>? additionalProperties;
+}
+
+@HostApi()
+abstract class HostApiBridge {
+  void sendMessage(Message message);
+}
+''';
+    final ParseResults results = _parseSource(code);
+    expect(results.root.enums.length, 1);
+    expect(results.root.enums[0].name, 'MessageKey');
+  });
 }