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 callee_span: Option<SourceSpan>,
141    pub span: SourceSpan,
142}
143
144#[derive(Debug, Clone, PartialEq, Eq)]
145pub enum ParsedValidationRuleExpressionKind {
146    Call {
147        callee: Option<String>,
148        arguments: Vec<ParsedValidationRuleArgument>,
149    },
150    Identifier(String),
151    Unsupported,
152}
153
154#[derive(Debug, Clone, PartialEq, Eq)]
155pub struct ParsedValidationRuleArgument {
156    pub kind: ParsedValidationRuleArgumentKind,
157    pub span: SourceSpan,
158}
159
160#[derive(Debug, Clone, PartialEq, Eq)]
161pub enum ParsedValidationRuleArgumentKind {
162    StringLiteral(String),
163    Constant(ParsedConstantExpression),
164    ThisMember(ParsedThisMemberDesignator),
165    Unsupported,
166}
167
168/// An exact direct `this.<identifier>` decorator argument.
169#[derive(Debug, Clone, PartialEq, Eq)]
170pub struct ParsedThisMemberDesignator {
171    pub member: String,
172    pub span: SourceSpan,
173    pub this_span: SourceSpan,
174    pub member_span: SourceSpan,
175}
176
177/// A source-faithful `ComponentSymbol.contextField` decorator argument.
178#[derive(Debug, Clone, PartialEq, Eq)]
179pub struct ParsedStaticMemberDesignator {
180    pub object: String,
181    pub member: String,
182    pub span: SourceSpan,
183    pub object_span: SourceSpan,
184    pub member_span: SourceSpan,
185}
186
187#[derive(Debug, Clone, PartialEq, Eq)]
188pub struct ParsedProperty {
189    pub name: String,
190    pub is_identifier_name: bool,
191    pub decorators: Vec<ParsedDecorator>,
192    /// A direct initializer call selected from the general source AST. Its
193    /// callee has no framework meaning until a semantic authority resolves it.
194    pub initializer_call: Option<ParsedInitializerCall>,
195    /// A static object-argument shape selected from a direct initializer call.
196    /// It has no Form meaning until TypeScript authority resolves the outer
197    /// call to `defineForm`.
198    pub form_definition_shape: Option<ParsedFormDefinitionShape>,
199    pub initializer: Option<String>,
200    pub initializer_literal: Option<ParsedSerializableValue>,
201    pub initializer_expression: Option<ParsedComputedExpression>,
202    pub initializer_constant_expression: Option<ParsedConstantExpression>,
203    pub initializer_span: Option<SourceSpan>,
204    pub state_initial_value: Option<ParsedSerializableValue>,
205    pub state_initial_expression: Option<ParsedConstantExpression>,
206    pub state_type_annotation: Option<ParsedTypeAnnotation>,
207    pub type_annotation: Option<ParsedTypeAnnotation>,
208    pub name_span: SourceSpan,
209    pub is_static: bool,
210    pub is_definite_assignment: bool,
211    pub is_declare: bool,
212    pub span: SourceSpan,
213}
214
215/// Source-faithful static facts from a possible `defineForm({...})` argument.
216#[derive(Debug, Clone, PartialEq, Eq)]
217pub struct ParsedFormDefinitionShape {
218    pub call_span: SourceSpan,
219    pub definition_span: SourceSpan,
220    pub serialization: Option<String>,
221    pub serialization_span: Option<SourceSpan>,
222    pub fields_span: Option<SourceSpan>,
223    pub fields: Vec<ParsedFormFieldShape>,
224    pub unsupported_fields: Vec<Vec<String>>,
225    pub submit: Option<ParsedFormSubmitShape>,
226    pub unknown_options: Vec<String>,
227}
228
229/// One statically named leaf call below a possible Form `fields` object.
230#[derive(Debug, Clone, PartialEq, Eq)]
231pub struct ParsedFormFieldShape {
232    pub name: String,
233    pub path: Vec<String>,
234    pub declaration_span: SourceSpan,
235    pub call_span: SourceSpan,
236    pub callee_span: SourceSpan,
237    pub argument_count: usize,
238    pub initial_value: Option<ParsedSerializableValue>,
239    pub initial_span: Option<SourceSpan>,
240    pub validations: Vec<ParsedValidationRuleExpression>,
241    pub unknown_options: Vec<String>,
242}
243
244#[derive(Debug, Clone, PartialEq, Eq)]
245pub struct ParsedFormSubmitShape {
246    pub span: SourceSpan,
247    pub is_async: bool,
248    pub parameter_count: usize,
249    pub handler: ParsedInlineHandler,
250}
251
252/// Source-faithful facts for a direct class-field initializer call.
253#[derive(Debug, Clone, PartialEq, Eq)]
254pub struct ParsedInitializerCall {
255    pub callee_span: SourceSpan,
256    pub span: SourceSpan,
257    /// The parser records call arity without assigning framework meaning to
258    /// the callee. Semantic lowering uses this to reject malformed intrinsics.
259    pub argument_count: usize,
260    /// An inline function argument selected from a general initializer call.
261    /// This remains syntax only: a later semantic authority decides whether
262    /// the surrounding call is a framework action or some unrelated helper.
263    pub inline_handler: Option<ParsedInlineHandler>,
264}
265
266/// Parser-owned facts for an inline function supplied to a class-field call.
267///
268/// The body retains only state updates supported by the existing compiler
269/// action semantics, plus exact spans for every other non-empty statement.
270/// Consumers must reject unsupported bodies rather than guessing a lowering.
271#[derive(Debug, Clone, PartialEq, Eq)]
272pub struct ParsedInlineHandler {
273    pub span: SourceSpan,
274    pub body_span: SourceSpan,
275    pub is_async: bool,
276    pub is_expression_body: bool,
277    /// Ordered, source-owned parameters of the inline function. These remain
278    /// syntax facts; later semantic lowering decides whether a handler form
279    /// may consume them.
280    pub parameters: Vec<ParsedMethodParameter>,
281    /// Serializable local declarations retained in source order. They have no
282    /// framework meaning until a later, authority-backed action projection
283    /// validates their use.
284    pub local_variables: Vec<ParsedLocalVariable>,
285    pub state_updates: Vec<ParsedStateUpdate>,
286    /// One direct identifier call retained from an otherwise closed inline
287    /// body. This is syntax only; later authorities decide whether the callee
288    /// is an admitted capability and whether its identifier arguments have
289    /// framework meaning.
290    pub direct_call: Option<ParsedInlineDirectCall>,
291    pub unsupported_statement_spans: Vec<SourceSpan>,
292    /// A restricted ordered-body view retained from a general inline function.
293    /// It has no framework meaning until an authority-backed later consumer
294    /// selects the surrounding initializer call.
295    pub effect_body: Option<ParsedEffectBody>,
296}
297
298#[derive(Debug, Clone, PartialEq, Eq)]
299pub struct ParsedInlineDirectCall {
300    pub callee: String,
301    pub callee_span: SourceSpan,
302    pub arguments: Vec<ParsedInlineDirectCallArgument>,
303    pub span: SourceSpan,
304    pub awaited: bool,
305}
306
307#[derive(Debug, Clone, PartialEq, Eq)]
308pub struct ParsedInlineDirectCallArgument {
309    pub name: String,
310    pub span: SourceSpan,
311}
312
313/// Authored TypeScript annotation retained for a state field without type checking.
314#[derive(Debug, Clone, PartialEq, Eq)]
315pub struct ParsedTypeAnnotation {
316    pub text: String,
317    pub span: SourceSpan,
318}
319
320#[derive(Debug, Clone, PartialEq, Eq)]
321pub enum ParsedSerializableValue {
322    Null,
323    Number(String),
324    String(String),
325    Boolean(bool),
326    Array(Vec<ParsedSerializableValue>),
327    Object(BTreeMap<String, ParsedSerializableValue>),
328}
329
330/// A compiler-owned numeric arithmetic expression accepted in `state(...)`.
331#[derive(Debug, Clone, PartialEq, Eq)]
332pub struct ParsedArithmeticExpression {
333    pub kind: ParsedArithmeticExpressionKind,
334    pub span: SourceSpan,
335}
336
337#[derive(Debug, Clone, PartialEq, Eq)]
338pub enum ParsedArithmeticExpressionKind {
339    Number(String),
340    Binary {
341        operator: ParsedArithmeticOperator,
342        left: Box<ParsedArithmeticExpression>,
343        right: Box<ParsedArithmeticExpression>,
344    },
345}
346
347#[derive(Debug, Clone, Copy, PartialEq, Eq)]
348pub enum ParsedArithmeticOperator {
349    Add,
350    Subtract,
351    Multiply,
352    Divide,
353    Remainder,
354}
355
356/// A compiler-owned constant expression accepted in `state(...)`.
357#[derive(Debug, Clone, PartialEq, Eq)]
358pub struct ParsedConstantExpression {
359    pub kind: ParsedConstantExpressionKind,
360    pub span: SourceSpan,
361}
362
363#[derive(Debug, Clone, PartialEq, Eq)]
364pub enum ParsedConstantExpressionKind {
365    Primitive(ParsedSerializableValue),
366    Boolean(bool),
367    Arithmetic(ParsedArithmeticExpression),
368    Comparison {
369        operator: ParsedComparisonOperator,
370        left: ParsedArithmeticExpression,
371        right: ParsedArithmeticExpression,
372    },
373    Logical {
374        operator: ParsedLogicalOperator,
375        left: Box<ParsedConstantExpression>,
376        right: Box<ParsedConstantExpression>,
377    },
378    NullishCoalescing {
379        left: Box<ParsedConstantExpression>,
380        right: Box<ParsedConstantExpression>,
381    },
382    Unary {
383        operator: ParsedUnaryOperator,
384        operand: Box<ParsedConstantExpression>,
385    },
386}
387
388/// A supported expression retained from one `@computed()` getter body.
389#[derive(Debug, Clone, PartialEq, Eq)]
390pub struct ParsedComputedExpression {
391    pub kind: ParsedComputedExpressionKind,
392    pub span: SourceSpan,
393}
394
395/// Parsed computed getter expression forms accepted by the E2 lowering slice.
396#[derive(Debug, Clone, PartialEq, Eq)]
397pub enum ParsedComputedExpressionKind {
398    Literal(ParsedSerializableValue),
399    ThisMember(String),
400    MemberAccess {
401        object: Box<ParsedComputedExpression>,
402        property: String,
403        optional: bool,
404    },
405    /// A statically bounded property or array-element read.
406    ///
407    /// The parser admits only string and non-negative integer literal indices;
408    /// dynamic JavaScript property lookup remains outside the semantic subset.
409    IndexAccess {
410        object: Box<ParsedComputedExpression>,
411        index: Box<ParsedComputedExpression>,
412    },
413    Conditional {
414        condition: Box<ParsedComputedExpression>,
415        when_true: Box<ParsedComputedExpression>,
416        when_false: Box<ParsedComputedExpression>,
417    },
418    Template {
419        quasis: Vec<String>,
420        expressions: Vec<ParsedComputedExpression>,
421    },
422    Call {
423        callee: String,
424        arguments: Vec<ParsedComputedExpression>,
425    },
426    Arithmetic {
427        left: Box<ParsedComputedExpression>,
428        right: Box<ParsedComputedExpression>,
429        operator: ParsedArithmeticOperator,
430    },
431    Comparison {
432        left: Box<ParsedComputedExpression>,
433        right: Box<ParsedComputedExpression>,
434        operator: ParsedComparisonOperator,
435    },
436    Logical {
437        left: Box<ParsedComputedExpression>,
438        right: Box<ParsedComputedExpression>,
439        operator: ParsedLogicalOperator,
440    },
441    NullishCoalescing {
442        left: Box<ParsedComputedExpression>,
443        right: Box<ParsedComputedExpression>,
444    },
445    Unary {
446        operand: Box<ParsedComputedExpression>,
447        operator: ParsedUnaryOperator,
448    },
449}
450
451#[derive(Debug, Clone, Copy, PartialEq, Eq)]
452pub enum ParsedComparisonOperator {
453    Equal,
454    NotEqual,
455    LessThan,
456    LessThanOrEqual,
457    GreaterThan,
458    GreaterThanOrEqual,
459}
460
461#[derive(Debug, Clone, Copy, PartialEq, Eq)]
462pub enum ParsedLogicalOperator {
463    And,
464    Or,
465}
466
467#[derive(Debug, Clone, Copy, PartialEq, Eq)]
468pub enum ParsedUnaryOperator {
469    Not,
470    Plus,
471    Minus,
472}
473
474#[derive(Debug, Clone, PartialEq, Eq)]
475pub struct ParsedMethod {
476    pub name: String,
477    pub span: SourceSpan,
478    pub decorators: Vec<ParsedDecorator>,
479    pub is_getter: bool,
480    pub is_setter: bool,
481    pub is_async: bool,
482    pub is_static: bool,
483    pub jsx_roots: Vec<ParsedJsxNode>,
484    pub bindings: Vec<String>,
485    pub state_updates: Vec<ParsedStateUpdate>,
486    pub local_variables: Vec<ParsedLocalVariable>,
487    pub parameters: Vec<ParsedMethodParameter>,
488    pub return_type_annotation: Option<ParsedTypeAnnotation>,
489    pub return_values: Vec<ParsedSerializableValue>,
490    pub computed_expression: Option<ParsedComputedExpression>,
491    pub effect_body: Option<ParsedEffectBody>,
492    pub calls: Vec<ParsedMethodCall>,
493}
494
495/// Ordered syntax retained from one `@effect()` method body.
496#[derive(Debug, Clone, PartialEq, Eq)]
497pub struct ParsedEffectBody {
498    pub statements: Vec<ParsedEffectStatement>,
499    pub cleanup: Option<ParsedEffectCleanup>,
500}
501
502/// A synchronous cleanup callback returned from a retained inline effect body.
503#[derive(Debug, Clone, PartialEq, Eq)]
504pub struct ParsedEffectCleanup {
505    pub span: SourceSpan,
506    pub is_async: bool,
507    pub body: Box<ParsedEffectBody>,
508}
509
510#[derive(Debug, Clone, PartialEq, Eq)]
511pub struct ParsedEffectStatement {
512    pub kind: ParsedEffectStatementKind,
513    pub span: SourceSpan,
514}
515
516#[derive(Debug, Clone, PartialEq, Eq)]
517pub enum ParsedEffectStatementKind {
518    StaticMemberAssignment {
519        target: ParsedEffectExpression,
520        value: ParsedEffectExpression,
521    },
522    CapabilityCall {
523        callee: ParsedEffectExpression,
524        arguments: Vec<ParsedEffectExpression>,
525    },
526    EffectReturn {
527        value: Option<ParsedEffectExpression>,
528    },
529    Empty,
530    Unsupported(ParsedUnsupportedEffectStatementKind),
531}
532
533#[derive(Debug, Clone, Copy, PartialEq, Eq)]
534pub enum ParsedUnsupportedEffectStatementKind {
535    LocalDeclaration,
536    Branch,
537    Loop,
538    NestedBlock,
539    ExceptionHandling,
540    AsyncOperation,
541    CompoundAssignment,
542    CleanupReturnCandidate,
543    UnsupportedExpression,
544}
545
546/// Expression syntax accepted as an operand of a lowered effect statement.
547#[derive(Debug, Clone, PartialEq, Eq)]
548pub struct ParsedEffectExpression {
549    pub kind: ParsedEffectExpressionKind,
550    pub span: SourceSpan,
551}
552
553#[derive(Debug, Clone, PartialEq, Eq)]
554pub enum ParsedEffectExpressionKind {
555    Literal(ParsedSerializableValue),
556    Identifier(String),
557    ThisMember(String),
558    MemberAccess {
559        object: Box<ParsedEffectExpression>,
560        property: String,
561    },
562    Arithmetic {
563        left: Box<ParsedEffectExpression>,
564        right: Box<ParsedEffectExpression>,
565        operator: ParsedArithmeticOperator,
566    },
567    Comparison {
568        left: Box<ParsedEffectExpression>,
569        right: Box<ParsedEffectExpression>,
570        operator: ParsedComparisonOperator,
571    },
572    Logical {
573        left: Box<ParsedEffectExpression>,
574        right: Box<ParsedEffectExpression>,
575        operator: ParsedLogicalOperator,
576    },
577    NullishCoalescing {
578        left: Box<ParsedEffectExpression>,
579        right: Box<ParsedEffectExpression>,
580    },
581    Unary {
582        operand: Box<ParsedEffectExpression>,
583        operator: ParsedUnaryOperator,
584    },
585}
586
587/// One directly authored method call retained for computed-purity analysis.
588#[derive(Debug, Clone, PartialEq, Eq)]
589pub struct ParsedMethodCall {
590    pub callee: String,
591    pub span: SourceSpan,
592}
593
594#[derive(Debug, Clone, PartialEq, Eq)]
595pub struct ParsedMethodParameter {
596    pub name: String,
597    pub decorators: Vec<ParsedDecorator>,
598    pub span: SourceSpan,
599    pub type_annotation: Option<ParsedTypeAnnotation>,
600}
601
602#[derive(Debug, Clone, PartialEq, Eq)]
603pub struct ParsedLocalVariable {
604    pub name: String,
605    pub value: ParsedSerializableValue,
606    pub span: SourceSpan,
607}
608
609#[derive(Debug, Clone, PartialEq, Eq)]
610pub struct ParsedStateUpdate {
611    pub field: String,
612    pub operation: ParsedStateOperation,
613    pub span: SourceSpan,
614}
615
616#[derive(Debug, Clone, PartialEq, Eq)]
617pub enum ParsedStateOperation {
618    Increment,
619    Decrement,
620    AddAssign(ParsedSerializableValue),
621    SubtractAssign(ParsedSerializableValue),
622    Assign(ParsedSerializableValue),
623    AssignParameter(String),
624    Toggle,
625}
626
627#[derive(Debug, Clone, PartialEq, Eq)]
628pub enum ParsedJsxChild {
629    Text {
630        value: String,
631        span: SourceSpan,
632    },
633    Binding {
634        expression: String,
635        span: SourceSpan,
636    },
637    Element(ParsedJsxElement),
638    Fragment(ParsedJsxFragment),
639    Conditional(ParsedJsxConditional),
640    List(ParsedJsxList),
641}
642
643#[derive(Debug, Clone, PartialEq, Eq)]
644pub enum ParsedJsxNode {
645    Element(ParsedJsxElement),
646    Fragment(ParsedJsxFragment),
647}
648
649#[derive(Debug, Clone, PartialEq, Eq)]
650pub struct ParsedJsxElement {
651    pub name: String,
652    pub name_span: SourceSpan,
653    pub span: SourceSpan,
654    pub attributes: Vec<ParsedJsxAttribute>,
655    pub event_handlers: Vec<ParsedEventHandler>,
656    pub children: Vec<ParsedJsxChild>,
657}
658
659#[derive(Debug, Clone, PartialEq, Eq)]
660pub struct ParsedJsxFragment {
661    pub span: SourceSpan,
662    pub children: Vec<ParsedJsxChild>,
663}
664
665#[derive(Debug, Clone, PartialEq, Eq)]
666pub struct ParsedJsxConditional {
667    pub condition: String,
668    pub span: SourceSpan,
669    pub when_true: ParsedJsxNode,
670    pub when_false: Option<ParsedJsxNode>,
671}
672
673#[derive(Debug, Clone, PartialEq, Eq)]
674pub struct ParsedJsxList {
675    pub iterable: String,
676    pub item_variable: String,
677    pub index_variable: Option<String>,
678    pub key_expression: String,
679    pub span: SourceSpan,
680    pub item_template: ParsedJsxNode,
681}
682
683#[derive(Debug, Clone, PartialEq, Eq)]
684pub struct ParsedJsxAttribute {
685    pub name: String,
686    pub value: ParsedJsxAttributeValue,
687    pub name_span: SourceSpan,
688    pub value_span: Option<SourceSpan>,
689    pub expression_span: Option<SourceSpan>,
690    pub this_member: Option<ParsedThisMemberDesignator>,
691    pub constant_value: Option<ParsedSerializableValue>,
692    pub span: SourceSpan,
693}
694
695#[derive(Debug, Clone, PartialEq, Eq)]
696pub enum ParsedJsxAttributeValue {
697    Boolean,
698    Static(String),
699    Expression(Option<String>),
700    Spread(Option<String>),
701    Unsupported,
702}
703
704#[derive(Debug, Clone, PartialEq, Eq)]
705pub struct ParsedEventHandler {
706    pub event: String,
707    pub handler: String,
708    pub arguments: Vec<ParsedSerializableValue>,
709    pub span: SourceSpan,
710}
711
712#[derive(Debug, Clone, PartialEq, Eq)]
713pub struct ParseDiagnostic {
714    pub message: String,
715    pub severity: ParseSeverity,
716    pub labels: Vec<ParseLabel>,
717}
718
719#[derive(Debug, Clone, PartialEq, Eq)]
720pub enum ParseSeverity {
721    Info,
722    Warning,
723    Error,
724}
725
726#[derive(Debug, Clone, PartialEq, Eq)]
727pub struct ParseLabel {
728    pub span: SourceSpan,
729}
730
731#[derive(Debug, Clone, Copy, PartialEq, Eq)]
732pub struct SourceSpan {
733    pub start: usize,
734    pub end: usize,
735    pub line: usize,
736    pub column: usize,
737}