mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-07-19 18:55:01 +00:00
feat: improve style of hover param docs (#813)
* feat: improve style of hover param docs * feat: give value example in parameter docs
This commit is contained in:
parent
c128f633d4
commit
808da99092
13 changed files with 103 additions and 81 deletions
|
@ -388,7 +388,7 @@ mod type_describe_tests {
|
|||
description => format!("Check on {text:?} ({pos:?})"),
|
||||
}, {
|
||||
let literal_type = literal_type.and_then(|e| e.describe())
|
||||
.unwrap_or_else(|| "<nil>".to_string());
|
||||
.unwrap_or_else(|| "<nil>".into());
|
||||
assert_snapshot!(literal_type);
|
||||
})
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@ use core::fmt;
|
|||
use std::collections::BTreeMap;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use ecow::EcoString;
|
||||
use ecow::{eco_format, EcoString};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use typst::syntax::Span;
|
||||
|
||||
|
@ -14,9 +14,9 @@ use crate::ty::{DocSource, Interned};
|
|||
use crate::upstream::plain_docs_sentence;
|
||||
|
||||
type TypeRepr = Option<(
|
||||
/* short */ String,
|
||||
/* long */ String,
|
||||
/* value */ String,
|
||||
/* short */ EcoString,
|
||||
/* long */ EcoString,
|
||||
/* value */ EcoString,
|
||||
)>;
|
||||
|
||||
/// Documentation about a definition (without type information).
|
||||
|
@ -100,41 +100,57 @@ impl fmt::Display for SigHoverDocs<'_> {
|
|||
let docs = self.0;
|
||||
let base_docs = docs.docs.trim();
|
||||
|
||||
let has_params_docs = !docs.pos.is_empty() || !docs.named.is_empty() || docs.rest.is_some();
|
||||
|
||||
if !base_docs.is_empty() {
|
||||
f.write_str(base_docs)?;
|
||||
}
|
||||
|
||||
if has_params_docs {
|
||||
f.write_str("\n\n")?;
|
||||
fn write_param_docs(
|
||||
f: &mut fmt::Formatter<'_>,
|
||||
p: &ParamDocsT<TypeRepr>,
|
||||
kind: &str,
|
||||
is_first: &mut bool,
|
||||
) -> fmt::Result {
|
||||
if *is_first {
|
||||
*is_first = false;
|
||||
write!(f, "\n\n## {}\n\n", p.name)?;
|
||||
} else {
|
||||
write!(f, "\n\n## {} ({kind})\n\n", p.name)?;
|
||||
}
|
||||
|
||||
// p.cano_type.0
|
||||
if let Some(t) = &p.cano_type {
|
||||
write!(f, "```typc\ntype: {}\n```\n\n", t.2)?;
|
||||
}
|
||||
|
||||
f.write_str(p.docs.trim())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
if !docs.pos.is_empty() {
|
||||
f.write_str("\n\n# Positional Parameters")?;
|
||||
|
||||
let mut is_first = true;
|
||||
for p in &docs.pos {
|
||||
write_param_docs(f, p, "positional", &mut is_first)?;
|
||||
}
|
||||
}
|
||||
|
||||
if has_params_docs {
|
||||
f.write_str("## Parameters")?;
|
||||
|
||||
for p in &docs.pos {
|
||||
write!(f, "\n\n@positional `{}`", p.name)?;
|
||||
if !p.docs.is_empty() {
|
||||
f.write_str(" — ")?;
|
||||
f.write_str(&p.docs)?;
|
||||
}
|
||||
}
|
||||
|
||||
for (name, p) in &docs.named {
|
||||
write!(f, "\n\n@named `{name}`")?;
|
||||
if !p.docs.is_empty() {
|
||||
f.write_str(" — ")?;
|
||||
f.write_str(&p.docs)?;
|
||||
}
|
||||
}
|
||||
if docs.rest.is_some() {
|
||||
f.write_str("\n\n# Rest Parameters")?;
|
||||
|
||||
let mut is_first = true;
|
||||
if let Some(rest) = &docs.rest {
|
||||
write!(f, "\n\n@rest `{}`", rest.name)?;
|
||||
if !rest.docs.is_empty() {
|
||||
f.write_str(" — ")?;
|
||||
f.write_str(&rest.docs)?;
|
||||
}
|
||||
write_param_docs(f, rest, "spread right", &mut is_first)?;
|
||||
}
|
||||
}
|
||||
|
||||
if !docs.named.is_empty() {
|
||||
f.write_str("\n\n# Named Parameters")?;
|
||||
|
||||
let mut is_first = true;
|
||||
for p in docs.named.values() {
|
||||
write_param_docs(f, p, "named", &mut is_first)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,7 +235,7 @@ 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)>>;
|
||||
pub type VarDocs = VarDocsT<Option<(EcoString, EcoString, EcoString)>>;
|
||||
|
||||
/// Describes a primary pattern binding.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
|
@ -276,9 +292,9 @@ impl ParamDocs {
|
|||
|
||||
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());
|
||||
let short = ty.repr().unwrap_or_else(|| "any".into());
|
||||
let long = eco_format!("{ty:?}");
|
||||
let value = ty.value_repr().unwrap_or_else(|| "".into());
|
||||
|
||||
Some((short, long, value))
|
||||
}
|
||||
|
|
|
@ -4,6 +4,6 @@ expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
|||
input_file: crates/tinymist-query/src/fixtures/hover/annotate_docs_error.typ
|
||||
---
|
||||
{
|
||||
"contents": "```typc\nlet speaker-note(\n note: any,\n mode: str = \"typ\",\n setting: (any) => any = Closure(..),\n) = none;\n```\n\n---\nSpeaker notes are a way to add additional information to your slides that is not visible to the audience. This can be useful for providing additional context or reminders to yourself.\n\n ## Example\n\n ```typ\n#speaker-note[This is a speaker note]\n\n```\n```\nRender Error\ncompiling node: error: unknown variable: speaker-note at \"/__render__.typ\":201..213\nHint: if you meant to use subtraction, try adding spaces around the minus sign: \\`speaker - note\\`\n\n```\n\n## Parameters\n\n@positional `note`\n\n@named `mode`\n\n@named `setting`",
|
||||
"contents": "```typc\nlet speaker-note(\n note: any,\n mode: str = \"typ\",\n setting: (any) => any = Closure(..),\n) = none;\n```\n\n---\nSpeaker notes are a way to add additional information to your slides that is not visible to the audience. This can be useful for providing additional context or reminders to yourself.\n\n ## Example\n\n ```typ\n#speaker-note[This is a speaker note]\n\n```\n```\nRender Error\ncompiling node: error: unknown variable: speaker-note at \"/__render__.typ\":201..213\nHint: if you meant to use subtraction, try adding spaces around the minus sign: \\`speaker - note\\`\n\n```\n\n# Positional Parameters\n\n## note\n\n```typc\ntype: \n```\n\n\n\n# Named Parameters\n\n## mode\n\n```typc\ntype: \"typ\"\n```\n\n\n\n## setting (named)\n\n```typc\ntype: (any) => any\n```\n\n",
|
||||
"range": "11:20:11:32"
|
||||
}
|
||||
|
|
|
@ -4,6 +4,6 @@ expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
|||
input_file: crates/tinymist-query/src/fixtures/hover/annotate_fn.typ
|
||||
---
|
||||
{
|
||||
"contents": "```typc\nlet touying-fn-wrapper(\n fn: (..: any) => any | function,\n ..args: arguments,\n max-repetitions: int | none = none,\n repetitions: int | none = none,\n) = none;\n```\n\n---\n## Parameters\n\n@positional `fn` — The `fn`.\n\n@named `max-repetitions` — The `max-repetitions`.\n\n@named `repetitions` — The `repetitions`.\n\n@rest `args` — The `args`.",
|
||||
"contents": "```typc\nlet touying-fn-wrapper(\n fn: (..: any) => any | function,\n ..args: arguments,\n max-repetitions: int | none = none,\n repetitions: int | none = none,\n) = none;\n```\n\n---\n\n\n# Positional Parameters\n\n## fn\n\n```typc\ntype: (..: any) => any | function\n```\n\nThe `fn`.\n\n# Rest Parameters\n\n## args\n\n```typc\ntype: arguments\n```\n\nThe `args`.\n\n# Named Parameters\n\n## max-repetitions\n\n```typc\ntype: int | none\n```\n\nThe `max-repetitions`.\n\n## repetitions (named)\n\n```typc\ntype: int | none\n```\n\nThe `repetitions`.",
|
||||
"range": "8:20:8:38"
|
||||
}
|
||||
|
|
|
@ -4,6 +4,6 @@ expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
|||
input_file: crates/tinymist-query/src/fixtures/hover/annotate_ret.typ
|
||||
---
|
||||
{
|
||||
"contents": "```typc\nlet _delayed-wrapper(\n body: any,\n) = content;\n```\n\n---\n## Parameters\n\n@positional `body`",
|
||||
"contents": "```typc\nlet _delayed-wrapper(\n body: any,\n) = content;\n```\n\n---\n\n\n# Positional Parameters\n\n## body\n\n```typc\ntype: \n```\n\n",
|
||||
"range": "6:20:6:36"
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -4,6 +4,6 @@ expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
|||
input_file: crates/tinymist-query/src/fixtures/hover/pagebreak.typ
|
||||
---
|
||||
{
|
||||
"contents": "```typc\nlet pagebreak(\n to: none | str = none,\n weak: bool = false,\n);\n```\n\n---\nA manual page break.\n\nMust not be used inside any containers.\n\n# Example\n```typ\nThe next page contains\nmore details on compound theory.\n#pagebreak()\n\n== Compound Theory\nIn 1984, the first ...\n```\n\n## Parameters\n\n@named `to` — If given, ensures that the next page will be an even/odd page, with an\nempty page in between if necessary.\n\n```typ\n#set page(height: 30pt)\n\nFirst.\n#pagebreak(to: \"odd\")\nThird.\n```\n\n@named `weak` — If `true`, the page break is skipped if the current page is already\nempty.\n\n---\n[Open docs](https://typst.app/docs/reference/layout/pagebreak/)",
|
||||
"contents": "```typc\nlet pagebreak(\n to: none | str = none,\n weak: bool = false,\n);\n```\n\n---\nA manual page break.\n\nMust not be used inside any containers.\n\n# Example\n```typ\nThe next page contains\nmore details on compound theory.\n#pagebreak()\n\n== Compound Theory\nIn 1984, the first ...\n```\n\n# Named Parameters\n\n## to\n\n```typc\ntype: \"even\" | \"odd\" | none\n```\n\nIf given, ensures that the next page will be an even/odd page, with an\nempty page in between if necessary.\n\n```typ\n#set page(height: 30pt)\n\nFirst.\n#pagebreak(to: \"odd\")\nThird.\n```\n\n## weak (named)\n\n```typc\ntype: bool\n```\n\nIf `true`, the page break is skipped if the current page is already\nempty.\n\n---\n[Open docs](https://typst.app/docs/reference/layout/pagebreak/)",
|
||||
"range": "0:20:0:29"
|
||||
}
|
||||
|
|
|
@ -4,6 +4,6 @@ expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
|||
input_file: crates/tinymist-query/src/fixtures/hover/value_repr.typ
|
||||
---
|
||||
{
|
||||
"contents": "```typc\nlet f(\n x: any,\n y: any,\n z: any,\n w01: int = 1,\n w02: str = \"test\",\n w03: any = 1 + 2,\n w04: any = Label(test),\n w05: function = box,\n w06: any = list.item,\n w07: content = Expr(..),\n w08: any = Expr(..),\n w09: any = 1 + 2,\n w10: array = (\n 1,\n 2,\n ),\n w11: array = (),\n w12: dict = (:),\n w13: dict = (a: 1),\n w14: dict = (a: box),\n w15: dict = (a: list.item),\n) = int;\n```\n\n---\n## Parameters\n\n@positional `x`\n\n@positional `y`\n\n@positional `z`\n\n@named `w01`\n\n@named `w02`\n\n@named `w03`\n\n@named `w04`\n\n@named `w05`\n\n@named `w06`\n\n@named `w07`\n\n@named `w08`\n\n@named `w09`\n\n@named `w10`\n\n@named `w11`\n\n@named `w12`\n\n@named `w13`\n\n@named `w14`\n\n@named `w15`",
|
||||
"contents": "```typc\nlet f(\n x: any,\n y: any,\n z: any,\n w01: int = 1,\n w02: str = \"test\",\n w03: any = 1 + 2,\n w04: any = Label(test),\n w05: function = box,\n w06: any = list.item,\n w07: content = Expr(..),\n w08: any = Expr(..),\n w09: any = 1 + 2,\n w10: array = (\n 1,\n 2,\n ),\n w11: array = (),\n w12: dict = (:),\n w13: dict = (a: 1),\n w14: dict = (a: box),\n w15: dict = (a: list.item),\n) = int;\n```\n\n---\n\n\n# Positional Parameters\n\n## x\n\n```typc\ntype: \n```\n\n\n\n## y (positional)\n\n```typc\ntype: \n```\n\n\n\n## z (positional)\n\n```typc\ntype: \n```\n\n\n\n# Named Parameters\n\n## w01\n\n```typc\ntype: 1\n```\n\n\n\n## w02 (named)\n\n```typc\ntype: \"test\"\n```\n\n\n\n## w03 (named)\n\n```typc\ntype: any\n```\n\n\n\n## w04 (named)\n\n```typc\ntype: \n```\n\n\n\n## w05 (named)\n\n```typc\ntype: box\n```\n\n\n\n## w06 (named)\n\n```typc\ntype: any\n```\n\n\n\n## w07 (named)\n\n```typc\ntype: content\n```\n\n\n\n## w08 (named)\n\n```typc\ntype: any\n```\n\n\n\n## w09 (named)\n\n```typc\ntype: any\n```\n\n\n\n## w10 (named)\n\n```typc\ntype: array\n```\n\n\n\n## w11 (named)\n\n```typc\ntype: array\n```\n\n\n\n## w12 (named)\n\n```typc\ntype: dict\n```\n\n\n\n## w13 (named)\n\n```typc\ntype: dict\n```\n\n\n\n## w14 (named)\n\n```typc\ntype: dict\n```\n\n\n\n## w15 (named)\n\n```typc\ntype: dict\n```\n\n",
|
||||
"range": "23:20:23:21"
|
||||
}
|
||||
|
|
|
@ -272,7 +272,11 @@ fn link_tooltip(
|
|||
Some(HoverContents::Array(results))
|
||||
}
|
||||
|
||||
fn push_result_ty(name: &str, ty_repr: Option<&(String, String, String)>, type_doc: &mut String) {
|
||||
fn push_result_ty(
|
||||
name: &str,
|
||||
ty_repr: Option<&(EcoString, EcoString, EcoString)>,
|
||||
type_doc: &mut String,
|
||||
) {
|
||||
let Some((short, _, _)) = ty_repr else {
|
||||
return;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use core::fmt;
|
||||
|
||||
use ecow::{eco_format, EcoString};
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::RegexSet;
|
||||
use strum::{EnumIter, IntoEnumIterator};
|
||||
|
@ -312,7 +313,7 @@ impl BuiltinTy {
|
|||
BuiltinTy::Type(builtin).literally()
|
||||
}
|
||||
|
||||
pub(crate) fn describe(&self) -> String {
|
||||
pub(crate) fn describe(&self) -> EcoString {
|
||||
let res = match self {
|
||||
BuiltinTy::Clause => "any",
|
||||
BuiltinTy::Undef => "any",
|
||||
|
@ -347,9 +348,9 @@ impl BuiltinTy {
|
|||
BuiltinTy::Tag(tag) => {
|
||||
let (name, id) = tag.as_ref();
|
||||
return if let Some(id) = id {
|
||||
format!("tag {name} of {id:?}")
|
||||
eco_format!("tag {name} of {id:?}")
|
||||
} else {
|
||||
format!("tag {name}")
|
||||
eco_format!("tag {name}")
|
||||
};
|
||||
}
|
||||
BuiltinTy::Path(s) => match s {
|
||||
|
@ -369,7 +370,7 @@ impl BuiltinTy {
|
|||
},
|
||||
};
|
||||
|
||||
res.to_string()
|
||||
res.into()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
use ecow::{eco_format, EcoString};
|
||||
use reflexo::hash::hash128;
|
||||
use typst::foundations::Repr;
|
||||
|
||||
use crate::ty::prelude::*;
|
||||
use crate::{ty::prelude::*, upstream::truncated_repr_};
|
||||
|
||||
impl TypeScheme {
|
||||
/// Describe the given type with the given type scheme.
|
||||
pub fn describe(&self, ty: &Ty) -> Option<String> {
|
||||
pub fn describe(&self, ty: &Ty) -> Option<EcoString> {
|
||||
let mut worker: TypeDescriber = TypeDescriber::default();
|
||||
worker.describe_root(ty)
|
||||
}
|
||||
|
@ -13,7 +14,7 @@ impl TypeScheme {
|
|||
|
||||
impl Ty {
|
||||
/// Describe the given type.
|
||||
pub fn repr(&self) -> Option<String> {
|
||||
pub fn repr(&self) -> Option<EcoString> {
|
||||
let mut worker = TypeDescriber {
|
||||
repr: true,
|
||||
..Default::default()
|
||||
|
@ -22,16 +23,17 @@ impl Ty {
|
|||
}
|
||||
|
||||
/// Describe available value instances of the given type.
|
||||
pub fn value_repr(&self) -> Option<String> {
|
||||
pub fn value_repr(&self) -> Option<EcoString> {
|
||||
let mut worker = TypeDescriber {
|
||||
repr: true,
|
||||
value: true,
|
||||
..Default::default()
|
||||
};
|
||||
worker.describe_root(self)
|
||||
}
|
||||
|
||||
/// Describe the given type.
|
||||
pub fn describe(&self) -> Option<String> {
|
||||
pub fn describe(&self) -> Option<EcoString> {
|
||||
let mut worker = TypeDescriber::default();
|
||||
worker.describe_root(self)
|
||||
}
|
||||
|
@ -55,13 +57,14 @@ impl Ty {
|
|||
#[derive(Default)]
|
||||
struct TypeDescriber {
|
||||
repr: bool,
|
||||
described: HashMap<u128, String>,
|
||||
results: HashSet<String>,
|
||||
value: bool,
|
||||
described: HashMap<u128, EcoString>,
|
||||
results: HashSet<EcoString>,
|
||||
functions: Vec<Interned<SigTy>>,
|
||||
}
|
||||
|
||||
impl TypeDescriber {
|
||||
fn describe_root(&mut self, ty: &Ty) -> Option<String> {
|
||||
fn describe_root(&mut self, ty: &Ty) -> Option<EcoString> {
|
||||
let _ = TypeDescriber::describe_iter;
|
||||
// recursive structure
|
||||
if let Some(t) = self.described.get(&hash128(ty)) {
|
||||
|
@ -72,7 +75,7 @@ impl TypeDescriber {
|
|||
if !res.is_empty() {
|
||||
return Some(res);
|
||||
}
|
||||
self.described.insert(hash128(ty), "$self".to_string());
|
||||
self.described.insert(hash128(ty), "$self".into());
|
||||
|
||||
let mut results = std::mem::take(&mut self.results)
|
||||
.into_iter()
|
||||
|
@ -83,7 +86,7 @@ impl TypeDescriber {
|
|||
// only first function is described
|
||||
let f = functions[0].clone();
|
||||
|
||||
let mut res = String::new();
|
||||
let mut res = EcoString::new();
|
||||
res.push('(');
|
||||
let mut not_first = false;
|
||||
for ty in f.positional_params() {
|
||||
|
@ -124,13 +127,13 @@ impl TypeDescriber {
|
|||
}
|
||||
|
||||
if results.is_empty() {
|
||||
self.described.insert(hash128(ty), "any".to_string());
|
||||
self.described.insert(hash128(ty), "any".into());
|
||||
return None;
|
||||
}
|
||||
|
||||
results.sort();
|
||||
results.dedup();
|
||||
let res = results.join(" | ");
|
||||
let res: EcoString = results.join(" | ").into();
|
||||
self.described.insert(hash128(ty), res.clone());
|
||||
Some(res)
|
||||
}
|
||||
|
@ -144,7 +147,7 @@ impl TypeDescriber {
|
|||
}
|
||||
}
|
||||
|
||||
fn describe(&mut self, ty: &Ty) -> String {
|
||||
fn describe(&mut self, ty: &Ty) -> EcoString {
|
||||
match ty {
|
||||
Ty::Var(..) => {}
|
||||
Ty::Union(tys) => {
|
||||
|
@ -158,57 +161,56 @@ impl TypeDescriber {
|
|||
self.functions.push(f.clone());
|
||||
}
|
||||
Ty::Dict(..) => {
|
||||
return "dict".to_string();
|
||||
return "dict".into();
|
||||
}
|
||||
Ty::Tuple(..) => {
|
||||
return "array".to_string();
|
||||
return "array".into();
|
||||
}
|
||||
Ty::Array(..) => {
|
||||
return "array".to_string();
|
||||
return "array".into();
|
||||
}
|
||||
// todo: sig with
|
||||
Ty::With(w) => {
|
||||
return self.describe(&w.sig);
|
||||
}
|
||||
Ty::Builtin(BuiltinTy::Content | BuiltinTy::Space) => {
|
||||
return "content".to_string();
|
||||
return "content".into();
|
||||
}
|
||||
// Doesn't provide any information, hence we doesn't describe it intermediately here.
|
||||
Ty::Any | Ty::Builtin(BuiltinTy::Clause | BuiltinTy::Undef | BuiltinTy::Infer) => {}
|
||||
Ty::Builtin(BuiltinTy::FlowNone | BuiltinTy::None) => {
|
||||
return "none".to_string();
|
||||
return "none".into();
|
||||
}
|
||||
Ty::Builtin(BuiltinTy::Auto) => {
|
||||
return "auto".to_string();
|
||||
return "auto".into();
|
||||
}
|
||||
Ty::Boolean(..) if self.repr => {
|
||||
return "bool".to_string();
|
||||
return "bool".into();
|
||||
}
|
||||
Ty::Boolean(None) => {
|
||||
return "bool".to_string();
|
||||
return "bool".into();
|
||||
}
|
||||
Ty::Boolean(Some(b)) => {
|
||||
return b.to_string();
|
||||
return eco_format!("{b}");
|
||||
}
|
||||
Ty::Builtin(b) => {
|
||||
return b.describe();
|
||||
}
|
||||
Ty::Value(v) if self.repr => return v.val.ty().short_name().to_string(),
|
||||
Ty::Value(v) => return v.val.repr().to_string(),
|
||||
Ty::Value(v) if self.value => return truncated_repr_::<181>(&v.val),
|
||||
Ty::Value(v) if self.repr => return v.val.ty().short_name().into(),
|
||||
Ty::Value(v) => return v.val.repr(),
|
||||
Ty::Field(..) => {
|
||||
return "field".to_string();
|
||||
return "field".into();
|
||||
}
|
||||
Ty::Args(..) => {
|
||||
return "arguments".to_string();
|
||||
return "arguments".into();
|
||||
}
|
||||
Ty::Pattern(..) => {
|
||||
return "pattern".to_string();
|
||||
}
|
||||
Ty::Select(..) | Ty::Unary(..) | Ty::Binary(..) | Ty::If(..) => {
|
||||
return "any".to_string()
|
||||
return "pattern".into();
|
||||
}
|
||||
Ty::Select(..) | Ty::Unary(..) | Ty::Binary(..) | Ty::If(..) => return "any".into(),
|
||||
}
|
||||
|
||||
String::new()
|
||||
EcoString::new()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -469,7 +469,6 @@ fn describe_value(ctx: &mut LocalContext, v: &Value) -> EcoString {
|
|||
.ty()
|
||||
.describe()
|
||||
.unwrap_or_else(|| "function".into())
|
||||
.into()
|
||||
}
|
||||
Value::Module(m) => {
|
||||
if let Some(fid) = m.file_id() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue