mirror of
https://github.com/typst/typst
synced 2025-05-15 09:35:28 +08:00
initial attempt at a local sink on call
This commit is contained in:
parent
e196e45c31
commit
3823f560c5
@ -325,22 +325,26 @@ impl Display for Tracepoint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enrich a [`SourceResult`] with a tracepoint.
|
/// Enrich diagnostics with a tracepoint.
|
||||||
pub trait Trace<T> {
|
pub trait Trace {
|
||||||
/// Add the tracepoint to all errors that lie outside the `span`.
|
/// Add the tracepoint to all diagnostics that lie outside the `span`.
|
||||||
fn trace<F>(self, world: Tracked<dyn World + '_>, make_point: F, span: Span) -> Self
|
fn trace<F>(self, world: Tracked<dyn World + '_>, make_point: F, span: Span) -> Self
|
||||||
where
|
where
|
||||||
F: Fn() -> Tracepoint;
|
F: Fn() -> Tracepoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Trace<T> for SourceResult<T> {
|
impl Trace for EcoVec<SourceDiagnostic> {
|
||||||
fn trace<F>(self, world: Tracked<dyn World + '_>, make_point: F, span: Span) -> Self
|
fn trace<F>(
|
||||||
|
mut self,
|
||||||
|
world: Tracked<dyn World + '_>,
|
||||||
|
make_point: F,
|
||||||
|
span: Span,
|
||||||
|
) -> Self
|
||||||
where
|
where
|
||||||
F: Fn() -> Tracepoint,
|
F: Fn() -> Tracepoint,
|
||||||
{
|
{
|
||||||
self.map_err(|mut errors| {
|
let Some(trace_range) = world.range(span) else { return self };
|
||||||
let Some(trace_range) = world.range(span) else { return errors };
|
for error in self.make_mut().iter_mut() {
|
||||||
for error in errors.make_mut().iter_mut() {
|
|
||||||
// Skip traces that surround the error.
|
// Skip traces that surround the error.
|
||||||
if let Some(error_range) = world.range(error.span) {
|
if let Some(error_range) = world.range(error.span) {
|
||||||
if error.span.id() == span.id()
|
if error.span.id() == span.id()
|
||||||
@ -353,8 +357,16 @@ impl<T> Trace<T> for SourceResult<T> {
|
|||||||
|
|
||||||
error.trace.push(Spanned::new(make_point(), span));
|
error.trace.push(Spanned::new(make_point(), span));
|
||||||
}
|
}
|
||||||
errors
|
self
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Trace for SourceResult<T> {
|
||||||
|
fn trace<F>(self, world: Tracked<dyn World + '_>, make_point: F, span: Span) -> Self
|
||||||
|
where
|
||||||
|
F: Fn() -> Tracepoint,
|
||||||
|
{
|
||||||
|
self.map_err(|errors| errors.trace(world, make_point, span))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ use comemo::{Track, Tracked, TrackedMut, Validate};
|
|||||||
use ecow::EcoVec;
|
use ecow::EcoVec;
|
||||||
use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator};
|
use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator};
|
||||||
|
|
||||||
use crate::diag::{self, Severity, SourceDiagnostic, SourceResult};
|
use crate::diag::{self, Severity, SourceDiagnostic, SourceResult, Trace, Tracepoint};
|
||||||
use crate::foundations::{Styles, Value};
|
use crate::foundations::{Styles, Value};
|
||||||
use crate::introspection::Introspector;
|
use crate::introspection::Introspector;
|
||||||
use crate::syntax::{ast, FileId, Span};
|
use crate::syntax::{ast, FileId, Span};
|
||||||
@ -161,6 +161,30 @@ impl Sink {
|
|||||||
self.values
|
self.values
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Takes and returns all fields from this sink:
|
||||||
|
/// delayed errors, warnings and traced values.
|
||||||
|
pub fn take(
|
||||||
|
self,
|
||||||
|
) -> (
|
||||||
|
EcoVec<SourceDiagnostic>,
|
||||||
|
EcoVec<SourceDiagnostic>,
|
||||||
|
EcoVec<(Value, Option<Styles>)>,
|
||||||
|
) {
|
||||||
|
(self.delayed, self.warnings, self.values)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds a tracepoint to all warnings outside the given span.
|
||||||
|
pub fn trace_warnings<F>(
|
||||||
|
&mut self,
|
||||||
|
world: Tracked<dyn World + '_>,
|
||||||
|
make_point: F,
|
||||||
|
span: Span,
|
||||||
|
) where
|
||||||
|
F: Fn() -> Tracepoint,
|
||||||
|
{
|
||||||
|
self.warnings = std::mem::take(&mut self.warnings).trace(world, make_point, span);
|
||||||
|
}
|
||||||
|
|
||||||
/// Apply warning suppression.
|
/// Apply warning suppression.
|
||||||
pub fn suppress_warnings(&mut self, world: &dyn World) {
|
pub fn suppress_warnings(&mut self, world: &dyn World) {
|
||||||
self.warnings.retain(|diag| {
|
self.warnings.retain(|diag| {
|
||||||
@ -204,7 +228,7 @@ impl Sink {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Extend from another sink.
|
/// Extend from another sink.
|
||||||
fn extend(
|
pub fn extend(
|
||||||
&mut self,
|
&mut self,
|
||||||
delayed: EcoVec<SourceDiagnostic>,
|
delayed: EcoVec<SourceDiagnostic>,
|
||||||
warnings: EcoVec<SourceDiagnostic>,
|
warnings: EcoVec<SourceDiagnostic>,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use comemo::{Tracked, TrackedMut};
|
use comemo::{Track, Tracked, TrackedMut};
|
||||||
use ecow::{eco_format, EcoVec};
|
use ecow::{eco_format, EcoVec};
|
||||||
|
|
||||||
use crate::diag::{bail, error, At, HintedStrResult, SourceResult, Trace, Tracepoint};
|
use crate::diag::{bail, error, At, HintedStrResult, SourceResult, Trace, Tracepoint};
|
||||||
@ -165,8 +165,31 @@ impl Eval for ast::FuncCall<'_> {
|
|||||||
|
|
||||||
let point = || Tracepoint::Call(func.name().map(Into::into));
|
let point = || Tracepoint::Call(func.name().map(Into::into));
|
||||||
let f = || {
|
let f = || {
|
||||||
func.call(&mut vm.engine, vm.context, args)
|
// Create a temporary sink to accumulate all warnings produced by
|
||||||
.trace(vm.world(), point, span)
|
// this call (either directly or due to a nested call). Later, we
|
||||||
|
// add a tracepoint to those warnings, indicating this call was
|
||||||
|
// part of the call stack that led to the warning being raised,
|
||||||
|
// thus allowing suppression of the warning through this call.
|
||||||
|
let mut local_sink = Sink::new();
|
||||||
|
let previous_sink =
|
||||||
|
std::mem::replace(&mut vm.engine.sink, local_sink.track_mut());
|
||||||
|
|
||||||
|
let call_result = func.call(&mut vm.engine, vm.context, args).trace(
|
||||||
|
vm.world(),
|
||||||
|
point,
|
||||||
|
span,
|
||||||
|
);
|
||||||
|
|
||||||
|
std::mem::replace(&mut vm.engine.sink, previous_sink);
|
||||||
|
local_sink.trace_warnings(vm.world(), point, span);
|
||||||
|
|
||||||
|
// Push the accumulated warnings and other fields back to the
|
||||||
|
// original sink after we have modified them. This is needed so the
|
||||||
|
// warnings are properly returned by compilation later.
|
||||||
|
let (delayed, warnings, values) = local_sink.take();
|
||||||
|
vm.engine.sink.extend(delayed, warnings, values);
|
||||||
|
|
||||||
|
call_result
|
||||||
};
|
};
|
||||||
|
|
||||||
// Stacker is broken on WASM.
|
// Stacker is broken on WASM.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user