From 3382633b1fbe3aee4d1a0f506a4c6b75c71aa65b Mon Sep 17 00:00:00 2001 From: Myriad-Dreamin <35292584+Myriad-Dreamin@users.noreply.github.com> Date: Sat, 19 Oct 2024 14:39:26 +0800 Subject: [PATCH] feat: adjust new sink api (#594) * dev: delete eval crate * dev: adjust new sink api --- benches/lowering/src/lowering.rs | 1 + cli/src/query_repl.rs | 4 +- crates/reflexo-typst/src/compile.rs | 21 +--- crates/reflexo-typst/src/diag/console.rs | 2 +- crates/reflexo-typst/src/driver.rs | 4 +- crates/reflexo-typst/src/eval.rs | 31 ------ crates/reflexo-typst/src/export.rs | 35 +++---- .../src/export/dynamic_layout.rs | 16 ++- crates/reflexo-typst/src/lib.rs | 98 +++++++++++-------- fuzzers/incremental/src/main.rs | 2 +- packages/compiler/src/lib.rs | 11 ++- packages/typst.node/src/compiler/boxed.rs | 6 +- packages/typst.node/src/error.rs | 13 ++- tests/incremental/src/main.rs | 4 +- 14 files changed, 118 insertions(+), 130 deletions(-) delete mode 100644 crates/reflexo-typst/src/eval.rs diff --git a/benches/lowering/src/lowering.rs b/benches/lowering/src/lowering.rs index d87af519..08aca335 100644 --- a/benches/lowering/src/lowering.rs +++ b/benches/lowering/src/lowering.rs @@ -32,6 +32,7 @@ fn compile(driver: &CompileDriver, src: &str) -> Arc { std::marker::PhantomData.compile(&this.snapshot(), &mut Default::default()) }) .unwrap() + .output } fn main() { diff --git a/cli/src/query_repl.rs b/cli/src/query_repl.rs index dd0f9676..03ba5a6c 100644 --- a/cli/src/query_repl.rs +++ b/cli/src/query_repl.rs @@ -134,7 +134,7 @@ impl Completer for ReplContext { Ok(autocomplete( &world, - doc.as_ref().map(|f| f.as_ref()), + doc.as_ref().map(|f| f.output.as_ref()), &main, cursor, true, @@ -256,7 +256,7 @@ impl ReplContext { .ok(); doc.and_then(|doc| { driver - .query(line, &doc) + .query(line, &doc.output) .map_err(|err| self.process_err(&driver, err)) .ok() }) diff --git a/crates/reflexo-typst/src/compile.rs b/crates/reflexo-typst/src/compile.rs index 470dbcd3..681243a9 100644 --- a/crates/reflexo-typst/src/compile.rs +++ b/crates/reflexo-typst/src/compile.rs @@ -320,14 +320,11 @@ impl CompileActor { fn snapshot(&self, is_once: bool, reason: CompileReasons) -> CompileSnapshot { let world = self.verse.snapshot(); - let mut env = self.make_env(if is_once { + let env = self.make_env(if is_once { self.once_feature_set.clone() } else { self.watch_feature_set.clone() }); - if env.sink.is_none() { - env.sink = Some(Default::default()); - } CompileSnapshot { world: Arc::new(world.clone()), env: env.clone(), @@ -397,19 +394,9 @@ impl CompileActor { } let elapsed = start.elapsed().unwrap_or_default(); - let rep; - match &compiled.doc { - Ok(..) => { - let warnings = compiled.env.sink.as_ref().unwrap().clone().warnings(); - if warnings.is_empty() { - rep = CompileReport::CompileSuccess(id, warnings, elapsed); - } else { - rep = CompileReport::CompileWarning(id, warnings, elapsed); - } - } - Err(err) => { - rep = CompileReport::CompileError(id, err.clone(), elapsed); - } + let rep = match &compiled.doc { + Ok(..) => CompileReport::CompileSuccess(id, compiled.warnings.clone(), elapsed), + Err(err) => CompileReport::CompileError(id, err.clone(), elapsed), }; let _ = ConsoleDiagReporter::default().export( diff --git a/crates/reflexo-typst/src/diag/console.rs b/crates/reflexo-typst/src/diag/console.rs index 5942ccd8..d483a5b3 100644 --- a/crates/reflexo-typst/src/diag/console.rs +++ b/crates/reflexo-typst/src/diag/console.rs @@ -137,7 +137,7 @@ where // todo: log in browser compiler #[cfg(feature = "system-compile")] if _err.is_err() { - log::error!("failed to print diagnostics: {:?}", _err); + log::error!("failed to print diagnostics: {_err:?}"); } } diff --git a/crates/reflexo-typst/src/driver.rs b/crates/reflexo-typst/src/driver.rs index 7f87b9b2..cdd96d1e 100644 --- a/crates/reflexo-typst/src/driver.rs +++ b/crates/reflexo-typst/src/driver.rs @@ -5,7 +5,7 @@ use std::{ use reflexo_world::DETACHED_ENTRY; use typst::{ - diag::{eco_format, EcoString, SourceResult}, + diag::{eco_format, EcoString, SourceResult, Warned}, foundations::Content, }; @@ -47,7 +47,7 @@ impl>> CompileDriverImpl self.compiler.query(&self.snapshot(), selector, document) } - pub fn compile(&mut self, env: &mut CompileEnv) -> SourceResult> { + pub fn compile(&mut self, env: &mut CompileEnv) -> SourceResult>> { let world = self.snapshot(); self.compiler.ensure_main(&world)?; self.compiler.compile(&world, env) diff --git a/crates/reflexo-typst/src/eval.rs b/crates/reflexo-typst/src/eval.rs deleted file mode 100644 index b968fe51..00000000 --- a/crates/reflexo-typst/src/eval.rs +++ /dev/null @@ -1,31 +0,0 @@ -use comemo::Track; -use typst::{ - diag::{At, SourceResult}, - engine::{Route, Sink, Traced}, - foundations::Module, - syntax::Span, - World, -}; - -/// Compile a source file into a module. -/// -/// - 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. -pub fn evaluate(world: &dyn World, sink: &mut Sink) -> SourceResult { - let route = Route::default(); - - // Call `track` just once to keep comemo's ID stable. - let sink = sink.track_mut(); - - // Try to evaluate the source file into a module. - let traced = Traced::default(); - let world = world.track(); - let main = world.main(); - let main = world.source(main).at(Span::detached())?; - - typst::eval::eval(world, traced.track(), sink, route.track(), &main) -} diff --git a/crates/reflexo-typst/src/export.rs b/crates/reflexo-typst/src/export.rs index bb3bc418..47a16078 100644 --- a/crates/reflexo-typst/src/export.rs +++ b/crates/reflexo-typst/src/export.rs @@ -2,7 +2,10 @@ use std::sync::Arc; use reflexo_typst2vec::pass::Typst2VecPass; use reflexo_world::{CompilerFeat, CompilerWorld}; -use typst::{diag::SourceResult, World}; +use typst::{ + diag::{SourceResult, Warned}, + World, +}; use crate::{ vector::ir::{LayoutRegion, LayoutRegionNode}, @@ -103,9 +106,13 @@ impl CompileMiddleware for CompileExporter { &mut self.compiler } - fn wrap_compile(&mut self, world: &C::W, env: &mut CompileEnv) -> SourceResult> { + fn wrap_compile( + &mut self, + world: &C::W, + env: &mut CompileEnv, + ) -> SourceResult>> { let doc = self.inner_mut().compile(world, env)?; - self.exporter.export(world, doc.clone())?; + self.exporter.export(world, doc.output.clone())?; Ok(doc) } @@ -198,7 +205,11 @@ where &mut self.compiler } - fn wrap_compile(&mut self, world: &C::W, env: &mut CompileEnv) -> SourceResult> { + fn wrap_compile( + &mut self, + world: &C::W, + env: &mut CompileEnv, + ) -> SourceResult>> { let start = reflexo::time::now(); // todo unwrap main id let id = world.main_id().unwrap(); @@ -209,11 +220,6 @@ where let _ = self.reporter.export(world, rep); } - let sink = env.sink.take(); - let origin = sink.is_some(); - - env.sink = Some(sink.unwrap_or_default()); - let doc = self.inner_mut().compile(world, env); let elapsed = start.elapsed().unwrap_or_default(); @@ -222,12 +228,7 @@ where let doc = match doc { Ok(doc) => { - let warnings = env.sink.as_ref().unwrap().clone().warnings(); - if warnings.is_empty() { - rep = CompileReport::CompileSuccess(id, warnings, elapsed); - } else { - rep = CompileReport::CompileWarning(id, warnings, elapsed); - } + rep = CompileReport::CompileSuccess(id, doc.warnings.clone(), elapsed); Ok(doc) } @@ -237,10 +238,6 @@ where } }; - if !origin { - env.sink = None; - } - let rep = Arc::new((env.features.clone(), rep)); // we currently ignore export error here let _ = self.reporter.export(world, rep); diff --git a/crates/reflexo-typst/src/export/dynamic_layout.rs b/crates/reflexo-typst/src/export/dynamic_layout.rs index 9d471d8c..ef7be9a6 100644 --- a/crates/reflexo-typst/src/export/dynamic_layout.rs +++ b/crates/reflexo-typst/src/export/dynamic_layout.rs @@ -4,6 +4,7 @@ use reflexo_typst2vec::pass::{CommandExecutor, Typst2VecPass}; use reflexo_typst2vec::IntoTypst; use reflexo_vec2svg::{DynamicLayoutSvgExporter, MultiVecDocument}; use reflexo_world::TaskInputs; +use typst::diag::Warned; use typst::foundations::IntoValue; use typst::utils::LazyHash; use typst::{diag::SourceResult, World}; @@ -148,7 +149,7 @@ impl>> DynamicLayoutCompiler, env: &mut CompileEnv, - ) -> SourceResult<(Arc, MultiVecDocument)> { + ) -> SourceResult<(Warned>, MultiVecDocument)> { let mut svg_exporter = DynamicLayoutSvgExporter::default(); svg_exporter.typst2vec.command_executor = self.command_executor.clone(); self.do_export_with(world, env, svg_exporter) @@ -160,7 +161,7 @@ impl>> DynamicLayoutCompiler, env: &mut CompileEnv, mut svg_exporter: reflexo_vec2svg::DynamicLayoutSvgExporter, - ) -> SourceResult<(Arc, MultiVecDocument)> { + ) -> SourceResult<(Warned>, MultiVecDocument)> { // self.export(doc.clone())?; // checkout the entry file @@ -191,10 +192,11 @@ impl>> DynamicLayoutCompiler>> Compiler for DynamicLay Ok(()) } - fn compile(&mut self, world: &Self::W, env: &mut CompileEnv) -> SourceResult> { + fn compile( + &mut self, + world: &Self::W, + env: &mut CompileEnv, + ) -> SourceResult>> { let (res, doc) = self.do_export(world, env)?; std::fs::write(self.module_dest_path(), doc.to_bytes()).unwrap(); Ok(res) diff --git a/crates/reflexo-typst/src/lib.rs b/crates/reflexo-typst/src/lib.rs index e72e16ce..092ac9f8 100644 --- a/crates/reflexo-typst/src/lib.rs +++ b/crates/reflexo-typst/src/lib.rs @@ -45,7 +45,7 @@ pub use exporter::ast::{dump_ast, AstExporter}; pub use exporter::json::JsonExporter; -use ::typst::engine::Sink; +use ::typst::diag::Warned; #[cfg(feature = "pdf")] pub use exporter::pdf::PdfDocExporter; #[cfg(feature = "pdf")] @@ -84,7 +84,6 @@ pub mod program_meta { pub mod diag; mod driver; -pub mod eval; mod export; pub mod features; pub mod query; @@ -132,7 +131,7 @@ use std::sync::OnceLock; use crate::typst::prelude::*; use ::typst::{ - diag::{At, Hint, SourceDiagnostic, SourceResult}, + diag::{At, SourceDiagnostic, SourceResult}, foundations::Content, model::Document, syntax::Span, @@ -142,7 +141,6 @@ use ::typst::{ #[derive(Clone, Default)] pub struct CompileEnv { - pub sink: Option, pub features: Arc, } @@ -172,13 +170,9 @@ pub enum CompileReport { EcoVec, reflexo::time::Duration, ), - CompileWarning( - TypstFileId, - EcoVec, - reflexo::time::Duration, - ), CompileSuccess( TypstFileId, + // warnings, if not empty EcoVec, reflexo::time::Duration, ), @@ -191,7 +185,6 @@ impl CompileReport { Self::Stage(id, ..) | Self::CompileError(id, ..) | Self::ExportError(id, ..) - | Self::CompileWarning(id, ..) | Self::CompileSuccess(id, ..) => *id, }) } @@ -201,7 +194,6 @@ impl CompileReport { Self::Suspend | Self::Stage(..) => None, Self::CompileError(_, _, dur) | Self::ExportError(_, _, dur) - | Self::CompileWarning(_, _, dur) | Self::CompileSuccess(_, _, dur) => Some(*dur), } } @@ -211,7 +203,6 @@ impl CompileReport { Self::Suspend | Self::Stage(..) => None, Self::CompileError(_, diagnostics, ..) | Self::ExportError(_, diagnostics, ..) - | Self::CompileWarning(_, diagnostics, ..) | Self::CompileSuccess(_, diagnostics, ..) => Some(diagnostics), } } @@ -232,8 +223,16 @@ impl<'a> fmt::Display for CompileReportMsg<'a> { match self.0 { Suspend => write!(f, "suspended"), Stage(_, stage, ..) => write!(f, "{:?}: {} ...", input, stage), - CompileSuccess(_, _, duration) | CompileWarning(_, _, duration) => { - write!(f, "{:?}: compilation succeeded in {:?}", input, duration) + CompileSuccess(_, warnings, duration) => { + if warnings.is_empty() { + write!(f, "{input:?}: compilation succeeded in {duration:?}") + } else { + write!( + f, + "{input:?}: compilation succeeded with {} warnings in {duration:?}", + warnings.len() + ) + } } CompileError(_, _, duration) | ExportError(_, _, duration) => { write!(f, "{:?}: compilation failed after {:?}", input, duration) @@ -242,7 +241,7 @@ impl<'a> fmt::Display for CompileReportMsg<'a> { } } -type CompileRawResult = Deferred<(SourceResult>, CompileEnv)>; +type CompileRawResult = Deferred<(SourceResult>>, CompileEnv)>; type DocState = std::sync::OnceLock; /// A signal that possibly triggers an export. @@ -280,7 +279,7 @@ impl CompileSnapshot { Deferred::new(move || { let w = w.as_ref(); let mut c = std::marker::PhantomData; - let res = c.ensure_main(w).and_then(|_| c.compile(w, &mut env)); + let res = c.compile(w, &mut env); (res, env) }) }) @@ -310,11 +309,16 @@ impl CompileSnapshot { pub fn compile(&self) -> CompiledArtifact { let (doc, env) = self.start().wait().clone(); + let (doc, warnings) = match doc { + Ok(doc) => (Ok(doc.output), doc.warnings), + Err(err) => (Err(err), EcoVec::default()), + }; CompiledArtifact { signal: self.flags, world: self.world.clone(), env, doc, + warnings, success_doc: self.success_doc.clone(), } } @@ -339,7 +343,11 @@ pub struct CompiledArtifact { pub world: Arc>, /// Used env pub env: CompileEnv, + /// The diagnostics of the document. + pub warnings: EcoVec, + /// The compiled document. pub doc: SourceResult>, + /// The last successfully compiled document. success_doc: Option>, } @@ -350,6 +358,7 @@ impl Clone for CompiledArtifact { world: self.world.clone(), env: self.env.clone(), doc: self.doc.clone(), + warnings: self.warnings.clone(), success_doc: self.success_doc.clone(), } } @@ -385,34 +394,37 @@ pub trait Compiler { where Self::W: EntryReader, { - let main_id = world - .main_id() - .ok_or_else(|| eco_format!("no entry file")) - .at(Span::detached())?; - - world - .source(main_id) - .hint(AtFile(main_id)) - .at(Span::detached())?; - - Ok(()) + let check_main = world.main_id().ok_or_else(|| eco_format!("no entry file")); + check_main.at(Span::detached()).map(|_| ()) } /// Compile once from scratch. fn pure_compile( &mut self, world: &Self::W, - env: &mut CompileEnv, - ) -> SourceResult> { + _env: &mut CompileEnv, + ) -> SourceResult>> { self.reset()?; - let res = match env.sink.as_mut() { - Some(_sink) => ::typst::compile(world), - None => ::typst::compile(world), - }; - + let res = ::typst::compile(world); // compile document - res.output.map(Arc::new) + // res.output.map(Arc::new) + match res.output { + Ok(doc) => Ok(Warned { + output: Arc::new(doc), + warnings: res.warnings, + }), + Err(diags) => match (res.warnings.is_empty(), diags.is_empty()) { + (true, true) => Err(diags), + (true, false) => Err(diags), + (false, true) => Err(res.warnings), + (false, false) => { + let mut warnings = res.warnings; + warnings.extend(diags); + Err(warnings) + } + }, + } } /// With **the compilation state**, query the matches for the selector. @@ -426,7 +438,11 @@ pub trait Compiler { } /// Compile once from scratch. - fn compile(&mut self, world: &Self::W, env: &mut CompileEnv) -> SourceResult> { + fn compile( + &mut self, + world: &Self::W, + env: &mut CompileEnv, + ) -> SourceResult>> { self.pure_compile(world, env) } @@ -468,7 +484,7 @@ pub trait CompileMiddleware { &mut self, world: &<::Compiler as Compiler>::W, env: &mut CompileEnv, - ) -> SourceResult> { + ) -> SourceResult>> { self.inner_mut().compile(world, env) } @@ -500,7 +516,7 @@ impl Compiler for T { &mut self, world: &Self::W, env: &mut CompileEnv, - ) -> SourceResult> { + ) -> SourceResult>> { self.inner_mut().pure_compile(world, env) } @@ -515,7 +531,11 @@ impl Compiler for T { } #[inline] - fn compile(&mut self, world: &Self::W, env: &mut CompileEnv) -> SourceResult> { + fn compile( + &mut self, + world: &Self::W, + env: &mut CompileEnv, + ) -> SourceResult>> { self.wrap_compile(world, env) } diff --git a/fuzzers/incremental/src/main.rs b/fuzzers/incremental/src/main.rs index 67f38512..ca20048b 100644 --- a/fuzzers/incremental/src/main.rs +++ b/fuzzers/incremental/src/main.rs @@ -92,7 +92,7 @@ pub fn test_compiler( }) .unwrap(); - let delta = incr_server.pack_delta(doc); + let delta = incr_server.pack_delta(doc.output); let delta = BytesModuleStream::from_slice(&delta).checkout_owned(); incr_client.merge_delta(delta); incr_client.set_layout(incr_client.doc.layouts[0].unwrap_single()); diff --git a/packages/compiler/src/lib.rs b/packages/compiler/src/lib.rs index 209743d7..5250205b 100644 --- a/packages/compiler/src/lib.rs +++ b/packages/compiler/src/lib.rs @@ -312,8 +312,11 @@ impl TypstCompiler { &world, self.driver.compile(&mut Default::default()) ); - let artifact_bytes = - take_diag!(diagnostics_format, &world, vec_exporter.export(&world, doc)); + let artifact_bytes = take_diag!( + diagnostics_format, + &world, + vec_exporter.export(&world, doc.output) + ); let v: JsValue = Uint8Array::from(artifact_bytes.as_slice()).into(); @@ -343,7 +346,7 @@ impl TypstCompiler { .map_err(|e| format!("{e:?}"))?; let elements: Vec = self .driver - .query(selector, &doc) + .query(selector, &doc.output) .map_err(|e| format!("{e:?}"))?; let mapped: Vec<_> = elements @@ -393,7 +396,7 @@ impl TypstCompiler { self.driver.compile(&mut Default::default()) ); - let v = Uint8Array::from(state.update(doc).as_slice()).into(); + let v = Uint8Array::from(state.update(doc.output).as_slice()).into(); Ok(if diagnostics_format != 0 { let result = js_sys::Object::new(); js_sys::Reflect::set(&result, &"result".into(), &v)?; diff --git a/packages/typst.node/src/compiler/boxed.rs b/packages/typst.node/src/compiler/boxed.rs index 7a4f953f..2b9d2627 100644 --- a/packages/typst.node/src/compiler/boxed.rs +++ b/packages/typst.node/src/compiler/boxed.rs @@ -5,10 +5,10 @@ use std::{ sync::Arc, }; -use reflexo_typst::config::entry::MEMORY_MAIN_ENTRY; use reflexo_typst::error::{prelude::*, TypstSourceDiagnostic}; use reflexo_typst::foundations::Content; use reflexo_typst::typst::prelude::*; +use reflexo_typst::{config::entry::MEMORY_MAIN_ENTRY, typst::diag::Warned}; use reflexo_typst::{ error_once, Bytes, CompileDriver, CompileEnv, Compiler, EntryManager, EntryReader, PureCompiler, ShadowApi, TaskInputs, TypstDocument, TypstSystemWorld, @@ -144,7 +144,7 @@ impl Compiler for BoxedCompiler { &mut self, world: &TypstSystemWorld, env: &mut CompileEnv, - ) -> SourceResult> { + ) -> SourceResult>> { self.0.compiler.pure_compile(world, env) } @@ -163,7 +163,7 @@ impl Compiler for BoxedCompiler { &mut self, world: &TypstSystemWorld, env: &mut CompileEnv, - ) -> SourceResult> { + ) -> SourceResult>> { self.0.compiler.compile(world, env) } diff --git a/packages/typst.node/src/error.rs b/packages/typst.node/src/error.rs index 17b9b7e3..b3e557e4 100644 --- a/packages/typst.node/src/error.rs +++ b/packages/typst.node/src/error.rs @@ -3,6 +3,7 @@ use std::{cell::OnceCell, fmt::Write, sync::Arc}; use napi_derive::napi; use reflexo_typst::error::{long_diag_from_std, prelude::WithContext, TypstSourceDiagnostic}; +use reflexo_typst::typst::diag::Warned; use reflexo_typst::typst::prelude::*; use reflexo_typst::{TypstDocument, TypstWorld}; @@ -176,15 +177,19 @@ impl NodeTypstCompileResult { } } -impl From, E>> for NodeTypstCompileResult +impl From>, E>> for NodeTypstCompileResult where E: Into, { - fn from(res: Result, E>) -> Self { + fn from(res: Result>, E>) -> Self { match res { Ok(result) => NodeTypstCompileResult { - result: Some(NodeTypstDocument(result)), - error: None, + result: Some(NodeTypstDocument(result.output)), + error: if result.warnings.is_empty() { + None + } else { + Some(result.warnings.into()) + }, }, Err(e) => NodeTypstCompileResult { result: None, diff --git a/tests/incremental/src/main.rs b/tests/incremental/src/main.rs index c5d6c454..2cc4ca43 100644 --- a/tests/incremental/src/main.rs +++ b/tests/incremental/src/main.rs @@ -61,7 +61,7 @@ pub fn test_compiler( driver.compile(&mut Default::default()) }) .unwrap(); - let server_delta = incr_server.pack_delta(doc); + let server_delta = incr_server.pack_delta(doc.output); let server_delta = BytesModuleStream::from_slice(&server_delta).checkout_owned(); incr_client.merge_delta(server_delta); let _ = incr_svg_client.render_in_window(&mut incr_client, window); @@ -78,7 +78,7 @@ pub fn test_compiler( }) .unwrap(); - let server_delta = incr_server.pack_delta(doc); + let server_delta = incr_server.pack_delta(doc.output); let sd = server_delta.len(); let server_delta = BytesModuleStream::from_slice(&server_delta).checkout_owned(); incr_client.merge_delta(server_delta);