From b102b42d2c252ceb618664e98a36ca37194f721f Mon Sep 17 00:00:00 2001 From: Myriad-Dreamin <35292584+Myriad-Dreamin@users.noreply.github.com> Date: Mon, 11 Aug 2025 08:49:37 +0800 Subject: [PATCH] feat: compile diag crate for wasm32 target (#2026) --- crates/tinymist-project/src/lock.rs | 3 + crates/tinymist-project/src/lock/system.rs | 4 +- crates/tinymist-project/src/world.rs | 2 +- crates/tinymist-query/src/docs/convert.rs | 2 +- crates/tinymist-world/src/diag.rs | 84 +++++++++++++++ crates/tinymist-world/src/lib.rs | 1 + crates/tinymist-world/src/system/diag.rs | 115 ++++++--------------- crates/typlite/src/parser/media.rs | 2 +- 8 files changed, 121 insertions(+), 92 deletions(-) create mode 100644 crates/tinymist-world/src/diag.rs diff --git a/crates/tinymist-project/src/lock.rs b/crates/tinymist-project/src/lock.rs index 3d1a6d67..0281d78c 100644 --- a/crates/tinymist-project/src/lock.rs +++ b/crates/tinymist-project/src/lock.rs @@ -1,3 +1,6 @@ +/// The default name of the lock file used by tinymist. +pub const LOCK_FILENAME: &str = "tinymist.lock"; + #[cfg(feature = "system")] mod system; #[cfg(feature = "system")] diff --git a/crates/tinymist-project/src/lock/system.rs b/crates/tinymist-project/src/lock/system.rs index a885234e..ad02f551 100644 --- a/crates/tinymist-project/src/lock/system.rs +++ b/crates/tinymist-project/src/lock/system.rs @@ -13,9 +13,7 @@ use typst::diag::EcoString; use typst::World; use crate::model::{ApplyProjectTask, Id, ProjectInput, ProjectRoute, ResourcePath}; -use crate::{LockFile, LockFileCompat, LspWorld, ProjectPathMaterial, LOCK_VERSION}; - -pub const LOCK_FILENAME: &str = "tinymist.lock"; +use crate::{LockFile, LockFileCompat, LspWorld, ProjectPathMaterial, LOCK_FILENAME, LOCK_VERSION}; impl LockFile { pub fn get_document(&self, id: &Id) -> Option<&ProjectInput> { diff --git a/crates/tinymist-project/src/world.rs b/crates/tinymist-project/src/world.rs index d40c392c..a5e67856 100644 --- a/crates/tinymist-project/src/world.rs +++ b/crates/tinymist-project/src/world.rs @@ -4,7 +4,7 @@ pub use tinymist_world as base; pub use tinymist_world::args::*; pub use tinymist_world::config::CompileFontOpts; pub use tinymist_world::entry::*; -pub use tinymist_world::{font, package, system, vfs}; +pub use tinymist_world::{diag, font, package, system, vfs}; pub use tinymist_world::{ with_main, CompilerUniverse, CompilerWorld, DiagnosticFormat, EntryOpts, EntryState, RevisingUniverse, SourceWorld, TaskInputs, diff --git a/crates/tinymist-query/src/docs/convert.rs b/crates/tinymist-query/src/docs/convert.rs index 35d85725..acd828dd 100644 --- a/crates/tinymist-query/src/docs/convert.rs +++ b/crates/tinymist-query/src/docs/convert.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use ecow::{eco_format, EcoString}; use tinymist_std::path::unix_slash; -use tinymist_world::system::print_diagnostics_to_string; +use tinymist_world::diag::print_diagnostics_to_string; use tinymist_world::vfs::WorkspaceResolver; use tinymist_world::{ DiagnosticFormat, EntryReader, EntryState, ShadowApi, SourceWorld, TaskInputs, diff --git a/crates/tinymist-world/src/diag.rs b/crates/tinymist-world/src/diag.rs new file mode 100644 index 00000000..098d218c --- /dev/null +++ b/crates/tinymist-world/src/diag.rs @@ -0,0 +1,84 @@ +use ecow::EcoString; + +use std::str::FromStr; + +use codespan_reporting::diagnostic::{Diagnostic, Label}; +use codespan_reporting::term; +use codespan_reporting::term::termcolor::{NoColor, WriteColor}; +use tinymist_std::Result; +use tinymist_vfs::FileId; +use typst::diag::{eco_format, Severity, SourceDiagnostic, StrResult}; +use typst::syntax::Span; + +use crate::{CodeSpanReportWorld, DiagnosticFormat, SourceWorld}; + +/// Prints diagnostic messages to the terminal. +pub fn print_diagnostics_to_string<'d, 'files>( + world: &'files dyn SourceWorld, + errors: impl Iterator, + diagnostic_format: DiagnosticFormat, +) -> StrResult { + let mut w = NoColor::new(vec![]); + + print_diagnostics_to(world, errors, &mut w, diagnostic_format) + .map_err(|e| eco_format!("failed to print diagnostics to string: {e}"))?; + let output = EcoString::from_str( + std::str::from_utf8(&w.into_inner()) + .map_err(|e| eco_format!("failed to convert diagnostics to string: {e}"))?, + ) + .unwrap_or_default(); + Ok(output) +} + +/// Prints diagnostic messages to the terminal. +pub fn print_diagnostics_to<'d, 'files>( + world: &'files dyn SourceWorld, + errors: impl Iterator, + w: &mut impl WriteColor, + diagnostic_format: DiagnosticFormat, +) -> Result<(), codespan_reporting::files::Error> { + let world = CodeSpanReportWorld::new(world); + + let mut config = term::Config { + tab_width: 2, + ..Default::default() + }; + if diagnostic_format == DiagnosticFormat::Short { + config.display_style = term::DisplayStyle::Short; + } + + for diagnostic in errors { + let diag = match diagnostic.severity { + Severity::Error => Diagnostic::error(), + Severity::Warning => Diagnostic::warning(), + } + .with_message(diagnostic.message.clone()) + .with_notes( + diagnostic + .hints + .iter() + .map(|e| (eco_format!("hint: {e}")).into()) + .collect(), + ) + .with_labels(label(world.world, diagnostic.span).into_iter().collect()); + + term::emit(w, &config, &world, &diag)?; + + // Stacktrace-like helper diagnostics. + for point in &diagnostic.trace { + let message = point.v.to_string(); + let help = Diagnostic::help() + .with_message(message) + .with_labels(label(world.world, point.span).into_iter().collect()); + + term::emit(w, &config, &world, &help)?; + } + } + + Ok(()) +} + +/// Creates a label for a span. +fn label(world: &dyn SourceWorld, span: Span) -> Option> { + Some(Label::primary(span.id()?, world.source_range(span)?)) +} diff --git a/crates/tinymist-world/src/lib.rs b/crates/tinymist-world/src/lib.rs index 9bb2a4d3..317111ef 100644 --- a/crates/tinymist-world/src/lib.rs +++ b/crates/tinymist-world/src/lib.rs @@ -5,6 +5,7 @@ pub mod args; pub mod config; pub mod debug_loc; +pub mod diag; pub mod entry; pub mod font; pub mod package; diff --git a/crates/tinymist-world/src/system/diag.rs b/crates/tinymist-world/src/system/diag.rs index 8eeb974c..c955473c 100644 --- a/crates/tinymist-world/src/system/diag.rs +++ b/crates/tinymist-world/src/system/diag.rs @@ -1,21 +1,35 @@ -use ecow::EcoString; - use std::io::IsTerminal; -use std::str::FromStr; -use codespan_reporting::term::termcolor::{ColorChoice, NoColor, StandardStream, WriteColor}; -use codespan_reporting::{ - diagnostic::{Diagnostic, Label}, - term, -}; +use codespan_reporting::term::termcolor::{ColorChoice, StandardStream, WriteColor}; + +use ecow::EcoString; use tinymist_std::Result; -use tinymist_vfs::FileId; -use typst::diag::{eco_format, Severity, SourceDiagnostic, StrResult}; -use typst::syntax::Span; +use typst::diag::{SourceDiagnostic, StrResult}; -use crate::{CodeSpanReportWorld, DiagnosticFormat, SourceWorld}; +use crate::{DiagnosticFormat, SourceWorld}; -/// Get stderr with color support if desirable. +/// Prints diagnostic messages to the terminal. +#[deprecated(note = "Use `diag` mod instead")] +pub fn print_diagnostics_to<'d, 'files>( + world: &'files dyn SourceWorld, + errors: impl Iterator, + w: &mut impl WriteColor, + diagnostic_format: DiagnosticFormat, +) -> Result<(), codespan_reporting::files::Error> { + crate::diag::print_diagnostics_to(world, errors, w, diagnostic_format) +} + +/// Prints diagnostic messages to the terminal. +#[deprecated(note = "Use `diag` mod instead")] +pub fn print_diagnostics_to_string<'d, 'files>( + world: &'files dyn SourceWorld, + errors: impl Iterator, + diagnostic_format: DiagnosticFormat, +) -> StrResult { + crate::diag::print_diagnostics_to_string(world, errors, diagnostic_format) +} + +/// Gets stderr with color support if desirable. fn color_stream() -> StandardStream { StandardStream::stderr(if std::io::stderr().is_terminal() { ColorChoice::Auto @@ -24,7 +38,7 @@ fn color_stream() -> StandardStream { }) } -/// Print diagnostic messages to the terminal. +/// Prints diagnostic messages to the terminal. pub fn print_diagnostics<'d, 'files>( world: &'files dyn SourceWorld, errors: impl Iterator, @@ -35,76 +49,5 @@ pub fn print_diagnostics<'d, 'files>( DiagnosticFormat::Short => StandardStream::stderr(ColorChoice::Never), }; - print_diagnostics_to(world, errors, &mut w, diagnostic_format) -} - -/// Print diagnostic messages to the terminal. -pub fn print_diagnostics_to_string<'d, 'files>( - world: &'files dyn SourceWorld, - errors: impl Iterator, - diagnostic_format: DiagnosticFormat, -) -> StrResult { - let mut w = NoColor::new(vec![]); - - print_diagnostics_to(world, errors, &mut w, diagnostic_format) - .map_err(|e| eco_format!("failed to print diagnostics to string: {e}"))?; - let output = EcoString::from_str( - std::str::from_utf8(&w.into_inner()) - .map_err(|e| eco_format!("failed to convert diagnostics to string: {e}"))?, - ) - .unwrap_or_default(); - Ok(output) -} - -/// Print diagnostic messages to the terminal. -pub fn print_diagnostics_to<'d, 'files>( - world: &'files dyn SourceWorld, - errors: impl Iterator, - w: &mut impl WriteColor, - diagnostic_format: DiagnosticFormat, -) -> Result<(), codespan_reporting::files::Error> { - let world = CodeSpanReportWorld::new(world); - - let mut config = term::Config { - tab_width: 2, - ..Default::default() - }; - if diagnostic_format == DiagnosticFormat::Short { - config.display_style = term::DisplayStyle::Short; - } - - for diagnostic in errors { - let diag = match diagnostic.severity { - Severity::Error => Diagnostic::error(), - Severity::Warning => Diagnostic::warning(), - } - .with_message(diagnostic.message.clone()) - .with_notes( - diagnostic - .hints - .iter() - .map(|e| (eco_format!("hint: {e}")).into()) - .collect(), - ) - .with_labels(label(world.world, diagnostic.span).into_iter().collect()); - - term::emit(w, &config, &world, &diag)?; - - // Stacktrace-like helper diagnostics. - for point in &diagnostic.trace { - let message = point.v.to_string(); - let help = Diagnostic::help() - .with_message(message) - .with_labels(label(world.world, point.span).into_iter().collect()); - - term::emit(w, &config, &world, &help)?; - } - } - - Ok(()) -} - -/// Create a label for a span. -fn label(world: &dyn SourceWorld, span: Span) -> Option> { - Some(Label::primary(span.id()?, world.source_range(span)?)) + crate::diag::print_diagnostics_to(world, errors, &mut w, diagnostic_format) } diff --git a/crates/typlite/src/parser/media.rs b/crates/typlite/src/parser/media.rs index dd619329..a2791aab 100644 --- a/crates/typlite/src/parser/media.rs +++ b/crates/typlite/src/parser/media.rs @@ -7,7 +7,7 @@ use std::sync::{Arc, LazyLock}; use base64::Engine; use cmark_writer::ast::{HtmlAttribute, HtmlElement as CmarkHtmlElement, Node}; use ecow::{eco_format, EcoString}; -use tinymist_project::system::print_diagnostics_to_string; +use tinymist_project::diag::print_diagnostics_to_string; use tinymist_project::{base::ShadowApi, EntryReader, TaskInputs, MEMORY_MAIN_ENTRY}; use typst::{ foundations::{Bytes, Dict, IntoValue},