| // Copyright 2016 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef TOOLS_GN_XCODE_OBJECT_H_ | 
 | #define TOOLS_GN_XCODE_OBJECT_H_ | 
 |  | 
 | #include <iosfwd> | 
 | #include <map> | 
 | #include <memory> | 
 | #include <string> | 
 | #include <vector> | 
 |  | 
 | // Helper classes to generate Xcode project files. | 
 | // | 
 | // This code is based on gyp xcodeproj_file.py generator. It does not support | 
 | // all features of Xcode project but instead just enough to implement a hybrid | 
 | // mode where Xcode uses external scripts to perform the compilation steps. | 
 | // | 
 | // See | 
 | // https://chromium.googlesource.com/external/gyp/+/master/pylib/gyp/xcodeproj_file.py | 
 | // for more information on Xcode project file format. | 
 |  | 
 | // PBXObjectClass ------------------------------------------------------------- | 
 |  | 
 | enum PBXObjectClass { | 
 |   // Those values needs to stay sorted in alphabetic order. | 
 |   PBXAggregateTargetClass, | 
 |   PBXBuildFileClass, | 
 |   PBXContainerItemProxyClass, | 
 |   PBXFileReferenceClass, | 
 |   PBXFrameworksBuildPhaseClass, | 
 |   PBXGroupClass, | 
 |   PBXNativeTargetClass, | 
 |   PBXProjectClass, | 
 |   PBXResourcesBuildPhaseClass, | 
 |   PBXShellScriptBuildPhaseClass, | 
 |   PBXSourcesBuildPhaseClass, | 
 |   PBXTargetDependencyClass, | 
 |   XCBuildConfigurationClass, | 
 |   XCConfigurationListClass, | 
 | }; | 
 |  | 
 | const char* ToString(PBXObjectClass cls); | 
 |  | 
 | // Forward-declarations ------------------------------------------------------- | 
 |  | 
 | class PBXAggregateTarget; | 
 | class PBXBuildFile; | 
 | class PBXBuildPhase; | 
 | class PBXContainerItemProxy; | 
 | class PBXFileReference; | 
 | class PBXFrameworksBuildPhase; | 
 | class PBXGroup; | 
 | class PBXNativeTarget; | 
 | class PBXObject; | 
 | class PBXProject; | 
 | class PBXResourcesBuildPhase; | 
 | class PBXShellScriptBuildPhase; | 
 | class PBXSourcesBuildPhase; | 
 | class PBXTarget; | 
 | class PBXTargetDependency; | 
 | class XCBuildConfiguration; | 
 | class XCConfigurationList; | 
 |  | 
 | using PBXAttributes = std::map<std::string, std::string>; | 
 |  | 
 | // PBXObjectVisitor ----------------------------------------------------------- | 
 |  | 
 | class PBXObjectVisitor { | 
 |  public: | 
 |   PBXObjectVisitor(); | 
 |   virtual ~PBXObjectVisitor(); | 
 |   virtual void Visit(PBXObject* object) = 0; | 
 |  | 
 |  private: | 
 |   PBXObjectVisitor(const PBXObjectVisitor&) = delete; | 
 |   PBXObjectVisitor& operator=(const PBXObjectVisitor&) = delete; | 
 | }; | 
 |  | 
 | // PBXObjectVisitorConst ------------------------------------------------------ | 
 |  | 
 | class PBXObjectVisitorConst { | 
 |  public: | 
 |   PBXObjectVisitorConst(); | 
 |   virtual ~PBXObjectVisitorConst(); | 
 |   virtual void Visit(const PBXObject* object) = 0; | 
 |  | 
 |  private: | 
 |   PBXObjectVisitorConst(const PBXObjectVisitorConst&) = delete; | 
 |   PBXObjectVisitorConst& operator=(const PBXObjectVisitorConst&) = delete; | 
 | }; | 
 |  | 
 | // PBXObject ------------------------------------------------------------------ | 
 |  | 
 | class PBXObject { | 
 |  public: | 
 |   PBXObject(); | 
 |   virtual ~PBXObject(); | 
 |  | 
 |   const std::string id() const { return id_; } | 
 |   void SetId(const std::string& id); | 
 |  | 
 |   std::string Reference() const; | 
 |  | 
 |   virtual PBXObjectClass Class() const = 0; | 
 |   virtual std::string Name() const = 0; | 
 |   virtual std::string Comment() const; | 
 |   virtual void Visit(PBXObjectVisitor& visitor); | 
 |   virtual void Visit(PBXObjectVisitorConst& visitor) const; | 
 |   virtual void Print(std::ostream& out, unsigned indent) const = 0; | 
 |  | 
 |  private: | 
 |   std::string id_; | 
 |  | 
 |   PBXObject(const PBXObject&) = delete; | 
 |   PBXObject& operator=(const PBXObject&) = delete; | 
 | }; | 
 |  | 
 | // PBXBuildPhase -------------------------------------------------------------- | 
 |  | 
 | class PBXBuildPhase : public PBXObject { | 
 |  public: | 
 |   PBXBuildPhase(); | 
 |   ~PBXBuildPhase() override; | 
 |  | 
 |   void AddBuildFile(std::unique_ptr<PBXBuildFile> build_file); | 
 |  | 
 |   // PBXObject implementation. | 
 |   void Visit(PBXObjectVisitor& visitor) override; | 
 |   void Visit(PBXObjectVisitorConst& visitor) const override; | 
 |  | 
 |  protected: | 
 |   std::vector<std::unique_ptr<PBXBuildFile>> files_; | 
 |  | 
 |  private: | 
 |   PBXBuildPhase(const PBXBuildPhase&) = delete; | 
 |   PBXBuildPhase& operator=(const PBXBuildPhase&) = delete; | 
 | }; | 
 |  | 
 | // PBXTarget ------------------------------------------------------------------ | 
 |  | 
 | class PBXTarget : public PBXObject { | 
 |  public: | 
 |   PBXTarget(const std::string& name, | 
 |             const std::string& shell_script, | 
 |             const std::vector<std::string>& configs, | 
 |             const PBXAttributes& attributes); | 
 |   ~PBXTarget() override; | 
 |  | 
 |   void AddDependency(std::unique_ptr<PBXTargetDependency> dependency); | 
 |  | 
 |   // PBXObject implementation. | 
 |   std::string Name() const override; | 
 |   void Visit(PBXObjectVisitor& visitor) override; | 
 |   void Visit(PBXObjectVisitorConst& visitor) const override; | 
 |  | 
 |  protected: | 
 |   std::unique_ptr<XCConfigurationList> configurations_; | 
 |   std::vector<std::unique_ptr<PBXBuildPhase>> build_phases_; | 
 |   std::vector<std::unique_ptr<PBXTargetDependency>> dependencies_; | 
 |   PBXSourcesBuildPhase* source_build_phase_ = nullptr; | 
 |   PBXResourcesBuildPhase* resource_build_phase_ = nullptr; | 
 |   std::string name_; | 
 |  | 
 |  private: | 
 |   PBXTarget(const PBXTarget&) = delete; | 
 |   PBXTarget& operator=(const PBXTarget&) = delete; | 
 | }; | 
 |  | 
 | // PBXAggregateTarget --------------------------------------------------------- | 
 |  | 
 | class PBXAggregateTarget : public PBXTarget { | 
 |  public: | 
 |   PBXAggregateTarget(const std::string& name, | 
 |                      const std::string& shell_script, | 
 |                      const std::vector<std::string>& configs, | 
 |                      const PBXAttributes& attributes); | 
 |   ~PBXAggregateTarget() override; | 
 |  | 
 |   // PBXObject implementation. | 
 |   PBXObjectClass Class() const override; | 
 |   void Print(std::ostream& out, unsigned indent) const override; | 
 |  | 
 |  private: | 
 |   PBXAggregateTarget(const PBXAggregateTarget&) = delete; | 
 |   PBXAggregateTarget& operator=(const PBXAggregateTarget&) = delete; | 
 | }; | 
 |  | 
 | // PBXBuildFile --------------------------------------------------------------- | 
 |  | 
 | class PBXBuildFile : public PBXObject { | 
 |  public: | 
 |   PBXBuildFile(const PBXFileReference* file_reference, | 
 |                const PBXBuildPhase* build_phase); | 
 |   ~PBXBuildFile() override; | 
 |  | 
 |   // PBXObject implementation. | 
 |   PBXObjectClass Class() const override; | 
 |   std::string Name() const override; | 
 |   void Print(std::ostream& out, unsigned indent) const override; | 
 |  | 
 |  private: | 
 |   const PBXFileReference* file_reference_ = nullptr; | 
 |   const PBXBuildPhase* build_phase_ = nullptr; | 
 |  | 
 |   PBXBuildFile(const PBXBuildFile&) = delete; | 
 |   PBXBuildFile& operator=(const PBXBuildFile&) = delete; | 
 | }; | 
 |  | 
 | // PBXContainerItemProxy ------------------------------------------------------ | 
 | class PBXContainerItemProxy : public PBXObject { | 
 |  public: | 
 |   PBXContainerItemProxy(const PBXProject* project, const PBXTarget* target); | 
 |   ~PBXContainerItemProxy() override; | 
 |  | 
 |   // PBXObject implementation. | 
 |   PBXObjectClass Class() const override; | 
 |   std::string Name() const override; | 
 |   void Print(std::ostream& out, unsigned indent) const override; | 
 |  | 
 |  private: | 
 |   const PBXProject* project_ = nullptr; | 
 |   const PBXTarget* target_ = nullptr; | 
 |  | 
 |   PBXContainerItemProxy(const PBXContainerItemProxy&) = delete; | 
 |   PBXContainerItemProxy& operator=(const PBXContainerItemProxy&) = delete; | 
 | }; | 
 |  | 
 | // PBXFileReference ----------------------------------------------------------- | 
 |  | 
 | class PBXFileReference : public PBXObject { | 
 |  public: | 
 |   PBXFileReference(const std::string& name, | 
 |                    const std::string& path, | 
 |                    const std::string& type); | 
 |   ~PBXFileReference() override; | 
 |  | 
 |   // PBXObject implementation. | 
 |   PBXObjectClass Class() const override; | 
 |   std::string Name() const override; | 
 |   std::string Comment() const override; | 
 |   void Print(std::ostream& out, unsigned indent) const override; | 
 |  | 
 |   const std::string& path() const { return path_; } | 
 |  | 
 |  private: | 
 |   std::string name_; | 
 |   std::string path_; | 
 |   std::string type_; | 
 |  | 
 |   PBXFileReference(const PBXFileReference&) = delete; | 
 |   PBXFileReference& operator=(const PBXFileReference&) = delete; | 
 | }; | 
 |  | 
 | // PBXFrameworksBuildPhase ---------------------------------------------------- | 
 |  | 
 | class PBXFrameworksBuildPhase : public PBXBuildPhase { | 
 |  public: | 
 |   PBXFrameworksBuildPhase(); | 
 |   ~PBXFrameworksBuildPhase() override; | 
 |  | 
 |   // PBXObject implementation. | 
 |   PBXObjectClass Class() const override; | 
 |   std::string Name() const override; | 
 |   void Print(std::ostream& out, unsigned indent) const override; | 
 |  | 
 |  private: | 
 |   PBXFrameworksBuildPhase(const PBXFrameworksBuildPhase&) = delete; | 
 |   PBXFrameworksBuildPhase& operator=(const PBXFrameworksBuildPhase&) = delete; | 
 | }; | 
 |  | 
 | // PBXGroup ------------------------------------------------------------------- | 
 |  | 
 | class PBXGroup : public PBXObject { | 
 |  public: | 
 |   explicit PBXGroup(const std::string& path = std::string(), | 
 |                     const std::string& name = std::string()); | 
 |   ~PBXGroup() override; | 
 |  | 
 |   const std::string& path() const { return path_; } | 
 |   const std::string& name() const { return name_; } | 
 |  | 
 |   PBXFileReference* AddSourceFile(const std::string& navigator_path, | 
 |                                   const std::string& source_path); | 
 |  | 
 |   template <typename T, typename... Args> | 
 |   T* CreateChild(Args&&... args) { | 
 |     return static_cast<T*>( | 
 |         AddChildImpl(std::make_unique<T>(std::forward<Args>(args)...))); | 
 |   } | 
 |  | 
 |   // PBXObject implementation. | 
 |   PBXObjectClass Class() const override; | 
 |   std::string Name() const override; | 
 |   void Visit(PBXObjectVisitor& visitor) override; | 
 |   void Visit(PBXObjectVisitorConst& visitor) const override; | 
 |   void Print(std::ostream& out, unsigned indent) const override; | 
 |  | 
 |   // Returns whether the current PBXGroup should sort last when sorting | 
 |   // children of a PBXGroup. This should only be used for the "Products" | 
 |   // group which is hidden in Xcode UI when it is the last children of | 
 |   // the main PBXProject group. | 
 |   virtual bool SortLast() const; | 
 |  | 
 |  private: | 
 |   PBXObject* AddChildImpl(std::unique_ptr<PBXObject> child); | 
 |  | 
 |   std::vector<std::unique_ptr<PBXObject>> children_; | 
 |   std::string name_; | 
 |   std::string path_; | 
 |  | 
 |   PBXGroup(const PBXGroup&) = delete; | 
 |   PBXGroup& operator=(const PBXGroup&) = delete; | 
 | }; | 
 |  | 
 | // PBXMainGroup --------------------------------------------------------------- | 
 |  | 
 | class PBXMainGroup : public PBXGroup { | 
 |  public: | 
 |   explicit PBXMainGroup(const std::string& source_path); | 
 |   ~PBXMainGroup() override; | 
 |  | 
 |   std::string Name() const override; | 
 | }; | 
 |  | 
 | // PBXProductsGroup ----------------------------------------------------------- | 
 |  | 
 | class PBXProductsGroup : public PBXGroup { | 
 |  public: | 
 |   explicit PBXProductsGroup(); | 
 |   ~PBXProductsGroup() override; | 
 |  | 
 |   bool SortLast() const override; | 
 | }; | 
 |  | 
 | // PBXNativeTarget ------------------------------------------------------------ | 
 |  | 
 | class PBXNativeTarget : public PBXTarget { | 
 |  public: | 
 |   PBXNativeTarget(const std::string& name, | 
 |                   const std::string& shell_script, | 
 |                   const std::vector<std::string>& configs, | 
 |                   const PBXAttributes& attributes, | 
 |                   const std::string& product_type, | 
 |                   const std::string& product_name, | 
 |                   const PBXFileReference* product_reference); | 
 |   ~PBXNativeTarget() override; | 
 |  | 
 |   void AddResourceFile(const PBXFileReference* file_reference); | 
 |  | 
 |   void AddFileForIndexing(const PBXFileReference* file_reference); | 
 |  | 
 |   // PBXObject implementation. | 
 |   PBXObjectClass Class() const override; | 
 |   void Print(std::ostream& out, unsigned indent) const override; | 
 |  | 
 |  private: | 
 |   const PBXFileReference* product_reference_ = nullptr; | 
 |   std::string product_type_; | 
 |   std::string product_name_; | 
 |  | 
 |   PBXNativeTarget(const PBXNativeTarget&) = delete; | 
 |   PBXNativeTarget& operator=(const PBXNativeTarget&) = delete; | 
 | }; | 
 |  | 
 | // PBXProject ----------------------------------------------------------------- | 
 |  | 
 | class PBXProject : public PBXObject { | 
 |  public: | 
 |   PBXProject(const std::string& name, | 
 |              std::vector<std::string> configs, | 
 |              const std::string& source_path, | 
 |              const PBXAttributes& attributes); | 
 |   ~PBXProject() override; | 
 |  | 
 |   void AddSourceFileToIndexingTarget(const std::string& navigator_path, | 
 |                                      const std::string& source_path); | 
 |   void AddSourceFile(const std::string& navigator_path, | 
 |                      const std::string& source_path, | 
 |                      PBXNativeTarget* target); | 
 |   void AddAggregateTarget(const std::string& name, | 
 |                           const std::string& output_dir, | 
 |                           const std::string& shell_script); | 
 |   void AddIndexingTarget(); | 
 |   PBXNativeTarget* AddNativeTarget( | 
 |       const std::string& name, | 
 |       const std::string& type, | 
 |       const std::string& output_dir, | 
 |       const std::string& output_name, | 
 |       const std::string& output_type, | 
 |       const std::string& shell_script, | 
 |       const PBXAttributes& extra_attributes = PBXAttributes()); | 
 |  | 
 |   void SetProjectDirPath(const std::string& project_dir_path); | 
 |   void SetProjectRoot(const std::string& project_root); | 
 |   void AddTarget(std::unique_ptr<PBXTarget> target); | 
 |  | 
 |   // PBXObject implementation. | 
 |   PBXObjectClass Class() const override; | 
 |   std::string Name() const override; | 
 |   std::string Comment() const override; | 
 |   void Visit(PBXObjectVisitor& visitor) override; | 
 |   void Visit(PBXObjectVisitorConst& visitor) const override; | 
 |   void Print(std::ostream& out, unsigned indent) const override; | 
 |  | 
 |  private: | 
 |   PBXAttributes attributes_; | 
 |   std::unique_ptr<XCConfigurationList> configurations_; | 
 |   std::unique_ptr<PBXGroup> main_group_; | 
 |   std::string project_dir_path_; | 
 |   std::string project_root_; | 
 |   std::vector<std::unique_ptr<PBXTarget>> targets_; | 
 |   std::string name_; | 
 |   std::vector<std::string> configs_; | 
 |  | 
 |   PBXGroup* products_ = nullptr; | 
 |   PBXNativeTarget* target_for_indexing_ = nullptr; | 
 |  | 
 |   PBXProject(const PBXProject&) = delete; | 
 |   PBXProject& operator=(const PBXProject&) = delete; | 
 | }; | 
 |  | 
 | // PBXResourcesBuildPhase ----------------------------------------------------- | 
 |  | 
 | class PBXResourcesBuildPhase : public PBXBuildPhase { | 
 |  public: | 
 |   PBXResourcesBuildPhase(); | 
 |   ~PBXResourcesBuildPhase() override; | 
 |  | 
 |   // PBXObject implementation. | 
 |   PBXObjectClass Class() const override; | 
 |   std::string Name() const override; | 
 |   void Print(std::ostream& out, unsigned indent) const override; | 
 |  | 
 |  private: | 
 |   PBXResourcesBuildPhase(const PBXResourcesBuildPhase&) = delete; | 
 |   PBXResourcesBuildPhase& operator=(const PBXResourcesBuildPhase&) = delete; | 
 | }; | 
 |  | 
 | // PBXShellScriptBuildPhase --------------------------------------------------- | 
 |  | 
 | class PBXShellScriptBuildPhase : public PBXBuildPhase { | 
 |  public: | 
 |   PBXShellScriptBuildPhase(const std::string& name, | 
 |                            const std::string& shell_script); | 
 |   ~PBXShellScriptBuildPhase() override; | 
 |  | 
 |   // PBXObject implementation. | 
 |   PBXObjectClass Class() const override; | 
 |   std::string Name() const override; | 
 |   void Print(std::ostream& out, unsigned indent) const override; | 
 |  | 
 |  private: | 
 |   std::string name_; | 
 |   std::string shell_script_; | 
 |  | 
 |   PBXShellScriptBuildPhase(const PBXShellScriptBuildPhase&) = delete; | 
 |   PBXShellScriptBuildPhase& operator=(const PBXShellScriptBuildPhase&) = delete; | 
 | }; | 
 |  | 
 | // PBXSourcesBuildPhase ------------------------------------------------------- | 
 |  | 
 | class PBXSourcesBuildPhase : public PBXBuildPhase { | 
 |  public: | 
 |   PBXSourcesBuildPhase(); | 
 |   ~PBXSourcesBuildPhase() override; | 
 |  | 
 |   // PBXObject implementation. | 
 |   PBXObjectClass Class() const override; | 
 |   std::string Name() const override; | 
 |   void Print(std::ostream& out, unsigned indent) const override; | 
 |  | 
 |  private: | 
 |   PBXSourcesBuildPhase(const PBXSourcesBuildPhase&) = delete; | 
 |   PBXSourcesBuildPhase& operator=(const PBXSourcesBuildPhase&) = delete; | 
 | }; | 
 |  | 
 | // PBXTargetDependency ----------------------------------------------------- | 
 | class PBXTargetDependency : public PBXObject { | 
 |  public: | 
 |   PBXTargetDependency( | 
 |       const PBXTarget* target, | 
 |       std::unique_ptr<PBXContainerItemProxy> container_item_proxy); | 
 |   ~PBXTargetDependency() override; | 
 |  | 
 |   // PBXObject implementation. | 
 |   PBXObjectClass Class() const override; | 
 |   std::string Name() const override; | 
 |   void Visit(PBXObjectVisitor& visitor) override; | 
 |   void Visit(PBXObjectVisitorConst& visitor) const override; | 
 |   void Print(std::ostream& out, unsigned indent) const override; | 
 |  | 
 |  private: | 
 |   const PBXTarget* target_ = nullptr; | 
 |   std::unique_ptr<PBXContainerItemProxy> container_item_proxy_; | 
 |  | 
 |   PBXTargetDependency(const PBXTargetDependency&) = delete; | 
 |   PBXTargetDependency& operator=(const PBXTargetDependency&) = delete; | 
 | }; | 
 |  | 
 | // XCBuildConfiguration ------------------------------------------------------- | 
 |  | 
 | class XCBuildConfiguration : public PBXObject { | 
 |  public: | 
 |   XCBuildConfiguration(const std::string& name, | 
 |                        const PBXAttributes& attributes); | 
 |   ~XCBuildConfiguration() override; | 
 |  | 
 |   // PBXObject implementation. | 
 |   PBXObjectClass Class() const override; | 
 |   std::string Name() const override; | 
 |   void Print(std::ostream& out, unsigned indent) const override; | 
 |  | 
 |  private: | 
 |   PBXAttributes attributes_; | 
 |   std::string name_; | 
 |  | 
 |   XCBuildConfiguration(const XCBuildConfiguration&) = delete; | 
 |   XCBuildConfiguration& operator=(const XCBuildConfiguration&) = delete; | 
 | }; | 
 |  | 
 | // XCConfigurationList -------------------------------------------------------- | 
 |  | 
 | class XCConfigurationList : public PBXObject { | 
 |  public: | 
 |   XCConfigurationList(const std::vector<std::string>& configs, | 
 |                       const PBXAttributes& attributes, | 
 |                       const PBXObject* owner_reference); | 
 |   ~XCConfigurationList() override; | 
 |  | 
 |   // PBXObject implementation. | 
 |   PBXObjectClass Class() const override; | 
 |   std::string Name() const override; | 
 |   void Visit(PBXObjectVisitor& visitor) override; | 
 |   void Visit(PBXObjectVisitorConst& visitor) const override; | 
 |   void Print(std::ostream& out, unsigned indent) const override; | 
 |  | 
 |  private: | 
 |   std::vector<std::unique_ptr<XCBuildConfiguration>> configurations_; | 
 |   const PBXObject* owner_reference_ = nullptr; | 
 |  | 
 |   XCConfigurationList(const XCConfigurationList&) = delete; | 
 |   XCConfigurationList& operator=(const XCConfigurationList&) = delete; | 
 | }; | 
 |  | 
 | #endif  // TOOLS_GN_XCODE_OBJECT_H_ |