diff options
| author | Laurenz <laurmaedje@gmail.com> | 2023-03-13 21:40:57 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2023-03-13 21:41:33 +0100 |
| commit | 724e9b140cc0a87208aa9c4914b1b8aeddf25c30 (patch) | |
| tree | 632984e85eb21c5a5a04c397a74725df6f7f8a28 /src/model/content.rs | |
| parent | 880b1847bd4170ce80be5781c2163ba085cdcaff (diff) | |
Locatability and synthesis improvements
Diffstat (limited to 'src/model/content.rs')
| -rw-r--r-- | src/model/content.rs | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/src/model/content.rs b/src/model/content.rs index 071a5862..58b80487 100644 --- a/src/model/content.rs +++ b/src/model/content.rs @@ -8,7 +8,7 @@ use comemo::Tracked; use ecow::{eco_format, EcoString, EcoVec}; use once_cell::sync::Lazy; -use super::{node, Guard, Recipe, Style, StyleMap}; +use super::{node, Guard, Locatable, Recipe, StableId, Style, StyleMap, Synthesize}; use crate::diag::{SourceResult, StrResult}; use crate::eval::{ cast_from_value, cast_to_value, Args, Cast, Func, FuncInfo, Str, Value, Vm, @@ -29,8 +29,9 @@ pub struct Content { /// Modifiers that can be attached to content. #[derive(Debug, Clone, PartialEq, Hash)] enum Modifier { - Synthesized, + Prepared, Guard(Guard), + Id(StableId), } impl Content { @@ -101,6 +102,16 @@ impl Content { Some(unsafe { &*crate::util::fat::from_raw_parts(data, vtable) }) } + /// Cast to a trait object if this content has the given capability. + pub fn with_mut<C>(&mut self) -> Option<&mut C> + where + C: ?Sized + 'static, + { + let vtable = (self.id.0.vtable)(TypeId::of::<C>())?; + let data = self as *mut Self as *mut (); + Some(unsafe { &mut *crate::util::fat::from_raw_parts_mut(data, vtable) }) + } + /// The node's span. pub fn span(&self) -> Span { self.span @@ -233,17 +244,6 @@ impl Content { self } - /// Mark this content as prepared. - pub fn synthesized(mut self) -> Self { - self.modifiers.push(Modifier::Synthesized); - self - } - - /// Whether this node was prepared. - pub fn is_synthesized(&self) -> bool { - self.modifiers.contains(&Modifier::Synthesized) - } - /// Whether no show rule was executed for this node so far. pub(super) fn is_pristine(&self) -> bool { !self @@ -257,6 +257,37 @@ impl Content { self.modifiers.contains(&Modifier::Guard(id)) } + /// Whether this node was prepared. + pub fn is_prepared(&self) -> bool { + self.modifiers.contains(&Modifier::Prepared) + } + + /// Whether the node needs to be realized specially. + pub fn needs_preparation(&self) -> bool { + (self.can::<dyn Locatable>() + || self.can::<dyn Synthesize>() + || self.label().is_some()) + && !self.is_prepared() + } + + /// Mark this content as prepared. + pub fn mark_prepared(&mut self) { + self.modifiers.push(Modifier::Prepared); + } + + /// Attach a stable id to this content. + pub fn set_stable_id(&mut self, id: StableId) { + self.modifiers.push(Modifier::Id(id)); + } + + /// This content's stable identifier. + pub fn stable_id(&self) -> Option<StableId> { + self.modifiers.iter().find_map(|modifier| match modifier { + Modifier::Id(id) => Some(*id), + _ => None, + }) + } + /// Copy the modifiers from another piece of content. pub(super) fn copy_modifiers(&mut self, from: &Content) { self.span = from.span; |
