diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /third_party/rust/jsparagus-ast/src/associated_data.rs | |
parent | Initial commit. (diff) | |
download | firefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/jsparagus-ast/src/associated_data.rs')
-rw-r--r-- | third_party/rust/jsparagus-ast/src/associated_data.rs | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/third_party/rust/jsparagus-ast/src/associated_data.rs b/third_party/rust/jsparagus-ast/src/associated_data.rs new file mode 100644 index 0000000000..bdde80c0fd --- /dev/null +++ b/third_party/rust/jsparagus-ast/src/associated_data.rs @@ -0,0 +1,143 @@ +use crate::source_location_accessor::SourceLocationAccessor; +use crate::type_id::{NodeTypeId, NodeTypeIdAccessor}; +use crate::SourceLocation; +use std::collections::HashMap; + +#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] +struct Key { + type_id: NodeTypeId, + loc: SourceLocation, +} + +impl Key { + fn new<NodeT>(node: &NodeT) -> Self + where + NodeT: SourceLocationAccessor + NodeTypeIdAccessor, + { + Self { + type_id: node.get_type_id(), + loc: node.get_loc(), + } + } +} + +impl NodeTypeIdAccessor for Key { + fn get_type_id(&self) -> NodeTypeId { + self.type_id + } +} + +impl SourceLocationAccessor for Key { + fn set_loc(&mut self, start: SourceLocation, end: SourceLocation) { + self.loc.start = start.start; + self.loc.end = end.end; + } + + fn get_loc(&self) -> SourceLocation { + self.loc + } +} + +#[derive(Debug)] +struct Item<ValueT> { + #[allow(dead_code)] + key: Key, + value: ValueT, +} + +impl<ValueT> Item<ValueT> { + fn new(key: Key, value: ValueT) -> Self { + Self { key, value } + } +} + +type ItemIndex = usize; + +#[derive(Debug)] +pub struct AssociatedDataItemIndex { + index: ItemIndex, +} +impl AssociatedDataItemIndex { + fn new(index: ItemIndex) -> Self { + Self { index } + } +} + +// A map from AST node to `ValueT`, to associate extra data to AST node. +#[derive(Debug)] +pub struct AssociatedData<ValueT> { + items: Vec<Item<ValueT>>, + map: HashMap<Key, ItemIndex>, +} + +impl<ValueT> AssociatedData<ValueT> { + pub fn new() -> Self { + Self { + items: Vec::new(), + map: HashMap::new(), + } + } + + // Insert an item for `node`. + // Returns the index of the inserted item. + pub fn insert<NodeT>(&mut self, node: &NodeT, value: ValueT) -> AssociatedDataItemIndex + where + NodeT: SourceLocationAccessor + NodeTypeIdAccessor, + { + let index = self.items.len(); + let key = Key::new(node); + self.items.push(Item::new(key.clone(), value)); + self.map.insert(key, index); + + AssociatedDataItemIndex::new(index) + } + + // Get the immutable reference of the item for the index. + // The index is the return value of `insert` or `to_index`. + pub fn get_by_index(&self, index: AssociatedDataItemIndex) -> &ValueT { + // NOTE: This can panic if `index` is created by another instance of + // `AssociatedData`. + &self.items[index.index].value + } + + // Get the mutable reference of the item for the index. + // The index is the return value of `insert` or `to_index`. + pub fn get_mut_by_index(&mut self, index: AssociatedDataItemIndex) -> &mut ValueT { + // NOTE: This can panic if `index` is created by another instance of + // `AssociatedData`. + &mut self.items[index.index].value + } + + // Get the immutable reference of the item for `node`. + // `None` if there's no item inserted for `node`. + pub fn get<NodeT>(&self, node: &NodeT) -> Option<&ValueT> + where + NodeT: SourceLocationAccessor + NodeTypeIdAccessor, + { + self.to_index(node) + .and_then(|index| Some(self.get_by_index(index))) + } + + // Get the mutable reference of the item for `node`. + // `None` if there's no item inserted for `node`. + pub fn get_mut<NodeT>(&mut self, node: &NodeT) -> Option<&mut ValueT> + where + NodeT: SourceLocationAccessor + NodeTypeIdAccessor, + { + self.to_index(node) + .and_then(move |index| Some(self.get_mut_by_index(index))) + } + + // Returns the index for the item for `node`. + // `None` if there's no item inserted for `node`. + pub fn to_index<NodeT>(&self, node: &NodeT) -> Option<AssociatedDataItemIndex> + where + NodeT: SourceLocationAccessor + NodeTypeIdAccessor, + { + let key = Key::new(node); + match self.map.get(&key) { + Some(index) => Some(AssociatedDataItemIndex::new(*index)), + None => None, + } + } +} |