From 5c125b978d128e697f7a9f78d6045087fc697f53 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 7 May 2020 16:41:03 -0400 Subject: [PATCH] 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. --- CHANGES.md | 2 ++ src/languages/javascript.js | 25 ++++++++++++++++--- src/lib/regex.js | 4 +++ test/markup/javascript/object-attr.expect.txt | 10 +++++++- test/markup/javascript/object-attr.txt | 11 +++++++- 5 files changed, 46 insertions(+), 6 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 2cf4ad9ace..6c3f7225ce 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,6 +15,8 @@ Deprecations: - `endSameAsBegin` is now deprecated. (#2261) [Josh Goebel][] Language Improvements: + +- fix(javascript) fix regex inside parens after a non-regex (#2530) [Josh Goebel][] - enh(typescript) use identifier to match potential keywords, preventing false positivites (#2519) [Josh Goebel][] - enh(javascript) use identifier to match potential keywords, preventing false positivites (#2519) [Josh Goebel][] - [enh] Add `OPTIMIZE:` and `HACK:` to the labels highlighted inside comments [Josh Goebel][] diff --git a/src/languages/javascript.js b/src/languages/javascript.js index 35b12dba02..c8334357bc 100644 --- a/src/languages/javascript.js +++ b/src/languages/javascript.js @@ -6,6 +6,7 @@ Website: https://developer.mozilla.org/en-US/docs/Web/JavaScript */ import * as ECMAScript from "./lib/ecmascript"; +import * as regex from "../lib/regex"; export default function(hljs) { var IDENT_RE = ECMAScript.IDENT_RE; @@ -149,13 +150,29 @@ export default function(hljs) { hljs.C_BLOCK_COMMENT_MODE, NUMBER, { // object attr container - begin: /[{,\n]\s*/, relevance: 0, + begin: regex.concat(/[{,\n]\s*/, + // we need to look ahead to make sure that we actually have an + // attribute coming up so we don't steal a comma from a potential + // "value" container + // + // NOTE: this might not work how you think. We don't actually always + // enter this mode and stay. Instead it might merely match `, + // ` and then immediately end after the , because it + // fails to find any actual attrs. But this still does the job because + // it prevents the value contain rule from grabbing this instead and + // prevening this rule from firing when we actually DO have keys. + regex.lookahead(regex.concat( + // we also need to allow for multiple possible comments inbetween + // the first key:value pairing + /(((\/\/.*)|(\/\*(.|\n)*\*\/))\s*)*/, + IDENT_RE + '\\s*:'))), + relevance: 0, contains: [ { - begin: IDENT_RE + '\\s*:', returnBegin: true, + className: 'attr', + begin: IDENT_RE + regex.lookahead('\\s*:'), relevance: 0, - contains: [{className: 'attr', begin: IDENT_RE, relevance: 0}] - } + }, ] }, { // "value" container diff --git a/src/lib/regex.js b/src/lib/regex.js index 003dc9cbca..80a9ce1b70 100644 --- a/src/lib/regex.js +++ b/src/lib/regex.js @@ -8,6 +8,10 @@ export function source(re) { return (re && re.source) || re; } +export function lookahead(regex) { + return concat('(?=', regex, ')'); +} + export function concat(...args) { const joined = args.map((x) => source(x)).join(""); return joined; diff --git a/test/markup/javascript/object-attr.expect.txt b/test/markup/javascript/object-attr.expect.txt index e92b578cea..54e9d7301f 100644 --- a/test/markup/javascript/object-attr.expect.txt +++ b/test/markup/javascript/object-attr.expect.txt @@ -1,6 +1,14 @@ { key: value, // with comment key2: value, + key2clone: value, 'key-3': value, - key4: false ? undefined : true + key4: false ? undefined : true, + key5: value, /* with a multiline comment */ + key6: value, + key7: value, /* with a multiline comment */ // another comment + key8: value, + key9: value, /* with a REAL multiline +comment */ + key10: value, } diff --git a/test/markup/javascript/object-attr.txt b/test/markup/javascript/object-attr.txt index 442c0a17ae..b024927090 100644 --- a/test/markup/javascript/object-attr.txt +++ b/test/markup/javascript/object-attr.txt @@ -1,6 +1,15 @@ { key: value, // with comment key2: value, + key2clone: value, 'key-3': value, - key4: false ? undefined : true + key4: false ? undefined : true, + key5: value, /* with a multiline comment */ + key6: value, + key7: value, /* with a multiline comment */ // another comment + key8: value, + key9: value, /* with a REAL multiline +comment */ + key10: value, } +