wright/source_tracking.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
//! Types and traits for tracking source code fed to the wright compiler.
use self::source::Source;
use dashmap::DashMap;
use source::SourceId;
use std::sync::Arc;
pub mod filename;
pub mod fragment;
pub mod immutable_string;
pub mod source;
/// A reference to a [Source] in a [SourceMap].
pub type SourceRef = Arc<Source>;
/// Storage for [Source]s used and referenced in compiling a wright project.
///
/// [Clone]ing is cheap, since this uses an [Arc] internally.
#[derive(Debug, Default, Clone)]
pub struct SourceMap {
/// Internally, we use [DashMap] for a concurrent hashmap from [Source::id]s to their [Arc]'d
///
/// Each source is wrapped in an [Arc] to make them all accessible without holding a reference to this map
/// directly.
inner: Arc<DashMap<SourceId, SourceRef>>,
}
impl SourceMap {
/// Construct a new empty [SourceMap].
pub fn new() -> Self {
Default::default()
}
/// Add a [Source] to this [SourceMap] and get a [SourceRef] to it after it's added.
pub fn add(&self, source: Source) -> SourceRef {
// Put the source in an Arc.
let source: SourceRef = Arc::new(source);
// Push the souce to the internal Vec.
self.inner.insert(source.id, Arc::clone(&source));
// Return the now-Arc'd source.
source
}
/// Get a reference to a [Source] stored in this [SourceMap] using it's [Source::id].
///
/// This is currently `O(1)` since [SourceMap] uses a [DashMap] internally.
///
/// Returns [None] if the [Source] with the given [Source::id] is not in this [SourceMap].
pub fn get(&self, id: SourceId) -> Option<SourceRef> {
self.inner.get(&id).map(|source| Arc::clone(&source))
}
}