Skip to main content

presolve_parser/
model.rs

1use std::collections::BTreeMap;
2
3use std::path::PathBuf;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct ParsedFile {
7    pub path: PathBuf,
8    pub classes: Vec<ParsedClass>,
9    pub type_aliases: Vec<ParsedTypeAlias>,
10    /// Module-local declarations that bind a name in TypeScript's type
11    /// namespace. The compiler uses this normalized fact to distinguish its
12    /// built-in marker types from authored lookalikes.
13    pub local_type_bindings: Vec<String>,
14    /// Module-local declarations in the value namespace. I6 uses this
15    /// normalized fact to reject authored functions that shadow compiler-owned
16    /// validation intrinsics.
17    pub local_value_bindings: Vec<String>,
18    pub imports: Vec<ParsedImport>,
19    pub exports: Vec<ParsedExport>,
20    pub diagnostics: Vec<ParseDiagnostic>,
21}
22
23/// Authored type alias retained for canonical semantic type lowering.
24#[derive(Debug, Clone, PartialEq, Eq)]
25pub struct ParsedTypeAlias {
26    pub name: String,
27    pub type_text: String,
28    pub span: SourceSpan,
29    pub type_span: SourceSpan,
30}
31
32#[derive(Debug, Clone, PartialEq, Eq)]
33pub struct ParsedImport {
34    pub source: String,
35    pub specifiers: Vec<ParsedImportSpecifier>,
36    pub span: SourceSpan,
37}
38
39#[derive(Debug, Clone, PartialEq, Eq)]
40pub struct ParsedImportSpecifier {
41    pub imported: String,
42    pub local: String,
43}
44
45#[derive(Debug, Clone, PartialEq, Eq)]
46pub struct ParsedExport {
47    pub kind: ParsedExportKind,
48    pub source: Option<String>,
49    pub specifiers: Vec<ParsedExportSpecifier>,
50    pub span: SourceSpan,
51}
52
53#[derive(Debug, Clone, Copy, PartialEq, Eq)]
54pub enum ParsedExportKind {
55    Named,
56    Default,
57    All,
58}
59
60#[derive(Debug, Clone, PartialEq, Eq)]
61pub struct ParsedExportSpecifier {
62    pub local: Option<String>,
63    pub exported: String,
64}
65
66#[derive(Debug, Clone, PartialEq, Eq)]
67pub struct ParsedClass {
68    pub name: String,
69    pub span: SourceSpan,
70    pub heritage: Option<ParsedClassHeritage>,
71    pub decorators: Vec<ParsedDecorator>,
72    pub properties: Vec<ParsedProperty>,
73    pub methods: Vec<ParsedMethod>,
74}
75
76/// Source-faithful class heritage retained for component-inheritance diagnostics.
77#[derive(Debug, Clone, PartialEq, Eq)]
78pub struct ParsedClassHeritage {
79    pub base: String,
80    pub span: SourceSpan,
81}
82
83#[derive(Debug, Clone, PartialEq, Eq)]
84pub struct ParsedDecorator {
85    pub name: String,
86    pub is_invoked: bool,
87    /// Source-normalized static-string values for every decorator argument.
88    /// Existing compiler consumers continue to use `argument` for their
89    /// one-argument contracts; multi-argument semantics must opt in explicitly.
90    pub arguments: Vec<Option<String>>,
91    pub argument: Option<String>,
92    pub argument_count: usize,
93    pub argument_spans: Vec<SourceSpan>,
94    pub static_member_argument: Option<ParsedStaticMemberDesignator>,
95    pub this_member_argument: Option<ParsedThisMemberDesignator>,
96    /// Normalized syntax for the sole outer argument of `@validate(...)`.
97    /// Semantic rule classification remains a core lowering responsibility.
98    pub validation_rule_expression: Option<ParsedValidationRuleExpression>,
99    pub span: SourceSpan,
100}
101
102/// Parser-owned syntax facts for one authored validation rule expression.
103#[derive(Debug, Clone, PartialEq, Eq)]
104pub struct ParsedValidationRuleExpression {
105    pub kind: ParsedValidationRuleExpressionKind,
106    pub span: SourceSpan,
107}
108
109#[derive(Debug, Clone, PartialEq, Eq)]
110pub enum ParsedValidationRuleExpressionKind {
111    Call {
112        callee: Option<String>,
113        arguments: Vec<ParsedValidationRuleArgument>,
114    },
115    Identifier(String),
116    Unsupported,
117}
118
119#[derive(Debug, Clone, PartialEq, Eq)]
120pub struct ParsedValidationRuleArgument {
121    pub kind: ParsedValidationRuleArgumentKind,
122    pub span: SourceSpan,
123}
124
125#[derive(Debug, Clone, PartialEq, Eq)]
126pub enum ParsedValidationRuleArgumentKind {
127    StringLiteral(String),
128    Constant(ParsedConstantExpression),
129    ThisMember(ParsedThisMemberDesignator),
130    Unsupported,
131}
132
133/// An exact direct `this.<identifier>` decorator argument.
134#[derive(Debug, Clone, PartialEq, Eq)]
135pub struct ParsedThisMemberDesignator {
136    pub member: String,
137    pub span: SourceSpan,
138    pub this_span: SourceSpan,
139    pub member_span: SourceSpan,
140}
141
142/// A source-faithful `ComponentSymbol.contextField` decorator argument.
143#[derive(Debug, Clone, PartialEq, Eq)]
144pub struct ParsedStaticMemberDesignator {
145    pub object: String,
146    pub member: String,
147    pub span: SourceSpan,
148    pub object_span: SourceSpan,
149    pub member_span: SourceSpan,
150}
151
152#[derive(Debug, Clone, PartialEq, Eq)]
153pub struct ParsedProperty {
154    pub name: String,
155    pub is_identifier_name: bool,
156    pub decorators: Vec<ParsedDecorator>,
157    pub initializer: Option<String>,
158    pub initializer_literal: Option<ParsedSerializableValue>,
159    pub initializer_expression: Option<ParsedComputedExpression>,
160    pub initializer_constant_expression: Option<ParsedConstantExpression>,
161    pub initializer_span: Option<SourceSpan>,
162    pub state_initial_value: Option<ParsedSerializableValue>,
163    pub state_initial_expression: Option<ParsedConstantExpression>,
164    pub state_type_annotation: Option<ParsedTypeAnnotation>,
165    pub type_annotation: Option<ParsedTypeAnnotation>,
166    pub name_span: SourceSpan,
167    pub is_static: bool,
168    pub is_definite_assignment: bool,
169    pub is_declare: bool,
170    pub span: SourceSpan,
171}
172
173/// Authored TypeScript annotation retained for a state field without type checking.
174#[derive(Debug, Clone, PartialEq, Eq)]
175pub struct ParsedTypeAnnotation {
176    pub text: String,
177    pub span: SourceSpan,
178}
179
180#[derive(Debug, Clone, PartialEq, Eq)]
181pub enum ParsedSerializableValue {
182    Null,
183    Number(String),
184    String(String),
185    Boolean(bool),
186    Array(Vec<ParsedSerializableValue>),
187    Object(BTreeMap<String, ParsedSerializableValue>),
188}
189
190/// A compiler-owned numeric arithmetic expression accepted in `state(...)`.
191#[derive(Debug, Clone, PartialEq, Eq)]
192pub struct ParsedArithmeticExpression {
193    pub kind: ParsedArithmeticExpressionKind,
194    pub span: SourceSpan,
195}
196
197#[derive(Debug, Clone, PartialEq, Eq)]
198pub enum ParsedArithmeticExpressionKind {
199    Number(String),
200    Binary {
201        operator: ParsedArithmeticOperator,
202        left: Box<ParsedArithmeticExpression>,
203        right: Box<ParsedArithmeticExpression>,
204    },
205}
206
207#[derive(Debug, Clone, Copy, PartialEq, Eq)]
208pub enum ParsedArithmeticOperator {
209    Add,
210    Subtract,
211    Multiply,
212    Divide,
213    Remainder,
214}
215
216/// A compiler-owned constant expression accepted in `state(...)`.
217#[derive(Debug, Clone, PartialEq, Eq)]
218pub struct ParsedConstantExpression {
219    pub kind: ParsedConstantExpressionKind,
220    pub span: SourceSpan,
221}
222
223#[derive(Debug, Clone, PartialEq, Eq)]
224pub enum ParsedConstantExpressionKind {
225    Primitive(ParsedSerializableValue),
226    Boolean(bool),
227    Arithmetic(ParsedArithmeticExpression),
228    Comparison {
229        operator: ParsedComparisonOperator,
230        left: ParsedArithmeticExpression,
231        right: ParsedArithmeticExpression,
232    },
233    Logical {
234        operator: ParsedLogicalOperator,
235        left: Box<ParsedConstantExpression>,
236        right: Box<ParsedConstantExpression>,
237    },
238    NullishCoalescing {
239        left: Box<ParsedConstantExpression>,
240        right: Box<ParsedConstantExpression>,
241    },
242    Unary {
243        operator: ParsedUnaryOperator,
244        operand: Box<ParsedConstantExpression>,
245    },
246}
247
248/// A supported expression retained from one `@computed()` getter body.
249#[derive(Debug, Clone, PartialEq, Eq)]
250pub struct ParsedComputedExpression {
251    pub kind: ParsedComputedExpressionKind,
252    pub span: SourceSpan,
253}
254
255/// Parsed computed getter expression forms accepted by the E2 lowering slice.
256#[derive(Debug, Clone, PartialEq, Eq)]
257pub enum ParsedComputedExpressionKind {
258    Literal(ParsedSerializableValue),
259    ThisMember(String),
260    MemberAccess {
261        object: Box<ParsedComputedExpression>,
262        property: String,
263        optional: bool,
264    },
265    /// A statically bounded property or array-element read.
266    ///
267    /// The parser admits only string and non-negative integer literal indices;
268    /// dynamic JavaScript property lookup remains outside the semantic subset.
269    IndexAccess {
270        object: Box<ParsedComputedExpression>,
271        index: Box<ParsedComputedExpression>,
272    },
273    Conditional {
274        condition: Box<ParsedComputedExpression>,
275        when_true: Box<ParsedComputedExpression>,
276        when_false: Box<ParsedComputedExpression>,
277    },
278    Template {
279        quasis: Vec<String>,
280        expressions: Vec<ParsedComputedExpression>,
281    },
282    Call {
283        callee: String,
284        arguments: Vec<ParsedComputedExpression>,
285    },
286    Arithmetic {
287        left: Box<ParsedComputedExpression>,
288        right: Box<ParsedComputedExpression>,
289        operator: ParsedArithmeticOperator,
290    },
291    Comparison {
292        left: Box<ParsedComputedExpression>,
293        right: Box<ParsedComputedExpression>,
294        operator: ParsedComparisonOperator,
295    },
296    Logical {
297        left: Box<ParsedComputedExpression>,
298        right: Box<ParsedComputedExpression>,
299        operator: ParsedLogicalOperator,
300    },
301    NullishCoalescing {
302        left: Box<ParsedComputedExpression>,
303        right: Box<ParsedComputedExpression>,
304    },
305    Unary {
306        operand: Box<ParsedComputedExpression>,
307        operator: ParsedUnaryOperator,
308    },
309}
310
311#[derive(Debug, Clone, Copy, PartialEq, Eq)]
312pub enum ParsedComparisonOperator {
313    Equal,
314    NotEqual,
315    LessThan,
316    LessThanOrEqual,
317    GreaterThan,
318    GreaterThanOrEqual,
319}
320
321#[derive(Debug, Clone, Copy, PartialEq, Eq)]
322pub enum ParsedLogicalOperator {
323    And,
324    Or,
325}
326
327#[derive(Debug, Clone, Copy, PartialEq, Eq)]
328pub enum ParsedUnaryOperator {
329    Not,
330    Plus,
331    Minus,
332}
333
334#[derive(Debug, Clone, PartialEq, Eq)]
335pub struct ParsedMethod {
336    pub name: String,
337    pub span: SourceSpan,
338    pub decorators: Vec<ParsedDecorator>,
339    pub is_getter: bool,
340    pub is_setter: bool,
341    pub is_async: bool,
342    pub is_static: bool,
343    pub jsx_roots: Vec<ParsedJsxNode>,
344    pub bindings: Vec<String>,
345    pub state_updates: Vec<ParsedStateUpdate>,
346    pub local_variables: Vec<ParsedLocalVariable>,
347    pub parameters: Vec<ParsedMethodParameter>,
348    pub return_type_annotation: Option<ParsedTypeAnnotation>,
349    pub return_values: Vec<ParsedSerializableValue>,
350    pub computed_expression: Option<ParsedComputedExpression>,
351    pub effect_body: Option<ParsedEffectBody>,
352    pub calls: Vec<ParsedMethodCall>,
353}
354
355/// Ordered syntax retained from one `@effect()` method body.
356#[derive(Debug, Clone, PartialEq, Eq)]
357pub struct ParsedEffectBody {
358    pub statements: Vec<ParsedEffectStatement>,
359}
360
361#[derive(Debug, Clone, PartialEq, Eq)]
362pub struct ParsedEffectStatement {
363    pub kind: ParsedEffectStatementKind,
364    pub span: SourceSpan,
365}
366
367#[derive(Debug, Clone, PartialEq, Eq)]
368pub enum ParsedEffectStatementKind {
369    StaticMemberAssignment {
370        target: ParsedEffectExpression,
371        value: ParsedEffectExpression,
372    },
373    CapabilityCall {
374        callee: ParsedEffectExpression,
375        arguments: Vec<ParsedEffectExpression>,
376    },
377    EffectReturn {
378        value: Option<ParsedEffectExpression>,
379    },
380    Empty,
381    Unsupported(ParsedUnsupportedEffectStatementKind),
382}
383
384#[derive(Debug, Clone, Copy, PartialEq, Eq)]
385pub enum ParsedUnsupportedEffectStatementKind {
386    LocalDeclaration,
387    Branch,
388    Loop,
389    NestedBlock,
390    ExceptionHandling,
391    AsyncOperation,
392    CompoundAssignment,
393    CleanupReturnCandidate,
394    UnsupportedExpression,
395}
396
397/// Expression syntax accepted as an operand of a lowered effect statement.
398#[derive(Debug, Clone, PartialEq, Eq)]
399pub struct ParsedEffectExpression {
400    pub kind: ParsedEffectExpressionKind,
401    pub span: SourceSpan,
402}
403
404#[derive(Debug, Clone, PartialEq, Eq)]
405pub enum ParsedEffectExpressionKind {
406    Literal(ParsedSerializableValue),
407    Identifier(String),
408    ThisMember(String),
409    MemberAccess {
410        object: Box<ParsedEffectExpression>,
411        property: String,
412    },
413    Arithmetic {
414        left: Box<ParsedEffectExpression>,
415        right: Box<ParsedEffectExpression>,
416        operator: ParsedArithmeticOperator,
417    },
418    Comparison {
419        left: Box<ParsedEffectExpression>,
420        right: Box<ParsedEffectExpression>,
421        operator: ParsedComparisonOperator,
422    },
423    Logical {
424        left: Box<ParsedEffectExpression>,
425        right: Box<ParsedEffectExpression>,
426        operator: ParsedLogicalOperator,
427    },
428    NullishCoalescing {
429        left: Box<ParsedEffectExpression>,
430        right: Box<ParsedEffectExpression>,
431    },
432    Unary {
433        operand: Box<ParsedEffectExpression>,
434        operator: ParsedUnaryOperator,
435    },
436}
437
438/// One directly authored method call retained for computed-purity analysis.
439#[derive(Debug, Clone, PartialEq, Eq)]
440pub struct ParsedMethodCall {
441    pub callee: String,
442    pub span: SourceSpan,
443}
444
445#[derive(Debug, Clone, PartialEq, Eq)]
446pub struct ParsedMethodParameter {
447    pub name: String,
448    pub decorators: Vec<ParsedDecorator>,
449    pub span: SourceSpan,
450    pub type_annotation: Option<ParsedTypeAnnotation>,
451}
452
453#[derive(Debug, Clone, PartialEq, Eq)]
454pub struct ParsedLocalVariable {
455    pub name: String,
456    pub value: ParsedSerializableValue,
457    pub span: SourceSpan,
458}
459
460#[derive(Debug, Clone, PartialEq, Eq)]
461pub struct ParsedStateUpdate {
462    pub field: String,
463    pub operation: ParsedStateOperation,
464    pub span: SourceSpan,
465}
466
467#[derive(Debug, Clone, PartialEq, Eq)]
468pub enum ParsedStateOperation {
469    Increment,
470    Decrement,
471    AddAssign(ParsedSerializableValue),
472    SubtractAssign(ParsedSerializableValue),
473    Assign(ParsedSerializableValue),
474    AssignParameter(String),
475    Toggle,
476}
477
478#[derive(Debug, Clone, PartialEq, Eq)]
479pub enum ParsedJsxChild {
480    Text {
481        value: String,
482        span: SourceSpan,
483    },
484    Binding {
485        expression: String,
486        span: SourceSpan,
487    },
488    Element(ParsedJsxElement),
489    Fragment(ParsedJsxFragment),
490    Conditional(ParsedJsxConditional),
491    List(ParsedJsxList),
492}
493
494#[derive(Debug, Clone, PartialEq, Eq)]
495pub enum ParsedJsxNode {
496    Element(ParsedJsxElement),
497    Fragment(ParsedJsxFragment),
498}
499
500#[derive(Debug, Clone, PartialEq, Eq)]
501pub struct ParsedJsxElement {
502    pub name: String,
503    pub name_span: SourceSpan,
504    pub span: SourceSpan,
505    pub attributes: Vec<ParsedJsxAttribute>,
506    pub event_handlers: Vec<ParsedEventHandler>,
507    pub children: Vec<ParsedJsxChild>,
508}
509
510#[derive(Debug, Clone, PartialEq, Eq)]
511pub struct ParsedJsxFragment {
512    pub span: SourceSpan,
513    pub children: Vec<ParsedJsxChild>,
514}
515
516#[derive(Debug, Clone, PartialEq, Eq)]
517pub struct ParsedJsxConditional {
518    pub condition: String,
519    pub span: SourceSpan,
520    pub when_true: ParsedJsxNode,
521    pub when_false: Option<ParsedJsxNode>,
522}
523
524#[derive(Debug, Clone, PartialEq, Eq)]
525pub struct ParsedJsxList {
526    pub iterable: String,
527    pub item_variable: String,
528    pub index_variable: Option<String>,
529    pub key_expression: String,
530    pub span: SourceSpan,
531    pub item_template: ParsedJsxNode,
532}
533
534#[derive(Debug, Clone, PartialEq, Eq)]
535pub struct ParsedJsxAttribute {
536    pub name: String,
537    pub value: ParsedJsxAttributeValue,
538    pub name_span: SourceSpan,
539    pub value_span: Option<SourceSpan>,
540    pub expression_span: Option<SourceSpan>,
541    pub this_member: Option<ParsedThisMemberDesignator>,
542    pub constant_value: Option<ParsedSerializableValue>,
543    pub span: SourceSpan,
544}
545
546#[derive(Debug, Clone, PartialEq, Eq)]
547pub enum ParsedJsxAttributeValue {
548    Boolean,
549    Static(String),
550    Expression(Option<String>),
551    Spread(Option<String>),
552    Unsupported,
553}
554
555#[derive(Debug, Clone, PartialEq, Eq)]
556pub struct ParsedEventHandler {
557    pub event: String,
558    pub handler: String,
559    pub arguments: Vec<ParsedSerializableValue>,
560    pub span: SourceSpan,
561}
562
563#[derive(Debug, Clone, PartialEq, Eq)]
564pub struct ParseDiagnostic {
565    pub message: String,
566    pub severity: ParseSeverity,
567    pub labels: Vec<ParseLabel>,
568}
569
570#[derive(Debug, Clone, PartialEq, Eq)]
571pub enum ParseSeverity {
572    Info,
573    Warning,
574    Error,
575}
576
577#[derive(Debug, Clone, PartialEq, Eq)]
578pub struct ParseLabel {
579    pub span: SourceSpan,
580}
581
582#[derive(Debug, Clone, Copy, PartialEq, Eq)]
583pub struct SourceSpan {
584    pub start: usize,
585    pub end: usize,
586    pub line: usize,
587    pub column: usize,
588}