summaryrefslogtreecommitdiffstats
path: root/Source/cmFileAPICodemodel.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2018-11-13 12:00:33 (GMT)
committerKyle Edwards <kyle.edwards@kitware.com>2018-12-12 20:12:26 (GMT)
commiteb8c7676a4723a44245e47630f12d4868e8e182c (patch)
tree20ffcfb48ea6f109eedf1dddf016f740db9b1640 /Source/cmFileAPICodemodel.cxx
parent42f0125ceb6c34ce5a67e9954d1831b2aeb263ba (diff)
downloadCMake-eb8c7676a4723a44245e47630f12d4868e8e182c.zip
CMake-eb8c7676a4723a44245e47630f12d4868e8e182c.tar.gz
CMake-eb8c7676a4723a44245e47630f12d4868e8e182c.tar.bz2
fileapi: extend codemodel v2 with a project model
Offer clients a `project()`-centric view of the build system. This is similar to the directory-centric view but consolidates subdirectories that do not call `project()` with a new project name. Issue: #18398 Co-Author: Kyle Edwards <kyle.edwards@kitware.com>
Diffstat (limited to 'Source/cmFileAPICodemodel.cxx')
-rw-r--r--Source/cmFileAPICodemodel.cxx86
1 files changed, 86 insertions, 0 deletions
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index 3d4a7cf..d432c1e 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -63,22 +63,42 @@ class CodemodelConfig
{
cmStateSnapshot Snapshot;
Json::Value TargetIndexes = Json::arrayValue;
+ Json::ArrayIndex ProjectIndex;
};
std::map<cmStateSnapshot, Json::ArrayIndex, cmStateSnapshot::StrictWeakOrder>
DirectoryMap;
std::vector<Directory> Directories;
+ struct Project
+ {
+ cmStateSnapshot Snapshot;
+ static const Json::ArrayIndex NoParentIndex =
+ static_cast<Json::ArrayIndex>(-1);
+ Json::ArrayIndex ParentIndex = NoParentIndex;
+ Json::Value ChildIndexes = Json::arrayValue;
+ Json::Value DirectoryIndexes = Json::arrayValue;
+ Json::Value TargetIndexes = Json::arrayValue;
+ };
+ std::map<cmStateSnapshot, Json::ArrayIndex, cmStateSnapshot::StrictWeakOrder>
+ ProjectMap;
+ std::vector<Project> Projects;
+
void ProcessDirectories();
Json::ArrayIndex GetDirectoryIndex(cmLocalGenerator const* lg);
Json::ArrayIndex GetDirectoryIndex(cmStateSnapshot s);
+ Json::ArrayIndex AddProject(cmStateSnapshot s);
+
Json::Value DumpTargets();
Json::Value DumpTarget(cmGeneratorTarget* gt, Json::ArrayIndex ti);
Json::Value DumpDirectories();
Json::Value DumpDirectory(Directory& d);
+ Json::Value DumpProjects();
+ Json::Value DumpProject(Project& p);
+
public:
CodemodelConfig(cmFileAPI& fileAPI, unsigned long version,
std::string const& config);
@@ -358,6 +378,7 @@ Json::Value CodemodelConfig::Dump()
this->ProcessDirectories();
configuration["targets"] = this->DumpTargets();
configuration["directories"] = this->DumpDirectories();
+ configuration["projects"] = this->DumpProjects();
return configuration;
}
@@ -376,6 +397,9 @@ void CodemodelConfig::ProcessDirectories()
Directory& d = this->Directories[directoryIndex];
d.Snapshot = lg->GetStateSnapshot().GetBuildsystemDirectory();
this->DirectoryMap[d.Snapshot] = directoryIndex;
+
+ d.ProjectIndex = this->AddProject(d.Snapshot);
+ this->Projects[d.ProjectIndex].DirectoryIndexes.append(directoryIndex);
}
}
@@ -392,6 +416,29 @@ Json::ArrayIndex CodemodelConfig::GetDirectoryIndex(cmStateSnapshot s)
return i->second;
}
+Json::ArrayIndex CodemodelConfig::AddProject(cmStateSnapshot s)
+{
+ cmStateSnapshot ps = s.GetBuildsystemDirectoryParent();
+ if (ps.IsValid() && ps.GetProjectName() == s.GetProjectName()) {
+ // This directory is part of its parent directory project.
+ Json::ArrayIndex const parentDirIndex = this->GetDirectoryIndex(ps);
+ return this->Directories[parentDirIndex].ProjectIndex;
+ }
+
+ // This directory starts a new project.
+ auto projectIndex = static_cast<Json::ArrayIndex>(this->Projects.size());
+ this->Projects.emplace_back();
+ Project& p = this->Projects[projectIndex];
+ p.Snapshot = s;
+ this->ProjectMap[s] = projectIndex;
+ if (ps.IsValid()) {
+ Json::ArrayIndex const parentDirIndex = this->GetDirectoryIndex(ps);
+ p.ParentIndex = this->Directories[parentDirIndex].ProjectIndex;
+ this->Projects[p.ParentIndex].ChildIndexes.append(projectIndex);
+ }
+ return projectIndex;
+}
+
Json::Value CodemodelConfig::DumpTargets()
{
Json::Value targets = Json::arrayValue;
@@ -437,6 +484,11 @@ Json::Value CodemodelConfig::DumpTarget(cmGeneratorTarget* gt,
target["directoryIndex"] = di;
this->Directories[di].TargetIndexes.append(ti);
+ // Cross-reference project containing target.
+ Json::ArrayIndex pi = this->Directories[di].ProjectIndex;
+ target["projectIndex"] = pi;
+ this->Projects[pi].TargetIndexes.append(ti);
+
return target;
}
@@ -473,6 +525,8 @@ Json::Value CodemodelConfig::DumpDirectory(Directory& d)
directory["childIndexes"] = std::move(childIndexes);
}
+ directory["projectIndex"] = d.ProjectIndex;
+
if (!d.TargetIndexes.empty()) {
directory["targetIndexes"] = std::move(d.TargetIndexes);
}
@@ -480,6 +534,38 @@ Json::Value CodemodelConfig::DumpDirectory(Directory& d)
return directory;
}
+Json::Value CodemodelConfig::DumpProjects()
+{
+ Json::Value projects = Json::arrayValue;
+ for (Project& p : this->Projects) {
+ projects.append(this->DumpProject(p));
+ }
+ return projects;
+}
+
+Json::Value CodemodelConfig::DumpProject(Project& p)
+{
+ Json::Value project = Json::objectValue;
+
+ project["name"] = p.Snapshot.GetProjectName();
+
+ if (p.ParentIndex != Project::NoParentIndex) {
+ project["parentIndex"] = p.ParentIndex;
+ }
+
+ if (!p.ChildIndexes.empty()) {
+ project["childIndexes"] = std::move(p.ChildIndexes);
+ }
+
+ project["directoryIndexes"] = std::move(p.DirectoryIndexes);
+
+ if (!p.TargetIndexes.empty()) {
+ project["targetIndexes"] = std::move(p.TargetIndexes);
+ }
+
+ return project;
+}
+
Target::Target(cmGeneratorTarget* gt, std::string const& config)
: GT(gt)
, Config(config)