Skip to content

Commit 50ecb09

Browse files
committed
feat: emit SCIP via rust-analyzer
1 parent 6711ded commit 50ecb09

File tree

8 files changed

+630
-14
lines changed

8 files changed

+630
-14
lines changed

Cargo.lock

Lines changed: 50 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ide/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ pub use crate::{
8787
},
8888
join_lines::JoinLinesConfig,
8989
markup::Markup,
90-
moniker::{MonikerKind, MonikerResult, PackageInformation},
90+
moniker::{MonikerDescriptorKind, MonikerKind, MonikerResult, PackageInformation},
9191
move_item::Direction,
9292
navigation_target::NavigationTarget,
9393
prime_caches::ParallelPrimeCachesProgress,

crates/ide/src/moniker.rs

Lines changed: 118 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,39 @@ use syntax::{AstNode, SyntaxKind::*, T};
1313

1414
use crate::{doc_links::token_as_doc_comment, RangeInfo};
1515

16+
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
17+
pub enum MonikerDescriptorKind {
18+
Namespace,
19+
Type,
20+
Term,
21+
Method,
22+
TypeParameter,
23+
Parameter,
24+
Macro,
25+
Meta,
26+
}
27+
28+
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
29+
pub struct MonikerDescriptor {
30+
pub name: Name,
31+
pub desc: MonikerDescriptorKind,
32+
}
33+
1634
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1735
pub struct MonikerIdentifier {
18-
crate_name: String,
19-
path: Vec<Name>,
36+
pub crate_name: String,
37+
pub description: Vec<MonikerDescriptor>,
2038
}
2139

