-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathis-atomic.js
52 lines (38 loc) · 1.24 KB
/
is-atomic.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
import regexSource from './regex-source.js'
const closingCharacters = {
'(': `)`,
'[': `]`,
}
export default function isAtomic(regex) {
const string = regexSource(regex)
return /^\w$/.test(string) || enclosedByTopLevelCharacters(string)
}
function enclosedByTopLevelCharacters(string) {
const openingCharacter = string[0]
const closingCharacter = closingCharacters[openingCharacter]
const closedByAppropriateCharacter = closingCharacter !== undefined
&& string[string.length - 1] === closingCharacter
if (!closedByAppropriateCharacter) {
return false
}
return !isClosedBeforeEndOfString(string, openingCharacter, closingCharacter)
}
function isClosedBeforeEndOfString(string, openingCharacter, closingCharacter) {
let depth = 0
for (let characterIndex = 0; characterIndex < string.length - 1; ++characterIndex) {
depth = calculateNewDepth(depth, openingCharacter, closingCharacter, string[characterIndex])
if (depth === 0) {
return true
}
}
return false
}
function calculateNewDepth(previousDepth, openingCharacter, closingCharacter, character) {
if (character === openingCharacter) {
return previousDepth + 1
} else if (character === closingCharacter) {
return previousDepth - 1
} else {
return previousDepth
}
}