Skip to content

Commit

Permalink
Count parens found in regexp matches (parens could be just before reg…
Browse files Browse the repository at this point in the history
…exp due to how we tell difference between division symbol and regexp literals). Fixes #38.
  • Loading branch information
unscriptable committed Mar 14, 2014
1 parent 54c7551 commit b26c964
Showing 1 changed file with 43 additions and 20 deletions.
63 changes: 43 additions & 20 deletions lib/compile/scan.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,30 @@ define([], function () {

/*
* This function should work for most AMD and UMD formats.
* things we need to know about the module:
* It won't work for UMD that has a dependency list, yet references
* the dependency list or the factory as variables. These need to be
* literals. For instance, the following will not work:
* var deps = ['foo', 'bar'];
* var factory = function (foo, bar) {};
* define(deps, factory);
*
* The following will work, of course:
* define(['foo', 'bar'], function (foo, bar) {});
*
* Comments and line feeds amongst the define() args are handled.
*
* Things we need to know about the module:
* - where to insert (or replace) module id
* - what are the dependencies
* - r-value requires should be moved to dep list and
* variable name assigned. then, substitute require('...') with variable
* variable name assigned. then, substitute require('...')
* with variable
*/

var findDefinesRx, removeCommentsRx, cleanDepsRx, splitArgsRx;
var findDefinesRx, removeCommentsRx, cleanDepsRx, splitArgsRx,
countParensRx;

// find all of these signatures (plus some more variants):
// Find all of these signatures (plus some more variants):
// define("id", ["dep1", "dep2"], function (dep1, dep2) {...
// define("id", function (require) {...
// define("id", function factoryName (require) {...
Expand All @@ -40,7 +54,7 @@ define([], function () {
// filter out some false positives that we can't eliminate in the
// rest of the regexps since we may grab too many chars if we do.
// these are not captured.
'[.$_]require\\s*\\(|[.$_]define\\s*\\('
'[.$_]require|[.$_]define'
// also find "require('id')" (r-val)
+ '|\\brequire\\s*\\(\\s*["\']([^"\']+)["\']\\s*\\)'
// find "define ( 'id'? , [deps]? ," capturing id and deps
Expand Down Expand Up @@ -70,6 +84,7 @@ define([], function () {
removeCommentsRx = /\/\*[\s\S]*?\*\/|\/\/.*?[\n\r]/g;
cleanDepsRx = /\s*["']\s*/g;
splitArgsRx = /\s*,\s*/;
countParensRx = /\(|\)/;

function scan (source) {
var modules, module, pCount;
Expand Down Expand Up @@ -109,18 +124,17 @@ define([], function () {
function amdParser (m, rval, def, id1, id2, deps, factory, args, fStart, bcStart, bcEnd, lcStart, lcEnd, rx, escQ, q, pStart, pEnd, matchPos, source) {
var id = id1 || id2;

// optimization: just ignore escaped quotes and regexps
if (escQ || rx) return '';
// optimization: skip over escaped quotes
if (escQ) return '';

// optimization: fStart matches "{" (a lot!), so fail early when not inDefine
if (!inDefine && fStart) return '';
// optimization: skip over regexps, but count parens
if (rx) {
pCount += countParensInString(m);
return '';
}

// fix false detection of require(), such as `goog.require()` or
// `$require()`. we can't detect this in the regexp since it
// will then grab too many characters.
// if (rval && source[matchPos - 1]) {
// rval = null;
// }
// optimization: fStart matches "{" (a lot!), so quit early when not inDefine
if (!inDefine && fStart) return '';

// optimization: inComment and inString are treated as a separate set of
// states from the primary states (inDefine, inFactory).
Expand Down Expand Up @@ -153,7 +167,7 @@ define([], function () {
}

else {
countParens(pStart, pEnd);
checkParens(pStart, pEnd);
checkCommentsAndStrings(bcStart || lcStart, q);
}
}
Expand Down Expand Up @@ -182,7 +196,7 @@ define([], function () {
}

else {
countParens(pStart, pEnd);
checkParens(pStart, pEnd);
checkCommentsAndStrings(bcStart || lcStart, q);
}
}
Expand All @@ -199,7 +213,7 @@ define([], function () {
captureSignatureCount(matchPos, m.length);
}
else {
countParens(pStart, pEnd);
checkParens(pStart, pEnd);
checkCommentsAndStrings(bcStart || lcStart, q);
}
}
Expand All @@ -215,7 +229,7 @@ define([], function () {
modules.push(module);
inFactory = false;
inDefine = true;
pCount = 1;
pCount = 1; // reset to easily find the end
}

function toFactory () {
Expand All @@ -241,7 +255,7 @@ define([], function () {
.split(splitArgsRx);
}

function countParens (enter, exit) {
function checkParens (enter, exit) {
if (enter) {
pCount++;
}
Expand All @@ -265,4 +279,13 @@ define([], function () {

return scan;

function countParensInString (str) {
var matches = str.match(countParensRx);
return matches ? matches.reduce(reduceParens, 0) : 0;
}

function reduceParens (count, p) {
return count + (p === '(' ? 1 : -1)
}

});

0 comments on commit b26c964

Please sign in to comment.