Skip to main content

svelte_syntax/ast/
common.rs

1use std::sync::Arc;
2
3use serde::{Deserialize, Serialize};
4
5use crate::LineColumn;
6
7/// Serde discriminant for `"type": "Script"` in the JSON AST.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
9pub enum ScriptType {
10    Script,
11}
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
14#[serde(rename_all = "lowercase")]
15pub enum ScriptContext {
16    Default,
17    Module,
18}
19
20#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
21pub struct SourceRange {
22    pub start: LineColumn,
23    pub end: LineColumn,
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
27pub enum DirectiveValueSyntax {
28    #[default]
29    Implicit,
30    Expression,
31    Invalid,
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
35pub enum AttributeValueSyntax {
36    #[default]
37    Boolean,
38    Expression,
39    Quoted,
40    Unquoted,
41}
42
43#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
44pub enum AttrErrorKind {
45    InvalidName,
46    ExpectedEquals,
47    ExpectedValue,
48    HtmlTag,
49    Block(Arc<str>),
50}
51
52#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
53pub struct AttrError {
54    pub kind: AttrErrorKind,
55    pub start: usize,
56    pub end: usize,
57}
58
59#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
60pub enum SnippetHeaderErrorKind {
61    ExpectedRightBrace,
62    ExpectedRightParen,
63}
64
65#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
66pub struct SnippetHeaderError {
67    pub kind: SnippetHeaderErrorKind,
68    pub start: usize,
69    pub end: usize,
70}
71
72#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
73pub enum ParseErrorKind {
74    BlockInvalidContinuationPlacement,
75    ExpectedTokenElse,
76    ExpectedTokenAwaitBranch,
77    ExpectedTokenCommentClose,
78    ExpectedTokenStyleClose,
79    ExpectedTokenRightBrace,
80    ExpectedWhitespace,
81    BlockUnexpectedCharacter,
82    UnexpectedReservedWord { word: Arc<str> },
83    JsParseError { message: Arc<str> },
84    CssExpectedIdentifier,
85    UnexpectedEof,
86    BlockUnclosed,
87    ElementUnclosed { name: Arc<str> },
88    ElementInvalidClosingTag { name: Arc<str> },
89    ElementInvalidClosingTagAutoclosed { name: Arc<str>, reason: Arc<str> },
90}
91
92#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
93pub struct ParseError {
94    pub kind: ParseErrorKind,
95    pub start: usize,
96    pub end: usize,
97}
98
99/// A JavaScript comment extracted from OXC parsing, used for the public AST.
100#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
101pub struct JsComment {
102    pub kind: JsCommentKind,
103    pub value: Arc<str>,
104    pub start: usize,
105    pub end: usize,
106}
107
108#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
109pub enum JsCommentKind {
110    Line,
111    Block,
112}
113
114#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
115pub enum RootCommentType {
116    Line,
117    Block,
118}
119
120/// Serde discriminant for `"type": "Fragment"` in the JSON AST.
121#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
122pub enum FragmentType {
123    Fragment,
124}
125
126#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
127#[serde(untagged)]
128pub enum LiteralValue {
129    String(Arc<str>),
130    Number(i64),
131    JsonNumber(serde_json::Number),
132    Bool(bool),
133    Null,
134}
135
136#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
137pub struct Loc {
138    pub start: Position,
139    pub end: Position,
140}
141
142#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
143pub struct Position {
144    pub line: usize,
145    pub column: usize,
146    #[serde(skip_serializing_if = "Option::is_none")]
147    pub character: Option<usize>,
148}
149
150pub trait Span {
151    fn start(&self) -> usize;
152    fn end(&self) -> usize;
153
154    #[allow(dead_code)]
155    fn len(&self) -> usize {
156        self.end().saturating_sub(self.start())
157    }
158
159    #[allow(dead_code)]
160    fn is_empty(&self) -> bool {
161        self.start() >= self.end()
162    }
163
164    #[allow(dead_code)]
165    fn contains(&self, offset: usize) -> bool {
166        offset >= self.start() && offset <= self.end()
167    }
168}