-
Notifications
You must be signed in to change notification settings - Fork 5
/
grammar.js
108 lines (92 loc) · 2.63 KB
/
grammar.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/***
* this is not intended to be a full-blown JS parser bolted onto the side of the
* CSS parser. it's an attempt to tokenize the most common contents of JS
* string-template substitutions used in CSS-in-JS contexts. complex JS
* expressions will probably cause this parser to fail, but you shouldn't be
* using complex JS expressions in your CSS-in-JS anyway.
***/
module.exports = grammar(require('./tree-sitter-css/grammar'), {
name: 'css_in_js',
rules: {
/* new rules specific to CSS-in-JS */
_js_identifier: $ => /[$_a-zA-Z0-9]+/,
_js_string: $ => token(choice(
seq("'", /([^'\n]|\\(.|\n))*/, "'"),
seq('"', /([^"\n]|\\(.|\n))*/, '"'),
seq('`', /([^`\n]|\\(.|\n))*/, '`')
)),
_js_expr: $ => choice(
$._js_string,
prec.right(1, seq($._js_expr, /\+\-\*\/%/, $._js_expr)), // foo + bar
prec.right(1, seq($._js_expr, '??', $._js_expr)), // foo ?? bar
prec.right(0, seq($._js_expr, '?', $._js_expr, ':', $._js_expr)), // foo ? bar : baz
seq(
$._js_identifier,
optional(choice(
seq(/\??\./, $._js_identifier), // foo?.bar
seq(optional(/\??\./), '(', optional($._js_args), ')'), // foo?.(bar)
seq(optional(/\??\./), '[', $._js_expr, ']') // foo?.[bar]
))
)
),
_js_param: $ => choice(
$._js_identifier,
seq('{', $._js_params, '}')
),
_js_params: $ => seq(
$._js_param,
repeat(seq(',', $._js_param))
),
_js_args: $ => seq(
$._js_expr,
repeat(seq(
',',
$._js_expr
))
),
_js_fat_arrow_function: $ => seq(
choice(
$._js_identifier,
seq('(', optional($._js_params), ')')
),
'=>',
$._js_expr
),
js_interpolation: $ => seq(
'${',
choice(
$._js_expr,
$._js_fat_arrow_function
),
'}'
),
/* re-exports of CSS grammar rules so we can reference them */
identifier: ($, original) => original,
_value: ($, original) => original,
important: ($, original) => original,
/* updates to original CSS grammar rules */
_top_level_item: ($, original) => choice(
original,
$._block_item,
$.js_interpolation
),
_block_item: ($, original) => choice(
original,
seq($.js_interpolation, optional(';'))
),
declaration: ($, original) => choice(
original,
seq(
alias($.identifier, $.property_name), // keep alias from CSS rule
':',
$.js_interpolation,
repeat(seq(
optional(','),
$._value
)),
optional($.important),
';'
)
)
}
});