rust-project: Represent source roots properly
The current structure of a rust-project.json is documented here:
https://rust-analyzer.github.io/manual.html#non-cargo-based-projects
There are a couple of differences from what gn previously generated:
* There is no longer a 'roots' section
* Each crate has its own set of source includes and exclude directories.
This difference has prevented rust-analyzer from correctly spotting and
including Rust files pulled into a crate using the include! macro. With
the current change, 'gen' dirs are included such that such generated
files can be identified and correctly included by rust-analyzer.
Bug: chromium/1293933
Change-Id: I108dd20114274dc0b2112aefa5990af6381b5466
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/13420
Reviewed-by: Brett Wilson <brettw@chromium.org>
Commit-Queue: Tyler Mandry <tmandry@google.com>
diff --git a/src/gn/rust_project_writer.cc b/src/gn/rust_project_writer.cc
index eea527c..8c73d57 100644
--- a/src/gn/rust_project_writer.cc
+++ b/src/gn/rust_project_writer.cc
@@ -29,9 +29,6 @@
// Current structure of rust-project.json output file
//
// {
-// "roots": [
-// "some/source/root" // each crate's source root
-// ],
// "crates": [
// {
// "deps": [
@@ -40,6 +37,13 @@
// "name": "alloc" // extern name of dependency
// },
// ],
+// "source": [
+// "include_dirs": [
+// "some/source/root",
+// "some/gen/dir",
+// ],
+// "exclude_dirs": []
+// },
// "edition": "2018", // edition of crate
// "cfg": [
// "unix", // "atomic" value config options
@@ -204,8 +208,8 @@
FilePathToUTF8(rebased_out_dir) + std::string(current_sysroot) +
"/lib/rustlib/src/rust/library/" + std::string(crate) + "/src/lib.rs";
- Crate sysroot_crate =
- Crate(SourceFile(crate_path), crate_index, std::string(crate), "2018");
+ Crate sysroot_crate = Crate(SourceFile(crate_path), std::nullopt, crate_index,
+ std::string(crate), "2018");
sysroot_crate.AddConfigItem("debug_assertions");
@@ -290,8 +294,10 @@
edition = FindArgValue("--edition", compiler_args);
}
- Crate crate =
- Crate(crate_root, crate_id, crate_label, edition.value_or("2015"));
+ auto gen_dir = GetBuildDirForTargetAsOutputFile(target, BuildDirType::GEN);
+
+ Crate crate = Crate(crate_root, gen_dir, crate_id, crate_label,
+ edition.value_or("2015"));
crate.SetCompilerArgs(compiler_args);
if (compiler_target.has_value())
@@ -353,24 +359,7 @@
void WriteCrates(const BuildSettings* build_settings,
CrateList& crate_list,
std::ostream& rust_project) {
- // produce a de-duplicated set of source roots:
- std::set<std::string> roots;
- for (auto& crate : crate_list) {
- roots.insert(
- FilePathToUTF8(build_settings->GetFullPath(crate.root().GetDir())));
- }
-
rust_project << "{" NEWLINE;
- rust_project << " \"roots\": [";
- bool first_root = true;
- for (auto& root : roots) {
- if (!first_root)
- rust_project << ",";
- first_root = false;
-
- rust_project << NEWLINE " \"" << root << "\"";
- }
- rust_project << NEWLINE " ]," NEWLINE;
rust_project << " \"crates\": [";
bool first_crate = true;
for (auto& crate : crate_list) {
@@ -384,7 +373,25 @@
rust_project << NEWLINE << " {" NEWLINE
<< " \"crate_id\": " << crate.index() << "," NEWLINE
<< " \"root_module\": \"" << crate_module << "\"," NEWLINE
- << " \"label\": \"" << crate.label() << "\"," NEWLINE;
+ << " \"label\": \"" << crate.label() << "\"," NEWLINE
+ << " \"source\": {" NEWLINE
+ << " \"include_dirs\": [" NEWLINE
+ << " \""
+ << FilePathToUTF8(
+ build_settings->GetFullPath(crate.root().GetDir()))
+ << "\"";
+ auto gen_dir = crate.gen_dir();
+ if (gen_dir.has_value()) {
+ auto gen_dir_path = FilePathToUTF8(
+ build_settings->GetFullPath(gen_dir->AsSourceDir(build_settings)));
+ rust_project << "," NEWLINE << " \"" << gen_dir_path
+ << "\"" NEWLINE;
+ } else {
+ rust_project << NEWLINE;
+ }
+ rust_project << " ]," NEWLINE
+ << " \"exclude_dirs\": []" NEWLINE
+ << " }," NEWLINE;
auto compiler_target = crate.CompilerTarget();
if (compiler_target.has_value()) {
diff --git a/src/gn/rust_project_writer_helpers.h b/src/gn/rust_project_writer_helpers.h
index 24b13d0..4ccf568 100644
--- a/src/gn/rust_project_writer_helpers.h
+++ b/src/gn/rust_project_writer_helpers.h
@@ -35,10 +35,15 @@
class Crate {
public:
Crate(SourceFile root,
+ std::optional<OutputFile> gen_dir,
CrateIndex index,
std::string label,
std::string edition)
- : root_(root), index_(index), label_(label), edition_(edition) {}
+ : root_(root),
+ gen_dir_(gen_dir),
+ index_(index),
+ label_(label),
+ edition_(edition) {}
~Crate() = default;
@@ -69,6 +74,9 @@
// Returns the root file for the crate.
SourceFile& root() { return root_; }
+ // Returns the root file for the crate.
+ std::optional<OutputFile>& gen_dir() { return gen_dir_; }
+
// Returns the crate index.
CrateIndex index() { return index_; };
@@ -103,6 +111,7 @@
private:
SourceFile root_;
+ std::optional<OutputFile> gen_dir_;
CrateIndex index_;
std::string label_;
std::string edition_;
diff --git a/src/gn/rust_project_writer_helpers_unittest.cc b/src/gn/rust_project_writer_helpers_unittest.cc
index 7ff3b48..ffdfcd8 100644
--- a/src/gn/rust_project_writer_helpers_unittest.cc
+++ b/src/gn/rust_project_writer_helpers_unittest.cc
@@ -27,10 +27,10 @@
TestWithScope setup;
CrateList crates;
- Crate dep =
- Crate(SourceFile("/root/tortoise/lib.rs"), 0, "//tortoise:bar", "2015");
- Crate target =
- Crate(SourceFile("/root/hare/lib.rs"), 1, "//hare:bar", "2015");
+ Crate dep = Crate(SourceFile("/root/tortoise/lib.rs"), std::nullopt, 0,
+ "//tortoise:bar", "2015");
+ Crate target = Crate(SourceFile("/root/hare/lib.rs"),
+ OutputFile("gendir/hare/"), 1, "//hare:bar", "2015");
target.AddDependency(0, "tortoise");
target.AddConfigItem("unix");
target.AddConfigItem("feature=\"test\"");
@@ -46,15 +46,17 @@
#endif
const char expected_json[] =
"{\n"
- " \"roots\": [\n"
- " \"/root/hare/\",\n"
- " \"/root/tortoise/\"\n"
- " ],\n"
" \"crates\": [\n"
" {\n"
" \"crate_id\": 0,\n"
" \"root_module\": \"/root/tortoise/lib.rs\",\n"
" \"label\": \"//tortoise:bar\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " \"/root/tortoise/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"deps\": [\n"
" ],\n"
" \"edition\": \"2015\",\n"
@@ -65,6 +67,13 @@
" \"crate_id\": 1,\n"
" \"root_module\": \"/root/hare/lib.rs\",\n"
" \"label\": \"//hare:bar\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " \"/root/hare/\",\n"
+ " \"out/Debug/gendir/hare/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"deps\": [\n"
" {\n"
" \"crate\": 0,\n"
@@ -101,21 +110,20 @@
const char expected_json[] =
"{\n"
- " \"roots\": [\n"
- " \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/alloc/src/\",\n"
- " \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/core/src/\",\n"
- " \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_abort/src/\",\n"
- " \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_unwind/src/\",\n"
- " \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/proc_macro/src/\",\n"
- " \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/std/src/\",\n"
- " \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/test/src/\",\n"
- " \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/unwind/src/\"\n"
- " ],\n"
" \"crates\": [\n"
" {\n"
" \"crate_id\": 0,\n"
- " \"root_module\": \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/core/src/lib.rs\",\n"
+ " \"root_module\": "
+ "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/core/src/"
+ "lib.rs\",\n"
" \"label\": \"core\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " "
+ "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/core/src/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"deps\": [\n"
" ],\n"
" \"edition\": \"2018\",\n"
@@ -125,8 +133,17 @@
" },\n"
" {\n"
" \"crate_id\": 1,\n"
- " \"root_module\": \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/alloc/src/lib.rs\",\n"
+ " \"root_module\": "
+ "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/alloc/src/"
+ "lib.rs\",\n"
" \"label\": \"alloc\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " "
+ "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/alloc/src/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"deps\": [\n"
" {\n"
" \"crate\": 0,\n"
@@ -140,8 +157,18 @@
" },\n"
" {\n"
" \"crate_id\": 2,\n"
- " \"root_module\": \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_abort/src/lib.rs\",\n"
+ " \"root_module\": "
+ "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_abort/src/"
+ "lib.rs\",\n"
" \"label\": \"panic_abort\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " "
+ "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_abort/src/"
+ "\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"deps\": [\n"
" ],\n"
" \"edition\": \"2018\",\n"
@@ -151,8 +178,17 @@
" },\n"
" {\n"
" \"crate_id\": 3,\n"
- " \"root_module\": \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/unwind/src/lib.rs\",\n"
+ " \"root_module\": "
+ "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/unwind/src/"
+ "lib.rs\",\n"
" \"label\": \"unwind\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " "
+ "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/unwind/src/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"deps\": [\n"
" ],\n"
" \"edition\": \"2018\",\n"
@@ -162,8 +198,17 @@
" },\n"
" {\n"
" \"crate_id\": 4,\n"
- " \"root_module\": \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/std/src/lib.rs\",\n"
+ " \"root_module\": "
+ "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/std/src/"
+ "lib.rs\",\n"
" \"label\": \"std\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " "
+ "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/std/src/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"deps\": [\n"
" {\n"
" \"crate\": 1,\n"
@@ -189,8 +234,18 @@
" },\n"
" {\n"
" \"crate_id\": 5,\n"
- " \"root_module\": \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_unwind/src/lib.rs\",\n"
+ " \"root_module\": "
+ "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_unwind/src/"
+ "lib.rs\",\n"
" \"label\": \"panic_unwind\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " "
+ "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_unwind/src/"
+ "\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"deps\": [\n"
" ],\n"
" \"edition\": \"2018\",\n"
@@ -200,8 +255,18 @@
" },\n"
" {\n"
" \"crate_id\": 6,\n"
- " \"root_module\": \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/proc_macro/src/lib.rs\",\n"
+ " \"root_module\": "
+ "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/proc_macro/src/"
+ "lib.rs\",\n"
" \"label\": \"proc_macro\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " "
+ "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/proc_macro/src/"
+ "\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"deps\": [\n"
" ],\n"
" \"edition\": \"2018\",\n"
@@ -211,8 +276,17 @@
" },\n"
" {\n"
" \"crate_id\": 7,\n"
- " \"root_module\": \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/test/src/lib.rs\",\n"
+ " \"root_module\": "
+ "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/test/src/"
+ "lib.rs\",\n"
" \"label\": \"test\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " "
+ "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/test/src/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"deps\": [\n"
" ],\n"
" \"edition\": \"2018\",\n"
diff --git a/src/gn/rust_project_writer_unittest.cc b/src/gn/rust_project_writer_unittest.cc
index 2d4f0dc..e57baf9 100644
--- a/src/gn/rust_project_writer_unittest.cc
+++ b/src/gn/rust_project_writer_unittest.cc
@@ -51,14 +51,18 @@
#endif
const char expected_json[] =
"{\n"
- " \"roots\": [\n"
- " \"path/foo/\"\n"
- " ],\n"
" \"crates\": [\n"
" {\n"
" \"crate_id\": 0,\n"
" \"root_module\": \"path/foo/lib.rs\",\n"
" \"label\": \"//foo:bar\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " \"path/foo/\",\n"
+ " \"path/out/Debug/gen/foo/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"compiler_args\": [\"--cfg=feature=\\\"foo_enabled\\\"\"],\n"
" \"deps\": [\n"
" ],\n"
@@ -111,15 +115,18 @@
#endif
const char expected_json[] =
"{\n"
- " \"roots\": [\n"
- " \"hare/\",\n"
- " \"tortoise/\"\n"
- " ],\n"
" \"crates\": [\n"
" {\n"
" \"crate_id\": 0,\n"
" \"root_module\": \"tortoise/lib.rs\",\n"
" \"label\": \"//tortoise:bar\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " \"tortoise/\",\n"
+ " \"out/Debug/gen/tortoise/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"deps\": [\n"
" ],\n"
" \"edition\": \"2015\",\n"
@@ -132,6 +139,13 @@
" \"crate_id\": 1,\n"
" \"root_module\": \"hare/lib.rs\",\n"
" \"label\": \"//hare:bar\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " \"hare/\",\n"
+ " \"out/Debug/gen/hare/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"deps\": [\n"
" {\n"
" \"crate\": 0,\n"
@@ -197,16 +211,18 @@
#endif
const char expected_json[] =
"{\n"
- " \"roots\": [\n"
- " \"achilles/\",\n"
- " \"hare/\",\n"
- " \"tortoise/\"\n"
- " ],\n"
" \"crates\": [\n"
" {\n"
" \"crate_id\": 0,\n"
" \"root_module\": \"tortoise/lib.rs\",\n"
" \"label\": \"//tortoise:bar\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " \"tortoise/\",\n"
+ " \"out/Debug/gen/tortoise/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"deps\": [\n"
" ],\n"
" \"edition\": \"2015\",\n"
@@ -219,6 +235,13 @@
" \"crate_id\": 1,\n"
" \"root_module\": \"achilles/lib.rs\",\n"
" \"label\": \"//achilles:bar\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " \"achilles/\",\n"
+ " \"out/Debug/gen/achilles/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"deps\": [\n"
" ],\n"
" \"edition\": \"2015\",\n"
@@ -231,6 +254,13 @@
" \"crate_id\": 2,\n"
" \"root_module\": \"hare/lib.rs\",\n"
" \"label\": \"//hare:bar\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " \"hare/\",\n"
+ " \"out/Debug/gen/hare/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"deps\": [\n"
" {\n"
" \"crate\": 0,\n"
@@ -314,16 +344,18 @@
#endif
const char expected_json[] =
"{\n"
- " \"roots\": [\n"
- " \"hare/\",\n"
- " \"tortoise/\",\n"
- " \"tortoise/macro/\"\n"
- " ],\n"
" \"crates\": [\n"
" {\n"
" \"crate_id\": 0,\n"
" \"root_module\": \"tortoise/lib.rs\",\n"
" \"label\": \"//tortoise:bar\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " \"tortoise/\",\n"
+ " \"out/Debug/gen/tortoise/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"deps\": [\n"
" ],\n"
" \"edition\": \"2015\",\n"
@@ -336,6 +368,13 @@
" \"crate_id\": 1,\n"
" \"root_module\": \"tortoise/macro/lib.rs\",\n"
" \"label\": \"//tortoise:macro\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " \"tortoise/macro/\",\n"
+ " \"out/Debug/gen/tortoise/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"deps\": [\n"
" ],\n"
" \"edition\": \"2015\",\n"
@@ -348,6 +387,13 @@
" \"crate_id\": 2,\n"
" \"root_module\": \"hare/lib.rs\",\n"
" \"label\": \"//hare:bar\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " \"hare/\",\n"
+ " \"out/Debug/gen/hare/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"deps\": [\n"
" {\n"
" \"crate\": 0,\n"
@@ -398,14 +444,18 @@
#endif
const char expected_json[] =
"{\n"
- " \"roots\": [\n"
- " \"path/foo/\"\n"
- " ],\n"
" \"crates\": [\n"
" {\n"
" \"crate_id\": 0,\n"
" \"root_module\": \"path/foo/lib.rs\",\n"
" \"label\": \"//foo:bar\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " \"path/foo/\",\n"
+ " \"path/out/Debug/gen/foo/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"target\": \"x86-64_unknown\",\n"
" \"compiler_args\": [\"--target\", \"x86-64_unknown\"],\n"
" \"deps\": [\n"
@@ -449,14 +499,18 @@
#endif
const char expected_json[] =
"{\n"
- " \"roots\": [\n"
- " \"path/foo/\"\n"
- " ],\n"
" \"crates\": [\n"
" {\n"
" \"crate_id\": 0,\n"
" \"root_module\": \"path/foo/lib.rs\",\n"
" \"label\": \"//foo:bar\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " \"path/foo/\",\n"
+ " \"path/out/Debug/gen/foo/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"compiler_args\": [\"--edition=2018\"],\n"
" \"deps\": [\n"
" ],\n"
@@ -500,14 +554,18 @@
#endif
const char expected_json[] =
"{\n"
- " \"roots\": [\n"
- " \"path/foo/\"\n"
- " ],\n"
" \"crates\": [\n"
" {\n"
" \"crate_id\": 0,\n"
" \"root_module\": \"path/foo/lib.rs\",\n"
" \"label\": \"//foo:bar\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " \"path/foo/\",\n"
+ " \"path/out/Debug/gen/foo/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"compiler_args\": [\"--edition\", \"2018\"],\n"
" \"deps\": [\n"
" ],\n"
@@ -552,14 +610,18 @@
#endif
const char expected_json[] =
"{\n"
- " \"roots\": [\n"
- " \"path/foo/\"\n"
- " ],\n"
" \"crates\": [\n"
" {\n"
" \"crate_id\": 0,\n"
" \"root_module\": \"path/foo/lib.rs\",\n"
" \"label\": \"//foo:bar\",\n"
+ " \"source\": {\n"
+ " \"include_dirs\": [\n"
+ " \"path/foo/\",\n"
+ " \"path/out/Debug/gen/foo/\"\n"
+ " ],\n"
+ " \"exclude_dirs\": []\n"
+ " },\n"
" \"compiler_args\": [\"--cfg=feature=\\\"foo_enabled\\\"\"],\n"
" \"deps\": [\n"
" ],\n"