mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-04 19:12:50 +00:00
Emit moniker in lsif
This commit is contained in:
parent
a07e406d06
commit
30ed7fac27
@ -10,9 +10,10 @@ use tt::Subtree;
|
|||||||
use vfs::{file_set::FileSet, VfsPath};
|
use vfs::{file_set::FileSet, VfsPath};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
input::CrateName, Change, CrateDisplayName, CrateGraph, CrateId, Dependency, Edition, Env,
|
input::{CrateName, CrateOrigin},
|
||||||
FileId, FilePosition, FileRange, ProcMacro, ProcMacroExpander, ProcMacroExpansionError,
|
Change, CrateDisplayName, CrateGraph, CrateId, Dependency, Edition, Env, FileId, FilePosition,
|
||||||
SourceDatabaseExt, SourceRoot, SourceRootId,
|
FileRange, ProcMacro, ProcMacroExpander, ProcMacroExpansionError, SourceDatabaseExt,
|
||||||
|
SourceRoot, SourceRootId,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const WORKSPACE: SourceRootId = SourceRootId(0);
|
pub const WORKSPACE: SourceRootId = SourceRootId(0);
|
||||||
@ -130,7 +131,7 @@ impl ChangeFixture {
|
|||||||
current_source_root_kind = *kind;
|
current_source_root_kind = *kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(krate) = meta.krate {
|
if let Some((krate, origin)) = meta.krate {
|
||||||
let crate_name = CrateName::normalize_dashes(&krate);
|
let crate_name = CrateName::normalize_dashes(&krate);
|
||||||
let crate_id = crate_graph.add_crate_root(
|
let crate_id = crate_graph.add_crate_root(
|
||||||
file_id,
|
file_id,
|
||||||
@ -141,6 +142,7 @@ impl ChangeFixture {
|
|||||||
meta.cfg,
|
meta.cfg,
|
||||||
meta.env,
|
meta.env,
|
||||||
Default::default(),
|
Default::default(),
|
||||||
|
origin,
|
||||||
);
|
);
|
||||||
let prev = crates.insert(crate_name.clone(), crate_id);
|
let prev = crates.insert(crate_name.clone(), crate_id);
|
||||||
assert!(prev.is_none());
|
assert!(prev.is_none());
|
||||||
@ -174,6 +176,7 @@ impl ChangeFixture {
|
|||||||
default_cfg,
|
default_cfg,
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
for (from, to, prelude) in crate_deps {
|
for (from, to, prelude) in crate_deps {
|
||||||
@ -209,6 +212,7 @@ impl ChangeFixture {
|
|||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
|
CrateOrigin::Lang("core".to_string()),
|
||||||
);
|
);
|
||||||
|
|
||||||
for krate in all_crates {
|
for krate in all_crates {
|
||||||
@ -243,6 +247,7 @@ impl ChangeFixture {
|
|||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
proc_macro,
|
proc_macro,
|
||||||
|
CrateOrigin::Lang("proc-macro".to_string()),
|
||||||
);
|
);
|
||||||
|
|
||||||
for krate in all_crates {
|
for krate in all_crates {
|
||||||
@ -324,7 +329,7 @@ enum SourceRootKind {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct FileMeta {
|
struct FileMeta {
|
||||||
path: String,
|
path: String,
|
||||||
krate: Option<String>,
|
krate: Option<(String, CrateOrigin)>,
|
||||||
deps: Vec<String>,
|
deps: Vec<String>,
|
||||||
extern_prelude: Vec<String>,
|
extern_prelude: Vec<String>,
|
||||||
cfg: CfgOptions,
|
cfg: CfgOptions,
|
||||||
@ -333,16 +338,36 @@ struct FileMeta {
|
|||||||
introduce_new_source_root: Option<SourceRootKind>,
|
introduce_new_source_root: Option<SourceRootKind>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_crate(crate_str: String) -> (String, CrateOrigin) {
|
||||||
|
if let Some((a, b)) = crate_str.split_once("@") {
|
||||||
|
(
|
||||||
|
a.to_owned(),
|
||||||
|
match b.split_once(":") {
|
||||||
|
Some(("CratesIo", data)) => match data.split_once(",") {
|
||||||
|
Some((version, url)) => CrateOrigin::CratesIo {
|
||||||
|
name: a.to_owned(),
|
||||||
|
repo: Some(url.to_owned()),
|
||||||
|
version: version.to_owned(),
|
||||||
|
},
|
||||||
|
_ => panic!("Bad crates.io parameter: {}", data),
|
||||||
|
},
|
||||||
|
_ => panic!("Bad string for crate origin: {}", b),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(crate_str, CrateOrigin::Unknown)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<Fixture> for FileMeta {
|
impl From<Fixture> for FileMeta {
|
||||||
fn from(f: Fixture) -> FileMeta {
|
fn from(f: Fixture) -> FileMeta {
|
||||||
let mut cfg = CfgOptions::default();
|
let mut cfg = CfgOptions::default();
|
||||||
f.cfg_atoms.iter().for_each(|it| cfg.insert_atom(it.into()));
|
f.cfg_atoms.iter().for_each(|it| cfg.insert_atom(it.into()));
|
||||||
f.cfg_key_values.iter().for_each(|(k, v)| cfg.insert_key_value(k.into(), v.into()));
|
f.cfg_key_values.iter().for_each(|(k, v)| cfg.insert_key_value(k.into(), v.into()));
|
||||||
|
|
||||||
let deps = f.deps;
|
let deps = f.deps;
|
||||||
FileMeta {
|
FileMeta {
|
||||||
path: f.path,
|
path: f.path,
|
||||||
krate: f.krate,
|
krate: f.krate.map(parse_crate),
|
||||||
extern_prelude: f.extern_prelude.unwrap_or_else(|| deps.clone()),
|
extern_prelude: f.extern_prelude.unwrap_or_else(|| deps.clone()),
|
||||||
deps,
|
deps,
|
||||||
cfg,
|
cfg,
|
||||||
|
@ -112,6 +112,24 @@ impl ops::Deref for CrateName {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Origin of the crates. It is used in emitting monikers.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum CrateOrigin {
|
||||||
|
/// Crates that are from crates.io official registry,
|
||||||
|
CratesIo { name: String, version: String, repo: Option<String> },
|
||||||
|
/// Crates that are provided by the language, like std, core, proc-macro, ...
|
||||||
|
Lang(String),
|
||||||
|
/// Crates that we don't know their origin.
|
||||||
|
// Idealy this enum should cover all cases, and then we remove this variant.
|
||||||
|
Unknown,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for CrateOrigin {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::Unknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct CrateDisplayName {
|
pub struct CrateDisplayName {
|
||||||
// The name we use to display various paths (with `_`).
|
// The name we use to display various paths (with `_`).
|
||||||
@ -205,6 +223,7 @@ pub struct CrateData {
|
|||||||
pub env: Env,
|
pub env: Env,
|
||||||
pub dependencies: Vec<Dependency>,
|
pub dependencies: Vec<Dependency>,
|
||||||
pub proc_macro: Vec<ProcMacro>,
|
pub proc_macro: Vec<ProcMacro>,
|
||||||
|
pub origin: CrateOrigin,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
@ -256,6 +275,7 @@ impl CrateGraph {
|
|||||||
potential_cfg_options: CfgOptions,
|
potential_cfg_options: CfgOptions,
|
||||||
env: Env,
|
env: Env,
|
||||||
proc_macro: Vec<ProcMacro>,
|
proc_macro: Vec<ProcMacro>,
|
||||||
|
origin: CrateOrigin,
|
||||||
) -> CrateId {
|
) -> CrateId {
|
||||||
let data = CrateData {
|
let data = CrateData {
|
||||||
root_file_id: file_id,
|
root_file_id: file_id,
|
||||||
@ -267,6 +287,7 @@ impl CrateGraph {
|
|||||||
env,
|
env,
|
||||||
proc_macro,
|
proc_macro,
|
||||||
dependencies: Vec::new(),
|
dependencies: Vec::new(),
|
||||||
|
origin,
|
||||||
};
|
};
|
||||||
let crate_id = CrateId(self.arena.len() as u32);
|
let crate_id = CrateId(self.arena.len() as u32);
|
||||||
let prev = self.arena.insert(crate_id, data);
|
let prev = self.arena.insert(crate_id, data);
|
||||||
@ -571,6 +592,7 @@ mod tests {
|
|||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
);
|
);
|
||||||
let crate2 = graph.add_crate_root(
|
let crate2 = graph.add_crate_root(
|
||||||
FileId(2u32),
|
FileId(2u32),
|
||||||
@ -581,6 +603,7 @@ mod tests {
|
|||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
);
|
);
|
||||||
let crate3 = graph.add_crate_root(
|
let crate3 = graph.add_crate_root(
|
||||||
FileId(3u32),
|
FileId(3u32),
|
||||||
@ -591,6 +614,7 @@ mod tests {
|
|||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
);
|
);
|
||||||
assert!(graph
|
assert!(graph
|
||||||
.add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2))
|
.add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2))
|
||||||
@ -615,6 +639,7 @@ mod tests {
|
|||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
);
|
);
|
||||||
let crate2 = graph.add_crate_root(
|
let crate2 = graph.add_crate_root(
|
||||||
FileId(2u32),
|
FileId(2u32),
|
||||||
@ -625,6 +650,7 @@ mod tests {
|
|||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
);
|
);
|
||||||
assert!(graph
|
assert!(graph
|
||||||
.add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2))
|
.add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2))
|
||||||
@ -646,6 +672,7 @@ mod tests {
|
|||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
);
|
);
|
||||||
let crate2 = graph.add_crate_root(
|
let crate2 = graph.add_crate_root(
|
||||||
FileId(2u32),
|
FileId(2u32),
|
||||||
@ -656,6 +683,7 @@ mod tests {
|
|||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
);
|
);
|
||||||
let crate3 = graph.add_crate_root(
|
let crate3 = graph.add_crate_root(
|
||||||
FileId(3u32),
|
FileId(3u32),
|
||||||
@ -666,6 +694,7 @@ mod tests {
|
|||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
);
|
);
|
||||||
assert!(graph
|
assert!(graph
|
||||||
.add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2))
|
.add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2))
|
||||||
@ -687,6 +716,7 @@ mod tests {
|
|||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
);
|
);
|
||||||
let crate2 = graph.add_crate_root(
|
let crate2 = graph.add_crate_root(
|
||||||
FileId(2u32),
|
FileId(2u32),
|
||||||
@ -697,6 +727,7 @@ mod tests {
|
|||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
);
|
);
|
||||||
assert!(graph
|
assert!(graph
|
||||||
.add_dep(
|
.add_dep(
|
||||||
|
@ -11,9 +11,9 @@ use syntax::{ast, Parse, SourceFile, TextRange, TextSize};
|
|||||||
pub use crate::{
|
pub use crate::{
|
||||||
change::Change,
|
change::Change,
|
||||||
input::{
|
input::{
|
||||||
CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, Dependency, Edition, Env,
|
CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency,
|
||||||
ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroId, ProcMacroKind,
|
Edition, Env, ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroId,
|
||||||
SourceRoot, SourceRootId,
|
ProcMacroKind, SourceRoot, SourceRootId,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
pub use salsa::{self, Cancelled};
|
pub use salsa::{self, Cancelled};
|
||||||
|
@ -34,7 +34,7 @@ mod display;
|
|||||||
use std::{iter, ops::ControlFlow, sync::Arc};
|
use std::{iter, ops::ControlFlow, sync::Arc};
|
||||||
|
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use base_db::{CrateDisplayName, CrateId, Edition, FileId};
|
use base_db::{CrateDisplayName, CrateId, CrateOrigin, Edition, FileId};
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
adt::{ReprKind, VariantData},
|
adt::{ReprKind, VariantData},
|
||||||
@ -144,6 +144,10 @@ pub struct CrateDependency {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Crate {
|
impl Crate {
|
||||||
|
pub fn origin(self, db: &dyn HirDatabase) -> CrateOrigin {
|
||||||
|
db.crate_graph()[self.id].origin.clone()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn dependencies(self, db: &dyn HirDatabase) -> Vec<CrateDependency> {
|
pub fn dependencies(self, db: &dyn HirDatabase) -> Vec<CrateDependency> {
|
||||||
db.crate_graph()[self.id]
|
db.crate_graph()[self.id]
|
||||||
.dependencies
|
.dependencies
|
||||||
|
@ -41,6 +41,7 @@ mod inlay_hints;
|
|||||||
mod join_lines;
|
mod join_lines;
|
||||||
mod markdown_remove;
|
mod markdown_remove;
|
||||||
mod matching_brace;
|
mod matching_brace;
|
||||||
|
mod moniker;
|
||||||
mod move_item;
|
mod move_item;
|
||||||
mod parent_module;
|
mod parent_module;
|
||||||
mod references;
|
mod references;
|
||||||
@ -83,6 +84,7 @@ pub use crate::{
|
|||||||
inlay_hints::{InlayHint, InlayHintsConfig, InlayKind},
|
inlay_hints::{InlayHint, InlayHintsConfig, InlayKind},
|
||||||
join_lines::JoinLinesConfig,
|
join_lines::JoinLinesConfig,
|
||||||
markup::Markup,
|
markup::Markup,
|
||||||
|
moniker::{MonikerKind, MonikerResult, PackageInformation},
|
||||||
move_item::Direction,
|
move_item::Direction,
|
||||||
navigation_target::NavigationTarget,
|
navigation_target::NavigationTarget,
|
||||||
prime_caches::PrimeCachesProgress,
|
prime_caches::PrimeCachesProgress,
|
||||||
@ -225,6 +227,7 @@ impl Analysis {
|
|||||||
cfg_options,
|
cfg_options,
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
);
|
);
|
||||||
change.change_file(file_id, Some(Arc::new(text)));
|
change.change_file(file_id, Some(Arc::new(text)));
|
||||||
change.set_crate_graph(crate_graph);
|
change.set_crate_graph(crate_graph);
|
||||||
@ -425,6 +428,14 @@ impl Analysis {
|
|||||||
self.with_db(|db| hover::hover(db, range, config))
|
self.with_db(|db| hover::hover(db, range, config))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns moniker of symbol at position.
|
||||||
|
pub fn moniker(
|
||||||
|
&self,
|
||||||
|
position: FilePosition,
|
||||||
|
) -> Cancellable<Option<RangeInfo<Vec<moniker::MonikerResult>>>> {
|
||||||
|
self.with_db(|db| moniker::moniker(db, position))
|
||||||
|
}
|
||||||
|
|
||||||
/// Return URL(s) for the documentation of the symbol under the cursor.
|
/// Return URL(s) for the documentation of the symbol under the cursor.
|
||||||
pub fn external_docs(
|
pub fn external_docs(
|
||||||
&self,
|
&self,
|
||||||
|
233
crates/ide/src/moniker.rs
Normal file
233
crates/ide/src/moniker.rs
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
//! This module generates [moniker](https://microsoft.github.io/language-server-protocol/specifications/lsif/0.6.0/specification/#exportsImports)
|
||||||
|
//! for LSIF and LSP.
|
||||||
|
|
||||||
|
use hir::{db::DefDatabase, Crate, Name, Semantics};
|
||||||
|
use ide_db::{
|
||||||
|
base_db::{CrateOrigin, FileId, FileLoader, FilePosition},
|
||||||
|
defs::Definition,
|
||||||
|
helpers::pick_best_token,
|
||||||
|
RootDatabase,
|
||||||
|
};
|
||||||
|
use itertools::Itertools;
|
||||||
|
use syntax::{AstNode, SyntaxKind::*, T};
|
||||||
|
|
||||||
|
use crate::{doc_links::token_as_doc_comment, RangeInfo};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct MonikerIdentifier {
|
||||||
|
crate_name: String,
|
||||||
|
path: Vec<Name>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for MonikerIdentifier {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
match self {
|
||||||
|
MonikerIdentifier { path, crate_name } => {
|
||||||
|
format!("{}::{}", crate_name, path.iter().map(|x| x.to_string()).join("::"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub enum MonikerKind {
|
||||||
|
Import,
|
||||||
|
Export,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct MonikerResult {
|
||||||
|
pub identifier: MonikerIdentifier,
|
||||||
|
pub kind: MonikerKind,
|
||||||
|
pub package_information: PackageInformation,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct PackageInformation {
|
||||||
|
pub name: String,
|
||||||
|
pub repo: String,
|
||||||
|
pub version: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn crate_for_file(db: &RootDatabase, file_id: FileId) -> Option<Crate> {
|
||||||
|
for &krate in db.relevant_crates(file_id).iter() {
|
||||||
|
let crate_def_map = db.crate_def_map(krate);
|
||||||
|
for (_, data) in crate_def_map.modules() {
|
||||||
|
if data.origin.file_id() == Some(file_id) {
|
||||||
|
return Some(krate.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn moniker(
|
||||||
|
db: &RootDatabase,
|
||||||
|
FilePosition { file_id, offset }: FilePosition,
|
||||||
|
) -> Option<RangeInfo<Vec<MonikerResult>>> {
|
||||||
|
let sema = &Semantics::new(db);
|
||||||
|
let file = sema.parse(file_id).syntax().clone();
|
||||||
|
let current_crate = crate_for_file(db, file_id)?;
|
||||||
|
let original_token = pick_best_token(file.token_at_offset(offset), |kind| match kind {
|
||||||
|
IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | T![super] | T![crate] | COMMENT => 2,
|
||||||
|
kind if kind.is_trivia() => 0,
|
||||||
|
_ => 1,
|
||||||
|
})?;
|
||||||
|
if let Some(doc_comment) = token_as_doc_comment(&original_token) {
|
||||||
|
return doc_comment.get_definition_with_descend_at(sema, offset, |def, _, _| {
|
||||||
|
let m = def_to_moniker(db, def, current_crate)?;
|
||||||
|
Some(RangeInfo::new(original_token.text_range(), vec![m]))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let navs = sema
|
||||||
|
.descend_into_macros(original_token.clone())
|
||||||
|
.into_iter()
|
||||||
|
.map(|token| {
|
||||||
|
Definition::from_token(sema, &token)
|
||||||
|
.into_iter()
|
||||||
|
.flat_map(|def| def_to_moniker(sema.db, def, current_crate))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
})
|
||||||
|
.flatten()
|
||||||
|
.unique()
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
Some(RangeInfo::new(original_token.text_range(), navs))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn def_to_moniker(
|
||||||
|
db: &RootDatabase,
|
||||||
|
def: Definition,
|
||||||
|
from_crate: Crate,
|
||||||
|
) -> Option<MonikerResult> {
|
||||||
|
if matches!(def, Definition::GenericParam(_) | Definition::SelfType(_) | Definition::Local(_)) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let module = def.module(db)?;
|
||||||
|
let krate = module.krate();
|
||||||
|
let mut path = vec![];
|
||||||
|
path.extend(module.path_to_root(db).into_iter().filter_map(|x| x.name(db)));
|
||||||
|
if let Definition::Field(it) = def {
|
||||||
|
path.push(it.parent_def(db).name(db));
|
||||||
|
}
|
||||||
|
path.push(def.name(db)?);
|
||||||
|
Some(MonikerResult {
|
||||||
|
identifier: MonikerIdentifier {
|
||||||
|
crate_name: krate.display_name(db)?.crate_name().to_string(),
|
||||||
|
path,
|
||||||
|
},
|
||||||
|
kind: if krate == from_crate { MonikerKind::Export } else { MonikerKind::Import },
|
||||||
|
package_information: {
|
||||||
|
let (name, repo, version) = match krate.origin(db) {
|
||||||
|
CrateOrigin::CratesIo { repo, name, version } => (name, repo?, version),
|
||||||
|
CrateOrigin::Lang(name) => (
|
||||||
|
name,
|
||||||
|
"https://github.com/rust-lang/rust/".to_string(),
|
||||||
|
"compiler_version".to_string(),
|
||||||
|
),
|
||||||
|
CrateOrigin::Unknown => return None,
|
||||||
|
};
|
||||||
|
PackageInformation { name, repo, version }
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::fixture;
|
||||||
|
|
||||||
|
use super::MonikerKind;
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn no_moniker(ra_fixture: &str) {
|
||||||
|
let (analysis, position) = fixture::position(ra_fixture);
|
||||||
|
if let Some(x) = analysis.moniker(position).unwrap() {
|
||||||
|
assert_eq!(x.info.len(), 0, "Moniker founded but no moniker expected: {:?}", x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn check_moniker(ra_fixture: &str, identifier: &str, package: &str, kind: MonikerKind) {
|
||||||
|
let (analysis, position) = fixture::position(ra_fixture);
|
||||||
|
let x = analysis.moniker(position).unwrap().expect("no moniker found").info;
|
||||||
|
assert_eq!(x.len(), 1);
|
||||||
|
let x = x.into_iter().next().unwrap();
|
||||||
|
assert_eq!(identifier, x.identifier.to_string());
|
||||||
|
assert_eq!(package, format!("{:?}", x.package_information));
|
||||||
|
assert_eq!(kind, x.kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn basic() {
|
||||||
|
check_moniker(
|
||||||
|
r#"
|
||||||
|
//- /lib.rs crate:main deps:foo
|
||||||
|
use foo::module::func;
|
||||||
|
fn main() {
|
||||||
|
func$0();
|
||||||
|
}
|
||||||
|
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
|
||||||
|
pub mod module {
|
||||||
|
pub fn func() {}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
"foo::module::func",
|
||||||
|
r#"PackageInformation { name: "foo", repo: "https://a.b/foo.git", version: "0.1.0" }"#,
|
||||||
|
MonikerKind::Import,
|
||||||
|
);
|
||||||
|
check_moniker(
|
||||||
|
r#"
|
||||||
|
//- /lib.rs crate:main deps:foo
|
||||||
|
use foo::module::func;
|
||||||
|
fn main() {
|
||||||
|
func();
|
||||||
|
}
|
||||||
|
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
|
||||||
|
pub mod module {
|
||||||
|
pub fn func$0() {}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
"foo::module::func",
|
||||||
|
r#"PackageInformation { name: "foo", repo: "https://a.b/foo.git", version: "0.1.0" }"#,
|
||||||
|
MonikerKind::Export,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn moniker_for_field() {
|
||||||
|
check_moniker(
|
||||||
|
r#"
|
||||||
|
//- /lib.rs crate:main deps:foo
|
||||||
|
use foo::St;
|
||||||
|
fn main() {
|
||||||
|
let x = St { a$0: 2 };
|
||||||
|
}
|
||||||
|
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
|
||||||
|
pub struct St {
|
||||||
|
pub a: i32,
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
"foo::St::a",
|
||||||
|
r#"PackageInformation { name: "foo", repo: "https://a.b/foo.git", version: "0.1.0" }"#,
|
||||||
|
MonikerKind::Import,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_moniker_for_local() {
|
||||||
|
no_moniker(
|
||||||
|
r#"
|
||||||
|
//- /lib.rs crate:main deps:foo
|
||||||
|
use foo::module::func;
|
||||||
|
fn main() {
|
||||||
|
func();
|
||||||
|
}
|
||||||
|
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
|
||||||
|
pub mod module {
|
||||||
|
pub fn func() {
|
||||||
|
let x$0 = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,7 @@ use ide_db::{
|
|||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
use syntax::{AstNode, SyntaxKind::*, SyntaxToken, TextRange, T};
|
use syntax::{AstNode, SyntaxKind::*, SyntaxToken, TextRange, T};
|
||||||
|
|
||||||
|
use crate::moniker::{crate_for_file, def_to_moniker, MonikerResult};
|
||||||
use crate::{
|
use crate::{
|
||||||
hover::hover_for_definition, Analysis, Fold, HoverConfig, HoverDocFormat, HoverResult,
|
hover::hover_for_definition, Analysis, Fold, HoverConfig, HoverDocFormat, HoverResult,
|
||||||
InlayHint, InlayHintsConfig, TryToNav,
|
InlayHint, InlayHintsConfig, TryToNav,
|
||||||
@ -40,6 +41,7 @@ pub struct TokenStaticData {
|
|||||||
pub hover: Option<HoverResult>,
|
pub hover: Option<HoverResult>,
|
||||||
pub definition: Option<FileRange>,
|
pub definition: Option<FileRange>,
|
||||||
pub references: Vec<ReferenceData>,
|
pub references: Vec<ReferenceData>,
|
||||||
|
pub moniker: Option<MonikerResult>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
@ -97,6 +99,7 @@ fn all_modules(db: &dyn HirDatabase) -> Vec<Module> {
|
|||||||
|
|
||||||
impl StaticIndex<'_> {
|
impl StaticIndex<'_> {
|
||||||
fn add_file(&mut self, file_id: FileId) {
|
fn add_file(&mut self, file_id: FileId) {
|
||||||
|
let current_crate = crate_for_file(self.db, file_id);
|
||||||
let folds = self.analysis.folding_ranges(file_id).unwrap();
|
let folds = self.analysis.folding_ranges(file_id).unwrap();
|
||||||
let inlay_hints = self
|
let inlay_hints = self
|
||||||
.analysis
|
.analysis
|
||||||
@ -143,6 +146,7 @@ impl StaticIndex<'_> {
|
|||||||
.try_to_nav(self.db)
|
.try_to_nav(self.db)
|
||||||
.map(|x| FileRange { file_id: x.file_id, range: x.focus_or_full_range() }),
|
.map(|x| FileRange { file_id: x.file_id, range: x.focus_or_full_range() }),
|
||||||
references: vec![],
|
references: vec![],
|
||||||
|
moniker: current_crate.and_then(|cc| def_to_moniker(self.db, def, cc)),
|
||||||
});
|
});
|
||||||
self.def_map.insert(def, x);
|
self.def_map.insert(def, x);
|
||||||
x
|
x
|
||||||
@ -206,6 +210,7 @@ mod tests {
|
|||||||
use crate::{fixture, StaticIndex};
|
use crate::{fixture, StaticIndex};
|
||||||
use ide_db::base_db::FileRange;
|
use ide_db::base_db::FileRange;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
use syntax::TextSize;
|
||||||
|
|
||||||
fn check_all_ranges(ra_fixture: &str) {
|
fn check_all_ranges(ra_fixture: &str) {
|
||||||
let (analysis, ranges) = fixture::annotations_without_marker(ra_fixture);
|
let (analysis, ranges) = fixture::annotations_without_marker(ra_fixture);
|
||||||
@ -231,6 +236,10 @@ mod tests {
|
|||||||
let mut range_set: HashSet<_> = ranges.iter().map(|x| x.0).collect();
|
let mut range_set: HashSet<_> = ranges.iter().map(|x| x.0).collect();
|
||||||
for (_, t) in s.tokens.iter() {
|
for (_, t) in s.tokens.iter() {
|
||||||
if let Some(x) = t.definition {
|
if let Some(x) = t.definition {
|
||||||
|
if x.range.start() == TextSize::from(0) {
|
||||||
|
// ignore definitions that are whole of file
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if !range_set.contains(&x) {
|
if !range_set.contains(&x) {
|
||||||
panic!("additional definition {:?}", x);
|
panic!("additional definition {:?}", x);
|
||||||
}
|
}
|
||||||
@ -262,6 +271,28 @@ enum E { X(Foo) }
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn multi_crate() {
|
||||||
|
check_definitions(
|
||||||
|
r#"
|
||||||
|
//- /main.rs crate:main deps:foo
|
||||||
|
|
||||||
|
|
||||||
|
use foo::func;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
//^^^^
|
||||||
|
func();
|
||||||
|
}
|
||||||
|
//- /foo/lib.rs crate:foo
|
||||||
|
|
||||||
|
pub func() {
|
||||||
|
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn derives() {
|
fn derives() {
|
||||||
check_all_ranges(
|
check_all_ranges(
|
||||||
|
@ -130,6 +130,8 @@ pub struct PackageData {
|
|||||||
pub version: semver::Version,
|
pub version: semver::Version,
|
||||||
/// Name as given in the `Cargo.toml`
|
/// Name as given in the `Cargo.toml`
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
/// Repository as given in the `Cargo.toml`
|
||||||
|
pub repository: Option<String>,
|
||||||
/// Path containing the `Cargo.toml`
|
/// Path containing the `Cargo.toml`
|
||||||
pub manifest: ManifestPath,
|
pub manifest: ManifestPath,
|
||||||
/// Targets provided by the crate (lib, bin, example, test, ...)
|
/// Targets provided by the crate (lib, bin, example, test, ...)
|
||||||
@ -146,9 +148,9 @@ pub struct PackageData {
|
|||||||
pub features: FxHashMap<String, Vec<String>>,
|
pub features: FxHashMap<String, Vec<String>>,
|
||||||
/// List of features enabled on this package
|
/// List of features enabled on this package
|
||||||
pub active_features: Vec<String>,
|
pub active_features: Vec<String>,
|
||||||
// String representation of package id
|
/// String representation of package id
|
||||||
pub id: String,
|
pub id: String,
|
||||||
// The contents of [package.metadata.rust-analyzer]
|
/// The contents of [package.metadata.rust-analyzer]
|
||||||
pub metadata: RustAnalyzerPackageMetaData,
|
pub metadata: RustAnalyzerPackageMetaData,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +305,14 @@ impl CargoWorkspace {
|
|||||||
meta.packages.sort_by(|a, b| a.id.cmp(&b.id));
|
meta.packages.sort_by(|a, b| a.id.cmp(&b.id));
|
||||||
for meta_pkg in &meta.packages {
|
for meta_pkg in &meta.packages {
|
||||||
let cargo_metadata::Package {
|
let cargo_metadata::Package {
|
||||||
id, edition, name, manifest_path, version, metadata, ..
|
id,
|
||||||
|
edition,
|
||||||
|
name,
|
||||||
|
manifest_path,
|
||||||
|
version,
|
||||||
|
metadata,
|
||||||
|
repository,
|
||||||
|
..
|
||||||
} = meta_pkg;
|
} = meta_pkg;
|
||||||
let meta = from_value::<PackageMetadata>(metadata.clone()).unwrap_or_default();
|
let meta = from_value::<PackageMetadata>(metadata.clone()).unwrap_or_default();
|
||||||
let edition = edition.parse::<Edition>().unwrap_or_else(|err| {
|
let edition = edition.parse::<Edition>().unwrap_or_else(|err| {
|
||||||
@ -324,6 +333,7 @@ impl CargoWorkspace {
|
|||||||
is_local,
|
is_local,
|
||||||
is_member,
|
is_member,
|
||||||
edition,
|
edition,
|
||||||
|
repository: repository.clone(),
|
||||||
dependencies: Vec::new(),
|
dependencies: Vec::new(),
|
||||||
features: meta_pkg.features.clone().into_iter().collect(),
|
features: meta_pkg.features.clone().into_iter().collect(),
|
||||||
active_features: Vec::new(),
|
active_features: Vec::new(),
|
||||||
|
@ -39,6 +39,7 @@ pub struct Crate {
|
|||||||
pub(crate) include: Vec<AbsPathBuf>,
|
pub(crate) include: Vec<AbsPathBuf>,
|
||||||
pub(crate) exclude: Vec<AbsPathBuf>,
|
pub(crate) exclude: Vec<AbsPathBuf>,
|
||||||
pub(crate) is_proc_macro: bool,
|
pub(crate) is_proc_macro: bool,
|
||||||
|
pub(crate) repository: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProjectJson {
|
impl ProjectJson {
|
||||||
@ -99,6 +100,7 @@ impl ProjectJson {
|
|||||||
include,
|
include,
|
||||||
exclude,
|
exclude,
|
||||||
is_proc_macro: crate_data.is_proc_macro,
|
is_proc_macro: crate_data.is_proc_macro,
|
||||||
|
repository: crate_data.repository,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
@ -142,6 +144,8 @@ struct CrateData {
|
|||||||
source: Option<CrateSource>,
|
source: Option<CrateSource>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
is_proc_macro: bool,
|
is_proc_macro: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
repository: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
|
@ -173,6 +173,11 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "hello_world",
|
||||||
|
version: "0.1.0",
|
||||||
|
repo: None,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
5,
|
5,
|
||||||
@ -242,6 +247,13 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "const_fn",
|
||||||
|
version: "0.2.98",
|
||||||
|
repo: Some(
|
||||||
|
"https://github.com/rust-lang/libc",
|
||||||
|
),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
2,
|
2,
|
||||||
@ -311,6 +323,11 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "an_example",
|
||||||
|
version: "0.1.0",
|
||||||
|
repo: None,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
4,
|
4,
|
||||||
@ -370,6 +387,13 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
|||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "libc",
|
||||||
|
version: "0.2.98",
|
||||||
|
repo: Some(
|
||||||
|
"https://github.com/rust-lang/libc",
|
||||||
|
),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
1,
|
1,
|
||||||
@ -439,6 +463,11 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "hello_world",
|
||||||
|
version: "0.1.0",
|
||||||
|
repo: None,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
6,
|
6,
|
||||||
@ -498,6 +527,13 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
|||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "build_script_build",
|
||||||
|
version: "0.2.98",
|
||||||
|
repo: Some(
|
||||||
|
"https://github.com/rust-lang/libc",
|
||||||
|
),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
3,
|
3,
|
||||||
@ -567,6 +603,11 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "it",
|
||||||
|
version: "0.1.0",
|
||||||
|
repo: None,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}"#]],
|
}"#]],
|
||||||
@ -651,6 +692,11 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "hello_world",
|
||||||
|
version: "0.1.0",
|
||||||
|
repo: None,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
5,
|
5,
|
||||||
@ -720,6 +766,13 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "const_fn",
|
||||||
|
version: "0.2.98",
|
||||||
|
repo: Some(
|
||||||
|
"https://github.com/rust-lang/libc",
|
||||||
|
),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
2,
|
2,
|
||||||
@ -791,6 +844,11 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "an_example",
|
||||||
|
version: "0.1.0",
|
||||||
|
repo: None,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
4,
|
4,
|
||||||
@ -850,6 +908,13 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
|||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "libc",
|
||||||
|
version: "0.2.98",
|
||||||
|
repo: Some(
|
||||||
|
"https://github.com/rust-lang/libc",
|
||||||
|
),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
1,
|
1,
|
||||||
@ -921,6 +986,11 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "hello_world",
|
||||||
|
version: "0.1.0",
|
||||||
|
repo: None,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
6,
|
6,
|
||||||
@ -980,6 +1050,13 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
|||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "build_script_build",
|
||||||
|
version: "0.2.98",
|
||||||
|
repo: Some(
|
||||||
|
"https://github.com/rust-lang/libc",
|
||||||
|
),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
3,
|
3,
|
||||||
@ -1051,6 +1128,11 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "it",
|
||||||
|
version: "0.1.0",
|
||||||
|
repo: None,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}"#]],
|
}"#]],
|
||||||
@ -1126,6 +1208,11 @@ fn cargo_hello_world_project_model() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "hello_world",
|
||||||
|
version: "0.1.0",
|
||||||
|
repo: None,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
5,
|
5,
|
||||||
@ -1197,6 +1284,13 @@ fn cargo_hello_world_project_model() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "const_fn",
|
||||||
|
version: "0.2.98",
|
||||||
|
repo: Some(
|
||||||
|
"https://github.com/rust-lang/libc",
|
||||||
|
),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
2,
|
2,
|
||||||
@ -1268,6 +1362,11 @@ fn cargo_hello_world_project_model() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "an_example",
|
||||||
|
version: "0.1.0",
|
||||||
|
repo: None,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
4,
|
4,
|
||||||
@ -1329,6 +1428,13 @@ fn cargo_hello_world_project_model() {
|
|||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "libc",
|
||||||
|
version: "0.2.98",
|
||||||
|
repo: Some(
|
||||||
|
"https://github.com/rust-lang/libc",
|
||||||
|
),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
1,
|
1,
|
||||||
@ -1400,6 +1506,11 @@ fn cargo_hello_world_project_model() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "hello_world",
|
||||||
|
version: "0.1.0",
|
||||||
|
repo: None,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
6,
|
6,
|
||||||
@ -1461,6 +1572,13 @@ fn cargo_hello_world_project_model() {
|
|||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "build_script_build",
|
||||||
|
version: "0.2.98",
|
||||||
|
repo: Some(
|
||||||
|
"https://github.com/rust-lang/libc",
|
||||||
|
),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
3,
|
3,
|
||||||
@ -1532,6 +1650,11 @@ fn cargo_hello_world_project_model() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "it",
|
||||||
|
version: "0.1.0",
|
||||||
|
repo: None,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}"#]],
|
}"#]],
|
||||||
@ -1583,6 +1706,9 @@ fn rust_project_hello_world_project_model() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: Lang(
|
||||||
|
"alloc",
|
||||||
|
),
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
10,
|
10,
|
||||||
@ -1611,6 +1737,9 @@ fn rust_project_hello_world_project_model() {
|
|||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: Lang(
|
||||||
|
"unwind",
|
||||||
|
),
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
7,
|
7,
|
||||||
@ -1639,6 +1768,9 @@ fn rust_project_hello_world_project_model() {
|
|||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: Lang(
|
||||||
|
"std_detect",
|
||||||
|
),
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
4,
|
4,
|
||||||
@ -1677,6 +1809,9 @@ fn rust_project_hello_world_project_model() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: Lang(
|
||||||
|
"proc_macro",
|
||||||
|
),
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
1,
|
1,
|
||||||
@ -1705,6 +1840,9 @@ fn rust_project_hello_world_project_model() {
|
|||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: Lang(
|
||||||
|
"core",
|
||||||
|
),
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
11,
|
11,
|
||||||
@ -1770,6 +1908,11 @@ fn rust_project_hello_world_project_model() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: CratesIo {
|
||||||
|
name: "hello_world",
|
||||||
|
version: "",
|
||||||
|
repo: None,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
8,
|
8,
|
||||||
@ -1798,6 +1941,9 @@ fn rust_project_hello_world_project_model() {
|
|||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: Lang(
|
||||||
|
"term",
|
||||||
|
),
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
5,
|
5,
|
||||||
@ -1826,6 +1972,9 @@ fn rust_project_hello_world_project_model() {
|
|||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: Lang(
|
||||||
|
"profiler_builtins",
|
||||||
|
),
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
2,
|
2,
|
||||||
@ -1854,6 +2003,9 @@ fn rust_project_hello_world_project_model() {
|
|||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: Lang(
|
||||||
|
"panic_abort",
|
||||||
|
),
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
9,
|
9,
|
||||||
@ -1882,6 +2034,9 @@ fn rust_project_hello_world_project_model() {
|
|||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: Lang(
|
||||||
|
"test",
|
||||||
|
),
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
6,
|
6,
|
||||||
@ -1992,6 +2147,9 @@ fn rust_project_hello_world_project_model() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: Lang(
|
||||||
|
"std",
|
||||||
|
),
|
||||||
},
|
},
|
||||||
CrateId(
|
CrateId(
|
||||||
3,
|
3,
|
||||||
@ -2020,6 +2178,9 @@ fn rust_project_hello_world_project_model() {
|
|||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: [],
|
proc_macro: [],
|
||||||
|
origin: Lang(
|
||||||
|
"panic_unwind",
|
||||||
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}"#]],
|
}"#]],
|
||||||
|
@ -6,7 +6,8 @@ use std::{collections::VecDeque, fmt, fs, process::Command};
|
|||||||
|
|
||||||
use anyhow::{format_err, Context, Result};
|
use anyhow::{format_err, Context, Result};
|
||||||
use base_db::{
|
use base_db::{
|
||||||
CrateDisplayName, CrateGraph, CrateId, CrateName, Dependency, Edition, Env, FileId, ProcMacro,
|
CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, Edition, Env,
|
||||||
|
FileId, ProcMacro,
|
||||||
};
|
};
|
||||||
use cfg::{CfgDiff, CfgOptions};
|
use cfg::{CfgDiff, CfgOptions};
|
||||||
use paths::{AbsPath, AbsPathBuf};
|
use paths::{AbsPath, AbsPathBuf};
|
||||||
@ -473,6 +474,15 @@ fn project_json_to_crate_graph(
|
|||||||
cfg_options,
|
cfg_options,
|
||||||
env,
|
env,
|
||||||
proc_macro.unwrap_or_default(),
|
proc_macro.unwrap_or_default(),
|
||||||
|
if let Some(name) = &krate.display_name {
|
||||||
|
CrateOrigin::CratesIo {
|
||||||
|
repo: krate.repository.clone(),
|
||||||
|
name: name.crate_name().to_string(),
|
||||||
|
version: krate.version.clone().unwrap_or_else(|| "".to_string()),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CrateOrigin::Unknown
|
||||||
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -681,6 +691,7 @@ fn detached_files_to_crate_graph(
|
|||||||
cfg_options.clone(),
|
cfg_options.clone(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
|
CrateOrigin::Unknown,
|
||||||
);
|
);
|
||||||
|
|
||||||
public_deps.add(detached_file_crate, &mut crate_graph);
|
public_deps.add(detached_file_crate, &mut crate_graph);
|
||||||
@ -821,7 +832,7 @@ fn add_target_crate_root(
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|feat| CfgFlag::KeyValue { key: "feature".into(), value: feat.0.into() }),
|
.map(|feat| CfgFlag::KeyValue { key: "feature".into(), value: feat.0.into() }),
|
||||||
);
|
);
|
||||||
|
let crate_name = display_name.crate_name().to_string();
|
||||||
crate_graph.add_crate_root(
|
crate_graph.add_crate_root(
|
||||||
file_id,
|
file_id,
|
||||||
edition,
|
edition,
|
||||||
@ -831,6 +842,11 @@ fn add_target_crate_root(
|
|||||||
potential_cfg_options,
|
potential_cfg_options,
|
||||||
env,
|
env,
|
||||||
proc_macro,
|
proc_macro,
|
||||||
|
CrateOrigin::CratesIo {
|
||||||
|
name: crate_name,
|
||||||
|
repo: pkg.repository.clone(),
|
||||||
|
version: pkg.version.to_string(),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -874,6 +890,7 @@ fn sysroot_to_crate_graph(
|
|||||||
cfg_options.clone(),
|
cfg_options.clone(),
|
||||||
env,
|
env,
|
||||||
proc_macro,
|
proc_macro,
|
||||||
|
CrateOrigin::Lang(sysroot[krate].name.clone()),
|
||||||
);
|
);
|
||||||
Some((krate, crate_id))
|
Some((krate, crate_id))
|
||||||
})
|
})
|
||||||
|
@ -5,8 +5,8 @@ use std::env;
|
|||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
use ide::{
|
use ide::{
|
||||||
Analysis, FileId, FileRange, RootDatabase, StaticIndex, StaticIndexedFile, TokenId,
|
Analysis, FileId, FileRange, MonikerKind, PackageInformation, RootDatabase, StaticIndex,
|
||||||
TokenStaticData,
|
StaticIndexedFile, TokenId, TokenStaticData,
|
||||||
};
|
};
|
||||||
use ide_db::LineIndexDatabase;
|
use ide_db::LineIndexDatabase;
|
||||||
|
|
||||||
@ -36,6 +36,7 @@ struct LsifManager<'a> {
|
|||||||
token_map: HashMap<TokenId, Id>,
|
token_map: HashMap<TokenId, Id>,
|
||||||
range_map: HashMap<FileRange, Id>,
|
range_map: HashMap<FileRange, Id>,
|
||||||
file_map: HashMap<FileId, Id>,
|
file_map: HashMap<FileId, Id>,
|
||||||
|
package_map: HashMap<PackageInformation, Id>,
|
||||||
analysis: &'a Analysis,
|
analysis: &'a Analysis,
|
||||||
db: &'a RootDatabase,
|
db: &'a RootDatabase,
|
||||||
vfs: &'a Vfs,
|
vfs: &'a Vfs,
|
||||||
@ -57,6 +58,7 @@ impl LsifManager<'_> {
|
|||||||
token_map: HashMap::default(),
|
token_map: HashMap::default(),
|
||||||
range_map: HashMap::default(),
|
range_map: HashMap::default(),
|
||||||
file_map: HashMap::default(),
|
file_map: HashMap::default(),
|
||||||
|
package_map: HashMap::default(),
|
||||||
analysis,
|
analysis,
|
||||||
db,
|
db,
|
||||||
vfs,
|
vfs,
|
||||||
@ -92,6 +94,28 @@ impl LsifManager<'_> {
|
|||||||
result_set_id
|
result_set_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_package_id(&mut self, package_information: PackageInformation) -> Id {
|
||||||
|
if let Some(x) = self.package_map.get(&package_information) {
|
||||||
|
return *x;
|
||||||
|
}
|
||||||
|
let pi = package_information.clone();
|
||||||
|
let result_set_id =
|
||||||
|
self.add_vertex(lsif::Vertex::PackageInformation(lsif::PackageInformation {
|
||||||
|
name: pi.name,
|
||||||
|
manager: "cargo".to_string(),
|
||||||
|
uri: None,
|
||||||
|
content: None,
|
||||||
|
repository: Some(lsif::Repository {
|
||||||
|
url: pi.repo,
|
||||||
|
r#type: "git".to_string(),
|
||||||
|
commit_id: None,
|
||||||
|
}),
|
||||||
|
version: Some(pi.version),
|
||||||
|
}));
|
||||||
|
self.package_map.insert(package_information, result_set_id);
|
||||||
|
result_set_id
|
||||||
|
}
|
||||||
|
|
||||||
fn get_range_id(&mut self, id: FileRange) -> Id {
|
fn get_range_id(&mut self, id: FileRange) -> Id {
|
||||||
if let Some(x) = self.range_map.get(&id) {
|
if let Some(x) = self.range_map.get(&id) {
|
||||||
return *x;
|
return *x;
|
||||||
@ -146,6 +170,26 @@ impl LsifManager<'_> {
|
|||||||
out_v: result_set_id.into(),
|
out_v: result_set_id.into(),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
if let Some(moniker) = token.moniker {
|
||||||
|
let package_id = self.get_package_id(moniker.package_information);
|
||||||
|
let moniker_id = self.add_vertex(lsif::Vertex::Moniker(lsp_types::Moniker {
|
||||||
|
scheme: "rust-analyzer".to_string(),
|
||||||
|
identifier: moniker.identifier.to_string(),
|
||||||
|
unique: lsp_types::UniquenessLevel::Scheme,
|
||||||
|
kind: Some(match moniker.kind {
|
||||||
|
MonikerKind::Import => lsp_types::MonikerKind::Import,
|
||||||
|
MonikerKind::Export => lsp_types::MonikerKind::Export,
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
self.add_edge(lsif::Edge::PackageInformation(lsif::EdgeData {
|
||||||
|
in_v: package_id.into(),
|
||||||
|
out_v: moniker_id.into(),
|
||||||
|
}));
|
||||||
|
self.add_edge(lsif::Edge::Moniker(lsif::EdgeData {
|
||||||
|
in_v: moniker_id.into(),
|
||||||
|
out_v: result_set_id.into(),
|
||||||
|
}));
|
||||||
|
}
|
||||||
if let Some(def) = token.definition {
|
if let Some(def) = token.definition {
|
||||||
let result_id = self.add_vertex(lsif::Vertex::DefinitionResult);
|
let result_id = self.add_vertex(lsif::Vertex::DefinitionResult);
|
||||||
let def_vertex = self.get_range_id(def);
|
let def_vertex = self.get_range_id(def);
|
||||||
|
Loading…
Reference in New Issue
Block a user