Skip to main content

oxc_codegen/
context.rs

1//! Code generation context management
2//!
3//! This module provides the [`Context`] type for managing the state and configuration
4//! during code generation, including JavaScript/TypeScript-specific syntax rules.
5
6use bitflags::bitflags;
7
8bitflags! {
9    /// Code generation context flags
10    ///
11    /// Controls various aspects of code generation including operator precedence,
12    /// language features, and syntax restrictions.
13    #[derive(Debug, Default, Clone, Copy)]
14    pub struct Context: u8 {
15        /// Forbid the `in` operator in expressions
16        ///
17        /// Used in contexts where the `in` operator could be ambiguous,
18        /// such as in the init clause of a for loop.
19        const FORBID_IN   = 1 << 0;
20        /// Forbid call expressions
21        ///
22        /// Used to prevent ambiguity in contexts like new expressions
23        /// where parentheses could be interpreted differently.
24        const FORBID_CALL = 1 << 1;
25        /// Enable TypeScript-specific code generation
26        ///
27        /// When set, TypeScript syntax features are enabled in the output.
28        const TYPESCRIPT  = 1 << 2;
29    }
30}
31
32impl Context {
33    /// Check if the `in` operator is forbidden in the current context
34    #[inline]
35    pub fn forbid_in(self) -> bool {
36        self.contains(Self::FORBID_IN)
37    }
38
39    /// Check if call expressions are forbidden in the current context
40    #[inline]
41    pub fn forbid_call(self) -> bool {
42        self.contains(Self::FORBID_CALL)
43    }
44
45    /// Create a new context with TypeScript support enabled
46    #[inline]
47    #[must_use]
48    pub fn with_typescript(mut self) -> Self {
49        self |= Self::TYPESCRIPT;
50        self
51    }
52
53    /// Conditionally set or unset the `FORBID_IN` flag
54    #[inline]
55    #[must_use]
56    pub fn and_forbid_in(self, include: bool) -> Self {
57        self.and(Self::FORBID_IN, include)
58    }
59
60    /// Conditionally set or unset the `FORBID_CALL` flag
61    #[inline]
62    #[must_use]
63    pub fn and_forbid_call(self, include: bool) -> Self {
64        self.and(Self::FORBID_CALL, include)
65    }
66
67    /// Helper method to conditionally set or unset a flag
68    #[inline]
69    fn and(self, flag: Self, set: bool) -> Self {
70        if set { self | flag } else { self - flag }
71    }
72}