mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-07-24 05:05:00 +00:00
fix: distinguish content value from content type (#1482)
* fix: distinguish content value from content type * docs: add comments * fix: repr
This commit is contained in:
parent
62815ae028
commit
be9c0478f6
21 changed files with 154 additions and 79 deletions
|
@ -164,7 +164,7 @@ impl FnCompletionFeat {
|
|||
BuiltinTy::TypeType(..) => {}
|
||||
BuiltinTy::Clause
|
||||
| BuiltinTy::Undef
|
||||
| BuiltinTy::Content
|
||||
| BuiltinTy::Content(..)
|
||||
| BuiltinTy::Space
|
||||
| BuiltinTy::None
|
||||
| BuiltinTy::Break
|
||||
|
|
|
@ -279,7 +279,7 @@ impl IfaceChecker for CompletionScopeChecker<'_> {
|
|||
self.defines.insert(name.clone().into(), term);
|
||||
}
|
||||
}
|
||||
Iface::Element { val, .. } if self.is_field_access() => {
|
||||
Iface::Content { val, .. } if self.is_field_access() => {
|
||||
// 255 is the magic "label"
|
||||
let styles = StyleChain::default();
|
||||
for field_id in 0u8..254u8 {
|
||||
|
@ -326,7 +326,7 @@ impl IfaceChecker for CompletionScopeChecker<'_> {
|
|||
Iface::Dict { .. } if self.is_field_access() => {
|
||||
self.type_methods(Some(iface.to_type()), Type::of::<Dict>());
|
||||
}
|
||||
Iface::Element { val, .. } => {
|
||||
Iface::Content { val, .. } => {
|
||||
self.defines.insert_scope(val.scope());
|
||||
}
|
||||
// todo: distingusish TypeType and Type
|
||||
|
|
|
@ -148,7 +148,7 @@ impl TypeCompletionWorker<'_, '_, '_, '_> {
|
|||
BuiltinTy::Space => return None,
|
||||
BuiltinTy::Break => return None,
|
||||
BuiltinTy::Continue => return None,
|
||||
BuiltinTy::Content => return None,
|
||||
BuiltinTy::Content(..) => return None,
|
||||
BuiltinTy::Infer => return None,
|
||||
BuiltinTy::FlowNone => return None,
|
||||
BuiltinTy::Tag(..) => return None,
|
||||
|
|
|
@ -289,7 +289,7 @@ impl TypeChecker<'_> {
|
|||
self.check(content);
|
||||
}
|
||||
|
||||
Ty::Builtin(BuiltinTy::Element(element.elem))
|
||||
Ty::Builtin(BuiltinTy::Content(Some(element.elem)))
|
||||
}
|
||||
|
||||
fn check_unary(&mut self, unary: &Interned<UnExpr>) -> Ty {
|
||||
|
@ -452,7 +452,7 @@ impl TypeChecker<'_> {
|
|||
|
||||
let selected = match selector {
|
||||
Some(selector) => Self::content_by_selector(selector)?,
|
||||
None => Ty::Builtin(BuiltinTy::Content),
|
||||
None => Ty::Builtin(BuiltinTy::Content(None)),
|
||||
};
|
||||
|
||||
let show_fact = Ty::Func(SigTy::unary(selected, Ty::Any));
|
||||
|
@ -463,33 +463,38 @@ impl TypeChecker<'_> {
|
|||
}
|
||||
|
||||
fn content_by_selector(selector: Ty) -> Option<Ty> {
|
||||
#[inline(always)]
|
||||
fn text_type() -> Ty {
|
||||
Ty::Builtin(BuiltinTy::Content(Some(
|
||||
Element::of::<typst::text::TextElem>(),
|
||||
)))
|
||||
}
|
||||
|
||||
crate::log_debug_ct!("check selector {selector:?}");
|
||||
|
||||
Some(match selector {
|
||||
Ty::With(with) => return Self::content_by_selector(with.sig.as_ref().clone()),
|
||||
Ty::Builtin(BuiltinTy::Type(ty)) => {
|
||||
if ty == Type::of::<typst::foundations::Regex>() {
|
||||
Ty::Builtin(BuiltinTy::Element(Element::of::<typst::text::TextElem>()))
|
||||
text_type()
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
Ty::Builtin(BuiltinTy::Element(..)) => selector,
|
||||
Ty::Builtin(BuiltinTy::Element(ty)) => Ty::Builtin(BuiltinTy::Content(Some(ty))),
|
||||
Ty::Value(ins_ty) => match &ins_ty.val {
|
||||
Value::Str(..) => {
|
||||
Ty::Builtin(BuiltinTy::Element(Element::of::<typst::text::TextElem>()))
|
||||
}
|
||||
Value::Content(c) => Ty::Builtin(BuiltinTy::Element(c.elem())),
|
||||
Value::Str(..) => text_type(),
|
||||
Value::Content(c) => Ty::Builtin(BuiltinTy::Content(Some(c.elem()))),
|
||||
Value::Func(f) => {
|
||||
if let Some(elem) = f.element() {
|
||||
Ty::Builtin(BuiltinTy::Element(elem))
|
||||
Ty::Builtin(BuiltinTy::Content(Some(elem)))
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
Value::Dyn(value) => {
|
||||
if value.ty() == Type::of::<typst::foundations::Regex>() {
|
||||
Ty::Builtin(BuiltinTy::Element(Element::of::<typst::text::TextElem>()))
|
||||
text_type()
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
|
@ -540,7 +545,7 @@ impl TypeChecker<'_> {
|
|||
if let Some(body) = content_ref.body.as_ref() {
|
||||
self.check(body);
|
||||
}
|
||||
Ty::Builtin(BuiltinTy::Content)
|
||||
Ty::Builtin(BuiltinTy::Content(None))
|
||||
}
|
||||
|
||||
fn check_import(&mut self, import: &Interned<ImportExpr>) -> Ty {
|
||||
|
@ -549,7 +554,7 @@ impl TypeChecker<'_> {
|
|||
}
|
||||
|
||||
fn check_include(&mut self, _include: &Interned<IncludeExpr>) -> Ty {
|
||||
Ty::Builtin(BuiltinTy::Content)
|
||||
Ty::Builtin(BuiltinTy::Content(None))
|
||||
}
|
||||
|
||||
fn check_contextual(&mut self, expr: &Interned<Expr>) -> Ty {
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
/// contains: add
|
||||
|
||||
#let add = math.op("+")
|
||||
#let ct = []
|
||||
|
||||
#ct.a/* range 0..1 */
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
source: crates/tinymist-query/src/completion.rs
|
||||
description: Completion on / (67..68)
|
||||
expression: "JsonRepr::new_pure(results)"
|
||||
input_file: crates/tinymist-query/src/fixtures/completion/math_op.typ
|
||||
---
|
||||
[
|
||||
{
|
||||
"isIncomplete": false,
|
||||
"items": []
|
||||
}
|
||||
]
|
|
@ -14,7 +14,7 @@ input_file: crates/tinymist-query/src/fixtures/completion/set_in_show.typ
|
|||
"labelDetails": {
|
||||
"description": "(str, align: alignment, block: bool, lang: none | str, syntaxes: [syntax], tab-size: int, theme: [theme]) => raw"
|
||||
},
|
||||
"sortText": "054",
|
||||
"sortText": "053",
|
||||
"textEdit": {
|
||||
"newText": "raw(${1:})",
|
||||
"range": {
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
source: crates/tinymist-query/src/hover.rs
|
||||
expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
||||
input_file: crates/tinymist-query/src/fixtures/hover/value_repr.typ
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"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: (content | none, baseline: relative, clip: bool, fill: color, height: auto | relative, inset: inset, outset: outset, radius: radius, stroke: stroke, width: auto | fraction | relative) => box = (content | none, baseline: relative, clip: bool, fill: color, height: auto | relative, inset: inset, outset: outset, radius: radius, stroke: stroke, width: auto | fraction | relative) => box,\n w06: (content) => item | any = (body-indent: length, indent: length, marker: array | content | function, spacing: auto | length, tight: bool, ..: content) => 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: dictionary = (:),\n w13: dictionary = (a: 1),\n w14: dictionary = (a: (content | none, baseline: relative, clip: bool, fill: color, height: auto | relative, inset: inset, outset: outset, radius: radius, stroke: stroke, width: auto | fraction | relative) => box),\n w15: dictionary = (a: (body-indent: length, indent: length, marker: array | content | function, spacing: auto | length, tight: bool, ..: content) => list.item),\n) = int;\n```\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: (content | none, baseline: relative, clip: bool, fill: color, height: auto | relative, inset: inset, outset: outset, radius: radius, stroke: stroke, width: auto | fraction | relative) => box\n```\n\n\n\n## w06 (named)\n\n```typc\ntype: (content) => item | 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: dictionary\n```\n\n\n\n## w13 (named)\n\n```typc\ntype: dictionary\n```\n\n\n\n## w14 (named)\n\n```typc\ntype: dictionary\n```\n\n\n\n## w15 (named)\n\n```typc\ntype: dictionary\n```\n\n",
|
||||
"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: (content | none, baseline: relative, clip: bool, fill: color, height: auto | relative, inset: inset, outset: outset, radius: radius, stroke: stroke, width: auto | fraction | relative) => box = (content | none, baseline: relative, clip: bool, fill: color, height: auto | relative, inset: inset, outset: outset, radius: radius, stroke: stroke, width: auto | fraction | relative) => box,\n w06: (content) => item | any = (body-indent: length, indent: length, marker: array | content | function, spacing: auto | length, tight: bool, ..: content) => list.item,\n w07: text = Expr(..),\n w08: any = Expr(..),\n w09: any = 1 + 2,\n w10: array = (\n 1,\n 2,\n ),\n w11: array = (),\n w12: dictionary = (:),\n w13: dictionary = (a: 1),\n w14: dictionary = (a: (content | none, baseline: relative, clip: bool, fill: color, height: auto | relative, inset: inset, outset: outset, radius: radius, stroke: stroke, width: auto | fraction | relative) => box),\n w15: dictionary = (a: (body-indent: length, indent: length, marker: array | content | function, spacing: auto | length, tight: bool, ..: content) => list.item),\n) = int;\n```\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: (content | none, baseline: relative, clip: bool, fill: color, height: auto | relative, inset: inset, outset: outset, radius: radius, stroke: stroke, width: auto | fraction | relative) => box\n```\n\n\n\n## w06 (named)\n\n```typc\ntype: (content) => item | any\n```\n\n\n\n## w07 (named)\n\n```typc\ntype: text\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: dictionary\n```\n\n\n\n## w13 (named)\n\n```typc\ntype: dictionary\n```\n\n\n\n## w14 (named)\n\n```typc\ntype: dictionary\n```\n\n\n\n## w15 (named)\n\n```typc\ntype: dictionary\n```\n\n",
|
||||
"range": "23:20:23:21"
|
||||
}
|
||||
|
|
|
@ -2,20 +2,19 @@
|
|||
source: crates/tinymist-query/src/analysis.rs
|
||||
expression: result
|
||||
input_file: crates/tinymist-query/src/fixtures/type_check/bug_cite_func_infer.typ
|
||||
snapshot_kind: text
|
||||
---
|
||||
"cite_prose" = (RefLabel) => Element(ref)
|
||||
"cite_prose" = (RefLabel) => Content(ref)
|
||||
"labl" = Any
|
||||
"cite_prose_different_name" = (RefLabel) => Element(ref)
|
||||
"cite_prose_different_name" = (RefLabel) => Content(ref)
|
||||
"labl" = Any
|
||||
=====
|
||||
5..15 -> @cite_prose
|
||||
16..20 -> @labl
|
||||
24..27 -> Func(ref)
|
||||
24..33 -> Element(ref)
|
||||
24..33 -> Content(ref)
|
||||
28..32 -> @labl
|
||||
39..64 -> @cite_prose_different_name
|
||||
65..69 -> @labl
|
||||
73..76 -> Func(ref)
|
||||
73..82 -> Element(ref)
|
||||
73..82 -> Content(ref)
|
||||
77..81 -> @labl
|
||||
|
|
|
@ -2,11 +2,10 @@
|
|||
source: crates/tinymist-query/src/analysis.rs
|
||||
expression: result
|
||||
input_file: crates/tinymist-query/src/fixtures/type_check/infer.typ
|
||||
snapshot_kind: text
|
||||
---
|
||||
=====
|
||||
1..6 -> Func(image)
|
||||
1..18 -> Element(image)
|
||||
1..18 -> Content(image)
|
||||
21..25 -> Func(read)
|
||||
21..37 -> (Type(bytes) | Type(str))
|
||||
40..44 -> Func(json)
|
||||
|
|
|
@ -5,48 +5,48 @@ input_file: crates/tinymist-query/src/fixtures/type_check/infer2.typ
|
|||
---
|
||||
=====
|
||||
1..5 -> Func(text)
|
||||
1..52 -> Element(text)
|
||||
1..52 -> Content(text)
|
||||
23..25 -> ()
|
||||
46..49 -> Rgb(1, 0.254902, 0.211765, 1)
|
||||
54..58 -> Func(path)
|
||||
54..82 -> Element(path)
|
||||
54..82 -> Content(path)
|
||||
65..68 -> Rgb(1, 0.254902, 0.211765, 1)
|
||||
78..81 -> Rgb(1, 0.254902, 0.211765, 1)
|
||||
84..88 -> Func(line)
|
||||
84..127 -> Element(line)
|
||||
84..127 -> Content(line)
|
||||
123..126 -> Rgb(1, 0.254902, 0.211765, 1)
|
||||
129..133 -> Func(rect)
|
||||
129..220 -> Element(rect)
|
||||
129..220 -> Content(rect)
|
||||
165..168 -> Rgb(1, 0.254902, 0.211765, 1)
|
||||
178..181 -> Rgb(1, 0.254902, 0.211765, 1)
|
||||
222..229 -> Func(ellipse)
|
||||
222..253 -> Element(ellipse)
|
||||
222..253 -> Content(ellipse)
|
||||
236..239 -> Rgb(1, 0.254902, 0.211765, 1)
|
||||
249..252 -> Rgb(1, 0.254902, 0.211765, 1)
|
||||
255..261 -> Func(circle)
|
||||
255..285 -> Element(circle)
|
||||
255..285 -> Content(circle)
|
||||
268..271 -> Rgb(1, 0.254902, 0.211765, 1)
|
||||
281..284 -> Rgb(1, 0.254902, 0.211765, 1)
|
||||
287..290 -> Func(box)
|
||||
287..314 -> Element(box)
|
||||
287..314 -> Content(box)
|
||||
297..300 -> Rgb(1, 0.254902, 0.211765, 1)
|
||||
310..313 -> Rgb(1, 0.254902, 0.211765, 1)
|
||||
316..321 -> Func(block)
|
||||
316..345 -> Element(block)
|
||||
316..345 -> Content(block)
|
||||
328..331 -> Rgb(1, 0.254902, 0.211765, 1)
|
||||
341..344 -> Rgb(1, 0.254902, 0.211765, 1)
|
||||
347..352 -> Func(table)
|
||||
347..439 -> Element(table)
|
||||
347..439 -> Content(table)
|
||||
362..365 -> Rgb(1, 0.254902, 0.211765, 1)
|
||||
377..380 -> Rgb(1, 0.254902, 0.211765, 1)
|
||||
384..389 -> Func(table)
|
||||
384..395 -> (Func(hline) | (Func(hline) | Func(table).hline))
|
||||
384..408 -> Element(hline)
|
||||
384..408 -> Content(hline)
|
||||
404..407 -> Rgb(1, 0.254902, 0.211765, 1)
|
||||
412..417 -> Func(table)
|
||||
412..423 -> (Func(vline) | (Func(vline) | Func(table).vline))
|
||||
412..436 -> Element(vline)
|
||||
412..436 -> Content(vline)
|
||||
432..435 -> Rgb(1, 0.254902, 0.211765, 1)
|
||||
441..445 -> Func(text)
|
||||
441..457 -> Element(text)
|
||||
441..457 -> Content(text)
|
||||
454..456 -> ()
|
||||
|
|
|
@ -5,6 +5,6 @@ input_file: crates/tinymist-query/src/fixtures/type_check/infer_stroke_dict.typ
|
|||
---
|
||||
=====
|
||||
1..5 -> Func(text)
|
||||
1..54 -> Element(text)
|
||||
1..54 -> Content(text)
|
||||
14..51 -> {"paint": Luma(0, 1), "thickness": 1.0pt}
|
||||
25..30 -> Luma(0, 1)
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
source: crates/tinymist-query/src/analysis.rs
|
||||
expression: result
|
||||
input_file: crates/tinymist-query/src/fixtures/type_check/show.typ
|
||||
snapshot_kind: text
|
||||
---
|
||||
"" = (Any) => Any.it
|
||||
"it" = Element(text)
|
||||
"it" = Content(text)
|
||||
=====
|
||||
26..31 -> Type(regex)
|
||||
26..40 -> Type(regex)
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
source: crates/tinymist-query/src/analysis.rs
|
||||
expression: result
|
||||
input_file: crates/tinymist-query/src/fixtures/type_check/show_raw.typ
|
||||
snapshot_kind: text
|
||||
---
|
||||
"" = (Any) => Any.it
|
||||
"it" = Element(raw)
|
||||
"it" = Content(raw)
|
||||
=====
|
||||
26..29 -> Func(raw)
|
||||
31..33 -> @it
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
source: crates/tinymist-query/src/analysis.rs
|
||||
expression: result
|
||||
input_file: crates/tinymist-query/src/fixtures/type_check/show_raw_where.typ
|
||||
snapshot_kind: text
|
||||
---
|
||||
"" = (Any) => Any.it
|
||||
"it" = Element(raw)
|
||||
"it" = Content(raw)
|
||||
=====
|
||||
26..29 -> Func(raw)
|
||||
26..35 -> (Func(raw) | Func(raw).where)
|
||||
|
|
|
@ -7,19 +7,19 @@ input_file: crates/tinymist-query/src/fixtures/type_check/text_font.typ
|
|||
"y" = ("Test", )
|
||||
=====
|
||||
1..5 -> Func(text)
|
||||
1..21 -> Element(text)
|
||||
1..21 -> Content(text)
|
||||
23..27 -> Func(text)
|
||||
23..39 -> Element(text)
|
||||
23..39 -> Content(text)
|
||||
34..36 -> ()
|
||||
41..45 -> Func(text)
|
||||
41..64 -> Element(text)
|
||||
41..64 -> Content(text)
|
||||
52..61 -> ("Test", )
|
||||
70..71 -> @x
|
||||
82..86 -> Func(text)
|
||||
82..97 -> Element(text)
|
||||
82..97 -> Content(text)
|
||||
93..94 -> @x
|
||||
103..104 -> @y
|
||||
107..116 -> ("Test", )
|
||||
118..122 -> Func(text)
|
||||
118..133 -> Element(text)
|
||||
118..133 -> Content(text)
|
||||
129..130 -> @y
|
||||
|
|
|
@ -6,9 +6,10 @@ use rustc_hash::FxHashMap;
|
|||
use std::ops::Deref;
|
||||
use tinymist_std::hash::hash128;
|
||||
use typst::{
|
||||
foundations::{Element, NativeElement, Value},
|
||||
model::{EmphElem, EnumElem, HeadingElem, ListElem, StrongElem, TermsElem},
|
||||
syntax::{Span, SyntaxNode},
|
||||
foundations::{Element, NativeElement, Type, Value},
|
||||
model::{EmphElem, EnumElem, HeadingElem, ListElem, ParbreakElem, StrongElem, TermsElem},
|
||||
syntax::{ast::MathTextKind, Span, SyntaxNode},
|
||||
text::LinebreakElem,
|
||||
utils::LazyHash,
|
||||
};
|
||||
|
||||
|
@ -370,16 +371,37 @@ impl ExprWorker<'_> {
|
|||
.map_or_else(none_expr, |body| self.check(body)),
|
||||
)),
|
||||
|
||||
Text(..) => Expr::Type(Ty::Builtin(BuiltinTy::Content)),
|
||||
MathText(..) => Expr::Type(Ty::Builtin(BuiltinTy::Content)),
|
||||
Raw(..) => Expr::Type(Ty::Builtin(BuiltinTy::Content)),
|
||||
Link(..) => Expr::Type(Ty::Builtin(BuiltinTy::Content)),
|
||||
Text(..) => Expr::Type(Ty::Builtin(BuiltinTy::Content(Some(Element::of::<
|
||||
typst::text::TextElem,
|
||||
>())))),
|
||||
MathText(t) => Expr::Type(Ty::Builtin(BuiltinTy::Content(Some({
|
||||
match t.get() {
|
||||
MathTextKind::Character(..) => Element::of::<typst::foundations::SymbolElem>(),
|
||||
MathTextKind::Number(..) => Element::of::<typst::foundations::SymbolElem>(),
|
||||
}
|
||||
})))),
|
||||
Raw(..) => Expr::Type(Ty::Builtin(BuiltinTy::Content(Some(Element::of::<
|
||||
typst::text::RawElem,
|
||||
>())))),
|
||||
Link(..) => Expr::Type(Ty::Builtin(BuiltinTy::Content(Some(Element::of::<
|
||||
typst::model::LinkElem,
|
||||
>())))),
|
||||
Space(..) => Expr::Type(Ty::Builtin(BuiltinTy::Space)),
|
||||
Linebreak(..) => Expr::Type(Ty::Builtin(BuiltinTy::Content)),
|
||||
Parbreak(..) => Expr::Type(Ty::Builtin(BuiltinTy::Content)),
|
||||
Escape(..) => Expr::Type(Ty::Builtin(BuiltinTy::Content)),
|
||||
Shorthand(..) => Expr::Type(Ty::Builtin(BuiltinTy::Content)),
|
||||
SmartQuote(..) => Expr::Type(Ty::Builtin(BuiltinTy::Content)),
|
||||
Linebreak(..) => Expr::Type(Ty::Builtin(BuiltinTy::Content(Some(Element::of::<
|
||||
LinebreakElem,
|
||||
>())))),
|
||||
Parbreak(..) => Expr::Type(Ty::Builtin(BuiltinTy::Content(Some(Element::of::<
|
||||
ParbreakElem,
|
||||
>())))),
|
||||
Escape(..) => Expr::Type(Ty::Builtin(BuiltinTy::Content(Some(Element::of::<
|
||||
typst::text::TextElem,
|
||||
>())))),
|
||||
Shorthand(..) => Expr::Type(Ty::Builtin(BuiltinTy::Type(Type::of::<
|
||||
typst::foundations::Symbol,
|
||||
>()))),
|
||||
SmartQuote(..) => Expr::Type(Ty::Builtin(BuiltinTy::Content(Some(Element::of::<
|
||||
typst::text::SmartQuoteElem,
|
||||
>())))),
|
||||
|
||||
Strong(strong) => {
|
||||
let body = self.check_inline_markup(strong.body());
|
||||
|
@ -407,8 +429,13 @@ impl ExprWorker<'_> {
|
|||
self.check_element::<TermsElem>(eco_vec![term, description])
|
||||
}
|
||||
|
||||
MathAlignPoint(..) => Expr::Type(Ty::Builtin(BuiltinTy::Content)),
|
||||
MathShorthand(..) => Expr::Type(Ty::Builtin(BuiltinTy::Content)),
|
||||
MathAlignPoint(..) => Expr::Type(Ty::Builtin(BuiltinTy::Content(Some(Element::of::<
|
||||
typst::math::AlignPointElem,
|
||||
>(
|
||||
))))),
|
||||
MathShorthand(..) => Expr::Type(Ty::Builtin(BuiltinTy::Type(Type::of::<
|
||||
typst::foundations::Symbol,
|
||||
>()))),
|
||||
MathDelimited(math_delimited) => {
|
||||
self.check_math(math_delimited.body().to_untyped().children())
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ impl Ty {
|
|||
pub(crate) fn from_return_site(func: &Func, ty: &'_ CastInfo) -> Self {
|
||||
use typst::foundations::func::Repr;
|
||||
match func.inner() {
|
||||
Repr::Element(elem) => return Ty::Builtin(BuiltinTy::Element(*elem)),
|
||||
Repr::Element(elem) => return Ty::Builtin(BuiltinTy::Content(Some(*elem))),
|
||||
Repr::Closure(_) | Repr::Plugin(_) => {}
|
||||
Repr::With(w) => return Ty::from_return_site(&w.0, ty),
|
||||
Repr::Native(_) => {}
|
||||
|
@ -208,7 +208,6 @@ impl TryFrom<FileId> for PackageId {
|
|||
pub enum BuiltinTy {
|
||||
Clause,
|
||||
Undef,
|
||||
Content,
|
||||
Space,
|
||||
None,
|
||||
Break,
|
||||
|
@ -239,9 +238,16 @@ pub enum BuiltinTy {
|
|||
Radius,
|
||||
|
||||
Tag(Box<(StrRef, Option<Interned<PackageId>>)>),
|
||||
|
||||
/// A value having a specific type.
|
||||
Type(typst::foundations::Type),
|
||||
/// A value of some type.
|
||||
TypeType(typst::foundations::Type),
|
||||
/// A content having a specific element type.
|
||||
Content(Option<typst::foundations::Element>),
|
||||
/// A value of some element type.
|
||||
Element(typst::foundations::Element),
|
||||
|
||||
Module(Interned<Decl>),
|
||||
Path(PathPreference),
|
||||
}
|
||||
|
@ -251,7 +257,13 @@ impl fmt::Debug for BuiltinTy {
|
|||
match self {
|
||||
BuiltinTy::Clause => f.write_str("Clause"),
|
||||
BuiltinTy::Undef => f.write_str("Undef"),
|
||||
BuiltinTy::Content => f.write_str("Content"),
|
||||
BuiltinTy::Content(ty) => {
|
||||
if let Some(ty) = ty {
|
||||
write!(f, "Content({})", ty.name())
|
||||
} else {
|
||||
f.write_str("Content")
|
||||
}
|
||||
}
|
||||
BuiltinTy::Space => f.write_str("Space"),
|
||||
BuiltinTy::None => f.write_str("None"),
|
||||
BuiltinTy::Break => f.write_str("Break"),
|
||||
|
@ -324,7 +336,7 @@ impl BuiltinTy {
|
|||
return Length.literally();
|
||||
}
|
||||
if builtin == Type::of::<Content>() {
|
||||
return Ty::Builtin(BuiltinTy::Content);
|
||||
return Ty::Builtin(BuiltinTy::Content(Option::None));
|
||||
}
|
||||
|
||||
BuiltinTy::Type(builtin).literally()
|
||||
|
@ -334,7 +346,13 @@ impl BuiltinTy {
|
|||
let res = match self {
|
||||
BuiltinTy::Clause => "any",
|
||||
BuiltinTy::Undef => "any",
|
||||
BuiltinTy::Content => "content",
|
||||
BuiltinTy::Content(ty) => {
|
||||
return if let Some(ty) = ty {
|
||||
eco_format!("content({})", ty.name())
|
||||
} else {
|
||||
"content".into()
|
||||
};
|
||||
}
|
||||
BuiltinTy::Space => "content",
|
||||
BuiltinTy::None => "none",
|
||||
BuiltinTy::Break => "break",
|
||||
|
|
|
@ -220,7 +220,7 @@ impl Ty {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get the type of the type
|
||||
/// Get as element type
|
||||
pub fn element(&self) -> Option<Element> {
|
||||
match self {
|
||||
Ty::Value(ins_ty) => match &ins_ty.val {
|
||||
|
@ -242,7 +242,7 @@ impl Ty {
|
|||
res = res || {
|
||||
match ty {
|
||||
Ty::Value(v) => is_content_builtin_type(&v.val.ty()),
|
||||
Ty::Builtin(BuiltinTy::Content | BuiltinTy::Element(..)) => true,
|
||||
Ty::Builtin(BuiltinTy::Content(..)) => true,
|
||||
Ty::Builtin(BuiltinTy::Type(v)) => is_content_builtin_type(v),
|
||||
_ => false,
|
||||
}
|
||||
|
|
|
@ -170,7 +170,10 @@ impl TypeDescriber {
|
|||
Ty::With(w) => {
|
||||
return self.describe(&w.sig);
|
||||
}
|
||||
Ty::Builtin(BuiltinTy::Content | BuiltinTy::Space) => {
|
||||
Ty::Builtin(BuiltinTy::Content(Some(elem))) => {
|
||||
return elem.name().into();
|
||||
}
|
||||
Ty::Builtin(BuiltinTy::Content(None) | BuiltinTy::Space) => {
|
||||
return "content".into();
|
||||
}
|
||||
// Doesn't provide any information, hence we doesn't describe it intermediately here.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use typst::foundations::{Dict, Module, Scope, Type};
|
||||
use typst::foundations::{Dict, Func, Module, Scope, Type};
|
||||
use typst::syntax::FileId;
|
||||
|
||||
use super::BoundChecker;
|
||||
|
@ -9,7 +9,7 @@ pub enum Iface<'a> {
|
|||
Array(&'a Interned<Ty>),
|
||||
Tuple(&'a Interned<Vec<Ty>>),
|
||||
Dict(&'a Interned<RecordTy>),
|
||||
Element {
|
||||
Content {
|
||||
val: &'a typst::foundations::Element,
|
||||
at: &'a Ty,
|
||||
},
|
||||
|
@ -45,7 +45,7 @@ impl Iface<'_> {
|
|||
Iface::Array(ty) => Ty::Array(ty.clone()),
|
||||
Iface::Tuple(tys) => Ty::Tuple(tys.clone()),
|
||||
Iface::Dict(dict) => Ty::Dict(dict.clone()),
|
||||
Iface::Element { at, .. }
|
||||
Iface::Content { at, .. }
|
||||
| Iface::TypeType { at, .. }
|
||||
| Iface::Type { at, .. }
|
||||
| Iface::Func { at, .. }
|
||||
|
@ -62,7 +62,7 @@ impl Iface<'_> {
|
|||
match self {
|
||||
Iface::Array(..) | Iface::Tuple(..) => None,
|
||||
Iface::Dict(dict) => dict.field_by_name(key).cloned(),
|
||||
Iface::Element { val, .. } => select_scope(Some(val.scope()), key),
|
||||
Iface::Content { val, .. } => select_scope(Some(val.scope()), key),
|
||||
// todo: distinguish TypeType and Type
|
||||
Iface::TypeType { val, .. } | Iface::Type { val, .. } => {
|
||||
select_scope(Some(val.scope()), key)
|
||||
|
@ -196,7 +196,11 @@ impl IfaceCheckDriver<'_> {
|
|||
}
|
||||
}
|
||||
// todo: more builtin types to check
|
||||
Ty::Builtin(BuiltinTy::Content) if self.value_as_iface() => {
|
||||
Ty::Builtin(BuiltinTy::Content(Some(elem))) if self.value_as_iface() => {
|
||||
self.checker
|
||||
.check(Iface::Content { val: elem, at }, &mut self.ctx, pol);
|
||||
}
|
||||
Ty::Builtin(BuiltinTy::Content(..)) if self.value_as_iface() => {
|
||||
let ty = Type::of::<typst::foundations::Content>();
|
||||
self.checker
|
||||
.check(Iface::Type { val: &ty, at }, &mut self.ctx, pol);
|
||||
|
@ -207,8 +211,14 @@ impl IfaceCheckDriver<'_> {
|
|||
.check(Iface::Type { val: ty, at }, &mut self.ctx, pol);
|
||||
}
|
||||
Ty::Builtin(BuiltinTy::Element(elem)) if self.value_as_iface() => {
|
||||
self.checker
|
||||
.check(Iface::Element { val: elem, at }, &mut self.ctx, pol);
|
||||
self.checker.check(
|
||||
Iface::Func {
|
||||
val: &Func::from(*elem),
|
||||
at,
|
||||
},
|
||||
&mut self.ctx,
|
||||
pol,
|
||||
);
|
||||
}
|
||||
Ty::Builtin(BuiltinTy::Module(module)) => {
|
||||
if let Decl::Module(m) = module.as_ref() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue