requirejs-rails 0.7.2 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +1 -1
- data/bin/r.js +2815 -80
- data/lib/requirejs/rails/version.rb +1 -1
- data/vendor/assets/javascripts/require.js +19 -9
- metadata +9 -9
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/bin/r.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license r.js 1.0.
|
2
|
+
* @license r.js 1.0.8 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
|
3
3
|
* Available via the MIT or new BSD license.
|
4
4
|
* see: http://github.com/jrburke/requirejs for details
|
5
5
|
*/
|
@@ -11,16 +11,16 @@
|
|
11
11
|
* the shell of the r.js file.
|
12
12
|
*/
|
13
13
|
|
14
|
-
/*jslint
|
14
|
+
/*jslint evil: true, nomen: true */
|
15
15
|
/*global readFile: true, process: false, Packages: false, print: false,
|
16
|
-
console: false, java: false, module: false */
|
16
|
+
console: false, java: false, module: false, requirejsVars */
|
17
17
|
|
18
18
|
var requirejs, require, define;
|
19
19
|
(function (console, args, readFileFunc) {
|
20
20
|
|
21
21
|
var fileName, env, fs, vm, path, exec, rhinoContext, dir, nodeRequire,
|
22
22
|
nodeDefine, exists, reqMain, loadedOptimizedLib,
|
23
|
-
version = '1.0.
|
23
|
+
version = '1.0.8',
|
24
24
|
jsSuffixRegExp = /\.js$/,
|
25
25
|
commandOption = '',
|
26
26
|
useLibLoaded = {},
|
@@ -102,7 +102,7 @@ var requirejs, require, define;
|
|
102
102
|
}
|
103
103
|
|
104
104
|
/** vim: et:ts=4:sw=4:sts=4
|
105
|
-
* @license RequireJS 1.0.
|
105
|
+
* @license RequireJS 1.0.8 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
|
106
106
|
* Available via the MIT or new BSD license.
|
107
107
|
* see: http://github.com/jrburke/requirejs for details
|
108
108
|
*/
|
@@ -110,9 +110,9 @@ var requirejs, require, define;
|
|
110
110
|
/*global window, navigator, document, importScripts, jQuery, setTimeout, opera */
|
111
111
|
|
112
112
|
|
113
|
-
(function () {
|
113
|
+
(function (undefined) {
|
114
114
|
//Change this version number for each release.
|
115
|
-
var version = "1.0.
|
115
|
+
var version = "1.0.8",
|
116
116
|
commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
|
117
117
|
cjsRequireRegExp = /require\(\s*["']([^'"\s]+)["']\s*\)/g,
|
118
118
|
currDirRegExp = /^\.\//,
|
@@ -526,18 +526,19 @@ var requirejs, require, define;
|
|
526
526
|
fullName = map.fullName,
|
527
527
|
args = manager.deps,
|
528
528
|
listeners = manager.listeners,
|
529
|
+
execCb = config.requireExecCb || req.execCb,
|
529
530
|
cjsModule;
|
530
531
|
|
531
532
|
//Call the callback to define the module, if necessary.
|
532
533
|
if (cb && isFunction(cb)) {
|
533
534
|
if (config.catchError.define) {
|
534
535
|
try {
|
535
|
-
ret =
|
536
|
+
ret = execCb(fullName, manager.callback, args, defined[fullName]);
|
536
537
|
} catch (e) {
|
537
538
|
err = e;
|
538
539
|
}
|
539
540
|
} else {
|
540
|
-
ret =
|
541
|
+
ret = execCb(fullName, manager.callback, args, defined[fullName]);
|
541
542
|
}
|
542
543
|
|
543
544
|
if (fullName) {
|
@@ -1277,7 +1278,7 @@ var requirejs, require, define;
|
|
1277
1278
|
} else {
|
1278
1279
|
//Regular dependency.
|
1279
1280
|
if (!urlFetched[url] && !loaded[fullName]) {
|
1280
|
-
req.load(context, fullName, url);
|
1281
|
+
(config.requireLoad || req.load)(context, fullName, url);
|
1281
1282
|
|
1282
1283
|
//Mark the URL as fetched, but only if it is
|
1283
1284
|
//not an empty: URL, used by the optimizer.
|
@@ -1581,7 +1582,8 @@ var requirejs, require, define;
|
|
1581
1582
|
moduleName = normalize(moduleName, relModuleMap && relModuleMap.fullName);
|
1582
1583
|
|
1583
1584
|
//If a colon is in the URL, it indicates a protocol is used and it is just
|
1584
|
-
//an URL to a file, or if it starts with a slash
|
1585
|
+
//an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?)
|
1586
|
+
//or ends with .js, then assume the user meant to use an url and not a module id.
|
1585
1587
|
//The slash is important for protocol-less URLs as well as full paths.
|
1586
1588
|
if (req.jsExtRegExp.test(moduleName)) {
|
1587
1589
|
//Just a plain path, not module name lookup, so just return it.
|
@@ -1617,7 +1619,7 @@ var requirejs, require, define;
|
|
1617
1619
|
|
1618
1620
|
//Join the path parts together, then figure out if baseUrl is needed.
|
1619
1621
|
url = syms.join("/") + (ext || ".js");
|
1620
|
-
url = (url.charAt(0) === '/' || url.match(
|
1622
|
+
url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? "" : config.baseUrl) + url;
|
1621
1623
|
}
|
1622
1624
|
|
1623
1625
|
return config.urlArgs ? url +
|
@@ -1981,7 +1983,15 @@ var requirejs, require, define;
|
|
1981
1983
|
//https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution
|
1982
1984
|
//UNFORTUNATELY Opera implements attachEvent but does not follow the script
|
1983
1985
|
//script execution mode.
|
1984
|
-
if (node.attachEvent &&
|
1986
|
+
if (node.attachEvent &&
|
1987
|
+
// check if node.attachEvent is artificially added by custom script or
|
1988
|
+
// natively supported by browser
|
1989
|
+
// read https://github.com/jrburke/requirejs/issues/187
|
1990
|
+
// if we can NOT find [native code] then it must NOT natively supported.
|
1991
|
+
// in IE8, node.attachEvent does not have toString()
|
1992
|
+
// TODO: a better way to check interactive mode
|
1993
|
+
!(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code]') < 0) &&
|
1994
|
+
!isOpera) {
|
1985
1995
|
//Probably IE. IE (at least 6-8) do not fire
|
1986
1996
|
//script onload right after executing the script, so
|
1987
1997
|
//we cannot tie the anonymous define call to a name.
|
@@ -2247,7 +2257,7 @@ var requirejs, require, define;
|
|
2247
2257
|
'\n}(requirejsVars.require, requirejsVars.requirejs, requirejsVars.define));';
|
2248
2258
|
};
|
2249
2259
|
|
2250
|
-
req.load = function (context, moduleName, url) {
|
2260
|
+
requirejsVars.nodeLoad = req.load = function (context, moduleName, url) {
|
2251
2261
|
var contents, err;
|
2252
2262
|
|
2253
2263
|
//Indicate a the module is in process of loading.
|
@@ -2293,6 +2303,9 @@ var requirejs, require, define;
|
|
2293
2303
|
text = req.makeNodeWrapper(text);
|
2294
2304
|
return eval(text);
|
2295
2305
|
};
|
2306
|
+
|
2307
|
+
//Hold on to the original execCb to use in useLib calls.
|
2308
|
+
requirejsVars.nodeRequireExecCb = require.execCb;
|
2296
2309
|
}());
|
2297
2310
|
|
2298
2311
|
}
|
@@ -2356,6 +2369,40 @@ var requirejs, require, define;
|
|
2356
2369
|
}
|
2357
2370
|
});
|
2358
2371
|
}());
|
2372
|
+
if(env === 'node') {
|
2373
|
+
/**
|
2374
|
+
* @license RequireJS Copyright (c) 2012, The Dojo Foundation All Rights Reserved.
|
2375
|
+
* Available via the MIT or new BSD license.
|
2376
|
+
* see: http://github.com/jrburke/requirejs for details
|
2377
|
+
*/
|
2378
|
+
|
2379
|
+
/*jslint strict: false */
|
2380
|
+
/*global define: false, load: false */
|
2381
|
+
|
2382
|
+
//Needed so that rhino/assert can return a stub for uglify's consolidator.js
|
2383
|
+
define('node/assert', ['assert'], function (assert) {
|
2384
|
+
return assert;
|
2385
|
+
});
|
2386
|
+
|
2387
|
+
}
|
2388
|
+
|
2389
|
+
if(env === 'rhino') {
|
2390
|
+
/**
|
2391
|
+
* @license RequireJS Copyright (c) 2012, The Dojo Foundation All Rights Reserved.
|
2392
|
+
* Available via the MIT or new BSD license.
|
2393
|
+
* see: http://github.com/jrburke/requirejs for details
|
2394
|
+
*/
|
2395
|
+
|
2396
|
+
/*jslint strict: false */
|
2397
|
+
/*global define: false, load: false */
|
2398
|
+
|
2399
|
+
//Just a stub for use with uglify's consolidator.js
|
2400
|
+
define('rhino/assert', function () {
|
2401
|
+
return {};
|
2402
|
+
});
|
2403
|
+
|
2404
|
+
}
|
2405
|
+
|
2359
2406
|
if(env === 'node') {
|
2360
2407
|
/**
|
2361
2408
|
* @license Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
|
@@ -3149,7 +3196,2610 @@ define('logger', ['env!env/print'], function (print) {
|
|
3149
3196
|
//so that the build does not attempt to inline some env modules,
|
3150
3197
|
//like Node's fs and path.
|
3151
3198
|
|
3152
|
-
define('uglifyjs/
|
3199
|
+
define('uglifyjs/consolidator', ["require", "exports", "module", "env!env/assert", "./parse-js", "./process"], function(require, exports, module, assert) {
|
3200
|
+
|
3201
|
+
/**
|
3202
|
+
* @preserve Copyright 2012 Robert Gust-Bardon <http://robert.gust-bardon.org/>.
|
3203
|
+
* All rights reserved.
|
3204
|
+
*
|
3205
|
+
* Redistribution and use in source and binary forms, with or without
|
3206
|
+
* modification, are permitted provided that the following conditions
|
3207
|
+
* are met:
|
3208
|
+
*
|
3209
|
+
* * Redistributions of source code must retain the above
|
3210
|
+
* copyright notice, this list of conditions and the following
|
3211
|
+
* disclaimer.
|
3212
|
+
*
|
3213
|
+
* * Redistributions in binary form must reproduce the above
|
3214
|
+
* copyright notice, this list of conditions and the following
|
3215
|
+
* disclaimer in the documentation and/or other materials
|
3216
|
+
* provided with the distribution.
|
3217
|
+
*
|
3218
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
|
3219
|
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
3220
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
3221
|
+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
3222
|
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
3223
|
+
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
3224
|
+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
3225
|
+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
3226
|
+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
3227
|
+
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
3228
|
+
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
3229
|
+
* SUCH DAMAGE.
|
3230
|
+
*/
|
3231
|
+
|
3232
|
+
/**
|
3233
|
+
* @fileoverview Enhances <a href="https://github.com/mishoo/UglifyJS/"
|
3234
|
+
* >UglifyJS</a> with consolidation of null, Boolean, and String values.
|
3235
|
+
* <p>Also known as aliasing, this feature has been deprecated in <a href=
|
3236
|
+
* "http://closure-compiler.googlecode.com/">the Closure Compiler</a> since its
|
3237
|
+
* initial release, where it is unavailable from the <abbr title=
|
3238
|
+
* "command line interface">CLI</a>. The Closure Compiler allows one to log and
|
3239
|
+
* influence this process. In contrast, this implementation does not introduce
|
3240
|
+
* any variable declarations in global code and derives String values from
|
3241
|
+
* identifier names used as property accessors.</p>
|
3242
|
+
* <p>Consolidating literals may worsen the data compression ratio when an <a
|
3243
|
+
* href="http://tools.ietf.org/html/rfc2616#section-3.5">encoding
|
3244
|
+
* transformation</a> is applied. For instance, <a href=
|
3245
|
+
* "http://code.jquery.com/jquery-1.7.1.js">jQuery 1.7.1</a> takes 248235 bytes.
|
3246
|
+
* Building it with <a href="https://github.com/mishoo/UglifyJS/tarball/v1.2.5">
|
3247
|
+
* UglifyJS v1.2.5</a> results in 93647 bytes (37.73% of the original) which are
|
3248
|
+
* then compressed to 33154 bytes (13.36% of the original) using <a href=
|
3249
|
+
* "http://linux.die.net/man/1/gzip">gzip(1)</a>. Building it with the same
|
3250
|
+
* version of UglifyJS 1.2.5 patched with the implementation of consolidation
|
3251
|
+
* results in 80784 bytes (a decrease of 12863 bytes, i.e. 13.74%, in comparison
|
3252
|
+
* to the aforementioned 93647 bytes) which are then compressed to 34013 bytes
|
3253
|
+
* (an increase of 859 bytes, i.e. 2.59%, in comparison to the aforementioned
|
3254
|
+
* 33154 bytes).</p>
|
3255
|
+
* <p>Written in <a href="http://es5.github.com/#x4.2.2">the strict variant</a>
|
3256
|
+
* of <a href="http://es5.github.com/">ECMA-262 5.1 Edition</a>. Encoded in <a
|
3257
|
+
* href="http://tools.ietf.org/html/rfc3629">UTF-8</a>. Follows <a href=
|
3258
|
+
* "http://google-styleguide.googlecode.com/svn-history/r76/trunk/javascriptguide.xml"
|
3259
|
+
* >Revision 2.28 of the Google JavaScript Style Guide</a> (except for the
|
3260
|
+
* discouraged use of the {@code function} tag and the {@code namespace} tag).
|
3261
|
+
* 100% typed for the <a href=
|
3262
|
+
* "http://closure-compiler.googlecode.com/files/compiler-20120123.tar.gz"
|
3263
|
+
* >Closure Compiler Version 1741</a>.</p>
|
3264
|
+
* <p>Should you find this software useful, please consider <a href=
|
3265
|
+
* "https://paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=JZLW72X8FD4WG"
|
3266
|
+
* >a donation</a>.</p>
|
3267
|
+
* @author follow.me@RGustBardon (Robert Gust-Bardon)
|
3268
|
+
* @supported Tested with:
|
3269
|
+
* <ul>
|
3270
|
+
* <li><a href="http://nodejs.org/dist/v0.6.10/">Node v0.6.10</a>,</li>
|
3271
|
+
* <li><a href="https://github.com/mishoo/UglifyJS/tarball/v1.2.5">UglifyJS
|
3272
|
+
* v1.2.5</a>.</li>
|
3273
|
+
* </ul>
|
3274
|
+
*/
|
3275
|
+
|
3276
|
+
/*global console:false, exports:true, module:false, require:false */
|
3277
|
+
/*jshint sub:true */
|
3278
|
+
/**
|
3279
|
+
* Consolidates null, Boolean, and String values found inside an <abbr title=
|
3280
|
+
* "abstract syntax tree">AST</abbr>.
|
3281
|
+
* @param {!TSyntacticCodeUnit} oAbstractSyntaxTree An array-like object
|
3282
|
+
* representing an <abbr title="abstract syntax tree">AST</abbr>.
|
3283
|
+
* @return {!TSyntacticCodeUnit} An array-like object representing an <abbr
|
3284
|
+
* title="abstract syntax tree">AST</abbr> with its null, Boolean, and
|
3285
|
+
* String values consolidated.
|
3286
|
+
*/
|
3287
|
+
// TODO(user) Consolidation of mathematical values found in numeric literals.
|
3288
|
+
// TODO(user) Unconsolidation.
|
3289
|
+
// TODO(user) Consolidation of ECMA-262 6th Edition programs.
|
3290
|
+
// TODO(user) Rewrite in ECMA-262 6th Edition.
|
3291
|
+
exports['ast_consolidate'] = function(oAbstractSyntaxTree) {
|
3292
|
+
'use strict';
|
3293
|
+
/*jshint bitwise:true, curly:true, eqeqeq:true, forin:true, immed:true,
|
3294
|
+
latedef:true, newcap:true, noarge:true, noempty:true, nonew:true,
|
3295
|
+
onevar:true, plusplus:true, regexp:true, undef:true, strict:true,
|
3296
|
+
sub:false, trailing:true */
|
3297
|
+
|
3298
|
+
var _,
|
3299
|
+
/**
|
3300
|
+
* A record consisting of data about one or more source elements.
|
3301
|
+
* @constructor
|
3302
|
+
* @nosideeffects
|
3303
|
+
*/
|
3304
|
+
TSourceElementsData = function() {
|
3305
|
+
/**
|
3306
|
+
* The category of the elements.
|
3307
|
+
* @type {number}
|
3308
|
+
* @see ESourceElementCategories
|
3309
|
+
*/
|
3310
|
+
this.nCategory = ESourceElementCategories.N_OTHER;
|
3311
|
+
/**
|
3312
|
+
* The number of occurrences (within the elements) of each primitive
|
3313
|
+
* value that could be consolidated.
|
3314
|
+
* @type {!Array.<!Object.<string, number>>}
|
3315
|
+
*/
|
3316
|
+
this.aCount = [];
|
3317
|
+
this.aCount[EPrimaryExpressionCategories.N_IDENTIFIER_NAMES] = {};
|
3318
|
+
this.aCount[EPrimaryExpressionCategories.N_STRING_LITERALS] = {};
|
3319
|
+
this.aCount[EPrimaryExpressionCategories.N_NULL_AND_BOOLEAN_LITERALS] =
|
3320
|
+
{};
|
3321
|
+
/**
|
3322
|
+
* Identifier names found within the elements.
|
3323
|
+
* @type {!Array.<string>}
|
3324
|
+
*/
|
3325
|
+
this.aIdentifiers = [];
|
3326
|
+
/**
|
3327
|
+
* Prefixed representation Strings of each primitive value that could be
|
3328
|
+
* consolidated within the elements.
|
3329
|
+
* @type {!Array.<string>}
|
3330
|
+
*/
|
3331
|
+
this.aPrimitiveValues = [];
|
3332
|
+
},
|
3333
|
+
/**
|
3334
|
+
* A record consisting of data about a primitive value that could be
|
3335
|
+
* consolidated.
|
3336
|
+
* @constructor
|
3337
|
+
* @nosideeffects
|
3338
|
+
*/
|
3339
|
+
TPrimitiveValue = function() {
|
3340
|
+
/**
|
3341
|
+
* The difference in the number of terminal symbols between the original
|
3342
|
+
* source text and the one with the primitive value consolidated. If the
|
3343
|
+
* difference is positive, the primitive value is considered worthwhile.
|
3344
|
+
* @type {number}
|
3345
|
+
*/
|
3346
|
+
this.nSaving = 0;
|
3347
|
+
/**
|
3348
|
+
* An identifier name of the variable that will be declared and assigned
|
3349
|
+
* the primitive value if the primitive value is consolidated.
|
3350
|
+
* @type {string}
|
3351
|
+
*/
|
3352
|
+
this.sName = '';
|
3353
|
+
},
|
3354
|
+
/**
|
3355
|
+
* A record consisting of data on what to consolidate within the range of
|
3356
|
+
* source elements that is currently being considered.
|
3357
|
+
* @constructor
|
3358
|
+
* @nosideeffects
|
3359
|
+
*/
|
3360
|
+
TSolution = function() {
|
3361
|
+
/**
|
3362
|
+
* An object whose keys are prefixed representation Strings of each
|
3363
|
+
* primitive value that could be consolidated within the elements and
|
3364
|
+
* whose values are corresponding data about those primitive values.
|
3365
|
+
* @type {!Object.<string, {nSaving: number, sName: string}>}
|
3366
|
+
* @see TPrimitiveValue
|
3367
|
+
*/
|
3368
|
+
this.oPrimitiveValues = {};
|
3369
|
+
/**
|
3370
|
+
* The difference in the number of terminal symbols between the original
|
3371
|
+
* source text and the one with all the worthwhile primitive values
|
3372
|
+
* consolidated.
|
3373
|
+
* @type {number}
|
3374
|
+
* @see TPrimitiveValue#nSaving
|
3375
|
+
*/
|
3376
|
+
this.nSavings = 0;
|
3377
|
+
},
|
3378
|
+
/**
|
3379
|
+
* The processor of <abbr title="abstract syntax tree">AST</abbr>s found
|
3380
|
+
* in UglifyJS.
|
3381
|
+
* @namespace
|
3382
|
+
* @type {!TProcessor}
|
3383
|
+
*/
|
3384
|
+
oProcessor = (/** @type {!TProcessor} */ require('./process')),
|
3385
|
+
/**
|
3386
|
+
* A record consisting of a number of constants that represent the
|
3387
|
+
* difference in the number of terminal symbols between a source text with
|
3388
|
+
* a modified syntactic code unit and the original one.
|
3389
|
+
* @namespace
|
3390
|
+
* @type {!Object.<string, number>}
|
3391
|
+
*/
|
3392
|
+
oWeights = {
|
3393
|
+
/**
|
3394
|
+
* The difference in the number of punctuators required by the bracket
|
3395
|
+
* notation and the dot notation.
|
3396
|
+
* <p><code>'[]'.length - '.'.length</code></p>
|
3397
|
+
* @const
|
3398
|
+
* @type {number}
|
3399
|
+
*/
|
3400
|
+
N_PROPERTY_ACCESSOR: 1,
|
3401
|
+
/**
|
3402
|
+
* The number of punctuators required by a variable declaration with an
|
3403
|
+
* initialiser.
|
3404
|
+
* <p><code>':'.length + ';'.length</code></p>
|
3405
|
+
* @const
|
3406
|
+
* @type {number}
|
3407
|
+
*/
|
3408
|
+
N_VARIABLE_DECLARATION: 2,
|
3409
|
+
/**
|
3410
|
+
* The number of terminal symbols required to introduce a variable
|
3411
|
+
* statement (excluding its variable declaration list).
|
3412
|
+
* <p><code>'var '.length</code></p>
|
3413
|
+
* @const
|
3414
|
+
* @type {number}
|
3415
|
+
*/
|
3416
|
+
N_VARIABLE_STATEMENT_AFFIXATION: 4,
|
3417
|
+
/**
|
3418
|
+
* The number of terminal symbols needed to enclose source elements
|
3419
|
+
* within a function call with no argument values to a function with an
|
3420
|
+
* empty parameter list.
|
3421
|
+
* <p><code>'(function(){}());'.length</code></p>
|
3422
|
+
* @const
|
3423
|
+
* @type {number}
|
3424
|
+
*/
|
3425
|
+
N_CLOSURE: 17
|
3426
|
+
},
|
3427
|
+
/**
|
3428
|
+
* Categories of primary expressions from which primitive values that
|
3429
|
+
* could be consolidated are derivable.
|
3430
|
+
* @namespace
|
3431
|
+
* @enum {number}
|
3432
|
+
*/
|
3433
|
+
EPrimaryExpressionCategories = {
|
3434
|
+
/**
|
3435
|
+
* Identifier names used as property accessors.
|
3436
|
+
* @type {number}
|
3437
|
+
*/
|
3438
|
+
N_IDENTIFIER_NAMES: 0,
|
3439
|
+
/**
|
3440
|
+
* String literals.
|
3441
|
+
* @type {number}
|
3442
|
+
*/
|
3443
|
+
N_STRING_LITERALS: 1,
|
3444
|
+
/**
|
3445
|
+
* Null and Boolean literals.
|
3446
|
+
* @type {number}
|
3447
|
+
*/
|
3448
|
+
N_NULL_AND_BOOLEAN_LITERALS: 2
|
3449
|
+
},
|
3450
|
+
/**
|
3451
|
+
* Prefixes of primitive values that could be consolidated.
|
3452
|
+
* The String values of the prefixes must have same number of characters.
|
3453
|
+
* The prefixes must not be used in any properties defined in any version
|
3454
|
+
* of <a href=
|
3455
|
+
* "http://www.ecma-international.org/publications/standards/Ecma-262.htm"
|
3456
|
+
* >ECMA-262</a>.
|
3457
|
+
* @namespace
|
3458
|
+
* @enum {string}
|
3459
|
+
*/
|
3460
|
+
EValuePrefixes = {
|
3461
|
+
/**
|
3462
|
+
* Identifies String values.
|
3463
|
+
* @type {string}
|
3464
|
+
*/
|
3465
|
+
S_STRING: '#S',
|
3466
|
+
/**
|
3467
|
+
* Identifies null and Boolean values.
|
3468
|
+
* @type {string}
|
3469
|
+
*/
|
3470
|
+
S_SYMBOLIC: '#O'
|
3471
|
+
},
|
3472
|
+
/**
|
3473
|
+
* Categories of source elements in terms of their appropriateness of
|
3474
|
+
* having their primitive values consolidated.
|
3475
|
+
* @namespace
|
3476
|
+
* @enum {number}
|
3477
|
+
*/
|
3478
|
+
ESourceElementCategories = {
|
3479
|
+
/**
|
3480
|
+
* Identifies a source element that includes the <a href=
|
3481
|
+
* "http://es5.github.com/#x12.10">{@code with}</a> statement.
|
3482
|
+
* @type {number}
|
3483
|
+
*/
|
3484
|
+
N_WITH: 0,
|
3485
|
+
/**
|
3486
|
+
* Identifies a source element that includes the <a href=
|
3487
|
+
* "http://es5.github.com/#x15.1.2.1">{@code eval}</a> identifier name.
|
3488
|
+
* @type {number}
|
3489
|
+
*/
|
3490
|
+
N_EVAL: 1,
|
3491
|
+
/**
|
3492
|
+
* Identifies a source element that must be excluded from the process
|
3493
|
+
* unless its whole scope is examined.
|
3494
|
+
* @type {number}
|
3495
|
+
*/
|
3496
|
+
N_EXCLUDABLE: 2,
|
3497
|
+
/**
|
3498
|
+
* Identifies source elements not posing any problems.
|
3499
|
+
* @type {number}
|
3500
|
+
*/
|
3501
|
+
N_OTHER: 3
|
3502
|
+
},
|
3503
|
+
/**
|
3504
|
+
* The list of literals (other than the String ones) whose primitive
|
3505
|
+
* values can be consolidated.
|
3506
|
+
* @const
|
3507
|
+
* @type {!Array.<string>}
|
3508
|
+
*/
|
3509
|
+
A_OTHER_SUBSTITUTABLE_LITERALS = [
|
3510
|
+
'null', // The null literal.
|
3511
|
+
'false', // The Boolean literal {@code false}.
|
3512
|
+
'true' // The Boolean literal {@code true}.
|
3513
|
+
];
|
3514
|
+
|
3515
|
+
(/**
|
3516
|
+
* Consolidates all worthwhile primitive values in a syntactic code unit.
|
3517
|
+
* @param {!TSyntacticCodeUnit} oSyntacticCodeUnit An array-like object
|
3518
|
+
* representing the branch of the abstract syntax tree representing the
|
3519
|
+
* syntactic code unit along with its scope.
|
3520
|
+
* @see TPrimitiveValue#nSaving
|
3521
|
+
*/
|
3522
|
+
function fExamineSyntacticCodeUnit(oSyntacticCodeUnit) {
|
3523
|
+
var _,
|
3524
|
+
/**
|
3525
|
+
* Indicates whether the syntactic code unit represents global code.
|
3526
|
+
* @type {boolean}
|
3527
|
+
*/
|
3528
|
+
bIsGlobal = 'toplevel' === oSyntacticCodeUnit[0],
|
3529
|
+
/**
|
3530
|
+
* Indicates whether the whole scope is being examined.
|
3531
|
+
* @type {boolean}
|
3532
|
+
*/
|
3533
|
+
bIsWhollyExaminable = !bIsGlobal,
|
3534
|
+
/**
|
3535
|
+
* An array-like object representing source elements that constitute a
|
3536
|
+
* syntactic code unit.
|
3537
|
+
* @type {!TSyntacticCodeUnit}
|
3538
|
+
*/
|
3539
|
+
oSourceElements,
|
3540
|
+
/**
|
3541
|
+
* A record consisting of data about the source element that is
|
3542
|
+
* currently being examined.
|
3543
|
+
* @type {!TSourceElementsData}
|
3544
|
+
*/
|
3545
|
+
oSourceElementData,
|
3546
|
+
/**
|
3547
|
+
* The scope of the syntactic code unit.
|
3548
|
+
* @type {!TScope}
|
3549
|
+
*/
|
3550
|
+
oScope,
|
3551
|
+
/**
|
3552
|
+
* An instance of an object that allows the traversal of an <abbr
|
3553
|
+
* title="abstract syntax tree">AST</abbr>.
|
3554
|
+
* @type {!TWalker}
|
3555
|
+
*/
|
3556
|
+
oWalker,
|
3557
|
+
/**
|
3558
|
+
* An object encompassing collections of functions used during the
|
3559
|
+
* traversal of an <abbr title="abstract syntax tree">AST</abbr>.
|
3560
|
+
* @namespace
|
3561
|
+
* @type {!Object.<string, !Object.<string, function(...[*])>>}
|
3562
|
+
*/
|
3563
|
+
oWalkers = {
|
3564
|
+
/**
|
3565
|
+
* A collection of functions used during the surveyance of source
|
3566
|
+
* elements.
|
3567
|
+
* @namespace
|
3568
|
+
* @type {!Object.<string, function(...[*])>}
|
3569
|
+
*/
|
3570
|
+
oSurveySourceElement: {
|
3571
|
+
/**#nocode+*/ // JsDoc Toolkit 2.4.0 hides some of the keys.
|
3572
|
+
/**
|
3573
|
+
* Classifies the source element as excludable if it does not
|
3574
|
+
* contain a {@code with} statement or the {@code eval} identifier
|
3575
|
+
* name. Adds the identifier of the function and its formal
|
3576
|
+
* parameters to the list of identifier names found.
|
3577
|
+
* @param {string} sIdentifier The identifier of the function.
|
3578
|
+
* @param {!Array.<string>} aFormalParameterList Formal parameters.
|
3579
|
+
* @param {!TSyntacticCodeUnit} oFunctionBody Function code.
|
3580
|
+
*/
|
3581
|
+
'defun': function(
|
3582
|
+
sIdentifier,
|
3583
|
+
aFormalParameterList,
|
3584
|
+
oFunctionBody) {
|
3585
|
+
fClassifyAsExcludable();
|
3586
|
+
fAddIdentifier(sIdentifier);
|
3587
|
+
aFormalParameterList.forEach(fAddIdentifier);
|
3588
|
+
},
|
3589
|
+
/**
|
3590
|
+
* Increments the count of the number of occurrences of the String
|
3591
|
+
* value that is equivalent to the sequence of terminal symbols
|
3592
|
+
* that constitute the encountered identifier name.
|
3593
|
+
* @param {!TSyntacticCodeUnit} oExpression The nonterminal
|
3594
|
+
* MemberExpression.
|
3595
|
+
* @param {string} sIdentifierName The identifier name used as the
|
3596
|
+
* property accessor.
|
3597
|
+
* @return {!Array} The encountered branch of an <abbr title=
|
3598
|
+
* "abstract syntax tree">AST</abbr> with its nonterminal
|
3599
|
+
* MemberExpression traversed.
|
3600
|
+
*/
|
3601
|
+
'dot': function(oExpression, sIdentifierName) {
|
3602
|
+
fCountPrimaryExpression(
|
3603
|
+
EPrimaryExpressionCategories.N_IDENTIFIER_NAMES,
|
3604
|
+
EValuePrefixes.S_STRING + sIdentifierName);
|
3605
|
+
return ['dot', oWalker.walk(oExpression), sIdentifierName];
|
3606
|
+
},
|
3607
|
+
/**
|
3608
|
+
* Adds the optional identifier of the function and its formal
|
3609
|
+
* parameters to the list of identifier names found.
|
3610
|
+
* @param {?string} sIdentifier The optional identifier of the
|
3611
|
+
* function.
|
3612
|
+
* @param {!Array.<string>} aFormalParameterList Formal parameters.
|
3613
|
+
* @param {!TSyntacticCodeUnit} oFunctionBody Function code.
|
3614
|
+
*/
|
3615
|
+
'function': function(
|
3616
|
+
sIdentifier,
|
3617
|
+
aFormalParameterList,
|
3618
|
+
oFunctionBody) {
|
3619
|
+
if ('string' === typeof sIdentifier) {
|
3620
|
+
fAddIdentifier(sIdentifier);
|
3621
|
+
}
|
3622
|
+
aFormalParameterList.forEach(fAddIdentifier);
|
3623
|
+
},
|
3624
|
+
/**
|
3625
|
+
* Either increments the count of the number of occurrences of the
|
3626
|
+
* encountered null or Boolean value or classifies a source element
|
3627
|
+
* as containing the {@code eval} identifier name.
|
3628
|
+
* @param {string} sIdentifier The identifier encountered.
|
3629
|
+
*/
|
3630
|
+
'name': function(sIdentifier) {
|
3631
|
+
if (-1 !== A_OTHER_SUBSTITUTABLE_LITERALS.indexOf(sIdentifier)) {
|
3632
|
+
fCountPrimaryExpression(
|
3633
|
+
EPrimaryExpressionCategories.N_NULL_AND_BOOLEAN_LITERALS,
|
3634
|
+
EValuePrefixes.S_SYMBOLIC + sIdentifier);
|
3635
|
+
} else {
|
3636
|
+
if ('eval' === sIdentifier) {
|
3637
|
+
oSourceElementData.nCategory =
|
3638
|
+
ESourceElementCategories.N_EVAL;
|
3639
|
+
}
|
3640
|
+
fAddIdentifier(sIdentifier);
|
3641
|
+
}
|
3642
|
+
},
|
3643
|
+
/**
|
3644
|
+
* Classifies the source element as excludable if it does not
|
3645
|
+
* contain a {@code with} statement or the {@code eval} identifier
|
3646
|
+
* name.
|
3647
|
+
* @param {TSyntacticCodeUnit} oExpression The expression whose
|
3648
|
+
* value is to be returned.
|
3649
|
+
*/
|
3650
|
+
'return': function(oExpression) {
|
3651
|
+
fClassifyAsExcludable();
|
3652
|
+
},
|
3653
|
+
/**
|
3654
|
+
* Increments the count of the number of occurrences of the
|
3655
|
+
* encountered String value.
|
3656
|
+
* @param {string} sStringValue The String value of the string
|
3657
|
+
* literal encountered.
|
3658
|
+
*/
|
3659
|
+
'string': function(sStringValue) {
|
3660
|
+
if (sStringValue.length > 0) {
|
3661
|
+
fCountPrimaryExpression(
|
3662
|
+
EPrimaryExpressionCategories.N_STRING_LITERALS,
|
3663
|
+
EValuePrefixes.S_STRING + sStringValue);
|
3664
|
+
}
|
3665
|
+
},
|
3666
|
+
/**
|
3667
|
+
* Adds the identifier reserved for an exception to the list of
|
3668
|
+
* identifier names found.
|
3669
|
+
* @param {!TSyntacticCodeUnit} oTry A block of code in which an
|
3670
|
+
* exception can occur.
|
3671
|
+
* @param {Array} aCatch The identifier reserved for an exception
|
3672
|
+
* and a block of code to handle the exception.
|
3673
|
+
* @param {TSyntacticCodeUnit} oFinally An optional block of code
|
3674
|
+
* to be evaluated regardless of whether an exception occurs.
|
3675
|
+
*/
|
3676
|
+
'try': function(oTry, aCatch, oFinally) {
|
3677
|
+
if (Array.isArray(aCatch)) {
|
3678
|
+
fAddIdentifier(aCatch[0]);
|
3679
|
+
}
|
3680
|
+
},
|
3681
|
+
/**
|
3682
|
+
* Classifies the source element as excludable if it does not
|
3683
|
+
* contain a {@code with} statement or the {@code eval} identifier
|
3684
|
+
* name. Adds the identifier of each declared variable to the list
|
3685
|
+
* of identifier names found.
|
3686
|
+
* @param {!Array.<!Array>} aVariableDeclarationList Variable
|
3687
|
+
* declarations.
|
3688
|
+
*/
|
3689
|
+
'var': function(aVariableDeclarationList) {
|
3690
|
+
fClassifyAsExcludable();
|
3691
|
+
aVariableDeclarationList.forEach(fAddVariable);
|
3692
|
+
},
|
3693
|
+
/**
|
3694
|
+
* Classifies a source element as containing the {@code with}
|
3695
|
+
* statement.
|
3696
|
+
* @param {!TSyntacticCodeUnit} oExpression An expression whose
|
3697
|
+
* value is to be converted to a value of type Object and
|
3698
|
+
* become the binding object of a new object environment
|
3699
|
+
* record of a new lexical environment in which the statement
|
3700
|
+
* is to be executed.
|
3701
|
+
* @param {!TSyntacticCodeUnit} oStatement The statement to be
|
3702
|
+
* executed in the augmented lexical environment.
|
3703
|
+
* @return {!Array} An empty array to stop the traversal.
|
3704
|
+
*/
|
3705
|
+
'with': function(oExpression, oStatement) {
|
3706
|
+
oSourceElementData.nCategory = ESourceElementCategories.N_WITH;
|
3707
|
+
return [];
|
3708
|
+
}
|
3709
|
+
/**#nocode-*/ // JsDoc Toolkit 2.4.0 hides some of the keys.
|
3710
|
+
},
|
3711
|
+
/**
|
3712
|
+
* A collection of functions used while looking for nested functions.
|
3713
|
+
* @namespace
|
3714
|
+
* @type {!Object.<string, function(...[*])>}
|
3715
|
+
*/
|
3716
|
+
oExamineFunctions: {
|
3717
|
+
/**#nocode+*/ // JsDoc Toolkit 2.4.0 hides some of the keys.
|
3718
|
+
/**
|
3719
|
+
* Orders an examination of a nested function declaration.
|
3720
|
+
* @this {!TSyntacticCodeUnit} An array-like object representing
|
3721
|
+
* the branch of an <abbr title="abstract syntax tree"
|
3722
|
+
* >AST</abbr> representing the syntactic code unit along with
|
3723
|
+
* its scope.
|
3724
|
+
* @return {!Array} An empty array to stop the traversal.
|
3725
|
+
*/
|
3726
|
+
'defun': function() {
|
3727
|
+
fExamineSyntacticCodeUnit(this);
|
3728
|
+
return [];
|
3729
|
+
},
|
3730
|
+
/**
|
3731
|
+
* Orders an examination of a nested function expression.
|
3732
|
+
* @this {!TSyntacticCodeUnit} An array-like object representing
|
3733
|
+
* the branch of an <abbr title="abstract syntax tree"
|
3734
|
+
* >AST</abbr> representing the syntactic code unit along with
|
3735
|
+
* its scope.
|
3736
|
+
* @return {!Array} An empty array to stop the traversal.
|
3737
|
+
*/
|
3738
|
+
'function': function() {
|
3739
|
+
fExamineSyntacticCodeUnit(this);
|
3740
|
+
return [];
|
3741
|
+
}
|
3742
|
+
/**#nocode-*/ // JsDoc Toolkit 2.4.0 hides some of the keys.
|
3743
|
+
}
|
3744
|
+
},
|
3745
|
+
/**
|
3746
|
+
* Records containing data about source elements.
|
3747
|
+
* @type {Array.<TSourceElementsData>}
|
3748
|
+
*/
|
3749
|
+
aSourceElementsData = [],
|
3750
|
+
/**
|
3751
|
+
* The index (in the source text order) of the source element
|
3752
|
+
* immediately following a <a href="http://es5.github.com/#x14.1"
|
3753
|
+
* >Directive Prologue</a>.
|
3754
|
+
* @type {number}
|
3755
|
+
*/
|
3756
|
+
nAfterDirectivePrologue = 0,
|
3757
|
+
/**
|
3758
|
+
* The index (in the source text order) of the source element that is
|
3759
|
+
* currently being considered.
|
3760
|
+
* @type {number}
|
3761
|
+
*/
|
3762
|
+
nPosition,
|
3763
|
+
/**
|
3764
|
+
* The index (in the source text order) of the source element that is
|
3765
|
+
* the last element of the range of source elements that is currently
|
3766
|
+
* being considered.
|
3767
|
+
* @type {(undefined|number)}
|
3768
|
+
*/
|
3769
|
+
nTo,
|
3770
|
+
/**
|
3771
|
+
* Initiates the traversal of a source element.
|
3772
|
+
* @param {!TWalker} oWalker An instance of an object that allows the
|
3773
|
+
* traversal of an abstract syntax tree.
|
3774
|
+
* @param {!TSyntacticCodeUnit} oSourceElement A source element from
|
3775
|
+
* which the traversal should commence.
|
3776
|
+
* @return {function(): !TSyntacticCodeUnit} A function that is able to
|
3777
|
+
* initiate the traversal from a given source element.
|
3778
|
+
*/
|
3779
|
+
cContext = function(oWalker, oSourceElement) {
|
3780
|
+
/**
|
3781
|
+
* @return {!TSyntacticCodeUnit} A function that is able to
|
3782
|
+
* initiate the traversal from a given source element.
|
3783
|
+
*/
|
3784
|
+
var fLambda = function() {
|
3785
|
+
return oWalker.walk(oSourceElement);
|
3786
|
+
};
|
3787
|
+
|
3788
|
+
return fLambda;
|
3789
|
+
},
|
3790
|
+
/**
|
3791
|
+
* Classifies the source element as excludable if it does not
|
3792
|
+
* contain a {@code with} statement or the {@code eval} identifier
|
3793
|
+
* name.
|
3794
|
+
*/
|
3795
|
+
fClassifyAsExcludable = function() {
|
3796
|
+
if (oSourceElementData.nCategory ===
|
3797
|
+
ESourceElementCategories.N_OTHER) {
|
3798
|
+
oSourceElementData.nCategory =
|
3799
|
+
ESourceElementCategories.N_EXCLUDABLE;
|
3800
|
+
}
|
3801
|
+
},
|
3802
|
+
/**
|
3803
|
+
* Adds an identifier to the list of identifier names found.
|
3804
|
+
* @param {string} sIdentifier The identifier to be added.
|
3805
|
+
*/
|
3806
|
+
fAddIdentifier = function(sIdentifier) {
|
3807
|
+
if (-1 === oSourceElementData.aIdentifiers.indexOf(sIdentifier)) {
|
3808
|
+
oSourceElementData.aIdentifiers.push(sIdentifier);
|
3809
|
+
}
|
3810
|
+
},
|
3811
|
+
/**
|
3812
|
+
* Adds the identifier of a variable to the list of identifier names
|
3813
|
+
* found.
|
3814
|
+
* @param {!Array} aVariableDeclaration A variable declaration.
|
3815
|
+
*/
|
3816
|
+
fAddVariable = function(aVariableDeclaration) {
|
3817
|
+
fAddIdentifier(/** @type {string} */ aVariableDeclaration[0]);
|
3818
|
+
},
|
3819
|
+
/**
|
3820
|
+
* Increments the count of the number of occurrences of the prefixed
|
3821
|
+
* String representation attributed to the primary expression.
|
3822
|
+
* @param {number} nCategory The category of the primary expression.
|
3823
|
+
* @param {string} sName The prefixed String representation attributed
|
3824
|
+
* to the primary expression.
|
3825
|
+
*/
|
3826
|
+
fCountPrimaryExpression = function(nCategory, sName) {
|
3827
|
+
if (!oSourceElementData.aCount[nCategory].hasOwnProperty(sName)) {
|
3828
|
+
oSourceElementData.aCount[nCategory][sName] = 0;
|
3829
|
+
if (-1 === oSourceElementData.aPrimitiveValues.indexOf(sName)) {
|
3830
|
+
oSourceElementData.aPrimitiveValues.push(sName);
|
3831
|
+
}
|
3832
|
+
}
|
3833
|
+
oSourceElementData.aCount[nCategory][sName] += 1;
|
3834
|
+
},
|
3835
|
+
/**
|
3836
|
+
* Consolidates all worthwhile primitive values in a range of source
|
3837
|
+
* elements.
|
3838
|
+
* @param {number} nFrom The index (in the source text order) of the
|
3839
|
+
* source element that is the first element of the range.
|
3840
|
+
* @param {number} nTo The index (in the source text order) of the
|
3841
|
+
* source element that is the last element of the range.
|
3842
|
+
* @param {boolean} bEnclose Indicates whether the range should be
|
3843
|
+
* enclosed within a function call with no argument values to a
|
3844
|
+
* function with an empty parameter list if any primitive values
|
3845
|
+
* are consolidated.
|
3846
|
+
* @see TPrimitiveValue#nSaving
|
3847
|
+
*/
|
3848
|
+
fExamineSourceElements = function(nFrom, nTo, bEnclose) {
|
3849
|
+
var _,
|
3850
|
+
/**
|
3851
|
+
* The index of the last mangled name.
|
3852
|
+
* @type {number}
|
3853
|
+
*/
|
3854
|
+
nIndex = oScope.cname,
|
3855
|
+
/**
|
3856
|
+
* The index of the source element that is currently being
|
3857
|
+
* considered.
|
3858
|
+
* @type {number}
|
3859
|
+
*/
|
3860
|
+
nPosition,
|
3861
|
+
/**
|
3862
|
+
* A collection of functions used during the consolidation of
|
3863
|
+
* primitive values and identifier names used as property
|
3864
|
+
* accessors.
|
3865
|
+
* @namespace
|
3866
|
+
* @type {!Object.<string, function(...[*])>}
|
3867
|
+
*/
|
3868
|
+
oWalkersTransformers = {
|
3869
|
+
/**
|
3870
|
+
* If the String value that is equivalent to the sequence of
|
3871
|
+
* terminal symbols that constitute the encountered identifier
|
3872
|
+
* name is worthwhile, a syntactic conversion from the dot
|
3873
|
+
* notation to the bracket notation ensues with that sequence
|
3874
|
+
* being substituted by an identifier name to which the value
|
3875
|
+
* is assigned.
|
3876
|
+
* Applies to property accessors that use the dot notation.
|
3877
|
+
* @param {!TSyntacticCodeUnit} oExpression The nonterminal
|
3878
|
+
* MemberExpression.
|
3879
|
+
* @param {string} sIdentifierName The identifier name used as
|
3880
|
+
* the property accessor.
|
3881
|
+
* @return {!Array} A syntactic code unit that is equivalent to
|
3882
|
+
* the one encountered.
|
3883
|
+
* @see TPrimitiveValue#nSaving
|
3884
|
+
*/
|
3885
|
+
'dot': function(oExpression, sIdentifierName) {
|
3886
|
+
/**
|
3887
|
+
* The prefixed String value that is equivalent to the
|
3888
|
+
* sequence of terminal symbols that constitute the
|
3889
|
+
* encountered identifier name.
|
3890
|
+
* @type {string}
|
3891
|
+
*/
|
3892
|
+
var sPrefixed = EValuePrefixes.S_STRING + sIdentifierName;
|
3893
|
+
|
3894
|
+
return oSolutionBest.oPrimitiveValues.hasOwnProperty(
|
3895
|
+
sPrefixed) &&
|
3896
|
+
oSolutionBest.oPrimitiveValues[sPrefixed].nSaving > 0 ?
|
3897
|
+
['sub',
|
3898
|
+
oWalker.walk(oExpression),
|
3899
|
+
['name',
|
3900
|
+
oSolutionBest.oPrimitiveValues[sPrefixed].sName]] :
|
3901
|
+
['dot', oWalker.walk(oExpression), sIdentifierName];
|
3902
|
+
},
|
3903
|
+
/**
|
3904
|
+
* If the encountered identifier is a null or Boolean literal
|
3905
|
+
* and its value is worthwhile, the identifier is substituted
|
3906
|
+
* by an identifier name to which that value is assigned.
|
3907
|
+
* Applies to identifier names.
|
3908
|
+
* @param {string} sIdentifier The identifier encountered.
|
3909
|
+
* @return {!Array} A syntactic code unit that is equivalent to
|
3910
|
+
* the one encountered.
|
3911
|
+
* @see TPrimitiveValue#nSaving
|
3912
|
+
*/
|
3913
|
+
'name': function(sIdentifier) {
|
3914
|
+
/**
|
3915
|
+
* The prefixed representation String of the identifier.
|
3916
|
+
* @type {string}
|
3917
|
+
*/
|
3918
|
+
var sPrefixed = EValuePrefixes.S_SYMBOLIC + sIdentifier;
|
3919
|
+
|
3920
|
+
return [
|
3921
|
+
'name',
|
3922
|
+
oSolutionBest.oPrimitiveValues.hasOwnProperty(sPrefixed) &&
|
3923
|
+
oSolutionBest.oPrimitiveValues[sPrefixed].nSaving > 0 ?
|
3924
|
+
oSolutionBest.oPrimitiveValues[sPrefixed].sName :
|
3925
|
+
sIdentifier
|
3926
|
+
];
|
3927
|
+
},
|
3928
|
+
/**
|
3929
|
+
* If the encountered String value is worthwhile, it is
|
3930
|
+
* substituted by an identifier name to which that value is
|
3931
|
+
* assigned.
|
3932
|
+
* Applies to String values.
|
3933
|
+
* @param {string} sStringValue The String value of the string
|
3934
|
+
* literal encountered.
|
3935
|
+
* @return {!Array} A syntactic code unit that is equivalent to
|
3936
|
+
* the one encountered.
|
3937
|
+
* @see TPrimitiveValue#nSaving
|
3938
|
+
*/
|
3939
|
+
'string': function(sStringValue) {
|
3940
|
+
/**
|
3941
|
+
* The prefixed representation String of the primitive value
|
3942
|
+
* of the literal.
|
3943
|
+
* @type {string}
|
3944
|
+
*/
|
3945
|
+
var sPrefixed =
|
3946
|
+
EValuePrefixes.S_STRING + sStringValue;
|
3947
|
+
|
3948
|
+
return oSolutionBest.oPrimitiveValues.hasOwnProperty(
|
3949
|
+
sPrefixed) &&
|
3950
|
+
oSolutionBest.oPrimitiveValues[sPrefixed].nSaving > 0 ?
|
3951
|
+
['name',
|
3952
|
+
oSolutionBest.oPrimitiveValues[sPrefixed].sName] :
|
3953
|
+
['string', sStringValue];
|
3954
|
+
}
|
3955
|
+
},
|
3956
|
+
/**
|
3957
|
+
* Such data on what to consolidate within the range of source
|
3958
|
+
* elements that is currently being considered that lead to the
|
3959
|
+
* greatest known reduction of the number of the terminal symbols
|
3960
|
+
* in comparison to the original source text.
|
3961
|
+
* @type {!TSolution}
|
3962
|
+
*/
|
3963
|
+
oSolutionBest = new TSolution(),
|
3964
|
+
/**
|
3965
|
+
* Data representing an ongoing attempt to find a better
|
3966
|
+
* reduction of the number of the terminal symbols in comparison
|
3967
|
+
* to the original source text than the best one that is
|
3968
|
+
* currently known.
|
3969
|
+
* @type {!TSolution}
|
3970
|
+
* @see oSolutionBest
|
3971
|
+
*/
|
3972
|
+
oSolutionCandidate = new TSolution(),
|
3973
|
+
/**
|
3974
|
+
* A record consisting of data about the range of source elements
|
3975
|
+
* that is currently being examined.
|
3976
|
+
* @type {!TSourceElementsData}
|
3977
|
+
*/
|
3978
|
+
oSourceElementsData = new TSourceElementsData(),
|
3979
|
+
/**
|
3980
|
+
* Variable declarations for each primitive value that is to be
|
3981
|
+
* consolidated within the elements.
|
3982
|
+
* @type {!Array.<!Array>}
|
3983
|
+
*/
|
3984
|
+
aVariableDeclarations = [],
|
3985
|
+
/**
|
3986
|
+
* Augments a list with a prefixed representation String.
|
3987
|
+
* @param {!Array.<string>} aList A list that is to be augmented.
|
3988
|
+
* @return {function(string)} A function that augments a list
|
3989
|
+
* with a prefixed representation String.
|
3990
|
+
*/
|
3991
|
+
cAugmentList = function(aList) {
|
3992
|
+
/**
|
3993
|
+
* @param {string} sPrefixed Prefixed representation String of
|
3994
|
+
* a primitive value that could be consolidated within the
|
3995
|
+
* elements.
|
3996
|
+
*/
|
3997
|
+
var fLambda = function(sPrefixed) {
|
3998
|
+
if (-1 === aList.indexOf(sPrefixed)) {
|
3999
|
+
aList.push(sPrefixed);
|
4000
|
+
}
|
4001
|
+
};
|
4002
|
+
|
4003
|
+
return fLambda;
|
4004
|
+
},
|
4005
|
+
/**
|
4006
|
+
* Adds the number of occurrences of a primitive value of a given
|
4007
|
+
* category that could be consolidated in the source element with
|
4008
|
+
* a given index to the count of occurrences of that primitive
|
4009
|
+
* value within the range of source elements that is currently
|
4010
|
+
* being considered.
|
4011
|
+
* @param {number} nPosition The index (in the source text order)
|
4012
|
+
* of a source element.
|
4013
|
+
* @param {number} nCategory The category of the primary
|
4014
|
+
* expression from which the primitive value is derived.
|
4015
|
+
* @return {function(string)} A function that performs the
|
4016
|
+
* addition.
|
4017
|
+
* @see cAddOccurrencesInCategory
|
4018
|
+
*/
|
4019
|
+
cAddOccurrences = function(nPosition, nCategory) {
|
4020
|
+
/**
|
4021
|
+
* @param {string} sPrefixed The prefixed representation String
|
4022
|
+
* of a primitive value.
|
4023
|
+
*/
|
4024
|
+
var fLambda = function(sPrefixed) {
|
4025
|
+
if (!oSourceElementsData.aCount[nCategory].hasOwnProperty(
|
4026
|
+
sPrefixed)) {
|
4027
|
+
oSourceElementsData.aCount[nCategory][sPrefixed] = 0;
|
4028
|
+
}
|
4029
|
+
oSourceElementsData.aCount[nCategory][sPrefixed] +=
|
4030
|
+
aSourceElementsData[nPosition].aCount[nCategory][
|
4031
|
+
sPrefixed];
|
4032
|
+
};
|
4033
|
+
|
4034
|
+
return fLambda;
|
4035
|
+
},
|
4036
|
+
/**
|
4037
|
+
* Adds the number of occurrences of each primitive value of a
|
4038
|
+
* given category that could be consolidated in the source
|
4039
|
+
* element with a given index to the count of occurrences of that
|
4040
|
+
* primitive values within the range of source elements that is
|
4041
|
+
* currently being considered.
|
4042
|
+
* @param {number} nPosition The index (in the source text order)
|
4043
|
+
* of a source element.
|
4044
|
+
* @return {function(number)} A function that performs the
|
4045
|
+
* addition.
|
4046
|
+
* @see fAddOccurrences
|
4047
|
+
*/
|
4048
|
+
cAddOccurrencesInCategory = function(nPosition) {
|
4049
|
+
/**
|
4050
|
+
* @param {number} nCategory The category of the primary
|
4051
|
+
* expression from which the primitive value is derived.
|
4052
|
+
*/
|
4053
|
+
var fLambda = function(nCategory) {
|
4054
|
+
Object.keys(
|
4055
|
+
aSourceElementsData[nPosition].aCount[nCategory]
|
4056
|
+
).forEach(cAddOccurrences(nPosition, nCategory));
|
4057
|
+
};
|
4058
|
+
|
4059
|
+
return fLambda;
|
4060
|
+
},
|
4061
|
+
/**
|
4062
|
+
* Adds the number of occurrences of each primitive value that
|
4063
|
+
* could be consolidated in the source element with a given index
|
4064
|
+
* to the count of occurrences of that primitive values within
|
4065
|
+
* the range of source elements that is currently being
|
4066
|
+
* considered.
|
4067
|
+
* @param {number} nPosition The index (in the source text order)
|
4068
|
+
* of a source element.
|
4069
|
+
*/
|
4070
|
+
fAddOccurrences = function(nPosition) {
|
4071
|
+
Object.keys(aSourceElementsData[nPosition].aCount).forEach(
|
4072
|
+
cAddOccurrencesInCategory(nPosition));
|
4073
|
+
},
|
4074
|
+
/**
|
4075
|
+
* Creates a variable declaration for a primitive value if that
|
4076
|
+
* primitive value is to be consolidated within the elements.
|
4077
|
+
* @param {string} sPrefixed Prefixed representation String of a
|
4078
|
+
* primitive value that could be consolidated within the
|
4079
|
+
* elements.
|
4080
|
+
* @see aVariableDeclarations
|
4081
|
+
*/
|
4082
|
+
cAugmentVariableDeclarations = function(sPrefixed) {
|
4083
|
+
if (oSolutionBest.oPrimitiveValues[sPrefixed].nSaving > 0) {
|
4084
|
+
aVariableDeclarations.push([
|
4085
|
+
oSolutionBest.oPrimitiveValues[sPrefixed].sName,
|
4086
|
+
[0 === sPrefixed.indexOf(EValuePrefixes.S_SYMBOLIC) ?
|
4087
|
+
'name' : 'string',
|
4088
|
+
sPrefixed.substring(EValuePrefixes.S_SYMBOLIC.length)]
|
4089
|
+
]);
|
4090
|
+
}
|
4091
|
+
},
|
4092
|
+
/**
|
4093
|
+
* Sorts primitive values with regard to the difference in the
|
4094
|
+
* number of terminal symbols between the original source text
|
4095
|
+
* and the one with those primitive values consolidated.
|
4096
|
+
* @param {string} sPrefixed0 The prefixed representation String
|
4097
|
+
* of the first of the two primitive values that are being
|
4098
|
+
* compared.
|
4099
|
+
* @param {string} sPrefixed1 The prefixed representation String
|
4100
|
+
* of the second of the two primitive values that are being
|
4101
|
+
* compared.
|
4102
|
+
* @return {number}
|
4103
|
+
* <dl>
|
4104
|
+
* <dt>-1</dt>
|
4105
|
+
* <dd>if the first primitive value must be placed before
|
4106
|
+
* the other one,</dd>
|
4107
|
+
* <dt>0</dt>
|
4108
|
+
* <dd>if the first primitive value may be placed before
|
4109
|
+
* the other one,</dd>
|
4110
|
+
* <dt>1</dt>
|
4111
|
+
* <dd>if the first primitive value must not be placed
|
4112
|
+
* before the other one.</dd>
|
4113
|
+
* </dl>
|
4114
|
+
* @see TSolution.oPrimitiveValues
|
4115
|
+
*/
|
4116
|
+
cSortPrimitiveValues = function(sPrefixed0, sPrefixed1) {
|
4117
|
+
/**
|
4118
|
+
* The difference between:
|
4119
|
+
* <ol>
|
4120
|
+
* <li>the difference in the number of terminal symbols
|
4121
|
+
* between the original source text and the one with the
|
4122
|
+
* first primitive value consolidated, and</li>
|
4123
|
+
* <li>the difference in the number of terminal symbols
|
4124
|
+
* between the original source text and the one with the
|
4125
|
+
* second primitive value consolidated.</li>
|
4126
|
+
* </ol>
|
4127
|
+
* @type {number}
|
4128
|
+
*/
|
4129
|
+
var nDifference =
|
4130
|
+
oSolutionCandidate.oPrimitiveValues[sPrefixed0].nSaving -
|
4131
|
+
oSolutionCandidate.oPrimitiveValues[sPrefixed1].nSaving;
|
4132
|
+
|
4133
|
+
return nDifference > 0 ? -1 : nDifference < 0 ? 1 : 0;
|
4134
|
+
},
|
4135
|
+
/**
|
4136
|
+
* Assigns an identifier name to a primitive value and calculates
|
4137
|
+
* whether instances of that primitive value are worth
|
4138
|
+
* consolidating.
|
4139
|
+
* @param {string} sPrefixed The prefixed representation String
|
4140
|
+
* of a primitive value that is being evaluated.
|
4141
|
+
*/
|
4142
|
+
fEvaluatePrimitiveValue = function(sPrefixed) {
|
4143
|
+
var _,
|
4144
|
+
/**
|
4145
|
+
* The index of the last mangled name.
|
4146
|
+
* @type {number}
|
4147
|
+
*/
|
4148
|
+
nIndex,
|
4149
|
+
/**
|
4150
|
+
* The representation String of the primitive value that is
|
4151
|
+
* being evaluated.
|
4152
|
+
* @type {string}
|
4153
|
+
*/
|
4154
|
+
sName =
|
4155
|
+
sPrefixed.substring(EValuePrefixes.S_SYMBOLIC.length),
|
4156
|
+
/**
|
4157
|
+
* The number of source characters taken up by the
|
4158
|
+
* representation String of the primitive value that is
|
4159
|
+
* being evaluated.
|
4160
|
+
* @type {number}
|
4161
|
+
*/
|
4162
|
+
nLengthOriginal = sName.length,
|
4163
|
+
/**
|
4164
|
+
* The number of source characters taken up by the
|
4165
|
+
* identifier name that could substitute the primitive
|
4166
|
+
* value that is being evaluated.
|
4167
|
+
* substituted.
|
4168
|
+
* @type {number}
|
4169
|
+
*/
|
4170
|
+
nLengthSubstitution,
|
4171
|
+
/**
|
4172
|
+
* The number of source characters taken up by by the
|
4173
|
+
* representation String of the primitive value that is
|
4174
|
+
* being evaluated when it is represented by a string
|
4175
|
+
* literal.
|
4176
|
+
* @type {number}
|
4177
|
+
*/
|
4178
|
+
nLengthString = oProcessor.make_string(sName).length;
|
4179
|
+
|
4180
|
+
oSolutionCandidate.oPrimitiveValues[sPrefixed] =
|
4181
|
+
new TPrimitiveValue();
|
4182
|
+
do { // Find an identifier unused in this or any nested scope.
|
4183
|
+
nIndex = oScope.cname;
|
4184
|
+
oSolutionCandidate.oPrimitiveValues[sPrefixed].sName =
|
4185
|
+
oScope.next_mangled();
|
4186
|
+
} while (-1 !== oSourceElementsData.aIdentifiers.indexOf(
|
4187
|
+
oSolutionCandidate.oPrimitiveValues[sPrefixed].sName));
|
4188
|
+
nLengthSubstitution = oSolutionCandidate.oPrimitiveValues[
|
4189
|
+
sPrefixed].sName.length;
|
4190
|
+
if (0 === sPrefixed.indexOf(EValuePrefixes.S_SYMBOLIC)) {
|
4191
|
+
// foo:null, or foo:null;
|
4192
|
+
oSolutionCandidate.oPrimitiveValues[sPrefixed].nSaving -=
|
4193
|
+
nLengthSubstitution + nLengthOriginal +
|
4194
|
+
oWeights.N_VARIABLE_DECLARATION;
|
4195
|
+
// null vs foo
|
4196
|
+
oSolutionCandidate.oPrimitiveValues[sPrefixed].nSaving +=
|
4197
|
+
oSourceElementsData.aCount[
|
4198
|
+
EPrimaryExpressionCategories.
|
4199
|
+
N_NULL_AND_BOOLEAN_LITERALS][sPrefixed] *
|
4200
|
+
(nLengthOriginal - nLengthSubstitution);
|
4201
|
+
} else {
|
4202
|
+
// foo:'fromCharCode';
|
4203
|
+
oSolutionCandidate.oPrimitiveValues[sPrefixed].nSaving -=
|
4204
|
+
nLengthSubstitution + nLengthString +
|
4205
|
+
oWeights.N_VARIABLE_DECLARATION;
|
4206
|
+
// .fromCharCode vs [foo]
|
4207
|
+
if (oSourceElementsData.aCount[
|
4208
|
+
EPrimaryExpressionCategories.N_IDENTIFIER_NAMES
|
4209
|
+
].hasOwnProperty(sPrefixed)) {
|
4210
|
+
oSolutionCandidate.oPrimitiveValues[sPrefixed].nSaving +=
|
4211
|
+
oSourceElementsData.aCount[
|
4212
|
+
EPrimaryExpressionCategories.N_IDENTIFIER_NAMES
|
4213
|
+
][sPrefixed] *
|
4214
|
+
(nLengthOriginal - nLengthSubstitution -
|
4215
|
+
oWeights.N_PROPERTY_ACCESSOR);
|
4216
|
+
}
|
4217
|
+
// 'fromCharCode' vs foo
|
4218
|
+
if (oSourceElementsData.aCount[
|
4219
|
+
EPrimaryExpressionCategories.N_STRING_LITERALS
|
4220
|
+
].hasOwnProperty(sPrefixed)) {
|
4221
|
+
oSolutionCandidate.oPrimitiveValues[sPrefixed].nSaving +=
|
4222
|
+
oSourceElementsData.aCount[
|
4223
|
+
EPrimaryExpressionCategories.N_STRING_LITERALS
|
4224
|
+
][sPrefixed] *
|
4225
|
+
(nLengthString - nLengthSubstitution);
|
4226
|
+
}
|
4227
|
+
}
|
4228
|
+
if (oSolutionCandidate.oPrimitiveValues[sPrefixed].nSaving >
|
4229
|
+
0) {
|
4230
|
+
oSolutionCandidate.nSavings +=
|
4231
|
+
oSolutionCandidate.oPrimitiveValues[sPrefixed].nSaving;
|
4232
|
+
} else {
|
4233
|
+
oScope.cname = nIndex; // Free the identifier name.
|
4234
|
+
}
|
4235
|
+
},
|
4236
|
+
/**
|
4237
|
+
* Adds a variable declaration to an existing variable statement.
|
4238
|
+
* @param {!Array} aVariableDeclaration A variable declaration
|
4239
|
+
* with an initialiser.
|
4240
|
+
*/
|
4241
|
+
cAddVariableDeclaration = function(aVariableDeclaration) {
|
4242
|
+
(/** @type {!Array} */ oSourceElements[nFrom][1]).unshift(
|
4243
|
+
aVariableDeclaration);
|
4244
|
+
};
|
4245
|
+
|
4246
|
+
if (nFrom > nTo) {
|
4247
|
+
return;
|
4248
|
+
}
|
4249
|
+
// If the range is a closure, reuse the closure.
|
4250
|
+
if (nFrom === nTo &&
|
4251
|
+
'stat' === oSourceElements[nFrom][0] &&
|
4252
|
+
'call' === oSourceElements[nFrom][1][0] &&
|
4253
|
+
'function' === oSourceElements[nFrom][1][1][0]) {
|
4254
|
+
fExamineSyntacticCodeUnit(oSourceElements[nFrom][1][1]);
|
4255
|
+
return;
|
4256
|
+
}
|
4257
|
+
// Create a list of all derived primitive values within the range.
|
4258
|
+
for (nPosition = nFrom; nPosition <= nTo; nPosition += 1) {
|
4259
|
+
aSourceElementsData[nPosition].aPrimitiveValues.forEach(
|
4260
|
+
cAugmentList(oSourceElementsData.aPrimitiveValues));
|
4261
|
+
}
|
4262
|
+
if (0 === oSourceElementsData.aPrimitiveValues.length) {
|
4263
|
+
return;
|
4264
|
+
}
|
4265
|
+
for (nPosition = nFrom; nPosition <= nTo; nPosition += 1) {
|
4266
|
+
// Add the number of occurrences to the total count.
|
4267
|
+
fAddOccurrences(nPosition);
|
4268
|
+
// Add identifiers of this or any nested scope to the list.
|
4269
|
+
aSourceElementsData[nPosition].aIdentifiers.forEach(
|
4270
|
+
cAugmentList(oSourceElementsData.aIdentifiers));
|
4271
|
+
}
|
4272
|
+
// Distribute identifier names among derived primitive values.
|
4273
|
+
do { // If there was any progress, find a better distribution.
|
4274
|
+
oSolutionBest = oSolutionCandidate;
|
4275
|
+
if (Object.keys(oSolutionCandidate.oPrimitiveValues).length > 0) {
|
4276
|
+
// Sort primitive values descending by their worthwhileness.
|
4277
|
+
oSourceElementsData.aPrimitiveValues.sort(cSortPrimitiveValues);
|
4278
|
+
}
|
4279
|
+
oSolutionCandidate = new TSolution();
|
4280
|
+
oSourceElementsData.aPrimitiveValues.forEach(
|
4281
|
+
fEvaluatePrimitiveValue);
|
4282
|
+
oScope.cname = nIndex;
|
4283
|
+
} while (oSolutionCandidate.nSavings > oSolutionBest.nSavings);
|
4284
|
+
// Take the necessity of adding a variable statement into account.
|
4285
|
+
if ('var' !== oSourceElements[nFrom][0]) {
|
4286
|
+
oSolutionBest.nSavings -= oWeights.N_VARIABLE_STATEMENT_AFFIXATION;
|
4287
|
+
}
|
4288
|
+
if (bEnclose) {
|
4289
|
+
// Take the necessity of forming a closure into account.
|
4290
|
+
oSolutionBest.nSavings -= oWeights.N_CLOSURE;
|
4291
|
+
}
|
4292
|
+
if (oSolutionBest.nSavings > 0) {
|
4293
|
+
// Create variable declarations suitable for UglifyJS.
|
4294
|
+
Object.keys(oSolutionBest.oPrimitiveValues).forEach(
|
4295
|
+
cAugmentVariableDeclarations);
|
4296
|
+
// Rewrite expressions that contain worthwhile primitive values.
|
4297
|
+
for (nPosition = nFrom; nPosition <= nTo; nPosition += 1) {
|
4298
|
+
oWalker = oProcessor.ast_walker();
|
4299
|
+
oSourceElements[nPosition] =
|
4300
|
+
oWalker.with_walkers(
|
4301
|
+
oWalkersTransformers,
|
4302
|
+
cContext(oWalker, oSourceElements[nPosition]));
|
4303
|
+
}
|
4304
|
+
if ('var' === oSourceElements[nFrom][0]) { // Reuse the statement.
|
4305
|
+
(/** @type {!Array.<!Array>} */ aVariableDeclarations.reverse(
|
4306
|
+
)).forEach(cAddVariableDeclaration);
|
4307
|
+
} else { // Add a variable statement.
|
4308
|
+
Array.prototype.splice.call(
|
4309
|
+
oSourceElements,
|
4310
|
+
nFrom,
|
4311
|
+
0,
|
4312
|
+
['var', aVariableDeclarations]);
|
4313
|
+
nTo += 1;
|
4314
|
+
}
|
4315
|
+
if (bEnclose) {
|
4316
|
+
// Add a closure.
|
4317
|
+
Array.prototype.splice.call(
|
4318
|
+
oSourceElements,
|
4319
|
+
nFrom,
|
4320
|
+
0,
|
4321
|
+
['stat', ['call', ['function', null, [], []], []]]);
|
4322
|
+
// Copy source elements into the closure.
|
4323
|
+
for (nPosition = nTo + 1; nPosition > nFrom; nPosition -= 1) {
|
4324
|
+
Array.prototype.unshift.call(
|
4325
|
+
oSourceElements[nFrom][1][1][3],
|
4326
|
+
oSourceElements[nPosition]);
|
4327
|
+
}
|
4328
|
+
// Remove source elements outside the closure.
|
4329
|
+
Array.prototype.splice.call(
|
4330
|
+
oSourceElements,
|
4331
|
+
nFrom + 1,
|
4332
|
+
nTo - nFrom + 1);
|
4333
|
+
}
|
4334
|
+
}
|
4335
|
+
if (bEnclose) {
|
4336
|
+
// Restore the availability of identifier names.
|
4337
|
+
oScope.cname = nIndex;
|
4338
|
+
}
|
4339
|
+
};
|
4340
|
+
|
4341
|
+
oSourceElements = (/** @type {!TSyntacticCodeUnit} */
|
4342
|
+
oSyntacticCodeUnit[bIsGlobal ? 1 : 3]);
|
4343
|
+
if (0 === oSourceElements.length) {
|
4344
|
+
return;
|
4345
|
+
}
|
4346
|
+
oScope = bIsGlobal ? oSyntacticCodeUnit.scope : oSourceElements.scope;
|
4347
|
+
// Skip a Directive Prologue.
|
4348
|
+
while (nAfterDirectivePrologue < oSourceElements.length &&
|
4349
|
+
'stat' === oSourceElements[nAfterDirectivePrologue][0] &&
|
4350
|
+
'string' === oSourceElements[nAfterDirectivePrologue][1][0]) {
|
4351
|
+
nAfterDirectivePrologue += 1;
|
4352
|
+
aSourceElementsData.push(null);
|
4353
|
+
}
|
4354
|
+
if (oSourceElements.length === nAfterDirectivePrologue) {
|
4355
|
+
return;
|
4356
|
+
}
|
4357
|
+
for (nPosition = nAfterDirectivePrologue;
|
4358
|
+
nPosition < oSourceElements.length;
|
4359
|
+
nPosition += 1) {
|
4360
|
+
oSourceElementData = new TSourceElementsData();
|
4361
|
+
oWalker = oProcessor.ast_walker();
|
4362
|
+
// Classify a source element.
|
4363
|
+
// Find its derived primitive values and count their occurrences.
|
4364
|
+
// Find all identifiers used (including nested scopes).
|
4365
|
+
oWalker.with_walkers(
|
4366
|
+
oWalkers.oSurveySourceElement,
|
4367
|
+
cContext(oWalker, oSourceElements[nPosition]));
|
4368
|
+
// Establish whether the scope is still wholly examinable.
|
4369
|
+
bIsWhollyExaminable = bIsWhollyExaminable &&
|
4370
|
+
ESourceElementCategories.N_WITH !== oSourceElementData.nCategory &&
|
4371
|
+
ESourceElementCategories.N_EVAL !== oSourceElementData.nCategory;
|
4372
|
+
aSourceElementsData.push(oSourceElementData);
|
4373
|
+
}
|
4374
|
+
if (bIsWhollyExaminable) { // Examine the whole scope.
|
4375
|
+
fExamineSourceElements(
|
4376
|
+
nAfterDirectivePrologue,
|
4377
|
+
oSourceElements.length - 1,
|
4378
|
+
false);
|
4379
|
+
} else { // Examine unexcluded ranges of source elements.
|
4380
|
+
for (nPosition = oSourceElements.length - 1;
|
4381
|
+
nPosition >= nAfterDirectivePrologue;
|
4382
|
+
nPosition -= 1) {
|
4383
|
+
oSourceElementData = (/** @type {!TSourceElementsData} */
|
4384
|
+
aSourceElementsData[nPosition]);
|
4385
|
+
if (ESourceElementCategories.N_OTHER ===
|
4386
|
+
oSourceElementData.nCategory) {
|
4387
|
+
if ('undefined' === typeof nTo) {
|
4388
|
+
nTo = nPosition; // Indicate the end of a range.
|
4389
|
+
}
|
4390
|
+
// Examine the range if it immediately follows a Directive Prologue.
|
4391
|
+
if (nPosition === nAfterDirectivePrologue) {
|
4392
|
+
fExamineSourceElements(nPosition, nTo, true);
|
4393
|
+
}
|
4394
|
+
} else {
|
4395
|
+
if ('undefined' !== typeof nTo) {
|
4396
|
+
// Examine the range that immediately follows this source element.
|
4397
|
+
fExamineSourceElements(nPosition + 1, nTo, true);
|
4398
|
+
nTo = void 0; // Obliterate the range.
|
4399
|
+
}
|
4400
|
+
// Examine nested functions.
|
4401
|
+
oWalker = oProcessor.ast_walker();
|
4402
|
+
oWalker.with_walkers(
|
4403
|
+
oWalkers.oExamineFunctions,
|
4404
|
+
cContext(oWalker, oSourceElements[nPosition]));
|
4405
|
+
}
|
4406
|
+
}
|
4407
|
+
}
|
4408
|
+
}(oAbstractSyntaxTree = oProcessor.ast_add_scope(oAbstractSyntaxTree)));
|
4409
|
+
return oAbstractSyntaxTree;
|
4410
|
+
};
|
4411
|
+
/*jshint sub:false */
|
4412
|
+
|
4413
|
+
|
4414
|
+
if (require.main === module) {
|
4415
|
+
(function() {
|
4416
|
+
'use strict';
|
4417
|
+
/*jshint bitwise:true, curly:true, eqeqeq:true, forin:true, immed:true,
|
4418
|
+
latedef:true, newcap:true, noarge:true, noempty:true, nonew:true,
|
4419
|
+
onevar:true, plusplus:true, regexp:true, undef:true, strict:true,
|
4420
|
+
sub:false, trailing:true */
|
4421
|
+
|
4422
|
+
var _,
|
4423
|
+
/**
|
4424
|
+
* NodeJS module for unit testing.
|
4425
|
+
* @namespace
|
4426
|
+
* @type {!TAssert}
|
4427
|
+
* @see http://nodejs.org/docs/v0.6.10/api/all.html#assert
|
4428
|
+
*/
|
4429
|
+
oAssert = (/** @type {!TAssert} */ require('env!env/assert')),
|
4430
|
+
/**
|
4431
|
+
* The parser of ECMA-262 found in UglifyJS.
|
4432
|
+
* @namespace
|
4433
|
+
* @type {!TParser}
|
4434
|
+
*/
|
4435
|
+
oParser = (/** @type {!TParser} */ require('./parse-js')),
|
4436
|
+
/**
|
4437
|
+
* The processor of <abbr title="abstract syntax tree">AST</abbr>s
|
4438
|
+
* found in UglifyJS.
|
4439
|
+
* @namespace
|
4440
|
+
* @type {!TProcessor}
|
4441
|
+
*/
|
4442
|
+
oProcessor = (/** @type {!TProcessor} */ require('./process')),
|
4443
|
+
/**
|
4444
|
+
* An instance of an object that allows the traversal of an <abbr
|
4445
|
+
* title="abstract syntax tree">AST</abbr>.
|
4446
|
+
* @type {!TWalker}
|
4447
|
+
*/
|
4448
|
+
oWalker,
|
4449
|
+
/**
|
4450
|
+
* A collection of functions for the removal of the scope information
|
4451
|
+
* during the traversal of an <abbr title="abstract syntax tree"
|
4452
|
+
* >AST</abbr>.
|
4453
|
+
* @namespace
|
4454
|
+
* @type {!Object.<string, function(...[*])>}
|
4455
|
+
*/
|
4456
|
+
oWalkersPurifiers = {
|
4457
|
+
/**#nocode+*/ // JsDoc Toolkit 2.4.0 hides some of the keys.
|
4458
|
+
/**
|
4459
|
+
* Deletes the scope information from the branch of the abstract
|
4460
|
+
* syntax tree representing the encountered function declaration.
|
4461
|
+
* @param {string} sIdentifier The identifier of the function.
|
4462
|
+
* @param {!Array.<string>} aFormalParameterList Formal parameters.
|
4463
|
+
* @param {!TSyntacticCodeUnit} oFunctionBody Function code.
|
4464
|
+
*/
|
4465
|
+
'defun': function(
|
4466
|
+
sIdentifier,
|
4467
|
+
aFormalParameterList,
|
4468
|
+
oFunctionBody) {
|
4469
|
+
delete oFunctionBody.scope;
|
4470
|
+
},
|
4471
|
+
/**
|
4472
|
+
* Deletes the scope information from the branch of the abstract
|
4473
|
+
* syntax tree representing the encountered function expression.
|
4474
|
+
* @param {?string} sIdentifier The optional identifier of the
|
4475
|
+
* function.
|
4476
|
+
* @param {!Array.<string>} aFormalParameterList Formal parameters.
|
4477
|
+
* @param {!TSyntacticCodeUnit} oFunctionBody Function code.
|
4478
|
+
*/
|
4479
|
+
'function': function(
|
4480
|
+
sIdentifier,
|
4481
|
+
aFormalParameterList,
|
4482
|
+
oFunctionBody) {
|
4483
|
+
delete oFunctionBody.scope;
|
4484
|
+
}
|
4485
|
+
/**#nocode-*/ // JsDoc Toolkit 2.4.0 hides some of the keys.
|
4486
|
+
},
|
4487
|
+
/**
|
4488
|
+
* Initiates the traversal of a source element.
|
4489
|
+
* @param {!TWalker} oWalker An instance of an object that allows the
|
4490
|
+
* traversal of an abstract syntax tree.
|
4491
|
+
* @param {!TSyntacticCodeUnit} oSourceElement A source element from
|
4492
|
+
* which the traversal should commence.
|
4493
|
+
* @return {function(): !TSyntacticCodeUnit} A function that is able to
|
4494
|
+
* initiate the traversal from a given source element.
|
4495
|
+
*/
|
4496
|
+
cContext = function(oWalker, oSourceElement) {
|
4497
|
+
/**
|
4498
|
+
* @return {!TSyntacticCodeUnit} A function that is able to
|
4499
|
+
* initiate the traversal from a given source element.
|
4500
|
+
*/
|
4501
|
+
var fLambda = function() {
|
4502
|
+
return oWalker.walk(oSourceElement);
|
4503
|
+
};
|
4504
|
+
|
4505
|
+
return fLambda;
|
4506
|
+
},
|
4507
|
+
/**
|
4508
|
+
* A record consisting of configuration for the code generation phase.
|
4509
|
+
* @type {!Object}
|
4510
|
+
*/
|
4511
|
+
oCodeGenerationOptions = {
|
4512
|
+
beautify: true
|
4513
|
+
},
|
4514
|
+
/**
|
4515
|
+
* Tests whether consolidation of an ECMAScript program yields expected
|
4516
|
+
* results.
|
4517
|
+
* @param {{
|
4518
|
+
* sTitle: string,
|
4519
|
+
* sInput: string,
|
4520
|
+
* sOutput: string
|
4521
|
+
* }} oUnitTest A record consisting of data about a unit test: its
|
4522
|
+
* name, an ECMAScript program, and, if consolidation is to take
|
4523
|
+
* place, the resulting ECMAScript program.
|
4524
|
+
*/
|
4525
|
+
cAssert = function(oUnitTest) {
|
4526
|
+
var _,
|
4527
|
+
/**
|
4528
|
+
* An array-like object representing the <abbr title=
|
4529
|
+
* "abstract syntax tree">AST</abbr> obtained after consolidation.
|
4530
|
+
* @type {!TSyntacticCodeUnit}
|
4531
|
+
*/
|
4532
|
+
oSyntacticCodeUnitActual =
|
4533
|
+
exports.ast_consolidate(oParser.parse(oUnitTest.sInput)),
|
4534
|
+
/**
|
4535
|
+
* An array-like object representing the expected <abbr title=
|
4536
|
+
* "abstract syntax tree">AST</abbr>.
|
4537
|
+
* @type {!TSyntacticCodeUnit}
|
4538
|
+
*/
|
4539
|
+
oSyntacticCodeUnitExpected = oParser.parse(
|
4540
|
+
oUnitTest.hasOwnProperty('sOutput') ?
|
4541
|
+
oUnitTest.sOutput : oUnitTest.sInput);
|
4542
|
+
|
4543
|
+
delete oSyntacticCodeUnitActual.scope;
|
4544
|
+
oWalker = oProcessor.ast_walker();
|
4545
|
+
oWalker.with_walkers(
|
4546
|
+
oWalkersPurifiers,
|
4547
|
+
cContext(oWalker, oSyntacticCodeUnitActual));
|
4548
|
+
try {
|
4549
|
+
oAssert.deepEqual(
|
4550
|
+
oSyntacticCodeUnitActual,
|
4551
|
+
oSyntacticCodeUnitExpected);
|
4552
|
+
} catch (oException) {
|
4553
|
+
console.error(
|
4554
|
+
'########## A unit test has failed.\n' +
|
4555
|
+
oUnitTest.sTitle + '\n' +
|
4556
|
+
'##### actual code (' +
|
4557
|
+
oProcessor.gen_code(oSyntacticCodeUnitActual).length +
|
4558
|
+
' bytes)\n' +
|
4559
|
+
oProcessor.gen_code(
|
4560
|
+
oSyntacticCodeUnitActual,
|
4561
|
+
oCodeGenerationOptions) + '\n' +
|
4562
|
+
'##### expected code (' +
|
4563
|
+
oProcessor.gen_code(oSyntacticCodeUnitExpected).length +
|
4564
|
+
' bytes)\n' +
|
4565
|
+
oProcessor.gen_code(
|
4566
|
+
oSyntacticCodeUnitExpected,
|
4567
|
+
oCodeGenerationOptions));
|
4568
|
+
}
|
4569
|
+
};
|
4570
|
+
|
4571
|
+
[
|
4572
|
+
// 7.6.1 Reserved Words.
|
4573
|
+
{
|
4574
|
+
sTitle:
|
4575
|
+
'Omission of keywords while choosing an identifier name.',
|
4576
|
+
sInput:
|
4577
|
+
'(function() {' +
|
4578
|
+
' var a, b, c, d, e, f, g, h, i, j, k, l, m,' +
|
4579
|
+
' n, o, p, q, r, s, t, u, v, w, x, y, z,' +
|
4580
|
+
' A, B, C, D, E, F, G, H, I, J, K, L, M,' +
|
4581
|
+
' N, O, P, Q, R, S, T, U, V, W, X, Y, Z,' +
|
4582
|
+
' $, _,' +
|
4583
|
+
' aa, ab, ac, ad, ae, af, ag, ah, ai, aj, ak, al, am,' +
|
4584
|
+
' an, ao, ap, aq, ar, as, at, au, av, aw, ax, ay, az,' +
|
4585
|
+
' aA, aB, aC, aD, aE, aF, aG, aH, aI, aJ, aK, aL, aM,' +
|
4586
|
+
' aN, aO, aP, aQ, aR, aS, aT, aU, aV, aW, aX, aY, aZ,' +
|
4587
|
+
' a$, a_,' +
|
4588
|
+
' ba, bb, bc, bd, be, bf, bg, bh, bi, bj, bk, bl, bm,' +
|
4589
|
+
' bn, bo, bp, bq, br, bs, bt, bu, bv, bw, bx, by, bz,' +
|
4590
|
+
' bA, bB, bC, bD, bE, bF, bG, bH, bI, bJ, bK, bL, bM,' +
|
4591
|
+
' bN, bO, bP, bQ, bR, bS, bT, bU, bV, bW, bX, bY, bZ,' +
|
4592
|
+
' b$, b_,' +
|
4593
|
+
' ca, cb, cc, cd, ce, cf, cg, ch, ci, cj, ck, cl, cm,' +
|
4594
|
+
' cn, co, cp, cq, cr, cs, ct, cu, cv, cw, cx, cy, cz,' +
|
4595
|
+
' cA, cB, cC, cD, cE, cF, cG, cH, cI, cJ, cK, cL, cM,' +
|
4596
|
+
' cN, cO, cP, cQ, cR, cS, cT, cU, cV, cW, cX, cY, cZ,' +
|
4597
|
+
' c$, c_,' +
|
4598
|
+
' da, db, dc, dd, de, df, dg, dh, di, dj, dk, dl, dm,' +
|
4599
|
+
' dn, dq, dr, ds, dt, du, dv, dw, dx, dy, dz,' +
|
4600
|
+
' dA, dB, dC, dD, dE, dF, dG, dH, dI, dJ, dK, dL, dM,' +
|
4601
|
+
' dN, dO, dP, dQ, dR, dS, dT, dU, dV, dW, dX, dY, dZ,' +
|
4602
|
+
' d$, d_;' +
|
4603
|
+
' void ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",' +
|
4604
|
+
' "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"];' +
|
4605
|
+
'}());',
|
4606
|
+
sOutput:
|
4607
|
+
'(function() {' +
|
4608
|
+
' var dp =' +
|
4609
|
+
' "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",' +
|
4610
|
+
' a, b, c, d, e, f, g, h, i, j, k, l, m,' +
|
4611
|
+
' n, o, p, q, r, s, t, u, v, w, x, y, z,' +
|
4612
|
+
' A, B, C, D, E, F, G, H, I, J, K, L, M,' +
|
4613
|
+
' N, O, P, Q, R, S, T, U, V, W, X, Y, Z,' +
|
4614
|
+
' $, _,' +
|
4615
|
+
' aa, ab, ac, ad, ae, af, ag, ah, ai, aj, ak, al, am,' +
|
4616
|
+
' an, ao, ap, aq, ar, as, at, au, av, aw, ax, ay, az,' +
|
4617
|
+
' aA, aB, aC, aD, aE, aF, aG, aH, aI, aJ, aK, aL, aM,' +
|
4618
|
+
' aN, aO, aP, aQ, aR, aS, aT, aU, aV, aW, aX, aY, aZ,' +
|
4619
|
+
' a$, a_,' +
|
4620
|
+
' ba, bb, bc, bd, be, bf, bg, bh, bi, bj, bk, bl, bm,' +
|
4621
|
+
' bn, bo, bp, bq, br, bs, bt, bu, bv, bw, bx, by, bz,' +
|
4622
|
+
' bA, bB, bC, bD, bE, bF, bG, bH, bI, bJ, bK, bL, bM,' +
|
4623
|
+
' bN, bO, bP, bQ, bR, bS, bT, bU, bV, bW, bX, bY, bZ,' +
|
4624
|
+
' b$, b_,' +
|
4625
|
+
' ca, cb, cc, cd, ce, cf, cg, ch, ci, cj, ck, cl, cm,' +
|
4626
|
+
' cn, co, cp, cq, cr, cs, ct, cu, cv, cw, cx, cy, cz,' +
|
4627
|
+
' cA, cB, cC, cD, cE, cF, cG, cH, cI, cJ, cK, cL, cM,' +
|
4628
|
+
' cN, cO, cP, cQ, cR, cS, cT, cU, cV, cW, cX, cY, cZ,' +
|
4629
|
+
' c$, c_,' +
|
4630
|
+
' da, db, dc, dd, de, df, dg, dh, di, dj, dk, dl, dm,' +
|
4631
|
+
' dn, dq, dr, ds, dt, du, dv, dw, dx, dy, dz,' +
|
4632
|
+
' dA, dB, dC, dD, dE, dF, dG, dH, dI, dJ, dK, dL, dM,' +
|
4633
|
+
' dN, dO, dP, dQ, dR, dS, dT, dU, dV, dW, dX, dY, dZ,' +
|
4634
|
+
' d$, d_;' +
|
4635
|
+
' void [dp, dp];' +
|
4636
|
+
'}());'
|
4637
|
+
},
|
4638
|
+
// 7.8.1 Null Literals.
|
4639
|
+
{
|
4640
|
+
sTitle:
|
4641
|
+
'Evaluation with regard to the null value.',
|
4642
|
+
sInput:
|
4643
|
+
'/*jshint evil:true */' +
|
4644
|
+
'(function() {' +
|
4645
|
+
' var foo;' +
|
4646
|
+
' void [null, null, null];' +
|
4647
|
+
'}());' +
|
4648
|
+
'eval("");' +
|
4649
|
+
'(function() {' +
|
4650
|
+
' var foo;' +
|
4651
|
+
' void [null, null];' +
|
4652
|
+
'}());',
|
4653
|
+
sOutput:
|
4654
|
+
'/*jshint evil:true */' +
|
4655
|
+
'(function() {' +
|
4656
|
+
' var a = null, foo;' +
|
4657
|
+
' void [a, a, a];' +
|
4658
|
+
'}());' +
|
4659
|
+
'eval("");' +
|
4660
|
+
'(function() {' +
|
4661
|
+
' var foo;' +
|
4662
|
+
' void [null, null];' +
|
4663
|
+
'}());'
|
4664
|
+
},
|
4665
|
+
// 7.8.2 Boolean Literals.
|
4666
|
+
{
|
4667
|
+
sTitle:
|
4668
|
+
'Evaluation with regard to the false value.',
|
4669
|
+
sInput:
|
4670
|
+
'/*jshint evil:true */' +
|
4671
|
+
'(function() {' +
|
4672
|
+
' var foo;' +
|
4673
|
+
' void [false, false, false];' +
|
4674
|
+
'}());' +
|
4675
|
+
'eval("");' +
|
4676
|
+
'(function() {' +
|
4677
|
+
' var foo;' +
|
4678
|
+
' void [false, false];' +
|
4679
|
+
'}());',
|
4680
|
+
sOutput:
|
4681
|
+
'/*jshint evil:true */' +
|
4682
|
+
'(function() {' +
|
4683
|
+
' var a = false, foo;' +
|
4684
|
+
' void [a, a, a];' +
|
4685
|
+
'}());' +
|
4686
|
+
'eval("");' +
|
4687
|
+
'(function() {' +
|
4688
|
+
' var foo;' +
|
4689
|
+
' void [false, false];' +
|
4690
|
+
'}());'
|
4691
|
+
},
|
4692
|
+
{
|
4693
|
+
sTitle:
|
4694
|
+
'Evaluation with regard to the true value.',
|
4695
|
+
sInput:
|
4696
|
+
'/*jshint evil:true */' +
|
4697
|
+
'(function() {' +
|
4698
|
+
' var foo;' +
|
4699
|
+
' void [true, true, true];' +
|
4700
|
+
'}());' +
|
4701
|
+
'eval("");' +
|
4702
|
+
'(function() {' +
|
4703
|
+
' var foo;' +
|
4704
|
+
' void [true, true];' +
|
4705
|
+
'}());',
|
4706
|
+
sOutput:
|
4707
|
+
'/*jshint evil:true */' +
|
4708
|
+
'(function() {' +
|
4709
|
+
' var a = true, foo;' +
|
4710
|
+
' void [a, a, a];' +
|
4711
|
+
'}());' +
|
4712
|
+
'eval("");' +
|
4713
|
+
'(function() {' +
|
4714
|
+
' var foo;' +
|
4715
|
+
' void [true, true];' +
|
4716
|
+
'}());'
|
4717
|
+
},
|
4718
|
+
// 7.8.4 String Literals.
|
4719
|
+
{
|
4720
|
+
sTitle:
|
4721
|
+
'Evaluation with regard to the String value of a string literal.',
|
4722
|
+
sInput:
|
4723
|
+
'(function() {' +
|
4724
|
+
' var foo;' +
|
4725
|
+
' void ["abcd", "abcd", "abc", "abc"];' +
|
4726
|
+
'}());',
|
4727
|
+
sOutput:
|
4728
|
+
'(function() {' +
|
4729
|
+
' var a = "abcd", foo;' +
|
4730
|
+
' void [a, a, "abc", "abc"];' +
|
4731
|
+
'}());'
|
4732
|
+
},
|
4733
|
+
// 7.8.5 Regular Expression Literals.
|
4734
|
+
{
|
4735
|
+
sTitle:
|
4736
|
+
'Preservation of the pattern of a regular expression literal.',
|
4737
|
+
sInput:
|
4738
|
+
'void [/abcdefghijklmnopqrstuvwxyz/, /abcdefghijklmnopqrstuvwxyz/];'
|
4739
|
+
},
|
4740
|
+
{
|
4741
|
+
sTitle:
|
4742
|
+
'Preservation of the flags of a regular expression literal.',
|
4743
|
+
sInput:
|
4744
|
+
'void [/(?:)/gim, /(?:)/gim, /(?:)/gim, /(?:)/gim, /(?:)/gim,' +
|
4745
|
+
' /(?:)/gim, /(?:)/gim, /(?:)/gim, /(?:)/gim, /(?:)/gim,' +
|
4746
|
+
' /(?:)/gim, /(?:)/gim, /(?:)/gim, /(?:)/gim, /(?:)/gim];'
|
4747
|
+
},
|
4748
|
+
// 10.2 Lexical Environments.
|
4749
|
+
{
|
4750
|
+
sTitle:
|
4751
|
+
'Preservation of identifier names in the same scope.',
|
4752
|
+
sInput:
|
4753
|
+
'/*jshint shadow:true */' +
|
4754
|
+
'var a;' +
|
4755
|
+
'function b(i) {' +
|
4756
|
+
'}' +
|
4757
|
+
'for (var c; 0 === Math.random(););' +
|
4758
|
+
'for (var d in {});' +
|
4759
|
+
'void ["abcdefghijklmnopqrstuvwxyz"];' +
|
4760
|
+
'void [b(a), b(c), b(d)];' +
|
4761
|
+
'void [typeof e];' +
|
4762
|
+
'i: for (; 0 === Math.random();) {' +
|
4763
|
+
' if (42 === (new Date()).getMinutes()) {' +
|
4764
|
+
' continue i;' +
|
4765
|
+
' } else {' +
|
4766
|
+
' break i;' +
|
4767
|
+
' }' +
|
4768
|
+
'}' +
|
4769
|
+
'try {' +
|
4770
|
+
'} catch (f) {' +
|
4771
|
+
'} finally {' +
|
4772
|
+
'}' +
|
4773
|
+
'(function g(h) {' +
|
4774
|
+
'}());' +
|
4775
|
+
'void [{' +
|
4776
|
+
' i: 42,' +
|
4777
|
+
' "j": 42,' +
|
4778
|
+
' \'k\': 42' +
|
4779
|
+
'}];' +
|
4780
|
+
'void ["abcdefghijklmnopqrstuvwxyz"];',
|
4781
|
+
sOutput:
|
4782
|
+
'/*jshint shadow:true */' +
|
4783
|
+
'var a;' +
|
4784
|
+
'function b(i) {' +
|
4785
|
+
'}' +
|
4786
|
+
'for (var c; 0 === Math.random(););' +
|
4787
|
+
'for (var d in {});' +
|
4788
|
+
'(function() {' +
|
4789
|
+
' var i = "abcdefghijklmnopqrstuvwxyz";' +
|
4790
|
+
' void [i];' +
|
4791
|
+
' void [b(a), b(c), b(d)];' +
|
4792
|
+
' void [typeof e];' +
|
4793
|
+
' i: for (; 0 === Math.random();) {' +
|
4794
|
+
' if (42 === (new Date()).getMinutes()) {' +
|
4795
|
+
' continue i;' +
|
4796
|
+
' } else {' +
|
4797
|
+
' break i;' +
|
4798
|
+
' }' +
|
4799
|
+
' }' +
|
4800
|
+
' try {' +
|
4801
|
+
' } catch (f) {' +
|
4802
|
+
' } finally {' +
|
4803
|
+
' }' +
|
4804
|
+
' (function g(h) {' +
|
4805
|
+
' }());' +
|
4806
|
+
' void [{' +
|
4807
|
+
' i: 42,' +
|
4808
|
+
' "j": 42,' +
|
4809
|
+
' \'k\': 42' +
|
4810
|
+
' }];' +
|
4811
|
+
' void [i];' +
|
4812
|
+
'}());'
|
4813
|
+
},
|
4814
|
+
{
|
4815
|
+
sTitle:
|
4816
|
+
'Preservation of identifier names in nested function code.',
|
4817
|
+
sInput:
|
4818
|
+
'(function() {' +
|
4819
|
+
' void ["abcdefghijklmnopqrstuvwxyz"];' +
|
4820
|
+
' (function() {' +
|
4821
|
+
' var a;' +
|
4822
|
+
' for (var b; 0 === Math.random(););' +
|
4823
|
+
' for (var c in {});' +
|
4824
|
+
' void [typeof d];' +
|
4825
|
+
' h: for (; 0 === Math.random();) {' +
|
4826
|
+
' if (42 === (new Date()).getMinutes()) {' +
|
4827
|
+
' continue h;' +
|
4828
|
+
' } else {' +
|
4829
|
+
' break h;' +
|
4830
|
+
' }' +
|
4831
|
+
' }' +
|
4832
|
+
' try {' +
|
4833
|
+
' } catch (e) {' +
|
4834
|
+
' } finally {' +
|
4835
|
+
' }' +
|
4836
|
+
' (function f(g) {' +
|
4837
|
+
' }());' +
|
4838
|
+
' void [{' +
|
4839
|
+
' h: 42,' +
|
4840
|
+
' "i": 42,' +
|
4841
|
+
' \'j\': 42' +
|
4842
|
+
' }];' +
|
4843
|
+
' }());' +
|
4844
|
+
' void ["abcdefghijklmnopqrstuvwxyz"];' +
|
4845
|
+
'}());',
|
4846
|
+
sOutput:
|
4847
|
+
'(function() {' +
|
4848
|
+
' var h = "abcdefghijklmnopqrstuvwxyz";' +
|
4849
|
+
' void [h];' +
|
4850
|
+
' (function() {' +
|
4851
|
+
' var a;' +
|
4852
|
+
' for (var b; 0 === Math.random(););' +
|
4853
|
+
' for (var c in {});' +
|
4854
|
+
' void [typeof d];' +
|
4855
|
+
' h: for (; 0 === Math.random();) {' +
|
4856
|
+
' if (42 === (new Date()).getMinutes()) {' +
|
4857
|
+
' continue h;' +
|
4858
|
+
' } else {' +
|
4859
|
+
' break h;' +
|
4860
|
+
' }' +
|
4861
|
+
' }' +
|
4862
|
+
' try {' +
|
4863
|
+
' } catch (e) {' +
|
4864
|
+
' } finally {' +
|
4865
|
+
' }' +
|
4866
|
+
' (function f(g) {' +
|
4867
|
+
' }());' +
|
4868
|
+
' void [{' +
|
4869
|
+
' h: 42,' +
|
4870
|
+
' "i": 42,' +
|
4871
|
+
' \'j\': 42' +
|
4872
|
+
' }];' +
|
4873
|
+
' }());' +
|
4874
|
+
' void [h];' +
|
4875
|
+
'}());'
|
4876
|
+
},
|
4877
|
+
{
|
4878
|
+
sTitle:
|
4879
|
+
'Consolidation of a closure with other source elements.',
|
4880
|
+
sInput:
|
4881
|
+
'(function(foo) {' +
|
4882
|
+
'}("abcdefghijklmnopqrstuvwxyz"));' +
|
4883
|
+
'void ["abcdefghijklmnopqrstuvwxyz"];',
|
4884
|
+
sOutput:
|
4885
|
+
'(function() {' +
|
4886
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
4887
|
+
' (function(foo) {' +
|
4888
|
+
' })(a);' +
|
4889
|
+
' void [a];' +
|
4890
|
+
'}());'
|
4891
|
+
},
|
4892
|
+
{
|
4893
|
+
sTitle:
|
4894
|
+
'Consolidation of function code instead of a sole closure.',
|
4895
|
+
sInput:
|
4896
|
+
'(function(foo, bar) {' +
|
4897
|
+
' void ["abcdefghijklmnopqrstuvwxyz",' +
|
4898
|
+
' "abcdefghijklmnopqrstuvwxyz"];' +
|
4899
|
+
'}("abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"));',
|
4900
|
+
sOutput:
|
4901
|
+
'(function(foo, bar) {' +
|
4902
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
4903
|
+
' void [a, a];' +
|
4904
|
+
'}("abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"));'
|
4905
|
+
},
|
4906
|
+
// 11.1.5 Object Initialiser.
|
4907
|
+
{
|
4908
|
+
sTitle:
|
4909
|
+
'Preservation of property names of an object initialiser.',
|
4910
|
+
sInput:
|
4911
|
+
'var foo = {' +
|
4912
|
+
' abcdefghijklmnopqrstuvwxyz: 42,' +
|
4913
|
+
' "zyxwvutsrqponmlkjihgfedcba": 42,' +
|
4914
|
+
' \'mlkjihgfedcbanopqrstuvwxyz\': 42' +
|
4915
|
+
'};' +
|
4916
|
+
'void [' +
|
4917
|
+
' foo.abcdefghijklmnopqrstuvwxyz,' +
|
4918
|
+
' "zyxwvutsrqponmlkjihgfedcba",' +
|
4919
|
+
' \'mlkjihgfedcbanopqrstuvwxyz\'' +
|
4920
|
+
'];'
|
4921
|
+
},
|
4922
|
+
{
|
4923
|
+
sTitle:
|
4924
|
+
'Evaluation with regard to String values derived from identifier ' +
|
4925
|
+
'names used as property accessors.',
|
4926
|
+
sInput:
|
4927
|
+
'(function() {' +
|
4928
|
+
' var foo;' +
|
4929
|
+
' void [' +
|
4930
|
+
' Math.abcdefghij,' +
|
4931
|
+
' Math.abcdefghij,' +
|
4932
|
+
' Math.abcdefghi,' +
|
4933
|
+
' Math.abcdefghi' +
|
4934
|
+
' ];' +
|
4935
|
+
'}());',
|
4936
|
+
sOutput:
|
4937
|
+
'(function() {' +
|
4938
|
+
' var a = "abcdefghij", foo;' +
|
4939
|
+
' void [' +
|
4940
|
+
' Math[a],' +
|
4941
|
+
' Math[a],' +
|
4942
|
+
' Math.abcdefghi,' +
|
4943
|
+
' Math.abcdefghi' +
|
4944
|
+
' ];' +
|
4945
|
+
'}());'
|
4946
|
+
},
|
4947
|
+
// 11.2.1 Property Accessors.
|
4948
|
+
{
|
4949
|
+
sTitle:
|
4950
|
+
'Preservation of identifiers in the nonterminal MemberExpression.',
|
4951
|
+
sInput:
|
4952
|
+
'void [' +
|
4953
|
+
' Math.E,' +
|
4954
|
+
' Math.LN10,' +
|
4955
|
+
' Math.LN2,' +
|
4956
|
+
' Math.LOG2E,' +
|
4957
|
+
' Math.LOG10E,' +
|
4958
|
+
' Math.PI,' +
|
4959
|
+
' Math.SQRT1_2,' +
|
4960
|
+
' Math.SQRT2,' +
|
4961
|
+
' Math.abs,' +
|
4962
|
+
' Math.acos' +
|
4963
|
+
'];'
|
4964
|
+
},
|
4965
|
+
// 12.2 Variable Statement.
|
4966
|
+
{
|
4967
|
+
sTitle:
|
4968
|
+
'Preservation of the identifier of a variable that is being ' +
|
4969
|
+
'declared in a variable statement.',
|
4970
|
+
sInput:
|
4971
|
+
'(function() {' +
|
4972
|
+
' var abcdefghijklmnopqrstuvwxyz;' +
|
4973
|
+
' void [abcdefghijklmnopqrstuvwxyz];' +
|
4974
|
+
'}());'
|
4975
|
+
},
|
4976
|
+
{
|
4977
|
+
sTitle:
|
4978
|
+
'Exclusion of a variable statement in global code.',
|
4979
|
+
sInput:
|
4980
|
+
'void ["abcdefghijklmnopqrstuvwxyz"];' +
|
4981
|
+
'var foo = "abcdefghijklmnopqrstuvwxyz",' +
|
4982
|
+
' bar = "abcdefghijklmnopqrstuvwxyz";' +
|
4983
|
+
'void ["abcdefghijklmnopqrstuvwxyz"];'
|
4984
|
+
},
|
4985
|
+
{
|
4986
|
+
sTitle:
|
4987
|
+
'Exclusion of a variable statement in function code that ' +
|
4988
|
+
'contains a with statement.',
|
4989
|
+
sInput:
|
4990
|
+
'(function() {' +
|
4991
|
+
' with ({});' +
|
4992
|
+
' void ["abcdefghijklmnopqrstuvwxyz"];' +
|
4993
|
+
' var foo;' +
|
4994
|
+
' void ["abcdefghijklmnopqrstuvwxyz"];' +
|
4995
|
+
'}());'
|
4996
|
+
},
|
4997
|
+
{
|
4998
|
+
sTitle:
|
4999
|
+
'Exclusion of a variable statement in function code that ' +
|
5000
|
+
'contains a direct call to the eval function.',
|
5001
|
+
sInput:
|
5002
|
+
'/*jshint evil:true */' +
|
5003
|
+
'void [' +
|
5004
|
+
' function() {' +
|
5005
|
+
' eval("");' +
|
5006
|
+
' void ["abcdefghijklmnopqrstuvwxyz"];' +
|
5007
|
+
' var foo;' +
|
5008
|
+
' void ["abcdefghijklmnopqrstuvwxyz"];' +
|
5009
|
+
' }' +
|
5010
|
+
'];'
|
5011
|
+
},
|
5012
|
+
{
|
5013
|
+
sTitle:
|
5014
|
+
'Consolidation within a variable statement in global code.',
|
5015
|
+
sInput:
|
5016
|
+
'var foo = function() {' +
|
5017
|
+
' void ["abcdefghijklmnopqrstuvwxyz",' +
|
5018
|
+
' "abcdefghijklmnopqrstuvwxyz"];' +
|
5019
|
+
'};',
|
5020
|
+
sOutput:
|
5021
|
+
'var foo = function() {' +
|
5022
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5023
|
+
' void [a, a];' +
|
5024
|
+
'};'
|
5025
|
+
},
|
5026
|
+
{
|
5027
|
+
sTitle:
|
5028
|
+
'Consolidation within a variable statement excluded in function ' +
|
5029
|
+
'code due to the presence of a with statement.',
|
5030
|
+
sInput:
|
5031
|
+
'(function() {' +
|
5032
|
+
' with ({});' +
|
5033
|
+
' var foo = function() {' +
|
5034
|
+
' void ["abcdefghijklmnopqrstuvwxyz",' +
|
5035
|
+
' "abcdefghijklmnopqrstuvwxyz"];' +
|
5036
|
+
' };' +
|
5037
|
+
'}());',
|
5038
|
+
sOutput:
|
5039
|
+
'(function() {' +
|
5040
|
+
' with ({});' +
|
5041
|
+
' var foo = function() {' +
|
5042
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5043
|
+
' void [a, a];' +
|
5044
|
+
' };' +
|
5045
|
+
'}());'
|
5046
|
+
},
|
5047
|
+
{
|
5048
|
+
sTitle:
|
5049
|
+
'Consolidation within a variable statement excluded in function ' +
|
5050
|
+
'code due to the presence of a direct call to the eval function.',
|
5051
|
+
sInput:
|
5052
|
+
'/*jshint evil:true */' +
|
5053
|
+
'(function() {' +
|
5054
|
+
' eval("");' +
|
5055
|
+
' var foo = function() {' +
|
5056
|
+
' void ["abcdefghijklmnopqrstuvwxyz",' +
|
5057
|
+
' "abcdefghijklmnopqrstuvwxyz"];' +
|
5058
|
+
' };' +
|
5059
|
+
'}());',
|
5060
|
+
sOutput:
|
5061
|
+
'/*jshint evil:true */' +
|
5062
|
+
'(function() {' +
|
5063
|
+
' eval("");' +
|
5064
|
+
' var foo = function() {' +
|
5065
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5066
|
+
' void [a, a];' +
|
5067
|
+
' };' +
|
5068
|
+
'}());'
|
5069
|
+
},
|
5070
|
+
{
|
5071
|
+
sTitle:
|
5072
|
+
'Inclusion of a variable statement in function code that ' +
|
5073
|
+
'contains no with statement and no direct call to the eval ' +
|
5074
|
+
'function.',
|
5075
|
+
sInput:
|
5076
|
+
'(function() {' +
|
5077
|
+
' void ["abcdefghijklmnopqrstuvwxyz"];' +
|
5078
|
+
' var foo;' +
|
5079
|
+
' void ["abcdefghijklmnopqrstuvwxyz"];' +
|
5080
|
+
'}());',
|
5081
|
+
sOutput:
|
5082
|
+
'(function() {' +
|
5083
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5084
|
+
' void [a];' +
|
5085
|
+
' var foo;' +
|
5086
|
+
' void [a];' +
|
5087
|
+
'}());'
|
5088
|
+
},
|
5089
|
+
{
|
5090
|
+
sTitle:
|
5091
|
+
'Ignorance with regard to a variable statement in global code.',
|
5092
|
+
sInput:
|
5093
|
+
'var foo = "abcdefghijklmnopqrstuvwxyz";' +
|
5094
|
+
'void ["abcdefghijklmnopqrstuvwxyz",' +
|
5095
|
+
' "abcdefghijklmnopqrstuvwxyz"];',
|
5096
|
+
sOutput:
|
5097
|
+
'var foo = "abcdefghijklmnopqrstuvwxyz";' +
|
5098
|
+
'(function() {' +
|
5099
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5100
|
+
' void [a, a];' +
|
5101
|
+
'}());'
|
5102
|
+
},
|
5103
|
+
// 12.4 Expression Statement.
|
5104
|
+
{
|
5105
|
+
sTitle:
|
5106
|
+
'Preservation of identifiers in an expression statement.',
|
5107
|
+
sInput:
|
5108
|
+
'void [typeof abcdefghijklmnopqrstuvwxyz,' +
|
5109
|
+
' typeof abcdefghijklmnopqrstuvwxyz];'
|
5110
|
+
},
|
5111
|
+
// 12.6.3 The {@code for} Statement.
|
5112
|
+
{
|
5113
|
+
sTitle:
|
5114
|
+
'Preservation of identifiers in the variable declaration list of ' +
|
5115
|
+
'a for statement.',
|
5116
|
+
sInput:
|
5117
|
+
'for (var abcdefghijklmnopqrstuvwxyz; 0 === Math.random(););' +
|
5118
|
+
'for (var abcdefghijklmnopqrstuvwxyz; 0 === Math.random(););'
|
5119
|
+
},
|
5120
|
+
// 12.6.4 The {@code for-in} Statement.
|
5121
|
+
{
|
5122
|
+
sTitle:
|
5123
|
+
'Preservation of identifiers in the variable declaration list of ' +
|
5124
|
+
'a for-in statement.',
|
5125
|
+
sInput:
|
5126
|
+
'for (var abcdefghijklmnopqrstuvwxyz in {});' +
|
5127
|
+
'for (var abcdefghijklmnopqrstuvwxyz in {});'
|
5128
|
+
},
|
5129
|
+
// 12.7 The {@code continue} Statement.
|
5130
|
+
{
|
5131
|
+
sTitle:
|
5132
|
+
'Preservation of the identifier in a continue statement.',
|
5133
|
+
sInput:
|
5134
|
+
'abcdefghijklmnopqrstuvwxyz: for (; 0 === Math.random();) {' +
|
5135
|
+
' continue abcdefghijklmnopqrstuvwxyz;' +
|
5136
|
+
'}' +
|
5137
|
+
'abcdefghijklmnopqrstuvwxyz: for (; 0 === Math.random();) {' +
|
5138
|
+
' continue abcdefghijklmnopqrstuvwxyz;' +
|
5139
|
+
'}'
|
5140
|
+
},
|
5141
|
+
// 12.8 The {@code break} Statement.
|
5142
|
+
{
|
5143
|
+
sTitle:
|
5144
|
+
'Preservation of the identifier in a break statement.',
|
5145
|
+
sInput:
|
5146
|
+
'abcdefghijklmnopqrstuvwxyz: for (; 0 === Math.random();) {' +
|
5147
|
+
' break abcdefghijklmnopqrstuvwxyz;' +
|
5148
|
+
'}' +
|
5149
|
+
'abcdefghijklmnopqrstuvwxyz: for (; 0 === Math.random();) {' +
|
5150
|
+
' break abcdefghijklmnopqrstuvwxyz;' +
|
5151
|
+
'}'
|
5152
|
+
},
|
5153
|
+
// 12.9 The {@code return} Statement.
|
5154
|
+
{
|
5155
|
+
sTitle:
|
5156
|
+
'Exclusion of a return statement in function code that contains ' +
|
5157
|
+
'a with statement.',
|
5158
|
+
sInput:
|
5159
|
+
'(function() {' +
|
5160
|
+
' with ({});' +
|
5161
|
+
' void ["abcdefghijklmnopqrstuvwxyz"];' +
|
5162
|
+
' if (0 === Math.random()) {' +
|
5163
|
+
' return;' +
|
5164
|
+
' } else {' +
|
5165
|
+
' }' +
|
5166
|
+
' void ["abcdefghijklmnopqrstuvwxyz"];' +
|
5167
|
+
'}());'
|
5168
|
+
},
|
5169
|
+
{
|
5170
|
+
sTitle:
|
5171
|
+
'Exclusion of a return statement in function code that contains ' +
|
5172
|
+
'a direct call to the eval function.',
|
5173
|
+
sInput:
|
5174
|
+
'/*jshint evil:true */' +
|
5175
|
+
'(function() {' +
|
5176
|
+
' eval("");' +
|
5177
|
+
' void ["abcdefghijklmnopqrstuvwxyz"];' +
|
5178
|
+
' if (0 === Math.random()) {' +
|
5179
|
+
' return;' +
|
5180
|
+
' } else {' +
|
5181
|
+
' }' +
|
5182
|
+
' void ["abcdefghijklmnopqrstuvwxyz"];' +
|
5183
|
+
'}());'
|
5184
|
+
},
|
5185
|
+
{
|
5186
|
+
sTitle:
|
5187
|
+
'Consolidation within a return statement excluded in function ' +
|
5188
|
+
'code due to the presence of a with statement.',
|
5189
|
+
sInput:
|
5190
|
+
'(function() {' +
|
5191
|
+
' with ({});' +
|
5192
|
+
' return function() {' +
|
5193
|
+
' void ["abcdefghijklmnopqrstuvwxyz",' +
|
5194
|
+
' "abcdefghijklmnopqrstuvwxyz"];' +
|
5195
|
+
' };' +
|
5196
|
+
'}());',
|
5197
|
+
sOutput:
|
5198
|
+
'(function() {' +
|
5199
|
+
' with ({});' +
|
5200
|
+
' return function() {' +
|
5201
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5202
|
+
' void [a, a];' +
|
5203
|
+
' };' +
|
5204
|
+
'}());'
|
5205
|
+
},
|
5206
|
+
{
|
5207
|
+
sTitle:
|
5208
|
+
'Consolidation within a return statement excluded in function ' +
|
5209
|
+
'code due to the presence of a direct call to the eval function.',
|
5210
|
+
sInput:
|
5211
|
+
'/*jshint evil:true */' +
|
5212
|
+
'(function() {' +
|
5213
|
+
' eval("");' +
|
5214
|
+
' return function() {' +
|
5215
|
+
' void ["abcdefghijklmnopqrstuvwxyz",' +
|
5216
|
+
' "abcdefghijklmnopqrstuvwxyz"];' +
|
5217
|
+
' };' +
|
5218
|
+
'}());',
|
5219
|
+
sOutput:
|
5220
|
+
'/*jshint evil:true */' +
|
5221
|
+
'(function() {' +
|
5222
|
+
' eval("");' +
|
5223
|
+
' return function() {' +
|
5224
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5225
|
+
' void [a, a];' +
|
5226
|
+
' };' +
|
5227
|
+
'}());'
|
5228
|
+
},
|
5229
|
+
{
|
5230
|
+
sTitle:
|
5231
|
+
'Inclusion of a return statement in function code that contains ' +
|
5232
|
+
'no with statement and no direct call to the eval function.',
|
5233
|
+
sInput:
|
5234
|
+
'(function() {' +
|
5235
|
+
' void ["abcdefghijklmnopqrstuvwxyz"];' +
|
5236
|
+
' if (0 === Math.random()) {' +
|
5237
|
+
' return;' +
|
5238
|
+
' } else {' +
|
5239
|
+
' }' +
|
5240
|
+
' void ["abcdefghijklmnopqrstuvwxyz"];' +
|
5241
|
+
'}());',
|
5242
|
+
sOutput:
|
5243
|
+
'(function() {' +
|
5244
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5245
|
+
' void [a];' +
|
5246
|
+
' if (0 === Math.random()) {' +
|
5247
|
+
' return;' +
|
5248
|
+
' } else {' +
|
5249
|
+
' }' +
|
5250
|
+
' void [a];' +
|
5251
|
+
'}());'
|
5252
|
+
},
|
5253
|
+
// 12.10 The {@code with} Statement.
|
5254
|
+
{
|
5255
|
+
sTitle:
|
5256
|
+
'Preservation of the statement in a with statement.',
|
5257
|
+
sInput:
|
5258
|
+
'with ({}) {' +
|
5259
|
+
' void ["abcdefghijklmnopqrstuvwxyz",' +
|
5260
|
+
' "abcdefghijklmnopqrstuvwxyz"];' +
|
5261
|
+
'}'
|
5262
|
+
},
|
5263
|
+
{
|
5264
|
+
sTitle:
|
5265
|
+
'Exclusion of a with statement in the same syntactic code unit.',
|
5266
|
+
sInput:
|
5267
|
+
'void ["abcdefghijklmnopqrstuvwxyz"];' +
|
5268
|
+
'with ({' +
|
5269
|
+
' foo: "abcdefghijklmnopqrstuvwxyz",' +
|
5270
|
+
' bar: "abcdefghijklmnopqrstuvwxyz"' +
|
5271
|
+
'}) {' +
|
5272
|
+
' void ["abcdefghijklmnopqrstuvwxyz",' +
|
5273
|
+
' "abcdefghijklmnopqrstuvwxyz"];' +
|
5274
|
+
'}' +
|
5275
|
+
'void ["abcdefghijklmnopqrstuvwxyz"];'
|
5276
|
+
},
|
5277
|
+
{
|
5278
|
+
sTitle:
|
5279
|
+
'Exclusion of a with statement in nested function code.',
|
5280
|
+
sInput:
|
5281
|
+
'void ["abcdefghijklmnopqrstuvwxyz"];' +
|
5282
|
+
'(function() {' +
|
5283
|
+
' with ({' +
|
5284
|
+
' foo: "abcdefghijklmnopqrstuvwxyz",' +
|
5285
|
+
' bar: "abcdefghijklmnopqrstuvwxyz"' +
|
5286
|
+
' }) {' +
|
5287
|
+
' void ["abcdefghijklmnopqrstuvwxyz",' +
|
5288
|
+
' "abcdefghijklmnopqrstuvwxyz"];' +
|
5289
|
+
' }' +
|
5290
|
+
'}());' +
|
5291
|
+
'void ["abcdefghijklmnopqrstuvwxyz"];'
|
5292
|
+
},
|
5293
|
+
// 12.12 Labelled Statements.
|
5294
|
+
{
|
5295
|
+
sTitle:
|
5296
|
+
'Preservation of the label of a labelled statement.',
|
5297
|
+
sInput:
|
5298
|
+
'abcdefghijklmnopqrstuvwxyz: for (; 0 === Math.random(););' +
|
5299
|
+
'abcdefghijklmnopqrstuvwxyz: for (; 0 === Math.random(););'
|
5300
|
+
},
|
5301
|
+
// 12.14 The {@code try} Statement.
|
5302
|
+
{
|
5303
|
+
sTitle:
|
5304
|
+
'Preservation of the identifier in the catch clause of a try' +
|
5305
|
+
'statement.',
|
5306
|
+
sInput:
|
5307
|
+
'try {' +
|
5308
|
+
'} catch (abcdefghijklmnopqrstuvwxyz) {' +
|
5309
|
+
'} finally {' +
|
5310
|
+
'}' +
|
5311
|
+
'try {' +
|
5312
|
+
'} catch (abcdefghijklmnopqrstuvwxyz) {' +
|
5313
|
+
'} finally {' +
|
5314
|
+
'}'
|
5315
|
+
},
|
5316
|
+
// 13 Function Definition.
|
5317
|
+
{
|
5318
|
+
sTitle:
|
5319
|
+
'Preservation of the identifier of a function declaration.',
|
5320
|
+
sInput:
|
5321
|
+
'function abcdefghijklmnopqrstuvwxyz() {' +
|
5322
|
+
'}' +
|
5323
|
+
'void [abcdefghijklmnopqrstuvwxyz];'
|
5324
|
+
},
|
5325
|
+
{
|
5326
|
+
sTitle:
|
5327
|
+
'Preservation of the identifier of a function expression.',
|
5328
|
+
sInput:
|
5329
|
+
'void [' +
|
5330
|
+
' function abcdefghijklmnopqrstuvwxyz() {' +
|
5331
|
+
' },' +
|
5332
|
+
' function abcdefghijklmnopqrstuvwxyz() {' +
|
5333
|
+
' }' +
|
5334
|
+
'];'
|
5335
|
+
},
|
5336
|
+
{
|
5337
|
+
sTitle:
|
5338
|
+
'Preservation of a formal parameter of a function declaration.',
|
5339
|
+
sInput:
|
5340
|
+
'function foo(abcdefghijklmnopqrstuvwxyz) {' +
|
5341
|
+
'}' +
|
5342
|
+
'function bar(abcdefghijklmnopqrstuvwxyz) {' +
|
5343
|
+
'}'
|
5344
|
+
},
|
5345
|
+
{
|
5346
|
+
sTitle:
|
5347
|
+
'Preservation of a formal parameter in a function expression.',
|
5348
|
+
sInput:
|
5349
|
+
'void [' +
|
5350
|
+
' function(abcdefghijklmnopqrstuvwxyz) {' +
|
5351
|
+
' },' +
|
5352
|
+
' function(abcdefghijklmnopqrstuvwxyz) {' +
|
5353
|
+
' }' +
|
5354
|
+
'];'
|
5355
|
+
},
|
5356
|
+
{
|
5357
|
+
sTitle:
|
5358
|
+
'Exclusion of a function declaration.',
|
5359
|
+
sInput:
|
5360
|
+
'void ["abcdefghijklmnopqrstuvwxyz"];' +
|
5361
|
+
'function foo() {' +
|
5362
|
+
'}' +
|
5363
|
+
'void ["abcdefghijklmnopqrstuvwxyz"];'
|
5364
|
+
},
|
5365
|
+
{
|
5366
|
+
sTitle:
|
5367
|
+
'Consolidation within a function declaration.',
|
5368
|
+
sInput:
|
5369
|
+
'function foo() {' +
|
5370
|
+
' void ["abcdefghijklmnopqrstuvwxyz",' +
|
5371
|
+
' "abcdefghijklmnopqrstuvwxyz"];' +
|
5372
|
+
'}',
|
5373
|
+
sOutput:
|
5374
|
+
'function foo() {' +
|
5375
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5376
|
+
' void [a, a];' +
|
5377
|
+
'}'
|
5378
|
+
},
|
5379
|
+
// 14 Program.
|
5380
|
+
{
|
5381
|
+
sTitle:
|
5382
|
+
'Preservation of a program without source elements.',
|
5383
|
+
sInput:
|
5384
|
+
''
|
5385
|
+
},
|
5386
|
+
// 14.1 Directive Prologues and the Use Strict Directive.
|
5387
|
+
{
|
5388
|
+
sTitle:
|
5389
|
+
'Preservation of a Directive Prologue in global code.',
|
5390
|
+
sInput:
|
5391
|
+
'"abcdefghijklmnopqrstuvwxyz";' +
|
5392
|
+
'\'zyxwvutsrqponmlkjihgfedcba\';'
|
5393
|
+
},
|
5394
|
+
{
|
5395
|
+
sTitle:
|
5396
|
+
'Preservation of a Directive Prologue in a function declaration.',
|
5397
|
+
sInput:
|
5398
|
+
'function foo() {' +
|
5399
|
+
' "abcdefghijklmnopqrstuvwxyz";' +
|
5400
|
+
' \'zyxwvutsrqponmlkjihgfedcba\';' +
|
5401
|
+
'}'
|
5402
|
+
},
|
5403
|
+
{
|
5404
|
+
sTitle:
|
5405
|
+
'Preservation of a Directive Prologue in a function expression.',
|
5406
|
+
sInput:
|
5407
|
+
'void [' +
|
5408
|
+
' function() {' +
|
5409
|
+
' "abcdefghijklmnopqrstuvwxyz";' +
|
5410
|
+
' \'zyxwvutsrqponmlkjihgfedcba\';' +
|
5411
|
+
' }' +
|
5412
|
+
'];'
|
5413
|
+
},
|
5414
|
+
{
|
5415
|
+
sTitle:
|
5416
|
+
'Ignorance with regard to a Directive Prologue in global code.',
|
5417
|
+
sInput:
|
5418
|
+
'"abcdefghijklmnopqrstuvwxyz";' +
|
5419
|
+
'void ["abcdefghijklmnopqrstuvwxyz",' +
|
5420
|
+
' "abcdefghijklmnopqrstuvwxyz"];',
|
5421
|
+
sOutput:
|
5422
|
+
'"abcdefghijklmnopqrstuvwxyz";' +
|
5423
|
+
'(function() {' +
|
5424
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5425
|
+
' void [a, a];' +
|
5426
|
+
'}());'
|
5427
|
+
},
|
5428
|
+
{
|
5429
|
+
sTitle:
|
5430
|
+
'Ignorance with regard to a Directive Prologue in a function' +
|
5431
|
+
'declaration.',
|
5432
|
+
sInput:
|
5433
|
+
'function foo() {' +
|
5434
|
+
' "abcdefghijklmnopqrstuvwxyz";' +
|
5435
|
+
' void ["abcdefghijklmnopqrstuvwxyz",' +
|
5436
|
+
' "abcdefghijklmnopqrstuvwxyz"];' +
|
5437
|
+
'}',
|
5438
|
+
sOutput:
|
5439
|
+
'function foo() {' +
|
5440
|
+
' "abcdefghijklmnopqrstuvwxyz";' +
|
5441
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5442
|
+
' void [a, a];' +
|
5443
|
+
'}'
|
5444
|
+
},
|
5445
|
+
{
|
5446
|
+
sTitle:
|
5447
|
+
'Ignorance with regard to a Directive Prologue in a function' +
|
5448
|
+
'expression.',
|
5449
|
+
sInput:
|
5450
|
+
'(function() {' +
|
5451
|
+
' "abcdefghijklmnopqrstuvwxyz";' +
|
5452
|
+
' void ["abcdefghijklmnopqrstuvwxyz",' +
|
5453
|
+
' "abcdefghijklmnopqrstuvwxyz"];' +
|
5454
|
+
'}());',
|
5455
|
+
sOutput:
|
5456
|
+
'(function() {' +
|
5457
|
+
' "abcdefghijklmnopqrstuvwxyz";' +
|
5458
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5459
|
+
' void [a, a];' +
|
5460
|
+
'}());'
|
5461
|
+
},
|
5462
|
+
// 15.1 The Global Object.
|
5463
|
+
{
|
5464
|
+
sTitle:
|
5465
|
+
'Preservation of a property of the global object.',
|
5466
|
+
sInput:
|
5467
|
+
'void [undefined, undefined, undefined, undefined, undefined];'
|
5468
|
+
},
|
5469
|
+
// 15.1.2.1.1 Direct Call to Eval.
|
5470
|
+
{
|
5471
|
+
sTitle:
|
5472
|
+
'Exclusion of a direct call to the eval function in the same ' +
|
5473
|
+
'syntactic code unit.',
|
5474
|
+
sInput:
|
5475
|
+
'/*jshint evil:true */' +
|
5476
|
+
'void ["abcdefghijklmnopqrstuvwxyz"];' +
|
5477
|
+
'eval("");' +
|
5478
|
+
'void ["abcdefghijklmnopqrstuvwxyz"];'
|
5479
|
+
},
|
5480
|
+
{
|
5481
|
+
sTitle:
|
5482
|
+
'Exclusion of a direct call to the eval function in nested ' +
|
5483
|
+
'function code.',
|
5484
|
+
sInput:
|
5485
|
+
'/*jshint evil:true */' +
|
5486
|
+
'void ["abcdefghijklmnopqrstuvwxyz"];' +
|
5487
|
+
'(function() {' +
|
5488
|
+
' eval("");' +
|
5489
|
+
'}());' +
|
5490
|
+
'void ["abcdefghijklmnopqrstuvwxyz"];'
|
5491
|
+
},
|
5492
|
+
{
|
5493
|
+
sTitle:
|
5494
|
+
'Consolidation within a direct call to the eval function.',
|
5495
|
+
sInput:
|
5496
|
+
'/*jshint evil:true */' +
|
5497
|
+
'eval(function() {' +
|
5498
|
+
' void ["abcdefghijklmnopqrstuvwxyz",' +
|
5499
|
+
' "abcdefghijklmnopqrstuvwxyz"];' +
|
5500
|
+
'}());',
|
5501
|
+
sOutput:
|
5502
|
+
'/*jshint evil:true */' +
|
5503
|
+
'eval(function() {' +
|
5504
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5505
|
+
' void [a, a];' +
|
5506
|
+
'}());'
|
5507
|
+
},
|
5508
|
+
// Consolidation proper.
|
5509
|
+
{
|
5510
|
+
sTitle:
|
5511
|
+
'No consolidation if it does not result in a reduction of the ' +
|
5512
|
+
'number of source characters.',
|
5513
|
+
sInput:
|
5514
|
+
'(function() {' +
|
5515
|
+
' var foo;' +
|
5516
|
+
' void ["ab", "ab", "abc", "abc"];' +
|
5517
|
+
'}());'
|
5518
|
+
},
|
5519
|
+
{
|
5520
|
+
sTitle:
|
5521
|
+
'Identification of a range of source elements at the beginning ' +
|
5522
|
+
'of global code.',
|
5523
|
+
sInput:
|
5524
|
+
'/*jshint evil:true */' +
|
5525
|
+
'"abcdefghijklmnopqrstuvwxyz";' +
|
5526
|
+
'void ["abcdefghijklmnopqrstuvwxyz",' +
|
5527
|
+
' "abcdefghijklmnopqrstuvwxyz"];' +
|
5528
|
+
'eval("");',
|
5529
|
+
sOutput:
|
5530
|
+
'/*jshint evil:true */' +
|
5531
|
+
'"abcdefghijklmnopqrstuvwxyz";' +
|
5532
|
+
'(function() {' +
|
5533
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5534
|
+
' void [a, a];' +
|
5535
|
+
'}());' +
|
5536
|
+
'eval("");'
|
5537
|
+
},
|
5538
|
+
{
|
5539
|
+
sTitle:
|
5540
|
+
'Identification of a range of source elements in the middle of ' +
|
5541
|
+
'global code.',
|
5542
|
+
sInput:
|
5543
|
+
'/*jshint evil:true */' +
|
5544
|
+
'"abcdefghijklmnopqrstuvwxyz";' +
|
5545
|
+
'eval("");' +
|
5546
|
+
'void ["abcdefghijklmnopqrstuvwxyz",' +
|
5547
|
+
' "abcdefghijklmnopqrstuvwxyz"];' +
|
5548
|
+
'eval("");',
|
5549
|
+
sOutput:
|
5550
|
+
'/*jshint evil:true */' +
|
5551
|
+
'"abcdefghijklmnopqrstuvwxyz";' +
|
5552
|
+
'eval("");' +
|
5553
|
+
'(function() {' +
|
5554
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5555
|
+
' void [a, a];' +
|
5556
|
+
'}());' +
|
5557
|
+
'eval("");'
|
5558
|
+
},
|
5559
|
+
{
|
5560
|
+
sTitle:
|
5561
|
+
'Identification of a range of source elements at the end of ' +
|
5562
|
+
'global code.',
|
5563
|
+
sInput:
|
5564
|
+
'/*jshint evil:true */' +
|
5565
|
+
'"abcdefghijklmnopqrstuvwxyz";' +
|
5566
|
+
'eval("");' +
|
5567
|
+
'void ["abcdefghijklmnopqrstuvwxyz",' +
|
5568
|
+
' "abcdefghijklmnopqrstuvwxyz"];',
|
5569
|
+
sOutput:
|
5570
|
+
'/*jshint evil:true */' +
|
5571
|
+
'"abcdefghijklmnopqrstuvwxyz";' +
|
5572
|
+
'eval("");' +
|
5573
|
+
'(function() {' +
|
5574
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5575
|
+
' void [a, a];' +
|
5576
|
+
'}());'
|
5577
|
+
},
|
5578
|
+
{
|
5579
|
+
sTitle:
|
5580
|
+
'Identification of a range of source elements at the beginning ' +
|
5581
|
+
'of function code.',
|
5582
|
+
sInput:
|
5583
|
+
'/*jshint evil:true */' +
|
5584
|
+
'(function() {' +
|
5585
|
+
' "abcdefghijklmnopqrstuvwxyz";' +
|
5586
|
+
' void ["abcdefghijklmnopqrstuvwxyz",' +
|
5587
|
+
' "abcdefghijklmnopqrstuvwxyz"];' +
|
5588
|
+
' eval("");' +
|
5589
|
+
'}());',
|
5590
|
+
sOutput:
|
5591
|
+
'/*jshint evil:true */' +
|
5592
|
+
'(function() {' +
|
5593
|
+
' "abcdefghijklmnopqrstuvwxyz";' +
|
5594
|
+
' (function() {' +
|
5595
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5596
|
+
' void [a, a];' +
|
5597
|
+
' }());' +
|
5598
|
+
' eval("");' +
|
5599
|
+
'}());'
|
5600
|
+
},
|
5601
|
+
{
|
5602
|
+
sTitle:
|
5603
|
+
'Identification of a range of source elements in the middle of ' +
|
5604
|
+
'function code.',
|
5605
|
+
sInput:
|
5606
|
+
'/*jshint evil:true */' +
|
5607
|
+
'(function() {' +
|
5608
|
+
' "abcdefghijklmnopqrstuvwxyz";' +
|
5609
|
+
' eval("");' +
|
5610
|
+
' void ["abcdefghijklmnopqrstuvwxyz",' +
|
5611
|
+
' "abcdefghijklmnopqrstuvwxyz"];' +
|
5612
|
+
' eval("");' +
|
5613
|
+
'}());',
|
5614
|
+
sOutput:
|
5615
|
+
'/*jshint evil:true */' +
|
5616
|
+
'(function() {' +
|
5617
|
+
' "abcdefghijklmnopqrstuvwxyz";' +
|
5618
|
+
' eval("");' +
|
5619
|
+
' (function() {' +
|
5620
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5621
|
+
' void [a, a];' +
|
5622
|
+
' }());' +
|
5623
|
+
' eval("");' +
|
5624
|
+
'}());'
|
5625
|
+
},
|
5626
|
+
{
|
5627
|
+
sTitle:
|
5628
|
+
'Identification of a range of source elements at the end of ' +
|
5629
|
+
'function code.',
|
5630
|
+
sInput:
|
5631
|
+
'/*jshint evil:true */' +
|
5632
|
+
'(function() {' +
|
5633
|
+
' "abcdefghijklmnopqrstuvwxyz";' +
|
5634
|
+
' eval("");' +
|
5635
|
+
' void ["abcdefghijklmnopqrstuvwxyz",' +
|
5636
|
+
' "abcdefghijklmnopqrstuvwxyz"];' +
|
5637
|
+
'}());',
|
5638
|
+
sOutput:
|
5639
|
+
'/*jshint evil:true */' +
|
5640
|
+
'(function() {' +
|
5641
|
+
' "abcdefghijklmnopqrstuvwxyz";' +
|
5642
|
+
' eval("");' +
|
5643
|
+
' (function() {' +
|
5644
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5645
|
+
' void [a, a];' +
|
5646
|
+
' }());' +
|
5647
|
+
'}());'
|
5648
|
+
},
|
5649
|
+
{
|
5650
|
+
sTitle:
|
5651
|
+
'Evaluation with regard to String values of String literals and ' +
|
5652
|
+
'String values derived from identifier names used as property' +
|
5653
|
+
'accessors.',
|
5654
|
+
sInput:
|
5655
|
+
'(function() {' +
|
5656
|
+
' var foo;' +
|
5657
|
+
' void ["abcdefg", Math.abcdefg, "abcdef", Math.abcdef];' +
|
5658
|
+
'}());',
|
5659
|
+
sOutput:
|
5660
|
+
'(function() {' +
|
5661
|
+
' var a = "abcdefg", foo;' +
|
5662
|
+
' void [a, Math[a], "abcdef", Math.abcdef];' +
|
5663
|
+
'}());'
|
5664
|
+
},
|
5665
|
+
{
|
5666
|
+
sTitle:
|
5667
|
+
'Evaluation with regard to the necessity of adding a variable ' +
|
5668
|
+
'statement.',
|
5669
|
+
sInput:
|
5670
|
+
'/*jshint evil:true */' +
|
5671
|
+
'(function() {' +
|
5672
|
+
' void ["abcdefgh", "abcdefgh"];' +
|
5673
|
+
'}());' +
|
5674
|
+
'eval("");' +
|
5675
|
+
'(function() {' +
|
5676
|
+
' void ["abcdefg", "abcdefg"];' +
|
5677
|
+
'}());' +
|
5678
|
+
'eval("");' +
|
5679
|
+
'(function() {' +
|
5680
|
+
' var foo;' +
|
5681
|
+
' void ["abcd", "abcd"];' +
|
5682
|
+
'}());',
|
5683
|
+
sOutput:
|
5684
|
+
'/*jshint evil:true */' +
|
5685
|
+
'(function() {' +
|
5686
|
+
' var a = "abcdefgh";' +
|
5687
|
+
' void [a, a];' +
|
5688
|
+
'}());' +
|
5689
|
+
'eval("");' +
|
5690
|
+
'(function() {' +
|
5691
|
+
' void ["abcdefg", "abcdefg"];' +
|
5692
|
+
'}());' +
|
5693
|
+
'eval("");' +
|
5694
|
+
'(function() {' +
|
5695
|
+
' var a = "abcd", foo;' +
|
5696
|
+
' void [a, a];' +
|
5697
|
+
'}());'
|
5698
|
+
},
|
5699
|
+
{
|
5700
|
+
sTitle:
|
5701
|
+
'Evaluation with regard to the necessity of enclosing source ' +
|
5702
|
+
'elements.',
|
5703
|
+
sInput:
|
5704
|
+
'/*jshint evil:true */' +
|
5705
|
+
'void ["abcdefghijklmnopqrstuvwxy", "abcdefghijklmnopqrstuvwxy"];' +
|
5706
|
+
'eval("");' +
|
5707
|
+
'void ["abcdefghijklmnopqrstuvwx", "abcdefghijklmnopqrstuvwx"];' +
|
5708
|
+
'eval("");' +
|
5709
|
+
'(function() {' +
|
5710
|
+
' void ["abcdefgh", "abcdefgh"];' +
|
5711
|
+
'}());' +
|
5712
|
+
'(function() {' +
|
5713
|
+
' void ["abcdefghijklmnopqrstuvwxy",' +
|
5714
|
+
' "abcdefghijklmnopqrstuvwxy"];' +
|
5715
|
+
' eval("");' +
|
5716
|
+
' void ["abcdefghijklmnopqrstuvwx",' +
|
5717
|
+
' "abcdefghijklmnopqrstuvwx"];' +
|
5718
|
+
' eval("");' +
|
5719
|
+
' (function() {' +
|
5720
|
+
' void ["abcdefgh", "abcdefgh"];' +
|
5721
|
+
' }());' +
|
5722
|
+
'}());',
|
5723
|
+
sOutput:
|
5724
|
+
'/*jshint evil:true */' +
|
5725
|
+
'(function() {' +
|
5726
|
+
' var a = "abcdefghijklmnopqrstuvwxy";' +
|
5727
|
+
' void [a, a];' +
|
5728
|
+
'}());' +
|
5729
|
+
'eval("");' +
|
5730
|
+
'void ["abcdefghijklmnopqrstuvwx", "abcdefghijklmnopqrstuvwx"];' +
|
5731
|
+
'eval("");' +
|
5732
|
+
'(function() {' +
|
5733
|
+
' var a = "abcdefgh";' +
|
5734
|
+
' void [a, a];' +
|
5735
|
+
'}());' +
|
5736
|
+
'(function() {' +
|
5737
|
+
' (function() {' +
|
5738
|
+
' var a = "abcdefghijklmnopqrstuvwxy";' +
|
5739
|
+
' void [a, a];' +
|
5740
|
+
' }());' +
|
5741
|
+
' eval("");' +
|
5742
|
+
' void ["abcdefghijklmnopqrstuvwx", "abcdefghijklmnopqrstuvwx"];' +
|
5743
|
+
' eval("");' +
|
5744
|
+
' (function() {' +
|
5745
|
+
' var a = "abcdefgh";' +
|
5746
|
+
' void [a, a];' +
|
5747
|
+
' }());' +
|
5748
|
+
'}());'
|
5749
|
+
},
|
5750
|
+
{
|
5751
|
+
sTitle:
|
5752
|
+
'Employment of a closure while consolidating in global code.',
|
5753
|
+
sInput:
|
5754
|
+
'void ["abcdefghijklmnopqrstuvwxyz",' +
|
5755
|
+
' "abcdefghijklmnopqrstuvwxyz"];',
|
5756
|
+
sOutput:
|
5757
|
+
'(function() {' +
|
5758
|
+
' var a = "abcdefghijklmnopqrstuvwxyz";' +
|
5759
|
+
' void [a, a];' +
|
5760
|
+
'}());'
|
5761
|
+
},
|
5762
|
+
{
|
5763
|
+
sTitle:
|
5764
|
+
'Assignment of a shorter identifier to a value whose ' +
|
5765
|
+
'consolidation results in a greater reduction of the number of ' +
|
5766
|
+
'source characters.',
|
5767
|
+
sInput:
|
5768
|
+
'(function() {' +
|
5769
|
+
' var b, c, d, e, f, g, h, i, j, k, l, m,' +
|
5770
|
+
' n, o, p, q, r, s, t, u, v, w, x, y, z,' +
|
5771
|
+
' A, B, C, D, E, F, G, H, I, J, K, L, M,' +
|
5772
|
+
' N, O, P, Q, R, S, T, U, V, W, X, Y, Z,' +
|
5773
|
+
' $, _;' +
|
5774
|
+
' void ["abcde", "abcde", "edcba", "edcba", "edcba"];' +
|
5775
|
+
'}());',
|
5776
|
+
sOutput:
|
5777
|
+
'(function() {' +
|
5778
|
+
' var a = "edcba",' +
|
5779
|
+
' b, c, d, e, f, g, h, i, j, k, l, m,' +
|
5780
|
+
' n, o, p, q, r, s, t, u, v, w, x, y, z,' +
|
5781
|
+
' A, B, C, D, E, F, G, H, I, J, K, L, M,' +
|
5782
|
+
' N, O, P, Q, R, S, T, U, V, W, X, Y, Z,' +
|
5783
|
+
' $, _;' +
|
5784
|
+
' void ["abcde", "abcde", a, a, a];' +
|
5785
|
+
'}());'
|
5786
|
+
}
|
5787
|
+
].forEach(cAssert);
|
5788
|
+
}());
|
5789
|
+
}
|
5790
|
+
|
5791
|
+
/* Local Variables: */
|
5792
|
+
/* mode: js */
|
5793
|
+
/* coding: utf-8 */
|
5794
|
+
/* indent-tabs-mode: nil */
|
5795
|
+
/* tab-width: 2 */
|
5796
|
+
/* End: */
|
5797
|
+
/* vim: set ft=javascript fenc=utf-8 et ts=2 sts=2 sw=2: */
|
5798
|
+
/* :mode=javascript:noTabs=true:tabSize=2:indentSize=2:deepIndent=true: */
|
5799
|
+
|
5800
|
+
});
|
5801
|
+
define('uglifyjs/parse-js', ["exports"], function(exports) {
|
5802
|
+
|
3153
5803
|
/***********************************************************************
|
3154
5804
|
|
3155
5805
|
A JavaScript tokenizer / parser / beautifier / compressor.
|
@@ -3217,6 +5867,7 @@ var KEYWORDS = array_to_hash([
|
|
3217
5867
|
"catch",
|
3218
5868
|
"const",
|
3219
5869
|
"continue",
|
5870
|
+
"debugger",
|
3220
5871
|
"default",
|
3221
5872
|
"delete",
|
3222
5873
|
"do",
|
@@ -3245,7 +5896,6 @@ var RESERVED_WORDS = array_to_hash([
|
|
3245
5896
|
"byte",
|
3246
5897
|
"char",
|
3247
5898
|
"class",
|
3248
|
-
"debugger",
|
3249
5899
|
"double",
|
3250
5900
|
"enum",
|
3251
5901
|
"export",
|
@@ -3343,7 +5993,7 @@ var OPERATORS = array_to_hash([
|
|
3343
5993
|
|
3344
5994
|
var WHITESPACE_CHARS = array_to_hash(characters(" \u00a0\n\r\t\f\u000b\u200b\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000"));
|
3345
5995
|
|
3346
|
-
var PUNC_BEFORE_EXPRESSION = array_to_hash(characters("[{
|
5996
|
+
var PUNC_BEFORE_EXPRESSION = array_to_hash(characters("[{(,.;:"));
|
3347
5997
|
|
3348
5998
|
var PUNC_CHARS = array_to_hash(characters("[]{}(),;:"));
|
3349
5999
|
|
@@ -3638,10 +6288,10 @@ function tokenizer($TEXT) {
|
|
3638
6288
|
};
|
3639
6289
|
|
3640
6290
|
function read_name() {
|
3641
|
-
var backslash = false, name = "", ch;
|
6291
|
+
var backslash = false, name = "", ch, escaped = false, hex;
|
3642
6292
|
while ((ch = peek()) != null) {
|
3643
6293
|
if (!backslash) {
|
3644
|
-
if (ch == "\\") backslash = true, next();
|
6294
|
+
if (ch == "\\") escaped = backslash = true, next();
|
3645
6295
|
else if (is_identifier_char(ch)) name += next();
|
3646
6296
|
else break;
|
3647
6297
|
}
|
@@ -3653,6 +6303,10 @@ function tokenizer($TEXT) {
|
|
3653
6303
|
backslash = false;
|
3654
6304
|
}
|
3655
6305
|
}
|
6306
|
+
if (HOP(KEYWORDS, name) && escaped) {
|
6307
|
+
hex = name.charCodeAt(0).toString(16).toUpperCase();
|
6308
|
+
name = "\\u" + "0000".substr(hex.length) + hex + name.slice(1);
|
6309
|
+
}
|
3656
6310
|
return name;
|
3657
6311
|
};
|
3658
6312
|
|
@@ -4061,8 +6715,11 @@ function parse($TEXT, exigent_mode, embed_tokens) {
|
|
4061
6715
|
init = is("keyword", "var")
|
4062
6716
|
? (next(), var_(true))
|
4063
6717
|
: expression(true, true);
|
4064
|
-
if (is("operator", "in"))
|
6718
|
+
if (is("operator", "in")) {
|
6719
|
+
if (init[0] == "var" && init[1].length > 1)
|
6720
|
+
croak("Only one variable declaration allowed in for..in loop");
|
4065
6721
|
return for_in(init);
|
6722
|
+
}
|
4066
6723
|
}
|
4067
6724
|
return regular_for(init);
|
4068
6725
|
};
|
@@ -4540,6 +7197,10 @@ function ast_squeeze_more(ast) {
|
|
4540
7197
|
}
|
4541
7198
|
},
|
4542
7199
|
"call": function(expr, args) {
|
7200
|
+
if (expr[0] == "dot" && expr[1][0] == "string" && args.length == 1
|
7201
|
+
&& (args[0][1] > 0 && expr[2] == "substring" || expr[2] == "substr")) {
|
7202
|
+
return [ "call", [ "dot", expr[1], "slice"], args];
|
7203
|
+
}
|
4543
7204
|
if (expr[0] == "dot" && expr[2] == "toString" && args.length == 0) {
|
4544
7205
|
// foo.toString() ==> foo+""
|
4545
7206
|
return [ "binary", "+", expr[1], [ "string", "" ]];
|
@@ -4706,6 +7367,9 @@ function ast_walker() {
|
|
4706
7367
|
"function": function(name, args, body) {
|
4707
7368
|
return [ this[0], name, args.slice(), MAP(body, walk) ];
|
4708
7369
|
},
|
7370
|
+
"debugger": function() {
|
7371
|
+
return [ this[0] ];
|
7372
|
+
},
|
4709
7373
|
"defun": function(name, args, body) {
|
4710
7374
|
return [ this[0], name, args.slice(), MAP(body, walk) ];
|
4711
7375
|
},
|
@@ -4849,12 +7513,13 @@ function Scope(parent) {
|
|
4849
7513
|
};
|
4850
7514
|
|
4851
7515
|
var base54 = (function(){
|
4852
|
-
var DIGITS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$
|
7516
|
+
var DIGITS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789";
|
4853
7517
|
return function(num) {
|
4854
|
-
var ret = "";
|
7518
|
+
var ret = "", base = 54;
|
4855
7519
|
do {
|
4856
|
-
ret
|
4857
|
-
num = Math.floor(num /
|
7520
|
+
ret += DIGITS.charAt(num % base);
|
7521
|
+
num = Math.floor(num / base);
|
7522
|
+
base = 64;
|
4858
7523
|
} while (num > 0);
|
4859
7524
|
return ret;
|
4860
7525
|
};
|
@@ -5308,7 +7973,9 @@ var when_constant = (function(){
|
|
5308
7973
|
case "string": ast = [ "string", val ]; break;
|
5309
7974
|
case "number": ast = [ "num", val ]; break;
|
5310
7975
|
case "boolean": ast = [ "name", String(val) ]; break;
|
5311
|
-
default:
|
7976
|
+
default:
|
7977
|
+
if (val === null) { ast = [ "atom", "null" ]; break; }
|
7978
|
+
throw new Error("Can't handle constant of type: " + (typeof val));
|
5312
7979
|
}
|
5313
7980
|
return yes.call(expr, ast, val);
|
5314
7981
|
} catch(ex) {
|
@@ -5377,17 +8044,15 @@ function prepare_ifs(ast) {
|
|
5377
8044
|
|
5378
8045
|
var conditional = walk(fi[1]);
|
5379
8046
|
|
5380
|
-
var e_body = statements.slice(i + 1);
|
8047
|
+
var e_body = redo_if(statements.slice(i + 1));
|
5381
8048
|
var e = e_body.length == 1 ? e_body[0] : [ "block", e_body ];
|
5382
8049
|
|
5383
|
-
|
8050
|
+
return statements.slice(0, i).concat([ [
|
5384
8051
|
fi[0], // "if"
|
5385
8052
|
conditional, // conditional
|
5386
8053
|
t, // then
|
5387
8054
|
e // else
|
5388
8055
|
] ]);
|
5389
|
-
|
5390
|
-
return redo_if(ret);
|
5391
8056
|
}
|
5392
8057
|
|
5393
8058
|
return statements;
|
@@ -5752,6 +8417,16 @@ function ast_squeeze(ast, options) {
|
|
5752
8417
|
});
|
5753
8418
|
};
|
5754
8419
|
|
8420
|
+
function abort_else(c, t, e) {
|
8421
|
+
var ret = [ [ "if", negate(c), e ] ];
|
8422
|
+
if (t[0] == "block") {
|
8423
|
+
if (t[1]) ret = ret.concat(t[1]);
|
8424
|
+
} else {
|
8425
|
+
ret.push(t);
|
8426
|
+
}
|
8427
|
+
return walk([ "block", ret ]);
|
8428
|
+
};
|
8429
|
+
|
5755
8430
|
function make_real_if(c, t, e) {
|
5756
8431
|
c = walk(c);
|
5757
8432
|
t = walk(t);
|
@@ -5785,9 +8460,10 @@ function ast_squeeze(ast, options) {
|
|
5785
8460
|
}
|
5786
8461
|
else if (t[0] == "stat") {
|
5787
8462
|
if (e) {
|
5788
|
-
if (e[0] == "stat")
|
8463
|
+
if (e[0] == "stat")
|
5789
8464
|
ret = best_of(ret, [ "stat", make_conditional(c, t[1], e[1]) ]);
|
5790
|
-
|
8465
|
+
else if (aborts(e))
|
8466
|
+
ret = abort_else(c, t, e);
|
5791
8467
|
}
|
5792
8468
|
else {
|
5793
8469
|
ret = best_of(ret, [ "stat", make_conditional(c, t[1]) ]);
|
@@ -5807,13 +8483,7 @@ function ast_squeeze(ast, options) {
|
|
5807
8483
|
ret = walk([ "block", ret ]);
|
5808
8484
|
}
|
5809
8485
|
else if (t && aborts(e)) {
|
5810
|
-
ret =
|
5811
|
-
if (t[0] == "block") {
|
5812
|
-
if (t[1]) ret = ret.concat(t[1]);
|
5813
|
-
} else {
|
5814
|
-
ret.push(t);
|
5815
|
-
}
|
5816
|
-
ret = walk([ "block", ret ]);
|
8486
|
+
ret = abort_else(c, t, e);
|
5817
8487
|
}
|
5818
8488
|
return ret;
|
5819
8489
|
};
|
@@ -5945,7 +8615,6 @@ function make_string(str, ascii_only) {
|
|
5945
8615
|
case "\f": return "\\f";
|
5946
8616
|
case "\n": return "\\n";
|
5947
8617
|
case "\r": return "\\r";
|
5948
|
-
case "\t": return "\\t";
|
5949
8618
|
case "\u2028": return "\\u2028";
|
5950
8619
|
case "\u2029": return "\\u2029";
|
5951
8620
|
case '"': ++dq; return '"';
|
@@ -6106,6 +8775,7 @@ function gen_code(ast, options) {
|
|
6106
8775
|
"string": encode_string,
|
6107
8776
|
"num": make_num,
|
6108
8777
|
"name": make_name,
|
8778
|
+
"debugger": function(){ return "debugger" },
|
6109
8779
|
"toplevel": function(statements) {
|
6110
8780
|
return make_block_statements(statements)
|
6111
8781
|
.join(newline + newline);
|
@@ -6189,7 +8859,7 @@ function gen_code(ast, options) {
|
|
6189
8859
|
if (expr[0] == "num") {
|
6190
8860
|
if (!/\./.test(expr[1]))
|
6191
8861
|
out += ".";
|
6192
|
-
} else if (needs_parens(expr))
|
8862
|
+
} else if (expr[0] != "function" && needs_parens(expr))
|
6193
8863
|
out = "(" + out + ")";
|
6194
8864
|
while (i < arguments.length)
|
6195
8865
|
out += "." + make_name(arguments[i++]);
|
@@ -6287,7 +8957,7 @@ function gen_code(ast, options) {
|
|
6287
8957
|
if (p.length == 3) {
|
6288
8958
|
// getter/setter. The name is in p[0], the arg.list in p[1][2], the
|
6289
8959
|
// body in p[1][3] and type ("get" / "set") in p[2].
|
6290
|
-
return indent(make_function(p[0], p[1][2], p[1][3], p[2]));
|
8960
|
+
return indent(make_function(p[0], p[1][2], p[1][3], p[2], true));
|
6291
8961
|
}
|
6292
8962
|
var key = p[0], val = parenthesize(p[1], "seq");
|
6293
8963
|
if (options.quote_keys) {
|
@@ -6364,14 +9034,14 @@ function gen_code(ast, options) {
|
|
6364
9034
|
return make(th);
|
6365
9035
|
};
|
6366
9036
|
|
6367
|
-
function make_function(name, args, body, keyword) {
|
9037
|
+
function make_function(name, args, body, keyword, no_parens) {
|
6368
9038
|
var out = keyword || "function";
|
6369
9039
|
if (name) {
|
6370
9040
|
out += " " + make_name(name);
|
6371
9041
|
}
|
6372
9042
|
out += "(" + add_commas(MAP(args, make_name)) + ")";
|
6373
9043
|
out = add_spaces([ out, make_block(body) ]);
|
6374
|
-
return needs_parens(this) ? "(" + out + ")" : out;
|
9044
|
+
return (!no_parens && needs_parens(this)) ? "(" + out + ")" : out;
|
6375
9045
|
};
|
6376
9046
|
|
6377
9047
|
function must_has_semicolon(node) {
|
@@ -6568,7 +9238,7 @@ exports.MAP = MAP;
|
|
6568
9238
|
// keep this last!
|
6569
9239
|
exports.ast_squeeze_more = require("./squeeze-more").ast_squeeze_more;
|
6570
9240
|
|
6571
|
-
});define('uglifyjs/index', ["require", "exports", "module", "./parse-js", "./process"], function(require, exports, module) {
|
9241
|
+
});define('uglifyjs/index', ["require", "exports", "module", "./parse-js", "./process", "./consolidator"], function(require, exports, module) {
|
6572
9242
|
|
6573
9243
|
//convienence function(src, [options]);
|
6574
9244
|
function uglify(orig_code, options){
|
@@ -6585,6 +9255,7 @@ function uglify(orig_code, options){
|
|
6585
9255
|
|
6586
9256
|
uglify.parser = require("./parse-js");
|
6587
9257
|
uglify.uglify = require("./process");
|
9258
|
+
uglify.consolidator = require("./consolidator");
|
6588
9259
|
|
6589
9260
|
module.exports = uglify
|
6590
9261
|
|
@@ -7817,6 +10488,7 @@ function (lang, logger, envOptimize, file, parse,
|
|
7817
10488
|
|
7818
10489
|
var optimize,
|
7819
10490
|
cssImportRegExp = /\@import\s+(url\()?\s*([^);]+)\s*(\))?([\w, ]*)(;)?/g,
|
10491
|
+
cssCommentImportRegExp = /\/\*[^\*]*@import[^\*]*\*\//g,
|
7820
10492
|
cssUrlRegExp = /\url\(\s*([^\)]+)\s*\)?/g;
|
7821
10493
|
|
7822
10494
|
/**
|
@@ -7840,24 +10512,30 @@ function (lang, logger, envOptimize, file, parse,
|
|
7840
10512
|
|
7841
10513
|
/**
|
7842
10514
|
* Inlines nested stylesheets that have @import calls in them.
|
7843
|
-
* @param {String} fileName
|
7844
|
-
* @param {String} fileContents
|
7845
|
-
* @param {String}
|
10515
|
+
* @param {String} fileName the file name
|
10516
|
+
* @param {String} fileContents the file contents
|
10517
|
+
* @param {String} cssImportIgnore comma delimited string of files to ignore
|
10518
|
+
* @param {Object} included an object used to track the files already imported
|
7846
10519
|
*/
|
7847
|
-
function flattenCss(fileName, fileContents, cssImportIgnore) {
|
10520
|
+
function flattenCss(fileName, fileContents, cssImportIgnore, included) {
|
7848
10521
|
//Find the last slash in the name.
|
7849
10522
|
fileName = fileName.replace(lang.backSlashRegExp, "/");
|
7850
10523
|
var endIndex = fileName.lastIndexOf("/"),
|
7851
10524
|
//Make a file path based on the last slash.
|
7852
10525
|
//If no slash, so must be just a file name. Use empty string then.
|
7853
|
-
filePath = (endIndex !== -1) ? fileName.substring(0, endIndex + 1) : ""
|
10526
|
+
filePath = (endIndex !== -1) ? fileName.substring(0, endIndex + 1) : "",
|
10527
|
+
//store a list of merged files
|
10528
|
+
importList = [];
|
10529
|
+
|
10530
|
+
//First make a pass by removing an commented out @import calls.
|
10531
|
+
fileContents = fileContents.replace(cssCommentImportRegExp, '');
|
7854
10532
|
|
7855
10533
|
//Make sure we have a delimited ignore list to make matching faster
|
7856
10534
|
if (cssImportIgnore && cssImportIgnore.charAt(cssImportIgnore.length - 1) !== ",") {
|
7857
10535
|
cssImportIgnore += ",";
|
7858
10536
|
}
|
7859
10537
|
|
7860
|
-
|
10538
|
+
fileContents = fileContents.replace(cssImportRegExp, function (fullMatch, urlStart, importFileName, urlEnd, mediaTypes) {
|
7861
10539
|
//Only process media type "all" or empty media type rules.
|
7862
10540
|
if (mediaTypes && ((mediaTypes.replace(/^\s\s*/, '').replace(/\s\s*$/, '')) !== "all")) {
|
7863
10541
|
return fullMatch;
|
@@ -7879,10 +10557,21 @@ function (lang, logger, envOptimize, file, parse,
|
|
7879
10557
|
//and we will just skip that import.
|
7880
10558
|
var fullImportFileName = importFileName.charAt(0) === "/" ? importFileName : filePath + importFileName,
|
7881
10559
|
importContents = file.readFile(fullImportFileName), i,
|
7882
|
-
importEndIndex, importPath, fixedUrlMatch, colonIndex, parts;
|
10560
|
+
importEndIndex, importPath, fixedUrlMatch, colonIndex, parts, flat;
|
10561
|
+
|
10562
|
+
//Skip the file if it has already been included.
|
10563
|
+
if (included[fullImportFileName]) {
|
10564
|
+
return '';
|
10565
|
+
}
|
10566
|
+
included[fullImportFileName] = true;
|
7883
10567
|
|
7884
10568
|
//Make sure to flatten any nested imports.
|
7885
|
-
|
10569
|
+
flat = flattenCss(fullImportFileName, importContents, cssImportIgnore, included);
|
10570
|
+
importContents = flat.fileContents;
|
10571
|
+
|
10572
|
+
if (flat.importList.length) {
|
10573
|
+
importList.push.apply(importList, flat.importList);
|
10574
|
+
}
|
7886
10575
|
|
7887
10576
|
//Make the full import path
|
7888
10577
|
importEndIndex = importFileName.lastIndexOf("/");
|
@@ -7925,12 +10614,18 @@ function (lang, logger, envOptimize, file, parse,
|
|
7925
10614
|
return "url(" + parts.join("/") + ")";
|
7926
10615
|
});
|
7927
10616
|
|
10617
|
+
importList.push(fullImportFileName);
|
7928
10618
|
return importContents;
|
7929
10619
|
} catch (e) {
|
7930
|
-
logger.
|
10620
|
+
logger.warn(fileName + "\n Cannot inline css import, skipping: " + importFileName);
|
7931
10621
|
return fullMatch;
|
7932
10622
|
}
|
7933
10623
|
});
|
10624
|
+
|
10625
|
+
return {
|
10626
|
+
importList : importList,
|
10627
|
+
fileContents : fileContents
|
10628
|
+
};
|
7934
10629
|
}
|
7935
10630
|
|
7936
10631
|
optimize = {
|
@@ -7942,21 +10637,22 @@ function (lang, logger, envOptimize, file, parse,
|
|
7942
10637
|
* through an minifier if one is specified via config.optimize.
|
7943
10638
|
*
|
7944
10639
|
* @param {String} fileName the name of the file to optimize
|
10640
|
+
* @param {String} fileContents the contents to optimize. If this is
|
10641
|
+
* a null value, then fileName will be used to read the fileContents.
|
7945
10642
|
* @param {String} outFileName the name of the file to use for the
|
7946
10643
|
* saved optimized content.
|
7947
10644
|
* @param {Object} config the build config object.
|
7948
|
-
* @param {String} [moduleName] the module name to use for the file.
|
7949
|
-
* Used for plugin resource collection.
|
7950
10645
|
* @param {Array} [pluginCollector] storage for any plugin resources
|
7951
10646
|
* found.
|
7952
10647
|
*/
|
7953
|
-
jsFile: function (fileName, outFileName, config,
|
10648
|
+
jsFile: function (fileName, fileContents, outFileName, config, pluginCollector) {
|
7954
10649
|
var parts = (config.optimize + "").split('.'),
|
7955
10650
|
optimizerName = parts[0],
|
7956
|
-
keepLines = parts[1] === 'keepLines'
|
7957
|
-
fileContents;
|
10651
|
+
keepLines = parts[1] === 'keepLines';
|
7958
10652
|
|
7959
|
-
|
10653
|
+
if (!fileContents) {
|
10654
|
+
fileContents = file.readFile(fileName);
|
10655
|
+
}
|
7960
10656
|
|
7961
10657
|
fileContents = optimize.js(fileName, fileContents, optimizerName,
|
7962
10658
|
keepLines, config, pluginCollector);
|
@@ -8026,21 +10722,25 @@ function (lang, logger, envOptimize, file, parse,
|
|
8026
10722
|
* cssImportIgnore options.
|
8027
10723
|
*/
|
8028
10724
|
cssFile: function (fileName, outFileName, config) {
|
10725
|
+
|
8029
10726
|
//Read in the file. Make sure we have a JS string.
|
8030
10727
|
var originalFileContents = file.readFile(fileName),
|
8031
|
-
|
8032
|
-
|
10728
|
+
flat = flattenCss(fileName, originalFileContents, config.cssImportIgnore, {}),
|
10729
|
+
fileContents = flat.fileContents,
|
10730
|
+
startIndex, endIndex, buildText;
|
8033
10731
|
|
8034
10732
|
//Do comment removal.
|
8035
10733
|
try {
|
8036
|
-
|
8037
|
-
|
8038
|
-
|
8039
|
-
|
8040
|
-
|
8041
|
-
|
10734
|
+
if (config.optimizeCss.indexOf(".keepComments") === -1) {
|
10735
|
+
startIndex = -1;
|
10736
|
+
//Get rid of comments.
|
10737
|
+
while ((startIndex = fileContents.indexOf("/*")) !== -1) {
|
10738
|
+
endIndex = fileContents.indexOf("*/", startIndex + 2);
|
10739
|
+
if (endIndex === -1) {
|
10740
|
+
throw "Improper comment in CSS file: " + fileName;
|
10741
|
+
}
|
10742
|
+
fileContents = fileContents.substring(0, startIndex) + fileContents.substring(endIndex + 2, fileContents.length);
|
8042
10743
|
}
|
8043
|
-
fileContents = fileContents.substring(0, startIndex) + fileContents.substring(endIndex + 2, fileContents.length);
|
8044
10744
|
}
|
8045
10745
|
//Get rid of newlines.
|
8046
10746
|
if (config.optimizeCss.indexOf(".keepLines") === -1) {
|
@@ -8059,6 +10759,14 @@ function (lang, logger, envOptimize, file, parse,
|
|
8059
10759
|
}
|
8060
10760
|
|
8061
10761
|
file.saveUtf8File(outFileName, fileContents);
|
10762
|
+
|
10763
|
+
//text output to stdout and/or written to build.txt file
|
10764
|
+
buildText = "\n"+ outFileName.replace(config.dir, "") +"\n----------------\n";
|
10765
|
+
flat.importList.push(fileName);
|
10766
|
+
buildText += flat.importList.map(function(path){
|
10767
|
+
return path.replace(config.dir, "");
|
10768
|
+
}).join("\n");
|
10769
|
+
return buildText +"\n";
|
8062
10770
|
},
|
8063
10771
|
|
8064
10772
|
/**
|
@@ -8069,17 +10777,19 @@ function (lang, logger, envOptimize, file, parse,
|
|
8069
10777
|
* cssImportIgnore options.
|
8070
10778
|
*/
|
8071
10779
|
css: function (startDir, config) {
|
10780
|
+
var buildText = "",
|
10781
|
+
i, fileName, fileList;
|
8072
10782
|
if (config.optimizeCss.indexOf("standard") !== -1) {
|
8073
|
-
|
8074
|
-
fileList = file.getFilteredFileList(startDir, /\.css$/, true);
|
10783
|
+
fileList = file.getFilteredFileList(startDir, /\.css$/, true);
|
8075
10784
|
if (fileList) {
|
8076
10785
|
for (i = 0; i < fileList.length; i++) {
|
8077
10786
|
fileName = fileList[i];
|
8078
10787
|
logger.trace("Optimizing (" + config.optimizeCss + ") CSS file: " + fileName);
|
8079
|
-
optimize.cssFile(fileName, fileName, config);
|
10788
|
+
buildText += optimize.cssFile(fileName, fileName, config);
|
8080
10789
|
}
|
8081
10790
|
}
|
8082
10791
|
}
|
10792
|
+
return buildText;
|
8083
10793
|
},
|
8084
10794
|
|
8085
10795
|
optimizers: {
|
@@ -8702,7 +11412,7 @@ function (lang, logger, file, parse, optimize, pragma,
|
|
8702
11412
|
baseConfig, config,
|
8703
11413
|
modules, builtModule, srcPath, buildContext,
|
8704
11414
|
destPath, moduleName, moduleMap, parentModuleMap, context,
|
8705
|
-
resources, resource, pluginProcessed = {}, plugin;
|
11415
|
+
resources, resource, pluginProcessed = {}, plugin, fileContents;
|
8706
11416
|
|
8707
11417
|
//Can now run the patches to require.js to allow it to be used for
|
8708
11418
|
//build generation. Do it here instead of at the top of the module
|
@@ -8731,7 +11441,7 @@ function (lang, logger, file, parse, optimize, pragma,
|
|
8731
11441
|
//the paths to use the dirBaseUrl
|
8732
11442
|
for (prop in paths) {
|
8733
11443
|
if (paths.hasOwnProperty(prop)) {
|
8734
|
-
buildPaths[prop] = paths[prop].replace(config.
|
11444
|
+
buildPaths[prop] = paths[prop].replace(config.appDir, config.dir);
|
8735
11445
|
}
|
8736
11446
|
}
|
8737
11447
|
} else {
|
@@ -8831,7 +11541,7 @@ function (lang, logger, file, parse, optimize, pragma,
|
|
8831
11541
|
//things like text loader plugins loading CSS to get the optimized
|
8832
11542
|
//CSS.
|
8833
11543
|
if (config.optimizeCss && config.optimizeCss !== "none" && config.dir) {
|
8834
|
-
optimize.css(config.dir, config);
|
11544
|
+
buildFileContents += optimize.css(config.dir, config);
|
8835
11545
|
}
|
8836
11546
|
|
8837
11547
|
if (modules) {
|
@@ -8905,7 +11615,7 @@ function (lang, logger, file, parse, optimize, pragma,
|
|
8905
11615
|
if (config.out && !config.cssIn) {
|
8906
11616
|
//Just need to worry about one JS file.
|
8907
11617
|
fileName = config.modules[0]._buildPath;
|
8908
|
-
optimize.jsFile(fileName, fileName, config);
|
11618
|
+
optimize.jsFile(fileName, null, fileName, config);
|
8909
11619
|
} else if (!config.cssIn) {
|
8910
11620
|
//Normal optimizations across modules.
|
8911
11621
|
|
@@ -8916,7 +11626,18 @@ function (lang, logger, file, parse, optimize, pragma,
|
|
8916
11626
|
moduleName = fileName.replace(config.dir, '');
|
8917
11627
|
//Get rid of the extension
|
8918
11628
|
moduleName = moduleName.substring(0, moduleName.length - 3);
|
8919
|
-
|
11629
|
+
|
11630
|
+
//Convert the file to transport format, but without a name
|
11631
|
+
//inserted (by passing null for moduleName) since the files are
|
11632
|
+
//standalone, one module per file.
|
11633
|
+
fileContents = file.readFile(fileName);
|
11634
|
+
fileContents = build.toTransport(config.anonDefRegExp,
|
11635
|
+
config.namespaceWithDot,
|
11636
|
+
null,
|
11637
|
+
fileName,
|
11638
|
+
fileContents);
|
11639
|
+
|
11640
|
+
optimize.jsFile(fileName, fileContents, fileName, config, pluginCollector);
|
8920
11641
|
}
|
8921
11642
|
|
8922
11643
|
//Normalize all the plugin resources.
|
@@ -8984,7 +11705,7 @@ function (lang, logger, file, parse, optimize, pragma,
|
|
8984
11705
|
|
8985
11706
|
//If just have one CSS file to optimize, do that here.
|
8986
11707
|
if (config.cssIn) {
|
8987
|
-
optimize.cssFile(config.cssIn, config.out, config);
|
11708
|
+
buildFileContents += optimize.cssFile(config.cssIn, config.out, config);
|
8988
11709
|
}
|
8989
11710
|
|
8990
11711
|
//Print out what was built into which layers.
|
@@ -9229,6 +11950,9 @@ function (lang, logger, file, parse, optimize, pragma,
|
|
9229
11950
|
mainConfigFile = config.mainConfigFile || (buildFileConfig && buildFileConfig.mainConfigFile);
|
9230
11951
|
if (mainConfigFile) {
|
9231
11952
|
mainConfigFile = build.makeAbsPath(mainConfigFile, absFilePath);
|
11953
|
+
if (!file.exists(mainConfigFile)) {
|
11954
|
+
throw new Error(mainConfigFile + ' does not exist.');
|
11955
|
+
}
|
9232
11956
|
try {
|
9233
11957
|
mainConfig = parse.findConfig(mainConfigFile, file.readFile(mainConfigFile));
|
9234
11958
|
} catch (configError) {
|
@@ -9382,6 +12106,9 @@ function (lang, logger, file, parse, optimize, pragma,
|
|
9382
12106
|
file.exclusionRegExp = config.dirExclusionRegExp;
|
9383
12107
|
}
|
9384
12108
|
|
12109
|
+
//Remove things that may cause problems in the build.
|
12110
|
+
delete config.jQuery;
|
12111
|
+
|
9385
12112
|
return config;
|
9386
12113
|
};
|
9387
12114
|
|
@@ -9633,7 +12360,8 @@ function (lang, logger, file, parse, optimize, pragma,
|
|
9633
12360
|
layer.modulesWithNames[moduleName] = true;
|
9634
12361
|
}
|
9635
12362
|
|
9636
|
-
var deps = null
|
12363
|
+
var deps = null,
|
12364
|
+
finalName;
|
9637
12365
|
|
9638
12366
|
//Look for CommonJS require calls inside the function if this is
|
9639
12367
|
//an anonymous define call that just has a function registered.
|
@@ -9651,7 +12379,12 @@ function (lang, logger, file, parse, optimize, pragma,
|
|
9651
12379
|
}
|
9652
12380
|
}
|
9653
12381
|
|
9654
|
-
|
12382
|
+
finalName = namedModule || moduleName || '';
|
12383
|
+
if (finalName) {
|
12384
|
+
finalName = "'" + (namedModule || moduleName) + "',";
|
12385
|
+
}
|
12386
|
+
|
12387
|
+
return start + namespace + "define(" + finalName +
|
9655
12388
|
(deps ? ('[' + deps.toString() + '],') : '') +
|
9656
12389
|
(namedModule ? namedFuncStart.replace(build.leadingCommaRegExp, '') : suffix);
|
9657
12390
|
});
|
@@ -9734,7 +12467,9 @@ function (lang, logger, file, parse, optimize, pragma,
|
|
9734
12467
|
}
|
9735
12468
|
|
9736
12469
|
var req = requirejs({
|
9737
|
-
context: contextName
|
12470
|
+
context: contextName,
|
12471
|
+
requireLoad: requirejsVars.nodeLoad,
|
12472
|
+
requireExecCb: requirejsVars.nodeRequireExecCb
|
9738
12473
|
});
|
9739
12474
|
|
9740
12475
|
req(['build'], function () {
|