requirejs-rails 0.7.2 → 0.7.3
Sign up to get free protection for your applications and to get access to all the features.
- 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 () {
|