Skip to content

Commit 7cad4da

Browse files
committed
Auto merge of rust-lang#18368 - Veykril:test-lsif_contains_generated_macros, r=lnicola
tests: Add `lsif_contains_generated_constant` test Closes rust-lang/rust-analyzer#18309
2 parents 0b906b6 + ec4b9e0 commit 7cad4da

File tree

6 files changed

+199
-17
lines changed

6 files changed

+199
-17
lines changed

src/tools/rust-analyzer/.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
/target/
1+
target/
22
/dist/
3-
crates/*/target
43
**/*.rs.bk
54
**/*.rs.pending-snap
65
.idea/*

src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ fn actual_main() -> anyhow::Result<ExitCode> {
8585
flags::RustAnalyzerCmd::UnresolvedReferences(cmd) => cmd.run()?,
8686
flags::RustAnalyzerCmd::Ssr(cmd) => cmd.run()?,
8787
flags::RustAnalyzerCmd::Search(cmd) => cmd.run()?,
88-
flags::RustAnalyzerCmd::Lsif(cmd) => cmd.run()?,
88+
flags::RustAnalyzerCmd::Lsif(cmd) => {
89+
cmd.run(&mut std::io::stdout(), Some(project_model::RustLibSource::Discover))?
90+
}
8991
flags::RustAnalyzerCmd::Scip(cmd) => cmd.run()?,
9092
flags::RustAnalyzerCmd::RunTests(cmd) => cmd.run()?,
9193
flags::RustAnalyzerCmd::RustcTests(cmd) => cmd.run()?,

src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use load_cargo::{load_workspace, LoadCargoConfig, ProcMacroServerChoice};
1212
use lsp_types::lsif;
1313
use project_model::{CargoConfig, ProjectManifest, ProjectWorkspace, RustLibSource};
1414
use rustc_hash::FxHashMap;
15+
use stdx::format_to;
1516
use vfs::{AbsPathBuf, Vfs};
1617

1718
use crate::{
@@ -21,7 +22,7 @@ use crate::{
2122
version::version,
2223
};
2324

24-
struct LsifManager<'a> {
25+
struct LsifManager<'a, 'w> {
2526
count: i32,
2627
token_map: FxHashMap<TokenId, Id>,
2728
range_map: FxHashMap<FileRange, Id>,
@@ -30,6 +31,7 @@ struct LsifManager<'a> {
3031
analysis: &'a Analysis,
3132
db: &'a RootDatabase,
3233
vfs: &'a Vfs,
34+
out: &'w mut dyn std::io::Write,
3335
}
3436

3537
#[derive(Clone, Copy)]
@@ -41,8 +43,13 @@ impl From<Id> for lsp_types::NumberOrString {
4143
}
4244
}
4345

44-
impl LsifManager<'_> {
45-
fn new<'a>(analysis: &'a Analysis, db: &'a RootDatabase, vfs: &'a Vfs) -> LsifManager<'a> {
46+
impl LsifManager<'_, '_> {
47+
fn new<'a, 'w>(
48+
analysis: &'a Analysis,
49+
db: &'a RootDatabase,
50+
vfs: &'a Vfs,
51+
out: &'w mut dyn std::io::Write,
52+
) -> LsifManager<'a, 'w> {
4653
LsifManager {
4754
count: 0,
4855
token_map: FxHashMap::default(),
@@ -52,6 +59,7 @@ impl LsifManager<'_> {
5259
analysis,
5360
db,
5461
vfs,
62+
out,
5563
}
5664
}
5765

@@ -70,9 +78,8 @@ impl LsifManager<'_> {
7078
self.add(lsif::Element::Edge(edge))
7179
}
7280

73-
// FIXME: support file in addition to stdout here
74-
fn emit(&self, data: &str) {
75-
println!("{data}");
81+
fn emit(&mut self, data: &str) {
82+
format_to!(self.out, "{data}\n");
7683
}
7784

7885
fn get_token_id(&mut self, id: TokenId) -> Id {
@@ -272,14 +279,14 @@ impl LsifManager<'_> {
272279
}
273280

274281
impl flags::Lsif {
275-
pub fn run(self) -> anyhow::Result<()> {
282+
pub fn run(
283+
self,
284+
out: &mut dyn std::io::Write,
285+
sysroot: Option<RustLibSource>,
286+
) -> anyhow::Result<()> {
276287
let now = Instant::now();
277-
let cargo_config = &CargoConfig {
278-
sysroot: Some(RustLibSource::Discover),
279-
all_targets: true,
280-
set_test: true,
281-
..Default::default()
282-
};
288+
let cargo_config =
289+
&CargoConfig { sysroot, all_targets: true, set_test: true, ..Default::default() };
283290
let no_progress = &|_| ();
284291
let load_cargo_config = LoadCargoConfig {
285292
load_out_dirs_from_check: true,
@@ -308,7 +315,7 @@ impl flags::Lsif {
308315

309316
let si = StaticIndex::compute(&analysis, vendored_libs_config);
310317

311-
let mut lsif = LsifManager::new(&analysis, db, &vfs);
318+
let mut lsif = LsifManager::new(&analysis, db, &vfs, out);
312319
lsif.add_vertex(lsif::Vertex::MetaData(lsif::MetaData {
313320
version: String::from("0.5.0"),
314321
project_root: lsp_types::Url::from_file_path(path).unwrap(),
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
use expect_test::expect;
2+
use test_utils::skip_slow_tests;
3+
4+
use crate::support::Project;
5+
6+
// If you choose to change the test fixture here, please inform the ferrocene/needy maintainers by
7+
// opening an issue at https://github.com/ferrocene/needy as the tool relies on specific token
8+
// mapping behavior.
9+
#[test]
10+
fn lsif_contains_generated_constant() {
11+
if skip_slow_tests() {
12+
return;
13+
}
14+
15+
let stdout = Project::with_fixture(
16+
r#"
17+
//- /Cargo.toml
18+
[package]
19+
name = "foo"
20+
version = "0.0.0"
21+
22+
//- /src/lib.rs
23+
#![allow(unused)]
24+
25+
macro_rules! generate_const_from_identifier(
26+
($id:ident) => (
27+
const _: () = { const $id: &str = "encoded_data"; };
28+
)
29+
);
30+
31+
generate_const_from_identifier!(REQ_001);
32+
mod tests {
33+
use super::*;
34+
generate_const_from_identifier!(REQ_002);
35+
}
36+
"#,
37+
)
38+
.root("foo")
39+
.run_lsif();
40+
let n = stdout.find(r#"{"id":2,"#).unwrap();
41+
// the first 2 entries contain paths that are not stable
42+
let stdout = &stdout[n..];
43+
expect![[r#"
44+
{"id":2,"type":"vertex","label":"foldingRangeResult","result":[{"startLine":2,"startCharacter":43,"endLine":6,"endCharacter":1},{"startLine":3,"startCharacter":19,"endLine":5,"endCharacter":5},{"startLine":9,"startCharacter":10,"endLine":12,"endCharacter":1}]}
45+
{"id":3,"type":"edge","label":"textDocument/foldingRange","inV":2,"outV":1}
46+
{"id":4,"type":"vertex","label":"range","start":{"line":0,"character":3},"end":{"line":0,"character":8}}
47+
{"id":5,"type":"vertex","label":"resultSet"}
48+
{"id":6,"type":"edge","label":"next","inV":5,"outV":4}
49+
{"id":7,"type":"vertex","label":"range","start":{"line":2,"character":13},"end":{"line":2,"character":43}}
50+
{"id":8,"type":"vertex","label":"resultSet"}
51+
{"id":9,"type":"edge","label":"next","inV":8,"outV":7}
52+
{"id":10,"type":"vertex","label":"range","start":{"line":8,"character":0},"end":{"line":8,"character":30}}
53+
{"id":11,"type":"edge","label":"next","inV":8,"outV":10}
54+
{"id":12,"type":"vertex","label":"range","start":{"line":8,"character":32},"end":{"line":8,"character":39}}
55+
{"id":13,"type":"vertex","label":"resultSet"}
56+
{"id":14,"type":"edge","label":"next","inV":13,"outV":12}
57+
{"id":15,"type":"vertex","label":"range","start":{"line":9,"character":4},"end":{"line":9,"character":9}}
58+
{"id":16,"type":"vertex","label":"resultSet"}
59+
{"id":17,"type":"edge","label":"next","inV":16,"outV":15}
60+
{"id":18,"type":"vertex","label":"range","start":{"line":10,"character":8},"end":{"line":10,"character":13}}
61+
{"id":19,"type":"vertex","label":"resultSet"}
62+
{"id":20,"type":"edge","label":"next","inV":19,"outV":18}
63+
{"id":21,"type":"vertex","label":"range","start":{"line":11,"character":4},"end":{"line":11,"character":34}}
64+
{"id":22,"type":"edge","label":"next","inV":8,"outV":21}
65+
{"id":23,"type":"vertex","label":"range","start":{"line":11,"character":36},"end":{"line":11,"character":43}}
66+
{"id":24,"type":"vertex","label":"resultSet"}
67+
{"id":25,"type":"edge","label":"next","inV":24,"outV":23}
68+
{"id":26,"type":"edge","label":"contains","inVs":[4,7,10,12,15,18,21,23],"outV":1}
69+
{"id":27,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\n#[allow]\n```\n\n---\n\nValid forms are:\n\n* \\#\\[allow(lint1, lint2, ..., /\\*opt\\*/ reason = \"...\")\\]"}}}
70+
{"id":28,"type":"edge","label":"textDocument/hover","inV":27,"outV":5}
71+
{"id":29,"type":"vertex","label":"referenceResult"}
72+
{"id":30,"type":"edge","label":"textDocument/references","inV":29,"outV":5}
73+
{"id":31,"type":"edge","label":"item","document":1,"property":"references","inVs":[4],"outV":29}
74+
{"id":32,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo\n```\n\n```rust\nmacro_rules! generate_const_from_identifier\n```"}}}
75+
{"id":33,"type":"edge","label":"textDocument/hover","inV":32,"outV":8}
76+
{"id":34,"type":"vertex","label":"packageInformation","name":"foo","manager":"cargo","version":"0.0.0"}
77+
{"id":35,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::generate_const_from_identifier","unique":"scheme","kind":"export"}
78+
{"id":36,"type":"edge","label":"packageInformation","inV":34,"outV":35}
79+
{"id":37,"type":"edge","label":"moniker","inV":35,"outV":8}
80+
{"id":38,"type":"vertex","label":"definitionResult"}
81+
{"id":39,"type":"edge","label":"item","document":1,"inVs":[7],"outV":38}
82+
{"id":40,"type":"edge","label":"textDocument/definition","inV":38,"outV":8}
83+
{"id":41,"type":"vertex","label":"referenceResult"}
84+
{"id":42,"type":"edge","label":"textDocument/references","inV":41,"outV":8}
85+
{"id":43,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[7],"outV":41}
86+
{"id":44,"type":"edge","label":"item","document":1,"property":"references","inVs":[10,21],"outV":41}
87+
{"id":45,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo\n```\n\n```rust\nconst REQ_001: &str = \"encoded_data\"\n```"}}}
88+
{"id":46,"type":"edge","label":"textDocument/hover","inV":45,"outV":13}
89+
{"id":47,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::REQ_001","unique":"scheme","kind":"export"}
90+
{"id":48,"type":"edge","label":"packageInformation","inV":34,"outV":47}
91+
{"id":49,"type":"edge","label":"moniker","inV":47,"outV":13}
92+
{"id":50,"type":"vertex","label":"definitionResult"}
93+
{"id":51,"type":"edge","label":"item","document":1,"inVs":[12],"outV":50}
94+
{"id":52,"type":"edge","label":"textDocument/definition","inV":50,"outV":13}
95+
{"id":53,"type":"vertex","label":"referenceResult"}
96+
{"id":54,"type":"edge","label":"textDocument/references","inV":53,"outV":13}
97+
{"id":55,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[12],"outV":53}
98+
{"id":56,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo\n```\n\n```rust\nmod tests\n```"}}}
99+
{"id":57,"type":"edge","label":"textDocument/hover","inV":56,"outV":16}
100+
{"id":58,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::tests","unique":"scheme","kind":"export"}
101+
{"id":59,"type":"edge","label":"packageInformation","inV":34,"outV":58}
102+
{"id":60,"type":"edge","label":"moniker","inV":58,"outV":16}
103+
{"id":61,"type":"vertex","label":"definitionResult"}
104+
{"id":62,"type":"edge","label":"item","document":1,"inVs":[15],"outV":61}
105+
{"id":63,"type":"edge","label":"textDocument/definition","inV":61,"outV":16}
106+
{"id":64,"type":"vertex","label":"referenceResult"}
107+
{"id":65,"type":"edge","label":"textDocument/references","inV":64,"outV":16}
108+
{"id":66,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[15],"outV":64}
109+
{"id":67,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nextern crate foo\n```"}}}
110+
{"id":68,"type":"edge","label":"textDocument/hover","inV":67,"outV":19}
111+
{"id":69,"type":"vertex","label":"definitionResult"}
112+
{"id":70,"type":"vertex","label":"range","start":{"line":0,"character":0},"end":{"line":13,"character":0}}
113+
{"id":71,"type":"edge","label":"contains","inVs":[70],"outV":1}
114+
{"id":72,"type":"edge","label":"item","document":1,"inVs":[70],"outV":69}
115+
{"id":73,"type":"edge","label":"textDocument/definition","inV":69,"outV":19}
116+
{"id":74,"type":"vertex","label":"referenceResult"}
117+
{"id":75,"type":"edge","label":"textDocument/references","inV":74,"outV":19}
118+
{"id":76,"type":"edge","label":"item","document":1,"property":"references","inVs":[18],"outV":74}
119+
{"id":77,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo::tests\n```\n\n```rust\nconst REQ_002: &str = \"encoded_data\"\n```"}}}
120+
{"id":78,"type":"edge","label":"textDocument/hover","inV":77,"outV":24}
121+
{"id":79,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::tests::REQ_002","unique":"scheme","kind":"export"}
122+
{"id":80,"type":"edge","label":"packageInformation","inV":34,"outV":79}
123+
{"id":81,"type":"edge","label":"moniker","inV":79,"outV":24}
124+
{"id":82,"type":"vertex","label":"definitionResult"}
125+
{"id":83,"type":"edge","label":"item","document":1,"inVs":[23],"outV":82}
126+
{"id":84,"type":"edge","label":"textDocument/definition","inV":82,"outV":24}
127+
{"id":85,"type":"vertex","label":"referenceResult"}
128+
{"id":86,"type":"edge","label":"textDocument/references","inV":85,"outV":24}
129+
{"id":87,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[23],"outV":85}
130+
"#]].assert_eq(stdout);
131+
}

src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
1111
#![allow(clippy::disallowed_types)]
1212

13+
mod cli;
1314
mod ratoml;
1415
mod support;
1516
mod testdir;

src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ use std::{
66
};
77

88
use crossbeam_channel::{after, select, Receiver};
9+
use itertools::Itertools;
910
use lsp_server::{Connection, Message, Notification, Request};
1011
use lsp_types::{notification::Exit, request::Shutdown, TextDocumentIdentifier, Url};
1112
use parking_lot::{Mutex, MutexGuard};
1213
use paths::{Utf8Path, Utf8PathBuf};
1314
use rust_analyzer::{
15+
cli::flags,
1416
config::{Config, ConfigChange, ConfigErrors},
1517
lsp, main_loop,
1618
};
@@ -84,6 +86,46 @@ impl Project<'_> {
8486
self
8587
}
8688

