Add support for remaining target types in gn --type

Specifically, this adds the ability to filter targets by:
- rust_library
- rust_proc_macro
- bundle_data
- create_bundle
- generated_file

The is needed to efficiently list elements with the type rust_library
in `autotest.py` script in Chromium: http://crrev.com/c/8143145

Bug: 534608615
Change-Id: I148f78484c495c995d2373a7f51114676a6a6964
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/24340
Reviewed-by: Takuto Ikuta <tikuta@google.com>
Reviewed-by: Andrew Grieve <agrieve@google.com>
Commit-Queue: Andrew Grieve <agrieve@google.com>
diff --git a/docs/reference.md b/docs/reference.md
index 838ea13..3dcefac 100644
--- a/docs/reference.md
+++ b/docs/reference.md
@@ -671,8 +671,9 @@
       Tree output can not be used with the filtering or output flags: --as,
       --type, --testonly.
 
-  --type=(action|copy|executable|group|loadable_module|shared_library|
-          source_set|static_library)
+  --type=(action|bundle_data|copy|create_bundle|executable|
+          generated_file|group|loadable_module|rust_library|
+          rust_proc_macro|shared_library|source_set|static_library)
       Restrict outputs to targets matching the given type. If
       unspecified, no filtering will be performed.
 ```
@@ -1083,8 +1084,9 @@
       accordingly. When unspecified, the target's testonly flags are
       ignored.
 
-  --type=(action|copy|executable|group|loadable_module|shared_library|
-          source_set|static_library)
+  --type=(action|bundle_data|copy|create_bundle|executable|
+          generated_file|group|loadable_module|rust_library|
+          rust_proc_macro|shared_library|source_set|static_library)
       Restrict outputs to targets matching the given type. If
       unspecified, no filtering will be performed.
 ```
@@ -1345,8 +1347,9 @@
       Tree output can not be used with the filtering or output flags: --as,
       --type, --testonly.
 
-  --type=(action|copy|executable|group|loadable_module|shared_library|
-          source_set|static_library)
+  --type=(action|bundle_data|copy|create_bundle|executable|
+          generated_file|group|loadable_module|rust_library|
+          rust_proc_macro|shared_library|source_set|static_library)
       Restrict outputs to targets matching the given type. If
       unspecified, no filtering will be performed.
 
diff --git a/src/gn/commands.cc b/src/gn/commands.cc
index c37bc6a..bae4c4a 100644
--- a/src/gn/commands.cc
+++ b/src/gn/commands.cc
@@ -475,6 +475,11 @@
         {"source_set", Target::SOURCE_SET},
         {"copy", Target::COPY_FILES},
         {"action", Target::ACTION},
+        {"generated_file", Target::GENERATED_FILE},
+        {"rust_library", Target::RUST_LIBRARY},
+        {"rust_proc_macro", Target::RUST_PROC_MACRO},
+        {"bundle_data", Target::BUNDLE_DATA},
+        {"create_bundle", Target::CREATE_BUNDLE},
     };
     bool found = false;
     for (const auto& type : kTypes) {
diff --git a/src/gn/commands.h b/src/gn/commands.h
index d5b07ab..9a996b1 100644
--- a/src/gn/commands.h
+++ b/src/gn/commands.h
@@ -360,10 +360,11 @@
   "      output\n"                                                            \
   "          Prints the first output file for the target relative to the\n"   \
   "          root build directory.\n"
-#define TARGET_TYPE_FILTER_COMMAND_LINE_HELP                                 \
-  "  --type=(action|copy|executable|group|loadable_module|shared_library|\n" \
-  "          source_set|static_library)\n"                                   \
-  "      Restrict outputs to targets matching the given type. If\n"          \
+#define TARGET_TYPE_FILTER_COMMAND_LINE_HELP                              \
+  "  --type=(action|bundle_data|copy|create_bundle|executable|\n"         \
+  "          generated_file|group|loadable_module|rust_library|\n"        \
+  "          rust_proc_macro|shared_library|source_set|static_library)\n" \
+  "      Restrict outputs to targets matching the given type. If\n"       \
   "      unspecified, no filtering will be performed.\n"
 #define TARGET_TESTONLY_FILTER_COMMAND_LINE_HELP                           \
   "  --testonly=(true|false)\n"                                            \
diff --git a/src/gn/commands_unittest.cc b/src/gn/commands_unittest.cc
index 44c91b7..fe27816 100644
--- a/src/gn/commands_unittest.cc
+++ b/src/gn/commands_unittest.cc
@@ -4,6 +4,8 @@
 
 #include <stddef.h>
 
+#include "base/command_line.h"
+#include "base/values.h"
 #include "gn/commands.h"
 #include "gn/label_pattern.h"
 #include "gn/target.h"
@@ -33,3 +35,52 @@
   EXPECT_EQ(1, output.size());
   EXPECT_EQ(&target_cbar, output[0]);
 }
+
+TEST(Commands, ApplyTypeFilter) {
+  TestWithScope setup;
+
+  static const std::pair<std::string, Target::OutputType> cases[] = {
+      {"action", Target::ACTION},
+      {"bundle_data", Target::BUNDLE_DATA},
+      {"copy", Target::COPY_FILES},
+      {"create_bundle", Target::CREATE_BUNDLE},
+      {"executable", Target::EXECUTABLE},
+      {"generated_file", Target::GENERATED_FILE},
+      {"group", Target::GROUP},
+      {"loadable_module", Target::LOADABLE_MODULE},
+      {"rust_library", Target::RUST_LIBRARY},
+      {"rust_proc_macro", Target::RUST_PROC_MACRO},
+      {"shared_library", Target::SHARED_LIBRARY},
+      {"source_set", Target::SOURCE_SET},
+      {"static_library", Target::STATIC_LIBRARY},
+  };
+
+  std::vector<std::unique_ptr<Target>> created_targets;
+  std::vector<const Target*> all_targets;
+  for (const auto& test_case : cases) {
+    auto target = std::make_unique<Target>(
+        setup.settings(), Label(SourceDir("//a/"), test_case.first));
+    target->set_output_type(test_case.second);
+    all_targets.push_back(target.get());
+    created_targets.push_back(std::move(target));
+  }
+
+  for (const auto& test_case : cases) {
+    std::vector<const Target*> targets_to_filter = all_targets;
+
+    base::CommandLine cmdline(base::CommandLine::NO_PROGRAM);
+    cmdline.AppendSwitch("type", test_case.first);
+
+    commands::CommandSwitches::Init(cmdline);
+
+    base::ListValue out;
+    commands::FilterAndPrintTargets(&targets_to_filter, &out);
+
+    ASSERT_EQ(1u, targets_to_filter.size());
+    EXPECT_EQ(test_case.second, targets_to_filter[0]->output_type())
+        << "Failed for type: " << test_case.first;
+
+    commands::CommandSwitches empty_switches;
+    commands::CommandSwitches::Set(empty_switches);
+  }
+}