mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-08-02 17:32:16 +00:00
feat: adjust builtin types for typst v0.13.0 (#1416)
* feat: adjust builtin types for typst v0.13.0 * todo * test: update snapshot * test: update snapshot
This commit is contained in:
parent
7faef58186
commit
a191b7c852
12 changed files with 112 additions and 20 deletions
|
@ -610,7 +610,9 @@ impl CompletionPair<'_, '_, '_> {
|
|||
if let Some(ty) = ty {
|
||||
let filter = |ty: &Ty| match surrounding_syntax {
|
||||
SurroundingSyntax::StringContent => match ty {
|
||||
Ty::Builtin(BuiltinTy::Path(..) | BuiltinTy::TextFont) => true,
|
||||
Ty::Builtin(
|
||||
BuiltinTy::Path(..) | BuiltinTy::TextFont | BuiltinTy::TextFeature,
|
||||
) => true,
|
||||
Ty::Value(val) => matches!(val.val, Value::Str(..)),
|
||||
Ty::Builtin(BuiltinTy::Type(ty)) => {
|
||||
*ty == Type::of::<typst::foundations::Str>()
|
||||
|
|
|
@ -164,6 +164,7 @@ impl FnCompletionFeat {
|
|||
| BuiltinTy::Color
|
||||
| BuiltinTy::TextSize
|
||||
| BuiltinTy::TextFont
|
||||
| BuiltinTy::TextFeature
|
||||
| BuiltinTy::TextLang
|
||||
| BuiltinTy::TextRegion
|
||||
| BuiltinTy::Label
|
||||
|
|
|
@ -237,6 +237,9 @@ impl TypeCompletionWorker<'_, '_, '_, '_> {
|
|||
BuiltinTy::TextFont => {
|
||||
self.base.font_completions();
|
||||
}
|
||||
BuiltinTy::TextFeature => {
|
||||
self.base.font_feature_completions();
|
||||
}
|
||||
BuiltinTy::Margin => {
|
||||
self.snippet_completion("()", "(${})", "Margin dictionary.");
|
||||
self.type_completion(&Ty::Builtin(BuiltinTy::Length), docs);
|
||||
|
|
|
@ -19,6 +19,11 @@ impl CompletionPair<'_, '_, '_> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Add completions for current font features.
|
||||
pub fn font_feature_completions(&mut self) {
|
||||
// todo: add me
|
||||
}
|
||||
|
||||
/// Add completions for all available packages.
|
||||
pub fn package_completions(&mut self, all_versions: bool) {
|
||||
let w = self.worker.world().clone();
|
||||
|
|
|
@ -253,6 +253,8 @@ impl TypeChecker<'_> {
|
|||
LazyLock::new(|| Ty::Dict(FLOW_OUTSET_DICT.clone()));
|
||||
static FLOW_RADIUS_DICT_TYPE: LazyLock<Ty> =
|
||||
LazyLock::new(|| Ty::Dict(FLOW_RADIUS_DICT.clone()));
|
||||
static FLOW_TEXT_FONT_DICT_TYPE: LazyLock<Ty> =
|
||||
LazyLock::new(|| Ty::Dict(FLOW_TEXT_FONT_DICT.clone()));
|
||||
|
||||
fn is_ty(ty: &Ty) -> bool {
|
||||
match ty {
|
||||
|
@ -362,6 +364,16 @@ impl TypeChecker<'_> {
|
|||
self.constrain(&FLOW_RADIUS_DICT_TYPE, rhs);
|
||||
}
|
||||
}
|
||||
(lhs, Ty::Builtin(BuiltinTy::TextFont)) => {
|
||||
if lhs.is_dict() {
|
||||
self.constrain(lhs, &FLOW_TEXT_FONT_DICT_TYPE);
|
||||
}
|
||||
}
|
||||
(Ty::Builtin(BuiltinTy::TextFont), rhs) => {
|
||||
if rhs.is_dict() {
|
||||
self.constrain(&FLOW_TEXT_FONT_DICT_TYPE, rhs);
|
||||
}
|
||||
}
|
||||
(Ty::Dict(lhs), Ty::Dict(rhs)) => {
|
||||
for (key, lhs, rhs) in lhs.common_iface_fields(rhs) {
|
||||
crate::log_debug_ct!("constrain record item {key} {lhs:?} ⪯ {rhs:?}");
|
||||
|
|
|
@ -3,6 +3,5 @@ source: crates/tinymist-query/src/analysis.rs
|
|||
description: "Check on \"\\\"Test\\\"\" (34)"
|
||||
expression: post_ty
|
||||
input_file: crates/tinymist-query/src/fixtures/post_type_check/text_font_element.typ
|
||||
snapshot_kind: text
|
||||
---
|
||||
( ⪰ TextFont | (TextFont | Array<TextFont>))
|
||||
( ⪰ TextFont | "covers": Any | "name": Any | (TextFont | Array<TextFont>))
|
||||
|
|
|
@ -3,6 +3,5 @@ source: crates/tinymist-query/src/analysis.rs
|
|||
description: "Check on \"\\\"Test\\\"\" (31)"
|
||||
expression: post_ty
|
||||
input_file: crates/tinymist-query/src/fixtures/post_type_check/text_font_element2.typ
|
||||
snapshot_kind: text
|
||||
---
|
||||
( ⪰ ( ⪰ "Test" ⪯ (TextFont | Array<TextFont>)) ⪯ TextFont)
|
||||
( ⪰ ( ⪰ "Test" ⪯ (TextFont | Array<TextFont>)) ⪯ TextFont & "covers": Any & "name": Any)
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
---
|
||||
source: crates/tinymist-query/src/analysis.rs
|
||||
description: "Check on \"(\" (18)"
|
||||
expression: literal_type
|
||||
expression: post_ty
|
||||
input_file: crates/tinymist-query/src/fixtures/post_type_check/with_element.typ
|
||||
snapshot_kind: text
|
||||
---
|
||||
( ⪰ "alternates": Type(bool) | "baseline": Type(length) | "body": Type(content) | "bottom-edge": (Type(length) | "baseline" | "bounds" | "descender") | "cjk-latin-spacing": (Type(auto) | Type(none)) | "costs": Type(dictionary) | "dir": Dir | "discretionary-ligatures": Type(bool) | "fallback": Type(bool) | "features": (Type(array) | Type(dictionary)) | "fill": Color | "font": (TextFont | Array<TextFont>) | "fractions": Type(bool) | "historical-ligatures": Type(bool) | "hyphenate": (Type(auto) | Type(bool)) | "kerning": Type(bool) | "lang": TextLang | "ligatures": Type(bool) | "number-type": (Type(auto) | "lining" | "old-style") | "number-width": (Type(auto) | "proportional" | "tabular") | "overhang": Type(bool) | "region": TextRegion | "script": (Type(auto) | Type(str)) | "size": TextSize | "slashed-zero": Type(bool) | "spacing": Type(relative) | "stretch": Type(ratio) | "stroke": Stroke | "style": ("italic" | "normal" | "oblique") | "stylistic-set": (Type(array) | Type(int) | Type(none)) | "top-edge": (Type(length) | "ascender" | "baseline" | "bounds" | "cap-height" | "x-height") | "tracking": Type(length) | "weight": (Type(int) | "black" | "bold" | "extrabold" | "extralight" | "light" | "medium" | "regular" | "semibold" | "thin"))
|
||||
( ⪰ "alternates": Type(bool) | "baseline": Type(length) | "body": Type(content) | "bottom-edge": (Type(length) | "baseline" | "bounds" | "descender") | "cjk-latin-spacing": (Type(auto) | Type(none)) | "costs": {"hyphenation": Type(ratio), "orphan": Type(ratio), "runt": Type(ratio), "widow": Type(ratio)} | "dir": Dir | "discretionary-ligatures": Type(bool) | "fallback": Type(bool) | "features": (Type(array) | Type(dictionary)) | "fill": Color | "font": (TextFont | Array<TextFont>) | "fractions": Type(bool) | "historical-ligatures": Type(bool) | "hyphenate": (Type(auto) | Type(bool)) | "kerning": Type(bool) | "lang": TextLang | "ligatures": Type(bool) | "number-type": (Type(auto) | "lining" | "old-style") | "number-width": (Type(auto) | "proportional" | "tabular") | "overhang": Type(bool) | "region": TextRegion | "script": (Type(auto) | Type(str)) | "size": TextSize | "slashed-zero": Type(bool) | "spacing": Type(relative) | "stretch": Type(ratio) | "stroke": Stroke | "style": ("italic" | "normal" | "oblique") | "stylistic-set": (Type(array) | Type(int) | Type(none)) | "top-edge": (Type(length) | "ascender" | "baseline" | "bounds" | "cap-height" | "x-height") | "tracking": Type(length) | "weight": (Type(int) | "black" | "bold" | "extrabold" | "extralight" | "light" | "medium" | "regular" | "semibold" | "thin"))
|
||||
|
|
|
@ -5,7 +5,8 @@ use ecow::{eco_format, EcoString};
|
|||
use once_cell::sync::Lazy;
|
||||
use regex::RegexSet;
|
||||
use strum::{EnumIter, IntoEnumIterator};
|
||||
use typst::foundations::CastInfo;
|
||||
use typst::foundations::{CastInfo, Regex};
|
||||
use typst::layout::Ratio;
|
||||
use typst::syntax::FileId;
|
||||
use typst::{
|
||||
foundations::{AutoValue, Content, Func, NoneValue, ParamInfo, Type, Value},
|
||||
|
@ -221,6 +222,7 @@ pub enum BuiltinTy {
|
|||
Color,
|
||||
TextSize,
|
||||
TextFont,
|
||||
TextFeature,
|
||||
TextLang,
|
||||
TextRegion,
|
||||
|
||||
|
@ -263,6 +265,7 @@ impl fmt::Debug for BuiltinTy {
|
|||
BuiltinTy::Color => write!(f, "Color"),
|
||||
BuiltinTy::TextSize => write!(f, "TextSize"),
|
||||
BuiltinTy::TextFont => write!(f, "TextFont"),
|
||||
BuiltinTy::TextFeature => write!(f, "TextFeature"),
|
||||
BuiltinTy::TextLang => write!(f, "TextLang"),
|
||||
BuiltinTy::TextRegion => write!(f, "TextRegion"),
|
||||
BuiltinTy::Dir => write!(f, "Dir"),
|
||||
|
@ -345,6 +348,7 @@ impl BuiltinTy {
|
|||
BuiltinTy::Color => "color",
|
||||
BuiltinTy::TextSize => "text.size",
|
||||
BuiltinTy::TextFont => "text.font",
|
||||
BuiltinTy::TextFeature => "text.feature",
|
||||
BuiltinTy::TextLang => "text.lang",
|
||||
BuiltinTy::TextRegion => "text.region",
|
||||
BuiltinTy::Dir => "dir",
|
||||
|
@ -456,6 +460,7 @@ macro_rules! flow_record {
|
|||
pub(super) fn param_mapping(func: &Func, param: &ParamInfo) -> Option<Ty> {
|
||||
// todo: remove path params which is compatible with 0.12.0
|
||||
match (func.name()?, param.name) {
|
||||
// todo: pdf.embed
|
||||
("embed", "path") => Some(literally(Path(PathPreference::None))),
|
||||
("cbor", "path" | "source") => Some(literally(Path(PathPreference::None))),
|
||||
("plugin", "source") => Some(literally(Path(PathPreference::Wasm))),
|
||||
|
@ -474,10 +479,24 @@ pub(super) fn param_mapping(func: &Func, param: &ParamInfo) -> Option<Ty> {
|
|||
])),
|
||||
("cite", "key") => Some(Ty::iter_union([literally(CiteLabel)])),
|
||||
("ref", "target") => Some(Ty::iter_union([literally(RefLabel)])),
|
||||
("link", "dest") | ("footnote", "body") => Some(Ty::iter_union([
|
||||
("footnote", "body") => Some(Ty::iter_union([
|
||||
literally(RefLabel),
|
||||
Ty::from_cast_info(¶m.input),
|
||||
])),
|
||||
("link", "dest") => {
|
||||
static LINK_DEST_TYPE: Lazy<Ty> = Lazy::new(|| {
|
||||
flow_union!(
|
||||
literally(RefLabel),
|
||||
Ty::Builtin(BuiltinTy::Type(Type::of::<foundations::Str>())),
|
||||
Ty::Builtin(BuiltinTy::Type(Type::of::<typst::introspection::Location>())),
|
||||
Ty::Dict(RecordTy::new(vec![
|
||||
("x".into(), literally(Length)),
|
||||
("y".into(), literally(Length)),
|
||||
])),
|
||||
)
|
||||
});
|
||||
Some(LINK_DEST_TYPE.clone())
|
||||
}
|
||||
("bibliography", "path" | "sources") => {
|
||||
static BIB_PATH_TYPE: Lazy<Ty> = Lazy::new(|| {
|
||||
let bib_path_ty = literally(Path(PathPreference::Bibliography));
|
||||
|
@ -487,18 +506,52 @@ pub(super) fn param_mapping(func: &Func, param: &ParamInfo) -> Option<Ty> {
|
|||
}
|
||||
("text", "size") => Some(literally(TextSize)),
|
||||
("text", "font") => {
|
||||
// todo: the dict can be completed, but we have bugs...
|
||||
static FONT_TYPE: Lazy<Ty> = Lazy::new(|| {
|
||||
Ty::iter_union([literally(TextFont), Ty::Array(literally(TextFont).into())])
|
||||
});
|
||||
Some(FONT_TYPE.clone())
|
||||
}
|
||||
("text", "feature") => {
|
||||
static FONT_TYPE: Lazy<Ty> = Lazy::new(|| {
|
||||
Ty::iter_union([
|
||||
// todo: the key can only be the text feature
|
||||
Ty::Builtin(BuiltinTy::Type(Type::of::<foundations::Dict>())),
|
||||
Ty::Array(literally(TextFeature).into()),
|
||||
])
|
||||
});
|
||||
Some(FONT_TYPE.clone())
|
||||
}
|
||||
("text", "costs") => {
|
||||
static FONT_TYPE: Lazy<Ty> = Lazy::new(|| {
|
||||
Ty::Dict(flow_record!(
|
||||
"hyphenation" => literally(BuiltinTy::Type(Type::of::<Ratio>())),
|
||||
"runt" => literally(BuiltinTy::Type(Type::of::<Ratio>())),
|
||||
"widow" => literally(BuiltinTy::Type(Type::of::<Ratio>())),
|
||||
"orphan" => literally(BuiltinTy::Type(Type::of::<Ratio>())),
|
||||
))
|
||||
});
|
||||
Some(FONT_TYPE.clone())
|
||||
}
|
||||
("text", "lang") => Some(literally(TextLang)),
|
||||
("text", "region") => Some(literally(TextRegion)),
|
||||
("text" | "stack", "dir") => Some(literally(Dir)),
|
||||
("par", "first-line-indent") => {
|
||||
static FIRST_LINE_INDENT: Lazy<Ty> = Lazy::new(|| {
|
||||
Ty::iter_union([
|
||||
literally(Length),
|
||||
Ty::Dict(RecordTy::new(vec![
|
||||
("amount".into(), literally(Length)),
|
||||
("all".into(), Ty::Boolean(Option::None)),
|
||||
])),
|
||||
])
|
||||
});
|
||||
Some(FIRST_LINE_INDENT.clone())
|
||||
}
|
||||
(
|
||||
// todo: polygon.regular
|
||||
"page" | "highlight" | "text" | "path" | "rect" | "ellipse" | "circle" | "polygon"
|
||||
| "box" | "block" | "table" | "regular",
|
||||
"page" | "highlight" | "text" | "path" | "curve" | "rect" | "ellipse" | "circle"
|
||||
| "polygon" | "box" | "block" | "table" | "regular",
|
||||
"fill",
|
||||
) => Some(literally(Color)),
|
||||
(
|
||||
|
@ -509,7 +562,7 @@ pub(super) fn param_mapping(func: &Func, param: &ParamInfo) -> Option<Ty> {
|
|||
("block" | "box" | "circle" | "ellipse" | "rect" | "square", "outset") => {
|
||||
Some(literally(Outset))
|
||||
}
|
||||
("block" | "box" | "rect" | "square", "radius") => Some(literally(Radius)),
|
||||
("block" | "box" | "rect" | "square" | "highlight", "radius") => Some(literally(Radius)),
|
||||
("grid" | "table", "columns" | "rows" | "gutter" | "column-gutter" | "row-gutter") => {
|
||||
static COLUMN_TYPE: Lazy<Ty> = Lazy::new(|| {
|
||||
flow_union!(
|
||||
|
@ -521,7 +574,7 @@ pub(super) fn param_mapping(func: &Func, param: &ParamInfo) -> Option<Ty> {
|
|||
});
|
||||
Some(COLUMN_TYPE.clone())
|
||||
}
|
||||
("pattern", "size") => {
|
||||
("pattern" | "tiling", "size") => {
|
||||
static PATTERN_SIZE_TYPE: Lazy<Ty> = Lazy::new(|| {
|
||||
flow_union!(
|
||||
Ty::Value(InsTy::new(Value::Auto)),
|
||||
|
@ -533,9 +586,9 @@ pub(super) fn param_mapping(func: &Func, param: &ParamInfo) -> Option<Ty> {
|
|||
("stroke", "dash") => Some(FLOW_STROKE_DASH_TYPE.clone()),
|
||||
(
|
||||
//todo: table.cell, table.hline, table.vline, math.cancel, grid.cell, polygon.regular
|
||||
"cancel" | "highlight" | "overline" | "strike" | "underline" | "text" | "path" | "rect"
|
||||
| "ellipse" | "circle" | "polygon" | "box" | "block" | "table" | "line" | "cell"
|
||||
| "hline" | "vline" | "regular",
|
||||
"cancel" | "highlight" | "overline" | "strike" | "underline" | "text" | "path"
|
||||
| "curve" | "rect" | "ellipse" | "circle" | "polygon" | "box" | "block" | "table"
|
||||
| "line" | "cell" | "hline" | "vline" | "regular",
|
||||
"stroke",
|
||||
) => Some(Ty::Builtin(Stroke)),
|
||||
("page", "margin") => Some(Ty::Builtin(Margin)),
|
||||
|
@ -626,6 +679,13 @@ pub static FLOW_RADIUS_DICT: Lazy<Interned<RecordTy>> = Lazy::new(|| {
|
|||
)
|
||||
});
|
||||
|
||||
pub static FLOW_TEXT_FONT_DICT: Lazy<Interned<RecordTy>> = Lazy::new(|| {
|
||||
flow_record!(
|
||||
"name" => literally(TextFont),
|
||||
"covers" => flow_union!("latin-in-cjk", BuiltinTy::Type(Type::of::<Regex>())),
|
||||
)
|
||||
});
|
||||
|
||||
// todo bad case: array.fold
|
||||
// todo bad case: datetime
|
||||
// todo bad case: selector
|
||||
|
@ -634,9 +694,13 @@ pub static FLOW_RADIUS_DICT: Lazy<Interned<RecordTy>> = Lazy::new(|| {
|
|||
// todo: numbering/supplement
|
||||
// todo: grid/table.fill/align/stroke/inset can be a function
|
||||
// todo: math.cancel.angle can be a function
|
||||
// todo: text.features array/dictionary
|
||||
// todo: math.mat.augment
|
||||
// todo: csv.row-type can be an array or a dictionary
|
||||
// todo: text.stylistic-set is an array of integer
|
||||
// todo: raw.lang can be completed
|
||||
// todo: smartquote.quotes can be an array or a dictionary
|
||||
// todo: mat.augment can be a dictionary
|
||||
// todo: pdf.embed mime-type can be special
|
||||
|
||||
// ISO 639
|
||||
|
||||
|
|
|
@ -134,6 +134,10 @@ impl IfaceCheckDriver<'_> {
|
|||
self.checker
|
||||
.check(Iface::Dict(&FLOW_RADIUS_DICT), &mut self.ctx, pol);
|
||||
}
|
||||
Ty::Builtin(BuiltinTy::TextFont) if self.dict_as_iface() => {
|
||||
self.checker
|
||||
.check(Iface::Dict(&FLOW_TEXT_FONT_DICT), &mut self.ctx, pol);
|
||||
}
|
||||
// // todo: deduplicate checking early
|
||||
Ty::Value(ins_ty) => {
|
||||
if self.value_as_iface() {
|
||||
|
|
|
@ -186,6 +186,10 @@ impl SigCheckDriver<'_> {
|
|||
self.checker
|
||||
.check(Sig::DictCons(&FLOW_RADIUS_DICT), &mut self.ctx, pol);
|
||||
}
|
||||
Ty::Builtin(BuiltinTy::TextFont) if self.dict_as_sig() => {
|
||||
self.checker
|
||||
.check(Sig::DictCons(&FLOW_TEXT_FONT_DICT), &mut self.ctx, pol);
|
||||
}
|
||||
// todo: deduplicate checking early
|
||||
Ty::Value(ins_ty) => {
|
||||
if self.func_as_sig() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue