feat: provide parameter docs in hover tips (#702)

* feat: supports parameter docs

* dev: update snapshot
This commit is contained in:
Myriad-Dreamin 2024-10-17 19:21:33 +08:00 committed by GitHub
parent e57cf36f9b
commit d9d10df7a4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 190 additions and 95 deletions

View file

@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize};
use tinymist_world::base::{EntryState, ShadowApi, TaskInputs};
use tinymist_world::LspWorld;
use typst::foundations::{Bytes, Func, Value};
use typst::syntax::LinkedNode;
use typst::{
diag::StrResult,
syntax::{FileId, VirtualPath},
@ -16,7 +17,7 @@ use typst::{
use super::tidy::*;
use crate::analysis::{ParamAttrs, ParamSpec};
use crate::docs::library;
use crate::ty::Interned;
use crate::ty::{DocSource, Interned};
use crate::upstream::plain_docs_sentence;
use crate::{ty::Ty, AnalysisContext};
@ -69,7 +70,7 @@ pub enum SymbolDocsT<T> {
Function(Box<SignatureDocsT<T>>),
/// Documentation about a variable.
#[serde(rename = "var")]
Variable(TidyVarDocsT<T>),
Variable(VarDocsT<T>),
/// Documentation about a module.
#[serde(rename = "module")]
Module(TidyModuleDocs),
@ -306,6 +307,42 @@ fn format_ty(ty: Option<&Ty>, doc_ty: Option<&mut ShowTypeRepr>) -> TypeRepr {
}
}
pub(crate) fn variable_docs(ctx: &mut AnalysisContext, pos: &LinkedNode) -> Option<VarDocs> {
let source = ctx.source_by_id(pos.span().id()?).ok()?;
let type_info = ctx.type_check(&source)?;
let ty = type_info.type_of_span(pos.span())?;
// todo multiple sources
let mut srcs = ty.sources();
srcs.sort();
log::info!("check variable docs of ty: {ty:?} => {srcs:?}");
let doc_source = srcs.into_iter().next()?;
let return_ty = ty.describe().map(|short| (short, format!("{ty:?}")));
match doc_source {
DocSource::Var(var) => {
let docs = type_info
.var_docs
.get(&var.def)
.map(|docs| docs.docs().clone());
Some(VarDocs {
docs: docs.unwrap_or_default(),
return_ty,
def_docs: OnceLock::new(),
})
}
DocSource::Ins(ins) => ins.syntax.as_ref().map(|src| {
let docs = src.doc.as_ref().into();
VarDocs {
docs,
return_ty,
def_docs: OnceLock::new(),
}
}),
_ => None,
}
}
pub(crate) fn signature_docs(
ctx: &mut AnalysisContext,
runtime_fn: &Value,

View file

@ -1,8 +1,12 @@
use std::sync::OnceLock;
use ecow::EcoString;
use itertools::Itertools;
use serde::{Deserialize, Serialize};
use typst::diag::StrResult;
use crate::upstream::plain_docs_sentence;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TidyParamDocs {
pub name: EcoString,
@ -19,14 +23,23 @@ pub struct TidyFuncDocs {
}
/// Documentation about a variable (without type information).
pub type UntypedVarDocs = TidyVarDocsT<()>;
pub type UntypedVarDocs = VarDocsT<()>;
/// Documentation about a variable.
pub type TidyVarDocs = TidyVarDocsT<Option<(String, String)>>;
pub type VarDocs = VarDocsT<Option<(String, String)>>;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TidyVarDocsT<T> {
pub struct VarDocsT<T> {
pub docs: EcoString,
pub return_ty: T,
#[serde(skip)]
pub def_docs: OnceLock<String>,
}
impl VarDocs {
pub fn def_docs(&self) -> &String {
self.def_docs
.get_or_init(|| plain_docs_sentence(&self.docs).into())
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@ -146,7 +159,7 @@ pub fn identify_func_docs(converted: &str) -> StrResult<TidyFuncDocs> {
})
}
pub fn identify_var_docs(converted: EcoString) -> StrResult<TidyVarDocs> {
pub fn identify_var_docs(converted: EcoString) -> StrResult<VarDocs> {
let lines = converted.lines().collect::<Vec<_>>();
let mut return_ty = None;
@ -180,7 +193,11 @@ pub fn identify_var_docs(converted: EcoString) -> StrResult<TidyVarDocs> {
None => converted,
};
Ok(TidyVarDocs { docs, return_ty })
Ok(VarDocs {
docs,
return_ty,
def_docs: OnceLock::new(),
})
}
pub fn identify_tidy_module_docs(docs: EcoString) -> StrResult<TidyModuleDocs> {