2240
impl ToString for MonikerIdentifier {
2341
fn to_string(&self) -> String {
2442
match self {
25-
MonikerIdentifier { path, crate_name } => {
26-
format!("{}::{}", crate_name, path.iter().map(|x| x.to_string()).join("::"))
43+
MonikerIdentifier { description, crate_name } => {
44+
format!(
45+
"{}::{}",
46+
crate_name,
47+
description.iter().map(|x| x.name.to_string()).join("::")
48+
)
2749
}
2850
}
2951
}
@@ -42,6 +64,12 @@ pub struct MonikerResult {
4264
pub package_information: PackageInformation,
4365
}
4466

67+
impl MonikerResult {
68+
pub fn from_def(db: &RootDatabase, def: Definition, from_crate: Crate) -> Option<Self> {
69+
def_to_moniker(db, def, from_crate)
70+
}
71+
}
72+
4573
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4674
pub struct PackageInformation {
4775
pub name: String,
@@ -105,13 +133,23 @@ pub(crate) fn def_to_moniker(
105133
def: Definition,
106134
from_crate: Crate,
107135
) -> Option<MonikerResult> {
108-
if matches!(def, Definition::GenericParam(_) | Definition::SelfType(_) | Definition::Local(_)) {
136+
if matches!(
137+
def,
138+
Definition::GenericParam(_)
139+
| Definition::Label(_)
140+
| Definition::DeriveHelper(_)
141+
| Definition::BuiltinAttr(_)
142+
| Definition::ToolModule(_)
143+
) {
109144
return None;
110145
}
146+
111147
let module = def.module(db)?;
112148
let krate = module.krate();
113-
let mut path = vec![];
114-
path.extend(module.path_to_root(db).into_iter().filter_map(|x| x.name(db)));
149+
let mut description = vec![];
150+
description.extend(module.path_to_root(db).into_iter().filter_map(|x| {
151+
Some(MonikerDescriptor { name: x.name(db)?, desc: MonikerDescriptorKind::Namespace })
152+
}));
115153

116154
// Handle associated items within a trait
117155
if let Some(assoc) = def.as_assoc_item(db) {
@@ -120,31 +158,98 @@ pub(crate) fn def_to_moniker(
120158
AssocItemContainer::Trait(trait_) => {
121159
// Because different traits can have functions with the same name,
122160
// we have to include the trait name as part of the moniker for uniqueness.
123-
path.push(trait_.name(db));
161+
description.push(MonikerDescriptor {
162+
name: trait_.name(db),
163+
desc: MonikerDescriptorKind::Type,
164+
});
124165
}
125166
AssocItemContainer::Impl(impl_) => {
126167
// Because a struct can implement multiple traits, for implementations
127168
// we add both the struct name and the trait name to the path
128169
if let Some(adt) = impl_.self_ty(db).as_adt() {
129-
path.push(adt.name(db));
170+
description.push(MonikerDescriptor {
171+
name: adt.name(db),
172+
desc: MonikerDescriptorKind::Type,
173+
});
130174
}
131175

132176
if let Some(trait_) = impl_.trait_(db) {
133-
path.push(trait_.name(db));
177+
description.push(MonikerDescriptor {
178+
name: trait_.name(db),
179+
desc: MonikerDescriptorKind::Type,
180+
});
134181
}
135182
}
136183
}
137184
}
138185

139186
if let Definition::Field(it) = def {
140-
path.push(it.parent_def(db).name(db));
187+
description.push(MonikerDescriptor {
188+
name: it.parent_def(db).name(db),
189+
desc: MonikerDescriptorKind::Type,
190+
});
141191
}
142192

143-
path.push(def.name(db)?);
193+
let name_desc = match def {
194+
// These are handled by top-level guard (for performance).
195+
Definition::GenericParam(_)
196+
| Definition::Label(_)
197+
| Definition::DeriveHelper(_)
198+
| Definition::BuiltinAttr(_)
199+
| Definition::ToolModule(_) => return None,
200+
201+
Definition::Local(local) => {
202+
if !local.is_param(db) {
203+
return None;
204+
}
205+
206+
MonikerDescriptor { name: local.name(db), desc: MonikerDescriptorKind::Parameter }
207+
}
208+
Definition::Macro(m) => {
209+
MonikerDescriptor { name: m.name(db), desc: MonikerDescriptorKind::Macro }
210+
}
211+
Definition::Function(f) => {
212+
MonikerDescriptor { name: f.name(db), desc: MonikerDescriptorKind::Method }
213+
}
214+
Definition::Variant(v) => {
215+
MonikerDescriptor { name: v.name(db), desc: MonikerDescriptorKind::Type }
216+
}
217+
Definition::Const(c) => {
218+
MonikerDescriptor { name: c.name(db)?, desc: MonikerDescriptorKind::Term }
219+
}
220+
Definition::Trait(trait_) => {
221+
MonikerDescriptor { name: trait_.name(db), desc: MonikerDescriptorKind::Type }
222+
}
223+
Definition::TypeAlias(ta) => {
224+
MonikerDescriptor { name: ta.name(db), desc: MonikerDescriptorKind::TypeParameter }
225+
}
226+
Definition::Module(m) => {
227+
MonikerDescriptor { name: m.name(db)?, desc: MonikerDescriptorKind::Namespace }
228+
}
229+
Definition::BuiltinType(b) => {
230+
MonikerDescriptor { name: b.name(), desc: MonikerDescriptorKind::Type }
231+
}
232+
Definition::SelfType(imp) => MonikerDescriptor {
233+
name: imp.self_ty(db).as_adt()?.name(db),
234+
desc: MonikerDescriptorKind::Type,
235+
},
236+
Definition::Field(it) => {
237+
MonikerDescriptor { name: it.name(db), desc: MonikerDescriptorKind::Term }
238+
}
239+
Definition::Adt(adt) => {
240+
MonikerDescriptor { name: adt.name(db), desc: MonikerDescriptorKind::Type }
241+
}
242+
Definition::Static(s) => {
243+
MonikerDescriptor { name: s.name(db), desc: MonikerDescriptorKind::Meta }
244+
}
245+
};
246+
247+
description.push(name_desc);
248+
144249
Some(MonikerResult {
145250
identifier: MonikerIdentifier {
146251
crate_name: krate.display_name(db)?.crate_name().to_string(),
147-
path,
252+
description,
148253
},
149254
kind: if krate == from_crate { MonikerKind::Export } else { MonikerKind::Import },
150255
package_information: {

crates/rust-analyzer/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ crossbeam-channel = "0.5.5"
2323
dissimilar = "1.0.4"
2424
itertools = "0.10.3"
2525
lsp-types = { version = "0.93.0", features = ["proposed"] }
26+
scip = "0.1.1"
2627
parking_lot = "0.12.1"
2728
xflags = "0.2.4"
2829
oorandom = "11.1.3"

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ fn try_main() -> Result<()> {
9393
flags::RustAnalyzerCmd::Ssr(cmd) => cmd.run()?,
9494
flags::RustAnalyzerCmd::Search(cmd) => cmd.run()?,
9595
flags::RustAnalyzerCmd::Lsif(cmd) => cmd.run()?,
96+
flags::RustAnalyzerCmd::Scip(cmd) => cmd.run()?,
9697
}
9798
Ok(())
9899
}

crates/rust-analyzer/src/cli.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ mod analysis_stats;
99
mod diagnostics;
1010
mod ssr;
1111
mod lsif;
12+
mod scip;
1213

1314
mod progress_report;
1415

crates/rust-analyzer/src/cli/flags.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ xflags::xflags! {
112112
cmd lsif
113113
required path: PathBuf
114114
{}
115+
116+
cmd scip
117+
required path: PathBuf
118+
{}
115119
}
116120
}
117121

@@ -140,6 +144,7 @@ pub enum RustAnalyzerCmd {
140144
Search(Search),
141145
ProcMacro(ProcMacro),
142146
Lsif(Lsif),
147+
Scip(Scip),
143148
}
144149

145150
#[derive(Debug)]
@@ -207,6 +212,11 @@ pub struct Lsif {
207212
pub path: PathBuf,
208213
}
209214

215+
#[derive(Debug)]
216+
pub struct Scip {
217+
pub path: PathBuf,
218+
}
219+
210220
impl RustAnalyzer {
211221
pub const HELP: &'static str = Self::HELP_;
212222

0 commit comments

Comments
 (0)