diff --git a/lib/compile/scan.js b/lib/compile/scan.js index 7720390..25d5b3b 100644 --- a/lib/compile/scan.js +++ b/lib/compile/scan.js @@ -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) {... @@ -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 @@ -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; @@ -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). @@ -153,7 +167,7 @@ define([], function () { } else { - countParens(pStart, pEnd); + checkParens(pStart, pEnd); checkCommentsAndStrings(bcStart || lcStart, q); } } @@ -182,7 +196,7 @@ define([], function () { } else { - countParens(pStart, pEnd); + checkParens(pStart, pEnd); checkCommentsAndStrings(bcStart || lcStart, q); } } @@ -199,7 +213,7 @@ define([], function () { captureSignatureCount(matchPos, m.length); } else { - countParens(pStart, pEnd); + checkParens(pStart, pEnd); checkCommentsAndStrings(bcStart || lcStart, q); } } @@ -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 () { @@ -241,7 +255,7 @@ define([], function () { .split(splitArgsRx); } - function countParens (enter, exit) { + function checkParens (enter, exit) { if (enter) { pCount++; } @@ -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) + } + });