analyze: Make additional_compile_targets input key optional

It looks like it was required so that if people put in
"compile_targets" instead, they get an error about
additional_compile_targets missing. Instead, error out
on unknown keys.

Change-Id: Ib14b68085ee64348f248fbebad2ef05183a5059d
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/11340
Reviewed-by: Brett Wilson <brettw@chromium.org>
Commit-Queue: Nico Weber <thakis@chromium.org>
diff --git a/src/gn/analyzer.cc b/src/gn/analyzer.cc
index a42779a..7bb200c 100644
--- a/src/gn/analyzer.cc
+++ b/src/gn/analyzer.cc
@@ -138,42 +138,61 @@
     return Err(Location(), "Input is not a dictionary.");
 
   Err err;
-  std::vector<std::string> strings;
-  strings = GetStringVector(*dict, "files", &err);
-  if (err.has_error())
-    return err;
-  for (auto& s : strings) {
-    if (!IsPathSourceAbsolute(s) && !IsPathAbsolute(s)) {
-      return Err(Location(),
-                 "\"" + s + "\" is not a source-absolute or absolute path.");
+
+  const char kFilesKey[] = "files";
+  {
+    std::vector<std::string> files = GetStringVector(*dict, kFilesKey, &err);
+    if (err.has_error())
+      return err;
+    for (auto& s : files) {
+      if (!IsPathSourceAbsolute(s) && !IsPathAbsolute(s)) {
+        return Err(Location(),
+                   "\"" + s + "\" is not a source-absolute or absolute path.");
+      }
+      inputs->source_vec.emplace_back(std::move(s));
     }
-    inputs->source_vec.emplace_back(std::move(s));
   }
 
-  strings = GetStringVector(*dict, "additional_compile_targets", &err);
-  if (err.has_error())
-    return err;
-
   inputs->compile_included_all = false;
-  for (auto& s : strings) {
-    if (s == "all") {
-      inputs->compile_included_all = true;
-    } else {
-      inputs->compile_vec.push_back(
+  const char kAdditonalCompileTargetsKey[] = "additional_compile_targets";
+  if (dict->HasKey(kAdditonalCompileTargetsKey)) {
+    std::vector<std::string> additional_compile_targets =
+        GetStringVector(*dict, kAdditonalCompileTargetsKey, &err);
+    if (err.has_error())
+      return err;
+
+    for (auto& s : additional_compile_targets) {
+      if (s == "all") {
+        inputs->compile_included_all = true;
+      } else {
+        inputs->compile_vec.push_back(
+            AbsoluteOrSourceAbsoluteStringToLabel(default_toolchain, s, &err));
+        if (err.has_error())
+          return err;
+      }
+    }
+  }
+
+  const char kTestTargetsKey[] = "test_targets";
+  {
+    std::vector<std::string> test_targets =
+        GetStringVector(*dict, kTestTargetsKey, &err);
+    if (err.has_error())
+      return err;
+    for (auto& s : test_targets) {
+      inputs->test_vec.push_back(
           AbsoluteOrSourceAbsoluteStringToLabel(default_toolchain, s, &err));
       if (err.has_error())
         return err;
     }
   }
 
-  strings = GetStringVector(*dict, "test_targets", &err);
-  if (err.has_error())
-    return err;
-  for (auto& s : strings) {
-    inputs->test_vec.push_back(
-        AbsoluteOrSourceAbsoluteStringToLabel(default_toolchain, s, &err));
-    if (err.has_error())
-      return err;
+  for (const auto& kv : dict->DictItems()) {
+    if (kv.first == kFilesKey || kv.first == kAdditonalCompileTargetsKey ||
+        kv.first == kTestTargetsKey) {
+      continue;
+    }
+    return Err(Location(), "Unknown analyze input key \"" + kv.first + "\".");
   }
 
   for (auto& s : inputs->source_vec)
diff --git a/src/gn/analyzer_unittest.cc b/src/gn/analyzer_unittest.cc
index 558700e..98bef67 100644
--- a/src/gn/analyzer_unittest.cc
+++ b/src/gn/analyzer_unittest.cc
@@ -592,8 +592,7 @@
       })",
       "{"
       R"("error":)"
-      R"("Input does not have a key named )"
-      R"(\"additional_compile_targets\" with a list value.",)"
+      R"("Unknown analyze input key \"compile_targets\".",)"
       R"("invalid_targets":[])"
       "}");
 }