summaryrefslogtreecommitdiffstats
path: root/third_party/rust/jsparagus-ast/src/source_atom_set.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/jsparagus-ast/src/source_atom_set.rs')
-rw-r--r--third_party/rust/jsparagus-ast/src/source_atom_set.rs221
1 files changed, 221 insertions, 0 deletions
diff --git a/third_party/rust/jsparagus-ast/src/source_atom_set.rs b/third_party/rust/jsparagus-ast/src/source_atom_set.rs
new file mode 100644
index 0000000000..25369c9777
--- /dev/null
+++ b/third_party/rust/jsparagus-ast/src/source_atom_set.rs
@@ -0,0 +1,221 @@
+use indexmap::set::IndexSet;
+
+/// Index into SourceAtomSet.atoms.
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+pub struct SourceAtomSetIndex {
+ index: usize,
+}
+impl SourceAtomSetIndex {
+ fn new(index: usize) -> Self {
+ Self { index }
+ }
+}
+
+impl From<SourceAtomSetIndex> for usize {
+ fn from(index: SourceAtomSetIndex) -> usize {
+ index.index
+ }
+}
+
+// Call $handler macro with the list of common atoms.
+//
+// Basic Usage:
+//
+// ```
+// for_all_common_atoms!(test);
+// ```
+//
+// is expanded to
+//
+// ```
+// test!(
+// ("arguments", arguments, Arguments),
+// ("async", async_, Async),
+// ...
+// );
+// ```
+//
+// Extra Parameters:
+//
+// ```
+// for_all_common_atoms!(test, foo, bar);
+// ```
+//
+// is expanded to
+//
+// ```
+// test!(
+// foo, bar,
+// ("arguments", arguments, Arguments),
+// ("async", async_, Async),
+// ...
+// );
+// ```
+macro_rules! for_all_common_atoms {
+ ($handler:ident $(, $($params:tt)*)?) => {
+ // string representation, method name, enum variant
+ $handler!(
+ $($($params)*,)?
+ ("arguments", arguments, Arguments),
+ ("as", as_, As),
+ ("async", async_, Async),
+ ("await", await_, Await),
+ ("break", break_, Break),
+ ("case", case, Case),
+ ("catch", catch, Catch),
+ ("class", class, Class),
+ ("const", const_, Const),
+ ("continue", continue_, Continue),
+ ("debugger", debugger, Debugger),
+ ("default", default, Default),
+ ("delete", delete, Delete),
+ ("do", do_, Do),
+ ("else", else_, Else),
+ ("enum", enum_, Enum),
+ ("eval", eval, Eval),
+ ("export", export, Export),
+ ("extends", extends, Extends),
+ ("false", false_, False),
+ ("finally", finally, Finally),
+ ("for", for_, For),
+ ("from", from, From),
+ ("function", function, Function),
+ ("get", get, Get),
+ ("if", if_, If),
+ ("implements", implements, Implements),
+ ("import", import, Import),
+ ("in", in_, In),
+ ("instanceof", instanceof, Instanceof),
+ ("interface", interface, Interface),
+ ("let", let_, Let),
+ ("new", new_, New),
+ ("null", null, Null),
+ ("of", of, Of),
+ ("package", package, Package),
+ ("private", private, Private),
+ ("protected", protected, Protected),
+ ("public", public, Public),
+ ("return", return_, Return),
+ ("set", set, Set),
+ ("static", static_, Static),
+ ("super", super_, Super),
+ ("switch", switch, Switch),
+ ("target", target, Target),
+ ("this", this, This),
+ ("throw", throw, Throw),
+ ("true", true_, True),
+ ("try", try_, Try),
+ ("typeof", typeof_, Typeof),
+ ("var", var, Var),
+ ("void", void, Void),
+ ("while", while_, While),
+ ("with", with, With),
+ ("yield", yield_, Yield),
+ ("use strict", use_strict, UseStrict),
+ ("__proto__", __proto__, Proto),
+ );
+ }
+}
+
+// Define CommonAtoms enum, with
+//
+// enum CommonAtoms {
+// Arguments = 0,
+// Async,
+// ...
+// }
+macro_rules! define_enum {
+ (($s0:tt, $method0:ident, $variant0:ident),
+ $(($s:tt, $method:ident, $variant:ident),)*) => {
+ enum CommonAtoms {
+ $variant0 = 0,
+ $($variant,)*
+ }
+ };
+}
+for_all_common_atoms!(define_enum);
+
+// Define CommonSourceAtomSetIndices struct.
+//
+// impl CommonSourceAtomSetIndices {
+// pub fn arguments() -> SourceAtomSetIndex { ... }
+// pub fn async_() -> SourceAtomSetIndex { ... }
+// ...
+// }
+macro_rules! define_struct {
+ ($(($s:tt, $method:ident, $variant:ident),)*) => {
+ #[derive(Debug)]
+ pub struct CommonSourceAtomSetIndices {}
+
+ impl CommonSourceAtomSetIndices {
+ $(
+ pub fn $method() -> SourceAtomSetIndex {
+ SourceAtomSetIndex::new(CommonAtoms::$variant as usize)
+ }
+ )*
+ }
+ };
+}
+for_all_common_atoms!(define_struct);
+
+/// Set of atoms, including the following:
+///
+/// * atoms referred from bytecode
+/// * variable names referred from scope data
+///
+/// WARNING: This set itself does *NOT* map to JSScript::atoms().
+#[derive(Debug)]
+pub struct SourceAtomSet<'alloc> {
+ atoms: IndexSet<&'alloc str>,
+}
+
+impl<'alloc> SourceAtomSet<'alloc> {
+ // Create a set, with all common atoms inserted.
+ pub fn new() -> Self {
+ let mut result = Self {
+ atoms: IndexSet::new(),
+ };
+ result.insert_common_atoms();
+ result
+ }
+
+ // Insert all common atoms.
+ fn insert_common_atoms(&mut self) {
+ macro_rules! insert_atom {
+ ($self: ident,
+ $(($s:tt, $method:ident, $variant:ident),)*) => {
+ $(
+ $self.atoms.insert($s);
+ )*
+ };
+ }
+ for_all_common_atoms!(insert_atom, self);
+ }
+
+ // Create a set, without any common atoms.
+ //
+ // This is for moving `SourceAtomSet` out of `Rc<RefCell>`, by replacing
+ // it with the result of this method.
+ pub fn new_uninitialized() -> Self {
+ Self {
+ // 256 is a number which should cover 75% of scripts without
+ // reallocation.
+ atoms: IndexSet::with_capacity(256),
+ }
+ }
+
+ pub fn insert(&mut self, s: &'alloc str) -> SourceAtomSetIndex {
+ let (index, _) = self.atoms.insert_full(s);
+ SourceAtomSetIndex::new(index)
+ }
+
+ pub fn get(&self, index: SourceAtomSetIndex) -> &'alloc str {
+ self.atoms.get_index(usize::from(index)).unwrap()
+ }
+}
+
+impl<'alloc> From<SourceAtomSet<'alloc>> for Vec<&'alloc str> {
+ fn from(set: SourceAtomSet<'alloc>) -> Vec<&'alloc str> {
+ set.atoms.into_iter().collect()
+ }
+}