mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-11-23 12:46:43 +00:00
feat: merge func and variable docs parser (#812)
* feat: merge func and variable docs parser * test: update snapshot
This commit is contained in:
parent
7ab125bbc2
commit
c128f633d4
12 changed files with 80 additions and 141 deletions
|
|
@ -13,8 +13,11 @@ use crate::ty::Ty;
|
|||
use crate::ty::{DocSource, Interned};
|
||||
use crate::upstream::plain_docs_sentence;
|
||||
|
||||
type TypeRepr = Option<(/* short */ String, /* long */ String)>;
|
||||
type ShowTypeRepr<'a> = &'a mut dyn FnMut(Option<&Ty>) -> TypeRepr;
|
||||
type TypeRepr = Option<(
|
||||
/* short */ String,
|
||||
/* long */ String,
|
||||
/* value */ String,
|
||||
)>;
|
||||
|
||||
/// Documentation about a definition (without type information).
|
||||
pub type UntypedDefDocs = DefDocsT<()>;
|
||||
|
|
@ -86,13 +89,13 @@ impl SignatureDocsT<TypeRepr> {
|
|||
/// Get full documentation for the signature.
|
||||
pub fn hover_docs(&self) -> &EcoString {
|
||||
self.hover_docs
|
||||
.get_or_init(|| plain_docs_sentence(&format!("{}", SigDefDocs(self))))
|
||||
.get_or_init(|| plain_docs_sentence(&format!("{}", SigHoverDocs(self))))
|
||||
}
|
||||
}
|
||||
|
||||
struct SigDefDocs<'a>(&'a SignatureDocs);
|
||||
struct SigHoverDocs<'a>(&'a SignatureDocs);
|
||||
|
||||
impl fmt::Display for SigDefDocs<'_> {
|
||||
impl fmt::Display for SigHoverDocs<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let docs = self.0;
|
||||
let base_docs = docs.docs.trim();
|
||||
|
|
@ -213,6 +216,31 @@ impl SignatureDocs {
|
|||
}
|
||||
}
|
||||
|
||||
/// Documentation about a variable (without type information).
|
||||
pub type UntypedVarDocs = VarDocsT<()>;
|
||||
/// Documentation about a variable.
|
||||
pub type VarDocs = VarDocsT<Option<(String, String, String)>>;
|
||||
|
||||
/// Describes a primary pattern binding.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct VarDocsT<T> {
|
||||
/// Documentation for the pattern binding.
|
||||
pub docs: EcoString,
|
||||
/// The inferred type of the pattern binding source.
|
||||
pub return_ty: T,
|
||||
/// Cached documentation for the definition.
|
||||
#[serde(skip)]
|
||||
pub def_docs: OnceLock<String>,
|
||||
}
|
||||
|
||||
impl VarDocs {
|
||||
/// Get the markdown representation of the documentation.
|
||||
pub fn def_docs(&self) -> &String {
|
||||
self.def_docs
|
||||
.get_or_init(|| plain_docs_sentence(&self.docs).into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Documentation about a parameter (without type information).
|
||||
pub type TypelessParamDocs = ParamDocsT<()>;
|
||||
/// Documentation about a parameter.
|
||||
|
|
@ -235,24 +263,24 @@ pub struct ParamDocsT<T> {
|
|||
}
|
||||
|
||||
impl ParamDocs {
|
||||
fn new(param: &ParamSpec, ty: Option<&Ty>, doc_ty: Option<&mut ShowTypeRepr>) -> Self {
|
||||
fn new(param: &ParamSpec, ty: Option<&Ty>) -> Self {
|
||||
Self {
|
||||
name: param.name.as_ref().into(),
|
||||
docs: param.docs.clone().unwrap_or_default(),
|
||||
cano_type: format_ty(ty.or(Some(¶m.ty)), doc_ty),
|
||||
cano_type: format_ty(ty.or(Some(¶m.ty))),
|
||||
default: param.default.clone(),
|
||||
attrs: param.attrs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn format_ty(ty: Option<&Ty>, doc_ty: Option<&mut ShowTypeRepr>) -> TypeRepr {
|
||||
match doc_ty {
|
||||
Some(doc_ty) => doc_ty(ty),
|
||||
None => ty
|
||||
.and_then(|ty| ty.repr())
|
||||
.map(|short| (short, format!("{ty:?}"))),
|
||||
}
|
||||
fn format_ty(ty: Option<&Ty>) -> TypeRepr {
|
||||
let ty = ty?;
|
||||
let short = ty.repr().unwrap_or_else(|| "any".to_owned());
|
||||
let long = format!("{ty:?}");
|
||||
let value = ty.value_repr().unwrap_or_else(|| "".to_owned());
|
||||
|
||||
Some((short, long, value))
|
||||
}
|
||||
|
||||
pub(crate) fn var_docs(ctx: &mut LocalContext, pos: Span) -> Option<VarDocs> {
|
||||
|
|
@ -266,7 +294,7 @@ pub(crate) fn var_docs(ctx: &mut LocalContext, pos: Span) -> Option<VarDocs> {
|
|||
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:?}")));
|
||||
let return_ty = format_ty(Some(&ty));
|
||||
match doc_source {
|
||||
DocSource::Var(var) => {
|
||||
let docs = type_info
|
||||
|
|
@ -291,7 +319,7 @@ pub(crate) fn var_docs(ctx: &mut LocalContext, pos: Span) -> Option<VarDocs> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn sig_docs(sig: &Signature, mut doc_ty: Option<ShowTypeRepr>) -> Option<SignatureDocs> {
|
||||
pub(crate) fn sig_docs(sig: &Signature) -> Option<SignatureDocs> {
|
||||
let type_sig = sig.type_sig().clone();
|
||||
|
||||
let pos_in = sig
|
||||
|
|
@ -310,19 +338,14 @@ pub(crate) fn sig_docs(sig: &Signature, mut doc_ty: Option<ShowTypeRepr>) -> Opt
|
|||
let ret_in = type_sig.body.as_ref();
|
||||
|
||||
let pos = pos_in
|
||||
.map(|(param, ty)| ParamDocs::new(param, ty, doc_ty.as_mut()))
|
||||
.map(|(param, ty)| ParamDocs::new(param, ty))
|
||||
.collect();
|
||||
let named = named_in
|
||||
.map(|(param, ty)| {
|
||||
(
|
||||
param.name.clone(),
|
||||
ParamDocs::new(param, ty, doc_ty.as_mut()),
|
||||
)
|
||||
})
|
||||
.map(|(param, ty)| (param.name.clone(), ParamDocs::new(param, ty)))
|
||||
.collect();
|
||||
let rest = rest_in.map(|(param, ty)| ParamDocs::new(param, ty, doc_ty.as_mut()));
|
||||
let rest = rest_in.map(|(param, ty)| ParamDocs::new(param, ty));
|
||||
|
||||
let ret_ty = format_ty(ret_in, doc_ty.as_mut());
|
||||
let ret_ty = format_ty(ret_in);
|
||||
|
||||
Some(SignatureDocs {
|
||||
docs: sig.primary().docs.clone().unwrap_or_default(),
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ pub fn package_docs(ctx: &mut LocalContext, spec: &PackageInfo) -> StrResult<Str
|
|||
{
|
||||
let _ = writeln!(md, "<!-- begin:param {} -->", param.name);
|
||||
let ty = match ¶m.cano_type {
|
||||
Some((short, _)) => short,
|
||||
Some((short, _, _)) => short,
|
||||
None => "unknown",
|
||||
};
|
||||
let _ = writeln!(
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
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,
|
||||
|
|
@ -16,38 +12,18 @@ pub struct TidyParamDocs {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct TidyFuncDocs {
|
||||
pub struct TidyPatDocs {
|
||||
pub docs: EcoString,
|
||||
pub return_ty: Option<EcoString>,
|
||||
pub params: Vec<TidyParamDocs>,
|
||||
}
|
||||
|
||||
/// Documentation about a variable (without type information).
|
||||
pub type UntypedVarDocs = VarDocsT<()>;
|
||||
/// Documentation about a variable.
|
||||
pub type VarDocs = VarDocsT<Option<(String, String)>>;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
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)]
|
||||
pub struct TidyModuleDocs {
|
||||
pub docs: EcoString,
|
||||
}
|
||||
|
||||
pub fn identify_func_docs(converted: &str) -> StrResult<TidyFuncDocs> {
|
||||
pub fn identify_pat_docs(converted: &str) -> StrResult<TidyPatDocs> {
|
||||
let lines = converted.lines().collect::<Vec<_>>();
|
||||
|
||||
let mut matching_return_ty = true;
|
||||
|
|
@ -153,54 +129,13 @@ pub fn identify_func_docs(converted: &str) -> StrResult<TidyFuncDocs> {
|
|||
};
|
||||
|
||||
params.reverse();
|
||||
Ok(TidyFuncDocs {
|
||||
Ok(TidyPatDocs {
|
||||
docs,
|
||||
return_ty,
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn identify_var_docs(converted: EcoString) -> StrResult<VarDocs> {
|
||||
let lines = converted.lines().collect::<Vec<_>>();
|
||||
|
||||
let mut return_ty = None;
|
||||
let mut break_line = None;
|
||||
|
||||
let mut i = lines.len();
|
||||
loop {
|
||||
if i == 0 {
|
||||
break;
|
||||
}
|
||||
i -= 1;
|
||||
|
||||
let line = lines[i];
|
||||
if line.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Some(w) = line.trim_start().strip_prefix("->") else {
|
||||
break_line = Some(i + 1);
|
||||
break;
|
||||
};
|
||||
|
||||
// todo: convert me
|
||||
return_ty = Some((w.trim().into(), String::new()));
|
||||
break_line = Some(i);
|
||||
break;
|
||||
}
|
||||
|
||||
let docs = match break_line {
|
||||
Some(line_no) => (lines[..line_no]).iter().copied().join("\n").into(),
|
||||
None => converted,
|
||||
};
|
||||
|
||||
Ok(VarDocs {
|
||||
docs,
|
||||
return_ty,
|
||||
def_docs: OnceLock::new(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn identify_tidy_module_docs(docs: EcoString) -> StrResult<TidyModuleDocs> {
|
||||
Ok(TidyModuleDocs { docs })
|
||||
}
|
||||
|
|
@ -236,7 +171,7 @@ mod tests {
|
|||
use super::TidyParamDocs;
|
||||
|
||||
fn func(s: &str) -> String {
|
||||
let f = super::identify_func_docs(s).unwrap();
|
||||
let f = super::identify_pat_docs(s).unwrap();
|
||||
let mut res = format!(">> docs:\n{}\n<< docs", f.docs);
|
||||
if let Some(t) = f.return_ty {
|
||||
res.push_str(&format!("\n>>return\n{t}\n<<return"));
|
||||
|
|
@ -254,10 +189,10 @@ mod tests {
|
|||
}
|
||||
|
||||
fn var(s: &str) -> String {
|
||||
let f = super::identify_var_docs(s.into()).unwrap();
|
||||
let f = super::identify_pat_docs(s).unwrap();
|
||||
let mut res = format!(">> docs:\n{}\n<< docs", f.docs);
|
||||
if let Some(t) = f.return_ty {
|
||||
res.push_str(&format!("\n>>return\n{}\n<<return", t.0));
|
||||
res.push_str(&format!("\n>>return\n{t}\n<<return"));
|
||||
}
|
||||
res
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue