Add a bit more docs to compile

This commit is contained in:
Laurenz 2023-08-29 17:59:56 +02:00
parent a71a2057f2
commit 0e5c48ad0d
11 changed files with 66 additions and 51 deletions

View File

@ -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(),

View File

@ -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();

View File

@ -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) => {

View File

@ -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<dyn World + '_>,
route: Tracked<Route>,
@ -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<Span>,
/// A span that is currently under inspection.
inspected: Option<Span>,
}
impl<'a> Vm<'a> {
@ -254,7 +254,7 @@ impl<'a> Vm<'a> {
file: Option<FileId>,
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)
}

View File

@ -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<Span>,
inspected: Option<Span>,
values: EcoVec<Value>,
warnings: EcoVec<SourceDiagnostic>,
warnings_set: HashSet<u128>,
}
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<Span>) -> 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<Value> {
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<Span> {
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<Span> {
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);
}
}

View File

@ -33,7 +33,8 @@ pub fn analyze_expr(world: &dyn World, node: &LinkedNode) -> EcoVec<Value> {
}
}
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<Value> {
/// Try to load a module from the current source file.
pub fn analyze_import(world: &dyn World, source: &Source, path: &str) -> Option<Module> {
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()

View File

@ -73,7 +73,7 @@ fn expr_tooltip(world: &(dyn World + 'static), leaf: &LinkedNode) -> Option<Tool
let mut last = None;
let mut pieces: Vec<EcoString> = 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;

View File

@ -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<Document> {
let route = Route::default();

View File

@ -60,7 +60,7 @@ pub fn typeset(
loop {
tracing::info!("Layout iteration {iter}");
delayed = DelayedErrors::default();
delayed = DelayedErrors::new();
let constraint = <Introspector as Validate>::Constraint::new();
let mut locator = Locator::new();
@ -148,6 +148,13 @@ impl Vt<'_> {
#[derive(Default, Clone)]
pub struct DelayedErrors(Vec<SourceDiagnostic>);
impl DelayedErrors {
/// Create an empty list of delayed errors.
pub fn new() -> Self {
Self::default()
}
}
#[comemo::track]
impl DelayedErrors {
/// Push a delayed error.

View File

@ -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))
}

View File

@ -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) => {