Add instrumentation (Part 1) (#761)

This commit is contained in:
Sébastien d'Herbais de Thun 2023-04-23 14:33:56 +02:00 committed by GitHub
parent 2fbb14f712
commit 561ff979d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
73 changed files with 723 additions and 14 deletions

296
Cargo.lock generated
View File

@ -8,6 +8,18 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "ahash"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
dependencies = [
"cfg-if",
"getrandom",
"once_cell",
"version_check",
]
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "0.7.20" version = "0.7.20"
@ -483,6 +495,19 @@ dependencies = [
"syn 2.0.15", "syn 2.0.15",
] ]
[[package]]
name = "dashmap"
version = "5.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc"
dependencies = [
"cfg-if",
"hashbrown",
"lock_api",
"once_cell",
"parking_lot_core",
]
[[package]] [[package]]
name = "data-url" name = "data-url"
version = "0.1.1" version = "0.1.1"
@ -558,6 +583,15 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "env_logger"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
dependencies = [
"log",
]
[[package]] [[package]]
name = "errno" name = "errno"
version = "0.3.1" version = "0.3.1"
@ -589,6 +623,15 @@ dependencies = [
"regex", "regex",
] ]
[[package]]
name = "fastrand"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
dependencies = [
"instant",
]
[[package]] [[package]]
name = "fdeflate" name = "fdeflate"
version = "0.3.0" version = "0.3.0"
@ -606,7 +649,7 @@ checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"redox_syscall", "redox_syscall 0.2.16",
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
@ -870,6 +913,29 @@ dependencies = [
"rayon", "rayon",
] ]
[[package]]
name = "inferno"
version = "0.11.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fb7c1b80a1dfa604bb4a649a5c5aeef3d913f7c520cb42b40e534e8a61bcdfc"
dependencies = [
"ahash",
"clap 4.2.4",
"crossbeam-channel",
"crossbeam-utils",
"dashmap",
"env_logger",
"indexmap",
"is-terminal",
"itoa",
"log",
"num-format",
"once_cell",
"quick-xml",
"rgb",
"str_stack",
]
[[package]] [[package]]
name = "inotify" name = "inotify"
version = "0.9.6" version = "0.9.6"
@ -890,6 +956,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "instant"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
"cfg-if",
]
[[package]] [[package]]
name = "io-lifetimes" name = "io-lifetimes"
version = "1.0.10" version = "1.0.10"
@ -1067,6 +1142,16 @@ dependencies = [
"rand_chacha", "rand_chacha",
] ]
[[package]]
name = "lock_api"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.17" version = "0.4.17"
@ -1164,6 +1249,16 @@ dependencies = [
"windows-sys 0.42.0", "windows-sys 0.42.0",
] ]
[[package]]
name = "nu-ansi-term"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
dependencies = [
"overload",
"winapi",
]
[[package]] [[package]]
name = "num-bigint" name = "num-bigint"
version = "0.4.3" version = "0.4.3"
@ -1175,6 +1270,16 @@ dependencies = [
"num-traits", "num-traits",
] ]
[[package]]
name = "num-format"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3"
dependencies = [
"arrayvec 0.7.2",
"itoa",
]
[[package]] [[package]]
name = "num-integer" name = "num-integer"
version = "0.1.45" version = "0.1.45"
@ -1243,6 +1348,12 @@ version = "6.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267"
[[package]]
name = "overload"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]] [[package]]
name = "oxipng" name = "oxipng"
version = "8.0.0" version = "8.0.0"
@ -1267,6 +1378,19 @@ dependencies = [
"zopfli", "zopfli",
] ]
[[package]]
name = "parking_lot_core"
version = "0.9.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
dependencies = [
"cfg-if",
"libc",
"redox_syscall 0.2.16",
"smallvec",
"windows-sys 0.45.0",
]
[[package]] [[package]]
name = "paste" name = "paste"
version = "1.0.12" version = "1.0.12"
@ -1320,6 +1444,12 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db8bcd96cb740d03149cbad5518db9fd87126a10ab519c011893b1754134c468" checksum = "db8bcd96cb740d03149cbad5518db9fd87126a10ab519c011893b1754134c468"
[[package]]
name = "pin-project-lite"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
[[package]] [[package]]
name = "pixglyph" name = "pixglyph"
version = "0.1.0" version = "0.1.0"
@ -1357,6 +1487,15 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "psm"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "pulldown-cmark" name = "pulldown-cmark"
version = "0.9.2" version = "0.9.2"
@ -1369,6 +1508,15 @@ dependencies = [
"unicase", "unicase",
] ]
[[package]]
name = "quick-xml"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f50b1c63b38611e7d4d7f68b82d3ad0cc71a2ad2e7f61fc10f1328d917c93cd"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.26" version = "1.0.26"
@ -1446,6 +1594,15 @@ dependencies = [
"bitflags", "bitflags",
] ]
[[package]]
name = "redox_syscall"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
dependencies = [
"bitflags",
]
[[package]] [[package]]
name = "redox_users" name = "redox_users"
version = "0.4.3" version = "0.4.3"
@ -1453,7 +1610,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
dependencies = [ dependencies = [
"getrandom", "getrandom",
"redox_syscall", "redox_syscall 0.2.16",
"thiserror", "thiserror",
] ]
@ -1688,6 +1845,15 @@ dependencies = [
"yaml-rust", "yaml-rust",
] ]
[[package]]
name = "sharded-slab"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
dependencies = [
"lazy_static",
]
[[package]] [[package]]
name = "simd-adler32" name = "simd-adler32"
version = "0.3.5" version = "0.3.5"
@ -1727,6 +1893,19 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "stacker"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce"
dependencies = [
"cc",
"cfg-if",
"libc",
"psm",
"winapi",
]
[[package]] [[package]]
name = "stderrlog" name = "stderrlog"
version = "0.5.4" version = "0.5.4"
@ -1739,6 +1918,12 @@ dependencies = [
"thread_local", "thread_local",
] ]
[[package]]
name = "str_stack"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9091b6114800a5f2141aee1d1b9d6ca3592ac062dc5decb3764ec5895a47b4eb"
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.10.0" version = "0.10.0"
@ -1843,6 +2028,19 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "tempfile"
version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
dependencies = [
"cfg-if",
"fastrand",
"redox_syscall 0.3.5",
"rustix",
"windows-sys 0.45.0",
]
[[package]] [[package]]
name = "termcolor" name = "termcolor"
version = "1.1.3" version = "1.1.3"
@ -1932,6 +2130,85 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tracing"
version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
dependencies = [
"cfg-if",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "tracing-core"
version = "0.1.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
dependencies = [
"once_cell",
"valuable",
]
[[package]]
name = "tracing-error"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e"
dependencies = [
"tracing",
"tracing-subscriber",
]
[[package]]
name = "tracing-flame"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bae117ee14789185e129aaee5d93750abe67fdc5a9a62650452bfe4e122a3a9"
dependencies = [
"lazy_static",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "tracing-log"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
dependencies = [
"lazy_static",
"log",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70"
dependencies = [
"nu-ansi-term",
"sharded-slab",
"smallvec",
"thread_local",
"tracing-core",
"tracing-log",
]
[[package]] [[package]]
name = "ttf-parser" name = "ttf-parser"
version = "0.15.2" version = "0.15.2"
@ -1980,10 +2257,12 @@ dependencies = [
"rustybuzz", "rustybuzz",
"serde", "serde",
"siphasher", "siphasher",
"stacker",
"subsetter", "subsetter",
"svg2pdf", "svg2pdf",
"thin-vec", "thin-vec",
"tiny-skia", "tiny-skia",
"tracing",
"ttf-parser 0.18.1", "ttf-parser 0.18.1",
"typst-macros", "typst-macros",
"unicode-math-class", "unicode-math-class",
@ -2006,12 +2285,18 @@ dependencies = [
"comemo", "comemo",
"dirs", "dirs",
"elsa", "elsa",
"inferno",
"memmap2", "memmap2",
"notify", "notify",
"once_cell", "once_cell",
"open", "open",
"same-file", "same-file",
"siphasher", "siphasher",
"tempfile",
"tracing",
"tracing-error",
"tracing-flame",
"tracing-subscriber",
"typst", "typst",
"typst-library", "typst-library",
"walkdir", "walkdir",
@ -2056,6 +2341,7 @@ dependencies = [
"serde_yaml", "serde_yaml",
"smallvec", "smallvec",
"syntect", "syntect",
"tracing",
"ttf-parser 0.18.1", "ttf-parser 0.18.1",
"typed-arena", "typed-arena",
"typst", "typst",
@ -2276,6 +2562,12 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.4" version = "0.9.4"

View File

@ -51,10 +51,12 @@ unicode-xid = "0.2"
unscanny = "0.1" unscanny = "0.1"
usvg = { version = "0.22", default-features = false, features = ["text"] } usvg = { version = "0.22", default-features = false, features = ["text"] }
xmp-writer = "0.1" xmp-writer = "0.1"
tracing = "0.1.37"
indexmap = "1.9.3" indexmap = "1.9.3"
stacker = "0.1.15"
[profile.dev] [profile.dev]
debug = 0 debug = false
[profile.dev.package."*"] [profile.dev.package."*"]
opt-level = 2 opt-level = 2

View File

@ -34,6 +34,12 @@ siphasher = "0.3"
walkdir = "2" walkdir = "2"
clap = { version = "4.2.1", features = ["derive", "env"] } clap = { version = "4.2.1", features = ["derive", "env"] }
open = "4.0.1" open = "4.0.1"
tracing = "0.1.37"
tracing-subscriber = "0.3.16"
tracing-flame = "0.2.0"
tracing-error = "0.2"
inferno = "0.11.15"
tempfile = "3.5.0"
[build-dependencies] [build-dependencies]
clap = { version = "4.2.1", features = ["derive", "string"] } clap = { version = "4.2.1", features = ["derive", "string"] }

View File

@ -24,9 +24,9 @@ pub fn typst_version() -> String {
format!("{pkg} ({hash})") format!("{pkg} ({hash})")
} }
mod args { #[path = "src/args.rs"]
include!("src/args.rs"); #[allow(dead_code)]
} mod args;
fn main() { fn main() {
println!("cargo:rerun-if-env-changed=TYPST_VERSION"); println!("cargo:rerun-if-env-changed=TYPST_VERSION");

View File

@ -17,6 +17,10 @@ pub struct CliArguments {
/// The typst command to run /// The typst command to run
#[command(subcommand)] #[command(subcommand)]
pub command: Command, pub command: Command,
/// Sets the level of verbosity: 0 = none, 1 = warning & error, 2 = info, 3 = debug, 4 = trace
#[clap(short, long, action = ArgAction::Count)]
pub verbosity: u8,
} }
/// What to do. /// What to do.
@ -35,6 +39,22 @@ pub enum Command {
Fonts(FontsCommand), Fonts(FontsCommand),
} }
impl Command {
/// Returns the compile command if this is a compile or watch command.
pub fn as_compile(&self) -> Option<&CompileCommand> {
match self {
Command::Compile(cmd) => Some(cmd),
Command::Watch(cmd) => Some(cmd),
Command::Fonts(_) => None,
}
}
/// Returns whether this is a watch command.
pub fn is_watch(&self) -> bool {
matches!(self, Command::Watch(_))
}
}
/// Compiles the input file into a PDF file /// Compiles the input file into a PDF file
#[derive(Debug, Clone, Parser)] #[derive(Debug, Clone, Parser)]
pub struct CompileCommand { pub struct CompileCommand {
@ -47,6 +67,11 @@ pub struct CompileCommand {
/// Opens the output file after compilation using the default PDF viewer /// Opens the output file after compilation using the default PDF viewer
#[arg(long = "open")] #[arg(long = "open")]
pub open: Option<Option<String>>, pub open: Option<Option<String>>,
/// Produces a flamegraph of the compilation process and saves it to the
/// given file or to `flamegraph.svg` in the current working directory.
#[arg(long = "flamegraph", value_name = "OUTPUT_SVG")]
pub flamegraph: Option<Option<PathBuf>>,
} }
/// List all discovered fonts in system and custom font paths /// List all discovered fonts in system and custom font paths

View File

@ -1,4 +1,5 @@
mod args; mod args;
mod trace;
use std::cell::{RefCell, RefMut}; use std::cell::{RefCell, RefMut};
use std::collections::HashMap; use std::collections::HashMap;
@ -28,6 +29,7 @@ use typst::World;
use walkdir::WalkDir; use walkdir::WalkDir;
use crate::args::{CliArguments, Command, CompileCommand}; use crate::args::{CliArguments, Command, CompileCommand};
use crate::trace::init_tracing;
type CodespanResult<T> = Result<T, CodespanError>; type CodespanResult<T> = Result<T, CodespanError>;
type CodespanError = codespan_reporting::files::Error; type CodespanError = codespan_reporting::files::Error;
@ -80,7 +82,7 @@ impl CompileSettings {
/// Panics if the command is not a compile or watch command. /// Panics if the command is not a compile or watch command.
pub fn with_arguments(args: CliArguments) -> Self { pub fn with_arguments(args: CliArguments) -> Self {
let watch = matches!(args.command, Command::Watch(_)); let watch = matches!(args.command, Command::Watch(_));
let CompileCommand { input, output, open } = match args.command { let CompileCommand { input, output, open, .. } = match args.command {
Command::Compile(command) => command, Command::Compile(command) => command,
Command::Watch(command) => command, Command::Watch(command) => command,
_ => unreachable!(), _ => unreachable!(),
@ -118,6 +120,13 @@ impl FontsSettings {
/// Entry point. /// Entry point.
fn main() { fn main() {
let arguments = CliArguments::parse(); let arguments = CliArguments::parse();
let _guard = match init_tracing(&arguments) {
Ok(guard) => guard,
Err(err) => {
eprintln!("failed to initialize tracing, reason: {}", err);
return;
}
};
let res = match &arguments.command { let res = match &arguments.command {
Command::Compile(_) | Command::Watch(_) => { Command::Compile(_) | Command::Watch(_) => {
@ -225,7 +234,10 @@ fn compile(mut command: CompileSettings) -> StrResult<()> {
} }
/// Compile a single time. /// Compile a single time.
#[tracing::instrument(skip_all)]
fn compile_once(world: &mut SystemWorld, command: &CompileSettings) -> StrResult<bool> { fn compile_once(world: &mut SystemWorld, command: &CompileSettings) -> StrResult<bool> {
tracing::info!("Starting compilation");
status(command, Status::Compiling).unwrap(); status(command, Status::Compiling).unwrap();
world.reset(); world.reset();
@ -237,6 +249,8 @@ fn compile_once(world: &mut SystemWorld, command: &CompileSettings) -> StrResult
let buffer = typst::export::pdf(&document); let buffer = typst::export::pdf(&document);
fs::write(&command.output, buffer).map_err(|_| "failed to write PDF file")?; fs::write(&command.output, buffer).map_err(|_| "failed to write PDF file")?;
status(command, Status::Success).unwrap(); status(command, Status::Success).unwrap();
tracing::info!("Compilation succeeded");
Ok(false) Ok(false)
} }
@ -245,12 +259,15 @@ fn compile_once(world: &mut SystemWorld, command: &CompileSettings) -> StrResult
status(command, Status::Error).unwrap(); status(command, Status::Error).unwrap();
print_diagnostics(world, *errors) print_diagnostics(world, *errors)
.map_err(|_| "failed to print diagnostics")?; .map_err(|_| "failed to print diagnostics")?;
tracing::info!("Compilation failed");
Ok(true) Ok(true)
} }
} }
} }
/// Clear the terminal and render the status message. /// Clear the terminal and render the status message.
#[tracing::instrument(skip_all)]
fn status(command: &CompileSettings, status: Status) -> io::Result<()> { fn status(command: &CompileSettings, status: Status) -> io::Result<()> {
if !command.watch { if !command.watch {
return Ok(()); return Ok(());
@ -431,6 +448,7 @@ impl World for SystemWorld {
self.source(self.main) self.source(self.main)
} }
#[tracing::instrument(skip_all)]
fn resolve(&self, path: &Path) -> FileResult<SourceId> { fn resolve(&self, path: &Path) -> FileResult<SourceId> {
self.slot(path)? self.slot(path)?
.source .source
@ -469,6 +487,7 @@ impl World for SystemWorld {
} }
impl SystemWorld { impl SystemWorld {
#[tracing::instrument(skip_all)]
fn slot(&self, path: &Path) -> FileResult<RefMut<PathSlot>> { fn slot(&self, path: &Path) -> FileResult<RefMut<PathSlot>> {
let mut hashes = self.hashes.borrow_mut(); let mut hashes = self.hashes.borrow_mut();
let hash = match hashes.get(path).cloned() { let hash = match hashes.get(path).cloned() {
@ -488,6 +507,7 @@ impl SystemWorld {
})) }))
} }
#[tracing::instrument(skip_all)]
fn insert(&self, path: &Path, text: String) -> SourceId { fn insert(&self, path: &Path, text: String) -> SourceId {
let id = SourceId::from_u16(self.sources.len() as u16); let id = SourceId::from_u16(self.sources.len() as u16);
let source = Source::new(id, path, text); let source = Source::new(id, path, text);
@ -520,6 +540,7 @@ impl SystemWorld {
.map_or(false, |hash| self.paths.borrow().contains_key(&hash)) .map_or(false, |hash| self.paths.borrow().contains_key(&hash))
} }
#[tracing::instrument(skip_all)]
fn reset(&mut self) { fn reset(&mut self) {
self.sources.as_mut().clear(); self.sources.as_mut().clear();
self.hashes.borrow_mut().clear(); self.hashes.borrow_mut().clear();
@ -542,6 +563,7 @@ impl PathHash {
} }
/// Read a file. /// Read a file.
#[tracing::instrument(skip_all)]
fn read(path: &Path) -> FileResult<Vec<u8>> { fn read(path: &Path) -> FileResult<Vec<u8>> {
let f = |e| FileError::from_io(e, path); let f = |e| FileError::from_io(e, path);
if fs::metadata(path).map_err(f)?.is_dir() { if fs::metadata(path).map_err(f)?.is_dir() {

135
cli/src/trace.rs Normal file
View File

@ -0,0 +1,135 @@
use std::fs::File;
use std::io::{BufReader, BufWriter, Error, ErrorKind, Seek, SeekFrom};
use std::path::PathBuf;
use inferno::flamegraph::Options;
use tracing::metadata::LevelFilter;
use tracing_error::ErrorLayer;
use tracing_flame::{FlameLayer, FlushGuard};
use tracing_subscriber::fmt;
use tracing_subscriber::prelude::*;
use crate::args::CliArguments;
/// Will flush the flamegraph to disk when dropped.
pub struct TracingGuard {
flush_guard: Option<FlushGuard<BufWriter<File>>>,
temp_file: File,
output_svg: PathBuf,
}
impl TracingGuard {
pub fn finish(&mut self) -> Result<(), Error> {
if self.flush_guard.is_none() {
return Ok(());
}
tracing::info!("Flushing tracing flamegraph...");
// At this point, we're done tracing, so we can drop the guard.
// This will flush the tracing output to disk.
// We can then read the file and generate the flamegraph.
drop(self.flush_guard.take());
// Reset the file pointer to the beginning.
self.temp_file.seek(SeekFrom::Start(0))?;
// Create the readers and writers.
let reader = BufReader::new(&mut self.temp_file);
let output = BufWriter::new(File::create(&self.output_svg)?);
// Create the options: default in flame chart mode
let mut options = Options::default();
options.flame_chart = true;
inferno::flamegraph::from_reader(&mut options, reader, output)
.map_err(|e| Error::new(ErrorKind::Other, e))?;
Ok(())
}
}
impl Drop for TracingGuard {
fn drop(&mut self) {
if !std::thread::panicking() {
if let Err(e) = self.finish() {
// Since we are finished, we cannot rely on tracing to log the
// error.
eprintln!("Failed to flush tracing flamegraph: {e}");
}
}
}
}
/// Initializes the tracing system and returns a guard that will flush the
/// flamegraph to disk when dropped.
pub fn init_tracing(args: &CliArguments) -> Result<Option<TracingGuard>, Error> {
let flamegraph = args.command.as_compile().and_then(|c| c.flamegraph.as_ref());
if flamegraph.is_some() && args.command.is_watch() {
return Err(Error::new(
ErrorKind::InvalidInput,
"cannot use --flamegraph with watch command",
));
}
// Short circuit if we don't need to initialize flamegraph or debugging.
if flamegraph.is_none() && args.verbosity == 0 {
tracing_subscriber::fmt()
.without_time()
.with_max_level(level_filter(args))
.init();
return Ok(None);
}
// Build the FMT layer printing to the console.
let fmt_layer = fmt::Layer::default().without_time().with_filter(level_filter(args));
// Error layer for building backtraces
let error_layer = ErrorLayer::default();
// Build the registry.
let registry = tracing_subscriber::registry().with(fmt_layer).with(error_layer);
let Some(path) = flamegraph else {
registry.init();
return Ok(None);
};
// Create a temporary file to store the flamegraph data.
let temp_file = tempfile::tempfile()?;
let writer = BufWriter::new(temp_file.try_clone()?);
// Build the flamegraph layer.
let flame_layer = FlameLayer::new(writer)
.with_empty_samples(false)
.with_threads_collapsed(true)
.with_module_path(false)
.with_file_and_line(true);
let flush_guard = flame_layer.flush_on_drop();
// Build the subscriber.
registry.with(flame_layer).init();
tracing::warn!(
"Flamegraph is enabled, this can create a large temporary \
file and slow down the compilation process."
);
Ok(Some(TracingGuard {
flush_guard: Some(flush_guard),
temp_file,
output_svg: path.clone().unwrap_or_else(|| "flamegraph.svg".into()),
}))
}
/// Returns the log level filter for the given verbosity level.
fn level_filter(args: &CliArguments) -> LevelFilter {
match args.verbosity {
0 => LevelFilter::WARN,
1 => LevelFilter::INFO,
2 => LevelFilter::DEBUG,
_ => LevelFilter::TRACE,
}
}

View File

@ -39,3 +39,4 @@ unicode-script = "0.5"
unicode-segmentation = "1" unicode-segmentation = "1"
xi-unicode = "0.3" xi-unicode = "0.3"
chinese-number = { version = "0.7.1", default-features = false, features = ["number-to-chinese"] } chinese-number = { version = "0.7.1", default-features = false, features = ["number-to-chinese"] }
tracing = "0.1.37"

View File

@ -58,6 +58,7 @@ pub struct AlignElem {
} }
impl Show for AlignElem { impl Show for AlignElem {
#[tracing::instrument(name = "AlignElem::show", skip_all)]
fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> { fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> {
Ok(self Ok(self
.body() .body()

View File

@ -50,6 +50,7 @@ pub struct ColumnsElem {
} }
impl Layout for ColumnsElem { impl Layout for ColumnsElem {
#[tracing::instrument(name = "ColumnsElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,

View File

@ -99,6 +99,7 @@ pub struct BoxElem {
} }
impl Layout for BoxElem { impl Layout for BoxElem {
#[tracing::instrument(name = "BoxElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,
@ -326,6 +327,7 @@ pub struct BlockElem {
} }
impl Layout for BlockElem { impl Layout for BlockElem {
#[tracing::instrument(name = "BlockElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,

View File

@ -154,6 +154,7 @@ pub struct EnumElem {
} }
impl Layout for EnumElem { impl Layout for EnumElem {
#[tracing::instrument(name = "EnumElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,

View File

@ -19,6 +19,7 @@ pub struct FlowElem {
} }
impl Layout for FlowElem { impl Layout for FlowElem {
#[tracing::instrument(name = "FlowElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,
@ -122,6 +123,7 @@ impl<'a> FlowLayouter<'a> {
} }
/// Layout vertical spacing. /// Layout vertical spacing.
#[tracing::instrument(name = "FlowLayouter::layout_spacing", skip_all)]
fn layout_spacing(&mut self, v: &VElem, styles: StyleChain) { fn layout_spacing(&mut self, v: &VElem, styles: StyleChain) {
self.layout_item(match v.amount() { self.layout_item(match v.amount() {
Spacing::Rel(rel) => FlowItem::Absolute( Spacing::Rel(rel) => FlowItem::Absolute(
@ -133,6 +135,7 @@ impl<'a> FlowLayouter<'a> {
} }
/// Layout a paragraph. /// Layout a paragraph.
#[tracing::instrument(name = "FlowLayouter::layout_par", skip_all)]
fn layout_par( fn layout_par(
&mut self, &mut self,
vt: &mut Vt, vt: &mut Vt,
@ -179,6 +182,7 @@ impl<'a> FlowLayouter<'a> {
} }
/// Layout into a single region. /// Layout into a single region.
#[tracing::instrument(name = "FlowLayouter::layout_single", skip_all)]
fn layout_single( fn layout_single(
&mut self, &mut self,
vt: &mut Vt, vt: &mut Vt,
@ -237,6 +241,7 @@ impl<'a> FlowLayouter<'a> {
} }
/// Layout a finished frame. /// Layout a finished frame.
#[tracing::instrument(name = "FlowLayouter::layout_item", skip_all)]
fn layout_item(&mut self, item: FlowItem) { fn layout_item(&mut self, item: FlowItem) {
match item { match item {
FlowItem::Absolute(v, _) => self.regions.size.y -= v, FlowItem::Absolute(v, _) => self.regions.size.y -= v,

View File

@ -102,6 +102,7 @@ pub struct GridElem {
} }
impl Layout for GridElem { impl Layout for GridElem {
#[tracing::instrument(name = "GridElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,
@ -289,6 +290,7 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
} }
/// Determines the columns sizes and then layouts the grid row-by-row. /// Determines the columns sizes and then layouts the grid row-by-row.
#[tracing::instrument(name = "grid layout", skip(self))]
pub fn layout(mut self) -> SourceResult<GridLayout> { pub fn layout(mut self) -> SourceResult<GridLayout> {
self.measure_columns()?; self.measure_columns()?;

View File

@ -23,6 +23,7 @@ pub struct HideElem {
} }
impl Show for HideElem { impl Show for HideElem {
#[tracing::instrument(name = "HideElem::show", skip(self))]
fn show(&self, _: &mut Vt, _: StyleChain) -> SourceResult<Content> { fn show(&self, _: &mut Vt, _: StyleChain) -> SourceResult<Content> {
Ok(self.body().styled(MetaElem::set_data(vec![Meta::Hide]))) Ok(self.body().styled(MetaElem::set_data(vec![Meta::Hide])))
} }

View File

@ -112,6 +112,7 @@ pub struct ListElem {
} }
impl Layout for ListElem { impl Layout for ListElem {
#[tracing::instrument(name = "ListElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,

View File

@ -68,6 +68,7 @@ pub trait LayoutRoot {
} }
impl LayoutRoot for Content { impl LayoutRoot for Content {
#[tracing::instrument(name = "Content::layout_root", skip_all)]
fn layout_root(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Document> { fn layout_root(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Document> {
#[comemo::memoize] #[comemo::memoize]
fn cached( fn cached(
@ -87,6 +88,8 @@ impl LayoutRoot for Content {
.layout_root(&mut vt, styles) .layout_root(&mut vt, styles)
} }
tracing::info!("Starting layout");
cached( cached(
self, self,
vt.world, vt.world,
@ -126,6 +129,7 @@ pub trait Layout {
} }
impl Layout for Content { impl Layout for Content {
#[tracing::instrument(name = "Content::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,
@ -151,6 +155,8 @@ impl Layout for Content {
.layout(&mut vt, styles, regions) .layout(&mut vt, styles, regions)
} }
tracing::info!("Layouting `Content`");
cached( cached(
self, self,
vt.world, vt.world,
@ -164,6 +170,7 @@ impl Layout for Content {
} }
/// Realize into an element that is capable of root-level layout. /// Realize into an element that is capable of root-level layout.
#[tracing::instrument(skip_all)]
fn realize_root<'a>( fn realize_root<'a>(
vt: &mut Vt, vt: &mut Vt,
scratch: &'a Scratch<'a>, scratch: &'a Scratch<'a>,
@ -245,6 +252,7 @@ impl<'a, 'v, 't> Builder<'a, 'v, 't> {
} }
} }
#[tracing::instrument(skip_all)]
fn accept( fn accept(
&mut self, &mut self,
mut content: &'a Content, mut content: &'a Content,
@ -310,6 +318,7 @@ impl<'a, 'v, 't> Builder<'a, 'v, 't> {
} }
} }
#[tracing::instrument(skip_all)]
fn styled( fn styled(
&mut self, &mut self,
elem: &'a Content, elem: &'a Content,
@ -324,6 +333,7 @@ impl<'a, 'v, 't> Builder<'a, 'v, 't> {
Ok(()) Ok(())
} }
#[tracing::instrument(skip(self, local, outer))]
fn interrupt_style( fn interrupt_style(
&mut self, &mut self,
local: &Styles, local: &Styles,
@ -358,6 +368,7 @@ impl<'a, 'v, 't> Builder<'a, 'v, 't> {
Ok(()) Ok(())
} }
#[tracing::instrument(skip(self))]
fn interrupt_list(&mut self) -> SourceResult<()> { fn interrupt_list(&mut self) -> SourceResult<()> {
if !self.list.items.is_empty() { if !self.list.items.is_empty() {
let staged = mem::take(&mut self.list.staged); let staged = mem::take(&mut self.list.staged);
@ -371,6 +382,7 @@ impl<'a, 'v, 't> Builder<'a, 'v, 't> {
Ok(()) Ok(())
} }
#[tracing::instrument(skip(self))]
fn interrupt_par(&mut self) -> SourceResult<()> { fn interrupt_par(&mut self) -> SourceResult<()> {
self.interrupt_list()?; self.interrupt_list()?;
if !self.par.0.is_empty() { if !self.par.0.is_empty() {
@ -382,6 +394,7 @@ impl<'a, 'v, 't> Builder<'a, 'v, 't> {
Ok(()) Ok(())
} }
#[tracing::instrument(skip_all)]
fn interrupt_page(&mut self, styles: Option<StyleChain<'a>>) -> SourceResult<()> { fn interrupt_page(&mut self, styles: Option<StyleChain<'a>>) -> SourceResult<()> {
self.interrupt_par()?; self.interrupt_par()?;
let Some(doc) = &mut self.doc else { return Ok(()) }; let Some(doc) = &mut self.doc else { return Ok(()) };

View File

@ -60,6 +60,7 @@ pub struct PadElem {
} }
impl Layout for PadElem { impl Layout for PadElem {
#[tracing::instrument(name = "PadElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,

View File

@ -272,7 +272,10 @@ pub struct PageElem {
impl PageElem { impl PageElem {
/// Layout the page run into a sequence of frames, one per page. /// Layout the page run into a sequence of frames, one per page.
#[tracing::instrument(skip_all)]
pub fn layout(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Fragment> { pub fn layout(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Fragment> {
tracing::info!("Page layout");
// When one of the lengths is infinite the page fits its content along // When one of the lengths is infinite the page fits its content along
// that axis. // that axis.
let width = self.width(styles).unwrap_or(Abs::inf()); let width = self.width(styles).unwrap_or(Abs::inf());
@ -330,12 +333,20 @@ impl PageElem {
); );
// Realize overlays. // Realize overlays.
for frame in &mut fragment { for (i, frame) in fragment.iter_mut().enumerate() {
tracing::info!("Layouting page #{i}");
frame.prepend(Point::zero(), numbering_meta.clone()); frame.prepend(Point::zero(), numbering_meta.clone());
let size = frame.size(); let size = frame.size();
let pad = padding.resolve(styles).relative_to(size); let pad = padding.resolve(styles).relative_to(size);
let pw = size.x - pad.left - pad.right; let pw = size.x - pad.left - pad.right;
for marginal in [&header, &footer, &background, &foreground] { for (name, marginal) in [
("header", &header),
("footer", &footer),
("background", &background),
("foreground", &foreground),
] {
tracing::info!("Layouting {name}");
let Some(content) = marginal else { continue }; let Some(content) = marginal else { continue };
let (pos, area, align); let (pos, area, align);

View File

@ -126,6 +126,7 @@ impl Construct for ParElem {
impl ParElem { impl ParElem {
/// Layout the paragraph into a collection of lines. /// Layout the paragraph into a collection of lines.
#[tracing::instrument(name = "ParElement::layout", skip_all)]
pub fn layout( pub fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,

View File

@ -54,6 +54,7 @@ pub struct PlaceElem {
} }
impl Layout for PlaceElem { impl Layout for PlaceElem {
#[tracing::instrument(name = "PlaceElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,

View File

@ -34,6 +34,7 @@ pub struct RepeatElem {
} }
impl Layout for RepeatElem { impl Layout for RepeatElem {
#[tracing::instrument(name = "RepeatElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,

View File

@ -38,6 +38,7 @@ pub struct StackElem {
} }
impl Layout for StackElem { impl Layout for StackElem {
#[tracing::instrument(name = "StackElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,
@ -161,6 +162,7 @@ impl<'a> StackLayouter<'a> {
} }
/// Add spacing along the spacing direction. /// Add spacing along the spacing direction.
#[tracing::instrument(name = "StackLayouter::layout_spacing", skip_all)]
fn layout_spacing(&mut self, spacing: Spacing) { fn layout_spacing(&mut self, spacing: Spacing) {
match spacing { match spacing {
Spacing::Rel(v) => { Spacing::Rel(v) => {
@ -184,6 +186,7 @@ impl<'a> StackLayouter<'a> {
} }
/// Layout an arbitrary block. /// Layout an arbitrary block.
#[tracing::instrument(name = "StackLayouter::layout_block", skip_all)]
fn layout_block( fn layout_block(
&mut self, &mut self,
vt: &mut Vt, vt: &mut Vt,

View File

@ -122,6 +122,7 @@ pub struct TableElem {
} }
impl Layout for TableElem { impl Layout for TableElem {
#[tracing::instrument(name = "TableElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,

View File

@ -92,6 +92,7 @@ pub struct TermsElem {
} }
impl Layout for TermsElem { impl Layout for TermsElem {
#[tracing::instrument(name = "TermsElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,

View File

@ -37,6 +37,7 @@ pub struct MoveElem {
} }
impl Layout for MoveElem { impl Layout for MoveElem {
#[tracing::instrument(name = "MoveElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,
@ -105,6 +106,7 @@ pub struct RotateElem {
} }
impl Layout for RotateElem { impl Layout for RotateElem {
#[tracing::instrument(name = "RotateElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,
@ -173,6 +175,7 @@ pub struct ScaleElem {
} }
impl Layout for ScaleElem { impl Layout for ScaleElem {
#[tracing::instrument(name = "ScaleElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,

View File

@ -29,6 +29,7 @@ pub fn build() -> Library {
} }
/// Construct the module with global definitions. /// Construct the module with global definitions.
#[tracing::instrument(skip_all)]
fn global(math: Module, calc: Module) -> Module { fn global(math: Module, calc: Module) -> Module {
let mut global = Scope::deduplicating(); let mut global = Scope::deduplicating();

View File

@ -52,6 +52,7 @@ pub struct AccentElem {
} }
impl LayoutMath for AccentElem { impl LayoutMath for AccentElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
ctx.style(ctx.style.with_cramped(true)); ctx.style(ctx.style.with_cramped(true));
let base = ctx.layout_fragment(&self.base())?; let base = ctx.layout_fragment(&self.base())?;

View File

@ -8,6 +8,7 @@ use super::*;
pub struct AlignPointElem {} pub struct AlignPointElem {}
impl LayoutMath for AlignPointElem { impl LayoutMath for AlignPointElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
ctx.push(MathFragment::Align); ctx.push(MathFragment::Align);
Ok(()) Ok(())

View File

@ -27,6 +27,7 @@ pub struct AttachElem {
} }
impl LayoutMath for AttachElem { impl LayoutMath for AttachElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
let base = self.base(); let base = self.base();
let display_limits = base.is::<LimitsElem>(); let display_limits = base.is::<LimitsElem>();
@ -83,6 +84,7 @@ pub struct ScriptsElem {
} }
impl LayoutMath for ScriptsElem { impl LayoutMath for ScriptsElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
self.body().layout_math(ctx) self.body().layout_math(ctx)
} }
@ -105,6 +107,7 @@ pub struct LimitsElem {
} }
impl LayoutMath for LimitsElem { impl LayoutMath for LimitsElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
self.body().layout_math(ctx) self.body().layout_math(ctx)
} }

View File

@ -39,6 +39,7 @@ pub struct LrElem {
} }
impl LayoutMath for LrElem { impl LayoutMath for LrElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
let mut body = self.body(); let mut body = self.body();
if let Some(elem) = body.to::<LrElem>() { if let Some(elem) = body.to::<LrElem>() {

View File

@ -30,6 +30,7 @@ pub struct FracElem {
} }
impl LayoutMath for FracElem { impl LayoutMath for FracElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
layout(ctx, &self.num(), &self.denom(), false, self.span()) layout(ctx, &self.num(), &self.denom(), false, self.span())
} }

View File

@ -33,6 +33,7 @@ pub struct VecElem {
} }
impl LayoutMath for VecElem { impl LayoutMath for VecElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
let delim = self.delim(ctx.styles()); let delim = self.delim(ctx.styles());
let frame = layout_vec_body(ctx, &self.children(), Align::Center)?; let frame = layout_vec_body(ctx, &self.children(), Align::Center)?;
@ -115,6 +116,7 @@ pub struct MatElem {
} }
impl LayoutMath for MatElem { impl LayoutMath for MatElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
let delim = self.delim(ctx.styles()); let delim = self.delim(ctx.styles());
let frame = layout_mat_body(ctx, &self.rows())?; let frame = layout_mat_body(ctx, &self.rows())?;
@ -161,6 +163,7 @@ pub struct CasesElem {
} }
impl LayoutMath for CasesElem { impl LayoutMath for CasesElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
let delim = self.delim(ctx.styles()); let delim = self.delim(ctx.styles());
let frame = layout_vec_body(ctx, &self.children(), Align::Left)?; let frame = layout_vec_body(ctx, &self.children(), Align::Left)?;

View File

@ -173,6 +173,7 @@ impl Synthesize for EquationElem {
} }
impl Show for EquationElem { impl Show for EquationElem {
#[tracing::instrument(name = "EquationElem::show", skip_all)]
fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> { fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> {
let mut realized = self.clone().pack().guarded(Guard::Base(Self::func())); let mut realized = self.clone().pack().guarded(Guard::Base(Self::func()));
if self.block(styles) { if self.block(styles) {
@ -193,6 +194,7 @@ impl Finalize for EquationElem {
} }
impl Layout for EquationElem { impl Layout for EquationElem {
#[tracing::instrument(name = "EquationElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,
@ -340,12 +342,14 @@ pub trait LayoutMath {
} }
impl LayoutMath for EquationElem { impl LayoutMath for EquationElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
self.body().layout_math(ctx) self.body().layout_math(ctx)
} }
} }
impl LayoutMath for Content { impl LayoutMath for Content {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
// Directly layout the body of nested equations instead of handling it // Directly layout the body of nested equations instead of handling it
// like a normal equation so that things like this work: // like a normal equation so that things like this work:

View File

@ -34,6 +34,7 @@ pub struct OpElem {
} }
impl LayoutMath for OpElem { impl LayoutMath for OpElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
let fragment = let fragment =
ctx.layout_text(&TextElem::new(self.text()).spanned(self.span()))?; ctx.layout_text(&TextElem::new(self.text()).spanned(self.span()))?;

View File

@ -39,6 +39,7 @@ pub struct RootElem {
} }
impl LayoutMath for RootElem { impl LayoutMath for RootElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
layout(ctx, self.index(ctx.styles()).as_ref(), &self.radicand(), self.span()) layout(ctx, self.index(ctx.styles()).as_ref(), &self.radicand(), self.span())
} }

View File

@ -199,6 +199,7 @@ pub struct MathStyleElem {
} }
impl LayoutMath for MathStyleElem { impl LayoutMath for MathStyleElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
let mut style = ctx.style; let mut style = ctx.style;
if let Some(variant) = self.variant(StyleChain::default()) { if let Some(variant) = self.variant(StyleChain::default()) {

View File

@ -21,6 +21,7 @@ pub struct UnderlineElem {
} }
impl LayoutMath for UnderlineElem { impl LayoutMath for UnderlineElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
layout(ctx, &self.body(), &None, '\u{305}', LINE_GAP, false, self.span()) layout(ctx, &self.body(), &None, '\u{305}', LINE_GAP, false, self.span())
} }
@ -43,6 +44,7 @@ pub struct OverlineElem {
} }
impl LayoutMath for OverlineElem { impl LayoutMath for OverlineElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
layout(ctx, &self.body(), &None, '\u{332}', LINE_GAP, true, self.span()) layout(ctx, &self.body(), &None, '\u{332}', LINE_GAP, true, self.span())
} }
@ -69,6 +71,7 @@ pub struct UnderbraceElem {
} }
impl LayoutMath for UnderbraceElem { impl LayoutMath for UnderbraceElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
layout( layout(
ctx, ctx,
@ -103,6 +106,7 @@ pub struct OverbraceElem {
} }
impl LayoutMath for OverbraceElem { impl LayoutMath for OverbraceElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
layout( layout(
ctx, ctx,
@ -137,6 +141,7 @@ pub struct UnderbracketElem {
} }
impl LayoutMath for UnderbracketElem { impl LayoutMath for UnderbracketElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
layout( layout(
ctx, ctx,
@ -171,6 +176,7 @@ pub struct OverbracketElem {
} }
impl LayoutMath for OverbracketElem { impl LayoutMath for OverbracketElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
layout( layout(
ctx, ctx,

View File

@ -140,6 +140,7 @@ impl Synthesize for BibliographyElem {
} }
impl Show for BibliographyElem { impl Show for BibliographyElem {
#[tracing::instrument(name = "BibliographyElem::show", skip_all)]
fn show(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Content> { fn show(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Content> {
const COLUMN_GUTTER: Em = Em::new(0.65); const COLUMN_GUTTER: Em = Em::new(0.65);
const INDENT: Em = Em::new(1.5); const INDENT: Em = Em::new(1.5);
@ -336,6 +337,7 @@ impl Synthesize for CiteElem {
} }
impl Show for CiteElem { impl Show for CiteElem {
#[tracing::instrument(name = "CiteElem::show", skip(self, vt))]
fn show(&self, vt: &mut Vt, _: StyleChain) -> SourceResult<Content> { fn show(&self, vt: &mut Vt, _: StyleChain) -> SourceResult<Content> {
if !vt.introspector.init() { if !vt.introspector.init() {
return Ok(Content::empty()); return Ok(Content::empty());

View File

@ -72,6 +72,7 @@ struct LocateElem {
} }
impl Show for LocateElem { impl Show for LocateElem {
#[tracing::instrument(name = "LocateElem::show", skip(self, vt))]
fn show(&self, vt: &mut Vt, _: StyleChain) -> SourceResult<Content> { fn show(&self, vt: &mut Vt, _: StyleChain) -> SourceResult<Content> {
if !vt.introspector.init() { if !vt.introspector.init() {
return Ok(Content::empty()); return Ok(Content::empty());
@ -127,6 +128,7 @@ struct StyleElem {
} }
impl Show for StyleElem { impl Show for StyleElem {
#[tracing::instrument(name = "StyleElem::show", skip_all)]
fn show(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Content> { fn show(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Content> {
Ok(self.func().call_vt(vt, [styles.to_map().into()])?.display()) Ok(self.func().call_vt(vt, [styles.to_map().into()])?.display())
} }
@ -204,6 +206,7 @@ struct LayoutElem {
} }
impl Layout for LayoutElem { impl Layout for LayoutElem {
#[tracing::instrument(name = "LayoutElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,

View File

@ -302,6 +302,7 @@ impl Counter {
} }
/// Call a method on counter. /// Call a method on counter.
#[tracing::instrument(skip(vm))]
pub fn call_method( pub fn call_method(
self, self,
vm: &mut Vm, vm: &mut Vm,
@ -618,6 +619,7 @@ struct DisplayElem {
} }
impl Show for DisplayElem { impl Show for DisplayElem {
#[tracing::instrument(name = "DisplayElem::show", skip_all)]
fn show(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Content> { fn show(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Content> {
if !vt.introspector.init() { if !vt.introspector.init() {
return Ok(Content::empty()); return Ok(Content::empty());
@ -669,6 +671,7 @@ struct UpdateElem {
} }
impl Show for UpdateElem { impl Show for UpdateElem {
#[tracing::instrument(name = "UpdateElem::show", skip(self))]
fn show(&self, _: &mut Vt, _: StyleChain) -> SourceResult<Content> { fn show(&self, _: &mut Vt, _: StyleChain) -> SourceResult<Content> {
Ok(Content::empty()) Ok(Content::empty())
} }

View File

@ -43,7 +43,10 @@ impl Construct for DocumentElem {
impl LayoutRoot for DocumentElem { impl LayoutRoot for DocumentElem {
/// Layout the document into a sequence of frames, one per page. /// Layout the document into a sequence of frames, one per page.
#[tracing::instrument(name = "DocumentElem::layout_root", skip_all)]
fn layout_root(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Document> { fn layout_root(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Document> {
tracing::info!("Document layout");
let mut pages = vec![]; let mut pages = vec![];
for mut child in &self.children() { for mut child in &self.children() {

View File

@ -237,6 +237,7 @@ impl Synthesize for FigureElem {
} }
impl Show for FigureElem { impl Show for FigureElem {
#[tracing::instrument(name = "FigureElem::show", skip_all)]
fn show(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Content> { fn show(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Content> {
// We build the body of the figure. // We build the body of the figure.
let mut realized = self.body(); let mut realized = self.body();

View File

@ -108,6 +108,7 @@ impl Synthesize for HeadingElem {
} }
impl Show for HeadingElem { impl Show for HeadingElem {
#[tracing::instrument(name = "HeadingElem::show", skip_all)]
fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> { fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> {
let mut realized = self.body(); let mut realized = self.body();
if let Some(numbering) = self.numbering(styles) { if let Some(numbering) = self.numbering(styles) {

View File

@ -88,6 +88,7 @@ impl LinkElem {
} }
impl Show for LinkElem { impl Show for LinkElem {
#[tracing::instrument(name = "LinkElem::show", skip(self, vt))]
fn show(&self, vt: &mut Vt, _: StyleChain) -> SourceResult<Content> { fn show(&self, vt: &mut Vt, _: StyleChain) -> SourceResult<Content> {
let body = self.body(); let body = self.body();
let dest = match self.dest() { let dest = match self.dest() {

View File

@ -131,6 +131,7 @@ pub struct OutlineElem {
} }
impl Show for OutlineElem { impl Show for OutlineElem {
#[tracing::instrument(name = "OutlineElem::show", skip_all)]
fn show(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Content> { fn show(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Content> {
let mut seq = vec![ParbreakElem::new().pack()]; let mut seq = vec![ParbreakElem::new().pack()];
// Build the outline title. // Build the outline title.

View File

@ -146,6 +146,7 @@ impl Synthesize for RefElem {
} }
impl Show for RefElem { impl Show for RefElem {
#[tracing::instrument(name = "RefElem::show", skip_all)]
fn show(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Content> { fn show(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Content> {
if !vt.introspector.init() { if !vt.introspector.init() {
return Ok(Content::empty()); return Ok(Content::empty());

View File

@ -256,6 +256,7 @@ pub struct State {
impl State { impl State {
/// Call a method on a state. /// Call a method on a state.
#[tracing::instrument(skip(vm))]
pub fn call_method( pub fn call_method(
self, self,
vm: &mut Vm, vm: &mut Vm,
@ -280,6 +281,7 @@ impl State {
} }
/// Get the value of the state at the given location. /// Get the value of the state at the given location.
#[tracing::instrument(skip(self, vt))]
pub fn at(self, vt: &mut Vt, location: Location) -> SourceResult<Value> { pub fn at(self, vt: &mut Vt, location: Location) -> SourceResult<Value> {
let sequence = self.sequence(vt)?; let sequence = self.sequence(vt)?;
let offset = vt let offset = vt
@ -290,6 +292,7 @@ impl State {
} }
/// Get the value of the state at the final location. /// Get the value of the state at the final location.
#[tracing::instrument(skip(self, vt))]
pub fn final_(self, vt: &mut Vt, _: Location) -> SourceResult<Value> { pub fn final_(self, vt: &mut Vt, _: Location) -> SourceResult<Value> {
let sequence = self.sequence(vt)?; let sequence = self.sequence(vt)?;
Ok(sequence.last().unwrap().clone()) Ok(sequence.last().unwrap().clone())
@ -395,6 +398,7 @@ struct DisplayElem {
} }
impl Show for DisplayElem { impl Show for DisplayElem {
#[tracing::instrument(name = "DisplayElem::show", skip(self, vt))]
fn show(&self, vt: &mut Vt, _: StyleChain) -> SourceResult<Content> { fn show(&self, vt: &mut Vt, _: StyleChain) -> SourceResult<Content> {
if !vt.introspector.init() { if !vt.introspector.init() {
return Ok(Content::empty()); return Ok(Content::empty());
@ -425,6 +429,7 @@ struct UpdateElem {
} }
impl Show for UpdateElem { impl Show for UpdateElem {
#[tracing::instrument(name = "UpdateElem::show")]
fn show(&self, _: &mut Vt, _: StyleChain) -> SourceResult<Content> { fn show(&self, _: &mut Vt, _: StyleChain) -> SourceResult<Content> {
Ok(Content::empty()) Ok(Content::empty())
} }

View File

@ -66,6 +66,7 @@ pub struct UnderlineElem {
} }
impl Show for UnderlineElem { impl Show for UnderlineElem {
#[tracing::instrument(name = "UnderlineElem::show", skip_all)]
fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> { fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> {
Ok(self.body().styled(TextElem::set_deco(Decoration { Ok(self.body().styled(TextElem::set_deco(Decoration {
line: DecoLine::Underline, line: DecoLine::Underline,
@ -145,6 +146,7 @@ pub struct OverlineElem {
} }
impl Show for OverlineElem { impl Show for OverlineElem {
#[tracing::instrument(name = "OverlineElem::show", skip_all)]
fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> { fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> {
Ok(self.body().styled(TextElem::set_deco(Decoration { Ok(self.body().styled(TextElem::set_deco(Decoration {
line: DecoLine::Overline, line: DecoLine::Overline,
@ -209,6 +211,7 @@ pub struct StrikeElem {
} }
impl Show for StrikeElem { impl Show for StrikeElem {
#[tracing::instrument(name = "StrikeElem::show", skip_all)]
fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> { fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> {
Ok(self.body().styled(TextElem::set_deco(Decoration { Ok(self.body().styled(TextElem::set_deco(Decoration {
line: DecoLine::Strikethrough, line: DecoLine::Strikethrough,

View File

@ -105,6 +105,7 @@ pub struct StrongElem {
} }
impl Show for StrongElem { impl Show for StrongElem {
#[tracing::instrument(name = "StrongElem::show", skip_all)]
fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> { fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> {
Ok(self.body().styled(TextElem::set_delta(Delta(self.delta(styles))))) Ok(self.body().styled(TextElem::set_delta(Delta(self.delta(styles)))))
} }
@ -165,6 +166,7 @@ pub struct EmphElem {
} }
impl Show for EmphElem { impl Show for EmphElem {
#[tracing::instrument(name = "EmphElem::show", skip(self))]
fn show(&self, _: &mut Vt, _: StyleChain) -> SourceResult<Content> { fn show(&self, _: &mut Vt, _: StyleChain) -> SourceResult<Content> {
Ok(self.body().styled(TextElem::set_emph(Toggle))) Ok(self.body().styled(TextElem::set_emph(Toggle)))
} }

View File

@ -129,6 +129,7 @@ impl Synthesize for RawElem {
} }
impl Show for RawElem { impl Show for RawElem {
#[tracing::instrument(name = "RawElem::show", skip_all)]
fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> { fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> {
let text = self.text(); let text = self.text();
let lang = self.lang(styles).as_ref().map(|s| s.to_lowercase()); let lang = self.lang(styles).as_ref().map(|s| s.to_lowercase());

View File

@ -45,6 +45,7 @@ pub struct SubElem {
} }
impl Show for SubElem { impl Show for SubElem {
#[tracing::instrument(name = "SubElem::show", skip_all)]
fn show(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Content> { fn show(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Content> {
let body = self.body(); let body = self.body();
let mut transformed = None; let mut transformed = None;
@ -107,6 +108,7 @@ pub struct SuperElem {
} }
impl Show for SuperElem { impl Show for SuperElem {
#[tracing::instrument(name = "SuperElem::show", skip_all)]
fn show(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Content> { fn show(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Content> {
let body = self.body(); let body = self.body();
let mut transformed = None; let mut transformed = None;

View File

@ -52,6 +52,7 @@ pub struct ImageElem {
} }
impl Layout for ImageElem { impl Layout for ImageElem {
#[tracing::instrument(name = "ImageElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,

View File

@ -73,6 +73,7 @@ pub struct LineElem {
} }
impl Layout for LineElem { impl Layout for LineElem {
#[tracing::instrument(name = "LineElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
_: &mut Vt, _: &mut Vt,

View File

@ -60,6 +60,7 @@ pub struct PathElem {
} }
impl Layout for PathElem { impl Layout for PathElem {
#[tracing::instrument(name = "PathElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
_: &mut Vt, _: &mut Vt,

View File

@ -49,6 +49,7 @@ pub struct PolygonElem {
} }
impl Layout for PolygonElem { impl Layout for PolygonElem {
#[tracing::instrument(name = "PolygonElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
_: &mut Vt, _: &mut Vt,

View File

@ -154,6 +154,7 @@ pub struct RectElem {
} }
impl Layout for RectElem { impl Layout for RectElem {
#[tracing::instrument(name = "RectElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,
@ -264,6 +265,7 @@ pub struct SquareElem {
} }
impl Layout for SquareElem { impl Layout for SquareElem {
#[tracing::instrument(name = "SquareElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,
@ -346,6 +348,7 @@ pub struct EllipseElem {
} }
impl Layout for EllipseElem { impl Layout for EllipseElem {
#[tracing::instrument(name = "EllipseElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,
@ -453,6 +456,7 @@ pub struct CircleElem {
} }
impl Layout for CircleElem { impl Layout for CircleElem {
#[tracing::instrument(name = "CircleElem::layout", skip_all)]
fn layout( fn layout(
&self, &self,
vt: &mut Vt, vt: &mut Vt,
@ -477,6 +481,7 @@ impl Layout for CircleElem {
} }
/// Layout a shape. /// Layout a shape.
#[tracing::instrument(name = "shape::layout", skip_all)]
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn layout( fn layout(
vt: &mut Vt, vt: &mut Vt,

View File

@ -75,6 +75,12 @@ impl Func {
/// Call the function with the given arguments. /// Call the function with the given arguments.
pub fn call_vm(&self, vm: &mut Vm, mut args: Args) -> SourceResult<Value> { pub fn call_vm(&self, vm: &mut Vm, mut args: Args) -> SourceResult<Value> {
let _span = tracing::info_span!(
"call",
name = self.name().unwrap_or("<anon>"),
file = 0,
);
match &self.repr { match &self.repr {
Repr::Native(native) => { Repr::Native(native) => {
let value = (native.func)(vm, &mut args)?; let value = (native.func)(vm, &mut args)?;
@ -111,6 +117,7 @@ impl Func {
} }
/// Call the function with a Vt. /// Call the function with a Vt.
#[tracing::instrument(skip_all)]
pub fn call_vt( pub fn call_vt(
&self, &self,
vt: &mut Vt, vt: &mut Vt,
@ -281,6 +288,7 @@ pub enum Param {
impl Closure { impl Closure {
/// Call the function in the context with the arguments. /// Call the function in the context with the arguments.
#[comemo::memoize] #[comemo::memoize]
#[tracing::instrument(skip_all)]
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn call( fn call(
this: &Func, this: &Func,
@ -399,6 +407,7 @@ impl<'a> CapturesVisitor<'a> {
} }
/// Visit any node and collect all captured variables. /// Visit any node and collect all captured variables.
#[tracing::instrument(skip_all)]
pub fn visit(&mut self, node: &SyntaxNode) { pub fn visit(&mut self, node: &SyntaxNode) {
match node.cast() { match node.cast() {
// Every identifier is a potential variable that we need to capture. // Every identifier is a potential variable that we need to capture.

View File

@ -64,6 +64,7 @@ const MAX_CALL_DEPTH: usize = 64;
/// Evaluate a source file and return the resulting module. /// Evaluate a source file and return the resulting module.
#[comemo::memoize] #[comemo::memoize]
#[tracing::instrument(skip(world, route, tracer, source))]
pub fn eval( pub fn eval(
world: Tracked<dyn World>, world: Tracked<dyn World>,
route: Tracked<Route>, route: Tracked<Route>,
@ -203,6 +204,7 @@ impl<'a> Vm<'a> {
} }
/// Define a variable in the current scope. /// Define a variable in the current scope.
#[tracing::instrument(skip_all)]
pub fn define(&mut self, var: ast::Ident, value: impl Into<Value>) { pub fn define(&mut self, var: ast::Ident, value: impl Into<Value>) {
let value = value.into(); let value = value.into();
if self.traced == Some(var.span()) { if self.traced == Some(var.span()) {
@ -213,6 +215,7 @@ impl<'a> Vm<'a> {
/// Resolve a user-entered path to be relative to the compilation /// Resolve a user-entered path to be relative to the compilation
/// environment's root. /// environment's root.
#[tracing::instrument(skip_all)]
pub fn locate(&self, path: &str) -> StrResult<PathBuf> { pub fn locate(&self, path: &str) -> StrResult<PathBuf> {
if !self.location.is_detached() { if !self.location.is_detached() {
if let Some(path) = path.strip_prefix('/') { if let Some(path) = path.strip_prefix('/') {
@ -402,6 +405,7 @@ fn eval_markup(
impl Eval for ast::Expr { impl Eval for ast::Expr {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "Expr::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let span = self.span(); let span = self.span();
let forbidden = |name| { let forbidden = |name| {
@ -482,6 +486,7 @@ impl ast::Expr {
impl Eval for ast::Text { impl Eval for ast::Text {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "Text::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
Ok((vm.items.text)(self.get().clone())) Ok((vm.items.text)(self.get().clone()))
} }
@ -490,6 +495,7 @@ impl Eval for ast::Text {
impl Eval for ast::Space { impl Eval for ast::Space {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "Space::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
Ok((vm.items.space)()) Ok((vm.items.space)())
} }
@ -498,6 +504,7 @@ impl Eval for ast::Space {
impl Eval for ast::Linebreak { impl Eval for ast::Linebreak {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "Linebreak::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
Ok((vm.items.linebreak)()) Ok((vm.items.linebreak)())
} }
@ -506,6 +513,7 @@ impl Eval for ast::Linebreak {
impl Eval for ast::Parbreak { impl Eval for ast::Parbreak {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "Parbreak::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
Ok((vm.items.parbreak)()) Ok((vm.items.parbreak)())
} }
@ -514,6 +522,7 @@ impl Eval for ast::Parbreak {
impl Eval for ast::Escape { impl Eval for ast::Escape {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "Escape::eval", skip_all)]
fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> {
Ok(Value::Symbol(Symbol::new(self.get()))) Ok(Value::Symbol(Symbol::new(self.get())))
} }
@ -522,6 +531,7 @@ impl Eval for ast::Escape {
impl Eval for ast::Shorthand { impl Eval for ast::Shorthand {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "Shorthand::eval", skip_all)]
fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> {
Ok(Value::Symbol(Symbol::new(self.get()))) Ok(Value::Symbol(Symbol::new(self.get())))
} }
@ -530,6 +540,7 @@ impl Eval for ast::Shorthand {
impl Eval for ast::SmartQuote { impl Eval for ast::SmartQuote {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "SmartQuote::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
Ok((vm.items.smart_quote)(self.double())) Ok((vm.items.smart_quote)(self.double()))
} }
@ -538,6 +549,7 @@ impl Eval for ast::SmartQuote {
impl Eval for ast::Strong { impl Eval for ast::Strong {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "Strong::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
Ok((vm.items.strong)(self.body().eval(vm)?)) Ok((vm.items.strong)(self.body().eval(vm)?))
} }
@ -546,6 +558,7 @@ impl Eval for ast::Strong {
impl Eval for ast::Emph { impl Eval for ast::Emph {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "Emph::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
Ok((vm.items.emph)(self.body().eval(vm)?)) Ok((vm.items.emph)(self.body().eval(vm)?))
} }
@ -554,6 +567,7 @@ impl Eval for ast::Emph {
impl Eval for ast::Raw { impl Eval for ast::Raw {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "Raw::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let text = self.text(); let text = self.text();
let lang = self.lang().map(Into::into); let lang = self.lang().map(Into::into);
@ -565,6 +579,7 @@ impl Eval for ast::Raw {
impl Eval for ast::Link { impl Eval for ast::Link {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "Link::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
Ok((vm.items.link)(self.get().clone())) Ok((vm.items.link)(self.get().clone()))
} }
@ -573,6 +588,7 @@ impl Eval for ast::Link {
impl Eval for ast::Label { impl Eval for ast::Label {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "Label::eval", skip_all)]
fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> {
Ok(Value::Label(Label(self.get().into()))) Ok(Value::Label(Label(self.get().into())))
} }
@ -581,6 +597,7 @@ impl Eval for ast::Label {
impl Eval for ast::Ref { impl Eval for ast::Ref {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "Ref::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let label = Label(self.target().into()); let label = Label(self.target().into());
let supplement = self.supplement().map(|block| block.eval(vm)).transpose()?; let supplement = self.supplement().map(|block| block.eval(vm)).transpose()?;
@ -591,6 +608,7 @@ impl Eval for ast::Ref {
impl Eval for ast::Heading { impl Eval for ast::Heading {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "Heading::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let level = self.level(); let level = self.level();
let body = self.body().eval(vm)?; let body = self.body().eval(vm)?;
@ -601,6 +619,7 @@ impl Eval for ast::Heading {
impl Eval for ast::ListItem { impl Eval for ast::ListItem {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "ListItem::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
Ok((vm.items.list_item)(self.body().eval(vm)?)) Ok((vm.items.list_item)(self.body().eval(vm)?))
} }
@ -609,6 +628,7 @@ impl Eval for ast::ListItem {
impl Eval for ast::EnumItem { impl Eval for ast::EnumItem {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "EnumItem::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let number = self.number(); let number = self.number();
let body = self.body().eval(vm)?; let body = self.body().eval(vm)?;
@ -619,6 +639,7 @@ impl Eval for ast::EnumItem {
impl Eval for ast::TermItem { impl Eval for ast::TermItem {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "TermItem::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let term = self.term().eval(vm)?; let term = self.term().eval(vm)?;
let description = self.description().eval(vm)?; let description = self.description().eval(vm)?;
@ -629,6 +650,7 @@ impl Eval for ast::TermItem {
impl Eval for ast::Equation { impl Eval for ast::Equation {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "Equation::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let body = self.body().eval(vm)?; let body = self.body().eval(vm)?;
let block = self.block(); let block = self.block();
@ -639,6 +661,7 @@ impl Eval for ast::Equation {
impl Eval for ast::Math { impl Eval for ast::Math {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "Math::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
Ok(Content::sequence( Ok(Content::sequence(
self.exprs() self.exprs()
@ -651,6 +674,7 @@ impl Eval for ast::Math {
impl Eval for ast::MathIdent { impl Eval for ast::MathIdent {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "MathIdent::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
vm.scopes.get_in_math(self).cloned().at(self.span()) vm.scopes.get_in_math(self).cloned().at(self.span())
} }
@ -659,6 +683,7 @@ impl Eval for ast::MathIdent {
impl Eval for ast::MathAlignPoint { impl Eval for ast::MathAlignPoint {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "MathAlignPoint::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
Ok((vm.items.math_align_point)()) Ok((vm.items.math_align_point)())
} }
@ -667,6 +692,7 @@ impl Eval for ast::MathAlignPoint {
impl Eval for ast::MathDelimited { impl Eval for ast::MathDelimited {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "MathDelimited::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let open = self.open().eval_display(vm)?; let open = self.open().eval_display(vm)?;
let body = self.body().eval(vm)?; let body = self.body().eval(vm)?;
@ -678,6 +704,7 @@ impl Eval for ast::MathDelimited {
impl Eval for ast::MathAttach { impl Eval for ast::MathAttach {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "MathAttach::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let base = self.base().eval_display(vm)?; let base = self.base().eval_display(vm)?;
let bottom = self.bottom().map(|expr| expr.eval_display(vm)).transpose()?; let bottom = self.bottom().map(|expr| expr.eval_display(vm)).transpose()?;
@ -689,6 +716,7 @@ impl Eval for ast::MathAttach {
impl Eval for ast::MathFrac { impl Eval for ast::MathFrac {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "MathFrac::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let num = self.num().eval_display(vm)?; let num = self.num().eval_display(vm)?;
let denom = self.denom().eval_display(vm)?; let denom = self.denom().eval_display(vm)?;
@ -699,6 +727,7 @@ impl Eval for ast::MathFrac {
impl Eval for ast::Ident { impl Eval for ast::Ident {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "Ident::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
vm.scopes.get(self).cloned().at(self.span()) vm.scopes.get(self).cloned().at(self.span())
} }
@ -707,6 +736,7 @@ impl Eval for ast::Ident {
impl Eval for ast::None { impl Eval for ast::None {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "None::eval", skip_all)]
fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> {
Ok(Value::None) Ok(Value::None)
} }
@ -715,6 +745,7 @@ impl Eval for ast::None {
impl Eval for ast::Auto { impl Eval for ast::Auto {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "Auto::eval", skip_all)]
fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> {
Ok(Value::Auto) Ok(Value::Auto)
} }
@ -723,6 +754,7 @@ impl Eval for ast::Auto {
impl Eval for ast::Bool { impl Eval for ast::Bool {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "Bool::eval", skip_all)]
fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> {
Ok(Value::Bool(self.get())) Ok(Value::Bool(self.get()))
} }
@ -731,6 +763,7 @@ impl Eval for ast::Bool {
impl Eval for ast::Int { impl Eval for ast::Int {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "Int::eval", skip_all)]
fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> {
Ok(Value::Int(self.get())) Ok(Value::Int(self.get()))
} }
@ -739,6 +772,7 @@ impl Eval for ast::Int {
impl Eval for ast::Float { impl Eval for ast::Float {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "Float::eval", skip_all)]
fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> {
Ok(Value::Float(self.get())) Ok(Value::Float(self.get()))
} }
@ -747,6 +781,7 @@ impl Eval for ast::Float {
impl Eval for ast::Numeric { impl Eval for ast::Numeric {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "Numeric::eval", skip_all)]
fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> {
Ok(Value::numeric(self.get())) Ok(Value::numeric(self.get()))
} }
@ -755,6 +790,7 @@ impl Eval for ast::Numeric {
impl Eval for ast::Str { impl Eval for ast::Str {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "Str::eval", skip_all)]
fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, _: &mut Vm) -> SourceResult<Self::Output> {
Ok(Value::Str(self.get().into())) Ok(Value::Str(self.get().into()))
} }
@ -763,6 +799,7 @@ impl Eval for ast::Str {
impl Eval for ast::CodeBlock { impl Eval for ast::CodeBlock {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "CodeBlock::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
vm.scopes.enter(); vm.scopes.enter();
let output = self.body().eval(vm)?; let output = self.body().eval(vm)?;
@ -828,6 +865,7 @@ fn eval_code(
impl Eval for ast::ContentBlock { impl Eval for ast::ContentBlock {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "ContentBlock::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
vm.scopes.enter(); vm.scopes.enter();
let content = self.body().eval(vm)?; let content = self.body().eval(vm)?;
@ -839,6 +877,7 @@ impl Eval for ast::ContentBlock {
impl Eval for ast::Parenthesized { impl Eval for ast::Parenthesized {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "Parenthesized::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
self.expr().eval(vm) self.expr().eval(vm)
} }
@ -847,6 +886,7 @@ impl Eval for ast::Parenthesized {
impl Eval for ast::Array { impl Eval for ast::Array {
type Output = Array; type Output = Array;
#[tracing::instrument(skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let items = self.items(); let items = self.items();
@ -869,6 +909,7 @@ impl Eval for ast::Array {
impl Eval for ast::Dict { impl Eval for ast::Dict {
type Output = Dict; type Output = Dict;
#[tracing::instrument(skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let mut map = indexmap::IndexMap::new(); let mut map = indexmap::IndexMap::new();
@ -899,6 +940,7 @@ impl Eval for ast::Dict {
impl Eval for ast::Unary { impl Eval for ast::Unary {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "Unary::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let value = self.expr().eval(vm)?; let value = self.expr().eval(vm)?;
let result = match self.op() { let result = match self.op() {
@ -913,6 +955,7 @@ impl Eval for ast::Unary {
impl Eval for ast::Binary { impl Eval for ast::Binary {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "Binary::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
match self.op() { match self.op() {
ast::BinOp::Add => self.apply(vm, ops::add), ast::BinOp::Add => self.apply(vm, ops::add),
@ -987,6 +1030,7 @@ impl ast::Binary {
impl Eval for ast::FieldAccess { impl Eval for ast::FieldAccess {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "FieldAccess::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let value = self.target().eval(vm)?; let value = self.target().eval(vm)?;
let field = self.field(); let field = self.field();
@ -997,6 +1041,7 @@ impl Eval for ast::FieldAccess {
impl Eval for ast::FuncCall { impl Eval for ast::FuncCall {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "FuncCall::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let span = self.span(); let span = self.span();
if vm.depth >= MAX_CALL_DEPTH { if vm.depth >= MAX_CALL_DEPTH {
@ -1074,7 +1119,10 @@ impl Eval for ast::FuncCall {
let callee = callee.cast::<Func>().at(callee_span)?; let callee = callee.cast::<Func>().at(callee_span)?;
let point = || Tracepoint::Call(callee.name().map(Into::into)); let point = || Tracepoint::Call(callee.name().map(Into::into));
stacker::maybe_grow(32 * 1024, 2 * 1024 * 1024, || {
callee.call_vm(vm, args).trace(vm.world(), point, span) callee.call_vm(vm, args).trace(vm.world(), point, span)
})
} }
} }
@ -1138,6 +1186,7 @@ impl Eval for ast::Args {
impl Eval for ast::Closure { impl Eval for ast::Closure {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "Closure::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
// The closure's name is defined by its let binding if there's one. // The closure's name is defined by its let binding if there's one.
let name = self.name(); let name = self.name();
@ -1179,6 +1228,7 @@ impl Eval for ast::Closure {
impl ast::Pattern { impl ast::Pattern {
// Destruct the given value into the pattern. // Destruct the given value into the pattern.
#[tracing::instrument(skip_all)]
pub fn define(&self, vm: &mut Vm, value: Value) -> SourceResult<Value> { pub fn define(&self, vm: &mut Vm, value: Value) -> SourceResult<Value> {
match self { match self {
ast::Pattern::Ident(ident) => { ast::Pattern::Ident(ident) => {
@ -1274,6 +1324,7 @@ impl ast::Pattern {
impl Eval for ast::LetBinding { impl Eval for ast::LetBinding {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "LetBinding::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let value = match self.init() { let value = match self.init() {
Some(expr) => expr.eval(vm)?, Some(expr) => expr.eval(vm)?,
@ -1339,6 +1390,7 @@ impl Eval for ast::ShowRule {
impl Eval for ast::Conditional { impl Eval for ast::Conditional {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "Conditional::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let condition = self.condition(); let condition = self.condition();
if condition.eval(vm)?.cast::<bool>().at(condition.span())? { if condition.eval(vm)?.cast::<bool>().at(condition.span())? {
@ -1354,6 +1406,7 @@ impl Eval for ast::Conditional {
impl Eval for ast::WhileLoop { impl Eval for ast::WhileLoop {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "WhileLoop::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let flow = vm.flow.take(); let flow = vm.flow.take();
let mut output = Value::None; let mut output = Value::None;
@ -1421,6 +1474,7 @@ fn can_diverge(expr: &SyntaxNode) -> bool {
impl Eval for ast::ForLoop { impl Eval for ast::ForLoop {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "ForLoop::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let flow = vm.flow.take(); let flow = vm.flow.take();
let mut output = Value::None; let mut output = Value::None;
@ -1487,6 +1541,7 @@ impl Eval for ast::ForLoop {
impl Eval for ast::ModuleImport { impl Eval for ast::ModuleImport {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "ModuleImport::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let span = self.source().span(); let span = self.source().span();
let source = self.source().eval(vm)?; let source = self.source().eval(vm)?;
@ -1523,6 +1578,7 @@ impl Eval for ast::ModuleImport {
impl Eval for ast::ModuleInclude { impl Eval for ast::ModuleInclude {
type Output = Content; type Output = Content;
#[tracing::instrument(name = "ModuleInclude::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let span = self.source().span(); let span = self.source().span();
let source = self.source().eval(vm)?; let source = self.source().eval(vm)?;
@ -1559,6 +1615,7 @@ fn import(vm: &mut Vm, source: Value, span: Span) -> SourceResult<Module> {
impl Eval for ast::LoopBreak { impl Eval for ast::LoopBreak {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "LoopBreak::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
if vm.flow.is_none() { if vm.flow.is_none() {
vm.flow = Some(Flow::Break(self.span())); vm.flow = Some(Flow::Break(self.span()));
@ -1570,6 +1627,7 @@ impl Eval for ast::LoopBreak {
impl Eval for ast::LoopContinue { impl Eval for ast::LoopContinue {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "LoopContinue::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
if vm.flow.is_none() { if vm.flow.is_none() {
vm.flow = Some(Flow::Continue(self.span())); vm.flow = Some(Flow::Continue(self.span()));
@ -1581,6 +1639,7 @@ impl Eval for ast::LoopContinue {
impl Eval for ast::FuncReturn { impl Eval for ast::FuncReturn {
type Output = Value; type Output = Value;
#[tracing::instrument(name = "FuncReturn::eval", skip_all)]
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let value = self.body().map(|body| body.eval(vm)).transpose()?; let value = self.body().map(|body| body.eval(vm)).transpose()?;
if vm.flow.is_none() { if vm.flow.is_none() {

View File

@ -310,6 +310,7 @@ where
T::TYPE_NAME T::TYPE_NAME
} }
#[tracing::instrument(skip_all)]
fn hash128(&self) -> u128 { fn hash128(&self) -> u128 {
// Also hash the TypeId since values with different types but // Also hash the TypeId since values with different types but
// equal data should be different. // equal data should be different.

View File

@ -9,6 +9,7 @@ use super::{deflate, EmExt, PdfContext, RefExt};
use crate::util::SliceExt; use crate::util::SliceExt;
/// Embed all used fonts into the PDF. /// Embed all used fonts into the PDF.
#[tracing::instrument(skip_all)]
pub fn write_fonts(ctx: &mut PdfContext) { pub fn write_fonts(ctx: &mut PdfContext) {
for font in ctx.font_map.items() { for font in ctx.font_map.items() {
let type0_ref = ctx.alloc.bump(); let type0_ref = ctx.alloc.bump();

View File

@ -7,6 +7,7 @@ use super::{deflate, PdfContext, RefExt};
use crate::image::{DecodedImage, RasterFormat}; use crate::image::{DecodedImage, RasterFormat};
/// Embed all used images into the PDF. /// Embed all used images into the PDF.
#[tracing::instrument(skip_all)]
pub fn write_images(ctx: &mut PdfContext) { pub fn write_images(ctx: &mut PdfContext) {
for image in ctx.image_map.items() { for image in ctx.image_map.items() {
let image_ref = ctx.alloc.bump(); let image_ref = ctx.alloc.bump();
@ -67,6 +68,7 @@ pub fn write_images(ctx: &mut PdfContext) {
/// whether the image has color. /// whether the image has color.
/// ///
/// Skips the alpha channel as that's encoded separately. /// Skips the alpha channel as that's encoded separately.
#[tracing::instrument(skip_all)]
fn encode_image( fn encode_image(
format: RasterFormat, format: RasterFormat,
dynamic: &DynamicImage, dynamic: &DynamicImage,
@ -111,6 +113,7 @@ fn encode_image(
} }
/// Encode an image's alpha channel if present. /// Encode an image's alpha channel if present.
#[tracing::instrument(skip_all)]
fn encode_alpha(dynamic: &DynamicImage) -> (Vec<u8>, Filter) { fn encode_alpha(dynamic: &DynamicImage) -> (Vec<u8>, Filter) {
let pixels: Vec<_> = dynamic.pixels().map(|(_, _, Rgba([_, _, _, a]))| a).collect(); let pixels: Vec<_> = dynamic.pixels().map(|(_, _, Rgba([_, _, _, a]))| a).collect();
(deflate(&pixels), Filter::FlateDecode) (deflate(&pixels), Filter::FlateDecode)

View File

@ -23,6 +23,7 @@ use crate::model::Introspector;
/// Export a document into a PDF file. /// Export a document into a PDF file.
/// ///
/// Returns the raw bytes making up the PDF file. /// Returns the raw bytes making up the PDF file.
#[tracing::instrument(skip_all)]
pub fn pdf(document: &Document) -> Vec<u8> { pub fn pdf(document: &Document) -> Vec<u8> {
let mut ctx = PdfContext::new(document); let mut ctx = PdfContext::new(document);
page::construct_pages(&mut ctx, &document.pages); page::construct_pages(&mut ctx, &document.pages);
@ -79,6 +80,7 @@ impl<'a> PdfContext<'a> {
} }
/// Write the document catalog. /// Write the document catalog.
#[tracing::instrument(skip_all)]
fn write_catalog(ctx: &mut PdfContext) { fn write_catalog(ctx: &mut PdfContext) {
let lang = ctx let lang = ctx
.languages .languages
@ -140,6 +142,7 @@ fn write_catalog(ctx: &mut PdfContext) {
} }
/// Compress data with the DEFLATE algorithm. /// Compress data with the DEFLATE algorithm.
#[tracing::instrument(skip_all)]
fn deflate(data: &[u8]) -> Vec<u8> { fn deflate(data: &[u8]) -> Vec<u8> {
const COMPRESSION_LEVEL: u8 = 6; const COMPRESSION_LEVEL: u8 = 6;
miniz_oxide::deflate::compress_to_vec_zlib(data, COMPRESSION_LEVEL) miniz_oxide::deflate::compress_to_vec_zlib(data, COMPRESSION_LEVEL)

View File

@ -8,6 +8,7 @@ use crate::model::Content;
use crate::util::NonZeroExt; use crate::util::NonZeroExt;
/// Construct the outline for the document. /// Construct the outline for the document.
#[tracing::instrument(skip_all)]
pub fn write_outline(ctx: &mut PdfContext) -> Option<Ref> { pub fn write_outline(ctx: &mut PdfContext) -> Option<Ref> {
let mut tree: Vec<HeadingNode> = vec![]; let mut tree: Vec<HeadingNode> = vec![];
for heading in ctx.introspector.query(&item!(heading_func).select()) { for heading in ctx.introspector.query(&item!(heading_func).select()) {
@ -81,6 +82,7 @@ impl HeadingNode {
} }
/// Write an outline item and all its children. /// Write an outline item and all its children.
#[tracing::instrument(skip_all)]
fn write_outline_item( fn write_outline_item(
ctx: &mut PdfContext, ctx: &mut PdfContext,
node: &HeadingNode, node: &HeadingNode,

View File

@ -15,6 +15,7 @@ use crate::geom::{
use crate::image::Image; use crate::image::Image;
/// Construct page objects. /// Construct page objects.
#[tracing::instrument(skip_all)]
pub fn construct_pages(ctx: &mut PdfContext, frames: &[Frame]) { pub fn construct_pages(ctx: &mut PdfContext, frames: &[Frame]) {
for frame in frames { for frame in frames {
construct_page(ctx, frame); construct_page(ctx, frame);
@ -22,6 +23,7 @@ pub fn construct_pages(ctx: &mut PdfContext, frames: &[Frame]) {
} }
/// Construct a page object. /// Construct a page object.
#[tracing::instrument(skip_all)]
pub fn construct_page(ctx: &mut PdfContext, frame: &Frame) { pub fn construct_page(ctx: &mut PdfContext, frame: &Frame) {
let page_ref = ctx.alloc.bump(); let page_ref = ctx.alloc.bump();
ctx.page_refs.push(page_ref); ctx.page_refs.push(page_ref);
@ -64,6 +66,7 @@ pub fn construct_page(ctx: &mut PdfContext, frame: &Frame) {
} }
/// Write the page tree. /// Write the page tree.
#[tracing::instrument(skip_all)]
pub fn write_page_tree(ctx: &mut PdfContext) { pub fn write_page_tree(ctx: &mut PdfContext) {
for page in std::mem::take(&mut ctx.pages).into_iter() { for page in std::mem::take(&mut ctx.pages).into_iter() {
write_page(ctx, page); write_page(ctx, page);
@ -100,6 +103,7 @@ pub fn write_page_tree(ctx: &mut PdfContext) {
} }
/// Write a page tree node. /// Write a page tree node.
#[tracing::instrument(skip_all)]
fn write_page(ctx: &mut PdfContext, page: Page) { fn write_page(ctx: &mut PdfContext, page: Page) {
let content_id = ctx.alloc.bump(); let content_id = ctx.alloc.bump();

View File

@ -64,6 +64,7 @@ use crate::syntax::{Source, SourceId};
use crate::util::Buffer; use crate::util::Buffer;
/// Compile a source file into a fully layouted document. /// Compile a source file into a fully layouted document.
#[tracing::instrument(skip(world))]
pub fn compile(world: &(dyn World + 'static)) -> SourceResult<Document> { pub fn compile(world: &(dyn World + 'static)) -> SourceResult<Document> {
// Evaluate the source file into a module. // Evaluate the source file into a module.
let route = Route::default(); let route = Route::default();
@ -71,6 +72,8 @@ pub fn compile(world: &(dyn World + 'static)) -> SourceResult<Document> {
let module = let module =
eval::eval(world.track(), route.track(), tracer.track_mut(), world.main())?; eval::eval(world.track(), route.track(), tracer.track_mut(), world.main())?;
tracing::info!("Evaluation successful");
// Typeset the module's contents. // Typeset the module's contents.
model::typeset(world.track(), tracer.track_mut(), &module.content()) model::typeset(world.track(), tracer.track_mut(), &module.content())
} }

View File

@ -39,16 +39,19 @@ enum Attr {
impl Content { impl Content {
/// Create an empty element. /// Create an empty element.
#[tracing::instrument()]
pub fn new(func: ElemFunc) -> Self { pub fn new(func: ElemFunc) -> Self {
Self { func, attrs: EcoVec::new() } Self { func, attrs: EcoVec::new() }
} }
/// Create empty content. /// Create empty content.
#[tracing::instrument()]
pub fn empty() -> Self { pub fn empty() -> Self {
Self::new(SequenceElem::func()) Self::new(SequenceElem::func())
} }
/// Create a new sequence element from multiples elements. /// Create a new sequence element from multiples elements.
#[tracing::instrument(skip_all)]
pub fn sequence(iter: impl IntoIterator<Item = Self>) -> Self { pub fn sequence(iter: impl IntoIterator<Item = Self>) -> Self {
let mut iter = iter.into_iter(); let mut iter = iter.into_iter();
let Some(first) = iter.next() else { return Self::empty() }; let Some(first) = iter.next() else { return Self::empty() };
@ -91,6 +94,7 @@ impl Content {
} }
/// Access the child and styles. /// Access the child and styles.
#[tracing::instrument(skip_all)]
pub fn to_styled(&self) -> Option<(&Content, &Styles)> { pub fn to_styled(&self) -> Option<(&Content, &Styles)> {
if !self.is::<StyledElem>() { if !self.is::<StyledElem>() {
return None; return None;
@ -116,6 +120,7 @@ impl Content {
/// Cast to a trait object if the contained element has the given /// Cast to a trait object if the contained element has the given
/// capability. /// capability.
#[tracing::instrument(skip_all)]
pub fn with<C>(&self) -> Option<&C> pub fn with<C>(&self) -> Option<&C>
where where
C: ?Sized + 'static, C: ?Sized + 'static,
@ -127,6 +132,7 @@ impl Content {
/// Cast to a mutable trait object if the contained element has the given /// Cast to a mutable trait object if the contained element has the given
/// capability. /// capability.
#[tracing::instrument(skip_all)]
pub fn with_mut<C>(&mut self) -> Option<&mut C> pub fn with_mut<C>(&mut self) -> Option<&mut C>
where where
C: ?Sized + 'static, C: ?Sized + 'static,
@ -174,6 +180,7 @@ impl Content {
} }
/// Access a field on the content. /// Access a field on the content.
#[tracing::instrument(skip_all)]
pub fn field(&self, name: &str) -> Option<Value> { pub fn field(&self, name: &str) -> Option<Value> {
if let (Some(iter), "children") = (self.to_sequence(), name) { if let (Some(iter), "children") = (self.to_sequence(), name) {
Some(Value::Array(iter.cloned().map(Value::Content).collect())) Some(Value::Array(iter.cloned().map(Value::Content).collect()))
@ -360,6 +367,7 @@ impl Content {
/// Queries the content tree for all elements that match the given selector. /// Queries the content tree for all elements that match the given selector.
/// ///
/// Elements produced in `show` rules will not be included in the results. /// Elements produced in `show` rules will not be included in the results.
#[tracing::instrument(skip_all)]
pub fn query(&self, selector: Selector) -> Vec<&Content> { pub fn query(&self, selector: Selector) -> Vec<&Content> {
let mut results = Vec::new(); let mut results = Vec::new();
self.traverse(&mut |element| { self.traverse(&mut |element| {

View File

@ -94,6 +94,7 @@ pub struct Introspector {
impl Introspector { impl Introspector {
/// Create a new introspector. /// Create a new introspector.
#[tracing::instrument(skip(frames))]
pub fn new(frames: &[Frame]) -> Self { pub fn new(frames: &[Frame]) -> Self {
let mut introspector = Self { let mut introspector = Self {
pages: frames.len(), pages: frames.len(),
@ -113,6 +114,7 @@ impl Introspector {
} }
/// Extract metadata from a frame. /// Extract metadata from a frame.
#[tracing::instrument(skip_all)]
fn extract(&mut self, frame: &Frame, page: NonZeroUsize, ts: Transform) { fn extract(&mut self, frame: &Frame, page: NonZeroUsize, ts: Transform) {
for (pos, item) in frame.items() { for (pos, item) in frame.items() {
match item { match item {
@ -154,6 +156,7 @@ impl Introspector {
} }
/// Query for all matching elements. /// Query for all matching elements.
#[tracing::instrument(skip_all)]
pub fn query<'a>(&'a self, selector: &'a Selector) -> Vec<Content> { pub fn query<'a>(&'a self, selector: &'a Selector) -> Vec<Content> {
match selector { match selector {
Selector::Location(location) => self Selector::Location(location) => self
@ -168,6 +171,7 @@ impl Introspector {
} }
/// Query for the first matching element. /// Query for the first matching element.
#[tracing::instrument(skip_all)]
pub fn query_first<'a>(&'a self, selector: &'a Selector) -> Option<Content> { pub fn query_first<'a>(&'a self, selector: &'a Selector) -> Option<Content> {
match selector { match selector {
Selector::Location(location) => { Selector::Location(location) => {
@ -178,6 +182,7 @@ impl Introspector {
} }
/// Query for a unique element with the label. /// Query for a unique element with the label.
#[tracing::instrument(skip(self))]
pub fn query_label(&self, label: &Label) -> StrResult<Content> { pub fn query_label(&self, label: &Label) -> StrResult<Content> {
let mut found = None; let mut found = None;
for elem in self.all().filter(|elem| elem.label() == Some(label)) { for elem in self.all().filter(|elem| elem.label() == Some(label)) {
@ -200,12 +205,14 @@ impl Introspector {
} }
/// Gets the page numbering for the given location, if any. /// Gets the page numbering for the given location, if any.
#[tracing::instrument(skip(self))]
pub fn page_numbering(&self, location: Location) -> Value { pub fn page_numbering(&self, location: Location) -> Value {
let page = self.page(location); let page = self.page(location);
self.page_numberings.get(page.get() - 1).cloned().unwrap_or_default() self.page_numberings.get(page.get() - 1).cloned().unwrap_or_default()
} }
/// Find the position for the given location. /// Find the position for the given location.
#[tracing::instrument(skip(self))]
pub fn position(&self, location: Location) -> Position { pub fn position(&self, location: Location) -> Position {
self.elems self.elems
.get(&location) .get(&location)

View File

@ -23,11 +23,13 @@ use crate::World;
/// Typeset content into a fully layouted document. /// Typeset content into a fully layouted document.
#[comemo::memoize] #[comemo::memoize]
#[tracing::instrument(skip(world, tracer, content))]
pub fn typeset( pub fn typeset(
world: Tracked<dyn World>, world: Tracked<dyn World>,
mut tracer: TrackedMut<Tracer>, mut tracer: TrackedMut<Tracer>,
content: &Content, content: &Content,
) -> SourceResult<Document> { ) -> SourceResult<Document> {
tracing::info!("Starting layout");
let library = world.library(); let library = world.library();
let styles = StyleChain::new(&library.styles); let styles = StyleChain::new(&library.styles);
@ -38,6 +40,8 @@ pub fn typeset(
// Relayout until all introspections stabilize. // Relayout until all introspections stabilize.
// If that doesn't happen within five attempts, we give up. // If that doesn't happen within five attempts, we give up.
loop { loop {
tracing::info!("Layout iteration {iter}");
let constraint = Constraint::new(); let constraint = Constraint::new();
let mut provider = StabilityProvider::new(); let mut provider = StabilityProvider::new();
let mut vt = Vt { let mut vt = Vt {

View File

@ -360,7 +360,7 @@ impl Selector {
Self::Before { selector, end: location, inclusive } => { Self::Before { selector, end: location, inclusive } => {
if let Some(content) = introspector.query_first(location) { if let Some(content) = introspector.query_first(location) {
let loc = content.location().unwrap(); let loc = content.location().unwrap();
Box::new(selector.match_iter_inner(introspector, parent).filter( Box::new(selector.match_iter_inner(introspector, parent).take_while(
move |elem| { move |elem| {
introspector.is_before( introspector.is_before(
elem.location().unwrap(), elem.location().unwrap(),
@ -376,12 +376,12 @@ impl Selector {
Self::After { selector, start: location, inclusive } => { Self::After { selector, start: location, inclusive } => {
if let Some(content) = introspector.query_first(location) { if let Some(content) = introspector.query_first(location) {
let loc = content.location().unwrap(); let loc = content.location().unwrap();
Box::new(selector.match_iter_inner(introspector, parent).filter( Box::new(selector.match_iter_inner(introspector, parent).skip_while(
move |elem| { move |elem| {
introspector.is_after( introspector.is_before(
elem.location().unwrap(), elem.location().unwrap(),
loc, loc,
*inclusive, !*inclusive,
) )
}, },
)) ))
@ -586,6 +586,7 @@ impl<'a> StyleChain<'a> {
/// The resulting style chain contains styles from `local` as well as /// The resulting style chain contains styles from `local` as well as
/// `self`. The ones from `local` take precedence over the ones from /// `self`. The ones from `local` take precedence over the ones from
/// `self`. For folded properties `local` contributes the inner value. /// `self`. For folded properties `local` contributes the inner value.
#[tracing::instrument(skip_all)]
pub fn chain<'b>(&'b self, local: &'b Styles) -> StyleChain<'b> { pub fn chain<'b>(&'b self, local: &'b Styles) -> StyleChain<'b> {
if local.is_empty() { if local.is_empty() {
*self *self
@ -595,6 +596,7 @@ impl<'a> StyleChain<'a> {
} }
/// Cast the first value for the given property in the chain. /// Cast the first value for the given property in the chain.
#[tracing::instrument(skip_all)]
pub fn get<T: Cast>( pub fn get<T: Cast>(
self, self,
func: ElemFunc, func: ElemFunc,
@ -608,6 +610,7 @@ impl<'a> StyleChain<'a> {
} }
/// Cast the first value for the given property in the chain. /// Cast the first value for the given property in the chain.
#[tracing::instrument(skip_all)]
pub fn get_resolve<T: Cast + Resolve>( pub fn get_resolve<T: Cast + Resolve>(
self, self,
func: ElemFunc, func: ElemFunc,
@ -619,6 +622,7 @@ impl<'a> StyleChain<'a> {
} }
/// Cast the first value for the given property in the chain. /// Cast the first value for the given property in the chain.
#[tracing::instrument(skip_all)]
pub fn get_fold<T: Cast + Fold>( pub fn get_fold<T: Cast + Fold>(
self, self,
func: ElemFunc, func: ElemFunc,
@ -640,6 +644,7 @@ impl<'a> StyleChain<'a> {
} }
/// Cast the first value for the given property in the chain. /// Cast the first value for the given property in the chain.
#[tracing::instrument(skip_all)]
pub fn get_resolve_fold<T>( pub fn get_resolve_fold<T>(
self, self,
func: ElemFunc, func: ElemFunc,
@ -674,6 +679,7 @@ impl<'a> StyleChain<'a> {
} }
/// Iterate over all values for the given property in the chain. /// Iterate over all values for the given property in the chain.
#[tracing::instrument(skip_all)]
pub fn properties<T: Cast + 'a>( pub fn properties<T: Cast + 'a>(
self, self,
func: ElemFunc, func: ElemFunc,

View File

@ -190,6 +190,7 @@ impl SyntaxNode {
} }
/// Assign spans to each node. /// Assign spans to each node.
#[tracing::instrument(skip_all)]
pub(super) fn numberize( pub(super) fn numberize(
&mut self, &mut self,
id: SourceId, id: SourceId,

View File

@ -28,6 +28,7 @@ pub struct Source {
impl Source { impl Source {
/// Create a new source file. /// Create a new source file.
#[tracing::instrument(skip_all)]
pub fn new(id: SourceId, path: &Path, text: String) -> Self { pub fn new(id: SourceId, path: &Path, text: String) -> Self {
let mut root = parse(&text); let mut root = parse(&text);
root.numberize(id, Span::FULL).unwrap(); root.numberize(id, Span::FULL).unwrap();

View File

@ -34,6 +34,7 @@ where
} }
/// Calculate a 128-bit siphash of a value. /// Calculate a 128-bit siphash of a value.
#[tracing::instrument(skip_all)]
pub fn hash128<T: Hash + ?Sized>(value: &T) -> u128 { pub fn hash128<T: Hash + ?Sized>(value: &T) -> u128 {
let mut state = SipHasher13::new(); let mut state = SipHasher13::new();
value.hash(&mut state); value.hash(&mut state);
@ -128,6 +129,7 @@ pub trait PathExt {
} }
impl PathExt for Path { impl PathExt for Path {
#[tracing::instrument(skip_all)]
fn normalize(&self) -> PathBuf { fn normalize(&self) -> PathBuf {
let mut out = PathBuf::new(); let mut out = PathBuf::new();
for component in self.components() { for component in self.components() {