Store BundleData paths as SourceDirs rather than strings.

R=brettw@chromium.org
BUG=297668

Review URL: https://codereview.chromium.org/1911873002

Cr-Original-Commit-Position: refs/heads/master@{#389110}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 54f052e1445e26b4fd8bd61748f4ee870872c2fa
diff --git a/tools/gn/bundle_data.cc b/tools/gn/bundle_data.cc
index f1b60c0..f211c1f 100644
--- a/tools/gn/bundle_data.cc
+++ b/tools/gn/bundle_data.cc
@@ -105,19 +105,19 @@
   if (!asset_catalog_sources_.empty())
     outputs_as_source->push_back(GetCompiledAssetCatalogPath());
 
-  if (!root_dir_.empty())
+  if (!root_dir_.is_null())
     outputs_as_source->push_back(GetBundleRootDirOutput(settings));
 }
 
 SourceFile BundleData::GetCompiledAssetCatalogPath() const {
   DCHECK(!asset_catalog_sources_.empty());
-  std::string assets_car_path = resources_dir_ + "/Assets.car";
+  std::string assets_car_path = resources_dir_.value() + "/Assets.car";
   return SourceFile(SourceFile::SWAP_IN, &assets_car_path);
 }
 
 SourceFile BundleData::GetBundleRootDirOutput(const Settings* settings) const {
   const SourceDir& build_dir = settings->build_settings()->build_dir();
-  std::string bundle_root_relative = RebasePath(root_dir(), build_dir);
+  std::string bundle_root_relative = RebasePath(root_dir().value(), build_dir);
 
   size_t first_component = bundle_root_relative.find('/');
   if (first_component != std::string::npos) {
@@ -127,5 +127,5 @@
     outermost_bundle_dir.AppendToString(&return_value);
     return SourceFile(SourceFile::SWAP_IN, &return_value);
   }
-  return SourceFile(root_dir());
+  return SourceFile(root_dir().value());
 }
diff --git a/tools/gn/bundle_data.h b/tools/gn/bundle_data.h
index aaf5e33..d742674 100644
--- a/tools/gn/bundle_data.h
+++ b/tools/gn/bundle_data.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "tools/gn/bundle_file_rule.h"
+#include "tools/gn/source_dir.h"
 #include "tools/gn/unique_vector.h"
 
 class OutputFile;
@@ -85,17 +86,17 @@
   BundleFileRules& file_rules() { return file_rules_; }
   const BundleFileRules& file_rules() const { return file_rules_; }
 
-  std::string& root_dir() { return root_dir_; }
-  const std::string& root_dir() const { return root_dir_; }
+  SourceDir& root_dir() { return root_dir_; }
+  const SourceDir& root_dir() const { return root_dir_; }
 
-  std::string& resources_dir() { return resources_dir_; }
-  const std::string& resources_dir() const { return resources_dir_; }
+  SourceDir& resources_dir() { return resources_dir_; }
+  const SourceDir& resources_dir() const { return resources_dir_; }
 
-  std::string& executable_dir() { return executable_dir_; }
-  const std::string& executable_dir() const { return executable_dir_; }
+  SourceDir& executable_dir() { return executable_dir_; }
+  const SourceDir& executable_dir() const { return executable_dir_; }
 
-  std::string& plugins_dir() { return plugins_dir_; }
-  const std::string& plugins_dir() const { return plugins_dir_; }
+  SourceDir& plugins_dir() { return plugins_dir_; }
+  const SourceDir& plugins_dir() const { return plugins_dir_; }
 
   // Recursive collection of all bundle_data that the target depends on.
   const UniqueTargets& bundle_deps() const { return bundle_deps_; }
@@ -107,10 +108,10 @@
 
   // All those values are subdirectories relative to root_build_dir, and apart
   // from root_dir, they are either equal to root_dir_ or subdirectories of it.
-  std::string root_dir_;
-  std::string resources_dir_;
-  std::string executable_dir_;
-  std::string plugins_dir_;
+  SourceDir root_dir_;
+  SourceDir resources_dir_;
+  SourceDir executable_dir_;
+  SourceDir plugins_dir_;
 };
 
 #endif  // TOOLS_GN_BUNDLE_DATA_H_
diff --git a/tools/gn/bundle_file_rule.cc b/tools/gn/bundle_file_rule.cc
index 7684196..9f78667 100644
--- a/tools/gn/bundle_file_rule.cc
+++ b/tools/gn/bundle_file_rule.cc
@@ -29,16 +29,16 @@
         output_path.append(subrange.literal);
         break;
       case SUBSTITUTION_BUNDLE_ROOT_DIR:
-        output_path.append(bundle_data.root_dir());
+        output_path.append(bundle_data.root_dir().value());
         break;
       case SUBSTITUTION_BUNDLE_RESOURCES_DIR:
-        output_path.append(bundle_data.resources_dir());
+        output_path.append(bundle_data.resources_dir().value());
         break;
       case SUBSTITUTION_BUNDLE_EXECUTABLE_DIR:
-        output_path.append(bundle_data.executable_dir());
+        output_path.append(bundle_data.executable_dir().value());
         break;
       case SUBSTITUTION_BUNDLE_PLUGINS_DIR:
