dev: refactor analysis structure (#674)

This commit is contained in:
Myriad-Dreamin 2024-10-14 14:04:24 +08:00 committed by GitHub
parent 6124ac2837
commit 242a9253c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 30 additions and 76 deletions

View file

@ -16,9 +16,11 @@ pub mod linked_def;
pub use linked_def::*;
pub mod signature;
pub use signature::*;
mod ty;
mod post_tyck;
mod tyck;
pub(crate) use crate::ty::*;
pub(crate) use ty::*;
pub(crate) use post_tyck::*;
pub(crate) use tyck::*;
pub mod track_values;
pub use track_values::*;
mod prelude;
@ -33,7 +35,7 @@ mod type_check_tests {
use typst::syntax::Source;
use crate::analysis::ty;
use crate::analysis::*;
use crate::tests::*;
use super::{Ty, TypeScheme};
@ -43,7 +45,7 @@ mod type_check_tests {
snapshot_testing("type_check", &|ctx, path| {
let source = ctx.source_by_path(&path).unwrap();
let result = ty::type_check(ctx, source.clone());
let result = type_check(ctx, source.clone());
let result = result
.as_deref()
.map(|e| format!("{:#?}", TypeCheckSnapshot(&source, e)));
@ -101,7 +103,7 @@ mod post_type_check_tests {
use typst::syntax::LinkedNode;
use typst_shim::syntax::LinkedNodeExt;
use crate::analysis::ty;
use crate::analysis::*;
use crate::tests::*;
#[test]
@ -116,8 +118,8 @@ mod post_type_check_tests {
let node = root.leaf_at_compat(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));
let result = type_check(ctx, source.clone());
let literal_type = result.and_then(|info| post_type_check(ctx, &info, node));
with_settings!({
description => format!("Check on {text:?} ({pos:?})"),
@ -137,7 +139,7 @@ mod type_describe_tests {
use typst::syntax::LinkedNode;
use typst_shim::syntax::LinkedNodeExt;
use crate::analysis::ty;
use crate::analysis::*;
use crate::tests::*;
#[test]
@ -152,8 +154,8 @@ mod type_describe_tests {
let node = root.leaf_at_compat(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));
let result = type_check(ctx, source.clone());
let literal_type = result.and_then(|info| post_type_check(ctx, &info, node));
with_settings!({
description => format!("Check on {text:?} ({pos:?})"),

View file

@ -69,7 +69,7 @@ impl Analysis {
self.caches.signatures.clear();
self.caches.static_signatures.clear();
self.caches.def_use.clear();
self.caches.type_ck.clear();
self.caches.type_check.clear();
}
}
@ -80,7 +80,7 @@ pub struct AnalysisGlobalCaches {
lifetime: AtomicU64,
clear_lifetime: AtomicU64,
def_use: FxDashMap<u128, (u64, Option<Arc<DefUseInfo>>)>,
type_ck: FxDashMap<u128, (u64, Option<Arc<TypeScheme>>)>,
type_check: FxDashMap<u128, (u64, Option<Arc<TypeScheme>>)>,
static_signatures: FxDashMap<u128, (u64, Source, usize, Signature)>,
signatures: FxDashMap<u128, (u64, foundations::Func, Signature)>,
}
@ -493,13 +493,13 @@ impl<'w> AnalysisContext<'w> {
let h = hash128(&(&source, &def_use));
let res = if let Some(res) = self.analysis.caches.type_ck.get(&h) {
let res = if let Some(res) = self.analysis.caches.type_check.get(&h) {
res.1.clone()
} else {
let res = crate::analysis::ty::type_check(self, source);
let res = crate::analysis::type_check(self, source);
self.analysis
.caches
.type_ck
.type_check
.insert(h, (self.lifetime, res.clone()));
res
};
@ -729,7 +729,7 @@ impl<'w> AnalysisContext<'w> {
.retain(|_, (l, _)| lifetime - *l < 60);
self.analysis
.caches
.type_ck
.type_check
.retain(|_, (l, _)| lifetime - *l < 60);
}
}

View file

@ -24,12 +24,10 @@ use super::{
};
mod apply;
mod post_check;
mod select;
mod syntax;
pub(crate) use apply::*;
pub(crate) use post_check::*;
pub(crate) use select::*;
/// Type checking at the source unit level.

View file

@ -11,29 +11,18 @@ static EMPTY_ARGS: LazyLock<Interned<ArgsTy>> = LazyLock::new(|| ArgsTy::default
impl Ty {
/// Call the given type with the given arguments.
pub fn call(&self, args: &Interned<ArgsTy>, pol: bool, checker: &mut impl ApplyChecker) {
self.apply(SigSurfaceKind::Call, args, pol, checker)
pub fn call(&self, args: &Interned<ArgsTy>, pol: bool, c: &mut impl ApplyChecker) {
ApplySigChecker(c, args).ty(self, SigSurfaceKind::Call, pol);
}
/// Get the tuple element type of the given type.
pub fn tuple_element_of(&self, pol: bool, checker: &mut impl ApplyChecker) {
self.apply(SigSurfaceKind::Array, &EMPTY_ARGS, pol, checker)
pub fn tuple_element_of(&self, pol: bool, c: &mut impl ApplyChecker) {
ApplySigChecker(c, &EMPTY_ARGS).ty(self, SigSurfaceKind::Array, pol);
}
/// Get the element type of the given type.
pub fn element_of(&self, pol: bool, checker: &mut impl ApplyChecker) {
self.apply(SigSurfaceKind::ArrayOrDict, &EMPTY_ARGS, pol, checker)
}
fn apply(
&self,
surface: SigSurfaceKind,
args: &Interned<ArgsTy>,
pol: bool,
checker: &mut impl ApplyChecker,
) {
let mut worker = ApplySigChecker(checker, args);
worker.ty(self, surface, pol);
pub fn element_of(&self, pol: bool, c: &mut impl ApplyChecker) {
ApplySigChecker(c, &EMPTY_ARGS).ty(self, SigSurfaceKind::ArrayOrDict, pol);
}
}

View file

@ -4,26 +4,6 @@ pub trait BoundChecker: TyCtx {
fn collect(&mut self, ty: &Ty, pol: bool);
}
impl<T> TyCtx for T
where
T: FnMut(&Ty, bool) -> Option<TypeBounds>,
{
fn local_bind_of(&self, _var: &Interned<TypeVar>) -> Option<Ty> {
None
}
fn global_bounds(&self, _var: &Interned<TypeVar>, _pol: bool) -> Option<TypeBounds> {
None
}
}
impl<T> BoundChecker for T
where
T: FnMut(&Ty, bool) -> Option<TypeBounds>,
{
fn collect(&mut self, ty: &Ty, pol: bool) {
self(ty, pol);
}
}
impl Ty {
/// Check if the given type has bounds (is combinated).
pub fn has_bounds(&self) -> bool {
@ -32,22 +12,16 @@ impl Ty {
/// Profile the bounds of the given type.
pub fn bounds(&self, pol: bool, checker: &mut impl BoundChecker) {
let mut worker = BoundCheckContext;
worker.ty(self, pol, checker);
BoundCheckContext.ty(self, pol, checker);
}
}
pub struct BoundCheckContext;
impl BoundCheckContext {
fn tys<'a>(
&mut self,
tys: impl Iterator<Item = &'a Ty>,
pol: bool,
checker: &mut impl BoundChecker,
) {
fn tys<'a>(&mut self, tys: impl Iterator<Item = &'a Ty>, pol: bool, c: &mut impl BoundChecker) {
for ty in tys {
self.ty(ty, pol, checker);
self.ty(ty, pol, c);
}
}

View file

@ -86,17 +86,13 @@ pub trait SigChecker: TyCtx {
impl Ty {
/// Iterate over the signatures of the given type.
pub fn sig_surface(&self, pol: bool, sig_kind: SigSurfaceKind, checker: &mut impl SigChecker) {
let context = SigCheckContext {
let ctx = SigCheckContext {
sig_kind,
args: Vec::new(),
at: TyRef::new(Ty::Any),
};
let mut worker = SigCheckDriver {
ctx: context,
checker,
};
worker.ty(self, pol);
SigCheckDriver { ctx, checker }.ty(self, pol);
}
/// Get the signature representation of the given type.

View file

@ -1,12 +1,7 @@
use crate::{analysis::*, ty::def::*};
impl<'a> Sig<'a> {
pub fn call(
&self,
args: &Interned<ArgsTy>,
pol: bool,
ctx: &mut impl TyCtxMut,
) -> Option<Ty> {
pub fn call(&self, args: &Interned<ArgsTy>, pol: bool, ctx: &mut impl TyCtxMut) -> Option<Ty> {
log::debug!("call {self:?} {args:?} {pol:?}");
ctx.with_scope(|ctx| {
let body = self.check_bind(args, ctx)?;