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