1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #ifndef SNGCM_AST_PROJECT_INCLUDED
  7 #define SNGCM_AST_PROJECT_INCLUDED
  8 #include <sngcm/ast/AstApi.hpp>
  9 #include <soulng/util/CodeFormatter.hpp>
 10 #include <boost/filesystem.hpp>
 11 #include <string>
 12 #include <vector>
 13 #include <memory>
 14 #include <set>
 15 
 16 namespace sngcm { namespace ast {
 17 
 18 using namespace soulng::util;
 19 
 20 enum class BackEnd : int8_t 
 21 {
 22     llvm=  0cmsx=  1cppcm=  2
 23 };
 24 
 25 enum class Config : int8_t 
 26 {
 27     debug=  0release=  1profile=  2trace=  3
 28 };
 29 
 30 class ModuleVersionTagVerifier 
 31 {
 32 public:
 33     virtual void VerifyModuleVersionTag(const std::string& moduleFilePath) = 0;
 34 };
 35 
 36 void SetModuleVersionTagVerifier(ModuleVersionTagVerifier* verifier);
 37 
 38 enum class SystemDirKind : int 
 39 {
 40     regular=  0repository=  1
 41 };
 42 
 43 class Project;
 44 class Solution;
 45 
 46 std::string CmajorRootDir();
 47 std::string CmajorSystemLibDir(const std::string& configBackEnd backendconst std::string& toolChainSystemDirKind systemDirKind);
 48 std::string CmajorResourceDir();
 49 std::string CmajorLogFileDir();
 50 std::string CmajorSystemModuleFilePath(const std::string& configBackEnd backendconst std::string& toolChainSystemDirKind systemDirKind);
 51 std::string CmajorSystemWindowsModuleFilePath(const std::string& configconst std::string& toolChaninSystemDirKind systemDirKind);
 52 std::string MakeCmajorRootRelativeFilePath(const std::string& filePath);
 53 std::string ExpandCmajorRootRelativeFilePath(const std::string& filePath);
 54 std::vector<Project*> GetReferencedProjects(Project* projectSolution* solution);
 55 std::set<Project*> GetAllReferencedProjects(Project* projectSolution* solution);
 56 void AddReferencedProjects(std::std::set<Project*>&allReferencedProjectsProject*projectSolution*solution);
 57 void SetOutDir(const std::string& outDir_);
 58 const std::string& OutDir();
 59 
 60 enum class ProjectDeclarationType : uint8_t 
 61 {
 62     referenceDeclarationsourceFileDeclarationresourceFileDeclarationtextFileDeclarationtargetDeclaration
 63 };
 64 
 65 class ProjectDeclaration 
 66 {
 67 public:
 68     ProjectDeclaration(ProjectDeclarationType declarationType_);
 69     ProjectDeclaration(const ProjectDeclaration&) = delete;
 70     ProjectDeclaration& operator=(const ProjectDeclaration&) = delete;
 71     virtual ~ProjectDeclaration();
 72     ProjectDeclarationType GetDeclarationType() const { return declarationType; }
 73     virtual void Write(CodeFormatter& formatter) = 0;
 74 private:
 75     ProjectDeclarationType declarationType;
 76 };
 77 
 78 class ReferenceDeclaration public ProjectDeclaration
 79 {
 80 public:
 81     ReferenceDeclaration(const std::string& filePath_);
 82     const std::string& FilePath() const { return filePath; }
 83     void Write(CodeFormatter& formatter) override;
 84 private:
 85     std::string filePath;
 86 };
 87 
 88 class SourceFileDeclaration public ProjectDeclaration
 89 {
 90 public:
 91     SourceFileDeclaration(const std::string& filePath_);
 92     const std::string& FilePath() const { return filePath; }
 93     void Write(CodeFormatter& formatter) override;
 94 private:
 95     std::string filePath;
 96 };
 97 
 98 class ResourceFileDeclaration public ProjectDeclaration
 99 {
100 public:
101     ResourceFileDeclaration(const std::string& filePath_);
102     const std::string& FilePath() const { return filePath; }
103     void Write(CodeFormatter& formatter) override;
104 private:
105     std::string filePath;
106 };
107 
108 class TextFileDeclaration public ProjectDeclaration
109 {
110 public:
111     TextFileDeclaration(const std::string& filePath_);
112     const std::string& FilePath() const { return filePath; }
113     void Write(CodeFormatter& formatter) override;
114 private:
115     std::string filePath;
116 };
117 
118 enum class Target
119 {
120     programwinguiappwinapplibrarywinlibunitTest
121 };
122 
123 std::string TargetStr(Target target);
124 
125 Target ParseTarget(const std::string& targetStr);
126 
127 class TargetDeclaration public ProjectDeclaration
128 {
129 public:
130     TargetDeclaration(Target target_);
131     Target GetTarget() const { return target; }
132     void Write(CodeFormatter& formatter) override;
133 private:
134     Target target;
135 };
136 
137 class Project 
138 {
139 public:
140     Project(const std::u32string& name_const std::string& filePath_const std::string& config_BackEnd backend_const std::string& toolChain_
141         SystemDirKind systemDirKind);
142     Project(const Project&) = delete;
143     Project& operator=(const Project&) = delete;
144     const std::u32string& Name() const { return name; }
145     const std::string& FilePath() const { return filePath; }
146     const boost::filesystem::path& SourceBasePath() const { return sourceBasePath; }
147     const boost::filesystem::path& OutdirBasePath() const { return outdirBasePath; }
148     void AddDeclaration(ProjectDeclaration* declaration);
149     void ResolveDeclarations();
150     void Write(const std::string& projectFilePath);
151     const std::string& ModuleFilePath() const { return moduleFilePath; }
152     const std::string& LibraryFilePath() const { return libraryFilePath; }
153     const std::string& ExecutableFilePath() const { return executableFilePath; }
154     const std::std::vector<std::string>&References() const{returnreferences;}
155     const std::std::vector<std::string>&ReferencedProjectFilePaths() const{returnreferencedProjectFilePaths;}
156     const std::std::vector<std::string>&RelativeReferencedProjectFilePaths() const{returnrelativeReferencedProjectFilePaths;}
157     const std::std::vector<std::string>&SourceFilePaths() const{returnsourceFilePaths;}
158     const std::std::vector<std::string>&RelativeSourceFilePaths() const{returnrelativeSourceFilePaths;}
159     const std::std::vector<std::string>&ResourceFilePaths() const{returnresourceFilePaths; }
160     const std::std::vector<std::string>&RelativeResourceFilePaths() const{returnrelativeResourceFilePaths;}
161     const std::std::vector<std::string>&RelativeTextFilePaths() const{returnrelativeTextFilePaths;}
162     const std::std::vector<std::string>&TextFilePaths() const{returntextFilePaths;}
163     Target GetTarget() const { return target; }
164     void SetTarget(Target target_) { target = target_; }
165     bool DependsOn(Project* that) const;
166     void AddDependsOnProjects(Project* dependsOnProject);
167     bool IsSystemProject() const { return isSystemProject; }
168     void SetSystemProject() { isSystemProject = true; }
169     void SetRelativeFilePath(const std::string& relativeFilePath_) { relativeFilePath = relativeFilePath_; }
170     const std::string& RelativeFilePath() const { return relativeFilePath; }
171     void SetModuleFilePath(const std::string& moduleFilePath_);
172     void SetLibraryFilePath(const std::string& libraryFilePath_);
173     void SetReferencedProjects(const std::std::vector<Project*>&referencedProjects);
174     bool IsUpToDate(const std::string& systemModuleFilePath) const;
175     int LogStreamId() const { return logStreamId; }
176     void SetLogStreamId(int logStreamId_) { logStreamId = logStreamId_; }
177     void SetIndex(int index_) { index = index_; }
178     int Index() const { return index; }
179     const std::std::vector<Project*>&DependsOnProjects(){returndependsOn;}
180     bool Built();
181     void SetBuilt();
182     bool Ready();
183     void SetExcludeSourceFilePath(const std::string& excludeSourceFilePath_);
184     void SetHash(const std::string& hash_) { hash = hash_; }
185     const std::string& Hash() const { return hash; }
186     std::string Id() const;
187     void AddDependsOnId(const std::string& dependsOnId);
188     const std::std::vector<std::string>&DependsOnIds() const{returndependsOnIds;}
189     bool HasSourceFile(const std::string& sourceFilePath) const;
190     bool HasResourceFile(const std::string& resourceFilePath) const;
191     bool HasTextFile(const std::string& textFilePath) const;
192     void AddSourceFileName(const std::string& sourceFileNameconst std::string& sourceFilePath);
193     void AddResourceFileName(const std::string& resourceFileNameconst std::string& resourceFilePath);
194     void AddTextFileName(const std::string& textFileNameconst std::string& textFilePath);
195     void RemoveFile(const std::string& filePathconst std::string& fileName);
196     void Save();
197 private:
198     BackEnd backend;
199     std::string toolChain;
200     std::u32string name;
201     std::string filePath;
202     std::string config;
203     Target target;
204     boost::filesystem::path sourceBasePath;
205     boost::filesystem::path outdirBasePath;
206     boost::filesystem::path systemLibDir;
207     std::vector<std::std::unique_ptr<ProjectDeclaration>>declarations;
208     std::string relativeFilePath;
209     std::string moduleFilePath;
210     std::string libraryFilePath;
211     std::string executableFilePath;
212     std::string excludeSourceFilePath;
213     std::vector<std::string> references;
214     std::vector<std::string> referencedProjectFilePaths;
215     std::vector<std::string> sourceFilePaths;
216     std::vector<std::string> relativeSourceFilePaths;
217     std::vector<std::string> resourceFilePaths;
218     std::vector<std::string> relativeResourceFilePaths;
219     std::vector<std::string> relativeReferencedProjectFilePaths;
220     std::vector<std::string> relativeTextFilePaths;
221     std::vector<std::string> textFilePaths;
222     std::vector<Project*> dependsOn;
223     bool built;
224     bool isSystemProject;
225     int logStreamId;
226     int index;
227     std::string hash;
228     std::vector<std::string> dependsOnIds;
229     std::mutex mtx;
230 };
231 
232 
233 } } // namespace sngcm::ast
234 
235 #endif // SNGCM_AST_PROJECT_INCLUDED