Skip to content

Commit 5c125b9

Browse files
authored
fix(javascript) fix regex inside parens after a non-regex (#2531)
* make the object attr container smarter * deal with multi-line comments also * comments in any order, spanning multiple lines Essentially makes the object attr container much more sensitive by allowing it to look-ahead thru comments to find object keys - and therefore prevent them from being incorrectly matched by the "value container" rule.
1 parent 9e4f2dc commit 5c125b9

File tree

5 files changed

+46
-6
lines changed

5 files changed

+46
-6
lines changed

CHANGES.md

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Deprecations:
1515
- `endSameAsBegin` is now deprecated. (#2261) [Josh Goebel][]
1616

1717
Language Improvements:
18+
19+
- fix(javascript) fix regex inside parens after a non-regex (#2530) [Josh Goebel][]
1820
- enh(typescript) use identifier to match potential keywords, preventing false positivites (#2519) [Josh Goebel][]
1921
- enh(javascript) use identifier to match potential keywords, preventing false positivites (#2519) [Josh Goebel][]
2022
- [enh] Add `OPTIMIZE:` and `HACK:` to the labels highlighted inside comments [Josh Goebel][]

src/languages/javascript.js

+21-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Website: https://developer.mozilla.org/en-US/docs/Web/JavaScript
66
*/
77

88
import * as ECMAScript from "./lib/ecmascript";
9+
import * as regex from "../lib/regex";
910

1011
export default function(hljs) {
1112
var IDENT_RE = ECMAScript.IDENT_RE;
@@ -149,13 +150,29 @@ export default function(hljs) {
149150
hljs.C_BLOCK_COMMENT_MODE,
150151
NUMBER,
151152
{ // object attr container
152-
begin: /[{,\n]\s*/, relevance: 0,
153+
begin: regex.concat(/[{,\n]\s*/,
154+
// we need to look ahead to make sure that we actually have an
155+
// attribute coming up so we don't steal a comma from a potential
156+
// "value" container
157+
//
158+
// NOTE: this might not work how you think. We don't actually always
159+
// enter this mode and stay. Instead it might merely match `,
160+
// <comments up next>` and then immediately end after the , because it
161+
// fails to find any actual attrs. But this still does the job because
162+
// it prevents the value contain rule from grabbing this instead and
163+
// prevening this rule from firing when we actually DO have keys.
164+
regex.lookahead(regex.concat(
165+
// we also need to allow for multiple possible comments inbetween
166+
// the first key:value pairing
167+
/(((\/\/.*)|(\/\*(.|\n)*\*\/))\s*)*/,
168+
IDENT_RE + '\\s*:'))),
169+
relevance: 0,
153170
contains: [
154171
{
155-
begin: IDENT_RE + '\\s*:', returnBegin: true,
172+
className: 'attr',
173+
begin: IDENT_RE + regex.lookahead('\\s*:'),
156174
relevance: 0,
157-
contains: [{className: 'attr', begin: IDENT_RE, relevance: 0}]
158-
}
175+
},
159176
]
160177
},
161178
{ // "value" container

src/lib/regex.js

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ export function source(re) {
88
return (re && re.source) || re;
99
}
1010

11+
export function lookahead(regex) {
12+
return concat('(?=', regex, ')');
13+
}
14+
1115
export function concat(...args) {
1216
const joined = args.map((x) => source(x)).join("");
1317
return joined;
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
{
22
<span class="hljs-attr">key</span>: value, <span class="hljs-comment">// with comment</span>
33
<span class="hljs-attr">key2</span>: value,
4+
<span class="hljs-attr">key2clone</span>: value,
45
<span class="hljs-string">'key-3'</span>: value,
5-
<span class="hljs-attr">key4</span>: <span class="hljs-literal">false</span> ? <span class="hljs-literal">undefined</span> : <span class="hljs-literal">true</span>
6+
<span class="hljs-attr">key4</span>: <span class="hljs-literal">false</span> ? <span class="hljs-literal">undefined</span> : <span class="hljs-literal">true</span>,
7+
<span class="hljs-attr">key5</span>: value, <span class="hljs-comment">/* with a multiline comment */</span>
8+
<span class="hljs-attr">key6</span>: value,
9+
<span class="hljs-attr">key7</span>: value, <span class="hljs-comment">/* with a multiline comment */</span> <span class="hljs-comment">// another comment</span>
10+
<span class="hljs-attr">key8</span>: value,
11+
<span class="hljs-attr">key9</span>: value, <span class="hljs-comment">/* with a REAL multiline
12+
comment */</span>
13+
<span class="hljs-attr">key10</span>: value,
614
}
+10-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
{
22
key: value, // with comment
33
key2: value,
4+
key2clone: value,
45
'key-3': value,
5-
key4: false ? undefined : true
6+
key4: false ? undefined : true,
7+
key5: value, /* with a multiline comment */
8+
key6: value,
9+
key7: value, /* with a multiline comment */ // another comment
10+
key8: value,
11+
key9: value, /* with a REAL multiline
12+
comment */
13+
key10: value,
614
}
15+

0 commit comments

Comments
 (0)