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}