[Refactor Xcode Objects] Enable navigator paths for file references. Previously, the folder hierarchy of a file reference in project navigator was forced to be the same as its physical folder hierarchy on disk. This CL refactors xcode_object.h and xcode_object.cc to enable specifying a navigator folder hierarchy when generating a file reference and it is allowed to be completely different from the physical one. This CL also corrects the mi-uses between "name" and "path" in PBXFileReference and PBXGroup. Take "ios/tool.cc" as an example, name should be "tool.cc", while path should be "ios/tool.cc", and they are different. BUG=614818 Review-Url: https://codereview.chromium.org/2576773002 Cr-Original-Commit-Position: refs/heads/master@{#439429} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: d48f4812d85338487c72a7ab2b1c2db8d60dfdb0
diff --git a/tools/gn/xcode_object.cc b/tools/gn/xcode_object.cc index dc5bfb8..039cb52 100644 --- a/tools/gn/xcode_object.cc +++ b/tools/gn/xcode_object.cc
@@ -404,7 +404,7 @@ } std::string PBXFileReference::Name() const { - return path_; + return name_; } void PBXFileReference::Print(std::ostream& out, unsigned indent) const { @@ -417,16 +417,17 @@ PrintProperty(out, rules, "explicitFileType", type_); PrintProperty(out, rules, "includeInIndex", 0u); } else { - base::StringPiece ext = FindExtension(&path_); + base::StringPiece ext = FindExtension(&name_); if (HasExplicitFileType(ext)) PrintProperty(out, rules, "explicitFileType", GetSourceType(ext)); else PrintProperty(out, rules, "lastKnownFileType", GetSourceType(ext)); } - if (name_ != path_ && !name_.empty()) + if (!name_.empty()) PrintProperty(out, rules, "name", name_); + DCHECK(!path_.empty()); PrintProperty(out, rules, "path", path_); PrintProperty(out, rules, "sourceTree", type_.empty() ? "<group>" : "BUILT_PRODUCTS_DIR"); @@ -471,36 +472,39 @@ return children_.back().get(); } -PBXFileReference* PBXGroup::AddSourceFile(const std::string& source_path) { +PBXFileReference* PBXGroup::AddSourceFile(const std::string& navigator_path, + const std::string& source_path) { + DCHECK(!navigator_path.empty()); DCHECK(!source_path.empty()); - std::string::size_type sep = source_path.find("/"); + std::string::size_type sep = navigator_path.find("/"); if (sep == std::string::npos) { children_.push_back(base::MakeUnique<PBXFileReference>( - std::string(), source_path, std::string())); + navigator_path, source_path, std::string())); return static_cast<PBXFileReference*>(children_.back().get()); } PBXGroup* group = nullptr; - base::StringPiece component(source_path.data(), sep); + base::StringPiece component(navigator_path.data(), sep); for (const auto& child : children_) { if (child->Class() != PBXGroupClass) continue; PBXGroup* child_as_group = static_cast<PBXGroup*>(child.get()); - if (child_as_group->path_ == component) { + if (child_as_group->name_ == component) { group = child_as_group; break; } } if (!group) { - children_.push_back(base::WrapUnique(new PBXGroup(component.as_string()))); + children_.push_back(base::WrapUnique( + new PBXGroup(component.as_string(), component.as_string()))); group = static_cast<PBXGroup*>(children_.back().get()); } DCHECK(group); - DCHECK(group->path_ == component); - return group->AddSourceFile(source_path.substr(sep + 1)); + DCHECK(group->name_ == component); + return group->AddSourceFile(navigator_path.substr(sep + 1), source_path); } PBXObjectClass PBXGroup::Class() const { @@ -530,7 +534,7 @@ PrintProperty(out, rules, "children", children_); if (!name_.empty()) PrintProperty(out, rules, "name", name_); - if (!path_.empty()) + if (is_source_ && !path_.empty()) PrintProperty(out, rules, "path", path_); PrintProperty(out, rules, "sourceTree", "<group>"); out << indent_str << "};\n"; @@ -598,6 +602,7 @@ main_group_.reset(new PBXGroup); sources_ = static_cast<PBXGroup*>( main_group_->AddChild(base::MakeUnique<PBXGroup>(source_path, "Source"))); + sources_->set_is_source(true); products_ = static_cast<PBXGroup*>(main_group_->AddChild( base::MakeUnique<PBXGroup>(std::string(), "Product"))); main_group_->AddChild(base::MakeUnique<PBXGroup>(std::string(), "Build")); @@ -607,8 +612,10 @@ PBXProject::~PBXProject() {} -void PBXProject::AddSourceFile(const std::string& source_path) { - PBXFileReference* file_reference = sources_->AddSourceFile(source_path); +void PBXProject::AddSourceFile(const std::string& navigator_path, + const std::string& source_path) { + PBXFileReference* file_reference = + sources_->AddSourceFile(navigator_path, source_path); base::StringPiece ext = FindExtension(&source_path); if (!IsSourceFileForIndexing(ext)) return;
diff --git a/tools/gn/xcode_object.h b/tools/gn/xcode_object.h index 2ad43cc..83a776a 100644 --- a/tools/gn/xcode_object.h +++ b/tools/gn/xcode_object.h
@@ -218,7 +218,10 @@ const std::string& path() const { return path_; } PBXObject* AddChild(std::unique_ptr<PBXObject> child); - PBXFileReference* AddSourceFile(const std::string& source_path); + PBXFileReference* AddSourceFile(const std::string& navigator_path, + const std::string& source_path); + bool is_source() { return is_source_; } + void set_is_source(const bool is_source) { is_source_ = is_source; } // PBXObject implementation. PBXObjectClass Class() const override; @@ -230,6 +233,7 @@ std::vector<std::unique_ptr<PBXObject>> children_; std::string name_; std::string path_; + bool is_source_ = false; DISALLOW_COPY_AND_ASSIGN(PBXGroup); }; @@ -271,7 +275,8 @@ const PBXAttributes& attributes); ~PBXProject() override; - void AddSourceFile(const std::string& source_path); + void AddSourceFile(const std::string& navigator_path, + const std::string& source_path); void AddAggregateTarget(const std::string& name, const std::string& shell_script); void AddNativeTarget(const std::string& name,
diff --git a/tools/gn/xcode_writer.cc b/tools/gn/xcode_writer.cc index 633a1c8..07b50e4 100644 --- a/tools/gn/xcode_writer.cc +++ b/tools/gn/xcode_writer.cc
@@ -353,7 +353,7 @@ for (const SourceFile& source : sources) { std::string source_file = RebasePath(source.value(), source_dir, absolute_source_path); - sources_for_indexing->AddSourceFile(source_file); + sources_for_indexing->AddSourceFile(source_file, source_file); } projects_.push_back(std::move(sources_for_indexing));