mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-07-24 13:13:43 +00:00
dev: improve join type (#249)
* dev: improve join type * dev: update snapshot
This commit is contained in:
parent
4fae99d767
commit
c640d53396
8 changed files with 78 additions and 13 deletions
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
|||
#let tmpl(content, font: none) = {
|
||||
set text(font: font)
|
||||
|
||||
content
|
||||
}
|
||||
|
||||
#(/* position after */ tmpl)
|
|
@ -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))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue