use serde::{Deserialize, Serialize};
use tsz_parser::NodeIndex;
use crate::symbols::SymbolTable;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct ScopeId(pub u32);
impl ScopeId {
pub const NONE: Self = Self(u32::MAX);
#[must_use]
pub const fn is_none(&self) -> bool {
self.0 == u32::MAX
}
#[must_use]
pub const fn is_some(&self) -> bool {
self.0 != u32::MAX
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum ContainerKind {
SourceFile,
Function,
Module,
Class,
Block,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Scope {
pub parent: ScopeId,
pub table: SymbolTable,
pub kind: ContainerKind,
pub container_node: NodeIndex,
}
impl Scope {
#[must_use]
pub fn new(parent: ScopeId, kind: ContainerKind, node: NodeIndex) -> Self {
Self {
parent,
table: SymbolTable::new(),
kind,
container_node: node,
}
}
#[must_use]
pub const fn is_function_scope(&self) -> bool {
matches!(
self.kind,
ContainerKind::SourceFile | ContainerKind::Function | ContainerKind::Module
)
}
}
#[derive(Clone, Debug)]
pub struct ScopeContext {
pub locals: SymbolTable,
pub parent_idx: Option<usize>,
pub container_kind: ContainerKind,
pub container_node: NodeIndex,
pub hoisted_vars: Vec<(String, NodeIndex)>,
pub hoisted_functions: Vec<(String, NodeIndex)>,
}
impl ScopeContext {
#[must_use]
pub fn new(kind: ContainerKind, node: NodeIndex, parent: Option<usize>) -> Self {
Self {
locals: SymbolTable::new(),
parent_idx: parent,
container_kind: kind,
container_node: node,
hoisted_vars: Vec::new(),
hoisted_functions: Vec::new(),
}
}
#[must_use]
pub const fn is_function_scope(&self) -> bool {
matches!(
self.container_kind,
ContainerKind::SourceFile | ContainerKind::Function | ContainerKind::Module
)
}
}