dev: improve join type (#249)

* dev: improve join type

* dev: update snapshot
This commit is contained in:
Myriad-Dreamin 2024-05-07 18:30:14 +08:00 committed by GitHub
parent 4fae99d767
commit c640d53396
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 78 additions and 13 deletions

View file

@ -91,7 +91,7 @@ mod type_check_tests {
}
#[cfg(test)]
mod literal_type_check_tests {
mod post_type_check_tests {
use insta::with_settings;
use typst::syntax::LinkedNode;
@ -125,6 +125,41 @@ mod literal_type_check_tests {
}
}
#[cfg(test)]
mod type_describe_tests {
use insta::with_settings;
use typst::syntax::LinkedNode;
use crate::analysis::ty;
use crate::tests::*;
#[test]
fn test() {
snapshot_testing("type_describe", &|ctx, path| {
let source = ctx.source_by_path(&path).unwrap();
let pos = ctx
.to_typst_pos(find_test_position(&source), &source)
.unwrap();
let root = LinkedNode::new(source.root());
let node = root.leaf_at(pos + 1).unwrap();
let text = node.get().clone().into_text();
let result = ty::type_check(ctx, source.clone());
let literal_type = result.and_then(|info| ty::post_type_check(ctx, &info, node));
with_settings!({
description => format!("Check on {text:?} ({pos:?})"),
}, {
let literal_type = literal_type.and_then(|e| e.describe())
.unwrap_or_else(|| "<nil>".to_string());
assert_snapshot!(literal_type);
})
});
}
}
#[cfg(test)]
mod module_tests {
use reflexo::path::unix_slash;

View file

@ -1268,7 +1268,7 @@ struct TypeCanoStore {
#[derive(Default)]
struct TypeDescriber {
described: HashSet<u128>,
described: HashMap<u128, String>,
results: HashSet<String>,
functions: Vec<FlowSignature>,
}
@ -1276,15 +1276,15 @@ struct TypeDescriber {
impl TypeDescriber {
fn describe_root(&mut self, ty: &FlowType) -> Option<String> {
// recursive structure
if self.described.contains(&hash128(ty)) {
return Some("$self".to_string());
if let Some(t) = self.described.get(&hash128(ty)) {
return Some(t.clone());
}
let res = self.describe(ty);
if !res.is_empty() {
return Some(res);
}
self.described.insert(hash128(ty));
self.described.insert(hash128(ty), "$self".to_string());
let mut results = std::mem::take(&mut self.results)
.into_iter()
@ -1330,18 +1330,23 @@ impl TypeDescriber {
}
if results.is_empty() {
self.described.insert(hash128(ty), "any".to_string());
return None;
}
results.sort();
results.dedup();
Some(results.join(" | "))
let res = results.join(" | ");
self.described.insert(hash128(ty), res.clone());
Some(res)
}
fn describe_iter(&mut self, ty: &[FlowType]) {
for ty in ty.iter() {
let desc = self.describe(ty);
self.results.insert(desc);
if !desc.is_empty() {
self.results.insert(desc);
}
}
}
@ -1375,9 +1380,8 @@ impl TypeDescriber {
FlowType::Content => {
return "content".to_string();
}
FlowType::Any => {
return "any".to_string();
}
// Doesn't provide any information, hence we doesn't describe it intermediately here.
FlowType::Any => {}
FlowType::Space => {}
FlowType::None => {
return "none".to_string();
@ -1746,9 +1750,13 @@ struct Joiner {
}
impl Joiner {
fn finalize(self) -> FlowType {
log::debug!("join: {:?} {:?}", self.possibles, self.definite);
if self.possibles.is_empty() {
return self.definite;
}
if self.possibles.len() == 1 {
return self.possibles.into_iter().next().unwrap();
}
// let mut definite = self.definite.clone();
// for p in &self.possibles {

View file

@ -7,7 +7,7 @@ input_file: crates/tinymist-query/src/fixtures/type_check/sig_template_set.typ
"class" = ( ⪰ "article" | "article" | "letter" | "article" | "letter")
"content" = Any
"font" = None
"tmpl" = (Any, authors: ( ⪯ (Type(string) | Type(array))), class: Any, font: ( ⪯ (TextFont | Array<TextFont>))) -> None
"tmpl" = (Any, authors: ( ⪯ (Type(string) | Type(array))), class: Any, font: ( ⪯ (TextFont | Array<TextFont>))) -> Any
---
5..9 -> @tmpl
10..17 -> @content

View file

@ -0,0 +1,7 @@
---
source: crates/tinymist-query/src/analysis.rs
description: "Check on \"tmpl\" (95)"
expression: literal_type
input_file: crates/tinymist-query/src/fixtures/type_describe/user_named.typ
---
(any, font: array | none | text.font) => any

View file

@ -0,0 +1,7 @@
---
source: crates/tinymist-query/src/analysis.rs
description: "Check on \"tmpl\" (95)"
expression: literal_type
input_file: crates/tinymist-query/src/fixtures/type_describe/user_named.typ
---
(any, font: array | none | text.font) => any

View file

@ -0,0 +1,7 @@
#let tmpl(content, font: none) = {
set text(font: font)
content
}
#(/* position after */ tmpl)

View file

@ -301,6 +301,7 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
None
}
})
.or_else(|| Some("any".into()))
};
let detail = if let CompletionKind::Symbol(c) = &kind {
Some(symbol_detail(*c))