Fix --as=buildfile `gn desc deps` output.

Before this CL, `--as=buildfile` would report the location
of the parse tree node used to instantiate a Target, in practice
this meant that:

- For builtin target types like `action()` or `static_library()`,
  this would be the location of the BUILD.gn where these are called.

- For targets defined through templates (e.g. `java_library()`
  in Chromium), this would be the location of the .gni file where
  the underlying action() was invoked.

This CL ensures that the location of the BUILD.gn where the target
is defined is always returned. It does so by looking at the
build_dependency_files() set for the target, and extracting
the single BUILD.gn file location from it, falling back to
BUILDCONFIG.gn for targets that may be defined there instead.

NOTE: There is no unit-test because PrintAndFilterTargets()
relies on too much global state, including the command-line.
Writing a proper test would require a non-trivial refactor
of that code.

Manual testing can be done by comparing the outputs of:

```
gn desc . //base:base_java deps --all --as=buildfile
```

Before and after this CL.

Bug: chromium:1500273
Change-Id: I4393e98d21c56c86282a886cb595034c389cc31c
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/16100
Reviewed-by: Takuto Ikuta <tikuta@google.com>
Commit-Queue: David Turner <digit@google.com>
diff --git a/src/gn/commands.cc b/src/gn/commands.cc
index b535b20..0f607d9 100644
--- a/src/gn/commands.cc
+++ b/src/gn/commands.cc
@@ -202,9 +202,28 @@
   return true;
 }
 
-// Returns the file path generating this item.
+// Returns the file path of the BUILD.gn file generating this item.
 base::FilePath BuildFileForItem(const Item* item) {
-  return item->defined_from()->GetRange().begin().file()->physical_name();
+  // Find the only BUILD.gn file listed in build_dependency_files() for
+  // this Item. This may not exist if the item is defined in BUILDCONFIG.gn
+  // instead, so account for this too.
+  const SourceFile* buildconfig_gn = nullptr;
+  const SourceFile* build_gn = nullptr;
+  for (const SourceFile& build_file : item->build_dependency_files()) {
+    const std::string& name = build_file.GetName();
+    if (name == "BUILDCONFIG.gn") {
+      buildconfig_gn = &build_file;
+    } else if (name == "BUILD.gn") {
+      build_gn = &build_file;
+      break;
+    }
+  }
+  if (!build_gn)
+    build_gn = buildconfig_gn;
+
+  CHECK(build_gn) << "No BUILD.gn or BUILDCONFIG.gn file defining "
+                  << item->label().GetUserVisibleName(true);
+  return build_gn->Resolve(item->settings()->build_settings()->root_path());
 }
 
 void PrintTargetsAsBuildfiles(const std::vector<const Target*>& targets,