riot-compiler
Advanced tools
Comparing version 3.2.3 to 3.2.4
# Compiler Changes | ||
### v3.2.4 | ||
- Fix [riot#2369](https://github.com/riot/riot/issues/2369) : Possible bug involving compilation of tags containing regex. | ||
- Using the `skip-regex` function from npm for sharing bwteen modules (at future). | ||
- Using the `jsSplitter` function for safer replacement of JS code, part of the next compiler. | ||
### v3.2.3 | ||
@@ -4,0 +9,0 @@ - Fixes various issues with literal regexes. |
/** | ||
* Compiler for riot custom tags | ||
* @version v3.2.3 | ||
* @version v3.2.4 | ||
*/ | ||
@@ -100,3 +100,3 @@ | ||
es6: function (js, opts, url) { | ||
es6: function (js, opts, url) { // eslint-disable-line no-unused-vars | ||
return _r('Babel').transform( // eslint-disable-line | ||
@@ -163,2 +163,117 @@ js, | ||
var S_SQ_STR = /'[^'\n\r\\]*(?:\\(?:\r\n?|[\S\s])[^'\n\r\\]*)*'/.source | ||
var S_R_SRC1 = [ | ||
/\/\*[^*]*\*+(?:[^*\/][^*]*\*+)*\//.source, | ||
'//.*', | ||
S_SQ_STR, | ||
S_SQ_STR.replace(/'/g, '"'), | ||
'([/`])' | ||
].join('|') | ||
var S_R_SRC2 = `${S_R_SRC1.slice(0, -2)}{}])` | ||
function skipES6str (code, start, stack) { | ||
var re = /[`$\\]/g | ||
re.lastIndex = start | ||
while (re.exec(code)) { | ||
var end = re.lastIndex | ||
var c = code[end - 1] | ||
if (c === '`') { | ||
return end | ||
} | ||
if (c === '$' && code[end] === '{') { | ||
stack.push('`', '}') | ||
return end + 1 | ||
} | ||
re.lastIndex++ | ||
} | ||
throw new Error('Unclosed ES6 template') | ||
} | ||
function jsSplitter (code, start) { | ||
var re1 = new RegExp(S_R_SRC1, 'g') | ||
var re2 | ||
var skipRegex = brackets.skipRegex | ||
var offset = start |= 0 | ||
var result = [[]] | ||
var stack = [] | ||
var re = re1 | ||
var lastPos = re.lastIndex = offset | ||
var str, ch, idx, end, match | ||
while ((match = re.exec(code))) { | ||
idx = match.index | ||
end = re.lastIndex | ||
str = '' | ||
ch = match[1] | ||
if (ch) { | ||
if (ch === '{') { | ||
stack.push('}') | ||
} else if (ch === '}') { | ||
if (stack.pop() !== ch) { | ||
throw new Error("Unexpected '}'") | ||
} else if (stack[stack.length - 1] === '`') { | ||
ch = stack.pop() | ||
} | ||
} else if (ch === '/') { | ||
end = skipRegex(code, idx) | ||
if (end > idx + 1) { | ||
str = code.slice(idx, end) | ||
} | ||
} | ||
if (ch === '`') { | ||
end = skipES6str(code, end, stack) | ||
str = code.slice(idx, end) | ||
if (stack.length) { | ||
re = re2 || (re2 = new RegExp(S_R_SRC2, 'g')) | ||
} else { | ||
re = re1 | ||
} | ||
} | ||
} else { | ||
str = match[0] | ||
if (str[0] === '/') { | ||
str = str[1] === '*' ? ' ' : '' | ||
code = code.slice(offset, idx) + str + code.slice(end) | ||
end = idx + str.length | ||
str = '' | ||
} else if (str.length === 2) { | ||
str = '' | ||
} | ||
} | ||
if (str) { | ||
result[0].push(code.slice(lastPos, idx)) | ||
result.push(str) | ||
lastPos = end | ||
} | ||
re.lastIndex = end | ||
} | ||
result[0].push(code.slice(lastPos)) | ||
return result | ||
} | ||
/** | ||
@@ -352,6 +467,2 @@ * @module compiler | ||
var JS_ES6END = RegExp('[{}]|' + brackets.S_QBLOCKS, 'g') | ||
var JS_COMMS = RegExp(brackets.R_MLCOMMS.source + '|//[^\r\n]*|' + brackets.S_QBLOCK2, 'g') | ||
function riotjs (js) { | ||
@@ -368,3 +479,4 @@ var | ||
if (~js.indexOf('/')) js = rmComms(js, JS_COMMS) | ||
const src = jsSplitter(js) | ||
js = src.shift().join('<%>') | ||
@@ -375,3 +487,3 @@ while ((match = js.match(JS_ES6SIGN))) { | ||
js = RE.rightContext | ||
pos = skipBody(js, JS_ES6END) | ||
pos = skipBody(js) | ||
@@ -396,24 +508,21 @@ method = match[1] | ||
return parts.length ? parts.join('') + js : js | ||
if (parts.length) { | ||
js = parts.join('') + js | ||
} | ||
function rmComms (s, r, m) { | ||
r.lastIndex = 0 | ||
while ((m = r.exec(s))) { | ||
if (m[1]) { | ||
r.lastIndex = brackets.skipRegex(s, m.index) | ||
} else if (m[0][0] === '/') { | ||
s = s.slice(0, m.index) + ' ' + s.slice(r.lastIndex) | ||
r.lastIndex = m.index + 1 | ||
} | ||
} | ||
return s | ||
if (src.length) { | ||
js = js.replace(/<%>/g, function () { | ||
return src.shift() | ||
}) | ||
} | ||
function skipBody (s, r) { | ||
var m, i = 1 | ||
return js | ||
r.lastIndex = 0 | ||
while (i && (m = r.exec(s))) { | ||
if (m[0] === '{') ++i | ||
else if (m[0] === '}') --i | ||
function skipBody (s) { | ||
var r = /[{}]/g | ||
var i = 1 | ||
while (i && r.exec(s)) { | ||
if (s[r.lastIndex - 1] === '{') ++i | ||
else --i | ||
} | ||
@@ -746,3 +855,3 @@ return i ? s.length : r.lastIndex | ||
var version = 'v3.2.3' | ||
var version = 'v3.2.4' | ||
@@ -749,0 +858,0 @@ export default { |
@@ -94,3 +94,3 @@ | ||
es6: function (js, opts, url) { | ||
es6: function (js, opts, url) { // eslint-disable-line no-unused-vars | ||
return _r('Babel').transform( // eslint-disable-line | ||
@@ -157,2 +157,117 @@ js, | ||
var S_SQ_STR = /'[^'\n\r\\]*(?:\\(?:\r\n?|[\S\s])[^'\n\r\\]*)*'/.source | ||
var S_R_SRC1 = [ | ||
/\/\*[^*]*\*+(?:[^*\/][^*]*\*+)*\//.source, | ||
'//.*', | ||
S_SQ_STR, | ||
S_SQ_STR.replace(/'/g, '"'), | ||
'([/`])' | ||
].join('|') | ||
var S_R_SRC2 = `${S_R_SRC1.slice(0, -2)}{}])` | ||
function skipES6str (code, start, stack) { | ||
var re = /[`$\\]/g | ||
re.lastIndex = start | ||
while (re.exec(code)) { | ||
var end = re.lastIndex | ||
var c = code[end - 1] | ||
if (c === '`') { | ||
return end | ||
} | ||
if (c === '$' && code[end] === '{') { | ||
stack.push('`', '}') | ||
return end + 1 | ||
} | ||
re.lastIndex++ | ||
} | ||
throw new Error('Unclosed ES6 template') | ||
} | ||
function jsSplitter (code, start) { | ||
var re1 = new RegExp(S_R_SRC1, 'g') | ||
var re2 | ||
var skipRegex = brackets.skipRegex | ||
var offset = start |= 0 | ||
var result = [[]] | ||
var stack = [] | ||
var re = re1 | ||
var lastPos = re.lastIndex = offset | ||
var str, ch, idx, end, match | ||
while ((match = re.exec(code))) { | ||
idx = match.index | ||
end = re.lastIndex | ||
str = '' | ||
ch = match[1] | ||
if (ch) { | ||
if (ch === '{') { | ||
stack.push('}') | ||
} else if (ch === '}') { | ||
if (stack.pop() !== ch) { | ||
throw new Error("Unexpected '}'") | ||
} else if (stack[stack.length - 1] === '`') { | ||
ch = stack.pop() | ||
} | ||
} else if (ch === '/') { | ||
end = skipRegex(code, idx) | ||
if (end > idx + 1) { | ||
str = code.slice(idx, end) | ||
} | ||
} | ||
if (ch === '`') { | ||
end = skipES6str(code, end, stack) | ||
str = code.slice(idx, end) | ||
if (stack.length) { | ||
re = re2 || (re2 = new RegExp(S_R_SRC2, 'g')) | ||
} else { | ||
re = re1 | ||
} | ||
} | ||
} else { | ||
str = match[0] | ||
if (str[0] === '/') { | ||
str = str[1] === '*' ? ' ' : '' | ||
code = code.slice(offset, idx) + str + code.slice(end) | ||
end = idx + str.length | ||
str = '' | ||
} else if (str.length === 2) { | ||
str = '' | ||
} | ||
} | ||
if (str) { | ||
result[0].push(code.slice(lastPos, idx)) | ||
result.push(str) | ||
lastPos = end | ||
} | ||
re.lastIndex = end | ||
} | ||
result[0].push(code.slice(lastPos)) | ||
return result | ||
} | ||
riot.parsers = parsers | ||
@@ -162,3 +277,3 @@ | ||
* Compiler for riot custom tags | ||
* @version v3.2.3 | ||
* @version v3.2.4 | ||
*/ | ||
@@ -351,6 +466,2 @@ var compile = (function () { | ||
var JS_ES6END = RegExp('[{}]|' + brackets.S_QBLOCKS, 'g') | ||
var JS_COMMS = RegExp(brackets.R_MLCOMMS.source + '|//[^\r\n]*|' + brackets.S_QBLOCK2, 'g') | ||
function riotjs (js) { | ||
@@ -367,3 +478,4 @@ var | ||
if (~js.indexOf('/')) js = rmComms(js, JS_COMMS) | ||
const src = jsSplitter(js) | ||
js = src.shift().join('<%>') | ||
@@ -374,3 +486,3 @@ while ((match = js.match(JS_ES6SIGN))) { | ||
js = RE.rightContext | ||
pos = skipBody(js, JS_ES6END) | ||
pos = skipBody(js) | ||
@@ -395,24 +507,21 @@ method = match[1] | ||
return parts.length ? parts.join('') + js : js | ||
if (parts.length) { | ||
js = parts.join('') + js | ||
} | ||
function rmComms (s, r, m) { | ||
r.lastIndex = 0 | ||
while ((m = r.exec(s))) { | ||
if (m[1]) { | ||
r.lastIndex = brackets.skipRegex(s, m.index) | ||
} else if (m[0][0] === '/') { | ||
s = s.slice(0, m.index) + ' ' + s.slice(r.lastIndex) | ||
r.lastIndex = m.index + 1 | ||
} | ||
} | ||
return s | ||
if (src.length) { | ||
js = js.replace(/<%>/g, function () { | ||
return src.shift() | ||
}) | ||
} | ||
function skipBody (s, r) { | ||
var m, i = 1 | ||
return js | ||
r.lastIndex = 0 | ||
while (i && (m = r.exec(s))) { | ||
if (m[0] === '{') ++i | ||
else if (m[0] === '}') --i | ||
function skipBody (s) { | ||
var r = /[{}]/g | ||
var i = 1 | ||
while (i && r.exec(s)) { | ||
if (s[r.lastIndex - 1] === '{') ++i | ||
else --i | ||
} | ||
@@ -750,3 +859,3 @@ return i ? s.length : r.lastIndex | ||
js: compileJS, | ||
version: 'v3.2.3' | ||
version: 'v3.2.4' | ||
} | ||
@@ -753,0 +862,0 @@ return compile |
@@ -9,3 +9,3 @@ 'use strict' | ||
var safeRegex = require('./safe-regex') | ||
var skipRegex = require('./skip-regex') | ||
var skipRegex = require('skip-regex') | ||
@@ -43,3 +43,3 @@ /** | ||
*/ | ||
var S_QBLOCK2 = R_STRINGS.source + '|' + /(\/)(?![*\/])/.source | ||
var S_QBLOCK2 = R_STRINGS.source + '|(/)(?![*/])' | ||
@@ -46,0 +46,0 @@ /** |
/** | ||
* The riot-compiler v3.2.3 | ||
* The riot-compiler v3.2.4 | ||
* | ||
* @module compiler | ||
* @version v3.2.3 | ||
* @version v3.2.4 | ||
* @license MIT | ||
@@ -14,2 +14,3 @@ * @copyright Muut Inc. + contributors | ||
var safeRegex = require('./safe-regex') | ||
var jsSplitter = require('./js-splitter') | ||
var path = require('path') | ||
@@ -344,19 +345,2 @@ | ||
/** | ||
* Regex for remotion of multiline and single-line JavaScript comments, merged with | ||
* {@link module:brackets.S_QBLOCKS|brackets.S_QBLOCKS} to skip literal string and regexes. | ||
* Used by the {@link module:compiler~riotjs|riotjs} parser. | ||
* | ||
* 2016-01-18: rewritten to not capture the brackets (reduces 9 steps) | ||
* @const {RegExp} | ||
*/ | ||
var JS_ES6END = RegExp('[{}]|' + brackets.S_QBLOCKS, 'g') | ||
/** | ||
* Regex for remotion of multiline and single-line JavaScript comments, merged with | ||
* {@link module:brackets.S_QBLOCKS|brackets.S_QBLOCKS} to skip literal string and regexes. | ||
* @const {RegExp} | ||
*/ | ||
var JS_COMMS = RegExp(brackets.R_MLCOMMS.source + '|//[^\r\n]*|' + brackets.S_QBLOCK2, 'g') | ||
/** | ||
* Default parser for JavaScript, supports ES6-like method syntax | ||
@@ -378,3 +362,4 @@ * | ||
if (~js.indexOf('/')) js = rmComms(js, JS_COMMS) | ||
const src = jsSplitter(js) | ||
js = src.shift().join('<%>') | ||
@@ -385,3 +370,3 @@ while ((match = js.match(JS_ES6SIGN))) { | ||
js = RE.rightContext | ||
pos = skipBody(js, JS_ES6END) | ||
pos = skipBody(js) | ||
@@ -406,24 +391,21 @@ method = match[1] | ||
return parts.length ? parts.join('') + js : js | ||
if (parts.length) { | ||
js = parts.join('') + js | ||
} | ||
function rmComms (s, r, m) { | ||
r.lastIndex = 0 | ||
while ((m = r.exec(s))) { | ||
if (m[1]) { | ||
r.lastIndex = brackets.skipRegex(s, m.index) | ||
} else if (m[0][0] === '/') { | ||
s = s.slice(0, m.index) + ' ' + s.slice(r.lastIndex) | ||
r.lastIndex = m.index + 1 | ||
} | ||
} | ||
return s | ||
if (src.length) { | ||
js = js.replace(/<%>/g, function () { | ||
return src.shift() | ||
}) | ||
} | ||
function skipBody (s, r) { | ||
var m, i = 1 | ||
return js | ||
r.lastIndex = 0 | ||
while (i && (m = r.exec(s))) { | ||
if (m[0] === '{') ++i | ||
else if (m[0] === '}') --i | ||
function skipBody (s) { | ||
var r = /[{}]/g | ||
var i = 1 | ||
while (i && r.exec(s)) { | ||
if (s[r.lastIndex - 1] === '{') ++i | ||
else --i | ||
} | ||
@@ -1018,3 +1000,3 @@ return i ? s.length : r.lastIndex | ||
parsers: parsers, | ||
version: 'v3.2.3' | ||
version: 'v3.2.4' | ||
} |
{ | ||
"name": "riot-compiler", | ||
"version": "3.2.3", | ||
"version": "3.2.4", | ||
"description": "Compiler for riot .tag files", | ||
"main": "lib/compiler.js", | ||
"module": "dist/es6.compiler.js", | ||
"jsnext:main": "dist/es6.compiler.js", | ||
@@ -22,3 +23,3 @@ "directories": { | ||
"install-css": "npm i stylus nib node-sass less postcss autoprefixer", | ||
"prepublish": "make build && ./node_modules/.bin/riot-bump && ./node_modules/.bin/riot-bump lib" | ||
"prepublish": "make build && riot-bump && riot-bump lib" | ||
}, | ||
@@ -56,3 +57,6 @@ "repository": { | ||
}, | ||
"homepage": "https://github.com/riot/compiler#readme" | ||
"homepage": "https://github.com/riot/compiler#readme", | ||
"dependencies": { | ||
"skip-regex": "^0.2.0" | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
133982
2933
1
+ Addedskip-regex@^0.2.0
+ Addedskip-regex@0.2.0(transitive)