add documentation generation for type signatures
This commit is contained in:
@@ -3,15 +3,15 @@
|
||||
inner
|
||||
}
|
||||
|
||||
#let type_primitive(id, name) = {
|
||||
(type: "primitive", type_id: id, type_name: name)
|
||||
#let type_primitive(id, name, cs_name) = {
|
||||
(type: "primitive", type_id: id, type_name: name, type_name_cs: cs_name)
|
||||
}
|
||||
|
||||
#let int = type_primitive("integer", "an 'integer'");
|
||||
#let float = type_primitive("float", "a 'float'");
|
||||
#let bool = type_primitive("boolean", "a 'boolean'");
|
||||
#let string = type_primitive("string", "a 'string'");
|
||||
#let content = type_primitive("content", "a 'content'");
|
||||
#let int = type_primitive("integer", "an 'integer'", "celé číslo");
|
||||
#let float = type_primitive("float", "a 'float'", "desetinné číslo");
|
||||
#let bool = type_primitive("boolean", "a 'boolean'", "pravdivostní hodnota");
|
||||
#let string = type_primitive("string", "a 'string'", "textový řetězec");
|
||||
#let content = type_primitive("content", "a 'content'", "obsah generovaný Typst syntaxí");
|
||||
|
||||
#let literal(value) = {
|
||||
(type: "literal", value: value)
|
||||
@@ -21,8 +21,8 @@
|
||||
(type: "variants", variants: variants.pos())
|
||||
}
|
||||
|
||||
#let list(items) = {
|
||||
(type: "list", items: items)
|
||||
#let slice(items) = {
|
||||
(type: "slice", items: items)
|
||||
}
|
||||
|
||||
#let tuple(..items) = {
|
||||
@@ -38,13 +38,23 @@
|
||||
}
|
||||
|
||||
#let struct(..keyvals) = {
|
||||
let copy_doc(from, to) = {
|
||||
if "doc" in from {
|
||||
let to = to;
|
||||
to.doc = from.doc;
|
||||
to
|
||||
} else {
|
||||
to
|
||||
}
|
||||
}
|
||||
|
||||
let keyvals = keyvals.pos();
|
||||
let res = ().to-dict();
|
||||
for keyval in keyvals {
|
||||
if keyval.key.type != "literal" {
|
||||
panic("invalid type signature, struct keys must be literals");
|
||||
}
|
||||
res.insert(keyval.key.value, keyval.val);
|
||||
res.insert(keyval.key.value, copy_doc(keyval, keyval.val));
|
||||
}
|
||||
(type: "struct", pairs: res)
|
||||
}
|
||||
@@ -80,7 +90,7 @@
|
||||
} else {
|
||||
res
|
||||
}
|
||||
} else if target.type == "list" or target.type == "tuple" {
|
||||
} else if target.type == "slice" or target.type == "tuple" {
|
||||
"an array"
|
||||
} else if target.type == "dictionary" or target.type == "struct" {
|
||||
"a dictionary/hashmap"
|
||||
@@ -93,8 +103,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
let error(target, name_prefix, value, is_value: false) = {
|
||||
error_target_name(target, name_prefix) + " " + if is_value {
|
||||
let error(target, name_prefix, value, is_value: false, target_doc: none) = {
|
||||
if type(target_doc) != type(none) {
|
||||
error_target_name(target_doc)
|
||||
} else {
|
||||
error_target_name(target, name_prefix)
|
||||
} + " " + if is_value {
|
||||
"is unexpected"
|
||||
} else {
|
||||
"has an unexpected type '" + error_value_name(value) + "'"
|
||||
@@ -128,7 +142,11 @@
|
||||
if target.type == "struct" {
|
||||
for key in target.pairs.keys() {
|
||||
if key not in value {
|
||||
return (false, name_prefix + " is missing an entry for key " + dbg_literal(key));
|
||||
return (false, (
|
||||
error_target_name(target, name_prefix) +
|
||||
" is missing an entry for key " +
|
||||
dbg_literal(key)
|
||||
));
|
||||
}
|
||||
}
|
||||
for (key, val) in value.pairs() {
|
||||
@@ -137,7 +155,9 @@
|
||||
false, name_prefix + " contains an unexpected key " + dbg_literal(key)
|
||||
);
|
||||
}
|
||||
matches_type(val, target.pairs.at(key), name_prefix: name_prefix + " " + str(key))
|
||||
matches_type(
|
||||
val, target.pairs.at(key), name_prefix: name_prefix + " " + str(key)
|
||||
)
|
||||
}
|
||||
} else if target.type == "dictionary" {
|
||||
for (key, val) in value.pairs() {
|
||||
@@ -145,7 +165,9 @@
|
||||
if not cur.at(0) {
|
||||
return cur;
|
||||
}
|
||||
let cur = matches_type(val, target.val, name_prefix: name_prefix + " value");
|
||||
let cur = matches_type(
|
||||
val, target.val, name_prefix: name_prefix + " value"
|
||||
);
|
||||
if not cur.at(0) {
|
||||
return cur;
|
||||
}
|
||||
@@ -155,7 +177,7 @@
|
||||
(false, error(target, name_prefix, value))
|
||||
}
|
||||
} else if type(value) == array {
|
||||
if target.type == "list" {
|
||||
if target.type == "slice" {
|
||||
for (idx, val) in value.enumerate() {
|
||||
let cur = matches_type(
|
||||
val, target.items, name_prefix: name_prefix + " item at index " + str(idx)
|
||||
@@ -192,3 +214,85 @@
|
||||
|
||||
matches_type(value, signature, name_prefix: name_prefix)
|
||||
}
|
||||
|
||||
#let signature_docs(target, is_nested: false) = {
|
||||
let typeinfo(target, flatten: false, disable_doc: false) = {
|
||||
let try_doc(target, mapper: (v) => { v }) = {
|
||||
if "doc" in target and not disable_doc {
|
||||
mapper(target.doc.expl);
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
if target.type == "struct" {
|
||||
if not flatten {
|
||||
[slovník s přesnými atributy (_dictionary_)];
|
||||
try_doc(target, mapper: (v) => { [ -- ]; v; });
|
||||
":";
|
||||
}
|
||||
list(
|
||||
..target.pairs.pairs().map(((key, val)) => {
|
||||
raw(key);
|
||||
try_doc(val, mapper: (v) => { [ -- ]; text(v); });
|
||||
": "
|
||||
typeinfo(val, disable_doc: true);
|
||||
})
|
||||
);
|
||||
} else if target.type == "dictionary" {
|
||||
[slovník (_dictionary_)];
|
||||
try_doc(target, mapper: (v) => { [ -- ]; v; });
|
||||
":";
|
||||
list(
|
||||
{
|
||||
"S klíči typu ";
|
||||
typeinfo(target.val);
|
||||
},
|
||||
{
|
||||
"S hodnotami typu ";
|
||||
typeinfo(target.key);
|
||||
},
|
||||
);
|
||||
} else if target.type == "slice" {
|
||||
|
||||
} else if target.type == "tuple" {
|
||||
|
||||
} else if target.type == "primitive" {
|
||||
text(target.type_name_cs + " (");
|
||||
text(target.type_id, style: "italic");
|
||||
text(")");
|
||||
try_doc(target, mapper: (v) => { [ -- ]; text(v); });
|
||||
} else if target.type == "variants" {
|
||||
list(
|
||||
..target.variants.map((v) => {
|
||||
list.item({
|
||||
typeinfo(v);
|
||||
});
|
||||
})
|
||||
);
|
||||
} else {
|
||||
panic();
|
||||
}
|
||||
}
|
||||
|
||||
let args = ();
|
||||
if target.type == "struct" {
|
||||
for val in target.pairs.values() {
|
||||
args.push(signature_docs(val, is_nested: true));
|
||||
}
|
||||
} else {
|
||||
if "doc" in target and type(target.doc.argname) != type(none) {
|
||||
args.push({
|
||||
raw(target.doc.argname);
|
||||
[: ]
|
||||
typeinfo(target, flatten: true)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if not is_nested {
|
||||
list(..args.flatten());
|
||||
} else {
|
||||
args.flatten()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user