-        output_path.append(bundle_data.plugins_dir());
+        output_path.append(bundle_data.plugins_dir().value());
         break;
       default:
         output_path.append(SubstitutionWriter::GetSourceSubstitution(
diff --git a/tools/gn/create_bundle_target_generator.cc b/tools/gn/create_bundle_target_generator.cc
index 206a918..6085419 100644
--- a/tools/gn/create_bundle_target_generator.cc
+++ b/tools/gn/create_bundle_target_generator.cc
@@ -25,7 +25,7 @@
   target_->set_output_type(Target::CREATE_BUNDLE);
 
   BundleData& bundle_data = target_->bundle_data();
-  if (!GetBundleDir(std::string(),
+  if (!GetBundleDir(SourceDir(),
                     variables::kBundleRootDir,
                     &bundle_data.root_dir()))
     return;
@@ -44,26 +44,26 @@
 }
 
 bool CreateBundleTargetGenerator::GetBundleDir(
-    const std::string& bundle_root_dir,
+    const SourceDir& bundle_root_dir,
     const base::StringPiece& name,
-    std::string* bundle_dir) {
+    SourceDir* bundle_dir) {
   const Value* value = scope_->GetValue(name, true);
   if (!value)
     return true;
   if (!value->VerifyTypeIs(Value::STRING, err_))
     return false;
-  const std::string& str = value->string_value();
+  std::string str = value->string_value();
   if (!EnsureStringIsInOutputDir(GetBuildSettings()->build_dir(), str,
                                  value->origin(), err_))
     return false;
-  if (str != bundle_root_dir &&
-      !IsStringInOutputDir(SourceDir(bundle_root_dir), str)) {
+  if (str != bundle_root_dir.value() &&
+      !IsStringInOutputDir(bundle_root_dir, str)) {
     *err_ = Err(value->origin(), "Path is not in bundle root dir.",
         "The given file should be in the bundle root directory or below.\n"
         "Normally you would do \"$bundle_root_dir/foo\". I interpreted this\n"
         "as \"" + str + "\".");
     return false;
   }
-  bundle_dir->assign(value->string_value());
+  bundle_dir->SwapValue(&str);
   return true;
 }
diff --git a/tools/gn/create_bundle_target_generator.h b/tools/gn/create_bundle_target_generator.h
index db82b8a..50040b8 100644
--- a/tools/gn/create_bundle_target_generator.h
+++ b/tools/gn/create_bundle_target_generator.h
@@ -8,6 +8,8 @@
 #include "base/macros.h"
 #include "tools/gn/target_generator.h"
 
+class SourceDir;
+
 // Populates a Target with the values from a create_bundle rule.
 class CreateBundleTargetGenerator : public TargetGenerator {
  public:
@@ -21,9 +23,9 @@
   void DoRun() override;
 
  private:
-  bool GetBundleDir(const std::string& bundle_root_dir,
+  bool GetBundleDir(const SourceDir& bundle_root_dir,
                     const base::StringPiece& name,
-                    std::string* bundle_dir);
+                    SourceDir* bundle_dir);
 
   DISALLOW_COPY_AND_ASSIGN(CreateBundleTargetGenerator);
 };
diff --git a/tools/gn/ninja_create_bundle_target_writer_unittest.cc b/tools/gn/ninja_create_bundle_target_writer_unittest.cc
index 44dd894..d35b519 100644
--- a/tools/gn/ninja_create_bundle_target_writer_unittest.cc
+++ b/tools/gn/ninja_create_bundle_target_writer_unittest.cc
@@ -14,10 +14,11 @@
 namespace {
 
 void SetupBundleDataDir(BundleData* bundle_data, const std::string& root_dir) {
-  bundle_data->root_dir().assign(root_dir + "/bar.bundle");
-  bundle_data->resources_dir().assign(bundle_data->root_dir() + "/Resources");
-  bundle_data->executable_dir().assign(bundle_data->root_dir() + "/Executable");
-  bundle_data->plugins_dir().assign(bundle_data->root_dir() + "/PlugIns");
+  std::string bundle_root_dir = root_dir + "/bar.bundle";
+  bundle_data->root_dir() = SourceDir(bundle_root_dir);
+  bundle_data->resources_dir() = SourceDir(bundle_root_dir + "/Resources");
+  bundle_data->executable_dir() = SourceDir(bundle_root_dir + "/Executable");
+  bundle_data->plugins_dir() = SourceDir(bundle_root_dir + "/PlugIns");
 }
 
 }  // namespace
@@ -115,10 +116,11 @@
   target.set_output_type(Target::CREATE_BUNDLE);
 
   const std::string bundle_root_dir("//out/Debug/bar.bundle/Contents");
-  target.bundle_data().root_dir().assign(bundle_root_dir);
-  target.bundle_data().resources_dir().assign(bundle_root_dir + "/Resources");
-  target.bundle_data().executable_dir().assign(bundle_root_dir + "/MacOS");
-  target.bundle_data().plugins_dir().assign(bundle_root_dir + "/Plug Ins");
+  target.bundle_data().root_dir() = SourceDir(bundle_root_dir);
+  target.bundle_data().resources_dir() =
+      SourceDir(bundle_root_dir + "/Resources");
+  target.bundle_data().executable_dir() = SourceDir(bundle_root_dir + "/MacOS");
+  target.bundle_data().plugins_dir() = SourceDir(bundle_root_dir + "/Plug Ins");
 
   std::vector<SourceFile> sources;
   sources.push_back(SourceFile("//foo/input1.txt"));