Skip to content

Commit 586aa31

Browse files
committed
Add support for JSX identifiers
1 parent 622b552 commit 586aa31

File tree

4 files changed

+62
-11
lines changed

4 files changed

+62
-11
lines changed

index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1+
/**
2+
* @typedef {import('./lib/index.js').Options} Options
3+
*/
4+
15
export {cont, name, start} from './lib/index.js'

lib/index.js

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
1+
/**
2+
* @typedef Options
3+
* Configuration.
4+
* @property {boolean | null | undefined} [jsx=false]
5+
* Support JSX identifiers (default: `false`).
6+
*/
7+
18
const startRe = /[$_\p{ID_Start}]/u
29
const contRe = /[$_\u{200C}\u{200D}\p{ID_Continue}]/u
3-
const re = /^[$_\p{ID_Start}][$_\u{200C}\u{200D}\p{ID_Continue}]*$/u
10+
const contReJsx = /[-$_\u{200C}\u{200D}\p{ID_Continue}]/u
11+
const nameRe = /^[$_\p{ID_Start}][$_\u{200C}\u{200D}\p{ID_Continue}]*$/u
12+
const nameReJsx = /^[$_\p{ID_Start}][-$_\u{200C}\u{200D}\p{ID_Continue}]*$/u
13+
14+
/** @type {Options} */
15+
const emptyOptions = {}
416

517
/**
618
* Checks if the given code point can start an identifier.
@@ -20,22 +32,30 @@ export function start(code) {
2032
*
2133
* @param {number | undefined} code
2234
* Code point to check.
35+
* @param {Options | null | undefined} [options]
36+
* Configuration (optional).
2337
* @returns {boolean}
2438
* Whether `code` can continue an identifier.
2539
*/
2640
// Note: `undefined` is supported so you can pass the result from `''.codePointAt`.
27-
export function cont(code) {
28-
return code ? contRe.test(String.fromCodePoint(code)) : false
41+
export function cont(code, options) {
42+
const settings = options || emptyOptions
43+
const re = settings.jsx ? contReJsx : contRe
44+
return code ? re.test(String.fromCodePoint(code)) : false
2945
}
3046

3147
/**
3248
* Checks if the given value is a valid identifier name.
3349
*
3450
* @param {string} name
3551
* Identifier to check.
52+
* @param {Options | null | undefined} [options]
53+
* Configuration (optional).
3654
* @returns {boolean}
3755
* Whether `name` can be an identifier.
3856
*/
39-
export function name(name) {
57+
export function name(name, options) {
58+
const settings = options || emptyOptions
59+
const re = settings.jsx ? nameReJsx : nameRe
4060
return re.test(name)
4161
}

readme.md

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@
1717
* [Install](#install)
1818
* [Use](#use)
1919
* [API](#api)
20-
* [`cont(code)`](#contcode)
21-
* [`name(name)`](#namename)
20+
* [`cont(code[, options])`](#contcode-options)
21+
* [`name(name[, options])`](#namename-options)
2222
* [`start(code)`](#startcode)
23+
* [Options](#options)
2324
* [Types](#types)
2425
* [Compatibility](#compatibility)
2526
* [Related](#related)
@@ -78,27 +79,31 @@ This package exports the identifiers [`cont`][cont], [`name`][name], and
7879
[`start`][start].
7980
There is no default export.
8081

81-
### `cont(code)`
82+
### `cont(code[, options])`
8283

8384
Checks if the given code point can continue an identifier.
8485

8586
###### Parameters
8687

8788
* `code` (`number`)
8889
— code point to check
90+
* `options` ([`Options`][api-options], optional)
91+
— configuration
8992

9093
###### Returns
9194

9295
Whether `code` can continue an identifier (`boolean`).
9396

94-
### `name(name)`
97+
### `name(name[, options])`
9598

9699
Checks if the given value is a valid identifier name.
97100

98101
###### Parameters
99102

100103
* `name` (`string`)
101104
— identifier to check
105+
* `options` ([`Options`][api-options], optional)
106+
— configuration
102107

103108
###### Returns
104109

@@ -117,10 +122,19 @@ Checks if the given code point can start an identifier.
117122

118123
Whether `code` can start an identifier (`boolean`).
119124

125+
### Options
126+
127+
Configuration (TypeScript type).
128+
129+
###### Fields
130+
131+
* `jsx` (`boolean`, default: `false`)
132+
— support JSX identifiers.
133+
120134
## Types
121135

122136
This package is fully typed with [TypeScript][].
123-
It exports no additional types.
137+
It exports the additional type [`Options`][api-options].
124138

125139
## Compatibility
126140

@@ -198,8 +212,10 @@ abide by its terms.
198212

199213
[estree]: https://github.com/estree/estree
200214

201-
[cont]: #contcode
215+
[cont]: #contcode-options
202216

203-
[name]: #namename
217+
[name]: #namename-options
204218

205219
[start]: #startcode
220+
221+
[api-options]: #options

test.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ test('isIdentifierName', () => {
3939
'should say `0xd8_00 0xde_a7` (together 0x1_02_a7) is a cont code'
4040
)
4141
assert.ok(!cont(0xd8_00), 'should not say `0xd8_00` is a cont code')
42+
assert.ok(
43+
!cont('-'.codePointAt(0)),
44+
'should not say `-` is a cont code normally'
45+
)
46+
assert.ok(
47+
cont('-'.codePointAt(0), {jsx: true}),
48+
'should say `-` is a cont code w/ `jsx: true`'
49+
)
4250

4351
assert.ok(!name(''), 'should not say `` (empty string) is a name')
4452
assert.ok(name('a'), 'should say `a` is a name')
@@ -52,4 +60,7 @@ test('isIdentifierName', () => {
5260
assert.ok(!name('-aaa'), 'should not say `-aaa` is a name')
5361
assert.ok(name('ಠ_ಠ'), 'should say `ಠ_ಠ` is a name')
5462
assert.ok(name('𐊧'), 'should say `𐊧` (0x1_02_a7) is a name')
63+
assert.ok(!name('a-b'), 'should not say `a-b` is a name normally')
64+
assert.ok(name('a-b', {jsx: true}), 'should say `a-b` is a jsx name')
65+
assert.ok(name('a-', {jsx: true}), 'should say `a-` is a jsx name')
5566
})

0 commit comments

Comments
 (0)