1use react_compiler_diagnostics::SourceLocation;
15
16use crate::{
17 AliasingEffect, BlockId, EvaluationOrder, InstructionValue, LogicalOperator, ParamPattern,
18 Place, ScopeId,
19};
20
21#[derive(Debug, Clone)]
28pub struct ReactiveFunction {
29 pub loc: Option<SourceLocation>,
30 pub id: Option<String>,
31 pub name_hint: Option<String>,
32 pub params: Vec<ParamPattern>,
33 pub generator: bool,
34 pub is_async: bool,
35 pub body: ReactiveBlock,
36 pub directives: Vec<String>,
37 }
39
40pub type ReactiveBlock = Vec<ReactiveStatement>;
46
47#[derive(Debug, Clone)]
49pub enum ReactiveStatement {
50 Instruction(ReactiveInstruction),
51 Terminal(ReactiveTerminalStatement),
52 Scope(ReactiveScopeBlock),
53 PrunedScope(PrunedReactiveScopeBlock),
54}
55
56#[derive(Debug, Clone)]
62pub struct ReactiveInstruction {
63 pub id: EvaluationOrder,
64 pub lvalue: Option<Place>,
65 pub value: ReactiveValue,
66 pub effects: Option<Vec<AliasingEffect>>,
67 pub loc: Option<SourceLocation>,
68}
69
70#[derive(Debug, Clone)]
74pub enum ReactiveValue {
75 Instruction(InstructionValue),
77
78 LogicalExpression {
80 operator: LogicalOperator,
81 left: Box<ReactiveValue>,
82 right: Box<ReactiveValue>,
83 loc: Option<SourceLocation>,
84 },
85
86 ConditionalExpression {
88 test: Box<ReactiveValue>,
89 consequent: Box<ReactiveValue>,
90 alternate: Box<ReactiveValue>,
91 loc: Option<SourceLocation>,
92 },
93
94 SequenceExpression {
96 instructions: Vec<ReactiveInstruction>,
97 id: EvaluationOrder,
98 value: Box<ReactiveValue>,
99 loc: Option<SourceLocation>,
100 },
101
102 OptionalExpression {
104 id: EvaluationOrder,
105 value: Box<ReactiveValue>,
106 optional: bool,
107 loc: Option<SourceLocation>,
108 },
109}
110
111#[derive(Debug, Clone)]
116pub struct ReactiveTerminalStatement {
117 pub terminal: ReactiveTerminal,
118 pub label: Option<ReactiveLabel>,
119}
120
121#[derive(Debug, Clone)]
122pub struct ReactiveLabel {
123 pub id: BlockId,
124 pub implicit: bool,
125}
126
127#[derive(Debug, Clone, PartialEq, Eq)]
128pub enum ReactiveTerminalTargetKind {
129 Implicit,
130 Labeled,
131 Unlabeled,
132}
133
134impl std::fmt::Display for ReactiveTerminalTargetKind {
135 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
136 match self {
137 ReactiveTerminalTargetKind::Implicit => write!(f, "implicit"),
138 ReactiveTerminalTargetKind::Labeled => write!(f, "labeled"),
139 ReactiveTerminalTargetKind::Unlabeled => write!(f, "unlabeled"),
140 }
141 }
142}
143
144#[derive(Debug, Clone)]
145pub enum ReactiveTerminal {
146 Break {
147 target: BlockId,
148 id: EvaluationOrder,
149 target_kind: ReactiveTerminalTargetKind,
150 loc: Option<SourceLocation>,
151 },
152 Continue {
153 target: BlockId,
154 id: EvaluationOrder,
155 target_kind: ReactiveTerminalTargetKind,
156 loc: Option<SourceLocation>,
157 },
158 Return {
159 value: Place,
160 id: EvaluationOrder,
161 loc: Option<SourceLocation>,
162 },
163 Throw {
164 value: Place,
165 id: EvaluationOrder,
166 loc: Option<SourceLocation>,
167 },
168 Switch {
169 test: Place,
170 cases: Vec<ReactiveSwitchCase>,
171 id: EvaluationOrder,
172 loc: Option<SourceLocation>,
173 },
174 DoWhile {
175 loop_block: ReactiveBlock,
176 test: ReactiveValue,
177 id: EvaluationOrder,
178 loc: Option<SourceLocation>,
179 },
180 While {
181 test: ReactiveValue,
182 loop_block: ReactiveBlock,
183 id: EvaluationOrder,
184 loc: Option<SourceLocation>,
185 },
186 For {
187 init: ReactiveValue,
188 test: ReactiveValue,
189 update: Option<ReactiveValue>,
190 loop_block: ReactiveBlock,
191 id: EvaluationOrder,
192 loc: Option<SourceLocation>,
193 },
194 ForOf {
195 init: ReactiveValue,
196 test: ReactiveValue,
197 loop_block: ReactiveBlock,
198 id: EvaluationOrder,
199 loc: Option<SourceLocation>,
200 },
201 ForIn {
202 init: ReactiveValue,
203 loop_block: ReactiveBlock,
204 id: EvaluationOrder,
205 loc: Option<SourceLocation>,
206 },
207 If {
208 test: Place,
209 consequent: ReactiveBlock,
210 alternate: Option<ReactiveBlock>,
211 id: EvaluationOrder,
212 loc: Option<SourceLocation>,
213 },
214 Label {
215 block: ReactiveBlock,
216 id: EvaluationOrder,
217 loc: Option<SourceLocation>,
218 },
219 Try {
220 block: ReactiveBlock,
221 handler_binding: Option<Place>,
222 handler: ReactiveBlock,
223 id: EvaluationOrder,
224 loc: Option<SourceLocation>,
225 },
226}
227
228#[derive(Debug, Clone)]
229pub struct ReactiveSwitchCase {
230 pub test: Option<Place>,
231 pub block: Option<ReactiveBlock>,
232}
233
234#[derive(Debug, Clone)]
239pub struct ReactiveScopeBlock {
240 pub scope: ScopeId,
241 pub instructions: ReactiveBlock,
242}
243
244#[derive(Debug, Clone)]
245pub struct PrunedReactiveScopeBlock {
246 pub scope: ScopeId,
247 pub instructions: ReactiveBlock,
248}