11import { JS_TEMPLATE , JS_TEMPLATE_INTERPOLATION } from '../shared/languages/patterns.js' ;
22import { toArray } from '../util/iterables.js' ;
3- import { insertBefore } from '../util/language-util.js' ;
43import clike from './clike.js' ;
54
65/** @type {import('../types.d.ts').LanguageProto<'javascript'> } */
@@ -9,135 +8,10 @@ export default {
98 base : clike ,
109 optional : 'js-templates' ,
1110 alias : 'js' ,
12- grammar ( { base, getOptionalLanguage } ) {
13- insertBefore ( base , 'comment' , {
14- 'doc-comment' : {
15- pattern : / \/ \* \* (? ! \/ ) [ \s \S ] * ?(?: \* \/ | $ ) / ,
16- greedy : true ,
17- inside : 'jsdoc' ,
18- } ,
19- } ) ;
20-
21- insertBefore ( base , 'keyword' , {
22- 'regex' : {
23- pattern : RegExp (
24- // lookbehind
25- // eslint-disable-next-line regexp/no-dupe-characters-character-class
26- / ( (?: ^ | [ ^ $ \w \xA0 - \uFFFF . " ' \] ) \s ] | \b (?: r e t u r n | y i e l d ) ) \s * ) / . source +
27- // Regex pattern:
28- // There are 2 regex patterns here. The RegExp set notation proposal added support for nested character
29- // classes if the `v` flag is present. Unfortunately, nested CCs are both context-free and incompatible
30- // with the only syntax, so we have to define 2 different regex patterns.
31- / \/ / . source +
32- '(?:' +
33- / (?: \[ (?: [ ^ \] \\ \r \n ] | \\ .) * \] | \\ .| [ ^ / \\ \[ \r \n ] ) + \/ [ d g i m y u s ] { 0 , 7 } / . source +
34- '|' +
35- // `v` flag syntax. This supports 3 levels of nested character classes.
36- / (?: \[ (?: [ ^ [ \] \\ \r \n ] | \\ .| \[ (?: [ ^ [ \] \\ \r \n ] | \\ .| \[ (?: [ ^ [ \] \\ \r \n ] | \\ .) * \] ) * \] ) * \] | \\ .| [ ^ / \\ \[ \r \n ] ) + \/ [ d g i m y u s ] { 0 , 7 } v [ d g i m y u s ] { 0 , 7 } /
37- . source +
38- ')' +
39- // lookahead
40- / (? = (?: \s | \/ \* (?: [ ^ * ] | \* (? ! \/ ) ) * \* \/ ) * (?: $ | [ \r \n , . ; : } ) \] ] | \/ \/ ) ) / . source
41- ) ,
42- lookbehind : true ,
43- greedy : true ,
44- inside : {
45- 'regex-source' : {
46- pattern : / ^ ( \/ ) [ \s \S ] + (? = \/ [ a - z ] * $ ) / ,
47- lookbehind : true ,
48- alias : 'language-regex' ,
49- inside : 'regex' ,
50- } ,
51- 'regex-delimiter' : / ^ \/ | \/ $ / ,
52- 'regex-flags' : / ^ [ a - z ] + $ / ,
53- } ,
54- } ,
55- // This must be declared before keyword because we use "function" inside the look-forward
56- 'function-variable' : {
57- pattern :
58- / # ? (? ! \s ) [ _ $ a - z A - Z \xA0 - \uFFFF ] (?: (? ! \s ) [ $ \w \xA0 - \uFFFF ] ) * (? = \s * [ = : ] \s * (?: a s y n c \s * ) ? (?: \b f u n c t i o n \b | (?: \( (?: [ ^ ( ) ] | \( [ ^ ( ) ] * \) ) * \) | (? ! \s ) [ _ $ a - z A - Z \xA0 - \uFFFF ] (?: (? ! \s ) [ $ \w \xA0 - \uFFFF ] ) * ) \s * = > ) ) / ,
59- alias : 'function' ,
60- } ,
61- 'parameter' : [
62- {
63- pattern :
64- / ( f u n c t i o n (?: \s + (? ! \s ) [ _ $ a - z A - Z \xA0 - \uFFFF ] (?: (? ! \s ) [ $ \w \xA0 - \uFFFF ] ) * ) ? \s * \( \s * ) (? ! \s ) (?: [ ^ ( ) \s ] | \s + (? ! [ \s ) ] ) | \( [ ^ ( ) ] * \) ) + (? = \s * \) ) / ,
65- lookbehind : true ,
66- inside : 'javascript' ,
67- } ,
68- {
69- pattern :
70- / ( ^ | [ ^ $ \w \xA0 - \uFFFF ] ) (? ! \s ) [ _ $ a - z \xA0 - \uFFFF ] (?: (? ! \s ) [ $ \w \xA0 - \uFFFF ] ) * (? = \s * = > ) / i,
71- lookbehind : true ,
72- inside : 'javascript' ,
73- } ,
74- {
75- pattern : / ( \( \s * ) (? ! \s ) (?: [ ^ ( ) \s ] | \s + (? ! [ \s ) ] ) | \( [ ^ ( ) ] * \) ) + (? = \s * \) \s * = > ) / ,
76- lookbehind : true ,
77- inside : 'javascript' ,
78- } ,
79- {
80- pattern :
81- / ( (?: \b | \s | ^ ) (? ! (?: a s | a s y n c | a w a i t | b r e a k | c a s e | c a t c h | c l a s s | c o n s t | c o n t i n u e | d e b u g g e r | d e f a u l t | d e l e t e | d o | e l s e | e n u m | e x p o r t | e x t e n d s | f i n a l l y | f o r | f r o m | f u n c t i o n | g e t | i f | i m p l e m e n t s | i m p o r t | i n | i n s t a n c e o f | i n t e r f a c e | l e t | n e w | n u l l | o f | p a c k a g e | p r i v a t e | p r o t e c t e d | p u b l i c | r e t u r n | s e t | s t a t i c | s u p e r | s w i t c h | t h i s | t h r o w | t r y | t y p e o f | u n d e f i n e d | v a r | v o i d | w h i l e | w i t h | y i e l d ) (? ! [ $ \w \xA0 - \uFFFF ] ) ) (?: (? ! \s ) [ _ $ a - z A - Z \xA0 - \uFFFF ] (?: (? ! \s ) [ $ \w \xA0 - \uFFFF ] ) * \s * ) \( \s * | \] \s * \( \s * ) (? ! \s ) (?: [ ^ ( ) \s ] | \s + (? ! [ \s ) ] ) | \( [ ^ ( ) ] * \) ) + (? = \s * \) \s * \{ ) / ,
82- lookbehind : true ,
83- inside : 'javascript' ,
84- } ,
85- ] ,
86- 'constant' : / \b [ A - Z ] (?: [ A - Z _ ] | \d x ? ) * \b / ,
87- } ) ;
88-
89- const jsTemplates = getOptionalLanguage ( 'js-templates' ) ?. [ 'template-string' ] ;
90-
91- insertBefore ( base , 'string' , {
92- 'hashbang' : {
93- pattern : / ^ # ! .* / ,
94- greedy : true ,
95- alias : 'comment' ,
96- } ,
97- 'template-string' : [
98- ...toArray ( jsTemplates ) ,
99- {
100- pattern : JS_TEMPLATE ,
101- greedy : true ,
102- inside : /** @type {Grammar } */ ( {
103- 'template-punctuation' : {
104- pattern : / ^ ` | ` $ / ,
105- alias : 'string' ,
106- } ,
107- 'interpolation' : {
108- pattern : RegExp (
109- / ( (?: ^ | [ ^ \\ ] ) (?: \\ { 2 } ) * ) / . source + JS_TEMPLATE_INTERPOLATION . source
110- ) ,
111- lookbehind : true ,
112- inside : {
113- 'interpolation-punctuation' : {
114- pattern : / ^ \$ \{ | \} $ / ,
115- alias : 'punctuation' ,
116- } ,
117- $rest : /** @type {Grammar['$rest'] } */ ( 'javascript' ) ,
118- } ,
119- } ,
120- 'string' : / [ \s \S ] + / ,
121- } ) ,
122- } ,
123- ] ,
124- 'string-property' : {
125- pattern :
126- / ( (?: ^ | [ , { ] ) [ \t ] * ) ( [ " ' ] ) (?: \\ (?: \r \n | [ \s \S ] ) | (? ! \2) [ ^ \\ \r \n ] ) * \2(? = \s * : ) / m,
127- lookbehind : true ,
128- greedy : true ,
129- alias : 'property' ,
130- } ,
131- } ) ;
132-
133- insertBefore ( base , 'operator' , {
134- 'literal-property' : {
135- pattern :
136- / ( (?: ^ | [ , { ] ) [ \t ] * ) (? ! \s ) [ _ $ a - z A - Z \xA0 - \uFFFF ] (?: (? ! \s ) [ $ \w \xA0 - \uFFFF ] ) * (? = \s * : ) / m,
137- lookbehind : true ,
138- alias : 'property' ,
139- } ,
140- } ) ;
11+ grammar ( { getOptionalLanguage } ) {
12+ const jsTemplates = /** @type {GrammarTokens } */ ( getOptionalLanguage ( 'js-templates' ) ) ?. [
13+ 'template-string'
14+ ] ;
14115
14216 return {
14317 'class-name' : [
@@ -210,10 +84,140 @@ export default {
21084 } ,
21185 'operator' :
21286 / - - | \+ \+ | \* \* = ? | = > | & & = ? | \| \| = ? | [ ! = ] = = | < < = ? | > > > ? = ? | [ - + * / % & | ^ ! = < > ] = ? | \. { 3 } | \? \? = ? | \? \. ? | [ ~ : ] / ,
87+ $insertBefore : {
88+ 'comment' : {
89+ 'doc-comment' : {
90+ pattern : / \/ \* \* (? ! \/ ) [ \s \S ] * ?(?: \* \/ | $ ) / ,
91+ greedy : true ,
92+ inside : 'jsdoc' ,
93+ } ,
94+ } ,
95+ 'keyword' : {
96+ 'regex' : {
97+ pattern : RegExp (
98+ // lookbehind
99+ // eslint-disable-next-line regexp/no-dupe-characters-character-class
100+ / ( (?: ^ | [ ^ $ \w \xA0 - \uFFFF . " ' \] ) \s ] | \b (?: r e t u r n | y i e l d ) ) \s * ) / . source +
101+ // Regex pattern:
102+ // There are 2 regex patterns here. The RegExp set notation proposal added support for nested character
103+ // classes if the `v` flag is present. Unfortunately, nested CCs are both context-free and incompatible
104+ // with the only syntax, so we have to define 2 different regex patterns.
105+ / \/ / . source +
106+ '(?:' +
107+ / (?: \[ (?: [ ^ \] \\ \r \n ] | \\ .) * \] | \\ .| [ ^ / \\ \[ \r \n ] ) + \/ [ d g i m y u s ] { 0 , 7 } /
108+ . source +
109+ '|' +
110+ // `v` flag syntax. This supports 3 levels of nested character classes.
111+ / (?: \[ (?: [ ^ [ \] \\ \r \n ] | \\ .| \[ (?: [ ^ [ \] \\ \r \n ] | \\ .| \[ (?: [ ^ [ \] \\ \r \n ] | \\ .) * \] ) * \] ) * \] | \\ .| [ ^ / \\ \[ \r \n ] ) + \/ [ d g i m y u s ] { 0 , 7 } v [ d g i m y u s ] { 0 , 7 } /
112+ . source +
113+ ')' +
114+ // lookahead
115+ / (? = (?: \s | \/ \* (?: [ ^ * ] | \* (? ! \/ ) ) * \* \/ ) * (?: $ | [ \r \n , . ; : } ) \] ] | \/ \/ ) ) /
116+ . source
117+ ) ,
118+ lookbehind : true ,
119+ greedy : true ,
120+ inside : {
121+ 'regex-source' : {
122+ pattern : / ^ ( \/ ) [ \s \S ] + (? = \/ [ a - z ] * $ ) / ,
123+ lookbehind : true ,
124+ alias : 'language-regex' ,
125+ inside : 'regex' ,
126+ } ,
127+ 'regex-delimiter' : / ^ \/ | \/ $ / ,
128+ 'regex-flags' : / ^ [ a - z ] + $ / ,
129+ } ,
130+ } ,
131+ // This must be declared before keyword because we use "function" inside the look-forward
132+ 'function-variable' : {
133+ pattern :
134+ / # ? (? ! \s ) [ _ $ a - z A - Z \xA0 - \uFFFF ] (?: (? ! \s ) [ $ \w \xA0 - \uFFFF ] ) * (? = \s * [ = : ] \s * (?: a s y n c \s * ) ? (?: \b f u n c t i o n \b | (?: \( (?: [ ^ ( ) ] | \( [ ^ ( ) ] * \) ) * \) | (? ! \s ) [ _ $ a - z A - Z \xA0 - \uFFFF ] (?: (? ! \s ) [ $ \w \xA0 - \uFFFF ] ) * ) \s * = > ) ) / ,
135+ alias : 'function' ,
136+ } ,
137+ 'parameter' : [
138+ {
139+ pattern :
140+ / ( f u n c t i o n (?: \s + (? ! \s ) [ _ $ a - z A - Z \xA0 - \uFFFF ] (?: (? ! \s ) [ $ \w \xA0 - \uFFFF ] ) * ) ? \s * \( \s * ) (? ! \s ) (?: [ ^ ( ) \s ] | \s + (? ! [ \s ) ] ) | \( [ ^ ( ) ] * \) ) + (? = \s * \) ) / ,
141+ lookbehind : true ,
142+ inside : 'javascript' ,
143+ } ,
144+ {
145+ pattern :
146+ / ( ^ | [ ^ $ \w \xA0 - \uFFFF ] ) (? ! \s ) [ _ $ a - z \xA0 - \uFFFF ] (?: (? ! \s ) [ $ \w \xA0 - \uFFFF ] ) * (? = \s * = > ) / i,
147+ lookbehind : true ,
148+ inside : 'javascript' ,
149+ } ,
150+ {
151+ pattern :
152+ / ( \( \s * ) (? ! \s ) (?: [ ^ ( ) \s ] | \s + (? ! [ \s ) ] ) | \( [ ^ ( ) ] * \) ) + (? = \s * \) \s * = > ) / ,
153+ lookbehind : true ,
154+ inside : 'javascript' ,
155+ } ,
156+ {
157+ pattern :
158+ / ( (?: \b | \s | ^ ) (? ! (?: a s | a s y n c | a w a i t | b r e a k | c a s e | c a t c h | c l a s s | c o n s t | c o n t i n u e | d e b u g g e r | d e f a u l t | d e l e t e | d o | e l s e | e n u m | e x p o r t | e x t e n d s | f i n a l l y | f o r | f r o m | f u n c t i o n | g e t | i f | i m p l e m e n t s | i m p o r t | i n | i n s t a n c e o f | i n t e r f a c e | l e t | n e w | n u l l | o f | p a c k a g e | p r i v a t e | p r o t e c t e d | p u b l i c | r e t u r n | s e t | s t a t i c | s u p e r | s w i t c h | t h i s | t h r o w | t r y | t y p e o f | u n d e f i n e d | v a r | v o i d | w h i l e | w i t h | y i e l d ) (? ! [ $ \w \xA0 - \uFFFF ] ) ) (?: (? ! \s ) [ _ $ a - z A - Z \xA0 - \uFFFF ] (?: (? ! \s ) [ $ \w \xA0 - \uFFFF ] ) * \s * ) \( \s * | \] \s * \( \s * ) (? ! \s ) (?: [ ^ ( ) \s ] | \s + (? ! [ \s ) ] ) | \( [ ^ ( ) ] * \) ) + (? = \s * \) \s * \{ ) / ,
159+ lookbehind : true ,
160+ inside : 'javascript' ,
161+ } ,
162+ ] ,
163+ 'constant' : / \b [ A - Z ] (?: [ A - Z _ ] | \d x ? ) * \b / ,
164+ } ,
165+ 'string' : {
166+ 'hashbang' : {
167+ pattern : / ^ # ! .* / ,
168+ greedy : true ,
169+ alias : 'comment' ,
170+ } ,
171+ 'template-string' : [
172+ ...toArray ( jsTemplates ) ,
173+ {
174+ pattern : JS_TEMPLATE ,
175+ greedy : true ,
176+ inside : /** @type {Grammar } */ ( {
177+ 'template-punctuation' : {
178+ pattern : / ^ ` | ` $ / ,
179+ alias : 'string' ,
180+ } ,
181+ 'interpolation' : {
182+ pattern : RegExp (
183+ / ( (?: ^ | [ ^ \\ ] ) (?: \\ { 2 } ) * ) / . source +
184+ JS_TEMPLATE_INTERPOLATION . source
185+ ) ,
186+ lookbehind : true ,
187+ inside : {
188+ 'interpolation-punctuation' : {
189+ pattern : / ^ \$ \{ | \} $ / ,
190+ alias : 'punctuation' ,
191+ } ,
192+ $rest : /** @type {Grammar['$rest'] } */ ( 'javascript' ) ,
193+ } ,
194+ } ,
195+ 'string' : / [ \s \S ] + / ,
196+ } ) ,
197+ } ,
198+ ] ,
199+ 'string-property' : {
200+ pattern :
201+ / ( (?: ^ | [ , { ] ) [ \t ] * ) ( [ " ' ] ) (?: \\ (?: \r \n | [ \s \S ] ) | (? ! \2) [ ^ \\ \r \n ] ) * \2(? = \s * : ) / m,
202+ lookbehind : true ,
203+ greedy : true ,
204+ alias : 'property' ,
205+ } ,
206+ } ,
207+ 'operator' : {
208+ 'literal-property' : {
209+ pattern :
210+ / ( (?: ^ | [ , { ] ) [ \t ] * ) (? ! \s ) [ _ $ a - z A - Z \xA0 - \uFFFF ] (?: (? ! \s ) [ $ \w \xA0 - \uFFFF ] ) * (? = \s * : ) / m,
211+ lookbehind : true ,
212+ alias : 'property' ,
213+ } ,
214+ } ,
215+ } ,
213216 } ;
214217 } ,
215218} ;
216219
217220/**
218221 * @typedef {import('../types.d.ts').Grammar } Grammar
222+ * @typedef {import('../types.d.ts').GrammarTokens } GrammarTokens
219223 */
0 commit comments