11import { comment , rule , type AstNode , type Comment , type Declaration , type Rule } from './ast'
2-
3- const BACK_SLASH = '\\' . charCodeAt ( 0 )
4- const SLASH = '/' . charCodeAt ( 0 )
5- const ASTERISK = '*' . charCodeAt ( 0 )
6- const DOUBLE_QUOTE = '"' . charCodeAt ( 0 )
7- const SINGLE_QUOTE = "'" . charCodeAt ( 0 )
8- const COLON = ':' . charCodeAt ( 0 )
9- const SEMICOLON = ';' . charCodeAt ( 0 )
10- const LINE_BREAK = '\n' . charCodeAt ( 0 )
11- const SPACE = ' ' . charCodeAt ( 0 )
12- const TAB = '\t' . charCodeAt ( 0 )
13- const OPEN_CURLY_BRACKET = '{' . charCodeAt ( 0 )
14- const CLOSE_CURLY_BRACKET = '}' . charCodeAt ( 0 )
15- const OPEN_PARENTHESIS = '(' . charCodeAt ( 0 )
16- const CLOSE_PARENTHESIS = ')' . charCodeAt ( 0 )
17- const OPEN_BRACKET = '[' . charCodeAt ( 0 )
18- const CLOSE_BRACKET = ']' . charCodeAt ( 0 )
19- const DASH = '-' . charCodeAt ( 0 )
20- const AT_SIGN = '@' . charCodeAt ( 0 )
21- const EXCLAMATION_MARK = '!' . charCodeAt ( 0 )
2+ import * as Token from './tokens'
223
234export function parse ( input : string ) {
245 input = input . replaceAll ( '\r\n' , '\n' )
@@ -49,7 +30,7 @@ export function parse(input: string) {
4930 // ^
5031 // ```
5132 //
52- if ( currentChar === BACK_SLASH ) {
33+ if ( currentChar === Token . BACKSLASH ) {
5334 buffer += input . slice ( i , i + 2 )
5435 i += 1
5536 }
@@ -70,19 +51,19 @@ export function parse(input: string) {
7051 // ^^^^^^^^^^^^^
7152 // }
7253 // ```
73- else if ( currentChar === SLASH && input . charCodeAt ( i + 1 ) === ASTERISK ) {
54+ else if ( currentChar === Token . SLASH && input . charCodeAt ( i + 1 ) === Token . ASTERISK ) {
7455 let start = i
7556
7657 for ( let j = i + 2 ; j < input . length ; j ++ ) {
7758 peekChar = input . charCodeAt ( j )
7859
7960 // Current character is a `\` therefore the next character is escaped.
80- if ( peekChar === BACK_SLASH ) {
61+ if ( peekChar === Token . BACKSLASH ) {
8162 j += 1
8263 }
8364
8465 // End of the comment
85- else if ( peekChar === ASTERISK && input . charCodeAt ( j + 1 ) === SLASH ) {
66+ else if ( peekChar === Token . ASTERISK && input . charCodeAt ( j + 1 ) === Token . SLASH ) {
8667 i = j + 1
8768 break
8869 }
@@ -92,13 +73,13 @@ export function parse(input: string) {
9273
9374 // Collect all license comments so that we can hoist them to the top of
9475 // the AST.
95- if ( commentString . charCodeAt ( 2 ) === EXCLAMATION_MARK ) {
76+ if ( commentString . charCodeAt ( 2 ) === Token . EXCLAMATION_MARK ) {
9677 licenseComments . push ( comment ( commentString . slice ( 2 , - 2 ) ) )
9778 }
9879 }
9980
10081 // Start of a string.
101- else if ( currentChar === SINGLE_QUOTE || currentChar === DOUBLE_QUOTE ) {
82+ else if ( currentChar === Token . SINGLE_QUOTE || currentChar === Token . DOUBLE_QUOTE ) {
10283 let start = i
10384
10485 // We need to ensure that the closing quote is the same as the opening
@@ -115,7 +96,7 @@ export function parse(input: string) {
11596 for ( let j = i + 1 ; j < input . length ; j ++ ) {
11697 peekChar = input . charCodeAt ( j )
11798 // Current character is a `\` therefore the next character is escaped.
118- if ( peekChar === BACK_SLASH ) {
99+ if ( peekChar === Token . BACKSLASH ) {
119100 j += 1
120101 }
121102
@@ -135,7 +116,7 @@ export function parse(input: string) {
135116 // ^ Missing "
136117 // }
137118 // ```
138- else if ( peekChar === SEMICOLON && input . charCodeAt ( j + 1 ) === LINE_BREAK ) {
119+ else if ( peekChar === Token . SEMICOLON && input . charCodeAt ( j + 1 ) === Token . LINE_BREAK ) {
139120 throw new Error (
140121 `Unterminated string: ${ input . slice ( start , j + 1 ) + String . fromCharCode ( currentChar ) } ` ,
141122 )
@@ -151,7 +132,7 @@ export function parse(input: string) {
151132 // ^ Missing "
152133 // }
153134 // ```
154- else if ( peekChar === LINE_BREAK ) {
135+ else if ( peekChar === Token . LINE_BREAK ) {
155136 throw new Error (
156137 `Unterminated string: ${ input . slice ( start , j ) + String . fromCharCode ( currentChar ) } ` ,
157138 )
@@ -165,19 +146,21 @@ export function parse(input: string) {
165146 // Skip whitespace if the next character is also whitespace. This allows us
166147 // to reduce the amount of whitespace in the AST.
167148 else if (
168- ( currentChar === SPACE || currentChar === LINE_BREAK || currentChar === TAB ) &&
149+ ( currentChar === Token . SPACE ||
150+ currentChar === Token . LINE_BREAK ||
151+ currentChar === Token . TAB ) &&
169152 ( peekChar = input . charCodeAt ( i + 1 ) ) &&
170- ( peekChar === SPACE || peekChar === LINE_BREAK || peekChar === TAB )
153+ ( peekChar === Token . SPACE || peekChar === Token . LINE_BREAK || peekChar === Token . TAB )
171154 ) {
172155 continue
173156 }
174157
175158 // Replace new lines with spaces.
176- else if ( currentChar === LINE_BREAK ) {
159+ else if ( currentChar === Token . LINE_BREAK ) {
177160 if ( buffer . length === 0 ) continue
178161
179162 peekChar = buffer . charCodeAt ( buffer . length - 1 )
180- if ( peekChar !== SPACE && peekChar !== LINE_BREAK && peekChar !== TAB ) {
163+ if ( peekChar !== Token . SPACE && peekChar !== Token . LINE_BREAK && peekChar !== Token . TAB ) {
181164 buffer += ' '
182165 }
183166 }
@@ -188,7 +171,11 @@ export function parse(input: string) {
188171 // character, even `;` and ` }`. Therefore we have to make sure that we are
189172 // at the correct "end" of the custom property by making sure everything is
190173 // balanced.
191- else if ( currentChar === DASH && input . charCodeAt ( i + 1 ) === DASH && buffer . length === 0 ) {
174+ else if (
175+ currentChar === Token . DASH &&
176+ input . charCodeAt ( i + 1 ) === Token . DASH &&
177+ buffer . length === 0
178+ ) {
192179 let closingBracketStack = ''
193180
194181 let start = i
@@ -198,45 +185,45 @@ export function parse(input: string) {
198185 peekChar = input . charCodeAt ( j )
199186
200187 // Current character is a `\` therefore the next character is escaped.
201- if ( peekChar === BACK_SLASH ) {
188+ if ( peekChar === Token . BACKSLASH ) {
202189 j += 1
203190 }
204191
205192 // Start of a comment.
206- else if ( peekChar === SLASH && input . charCodeAt ( j + 1 ) === ASTERISK ) {
193+ else if ( peekChar === Token . SLASH && input . charCodeAt ( j + 1 ) === Token . ASTERISK ) {
207194 for ( let k = j + 2 ; k < input . length ; k ++ ) {
208195 peekChar = input . charCodeAt ( k )
209196 // Current character is a `\` therefore the next character is escaped.
210- if ( peekChar === BACK_SLASH ) {
197+ if ( peekChar === Token . BACKSLASH ) {
211198 k += 1
212199 }
213200
214201 // End of the comment
215- else if ( peekChar === ASTERISK && input . charCodeAt ( k + 1 ) === SLASH ) {
202+ else if ( peekChar === Token . ASTERISK && input . charCodeAt ( k + 1 ) === Token . SLASH ) {
216203 j = k + 1
217204 break
218205 }
219206 }
220207 }
221208
222209 // End of the "property" of the property-value pair.
223- else if ( colonIdx === - 1 && peekChar === COLON ) {
210+ else if ( colonIdx === - 1 && peekChar === Token . COLON ) {
224211 colonIdx = buffer . length + j - start
225212 }
226213
227214 // End of the custom property.
228- else if ( peekChar === SEMICOLON && closingBracketStack . length === 0 ) {
215+ else if ( peekChar === Token . SEMICOLON && closingBracketStack . length === 0 ) {
229216 buffer += input . slice ( start , j )
230217 i = j
231218 break
232219 }
233220
234221 // Start of a block.
235- else if ( peekChar === OPEN_PARENTHESIS ) {
222+ else if ( peekChar === Token . OPEN_PAREN ) {
236223 closingBracketStack += ')'
237- } else if ( peekChar === OPEN_BRACKET ) {
224+ } else if ( peekChar === Token . OPEN_BRACKET ) {
238225 closingBracketStack += ']'
239- } else if ( peekChar === OPEN_CURLY_BRACKET ) {
226+ } else if ( peekChar === Token . OPEN_CURLY ) {
240227 closingBracketStack += '}'
241228 }
242229
@@ -252,7 +239,7 @@ export function parse(input: string) {
252239 // }
253240 // ```
254241 else if (
255- ( peekChar === CLOSE_CURLY_BRACKET || input . length - 1 === j ) &&
242+ ( peekChar === Token . CLOSE_CURLY || input . length - 1 === j ) &&
256243 closingBracketStack . length === 0
257244 ) {
258245 i = j - 1
@@ -262,9 +249,9 @@ export function parse(input: string) {
262249
263250 // End of a block.
264251 else if (
265- peekChar === CLOSE_PARENTHESIS ||
266- peekChar === CLOSE_BRACKET ||
267- peekChar === CLOSE_CURLY_BRACKET
252+ peekChar === Token . CLOSE_PAREN ||
253+ peekChar === Token . CLOSE_BRACKET ||
254+ peekChar === Token . CLOSE_CURLY
268255 ) {
269256 if (
270257 closingBracketStack . length > 0 &&
@@ -293,7 +280,7 @@ export function parse(input: string) {
293280 // @charset "UTF-8";
294281 // ^
295282 // ```
296- else if ( currentChar === SEMICOLON && buffer . charCodeAt ( 0 ) === AT_SIGN ) {
283+ else if ( currentChar === Token . SEMICOLON && buffer . charCodeAt ( 0 ) === Token . AT_SIGN ) {
297284 node = rule ( buffer , [ ] )
298285
299286 // At-rule is nested inside of a rule, attach it to the parent.
@@ -322,7 +309,7 @@ export function parse(input: string) {
322309 // }
323310 // ```
324311 //
325- else if ( currentChar === SEMICOLON ) {
312+ else if ( currentChar === Token . SEMICOLON ) {
326313 let declaration = parseDeclaration ( buffer )
327314 if ( parent ) {
328315 parent . nodes . push ( declaration )
@@ -334,7 +321,7 @@ export function parse(input: string) {
334321 }
335322
336323 // Start of a block.
337- else if ( currentChar === OPEN_CURLY_BRACKET ) {
324+ else if ( currentChar === Token . OPEN_CURLY ) {
338325 closingBracketStack += '}'
339326
340327 // At this point `buffer` should resemble a selector or an at-rule.
@@ -359,7 +346,7 @@ export function parse(input: string) {
359346 }
360347
361348 // End of a block.
362- else if ( currentChar === CLOSE_CURLY_BRACKET ) {
349+ else if ( currentChar === Token . CLOSE_CURLY ) {
363350 if ( closingBracketStack === '' ) {
364351 throw new Error ( 'Missing opening {' )
365352 }
@@ -380,7 +367,7 @@ export function parse(input: string) {
380367 // ^
381368 // }
382369 // ```
383- if ( buffer . charCodeAt ( 0 ) === AT_SIGN ) {
370+ if ( buffer . charCodeAt ( 0 ) === Token . AT_SIGN ) {
384371 node = rule ( buffer . trim ( ) , [ ] )
385372
386373 // At-rule is nested inside of a rule, attach it to the parent.
@@ -452,7 +439,9 @@ export function parse(input: string) {
452439 // Skip whitespace at the start of a new node.
453440 if (
454441 buffer . length === 0 &&
455- ( currentChar === SPACE || currentChar === LINE_BREAK || currentChar === TAB )
442+ ( currentChar === Token . SPACE ||
443+ currentChar === Token . LINE_BREAK ||
444+ currentChar === Token . TAB )
456445 ) {
457446 continue
458447 }
0 commit comments