From 0e5c48ad0d04c22831e3b41c2904a24c7f5171cb Mon Sep 17 00:00:00 2001 From: Laurenz Date: Tue, 29 Aug 2023 17:59:56 +0200 Subject: [PATCH] Add a bit more docs to `compile` --- crates/typst-cli/src/compile.rs | 4 ++-- crates/typst-cli/src/query.rs | 2 +- crates/typst-docs/src/html.rs | 2 +- crates/typst/src/eval/mod.rs | 34 ++++++++++++++-------------- crates/typst/src/eval/tracer.rs | 39 +++++++++++++++++---------------- crates/typst/src/ide/analyze.rs | 5 +++-- crates/typst/src/ide/tooltip.rs | 2 +- crates/typst/src/lib.rs | 7 ++++++ crates/typst/src/model/mod.rs | 9 +++++++- tests/src/benches.rs | 8 +++---- tests/src/tests.rs | 5 ++--- 11 files changed, 66 insertions(+), 51 deletions(-) diff --git a/crates/typst-cli/src/compile.rs b/crates/typst-cli/src/compile.rs index 5ae569ba3..c4800171c 100644 --- a/crates/typst-cli/src/compile.rs +++ b/crates/typst-cli/src/compile.rs @@ -73,7 +73,7 @@ pub fn compile_once( world.reset(); world.source(world.main()).map_err(|err| err.to_string())?; - let mut tracer = Tracer::default(); + let mut tracer = Tracer::new(); let result = typst::compile(world, &mut tracer); let warnings = tracer.warnings(); @@ -218,7 +218,7 @@ pub fn print_diagnostics( config.display_style = term::DisplayStyle::Short; } - for diagnostic in warnings.iter().chain(errors.iter()) { + for diagnostic in warnings.iter().chain(errors) { let diag = match diagnostic.severity { Severity::Error => Diagnostic::error(), Severity::Warning => Diagnostic::warning(), diff --git a/crates/typst-cli/src/query.rs b/crates/typst-cli/src/query.rs index faf4e01b2..bf02f49d7 100644 --- a/crates/typst-cli/src/query.rs +++ b/crates/typst-cli/src/query.rs @@ -20,7 +20,7 @@ pub fn query(command: QueryCommand) -> StrResult<()> { world.reset(); world.source(world.main()).map_err(|err| err.to_string())?; - let mut tracer = Tracer::default(); + let mut tracer = Tracer::new(); let result = typst::compile(&world, &mut tracer); let warnings = tracer.warnings(); diff --git a/crates/typst-docs/src/html.rs b/crates/typst-docs/src/html.rs index 94f9e6102..bde69d89d 100644 --- a/crates/typst-docs/src/html.rs +++ b/crates/typst-docs/src/html.rs @@ -429,8 +429,8 @@ fn code_block(resolver: &dyn Resolver, lang: &str, text: &str) -> Html { let id = FileId::new(None, VirtualPath::new("main.typ")); let source = Source::new(id, compile); let world = DocWorld(source); - let mut tracer = Tracer::default(); + let mut tracer = Tracer::new(); let mut frames = match typst::compile(&world, &mut tracer) { Ok(doc) => doc.pages, Err(err) => { diff --git a/crates/typst/src/eval/mod.rs b/crates/typst/src/eval/mod.rs index b71669928..63eed5ac9 100644 --- a/crates/typst/src/eval/mod.rs +++ b/crates/typst/src/eval/mod.rs @@ -90,7 +90,7 @@ const MAX_CALL_DEPTH: usize = 64; /// Evaluate a source file and return the resulting module. #[comemo::memoize] -#[tracing::instrument(skip(world, route, tracer, source))] +#[tracing::instrument(skip_all)] pub fn eval( world: Tracked, route: Tracked, @@ -108,9 +108,9 @@ pub fn eval( set_lang_items(library.items.clone()); // Prepare VT. - let mut locator = Locator::default(); + let mut locator = Locator::new(); let introspector = Introspector::default(); - let mut delayed = DelayedErrors::default(); + let mut delayed = DelayedErrors::new(); let vt = Vt { world, introspector: introspector.track(), @@ -126,7 +126,7 @@ pub fn eval( let root = source.root(); let errors = root.errors(); - if !errors.is_empty() && vm.traced.is_none() { + if !errors.is_empty() && vm.inspected.is_none() { return Err(Box::new(errors.into_iter().map(Into::into).collect())); } @@ -175,9 +175,9 @@ pub fn eval_string( } // Prepare VT. - let mut tracer = Tracer::default(); - let mut locator = Locator::default(); - let mut delayed = DelayedErrors::default(); + let mut tracer = Tracer::new(); + let mut locator = Locator::new(); + let mut delayed = DelayedErrors::new(); let introspector = Introspector::default(); let vt = Vt { world, @@ -242,8 +242,8 @@ pub struct Vm<'a> { scopes: Scopes<'a>, /// The current call depth. depth: usize, - /// A span that is currently traced. - traced: Option, + /// A span that is currently under inspection. + inspected: Option, } impl<'a> Vm<'a> { @@ -254,7 +254,7 @@ impl<'a> Vm<'a> { file: Option, scopes: Scopes<'a>, ) -> Self { - let traced = file.and_then(|id| vt.tracer.span(id)); + let inspected = file.and_then(|id| vt.tracer.inspected(id)); let items = vt.world.library().items.clone(); Self { vt, @@ -264,7 +264,7 @@ impl<'a> Vm<'a> { flow: None, scopes, depth: 0, - traced, + inspected, } } @@ -294,8 +294,8 @@ impl<'a> Vm<'a> { #[tracing::instrument(skip_all)] pub fn define(&mut self, var: ast::Ident, value: impl IntoValue) { let value = value.into_value(); - if self.traced == Some(var.span()) { - self.vt.tracer.trace(value.clone()); + if self.inspected == Some(var.span()) { + self.vt.tracer.value(value.clone()); } self.scopes.top.define(var.get().clone(), value); } @@ -512,8 +512,8 @@ impl Eval for ast::Expr<'_> { }? .spanned(span); - if vm.traced == Some(span) { - vm.vt.tracer.trace(v.clone()); + if vm.inspected == Some(span) { + vm.vt.tracer.value(v.clone()); } Ok(v) @@ -1954,8 +1954,8 @@ impl Access for ast::Ident<'_> { fn access<'a>(self, vm: &'a mut Vm) -> SourceResult<&'a mut Value> { let span = self.span(); let value = vm.scopes.get_mut(&self).at(span)?; - if vm.traced == Some(span) { - vm.vt.tracer.trace(value.clone()); + if vm.inspected == Some(span) { + vm.vt.tracer.value(value.clone()); } Ok(value) } diff --git a/crates/typst/src/eval/tracer.rs b/crates/typst/src/eval/tracer.rs index 22e67fb1d..9507d838c 100644 --- a/crates/typst/src/eval/tracer.rs +++ b/crates/typst/src/eval/tracer.rs @@ -1,6 +1,6 @@ use std::collections::HashSet; -use ecow::{eco_vec, EcoVec}; +use ecow::EcoVec; use super::Value; use crate::diag::SourceDiagnostic; @@ -10,27 +10,28 @@ use crate::util::hash128; /// Traces warnings and which values existed for an expression at a span. #[derive(Default, Clone)] pub struct Tracer { - span: Option, + inspected: Option, values: EcoVec, warnings: EcoVec, warnings_set: HashSet, } impl Tracer { - /// The maximum number of traced items. - pub const MAX: usize = 10; + /// The maximum number of inspeted values. + pub const MAX_VALUES: usize = 10; - /// Create a new tracer, possibly with a span under inspection. - pub fn new(span: Option) -> Self { - Self { - span, - values: eco_vec![], - warnings: eco_vec![], - warnings_set: HashSet::new(), - } + /// Create a new tracer. + pub fn new() -> Self { + Self::default() } - /// Get the traced values. + /// Mark a span as inspected. All values observed for this span can be + /// retrieved via `values` later. + pub fn inspect(&mut self, span: Span) { + self.inspected = Some(span); + } + + /// Get the values for the inspeted span. pub fn values(self) -> EcoVec { self.values } @@ -43,18 +44,18 @@ impl Tracer { #[comemo::track] impl Tracer { - /// The traced span if it is part of the given source file. - pub fn span(&self, id: FileId) -> Option { - if self.span.and_then(Span::id) == Some(id) { - self.span + /// The inspeted span if it is part of the given source file. + pub fn inspected(&self, id: FileId) -> Option { + if self.inspected.and_then(Span::id) == Some(id) { + self.inspected } else { None } } /// Trace a value for the span. - pub fn trace(&mut self, v: Value) { - if self.values.len() < Self::MAX { + pub fn value(&mut self, v: Value) { + if self.values.len() < Self::MAX_VALUES { self.values.push(v); } } diff --git a/crates/typst/src/ide/analyze.rs b/crates/typst/src/ide/analyze.rs index 2e64069ef..1a545d24a 100644 --- a/crates/typst/src/ide/analyze.rs +++ b/crates/typst/src/ide/analyze.rs @@ -33,7 +33,8 @@ pub fn analyze_expr(world: &dyn World, node: &LinkedNode) -> EcoVec { } } - let mut tracer = Tracer::new(Some(node.span())); + let mut tracer = Tracer::new(); + tracer.inspect(node.span()); crate::compile(world, &mut tracer).ok(); tracer.values() } @@ -45,7 +46,7 @@ pub fn analyze_expr(world: &dyn World, node: &LinkedNode) -> EcoVec { /// Try to load a module from the current source file. pub fn analyze_import(world: &dyn World, source: &Source, path: &str) -> Option { let route = Route::default(); - let mut tracer = Tracer::default(); + let mut tracer = Tracer::new(); let id = source.id().join(path); let source = world.source(id).ok()?; eval(world.track(), route.track(), tracer.track_mut(), &source).ok() diff --git a/crates/typst/src/ide/tooltip.rs b/crates/typst/src/ide/tooltip.rs index 35125e921..4f2a345ee 100644 --- a/crates/typst/src/ide/tooltip.rs +++ b/crates/typst/src/ide/tooltip.rs @@ -73,7 +73,7 @@ fn expr_tooltip(world: &(dyn World + 'static), leaf: &LinkedNode) -> Option = vec![]; let mut iter = values.iter(); - for value in (&mut iter).take(Tracer::MAX - 1) { + for value in (&mut iter).take(Tracer::MAX_VALUES - 1) { if let Some((prev, count)) = &mut last { if *prev == value { *count += 1; diff --git a/crates/typst/src/lib.rs b/crates/typst/src/lib.rs index 8d7393a08..75ebe5be1 100644 --- a/crates/typst/src/lib.rs +++ b/crates/typst/src/lib.rs @@ -65,6 +65,13 @@ use crate::font::{Font, FontBook}; use crate::syntax::{FileId, PackageSpec, Source, Span}; /// Compile a source file into a fully layouted document. +/// +/// - Returns `Ok(document)` if there were no fatal errors. +/// - Returns `Err(errors)` if there were fatal errors. +/// +/// Requires a mutable reference to a tracer. Such a tracer can be created with +/// `Tracer::new()`. Independently of whether compilation succeeded, calling +/// `tracer.warnings()` after compilation will return all compiler warnings. #[tracing::instrument(skip_all)] pub fn compile(world: &dyn World, tracer: &mut Tracer) -> SourceResult { let route = Route::default(); diff --git a/crates/typst/src/model/mod.rs b/crates/typst/src/model/mod.rs index 9a0917844..0e7f99b1c 100644 --- a/crates/typst/src/model/mod.rs +++ b/crates/typst/src/model/mod.rs @@ -60,7 +60,7 @@ pub fn typeset( loop { tracing::info!("Layout iteration {iter}"); - delayed = DelayedErrors::default(); + delayed = DelayedErrors::new(); let constraint = ::Constraint::new(); let mut locator = Locator::new(); @@ -148,6 +148,13 @@ impl Vt<'_> { #[derive(Default, Clone)] pub struct DelayedErrors(Vec); +impl DelayedErrors { + /// Create an empty list of delayed errors. + pub fn new() -> Self { + Self::default() + } +} + #[comemo::track] impl DelayedErrors { /// Push a delayed error. diff --git a/tests/src/benches.rs b/tests/src/benches.rs index a100e24e3..8d74ca9c3 100644 --- a/tests/src/benches.rs +++ b/tests/src/benches.rs @@ -58,7 +58,7 @@ fn bench_edit(iai: &mut Iai) { fn bench_eval(iai: &mut Iai) { let world = BenchWorld::new(); let route = typst::eval::Route::default(); - let mut tracer = typst::eval::Tracer::default(); + let mut tracer = typst::eval::Tracer::new(); iai.run(|| { typst::eval::eval(world.track(), route.track(), tracer.track_mut(), &world.source) .unwrap() @@ -68,7 +68,7 @@ fn bench_eval(iai: &mut Iai) { fn bench_typeset(iai: &mut Iai) { let world = BenchWorld::new(); let route = typst::eval::Route::default(); - let mut tracer = typst::eval::Tracer::default(); + let mut tracer = typst::eval::Tracer::new(); let module = typst::eval::eval( world.track(), route.track(), @@ -82,13 +82,13 @@ fn bench_typeset(iai: &mut Iai) { fn bench_compile(iai: &mut Iai) { let world = BenchWorld::new(); - let mut tracer = Tracer::default(); + let mut tracer = Tracer::new(); iai.run(|| typst::compile(&world, &mut tracer)); } fn bench_render(iai: &mut Iai) { let world = BenchWorld::new(); - let mut tracer = Tracer::default(); + let mut tracer = Tracer::new(); let document = typst::compile(&world, &mut tracer).unwrap(); iai.run(|| typst::export::render(&document.pages[0], 1.0, Color::WHITE)) } diff --git a/tests/src/tests.rs b/tests/src/tests.rs index d5fe3b591..960aacd2e 100644 --- a/tests/src/tests.rs +++ b/tests/src/tests.rs @@ -526,15 +526,14 @@ fn test_part( if world.print.model { let world = (world as &dyn World).track(); let route = typst::eval::Route::default(); - let mut tracer = typst::eval::Tracer::default(); + let mut tracer = typst::eval::Tracer::new(); let module = typst::eval::eval(world, route.track(), tracer.track_mut(), &source).unwrap(); writeln!(output, "Model:\n{:#?}\n", module.content()).unwrap(); } - let mut tracer = Tracer::default(); - + let mut tracer = Tracer::new(); let (mut frames, diagnostics) = match typst::compile(world, &mut tracer) { Ok(document) => (document.pages, tracer.warnings()), Err(errors) => {