Add a bit more docs to compile
This commit is contained in:
parent
a71a2057f2
commit
0e5c48ad0d
@ -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(),
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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) => {
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user