89+
pub(crate) fn run_lsif(self) -> String {
90+
let tmp_dir = self.tmp_dir.unwrap_or_else(|| {
91+
if self.root_dir_contains_symlink {
92+
TestDir::new_symlink()
93+
} else {
94+
TestDir::new()
95+
}
96+
});
97+
98+
let FixtureWithProjectMeta {
99+
fixture,
100+
mini_core,
101+
proc_macro_names,
102+
toolchain,
103+
target_data_layout: _,
104+
} = FixtureWithProjectMeta::parse(self.fixture);
105+
assert!(proc_macro_names.is_empty());
106+
assert!(mini_core.is_none());
107+
assert!(toolchain.is_none());
108+
109+
for entry in fixture {
110+
let path = tmp_dir.path().join(&entry.path['/'.len_utf8()..]);
111+
fs::create_dir_all(path.parent().unwrap()).unwrap();
112+
fs::write(path.as_path(), entry.text.as_bytes()).unwrap();
113+
}
114+
115+
let tmp_dir_path = AbsPathBuf::assert(tmp_dir.path().to_path_buf());
116+
let mut buf = Vec::new();
117+
flags::Lsif::run(
118+
flags::Lsif {
119+
path: tmp_dir_path.join(self.roots.iter().exactly_one().unwrap()).into(),
120+
exclude_vendored_libraries: false,
121+
},
122+
&mut buf,
123+
None,
124+
)
125+
.unwrap();
126+
String::from_utf8(buf).unwrap()
127+
}
128+
87129
pub(crate) fn server(self) -> Server {
88130
static CONFIG_DIR_LOCK: Mutex<()> = Mutex::new(());
89131
let tmp_dir = self.tmp_dir.unwrap_or_else(|| {

0 commit comments

Comments
 (0)