From 9625e54754d069c71f80a608f2263b0ec58bf68e Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 25 Aug 2015 17:06:22 +0200 Subject: [PATCH 1/3] experimental string tracking as well --- lib/cjs.js | 38 ++++++++++++++++++++++----------- test/test.js | 4 ++-- test/tests/commonjs-requires.js | 4 ++-- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/lib/cjs.js b/lib/cjs.js index 2a957efb..1bce8e0e 100644 --- a/lib/cjs.js +++ b/lib/cjs.js @@ -9,28 +9,40 @@ var cjsRequireRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF."'])require\s*\(\s*("[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*')\s*\)/g; var commentRegEx = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg; + var stringRegEx = /(?:"[^"\\\n\r]*(?:\\.[^"\\\n\r]*)*"|'[^'\\\n\r]*(?:\\.[^'\\\n\r]*)*')/g; + function getCJSDeps(source) { - cjsRequireRegEx.lastIndex = commentRegEx.lastIndex = 0; + cjsRequireRegEx.lastIndex = commentRegEx.lastIndex = stringRegEx.lastIndex = 0; var deps = []; - // track comments in the source var match; - - var commentLocations = []; + + // track string and comment locations for unminified source + var stringLocations = [], commentLocations = []; + + function inLocation(locations, match, starts) { + var inLocation = false; + for (var i = 0; i < locations.length; i++) + if (locations[i][0] < match.index && locations[i][1] > match.index + (!starts ? match[0].length : 0)) + return true; + return false; + } + if (source.length / source.split('\n').length < 200) { - while (match = commentRegEx.exec(source)) - commentLocations.push([match.index, match.index + match[0].length]); + while (match = stringRegEx.exec(source)) + stringLocations.push([match.index, match.index + match[0].length]); + + while (match = commentRegEx.exec(source)) { + // only track comments not starting in strings + if (!inLocation(stringLocations, match, true)) + commentLocations.push([match.index, match.index + match[0].length]); + } } while (match = cjsRequireRegEx.exec(source)) { - // ensure we're not in a comment location - var inComment = false; - for (var i = 0; i < commentLocations.length; i++) { - if (commentLocations[i][0] < match.index && commentLocations[i][1] > match.index + match[0].length) - inComment = true; - } - if (!inComment) + // ensure we're not within a string or comment location + if (!inLocation(stringLocations, match) && !inLocation(commentLocations, match)) deps.push(match[1].substr(1, match[1].length - 2)); } diff --git a/test/test.js b/test/test.js index 9e36e207..a47789f4 100644 --- a/test/test.js +++ b/test/test.js @@ -366,8 +366,8 @@ asyncTest('CommonJS require variations', function() { ok(m.d1 == 'd'); ok(m.d2 == 'd'); ok(m.d3 == "require('not a dep')"); - // ok(m.d4 == "text require('still not a dep') text"); - // ok(m.d5 == 'text \'quote\' require("yet still not a dep")'); + ok(m.d4 == "text require('still not a dep') text"); + ok(m.d5 == 'text \'quote\' require("yet still not a dep")'); start(); }, err); }); diff --git a/test/tests/commonjs-requires.js b/test/tests/commonjs-requires.js index a13e00d3..a14773ed 100644 --- a/test/tests/commonjs-requires.js +++ b/test/tests/commonjs-requires.js @@ -7,6 +7,6 @@ exports.d2 = (require exports.d3 = "require('not a dep')"; -// exports.d4 = "text require('still not a dep') text"; +exports.d4 = "text require('still not a dep') text"; -// exports.d5 = 'text \'quote\' require("yet still not a dep")'; +exports.d5 = 'text \'quote\' require("yet still not a dep")'; \ No newline at end of file From 86c1892c1a330191ea217835e3aab9f147af1072 Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 25 Aug 2015 17:32:42 +0200 Subject: [PATCH 2/3] comment in string test --- test/test.js | 3 ++- test/tests/commonjs-d2.js | 1 + test/tests/commonjs-requires.js | 10 ++++++++-- 3 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 test/tests/commonjs-d2.js diff --git a/test/test.js b/test/test.js index a47789f4..f5a61de0 100644 --- a/test/test.js +++ b/test/test.js @@ -366,8 +366,9 @@ asyncTest('CommonJS require variations', function() { ok(m.d1 == 'd'); ok(m.d2 == 'd'); ok(m.d3 == "require('not a dep')"); - ok(m.d4 == "text require('still not a dep') text"); + ok(m.d4 == "text/* require('still not a dep') text"); ok(m.d5 == 'text \'quote\' require("yet still not a dep")'); + ok(m.d6 == 'd6'); start(); }, err); }); diff --git a/test/tests/commonjs-d2.js b/test/tests/commonjs-d2.js new file mode 100644 index 00000000..3b340b2e --- /dev/null +++ b/test/tests/commonjs-d2.js @@ -0,0 +1 @@ +module.exports = 'd6'; \ No newline at end of file diff --git a/test/tests/commonjs-requires.js b/test/tests/commonjs-requires.js index a14773ed..0c7ec9c3 100644 --- a/test/tests/commonjs-requires.js +++ b/test/tests/commonjs-requires.js @@ -7,6 +7,12 @@ exports.d2 = (require exports.d3 = "require('not a dep')"; -exports.d4 = "text require('still not a dep') text"; +exports.d4 = "text/* require('still not a dep') text"; -exports.d5 = 'text \'quote\' require("yet still not a dep")'; \ No newline at end of file +exports.d5 = 'text \'quote\' require("yet still not a dep")'; + +var regexWithString = /asdfasdf " /; + +exports.d6 = require('./commonjs-d2.js'); + +var regexClose = /asdf " */; \ No newline at end of file From 2f58dbf9b9665e90ecaba1f8c0d47de203346db9 Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 25 Aug 2015 18:00:50 +0200 Subject: [PATCH 3/3] another esoteric case --- lib/cjs.js | 2 +- test/tests/commonjs-requires.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/cjs.js b/lib/cjs.js index 1bce8e0e..268b72ec 100644 --- a/lib/cjs.js +++ b/lib/cjs.js @@ -7,7 +7,7 @@ var cjsExportsRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF.]|module\.)exports\s*(\[['"]|\.)|(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF.])module\.exports\s*[=,]/; // RegEx adjusted from https://github.com/jbrantly/yabble/blob/master/lib/yabble.js#L339 var cjsRequireRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF."'])require\s*\(\s*("[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*')\s*\)/g; - var commentRegEx = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg; + var commentRegEx = /(^|[^\\])(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg; var stringRegEx = /(?:"[^"\\\n\r]*(?:\\.[^"\\\n\r]*)*"|'[^'\\\n\r]*(?:\\.[^'\\\n\r]*)*')/g; diff --git a/test/tests/commonjs-requires.js b/test/tests/commonjs-requires.js index 0c7ec9c3..1e6f622f 100644 --- a/test/tests/commonjs-requires.js +++ b/test/tests/commonjs-requires.js @@ -5,6 +5,8 @@ exports.d1 = require( exports.d2 = (require ("./commonjs-d.js")); +var regex = / \/* /; + exports.d3 = "require('not a dep')"; exports.d4 = "text/* require('still not a dep') text";