mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +00:00
Getting cargo workspace from file_id
and refactoring
This commit is contained in:
parent
0913809ac8
commit
396934860c
3 changed files with 29 additions and 33 deletions
|
@ -133,7 +133,7 @@ pub(crate) fn external_docs(
|
||||||
db: &RootDatabase,
|
db: &RootDatabase,
|
||||||
position: &FilePosition,
|
position: &FilePosition,
|
||||||
target_dir: Option<&OsStr>,
|
target_dir: Option<&OsStr>,
|
||||||
) -> DocumentationLinks {
|
) -> Option<DocumentationLinks> {
|
||||||
let sema = &Semantics::new(db);
|
let sema = &Semantics::new(db);
|
||||||
let file = sema.parse(position.file_id).syntax().clone();
|
let file = sema.parse(position.file_id).syntax().clone();
|
||||||
let token = pick_best_token(file.token_at_offset(position.offset), |kind| match kind {
|
let token = pick_best_token(file.token_at_offset(position.offset), |kind| match kind {
|
||||||
|
@ -141,11 +141,10 @@ pub(crate) fn external_docs(
|
||||||
T!['('] | T![')'] => 2,
|
T!['('] | T![')'] => 2,
|
||||||
kind if kind.is_trivia() => 0,
|
kind if kind.is_trivia() => 0,
|
||||||
_ => 1,
|
_ => 1,
|
||||||
});
|
})?;
|
||||||
let Some(token) = token else { return Default::default() };
|
|
||||||
let token = sema.descend_into_macros_single(token);
|
let token = sema.descend_into_macros_single(token);
|
||||||
|
|
||||||
let Some(node) = token.parent() else { return Default::default() };
|
let node = token.parent()?;
|
||||||
let definition = match_ast! {
|
let definition = match_ast! {
|
||||||
match node {
|
match node {
|
||||||
ast::NameRef(name_ref) => match NameRefClass::classify(sema, &name_ref) {
|
ast::NameRef(name_ref) => match NameRefClass::classify(sema, &name_ref) {
|
||||||
|
@ -153,18 +152,18 @@ pub(crate) fn external_docs(
|
||||||
Some(NameRefClass::FieldShorthand { local_ref: _, field_ref }) => {
|
Some(NameRefClass::FieldShorthand { local_ref: _, field_ref }) => {
|
||||||
Definition::Field(field_ref)
|
Definition::Field(field_ref)
|
||||||
}
|
}
|
||||||
None => return Default::default(),
|
None => return None,
|
||||||
},
|
},
|
||||||
ast::Name(name) => match NameClass::classify(sema, &name) {
|
ast::Name(name) => match NameClass::classify(sema, &name) {
|
||||||
Some(NameClass::Definition(it) | NameClass::ConstReference(it)) => it,
|
Some(NameClass::Definition(it) | NameClass::ConstReference(it)) => it,
|
||||||
Some(NameClass::PatFieldShorthand { local_def: _, field_ref }) => Definition::Field(field_ref),
|
Some(NameClass::PatFieldShorthand { local_def: _, field_ref }) => Definition::Field(field_ref),
|
||||||
None => return Default::default(),
|
None => return None,
|
||||||
},
|
},
|
||||||
_ => return Default::default(),
|
_ => return None
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
get_doc_links(db, definition, target_dir)
|
Some(get_doc_links(db, definition, target_dir))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extracts all links from a given markdown text returning the definition text range, link-text
|
/// Extracts all links from a given markdown text returning the definition text range, link-text
|
||||||
|
@ -327,6 +326,10 @@ fn get_doc_links(
|
||||||
def: Definition,
|
def: Definition,
|
||||||
target_dir: Option<&OsStr>,
|
target_dir: Option<&OsStr>,
|
||||||
) -> DocumentationLinks {
|
) -> DocumentationLinks {
|
||||||
|
let join_url = |base_url: Option<Url>, path: &str| -> Option<Url> {
|
||||||
|
base_url.and_then(|url| url.join(path).ok())
|
||||||
|
};
|
||||||
|
|
||||||
let Some((target, file, frag)) = filename_and_frag_for_def(db, def) else { return Default::default(); };
|
let Some((target, file, frag)) = filename_and_frag_for_def(db, def) else { return Default::default(); };
|
||||||
|
|
||||||
let (mut web_url, mut local_url) = get_doc_base_urls(db, target, target_dir);
|
let (mut web_url, mut local_url) = get_doc_base_urls(db, target, target_dir);
|
||||||
|
@ -339,21 +342,13 @@ fn get_doc_links(
|
||||||
web_url = join_url(web_url, &file);
|
web_url = join_url(web_url, &file);
|
||||||
local_url = join_url(local_url, &file);
|
local_url = join_url(local_url, &file);
|
||||||
|
|
||||||
set_fragment_for_url(web_url.as_mut(), frag.as_deref());
|
web_url.as_mut().map(|url| url.set_fragment(frag.as_deref()));
|
||||||
set_fragment_for_url(local_url.as_mut(), frag.as_deref());
|
local_url.as_mut().map(|url| url.set_fragment(frag.as_deref()));
|
||||||
|
|
||||||
return DocumentationLinks {
|
return DocumentationLinks {
|
||||||
web_url: web_url.map(|it| it.into()),
|
web_url: web_url.map(|it| it.into()),
|
||||||
local_url: local_url.map(|it| it.into()),
|
local_url: local_url.map(|it| it.into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
fn join_url(base_url: Option<Url>, path: &str) -> Option<Url> {
|
|
||||||
base_url.and_then(|url| url.join(path).ok())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_fragment_for_url(url: Option<&mut Url>, frag: Option<&str>) {
|
|
||||||
url.map(|url| url.set_fragment(frag));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rewrite_intra_doc_link(
|
fn rewrite_intra_doc_link(
|
||||||
|
@ -467,8 +462,14 @@ fn get_doc_base_urls(
|
||||||
def: Definition,
|
def: Definition,
|
||||||
target_dir: Option<&OsStr>,
|
target_dir: Option<&OsStr>,
|
||||||
) -> (Option<Url>, Option<Url>) {
|
) -> (Option<Url>, Option<Url>) {
|
||||||
let local_doc_path =
|
let local_doc_path = target_dir
|
||||||
target_dir.and_then(create_url_from_os_str).and_then(|it| it.join("doc/").ok());
|
.and_then(|path: &OsStr| -> Option<Url> {
|
||||||
|
let mut with_prefix = OsStr::new("file:///").to_os_string();
|
||||||
|
with_prefix.push(path);
|
||||||
|
with_prefix.push("/");
|
||||||
|
with_prefix.to_str().and_then(|s| Url::parse(s).ok())
|
||||||
|
})
|
||||||
|
.and_then(|it| it.join("doc/").ok());
|
||||||
// special case base url of `BuiltinType` to core
|
// special case base url of `BuiltinType` to core
|
||||||
// https://github.com/rust-lang/rust-analyzer/issues/12250
|
// https://github.com/rust-lang/rust-analyzer/issues/12250
|
||||||
if let Definition::BuiltinType(..) = def {
|
if let Definition::BuiltinType(..) = def {
|
||||||
|
@ -533,14 +534,7 @@ fn get_doc_base_urls(
|
||||||
.and_then(|it| it.join(&format!("{display_name}/")).ok());
|
.and_then(|it| it.join(&format!("{display_name}/")).ok());
|
||||||
let local_base = local_base.and_then(|it| it.join(&format!("{display_name}/")).ok());
|
let local_base = local_base.and_then(|it| it.join(&format!("{display_name}/")).ok());
|
||||||
|
|
||||||
return (web_base, local_base);
|
(web_base, local_base)
|
||||||
|
|
||||||
fn create_url_from_os_str(path: &OsStr) -> Option<Url> {
|
|
||||||
let mut with_prefix = OsStr::new("file:///").to_os_string();
|
|
||||||
with_prefix.push(path);
|
|
||||||
with_prefix.push("/");
|
|
||||||
with_prefix.to_str().and_then(|s| Url::parse(s).ok())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the filename and extension generated for a symbol by rustdoc.
|
/// Get the filename and extension generated for a symbol by rustdoc.
|
||||||
|
|
|
@ -476,7 +476,7 @@ impl Analysis {
|
||||||
position: FilePosition,
|
position: FilePosition,
|
||||||
target_dir: Option<&OsStr>,
|
target_dir: Option<&OsStr>,
|
||||||
) -> Cancellable<doc_links::DocumentationLinks> {
|
) -> Cancellable<doc_links::DocumentationLinks> {
|
||||||
self.with_db(|db| doc_links::external_docs(db, &position, target_dir))
|
self.with_db(|db| doc_links::external_docs(db, &position, target_dir).unwrap_or_default())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes parameter information at the given position.
|
/// Computes parameter information at the given position.
|
||||||
|
|
|
@ -1537,14 +1537,16 @@ pub(crate) fn handle_open_docs(
|
||||||
params: lsp_types::TextDocumentPositionParams,
|
params: lsp_types::TextDocumentPositionParams,
|
||||||
) -> Result<(Option<lsp_types::Url>, Option<lsp_types::Url>)> {
|
) -> Result<(Option<lsp_types::Url>, Option<lsp_types::Url>)> {
|
||||||
let _p = profile::span("handle_open_docs");
|
let _p = profile::span("handle_open_docs");
|
||||||
|
let file_uri = ¶ms.text_document.uri;
|
||||||
|
let file_id = from_proto::file_id(&snap, file_uri)?;
|
||||||
let position = from_proto::file_position(&snap, params)?;
|
let position = from_proto::file_position(&snap, params)?;
|
||||||
|
|
||||||
let cargo = match snap.workspaces.get(0) {
|
let cargo = match &*snap.analysis.crates_for(file_id)? {
|
||||||
Some(ProjectWorkspace::Cargo { cargo, .. }) => Some(cargo),
|
&[crate_id, ..] => snap.cargo_target_for_crate_root(crate_id).map(|(it, _)| it),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
let target_dir =
|
|
||||||
cargo.and_then(|cargo| Some(cargo.target_directory())).and_then(|p| Some(p.as_os_str()));
|
let target_dir = cargo.map(|cargo| cargo.target_directory()).map(|p| p.as_os_str());
|
||||||
let Ok(remote_urls) = snap.analysis.external_docs(position, target_dir) else { return Ok((None, None)); };
|
let Ok(remote_urls) = snap.analysis.external_docs(position, target_dir) else { return Ok((None, None)); };
|
||||||
|
|
||||||
let web_url = remote_urls.web_url.and_then(|it| Url::parse(&it).ok());
|
let web_url = remote_urls.web_url.and_then(|it| Url::parse(&it).ok());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue