⬆️ rust-analyzer

This commit is contained in:
Laurențiu Nicola 2023-02-13 13:55:14 +02:00
parent 3e0e51c108
commit bc45c7659a
321 changed files with 11210 additions and 9720 deletions

View file

@ -26,58 +26,24 @@ use syntax::{
use crate::{
doc_links::{remove_links, rewrite_links},
hover::walk_and_push_ty,
markdown_remove::remove_markdown,
HoverAction, HoverConfig, HoverResult, Markup,
};
pub(super) fn type_info(
pub(super) fn type_info_of(
sema: &Semantics<'_, RootDatabase>,
config: &HoverConfig,
_config: &HoverConfig,
expr_or_pat: &Either<ast::Expr, ast::Pat>,
) -> Option<HoverResult> {
let TypeInfo { original, adjusted } = match expr_or_pat {
Either::Left(expr) => sema.type_of_expr(expr)?,
Either::Right(pat) => sema.type_of_pat(pat)?,
};
let mut res = HoverResult::default();
let mut targets: Vec<hir::ModuleDef> = Vec::new();
let mut push_new_def = |item: hir::ModuleDef| {
if !targets.contains(&item) {
targets.push(item);
}
};
walk_and_push_ty(sema.db, &original, &mut push_new_def);
res.markup = if let Some(adjusted_ty) = adjusted {
walk_and_push_ty(sema.db, &adjusted_ty, &mut push_new_def);
let original = original.display(sema.db).to_string();
let adjusted = adjusted_ty.display(sema.db).to_string();
let static_text_diff_len = "Coerced to: ".len() - "Type: ".len();
format!(
"{bt_start}Type: {:>apad$}\nCoerced to: {:>opad$}\n{bt_end}",
original,
adjusted,
apad = static_text_diff_len + adjusted.len().max(original.len()),
opad = original.len(),
bt_start = if config.markdown() { "```text\n" } else { "" },
bt_end = if config.markdown() { "```\n" } else { "" }
)
.into()
} else {
if config.markdown() {
Markup::fenced_block(&original.display(sema.db))
} else {
original.display(sema.db).to_string().into()
}
};
res.actions.push(HoverAction::goto_type_from_targets(sema.db, targets));
Some(res)
type_info(sema, _config, original, adjusted)
}
pub(super) fn try_expr(
sema: &Semantics<'_, RootDatabase>,
config: &HoverConfig,
_config: &HoverConfig,
try_expr: &ast::TryExpr,
) -> Option<HoverResult> {
let inner_ty = sema.type_of_expr(&try_expr.expr()?)?.original;
@ -153,14 +119,12 @@ pub(super) fn try_expr(
let ppad = static_text_len_diff.min(0).abs() as usize;
res.markup = format!(
"{bt_start}{} Type: {:>pad0$}\nPropagated as: {:>pad1$}\n{bt_end}",
"```text\n{} Type: {:>pad0$}\nPropagated as: {:>pad1$}\n```\n",
s,
inner_ty,
body_ty,
pad0 = ty_len_max + tpad,
pad1 = ty_len_max + ppad,
bt_start = if config.markdown() { "```text\n" } else { "" },
bt_end = if config.markdown() { "```\n" } else { "" }
)
.into();
Some(res)
@ -168,7 +132,7 @@ pub(super) fn try_expr(
pub(super) fn deref_expr(
sema: &Semantics<'_, RootDatabase>,
config: &HoverConfig,
_config: &HoverConfig,
deref_expr: &ast::PrefixExpr,
) -> Option<HoverResult> {
let inner_ty = sema.type_of_expr(&deref_expr.expr()?)?.original;
@ -197,15 +161,13 @@ pub(super) fn deref_expr(
.max(adjusted.len() + coerced_len)
.max(inner.len() + deref_len);
format!(
"{bt_start}Dereferenced from: {:>ipad$}\nTo type: {:>apad$}\nCoerced to: {:>opad$}\n{bt_end}",
"```text\nDereferenced from: {:>ipad$}\nTo type: {:>apad$}\nCoerced to: {:>opad$}\n```\n",
inner,
original,
adjusted,
ipad = max_len - deref_len,
apad = max_len - type_len,
opad = max_len - coerced_len,
bt_start = if config.markdown() { "```text\n" } else { "" },
bt_end = if config.markdown() { "```\n" } else { "" }
)
.into()
} else {
@ -215,13 +177,11 @@ pub(super) fn deref_expr(
let deref_len = "Dereferenced from: ".len();
let max_len = (original.len() + type_len).max(inner.len() + deref_len);
format!(
"{bt_start}Dereferenced from: {:>ipad$}\nTo type: {:>apad$}\n{bt_end}",
"```text\nDereferenced from: {:>ipad$}\nTo type: {:>apad$}\n```\n",
inner,
original,
ipad = max_len - deref_len,
apad = max_len - type_len,
bt_start = if config.markdown() { "```text\n" } else { "" },
bt_end = if config.markdown() { "```\n" } else { "" }
)
.into()
};
@ -230,12 +190,54 @@ pub(super) fn deref_expr(
Some(res)
}
pub(super) fn underscore(
sema: &Semantics<'_, RootDatabase>,
config: &HoverConfig,
token: &SyntaxToken,
) -> Option<HoverResult> {
if token.kind() != T![_] {
return None;
}
let parent = token.parent()?;
let _it = match_ast! {
match parent {
ast::InferType(it) => it,
ast::UnderscoreExpr(it) => return type_info_of(sema, config, &Either::Left(ast::Expr::UnderscoreExpr(it))),
ast::WildcardPat(it) => return type_info_of(sema, config, &Either::Right(ast::Pat::WildcardPat(it))),
_ => return None,
}
};
// let it = infer_type.syntax().parent()?;
// match_ast! {
// match it {
// ast::LetStmt(_it) => (),
// ast::Param(_it) => (),
// ast::RetType(_it) => (),
// ast::TypeArg(_it) => (),
// ast::CastExpr(_it) => (),
// ast::ParenType(_it) => (),
// ast::TupleType(_it) => (),
// ast::PtrType(_it) => (),
// ast::RefType(_it) => (),
// ast::ArrayType(_it) => (),
// ast::SliceType(_it) => (),
// ast::ForType(_it) => (),
// _ => return None,
// }
// }
// FIXME: https://github.com/rust-lang/rust-analyzer/issues/11762, this currently always returns Unknown
// type_info(sema, config, sema.resolve_type(&ast::Type::InferType(it))?, None)
None
}
pub(super) fn keyword(
sema: &Semantics<'_, RootDatabase>,
config: &HoverConfig,
token: &SyntaxToken,
) -> Option<HoverResult> {
if !token.kind().is_keyword() || !config.documentation.is_some() || !config.keywords {
if !token.kind().is_keyword() || !config.documentation || !config.keywords {
return None;
}
let parent = token.parent()?;
@ -259,7 +261,7 @@ pub(super) fn keyword(
/// i.e. `let S {a, ..} = S {a: 1, b: 2}`
pub(super) fn struct_rest_pat(
sema: &Semantics<'_, RootDatabase>,
config: &HoverConfig,
_config: &HoverConfig,
pattern: &RecordPat,
) -> HoverResult {
let missing_fields = sema.record_pattern_missing_fields(pattern);
@ -288,11 +290,7 @@ pub(super) fn struct_rest_pat(
// get rid of trailing comma
s.truncate(s.len() - 2);
if config.markdown() {
Markup::fenced_block(&s)
} else {
s.into()
}
Markup::fenced_block(&s)
};
res.actions.push(HoverAction::goto_type_from_targets(sema.db, targets));
res
@ -346,13 +344,8 @@ pub(super) fn process_markup(
config: &HoverConfig,
) -> Markup {
let markup = markup.as_str();
let markup = if !config.markdown() {
remove_markdown(markup)
} else if config.links_in_hover {
rewrite_links(db, markup, def)
} else {
remove_links(markup)
};
let markup =
if config.links_in_hover { rewrite_links(db, markup, def) } else { remove_links(markup) };
Markup::from(markup)
}
@ -465,8 +458,9 @@ pub(super) fn definition(
Definition::DeriveHelper(it) => (format!("derive_helper {}", it.name(db)), None),
};
let docs = match config.documentation {
Some(_) => docs.or_else(|| {
let docs = docs
.filter(|_| config.documentation)
.or_else(|| {
// docs are missing, for assoc items of trait impls try to fall back to the docs of the
// original item of the trait
let assoc = def.as_assoc_item(db)?;
@ -474,13 +468,46 @@ pub(super) fn definition(
let name = Some(assoc.name(db)?);
let item = trait_.items(db).into_iter().find(|it| it.name(db) == name)?;
item.docs(db)
}),
None => None,
};
let docs = docs.filter(|_| config.documentation.is_some()).map(Into::into);
})
.map(Into::into);
markup(docs, label, mod_path)
}
fn type_info(
sema: &Semantics<'_, RootDatabase>,
_config: &HoverConfig,
original: hir::Type,
adjusted: Option<hir::Type>,
) -> Option<HoverResult> {
let mut res = HoverResult::default();
let mut targets: Vec<hir::ModuleDef> = Vec::new();
let mut push_new_def = |item: hir::ModuleDef| {
if !targets.contains(&item) {
targets.push(item);
}
};
walk_and_push_ty(sema.db, &original, &mut push_new_def);
res.markup = if let Some(adjusted_ty) = adjusted {
walk_and_push_ty(sema.db, &adjusted_ty, &mut push_new_def);
let original = original.display(sema.db).to_string();
let adjusted = adjusted_ty.display(sema.db).to_string();
let static_text_diff_len = "Coerced to: ".len() - "Type: ".len();
format!(
"```text\nType: {:>apad$}\nCoerced to: {:>opad$}\n```\n",
original,
adjusted,
apad = static_text_diff_len + adjusted.len().max(original.len()),
opad = original.len(),
)
.into()
} else {
Markup::fenced_block(&original.display(sema.db))
};
res.actions.push(HoverAction::goto_type_from_targets(sema.db, targets));
Some(res)
}
fn render_builtin_attr(db: &RootDatabase, attr: hir::BuiltinAttr) -> Option<Markup> {
let name = attr.name(db);
let desc = format!("#[{name}]");