mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-27 20:35:09 +00:00
Don't parse intra doc links as syntax trees
This commit is contained in:
parent
5a343415e8
commit
6cf7b5f8d7
8 changed files with 33 additions and 55 deletions
|
@ -4,7 +4,6 @@ use std::iter;
|
||||||
|
|
||||||
use hir_expand::{span_map::SpanMapRef, InFile};
|
use hir_expand::{span_map::SpanMapRef, InFile};
|
||||||
use la_arena::ArenaMap;
|
use la_arena::ArenaMap;
|
||||||
use stdx::assert_eq_size;
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
|
@ -25,7 +24,6 @@ pub enum RawVisibility {
|
||||||
/// `pub`.
|
/// `pub`.
|
||||||
Public,
|
Public,
|
||||||
}
|
}
|
||||||
assert_eq_size!(RawVisibility, 48);
|
|
||||||
|
|
||||||
impl RawVisibility {
|
impl RawVisibility {
|
||||||
pub(crate) const fn private() -> RawVisibility {
|
pub(crate) const fn private() -> RawVisibility {
|
||||||
|
|
|
@ -26,7 +26,6 @@ pub mod span_map;
|
||||||
mod fixup;
|
mod fixup;
|
||||||
|
|
||||||
use attrs::collect_attrs;
|
use attrs::collect_attrs;
|
||||||
use stdx::assert_eq_size;
|
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
use std::{fmt, hash::Hash};
|
use std::{fmt, hash::Hash};
|
||||||
|
@ -176,7 +175,6 @@ pub struct MacroCallLoc {
|
||||||
pub kind: MacroCallKind,
|
pub kind: MacroCallKind,
|
||||||
pub call_site: Span,
|
pub call_site: Span,
|
||||||
}
|
}
|
||||||
assert_eq_size!(MacroCallLoc, 104);
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub struct MacroDefId {
|
pub struct MacroDefId {
|
||||||
|
@ -187,7 +185,6 @@ pub struct MacroDefId {
|
||||||
pub allow_internal_unsafe: bool,
|
pub allow_internal_unsafe: bool,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
assert_eq_size!(MacroDefId, 44);
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub enum MacroDefKind {
|
pub enum MacroDefKind {
|
||||||
|
|
|
@ -15,7 +15,6 @@ use crate::{
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use span::SyntaxContextId;
|
use span::SyntaxContextId;
|
||||||
use stdx::assert_eq_size;
|
|
||||||
use syntax::{ast, AstNode};
|
use syntax::{ast, AstNode};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
@ -23,7 +22,6 @@ pub struct ModPath {
|
||||||
pub kind: PathKind,
|
pub kind: PathKind,
|
||||||
segments: SmallVec<[Name; 1]>,
|
segments: SmallVec<[Name; 1]>,
|
||||||
}
|
}
|
||||||
assert_eq_size!(ModPath, 40);
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct UnescapedModPath<'a>(&'a ModPath);
|
pub struct UnescapedModPath<'a>(&'a ModPath);
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use stdx::assert_eq_size;
|
|
||||||
use syntax::{ast, format_smolstr, utils::is_raw_identifier, SmolStr};
|
use syntax::{ast, format_smolstr, utils::is_raw_identifier, SmolStr};
|
||||||
|
|
||||||
/// `Name` is a wrapper around string, which is used in hir for both references
|
/// `Name` is a wrapper around string, which is used in hir for both references
|
||||||
|
@ -14,7 +13,6 @@ use syntax::{ast, format_smolstr, utils::is_raw_identifier, SmolStr};
|
||||||
/// name without "r#".
|
/// name without "r#".
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
pub struct Name(Repr);
|
pub struct Name(Repr);
|
||||||
assert_eq_size!(Name, 24);
|
|
||||||
|
|
||||||
/// Wrapper of `Name` to print the name without "r#" even when it is a raw identifier.
|
/// Wrapper of `Name` to print the name without "r#" even when it is a raw identifier.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
use base_db::FileId;
|
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
attr::AttrsWithOwner,
|
attr::AttrsWithOwner,
|
||||||
item_scope::ItemInNs,
|
item_scope::ItemInNs,
|
||||||
|
@ -11,12 +10,8 @@ use hir_def::{
|
||||||
resolver::{HasResolver, Resolver, TypeNs},
|
resolver::{HasResolver, Resolver, TypeNs},
|
||||||
AssocItemId, AttrDefId, ModuleDefId,
|
AssocItemId, AttrDefId, ModuleDefId,
|
||||||
};
|
};
|
||||||
use hir_expand::{
|
use hir_expand::{mod_path::PathKind, name::Name};
|
||||||
name::Name,
|
|
||||||
span_map::{RealSpanMap, SpanMapRef},
|
|
||||||
};
|
|
||||||
use hir_ty::{db::HirDatabase, method_resolution};
|
use hir_ty::{db::HirDatabase, method_resolution};
|
||||||
use syntax::{ast, AstNode};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Adt, AsAssocItem, AssocItem, BuiltinType, Const, ConstParam, DocLinkDef, Enum, ExternCrateDecl,
|
Adt, AsAssocItem, AssocItem, BuiltinType, Const, ConstParam, DocLinkDef, Enum, ExternCrateDecl,
|
||||||
|
@ -129,7 +124,7 @@ fn resolve_doc_path_on_(
|
||||||
AttrDefId::GenericParamId(_) => return None,
|
AttrDefId::GenericParamId(_) => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut modpath = modpath_from_str(db, link)?;
|
let mut modpath = modpath_from_str(link)?;
|
||||||
|
|
||||||
let resolved = resolver.resolve_module_path_in_items(db.upcast(), &modpath);
|
let resolved = resolver.resolve_module_path_in_items(db.upcast(), &modpath);
|
||||||
if resolved.is_none() {
|
if resolved.is_none() {
|
||||||
|
@ -305,34 +300,37 @@ fn as_module_def_if_namespace_matches(
|
||||||
(ns.unwrap_or(expected_ns) == expected_ns).then(|| DocLinkDef::ModuleDef(def))
|
(ns.unwrap_or(expected_ns) == expected_ns).then(|| DocLinkDef::ModuleDef(def))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn modpath_from_str(db: &dyn HirDatabase, link: &str) -> Option<ModPath> {
|
fn modpath_from_str(link: &str) -> Option<ModPath> {
|
||||||
// FIXME: this is not how we should get a mod path here.
|
// FIXME: this is not how we should get a mod path here.
|
||||||
let try_get_modpath = |link: &str| {
|
let try_get_modpath = |link: &str| {
|
||||||
let ast_path = ast::SourceFile::parse(&format!("type T = {link};"))
|
let mut parts = link.split("::");
|
||||||
.syntax_node()
|
let mut first_segment = None;
|
||||||
.descendants()
|
let kind = match parts.next()? {
|
||||||
.find_map(ast::Path::cast)?;
|
"" => PathKind::Abs,
|
||||||
if ast_path.syntax().text() != link {
|
"crate" => PathKind::Crate,
|
||||||
return None;
|
"self" => PathKind::Super(0),
|
||||||
}
|
"super" => {
|
||||||
ModPath::from_src(
|
let mut deg = 1;
|
||||||
db.upcast(),
|
while let Some(segment) = parts.next() {
|
||||||
ast_path,
|
if segment == "super" {
|
||||||
SpanMapRef::RealSpanMap(&RealSpanMap::absolute(FileId::BOGUS)),
|
deg += 1;
|
||||||
)
|
} else {
|
||||||
|
first_segment = Some(segment);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PathKind::Super(deg)
|
||||||
|
}
|
||||||
|
segment => {
|
||||||
|
first_segment = Some(segment);
|
||||||
|
PathKind::Plain
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let parts = first_segment.into_iter().chain(parts).map(|segment| match segment.parse() {
|
||||||
|
Ok(idx) => Name::new_tuple_field(idx),
|
||||||
|
Err(_) => Name::new_text_dont_use(segment.into()),
|
||||||
|
});
|
||||||
|
Some(ModPath::from_segments(kind, parts))
|
||||||
};
|
};
|
||||||
|
try_get_modpath(link)
|
||||||
let full = try_get_modpath(link);
|
|
||||||
if full.is_some() {
|
|
||||||
return full;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tuple field names cannot be a part of `ModPath` usually, but rustdoc can
|
|
||||||
// resolve doc paths like `TupleStruct::0`.
|
|
||||||
// FIXME: Find a better way to handle these.
|
|
||||||
let (base, maybe_tuple_field) = link.rsplit_once("::")?;
|
|
||||||
let tuple_field = Name::new_tuple_field(maybe_tuple_field.parse().ok()?);
|
|
||||||
let mut modpath = try_get_modpath(base)?;
|
|
||||||
modpath.push_segment(tuple_field);
|
|
||||||
Some(modpath)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,7 +206,7 @@ impl server::TokenStream for TokenIdServer {
|
||||||
stream: if subtree.token_trees.is_empty() {
|
stream: if subtree.token_trees.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(subtree.token_trees)
|
Some(TokenStream { token_trees: subtree.token_trees })
|
||||||
},
|
},
|
||||||
span: bridge::DelimSpan::from_single(subtree.delimiter.open),
|
span: bridge::DelimSpan::from_single(subtree.delimiter.open),
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
|
|
||||||
use salsa::InternId;
|
use salsa::InternId;
|
||||||
use stdx::assert_eq_size;
|
|
||||||
|
|
||||||
mod map;
|
mod map;
|
||||||
|
|
||||||
|
@ -36,7 +35,6 @@ pub const FIXUP_ERASED_FILE_AST_ID_MARKER: ErasedFileAstId =
|
||||||
la_arena::Idx::from_raw(la_arena::RawIdx::from_u32(!0 - 1));
|
la_arena::Idx::from_raw(la_arena::RawIdx::from_u32(!0 - 1));
|
||||||
|
|
||||||
pub type Span = SpanData<SyntaxContextId>;
|
pub type Span = SpanData<SyntaxContextId>;
|
||||||
assert_eq_size!(Span, 20);
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||||
pub struct SpanData<Ctx> {
|
pub struct SpanData<Ctx> {
|
||||||
|
|
|
@ -59,12 +59,3 @@ macro_rules! impl_from {
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! assert_eq_size {
|
|
||||||
($($ty:ty,)+ $val:expr $(,)?) => {
|
|
||||||
const _: () = {
|
|
||||||
$(core::mem::transmute::<[u8; $val], $ty>;)+
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue