Narrow the scope of regexes used in build.js to the functions they relate to.

Former-commit-id: 6d838b24778d5e2107f4f5b25613ae40f363e969
This commit is contained in:
John-David Dalton
2012-11-20 16:08:41 -06:00
parent e2b8e530c9
commit 77bac4cf9e
2 changed files with 238 additions and 171 deletions

408
build.js
View File

@@ -476,7 +476,7 @@
return []; return [];
} }
// recursively accumulate the dependencies of the `methodName` function, and // recursively accumulate the dependencies of the `methodName` function, and
// the dependencies of its dependencies, and so on. // the dependencies of its dependencies, and so on
return _.uniq(dependencies.reduce(function(result, otherName) { return _.uniq(dependencies.reduce(function(result, otherName) {
result.push.apply(result, getDependencies(otherName).concat(otherName)); result.push.apply(result, getDependencies(otherName).concat(otherName));
return result; return result;
@@ -524,6 +524,17 @@
return (source.match(/(?:\s*\/\/.*)*\n( *)if *\(isFunction\(\/x\/[\s\S]+?};\n\1}/) || [''])[0]; return (source.match(/(?:\s*\/\/.*)*\n( *)if *\(isFunction\(\/x\/[\s\S]+?};\n\1}/) || [''])[0];
} }
/**
* Gets the `iteratorTemplate` from `source`.
*
* @private
* @param {String} source The source to inspect.
* @returns {String} Returns the `iteratorTemplate`.
*/
function getIteratorTemplate(source) {
return (source.match(/^( *)var iteratorTemplate *= *[\s\S]+?\n\1.+?;\n/m) || [''])[0];
}
/** /**
* Gets the names of methods in `source` belonging to the given `category`. * Gets the names of methods in `source` belonging to the given `category`.
* *
@@ -655,10 +666,8 @@
* @returns {String} Returns the source with the function removed. * @returns {String} Returns the source with the function removed.
*/ */
function removeFunction(source, funcName) { function removeFunction(source, funcName) {
var modified,
snippet = matchFunction(source, funcName);
// remove function // remove function
var snippet = matchFunction(source, funcName);
if (snippet) { if (snippet) {
source = source.replace(snippet, ''); source = source.replace(snippet, '');
} }
@@ -666,7 +675,7 @@
snippet = getMethodAssignments(source); snippet = getMethodAssignments(source);
// remove assignment and aliases // remove assignment and aliases
modified = getAliases(funcName).concat(funcName).reduce(function(result, otherName) { var modified = getAliases(funcName).concat(funcName).reduce(function(result, otherName) {
return result.replace(RegExp('(?:\\n *//.*\\s*)* *lodash\\.' + otherName + ' *= *.+\\n'), ''); return result.replace(RegExp('(?:\\n *//.*\\s*)* *lodash\\.' + otherName + ' *= *.+\\n'), '');
}, snippet); }, snippet);
@@ -706,11 +715,19 @@
* @returns {String} Returns the modified source. * @returns {String} Returns the modified source.
*/ */
function removeKeysOptimization(source) { function removeKeysOptimization(source) {
return removeVar(source, 'isKeysFast') source = removeVar(source, 'isKeysFast');
// remove optimized branch in `iteratorTemplate`
.replace(/(?: *\/\/.*\n)* *'( *)<% *if *\(isKeysFast[\s\S]+?'\1<% *} *else *\{ *%>.+\n([\s\S]+?) *'\1<% *} *%>.+/, "'\\n' +\n$2") // remove optimized branch in `iteratorTemplate`
// remove data object property assignment in `createIterator` source = source.replace(getIteratorTemplate(source), function(match) {
.replace(/ *'isKeysFast':.+\n/, ''); return match.replace(/(?: *\/\/.*\n)* *'( *)<% *if *\(isKeysFast[\s\S]+?'\1<% *} *else *\{ *%>.+\n([\s\S]+?) *'\1<% *} *%>.+/, "'\\n' +\n$2");
});
// remove data object property assignment in `createIterator`
source = source.replace(matchFunction(source, 'createIterator'), function(match) {
return match.replace(/ *'isKeysFast':.+\n/, '');
});
return source;
} }
/** /**
@@ -721,11 +738,21 @@
* @returns {String} Returns the modified source. * @returns {String} Returns the modified source.
*/ */
function removeNoArgsClass(source) { function removeNoArgsClass(source) {
return removeVar(source, 'noArgsClass') source = removeVar(source, 'noArgsClass');
// remove `noArgsClass` from `_.clone` and `_.isEqual`
.replace(/ *\|\| *\(noArgsClass *&&[^)]+?\)\)/g, '') // remove `noArgsClass` from `_.clone`, `_.isEmpty`, and `_.isEqual`
// remove `noArgsClass` from `_.isEqual` _.each(['clone', 'isEmpty', 'isEqual'], function(methodName) {
.replace(/if *\(noArgsClass[^}]+?}\n/, '\n'); source = source.replace(matchFunction(source, methodName), function(match) {
return match.replace(/ *\|\| *\(noArgsClass *&&[^)]+?\)\)/g, '');
});
});
// remove `noArgsClass` from `_.isEqual`
source = source.replace(matchFunction(source, 'isEqual'), function(match) {
return match.replace(/if *\(noArgsClass[^}]+?}\n/, '\n');
});
return source;
} }
/** /**
@@ -736,13 +763,20 @@
* @returns {String} Returns the modified source. * @returns {String} Returns the modified source.
*/ */
function removeNoNodeClass(source) { function removeNoNodeClass(source) {
return source // remove `noNodeClass` assignment
// remove `noNodeClass` assignment source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *try *\{(?:\s*\/\/.*)*\n *var noNodeClass[\s\S]+?catch[^}]+}\n/, '');
.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *try *\{(?:\s*\/\/.*)*\n *var noNodeClass[\s\S]+?catch[^}]+}\n/, '')
// remove `noNodeClass` from `isPlainObject` // remove `noNodeClass` from `_.isEqual`
.replace(/\(!noNodeClass *\|\|[\s\S]+?\)\) *&&/, '') source = source.replace(matchFunction(source, 'isEqual'), function(match) {
// remove `noNodeClass` from `_.isEqual` return match.replace(/ *\|\| *\(noNodeClass *&&[\s\S]+?\)\)\)/, '');
.replace(/ *\|\| *\(noNodeClass *&&[\s\S]+?\)\)\)/, ''); });
// remove `noNodeClass` from `_.isPlainObject`
source = source.replace(matchFunction(source, 'isPlainObject'), function(match) {
return match.replace(/\(!noNodeClass *\|\|[\s\S]+?\)\) *&&/, '');
});
return source;
} }
/** /**
@@ -784,8 +818,27 @@
} }
/** /**
* Searches `source` for a `varName` variable declaration and replaces its * Replaces the `funcName` function body in `source` with `funcValue`.
* assigned value with `varValue`. *
* @private
* @param {String} source The source to inspect.
* @param {String} varName The name of the function to replace.
* @returns {String} Returns the source with the function replaced.
*/
function replaceFunction(source, funcName, funcValue) {
var match = matchFunction(source, funcName);
if (match) {
// clip snippet after the JSDoc comment block
match = match.replace(/^\s*(?:\/\/.*|\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)\n/, '');
source = source.replace(match, function() {
return funcValue;
});
}
return source;
}
/**
* Replaces the `varName` variable declaration value in `source` with `varValue`.
* *
* @private * @private
* @param {String} source The source to inspect. * @param {String} source The source to inspect.
@@ -797,15 +850,21 @@
var result = source.replace(RegExp( var result = source.replace(RegExp(
'(( *)var ' + varName + ' *= *)' + '(( *)var ' + varName + ' *= *)' +
'(?:.+?;|(?:Function\\(.+?|.*?[^,])\\n[\\s\\S]+?\\n\\2.+?;)\\n' '(?:.+?;|(?:Function\\(.+?|.*?[^,])\\n[\\s\\S]+?\\n\\2.+?;)\\n'
), '$1' + varValue + ';\n'); ), function(match, captured) {
return captured + varValue + ';\n';
});
if (source == result) { if (source == result) {
// replace a varaible at the start or middle of a declaration list // replace a varaible at the start or middle of a declaration list
result = source.replace(RegExp('((?:var|\\n) +' + varName + ' *=).+?,'), '$1 ' + varValue + ','); result = source.replace(RegExp('((?:var|\\n) +' + varName + ' *=).+?,'), function(match, captured) {
return captured + ' ' + varValue + ',';
});
} }
if (source == result) { if (source == result) {
// replace a variable at the end of a variable declaration list // replace a variable at the end of a variable declaration list
result = source.replace(RegExp('(,\\s*' + varName + ' *=).+?;'), '$1 ' + varValue + ';'); result = source.replace(RegExp('(,\\s*' + varName + ' *=).+?;'), function(match, captured) {
return captured + ' ' + varValue + ';';
});
} }
return result; return result;
} }
@@ -823,8 +882,12 @@
if (value) { if (value) {
source = source.replace(/^[\s\S]*?function[^{]+{/, "$&\n 'use strict';"); source = source.replace(/^[\s\S]*?function[^{]+{/, "$&\n 'use strict';");
} }
// replace `useStrict` branch in `value` with hard-coded option // replace `useStrict` branch in `iteratorTemplate` with hard-coded option
return source.replace(/(?: *\/\/.*\n)*(\s*)' *<%.+?useStrict.+/, value ? "$1'\\'use strict\\';\\n' +" : ''); source = source.replace(getIteratorTemplate(source), function(match) {
return match.replace(/(?: *\/\/.*\n)*(\s*)' *<%.+?useStrict.+/, value ? "$1'\\'use strict\\';\\n' +" : '');
});
return source;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
@@ -855,6 +918,7 @@
'csp', 'csp',
'legacy', 'legacy',
'mobile', 'mobile',
'modularize',
'strict', 'strict',
'underscore', 'underscore',
'-c', '--stdout', '-c', '--stdout',
@@ -926,6 +990,9 @@
// flag used to specify a mobile build // flag used to specify a mobile build
var isMobile = !isLegacy && (isCSP || isUnderscore || options.indexOf('mobile') > -1); var isMobile = !isLegacy && (isCSP || isUnderscore || options.indexOf('mobile') > -1);
// flag used to specify a modularize build
var isModularize = options.indexOf('modularize') > -1;
// flag used to specify writing output to standard output // flag used to specify writing output to standard output
var isStdOut = options.indexOf('-c') > -1 || options.indexOf('--stdout') > -1; var isStdOut = options.indexOf('-c') > -1 || options.indexOf('--stdout') > -1;
@@ -1103,53 +1170,8 @@
source = removeFunction(source, 'cachedContains'); source = removeFunction(source, 'cachedContains');
source = removeVar(source, 'largeArraySize'); source = removeVar(source, 'largeArraySize');
// replace `_.clone`
if (useUnderscoreClone) {
source = source.replace(/^( *)function clone[\s\S]+?\n\1}/m, [
' function clone(value) {',
' return value && objectTypes[typeof value]',
' ? (isArray(value) ? slice.call(value) : assign({}, value))',
' : value',
' }'
].join('\n'));
}
// replace `_.contains`
source = source.replace(/^( *)function contains[\s\S]+?\n\1}/m, [
' function contains(collection, target) {',
' var length = collection ? collection.length : 0,',
' result = false;',
" if (typeof length == 'number') {",
' result = indexOf(collection, target) > -1;',
' } else {',
' forEach(collection, function(value) {',
' return (result = value === target) && indicatorObject;',
' });',
' }',
' return result;',
' }'
].join('\n'));
// replace `_.difference`
source = source.replace(/^( *)function difference[\s\S]+?\n\1}/m, [
' function difference(array) {',
' var index = -1,',
' length = array.length,',
' flattened = concat.apply(arrayRef, arguments),',
' result = [];',
'',
' while (++index < length) {',
' var value = array[index]',
' if (indexOf(flattened, value, length) < 0) {',
' result.push(value);',
' }',
' }',
' return result',
' }'
].join('\n'));
// replace `_.assign` // replace `_.assign`
source = source.replace(/^( *)var assign *= *createIterator[\s\S]+?\);/m, [ source = replaceFunction(source, 'assign', [
' function assign(object) {', ' function assign(object) {',
' if (!object) {', ' if (!object) {',
' return object;', ' return object;',
@@ -1167,7 +1189,7 @@
].join('\n')); ].join('\n'));
// replace `_.chain` // replace `_.chain`
source = source.replace(/^( *)function chain[\s\S]+?\n\1}/m, [ source = replaceFunction(source, 'chain', [
' function chain(value) {', ' function chain(value) {',
' value = new lodash(value);', ' value = new lodash(value);',
' value.__chain__ = true;', ' value.__chain__ = true;',
@@ -1175,8 +1197,35 @@
' }' ' }'
].join('\n')); ].join('\n'));
// replace `_.clone`
if (useUnderscoreClone) {
source = replaceFunction(source, 'clone', [
' function clone(value) {',
' return value && objectTypes[typeof value]',
' ? (isArray(value) ? slice.call(value) : assign({}, value))',
' : value',
' }'
].join('\n'));
}
// replace `_.contains`
source = replaceFunction(source, 'contains', [
' function contains(collection, target) {',
' var length = collection ? collection.length : 0,',
' result = false;',
" if (typeof length == 'number') {",
' result = indexOf(collection, target) > -1;',
' } else {',
' forEach(collection, function(value) {',
' return (result = value === target) && indicatorObject;',
' });',
' }',
' return result;',
' }'
].join('\n'));
// replace `_.defaults` // replace `_.defaults`
source = source.replace(/^( *)var defaults *= *createIterator[\s\S]+?\);/m, [ source = replaceFunction(source, 'defaults', [
' function defaults(object) {', ' function defaults(object) {',
' if (!object) {', ' if (!object) {',
' return object;', ' return object;',
@@ -1195,8 +1244,26 @@
' }' ' }'
].join('\n')); ].join('\n'));
// replace `_.difference`
source = replaceFunction(source, 'difference', [
' function difference(array) {',
' var index = -1,',
' length = array.length,',
' flattened = concat.apply(arrayRef, arguments),',
' result = [];',
'',
' while (++index < length) {',
' var value = array[index]',
' if (indexOf(flattened, value, length) < 0) {',
' result.push(value);',
' }',
' }',
' return result',
' }'
].join('\n'));
// replace `_.intersection` // replace `_.intersection`
source = source.replace(/^( *)function intersection[\s\S]+?\n\1}/m, [ source = replaceFunction(source, 'intersection', [
' function intersection(array) {', ' function intersection(array) {',
' var args = arguments,', ' var args = arguments,',
' argsLength = args.length,', ' argsLength = args.length,',
@@ -1218,7 +1285,7 @@
].join('\n')); ].join('\n'));
// replace `_.isEmpty` // replace `_.isEmpty`
source = source.replace(/^( *)function isEmpty[\s\S]+?\n\1}/m, [ source = replaceFunction(source, 'isEmpty', [
' function isEmpty(value) {', ' function isEmpty(value) {',
' if (!value) {', ' if (!value) {',
' return true;', ' return true;',
@@ -1236,14 +1303,14 @@
].join('\n')); ].join('\n'));
// replace `_.isFinite` // replace `_.isFinite`
source = source.replace(/^( *)function isFinite[\s\S]+?\n\1}/m, [ source = replaceFunction(source, 'isFinite', [
' function isFinite(value) {', ' function isFinite(value) {',
' return nativeIsFinite(value) && toString.call(value) == numberClass;', ' return nativeIsFinite(value) && toString.call(value) == numberClass;',
' }' ' }'
].join('\n')); ].join('\n'));
// replace `_.omit` // replace `_.omit`
source = source.replace(/^( *)function omit[\s\S]+?\n\1}/m, [ source = replaceFunction(source, 'omit', [
' function omit(object) {', ' function omit(object) {',
' var props = concat.apply(arrayRef, arguments),', ' var props = concat.apply(arrayRef, arguments),',
' result = {};', ' result = {};',
@@ -1258,7 +1325,7 @@
].join('\n')); ].join('\n'));
// replace `_.pick` // replace `_.pick`
source = source.replace(/^( *)function pick[\s\S]+?\n\1}/m, [ source = replaceFunction(source, 'pick', [
' function pick(object) {', ' function pick(object) {',
' var index = 0,', ' var index = 0,',
' props = concat.apply(arrayRef, arguments),', ' props = concat.apply(arrayRef, arguments),',
@@ -1276,60 +1343,58 @@
].join('\n')); ].join('\n'));
// replace `_.template` // replace `_.template`
source = source.replace(/^( *)function template[\s\S]+?\n\1}/m, function() { source = replaceFunction(source, 'template', [
return [ ' function template(text, data, options) {',
' function template(text, data, options) {', " text || (text = '');",
" text || (text = '');", ' options = defaults({}, options, lodash.templateSettings);',
' options = defaults({}, options, lodash.templateSettings);', '',
'', ' var index = 0,',
' var index = 0,', ' source = "__p += \'",',
' source = "__p += \'",', ' variable = options.variable;',
' variable = options.variable;', '',
'', ' var reDelimiters = RegExp(',
' var reDelimiters = RegExp(', " (options.escape || reNoMatch).source + '|' +",
" (options.escape || reNoMatch).source + '|' +", " (options.interpolate || reNoMatch).source + '|' +",
" (options.interpolate || reNoMatch).source + '|' +", " (options.evaluate || reNoMatch).source + '|$'",
" (options.evaluate || reNoMatch).source + '|$'", " , 'g');",
" , 'g');", '',
'', ' text.replace(reDelimiters, function(match, escapeValue, interpolateValue, evaluateValue, offset) {',
' text.replace(reDelimiters, function(match, escapeValue, interpolateValue, evaluateValue, offset) {', ' source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);',
' source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);', ' source +=',
' source +=', ' escapeValue ? "\' +\\n_.escape(" + escapeValue + ") +\\n\'" :',
' escapeValue ? "\' +\\n_.escape(" + escapeValue + ") +\\n\'" :', ' evaluateValue ? "\';\\n" + evaluateValue + ";\\n__p += \'" :',
' evaluateValue ? "\';\\n" + evaluateValue + ";\\n__p += \'" :', ' interpolateValue ? "\' +\\n((__t = (" + interpolateValue + ")) == null ? \'\' : __t) +\\n\'" : \'\';',
' interpolateValue ? "\' +\\n((__t = (" + interpolateValue + ")) == null ? \'\' : __t) +\\n\'" : \'\';', '',
'', ' index = offset + match.length;',
' index = offset + match.length;', ' });',
' });', '',
'', ' source += "\';\\n";',
' source += "\';\\n";', ' if (!variable) {',
' if (!variable) {', " variable = 'obj';",
" variable = 'obj';", " source = 'with (' + variable + ' || {}) {\\n' + source + '\\n}\\n';",
" source = 'with (' + variable + ' || {}) {\\n' + source + '\\n}\\n';", ' }',
' }', " source = 'function(' + variable + ') {\\n' +",
" source = 'function(' + variable + ') {\\n' +", " 'var __t, __p = \\'\\', __j = Array.prototype.join;\\n' +",
" 'var __t, __p = \\'\\', __j = Array.prototype.join;\\n' +", " 'function print() { __p += __j.call(arguments, \\'\\') }\\n' +",
" 'function print() { __p += __j.call(arguments, \\'\\') }\\n' +", ' source +',
' source +', " 'return __p\\n}';",
" 'return __p\\n}';", '',
'', ' try {',
' try {', " var result = Function('_', 'return ' + source)(lodash);",
" var result = Function('_', 'return ' + source)(lodash);", ' } catch(e) {',
' } catch(e) {', ' e.source = source;',
' e.source = source;', ' throw e;',
' throw e;', ' }',
' }', ' if (data) {',
' if (data) {', ' return result(data);',
' return result(data);', ' }',
' }', ' result.source = source;',
' result.source = source;', ' return result;',
' return result;', ' }'
' }' ].join('\n'));
].join('\n');
});
// replace `_.uniq` // replace `_.uniq`
source = source.replace(/^( *)function uniq[\s\S]+?\n\1}/m, [ source = replaceFunction(source, 'uniq', [
' function uniq(array, isSorted, callback, thisArg) {', ' function uniq(array, isSorted, callback, thisArg) {',
' var index = -1,', ' var index = -1,',
' length = array ? array.length : 0,', ' length = array ? array.length : 0,',
@@ -1359,7 +1424,7 @@
].join('\n')); ].join('\n'));
// replace `_.without` // replace `_.without`
source = source.replace(/^( *)function without[\s\S]+?\n\1}/m, [ source = replaceFunction(source, 'without', [
' function without(array) {', ' function without(array) {',
' var index = -1,', ' var index = -1,',
' length = array.length,', ' length = array.length,',
@@ -1376,7 +1441,7 @@
].join('\n')); ].join('\n'));
// replace `wrapperChain` // replace `wrapperChain`
source = source.replace(/^( *)function wrapperChain[\s\S]+?\n\1}/m, [ source = replaceFunction(source, 'wrapperChain', [
' function wrapperChain() {', ' function wrapperChain() {',
' this.__chain__ = true;', ' this.__chain__ = true;',
' return this;', ' return this;',
@@ -1404,14 +1469,20 @@
source = removeVar(source, 'reEmptyStringTrailing'); source = removeVar(source, 'reEmptyStringTrailing');
source = removeVar(source, 'reInsertVariable'); source = removeVar(source, 'reInsertVariable');
// remove `arguments` object check from `_.isEqual` source = source.replace(matchFunction(source, 'isEqual'), function(match) {
source = source.replace(/ *\|\| *className *== *argsClass/, ''); return match
// remove `arguments` object check from `_.isEqual`
// simplify DOM node check from `_.isEqual` .replace(/ *\|\| *className *== *argsClass/, '')
source = source.replace(/(if *\(className *!= *objectClass).+?noNodeClass[\s\S]+?{/, '$1) {'); // simplify DOM node check from `_.isEqual`
.replace(/(if *\(className *!= *objectClass).+?noNodeClass[\s\S]+?{/, '$1) {');
});
// remove conditional `charCodeCallback` use from `_.max` and `_.min` // remove conditional `charCodeCallback` use from `_.max` and `_.min`
source = source.replace(/!callback *&& *isString\(collection\)[\s\S]+?: */g, ''); _.each(['max', 'min'], function(methodName) {
source = source.replace(matchFunction(source, methodName), function(match) {
return match.replace(/!callback *&& *isString\(collection\)[\s\S]+?: */g, '');
});
});
// remove `lodash.prototype.toString` and `lodash.prototype.valueOf` assignments // remove `lodash.prototype.toString` and `lodash.prototype.valueOf` assignments
source = source.replace(/ *lodash\.prototype\.(?:toString|valueOf) *=.+\n/g, ''); source = source.replace(/ *lodash\.prototype\.(?:toString|valueOf) *=.+\n/g, '');
@@ -1435,12 +1506,16 @@
source = removeKeysOptimization(source); source = removeKeysOptimization(source);
// remove `prototype` [[Enumerable]] fix from `_.keys` // remove `prototype` [[Enumerable]] fix from `_.keys`
source = source.replace(/(?:\s*\/\/.*)*(\s*return *).+?propertyIsEnumerable[\s\S]+?: */, '$1'); source = source.replace(matchFunction(source, 'keys'), function(match) {
return match.replace(/(?:\s*\/\/.*)*(\s*return *).+?propertyIsEnumerable[\s\S]+?: */, '$1');
});
// remove `prototype` [[Enumerable]] fix from `iteratorTemplate` // remove `prototype` [[Enumerable]] fix from `iteratorTemplate`
source = source source = source.replace(getIteratorTemplate(source), function(match) {
.replace(/(?: *\/\/.*\n)* *' *(?:<% *)?if *\(!hasDontEnumBug *(?:&&|\))[\s\S]+?<% *} *(?:%>|').+/g, '') return match
.replace(/!hasDontEnumBug *\|\|/g, ''); .replace(/(?: *\/\/.*\n)* *' *(?:<% *)?if *\(!hasDontEnumBug *(?:&&|\))[\s\S]+?<% *} *(?:%>|').+/g, '')
.replace(/!hasDontEnumBug *\|\|/g, '');
});
} }
vm.runInContext(source, context); vm.runInContext(source, context);
return context._; return context._;
@@ -1481,19 +1556,14 @@
source = removeVar(source, varName); source = removeVar(source, varName);
}); });
_.each(['bind', 'isArray'], function(methodName) { // remove native `Function#bind` branch in `_.bind`
var snippet = matchFunction(source, methodName), source = source.replace(matchFunction(source, 'bind'), function(match) {
modified = snippet; return match.replace(/(?:\s*\/\/.*)*\s*return isBindFast[^:]+:\s*/, 'return ');
});
// remove native `Function#bind` branch in `_.bind` // remove native `Array.isArray` branch in `_.isArray`
if (methodName == 'bind') { source = source.replace(matchFunction(source, 'isArray'), function(match) {
modified = modified.replace(/(?:\s*\/\/.*)*\s*return isBindFast[^:]+:\s*/, 'return '); return match.replace(/nativeIsArray * \|\|/, '');
}
// remove native `Array.isArray` branch in `_.isArray`
else {
modified = modified.replace(/nativeIsArray * \|\|/, '');
}
source = source.replace(snippet, modified);
}); });
// replace `_.keys` with `shimKeys` // replace `_.keys` with `shimKeys`
@@ -1525,13 +1595,12 @@
// inline all functions defined with `createIterator` // inline all functions defined with `createIterator`
_.functions(lodash).forEach(function(methodName) { _.functions(lodash).forEach(function(methodName) {
var reFunc = RegExp('(\\bvar ' + methodName + ' *= *)createIterator\\(((?:{|[a-zA-Z])[\\s\\S]+?)\\);\\n'); var reFunc = RegExp('(\\bvar ' + methodName + ' *= *)createIterator\\(((?:{|[a-zA-Z])[\\s\\S]+?)\\);\\n');
if (reFunc.test(source)) {
// skip if not defined with `createIterator` // extract, format, and inject the compiled function's source code
if (!reFunc.test(source)) { source = source.replace(reFunc, function(match, captured) {
return; return captured + getFunctionSource(lodash[methodName]) + ';\n';
});
} }
// extract, format, and inject the compiled function's source code
source = source.replace(reFunc, '$1' + getFunctionSource(lodash[methodName]) + ';\n');
}); });
if (isUnderscore) { if (isUnderscore) {
@@ -1557,11 +1626,10 @@
// replace `isArguments` and its fallback // replace `isArguments` and its fallback
(function() { (function() {
var snippet = matchFunction(source, 'isArguments') var snippet = matchFunction(source, 'isArguments');
.replace(/function isArguments/, 'lodash.isArguments = function'); snippet = snippet.replace(/function isArguments/, 'lodash.isArguments = function');
source = removeFunction(source, 'isArguments'); source = removeFunction(source, 'isArguments');
source = source.replace(getIsArgumentsFallback(source), function(match) { source = source.replace(getIsArgumentsFallback(source), function(match) {
return snippet + '\n' + match return snippet + '\n' + match
.replace(/\bisArguments\b/g, 'lodash.$&') .replace(/\bisArguments\b/g, 'lodash.$&')
@@ -1647,7 +1715,7 @@
} }
else { else {
// inline `iteratorTemplate` template // inline `iteratorTemplate` template
source = source.replace(/(( *)var iteratorTemplate *= *)[\s\S]+?\n\2.+?;\n/, (function() { source = source.replace(getIteratorTemplate(source), function() {
var snippet = getFunctionSource(lodash._iteratorTemplate); var snippet = getFunctionSource(lodash._iteratorTemplate);
// prepend data object references to property names to avoid having to // prepend data object references to property names to avoid having to
@@ -1677,8 +1745,8 @@
// remove comments, including sourceURLs // remove comments, including sourceURLs
snippet = snippet.replace(/\s*\/\/.*(?:\n|$)/g, ''); snippet = snippet.replace(/\s*\/\/.*(?:\n|$)/g, '');
return '$1' + snippet + ';\n'; return ' var iteratorTemplate = ' + snippet + ';\n';
}())); });
} }
} }

View File

@@ -216,7 +216,6 @@
if (options.isTemplate) { if (options.isTemplate) {
return source; return source;
} }
// remove copyright/license header to add later in post-compile.js // remove copyright/license header to add later in post-compile.js
source = source.replace(/\/\*![\s\S]+?\*\//, ''); source = source.replace(/\/\*![\s\S]+?\*\//, '');