1/** 2 * @license r.js 2.3.7 Copyright jQuery Foundation and other contributors. 3 * Released under MIT license, http://github.com/requirejs/r.js/LICENSE 4 */ 5 6/* 7 * This is a bootstrap script to allow running RequireJS in the command line 8 * in either a Java/Rhino or Node environment. It is modified by the top-level 9 * dist.js file to inject other files to completely enable this file. It is 10 * the shell of the r.js file. 11 */ 12 13/*jslint evil: true, nomen: true, sloppy: true */ 14/*global readFile: true, process: false, Packages: false, print: false, 15console: false, java: false, module: false, requirejsVars, navigator, 16document, importScripts, self, location, Components, FileUtils */ 17 18var requirejs, require, define, xpcUtil; 19(function (console, args, readFileFunc) { 20 var fileName, env, fs, vm, path, exec, rhinoContext, dir, nodeRequire, 21 nodeDefine, exists, reqMain, loadedOptimizedLib, existsForNode, Cc, Ci, 22 version = '2.3.7', 23 jsSuffixRegExp = /\.js$/, 24 commandOption = '', 25 useLibLoaded = {}, 26 //Used by jslib/rhino/args.js 27 rhinoArgs = args, 28 //Used by jslib/xpconnect/args.js 29 xpconnectArgs = args, 30 readFile = typeof readFileFunc !== 'undefined' ? readFileFunc : null; 31 32 function showHelp() { 33 console.log('See https://github.com/requirejs/r.js for usage.'); 34 } 35 36 if (typeof process !== 'undefined' && process.versions && !!process.versions.node) { 37 env = 'node'; 38 39 //Get the fs module via Node's require before it 40 //gets replaced. Used in require/node.js 41 fs = require('fs'); 42 vm = require('vm'); 43 path = require('path'); 44 //In Node 0.7+ existsSync is on fs. 45 existsForNode = fs.existsSync || path.existsSync; 46 47 nodeRequire = require; 48 nodeDefine = define; 49 reqMain = require.main; 50 51 //Temporarily hide require and define to allow require.js to define 52 //them. 53 require = undefined; 54 define = undefined; 55 56 readFile = function (path) { 57 return fs.readFileSync(path, 'utf8'); 58 }; 59 60 exec = function (string, name) { 61 return vm.runInThisContext(this.requirejsVars.require.makeNodeWrapper(string), 62 name ? fs.realpathSync(name) : ''); 63 }; 64 65 exists = function (fileName) { 66 return existsForNode(fileName); 67 }; 68 69 70 fileName = process.argv[2]; 71 72 if (fileName && fileName.indexOf('-') === 0) { 73 commandOption = fileName.substring(1); 74 fileName = process.argv[3]; 75 } 76 } else if (typeof Packages !== 'undefined') { 77 env = 'rhino'; 78 79 fileName = args[0]; 80 81 if (fileName && fileName.indexOf('-') === 0) { 82 commandOption = fileName.substring(1); 83 fileName = args[1]; 84 } 85 86 //Exec/readFile differs between Rhino and Nashorn. Rhino has an 87 //importPackage where Nashorn does not, so branch on that. This is a 88 //coarser check -- detecting readFile existence might also be enough for 89 //this spot. However, sticking with importPackage to keep it the same 90 //as other Rhino/Nashorn detection branches. 91 if (typeof importPackage !== 'undefined') { 92 rhinoContext = Packages.org.mozilla.javascript.ContextFactory.getGlobal().enterContext(); 93 94 exec = function (string, name) { 95 return rhinoContext.evaluateString(this, string, name, 0, null); 96 }; 97 } else { 98 exec = function (string, name) { 99 load({ script: string, name: name}); 100 }; 101 readFile = readFully; 102 } 103 104 exists = function (fileName) { 105 return (new java.io.File(fileName)).exists();
106 }; 107 108 //Define a console.log for easier logging. Don't 109 //get fancy though. 110 if (typeof console === 'undefined') { 111 console = { 112 log: function () { 113 print.apply(undefined, arguments); 114 } 115 }; 116 } 117 } else if ((typeof navigator !== 'undefined' && typeof document !== 'undefined') || 118 (typeof importScripts !== 'undefined' && typeof self !== 'undefined')) { 119 env = 'browser'; 120 121 readFile = function (path) { 122 return fs.readFileSync(path, 'utf8'); 123 }; 124 125 exec = function (string) { 126 return eval(string); 127 }; 128 129 exists = function () { 130 console.log('x.js exists not applicable in browser env'); 131 return false; 132 }; 133 134 } else if (typeof Components !== 'undefined' && Components.classes && Components.interfaces) { 135 env = 'xpconnect'; 136 137 Components.utils['import']('resource://gre/modules/FileUtils.jsm'); 138 Cc = Components.classes; 139 Ci = Components.interfaces; 140 141 fileName = args[0]; 142 143 if (fileName && fileName.indexOf('-') === 0) { 144 commandOption = fileName.substring(1); 145 fileName = args[1]; 146 } 147 148 xpcUtil = { 149 isWindows: ('@mozilla.org/windows-registry-key;1' in Cc), 150 cwd: function () { 151 return FileUtils.getFile("CurWorkD", []).path; 152 }, 153 154 //Remove . and .. from paths, normalize on front slashes 155 normalize: function (path) { 156 //There has to be an easier way to do this. 157 var i, part, ary, 158 firstChar = path.charAt(0); 159 160 if (firstChar !== '/' && 161 firstChar !== '\\' && 162 path.indexOf(':') === -1) { 163 //A relative path. Use the current working directory. 164 path = xpcUtil.cwd() + '/' + path; 165 } 166 167 ary = path.replace(/\\/g, '/').split('/'); 168 169 for (i = 0; i < ary.length; i += 1) { 170 part = ary[i]; 171 if (part === '.') { 172 ary.splice(i, 1); 173 i -= 1; 174 } else if (part === '..') { 175 ary.splice(i - 1, 2); 176 i -= 2; 177 } 178 } 179 return ary.join('/'); 180 }, 181 182 xpfile: function (path) { 183 var fullPath; 184 try { 185 fullPath = xpcUtil.normalize(path); 186 if (xpcUtil.isWindows) { 187 fullPath = fullPath.replace(/\//g, '\\'); 188 } 189 return new FileUtils.File(fullPath); 190 } catch (e) { 191 throw new Error((fullPath || path) + ' failed: ' + e); 192 } 193 }, 194 195 readFile: function (/*String*/path, /*String?*/encoding) { 196 //A file read function that can deal with BOMs 197 encoding = encoding || "utf-8"; 198 199 var inStream, convertStream, 200 readData = {}, 201 fileObj = xpcUtil.xpfile(path); 202 203 //XPCOM, you so crazy 204 try { 205 inStream = Cc['@mozilla.org/network/file-input-stream;1'] 206 .createInstance(Ci.nsIFileInputStream); 207 inStream.init(fileObj, 1, 0, false); 208 209 convertStream = Cc['@mozilla.org/intl/converter-input-stream;1'] 210 .createInstance(Ci.nsIConverterInputStream); 211 convertStream.init(inStream, encoding, inStream.available(), 212 Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER); 213 214 convertStream.readString(inStream.available(), readData); 215 return readData.value; 216 } catch (e) { 217 throw new Error((fileObj && fileObj.path || '') + ': ' + e); 218 } finally { 219 if (convertStream) { 220 convertStream.close(); 221 } 222 if (inStream) { 223 inStream.close(); 224 } 225 } 226 } 227 }; 228 229 readFile = xpcUtil.readFile; 230 231 exec = function (string) { 232 return eval(string); 233 }; 234 235 exists = function (fileName) { 236 return xpcUtil.xpfile(fileName).exists();
vendor: 86,212 bytes, lines 237-2327
237 }; 238 239 //Define a console.log for easier logging. Don't 240 //get fancy though. 241 if (typeof console === 'undefined') { 242 console = { 243 log: function () { 244 print.apply(undefined, arguments); 245 } 246 }; 247 } 248 } 249 250 /** vim: et:ts=4:sw=4:sts=4 251 * @license RequireJS 2.3.7 Copyright jQuery Foundation and other contributors. 252 * Released under MIT license, https://github.com/requirejs/requirejs/blob/master/LICENSE 253 */ 254//Not using strict: uneven strict support in browsers, #392, and causes 255//problems with requirejs.exec()/transpiler plugins that may not be strict. 256/*jslint regexp: true, nomen: true, sloppy: true */ 257/*global window, navigator, document, importScripts, setTimeout, opera */ 258 259 260(function (global, setTimeout) { 261 var req, s, head, baseElement, dataMain, src, 262 interactiveScript, currentlyAddingScript, mainScript, subPath, 263 version = '2.3.7', 264 commentRegExp = /\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/mg, 265 cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, 266 jsSuffixRegExp = /\.js$/, 267 currDirRegExp = /^\.\//, 268 op = Object.prototype, 269 ostring = op.toString, 270 hasOwn = op.hasOwnProperty, 271 isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document), 272 isWebWorker = !isBrowser && typeof importScripts !== 'undefined', 273 //PS3 indicates loaded and complete, but need to wait for complete 274 //specifically. Sequence is 'loading', 'loaded', execution, 275 // then 'complete'. The UA check is unfortunate, but not sure how 276 //to feature test w/o causing perf issues. 277 readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ? 278 /^complete$/ : /^(complete|loaded)$/, 279 defContextName = '_', 280 //Oh the tragedy, detecting opera. See the usage of isOpera for reason. 281 isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]', 282 contexts = {}, 283 cfg = {}, 284 globalDefQueue = [], 285 useInteractive = false, 286 disallowedProps = ['__proto__', 'constructor']; 287 288 //Could match something like ')//comment', do not lose the prefix to comment. 289 function commentReplace(match, singlePrefix) { 290 return singlePrefix || ''; 291 } 292 293 function isFunction(it) { 294 return ostring.call(it) === '[object Function]'; 295 } 296 297 function isArray(it) { 298 return ostring.call(it) === '[object Array]'; 299 } 300 301 /** 302 * Helper function for iterating over an array. If the func returns 303 * a true value, it will break out of the loop. 304 */ 305 function each(ary, func) { 306 if (ary) { 307 var i; 308 for (i = 0; i < ary.length; i += 1) { 309 if (ary[i] && func(ary[i], i, ary)) { 310 break; 311 } 312 } 313 } 314 } 315 316 /** 317 * Helper function for iterating over an array backwards. If the func 318 * returns a true value, it will break out of the loop. 319 */ 320 function eachReverse(ary, func) { 321 if (ary) { 322 var i; 323 for (i = ary.length - 1; i > -1; i -= 1) { 324 if (ary[i] && func(ary[i], i, ary)) { 325 break; 326 } 327 } 328 } 329 } 330 331 function hasProp(obj, prop) { 332 return hasOwn.call(obj, prop); 333 } 334 335 function getOwn(obj, prop) { 336 return hasProp(obj, prop) && obj[prop]; 337 } 338 339 /** 340 * Cycles over properties in an object and calls a function for each 341 * property value. If the function returns a truthy value, then the 342 * iteration is stopped. 343 */ 344 function eachProp(obj, func) { 345 var prop; 346 for (prop in obj) { 347 if (hasProp(obj, prop) && disallowedProps.indexOf(prop) == -1) { 348 if (func(obj[prop], prop)) { 349 break; 350 } 351 } 352 } 353 } 354 355 /** 356 * Simple function to mix in properties from source into target, 357 * but only if target does not already have a property of the same name. 358 */ 359 function mixin(target, source, force, deepStringMixin) { 360 if (source) { 361 eachProp(source, function (value, prop) { 362 if (force || !hasProp(target, prop)) { 363 if (deepStringMixin && typeof value === 'object' && value && 364 !isArray(value) && !isFunction(value) && 365 !(value instanceof RegExp)) { 366 367 if (!target[prop]) { 368 target[prop] = {}; 369 } 370 mixin(target[prop], value, force, deepStringMixin); 371 } else { 372 target[prop] = value; 373 } 374 } 375 }); 376 } 377 return target; 378 } 379 380 //Similar to Function.prototype.bind, but the 'this' object is specified 381 //first, since it is easier to read/figure out what 'this' will be. 382 function bind(obj, fn) { 383 return function () { 384 return fn.apply(obj, arguments); 385 }; 386 } 387 388 function scripts() { 389 return document.getElementsByTagName('script'); 390 } 391 392 function defaultOnError(err) { 393 throw err; 394 } 395 396 //Allow getting a global that is expressed in 397 //dot notation, like 'a.b.c'. 398 function getGlobal(value) { 399 if (!value) { 400 return value; 401 } 402 var g = global; 403 each(value.split('.'), function (part) { 404 g = g[part]; 405 }); 406 return g; 407 } 408 409 /** 410 * Constructs an error with a pointer to an URL with more information. 411 * @param {String} id the error ID that maps to an ID on a web page. 412 * @param {String} message human readable error. 413 * @param {Error} [err] the original error, if there is one. 414 * 415 * @returns {Error} 416 */ 417 function makeError(id, msg, err, requireModules) { 418 var e = new Error(msg + '\nhttps://requirejs.org/docs/errors.html#' + id); 419 e.requireType = id; 420 e.requireModules = requireModules; 421 if (err) { 422 e.originalError = err; 423 } 424 return e; 425 } 426 427 if (typeof define !== 'undefined') { 428 //If a define is already in play via another AMD loader, 429 //do not overwrite. 430 return; 431 } 432 433 if (typeof requirejs !== 'undefined') { 434 if (isFunction(requirejs)) { 435 //Do not overwrite an existing requirejs instance. 436 return; 437 } 438 cfg = requirejs; 439 requirejs = undefined; 440 } 441 442 //Allow for a require config object 443 if (typeof require !== 'undefined' && !isFunction(require)) { 444 //assume it is a config object. 445 cfg = require; 446 require = undefined; 447 } 448 449 function newContext(contextName) { 450 var inCheckLoaded, Module, context, handlers, 451 checkLoadedTimeoutId, 452 config = { 453 //Defaults. Do not set a default for map 454 //config to speed up normalize(), which 455 //will run faster if there is no default. 456 waitSeconds: 7, 457 baseUrl: './', 458 paths: {}, 459 bundles: {}, 460 pkgs: {}, 461 shim: {}, 462 config: {} 463 }, 464 registry = {}, 465 //registry of just enabled modules, to speed 466 //cycle breaking code when lots of modules 467 //are registered, but not activated. 468 enabledRegistry = {}, 469 undefEvents = {}, 470 defQueue = [], 471 defined = {}, 472 urlFetched = {}, 473 bundlesMap = {}, 474 requireCounter = 1, 475 unnormalizedCounter = 1; 476 477 /** 478 * Trims the . and .. from an array of path segments. 479 * It will keep a leading path segment if a .. will become 480 * the first path segment, to help with module name lookups, 481 * which act like paths, but can be remapped. But the end result, 482 * all paths that use this function should look normalized. 483 * NOTE: this method MODIFIES the input array. 484 * @param {Array} ary the array of path segments. 485 */ 486 function trimDots(ary) { 487 var i, part; 488 for (i = 0; i < ary.length; i++) { 489 part = ary[i]; 490 if (part === '.') { 491 ary.splice(i, 1); 492 i -= 1; 493 } else if (part === '..') { 494 // If at the start, or previous value is still .., 495 // keep them so that when converted to a path it may 496 // still work when converted to a path, even though 497 // as an ID it is less than ideal. In larger point 498 // releases, may be better to just kick out an error. 499 if (i === 0 || (i === 1 && ary[2] === '..') || ary[i - 1] === '..') { 500 continue; 501 } else if (i > 0) { 502 ary.splice(i - 1, 2); 503 i -= 2; 504 } 505 } 506 } 507 } 508 509 /** 510 * Given a relative module name, like ./something, normalize it to 511 * a real name that can be mapped to a path. 512 * @param {String} name the relative name 513 * @param {String} baseName a real name that the name arg is relative 514 * to. 515 * @param {Boolean} applyMap apply the map config to the value. Should 516 * only be done if this normalization is for a dependency ID. 517 * @returns {String} normalized name 518 */ 519 function normalize(name, baseName, applyMap) { 520 var pkgMain, mapValue, nameParts, i, j, nameSegment, lastIndex, 521 foundMap, foundI, foundStarMap, starI, normalizedBaseParts, 522 baseParts = (baseName && baseName.split('/')), 523 map = config.map, 524 starMap = map && map['*']; 525 526 //Adjust any relative paths. 527 if (name) { 528 name = name.split('/'); 529 lastIndex = name.length - 1; 530 531 // If wanting node ID compatibility, strip .js from end 532 // of IDs. Have to do this here, and not in nameToUrl 533 // because node allows either .js or non .js to map 534 // to same file. 535 if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) { 536 name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, ''); 537 } 538 539 // Starts with a '.' so need the baseName 540 if (name[0].charAt(0) === '.' && baseParts) { 541 //Convert baseName to array, and lop off the last part, 542 //so that . matches that 'directory' and not name of the baseName's 543 //module. For instance, baseName of 'one/two/three', maps to 544 //'one/two/three.js', but we want the directory, 'one/two' for 545 //this normalization. 546 normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); 547 name = normalizedBaseParts.concat(name); 548 } 549 550 trimDots(name); 551 name = name.join('/'); 552 } 553 554 //Apply map config if available. 555 if (applyMap && map && (baseParts || starMap)) { 556 nameParts = name.split('/'); 557 558 outerLoop: for (i = nameParts.length; i > 0; i -= 1) { 559 nameSegment = nameParts.slice(0, i).join('/'); 560 561 if (baseParts) { 562 //Find the longest baseName segment match in the config. 563 //So, do joins on the biggest to smallest lengths of baseParts. 564 for (j = baseParts.length; j > 0; j -= 1) { 565 mapValue = getOwn(map, baseParts.slice(0, j).join('/')); 566 567 //baseName segment has config, find if it has one for 568 //this name. 569 if (mapValue) { 570 mapValue = getOwn(mapValue, nameSegment); 571 if (mapValue) { 572 //Match, update name to the new value. 573 foundMap = mapValue; 574 foundI = i; 575 break outerLoop; 576 } 577 } 578 } 579 } 580 581 //Check for a star map match, but just hold on to it, 582 //if there is a shorter segment match later in a matching 583 //config, then favor over this star map. 584 if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) { 585 foundStarMap = getOwn(starMap, nameSegment); 586 starI = i; 587 } 588 } 589 590 if (!foundMap && foundStarMap) { 591 foundMap = foundStarMap; 592 foundI = starI; 593 } 594 595 if (foundMap) { 596 nameParts.splice(0, foundI, foundMap); 597 name = nameParts.join('/'); 598 } 599 } 600 601 // If the name points to a package's name, use 602 // the package main instead. 603 pkgMain = getOwn(config.pkgs, name); 604 605 return pkgMain ? pkgMain : name; 606 } 607 608 function removeScript(name) { 609 if (isBrowser) { 610 each(scripts(), function (scriptNode) { 611 if (scriptNode.getAttribute('data-requiremodule') === name && 612 scriptNode.getAttribute('data-requirecontext') === context.contextName) { 613 scriptNode.parentNode.removeChild(scriptNode); 614 return true; 615 } 616 }); 617 } 618 } 619 620 function hasPathFallback(id) { 621 var pathConfig = getOwn(config.paths, id); 622 if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) { 623 //Pop off the first array value, since it failed, and 624 //retry 625 pathConfig.shift(); 626 context.require.undef(id); 627 628 //Custom require that does not do map translation, since 629 //ID is "absolute", already mapped/resolved. 630 context.makeRequire(null, { 631 skipMap: true 632 })([id]); 633 634 return true; 635 } 636 } 637 638 //Turns a plugin!resource to [plugin, resource] 639 //with the plugin being undefined if the name 640 //did not have a plugin prefix. 641 function splitPrefix(name) { 642 var prefix, 643 index = name ? name.indexOf('!') : -1; 644 if (index > -1) { 645 prefix = name.substring(0, index); 646 name = name.substring(index + 1, name.length); 647 } 648 return [prefix, name]; 649 } 650 651 /** 652 * Creates a module mapping that includes plugin prefix, module 653 * name, and path. If parentModuleMap is provided it will 654 * also normalize the name via require.normalize() 655 * 656 * @param {String} name the module name 657 * @param {String} [parentModuleMap] parent module map 658 * for the module name, used to resolve relative names. 659 * @param {Boolean} isNormalized: is the ID already normalized. 660 * This is true if this call is done for a define() module ID. 661 * @param {Boolean} applyMap: apply the map config to the ID. 662 * Should only be true if this map is for a dependency. 663 * 664 * @returns {Object} 665 */ 666 function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) { 667 var url, pluginModule, suffix, nameParts, 668 prefix = null, 669 parentName = parentModuleMap ? parentModuleMap.name : null, 670 originalName = name, 671 isDefine = true, 672 normalizedName = ''; 673 674 //If no name, then it means it is a require call, generate an 675 //internal name. 676 if (!name) { 677 isDefine = false; 678 name = '_@r' + (requireCounter += 1); 679 } 680 681 nameParts = splitPrefix(name); 682 prefix = nameParts[0]; 683 name = nameParts[1]; 684 685 if (prefix) { 686 prefix = normalize(prefix, parentName, applyMap); 687 pluginModule = getOwn(defined, prefix); 688 } 689 690 //Account for relative paths if there is a base name. 691 if (name) { 692 if (prefix) { 693 if (isNormalized) { 694 normalizedName = name; 695 } else if (pluginModule && pluginModule.normalize) { 696 //Plugin is loaded, use its normalize method. 697 normalizedName = pluginModule.normalize(name, function (name) { 698 return normalize(name, parentName, applyMap); 699 }); 700 } else { 701 // If nested plugin references, then do not try to 702 // normalize, as it will not normalize correctly. This 703 // places a restriction on resourceIds, and the longer 704 // term solution is not to normalize until plugins are 705 // loaded and all normalizations to allow for async 706 // loading of a loader plugin. But for now, fixes the 707 // common uses. Details in #1131 708 normalizedName = name.indexOf('!') === -1 ? 709 normalize(name, parentName, applyMap) : 710 name; 711 } 712 } else { 713 //A regular module. 714 normalizedName = normalize(name, parentName, applyMap); 715 716 //Normalized name may be a plugin ID due to map config 717 //application in normalize. The map config values must 718 //already be normalized, so do not need to redo that part. 719 nameParts = splitPrefix(normalizedName); 720 prefix = nameParts[0]; 721 normalizedName = nameParts[1]; 722 isNormalized = true; 723 724 url = context.nameToUrl(normalizedName); 725 } 726 } 727 728 //If the id is a plugin id that cannot be determined if it needs 729 //normalization, stamp it with a unique ID so two matching relative 730 //ids that may conflict can be separate. 731 suffix = prefix && !pluginModule && !isNormalized ? 732 '_unnormalized' + (unnormalizedCounter += 1) : 733 ''; 734 735 return { 736 prefix: prefix, 737 name: normalizedName, 738 parentMap: parentModuleMap, 739 unnormalized: !!suffix, 740 url: url, 741 originalName: originalName, 742 isDefine: isDefine, 743 id: (prefix ? 744 prefix + '!' + normalizedName : 745 normalizedName) + suffix 746 }; 747 } 748 749 function getModule(depMap) { 750 var id = depMap.id, 751 mod = getOwn(registry, id); 752 753 if (!mod) { 754 mod = registry[id] = new context.Module(depMap); 755 } 756 757 return mod; 758 } 759 760 function on(depMap, name, fn) { 761 var id = depMap.id, 762 mod = getOwn(registry, id); 763 764 if (hasProp(defined, id) && 765 (!mod || mod.defineEmitComplete)) { 766 if (name === 'defined') { 767 fn(defined[id]); 768 } 769 } else { 770 mod = getModule(depMap); 771 if (mod.error && name === 'error') { 772 fn(mod.error); 773 } else { 774 mod.on(name, fn); 775 } 776 } 777 } 778 779 function onError(err, errback) { 780 var ids = err.requireModules, 781 notified = false; 782 783 if (errback) { 784 errback(err); 785 } else { 786 each(ids, function (id) { 787 var mod = getOwn(registry, id); 788 if (mod) { 789 //Set error on module, so it skips timeout checks. 790 mod.error = err; 791 if (mod.events.error) { 792 notified = true; 793 mod.emit('error', err); 794 } 795 } 796 }); 797 798 if (!notified) { 799 req.onError(err); 800 } 801 } 802 } 803 804 /** 805 * Internal method to transfer globalQueue items to this context's 806 * defQueue. 807 */ 808 function takeGlobalQueue() { 809 //Push all the globalDefQueue items into the context's defQueue 810 if (globalDefQueue.length) { 811 each(globalDefQueue, function(queueItem) { 812 var id = queueItem[0]; 813 if (typeof id === 'string') { 814 context.defQueueMap[id] = true; 815 } 816 defQueue.push(queueItem); 817 }); 818 globalDefQueue = []; 819 } 820 } 821 822 handlers = { 823 'require': function (mod) { 824 if (mod.require) { 825 return mod.require; 826 } else { 827 return (mod.require = context.makeRequire(mod.map)); 828 } 829 }, 830 'exports': function (mod) { 831 mod.usingExports = true; 832 if (mod.map.isDefine) { 833 if (mod.exports) { 834 return (defined[mod.map.id] = mod.exports); 835 } else { 836 return (mod.exports = defined[mod.map.id] = {}); 837 } 838 } 839 }, 840 'module': function (mod) { 841 if (mod.module) { 842 return mod.module; 843 } else { 844 return (mod.module = { 845 id: mod.map.id, 846 uri: mod.map.url, 847 config: function () { 848 return getOwn(config.config, mod.map.id) || {}; 849 }, 850 exports: mod.exports || (mod.exports = {}) 851 }); 852 } 853 } 854 }; 855 856 function cleanRegistry(id) { 857 //Clean up machinery used for waiting modules. 858 delete registry[id]; 859 delete enabledRegistry[id]; 860 } 861 862 function breakCycle(mod, traced, processed) { 863 var id = mod.map.id; 864 865 if (mod.error) { 866 mod.emit('error', mod.error); 867 } else { 868 traced[id] = true; 869 each(mod.depMaps, function (depMap, i) { 870 var depId = depMap.id, 871 dep = getOwn(registry, depId); 872 873 //Only force things that have not completed 874 //being defined, so still in the registry, 875 //and only if it has not been matched up 876 //in the module already. 877 if (dep && !mod.depMatched[i] && !processed[depId]) { 878 if (getOwn(traced, depId)) { 879 mod.defineDep(i, defined[depId]); 880 mod.check(); //pass false? 881 } else { 882 breakCycle(dep, traced, processed); 883 } 884 } 885 }); 886 processed[id] = true; 887 } 888 } 889 890 function checkLoaded() { 891 var err, usingPathFallback, 892 waitInterval = config.waitSeconds * 1000, 893 //It is possible to disable the wait interval by using waitSeconds of 0. 894 expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(), 895 noLoads = [], 896 reqCalls = [], 897 stillLoading = false, 898 needCycleCheck = true; 899 900 //Do not bother if this call was a result of a cycle break. 901 if (inCheckLoaded) { 902 return; 903 } 904 905 inCheckLoaded = true; 906 907 //Figure out the state of all the modules. 908 eachProp(enabledRegistry, function (mod) { 909 var map = mod.map, 910 modId = map.id; 911 912 //Skip things that are not enabled or in error state. 913 if (!mod.enabled) { 914 return; 915 } 916 917 if (!map.isDefine) { 918 reqCalls.push(mod); 919 } 920 921 if (!mod.error) { 922 //If the module should be executed, and it has not 923 //been inited and time is up, remember it. 924 if (!mod.inited && expired) { 925 if (hasPathFallback(modId)) { 926 usingPathFallback = true; 927 stillLoading = true; 928 } else { 929 noLoads.push(modId); 930 removeScript(modId); 931 } 932 } else if (!mod.inited && mod.fetched && map.isDefine) { 933 stillLoading = true; 934 if (!map.prefix) { 935 //No reason to keep looking for unfinished 936 //loading. If the only stillLoading is a 937 //plugin resource though, keep going, 938 //because it may be that a plugin resource 939 //is waiting on a non-plugin cycle. 940 return (needCycleCheck = false); 941 } 942 } 943 } 944 }); 945 946 if (expired && noLoads.length) { 947 //If wait time expired, throw error of unloaded modules. 948 err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads); 949 err.contextName = context.contextName; 950 return onError(err); 951 } 952 953 //Not expired, check for a cycle. 954 if (needCycleCheck) { 955 each(reqCalls, function (mod) { 956 breakCycle(mod, {}, {}); 957 }); 958 } 959 960 //If still waiting on loads, and the waiting load is something 961 //other than a plugin resource, or there are still outstanding 962 //scripts, then just try back later. 963 if ((!expired || usingPathFallback) && stillLoading) { 964 //Something is still waiting to load. Wait for it, but only 965 //if a timeout is not already in effect. 966 if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) { 967 checkLoadedTimeoutId = setTimeout(function () { 968 checkLoadedTimeoutId = 0; 969 checkLoaded(); 970 }, 50); 971 } 972 } 973 974 inCheckLoaded = false; 975 } 976 977 Module = function (map) { 978 this.events = getOwn(undefEvents, map.id) || {}; 979 this.map = map; 980 this.shim = getOwn(config.shim, map.id); 981 this.depExports = []; 982 this.depMaps = []; 983 this.depMatched = []; 984 this.pluginMaps = {}; 985 this.depCount = 0; 986 987 /* this.exports this.factory 988 this.depMaps = [], 989 this.enabled, this.fetched 990 */ 991 }; 992 993 Module.prototype = { 994 init: function (depMaps, factory, errback, options) { 995 options = options || {}; 996 997 //Do not do more inits if already done. Can happen if there 998 //are multiple define calls for the same module. That is not 999 //a normal, common case, but it is also not unexpected. 1000 if (this.inited) { 1001 return; 1002 } 1003 1004 this.factory = factory; 1005 1006 if (errback) { 1007 //Register for errors on this module. 1008 this.on('error', errback); 1009 } else if (this.events.error) { 1010 //If no errback already, but there are error listeners 1011 //on this module, set up an errback to pass to the deps. 1012 errback = bind(this, function (err) { 1013 this.emit('error', err); 1014 }); 1015 } 1016 1017 //Do a copy of the dependency array, so that 1018 //source inputs are not modified. For example 1019 //"shim" deps are passed in here directly, and 1020 //doing a direct modification of the depMaps array 1021 //would affect that config. 1022 this.depMaps = depMaps && depMaps.slice(0); 1023 1024 this.errback = errback; 1025 1026 //Indicate this module has be initialized 1027 this.inited = true; 1028 1029 this.ignore = options.ignore; 1030 1031 //Could have option to init this module in enabled mode, 1032 //or could have been previously marked as enabled. However, 1033 //the dependencies are not known until init is called. So 1034 //if enabled previously, now trigger dependencies as enabled. 1035 if (options.enabled || this.enabled) { 1036 //Enable this module and dependencies. 1037 //Will call this.check() 1038 this.enable(); 1039 } else { 1040 this.check(); 1041 } 1042 }, 1043 1044 defineDep: function (i, depExports) { 1045 //Because of cycles, defined callback for a given 1046 //export can be called more than once. 1047 if (!this.depMatched[i]) { 1048 this.depMatched[i] = true; 1049 this.depCount -= 1; 1050 this.depExports[i] = depExports; 1051 } 1052 }, 1053 1054 fetch: function () { 1055 if (this.fetched) { 1056 return; 1057 } 1058 this.fetched = true; 1059 1060 context.startTime = (new Date()).getTime(); 1061 1062 var map = this.map; 1063 1064 //If the manager is for a plugin managed resource, 1065 //ask the plugin to load it now. 1066 if (this.shim) { 1067 context.makeRequire(this.map, { 1068 enableBuildCallback: true 1069 })(this.shim.deps || [], bind(this, function () { 1070 return map.prefix ? this.callPlugin() : this.load(); 1071 })); 1072 } else { 1073 //Regular dependency. 1074 return map.prefix ? this.callPlugin() : this.load(); 1075 } 1076 }, 1077 1078 load: function () { 1079 var url = this.map.url; 1080 1081 //Regular dependency. 1082 if (!urlFetched[url]) { 1083 urlFetched[url] = true; 1084 context.load(this.map.id, url); 1085 } 1086 }, 1087 1088 /** 1089 * Checks if the module is ready to define itself, and if so, 1090 * define it. 1091 */ 1092 check: function () { 1093 if (!this.enabled || this.enabling) { 1094 return; 1095 } 1096 1097 var err, cjsModule, 1098 id = this.map.id, 1099 depExports = this.depExports, 1100 exports = this.exports, 1101 factory = this.factory; 1102 1103 if (!this.inited) { 1104 // Only fetch if not already in the defQueue. 1105 if (!hasProp(context.defQueueMap, id)) { 1106 this.fetch(); 1107 } 1108 } else if (this.error) { 1109 this.emit('error', this.error); 1110 } else if (!this.defining) { 1111 //The factory could trigger another require call 1112 //that would result in checking this module to 1113 //define itself again. If already in the process 1114 //of doing that, skip this work. 1115 this.defining = true; 1116 1117 if (this.depCount < 1 && !this.defined) { 1118 if (isFunction(factory)) { 1119 //If there is an error listener, favor passing 1120 //to that instead of throwing an error. However, 1121 //only do it for define()'d modules. require 1122 //errbacks should not be called for failures in 1123 //their callbacks (#699). However if a global 1124 //onError is set, use that. 1125 if ((this.events.error && this.map.isDefine) || 1126 req.onError !== defaultOnError) { 1127 try { 1128 exports = context.execCb(id, factory, depExports, exports); 1129 } catch (e) { 1130 err = e; 1131 } 1132 } else { 1133 exports = context.execCb(id, factory, depExports, exports); 1134 } 1135 1136 // Favor return value over exports. If node/cjs in play, 1137 // then will not have a return value anyway. Favor 1138 // module.exports assignment over exports object. 1139 if (this.map.isDefine && exports === undefined) { 1140 cjsModule = this.module; 1141 if (cjsModule) { 1142 exports = cjsModule.exports; 1143 } else if (this.usingExports) { 1144 //exports already set the defined value. 1145 exports = this.exports; 1146 } 1147 } 1148 1149 if (err) { 1150 err.requireMap = this.map; 1151 err.requireModules = this.map.isDefine ? [this.map.id] : null; 1152 err.requireType = this.map.isDefine ? 'define' : 'require'; 1153 return onError((this.error = err)); 1154 } 1155 1156 } else { 1157 //Just a literal value 1158 exports = factory; 1159 } 1160 1161 this.exports = exports; 1162 1163 if (this.map.isDefine && !this.ignore) { 1164 defined[id] = exports; 1165 1166 if (req.onResourceLoad) { 1167 var resLoadMaps = []; 1168 each(this.depMaps, function (depMap) { 1169 resLoadMaps.push(depMap.normalizedMap || depMap); 1170 }); 1171 req.onResourceLoad(context, this.map, resLoadMaps); 1172 } 1173 } 1174 1175 //Clean up 1176 cleanRegistry(id); 1177 1178 this.defined = true; 1179 } 1180 1181 //Finished the define stage. Allow calling check again 1182 //to allow define notifications below in the case of a 1183 //cycle. 1184 this.defining = false; 1185 1186 if (this.defined && !this.defineEmitted) { 1187 this.defineEmitted = true; 1188 this.emit('defined', this.exports); 1189 this.defineEmitComplete = true; 1190 } 1191 1192 } 1193 }, 1194 1195 callPlugin: function () { 1196 var map = this.map, 1197 id = map.id, 1198 //Map already normalized the prefix. 1199 pluginMap = makeModuleMap(map.prefix); 1200 1201 //Mark this as a dependency for this plugin, so it 1202 //can be traced for cycles. 1203 this.depMaps.push(pluginMap); 1204 1205 on(pluginMap, 'defined', bind(this, function (plugin) { 1206 var load, normalizedMap, normalizedMod, 1207 bundleId = getOwn(bundlesMap, this.map.id), 1208 name = this.map.name, 1209 parentName = this.map.parentMap ? this.map.parentMap.name : null, 1210 localRequire = context.makeRequire(map.parentMap, { 1211 enableBuildCallback: true 1212 }); 1213 1214 //If current map is not normalized, wait for that 1215 //normalized name to load instead of continuing. 1216 if (this.map.unnormalized) { 1217 //Normalize the ID if the plugin allows it. 1218 if (plugin.normalize) { 1219 name = plugin.normalize(name, function (name) { 1220 return normalize(name, parentName, true); 1221 }) || ''; 1222 } 1223 1224 //prefix and name should already be normalized, no need 1225 //for applying map config again either. 1226 normalizedMap = makeModuleMap(map.prefix + '!' + name, 1227 this.map.parentMap, 1228 true); 1229 on(normalizedMap, 1230 'defined', bind(this, function (value) { 1231 this.map.normalizedMap = normalizedMap; 1232 this.init([], function () { return value; }, null, { 1233 enabled: true, 1234 ignore: true 1235 }); 1236 })); 1237 1238 normalizedMod = getOwn(registry, normalizedMap.id); 1239 if (normalizedMod) { 1240 //Mark this as a dependency for this plugin, so it 1241 //can be traced for cycles. 1242 this.depMaps.push(normalizedMap); 1243 1244 if (this.events.error) { 1245 normalizedMod.on('error', bind(this, function (err) { 1246 this.emit('error', err); 1247 })); 1248 } 1249 normalizedMod.enable(); 1250 } 1251 1252 return; 1253 } 1254 1255 //If a paths config, then just load that file instead to 1256 //resolve the plugin, as it is built into that paths layer. 1257 if (bundleId) { 1258 this.map.url = context.nameToUrl(bundleId); 1259 this.load(); 1260 return; 1261 } 1262 1263 load = bind(this, function (value) { 1264 this.init([], function () { return value; }, null, { 1265 enabled: true 1266 }); 1267 }); 1268 1269 load.error = bind(this, function (err) { 1270 this.inited = true; 1271 this.error = err; 1272 err.requireModules = [id]; 1273 1274 //Remove temp unnormalized modules for this module, 1275 //since they will never be resolved otherwise now. 1276 eachProp(registry, function (mod) { 1277 if (mod.map.id.indexOf(id + '_unnormalized') === 0) { 1278 cleanRegistry(mod.map.id); 1279 } 1280 }); 1281 1282 onError(err); 1283 }); 1284 1285 //Allow plugins to load other code without having to know the 1286 //context or how to 'complete' the load. 1287 load.fromText = bind(this, function (text, textAlt) { 1288 /*jslint evil: true */ 1289 var moduleName = map.name, 1290 moduleMap = makeModuleMap(moduleName), 1291 hasInteractive = useInteractive; 1292 1293 //As of 2.1.0, support just passing the text, to reinforce 1294 //fromText only being called once per resource. Still 1295 //support old style of passing moduleName but discard 1296 //that moduleName in favor of the internal ref. 1297 if (textAlt) { 1298 text = textAlt; 1299 } 1300 1301 //Turn off interactive script matching for IE for any define 1302 //calls in the text, then turn it back on at the end. 1303 if (hasInteractive) { 1304 useInteractive = false; 1305 } 1306 1307 //Prime the system by creating a module instance for 1308 //it. 1309 getModule(moduleMap); 1310 1311 //Transfer any config to this other module. 1312 if (hasProp(config.config, id)) { 1313 config.config[moduleName] = config.config[id]; 1314 } 1315 1316 try { 1317 req.exec(text); 1318 } catch (e) { 1319 return onError(makeError('fromtexteval', 1320 'fromText eval for ' + id + 1321 ' failed: ' + e, 1322 e, 1323 [id])); 1324 } 1325 1326 if (hasInteractive) { 1327 useInteractive = true; 1328 } 1329 1330 //Mark this as a dependency for the plugin 1331 //resource 1332 this.depMaps.push(moduleMap); 1333 1334 //Support anonymous modules. 1335 context.completeLoad(moduleName); 1336 1337 //Bind the value of that module to the value for this 1338 //resource ID. 1339 localRequire([moduleName], load); 1340 }); 1341 1342 //Use parentName here since the plugin's name is not reliable, 1343 //could be some weird string with no path that actually wants to 1344 //reference the parentName's path. 1345 plugin.load(map.name, localRequire, load, config); 1346 })); 1347 1348 context.enable(pluginMap, this); 1349 this.pluginMaps[pluginMap.id] = pluginMap; 1350 }, 1351 1352 enable: function () { 1353 enabledRegistry[this.map.id] = this; 1354 this.enabled = true; 1355 1356 //Set flag mentioning that the module is enabling, 1357 //so that immediate calls to the defined callbacks 1358 //for dependencies do not trigger inadvertent load 1359 //with the depCount still being zero. 1360 this.enabling = true; 1361 1362 //Enable each dependency 1363 each(this.depMaps, bind(this, function (depMap, i) { 1364 var id, mod, handler; 1365 1366 if (typeof depMap === 'string') { 1367 //Dependency needs to be converted to a depMap 1368 //and wired up to this module. 1369 depMap = makeModuleMap(depMap, 1370 (this.map.isDefine ? this.map : this.map.parentMap), 1371 false, 1372 !this.skipMap); 1373 this.depMaps[i] = depMap; 1374 1375 handler = getOwn(handlers, depMap.id); 1376 1377 if (handler) { 1378 this.depExports[i] = handler(this); 1379 return; 1380 } 1381 1382 this.depCount += 1; 1383 1384 on(depMap, 'defined', bind(this, function (depExports) { 1385 if (this.undefed) { 1386 return; 1387 } 1388 this.defineDep(i, depExports); 1389 this.check(); 1390 })); 1391 1392 if (this.errback) { 1393 on(depMap, 'error', bind(this, this.errback)); 1394 } else if (this.events.error) { 1395 // No direct errback on this module, but something 1396 // else is listening for errors, so be sure to 1397 // propagate the error correctly. 1398 on(depMap, 'error', bind(this, function(err) { 1399 this.emit('error', err); 1400 })); 1401 } 1402 } 1403 1404 id = depMap.id; 1405 mod = registry[id]; 1406 1407 //Skip special modules like 'require', 'exports', 'module' 1408 //Also, don't call enable if it is already enabled, 1409 //important in circular dependency cases. 1410 if (!hasProp(handlers, id) && mod && !mod.enabled) { 1411 context.enable(depMap, this); 1412 } 1413 })); 1414 1415 //Enable each plugin that is used in 1416 //a dependency 1417 eachProp(this.pluginMaps, bind(this, function (pluginMap) { 1418 var mod = getOwn(registry, pluginMap.id); 1419 if (mod && !mod.enabled) { 1420 context.enable(pluginMap, this); 1421 } 1422 })); 1423 1424 this.enabling = false; 1425 1426 this.check(); 1427 }, 1428 1429 on: function (name, cb) { 1430 var cbs = this.events[name]; 1431 if (!cbs) { 1432 cbs = this.events[name] = []; 1433 } 1434 cbs.push(cb); 1435 }, 1436 1437 emit: function (name, evt) { 1438 each(this.events[name], function (cb) { 1439 cb(evt); 1440 }); 1441 if (name === 'error') { 1442 //Now that the error handler was triggered, remove 1443 //the listeners, since this broken Module instance 1444 //can stay around for a while in the registry. 1445 delete this.events[name]; 1446 } 1447 } 1448 }; 1449 1450 function callGetModule(args) { 1451 //Skip modules already defined. 1452 if (!hasProp(defined, args[0])) { 1453 getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]); 1454 } 1455 } 1456 1457 function removeListener(node, func, name, ieName) { 1458 //Favor detachEvent because of IE9 1459 //issue, see attachEvent/addEventListener comment elsewhere 1460 //in this file. 1461 if (node.detachEvent && !isOpera) { 1462 //Probably IE. If not it will throw an error, which will be 1463 //useful to know. 1464 if (ieName) { 1465 node.detachEvent(ieName, func); 1466 } 1467 } else { 1468 node.removeEventListener(name, func, false); 1469 } 1470 } 1471 1472 /** 1473 * Given an event from a script node, get the requirejs info from it, 1474 * and then removes the event listeners on the node. 1475 * @param {Event} evt 1476 * @returns {Object} 1477 */ 1478 function getScriptData(evt) { 1479 //Using currentTarget instead of target for Firefox 2.0's sake. Not 1480 //all old browsers will be supported, but this one was easy enough 1481 //to support and still makes sense. 1482 var node = evt.currentTarget || evt.srcElement; 1483 1484 //Remove the listeners once here. 1485 removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange'); 1486 removeListener(node, context.onScriptError, 'error'); 1487 1488 return { 1489 node: node, 1490 id: node && node.getAttribute('data-requiremodule') 1491 }; 1492 } 1493 1494 function intakeDefines() { 1495 var args; 1496 1497 //Any defined modules in the global queue, intake them now. 1498 takeGlobalQueue(); 1499 1500 //Make sure any remaining defQueue items get properly processed. 1501 while (defQueue.length) { 1502 args = defQueue.shift(); 1503 if (args[0] === null) { 1504 return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + 1505 args[args.length - 1])); 1506 } else { 1507 //args are id, deps, factory. Should be normalized by the 1508 //define() function. 1509 callGetModule(args); 1510 } 1511 } 1512 context.defQueueMap = {}; 1513 } 1514 1515 context = { 1516 config: config, 1517 contextName: contextName, 1518 registry: registry, 1519 defined: defined, 1520 urlFetched: urlFetched, 1521 defQueue: defQueue, 1522 defQueueMap: {}, 1523 Module: Module, 1524 makeModuleMap: makeModuleMap, 1525 nextTick: req.nextTick, 1526 onError: onError, 1527 1528 /** 1529 * Set a configuration for the context. 1530 * @param {Object} cfg config object to integrate. 1531 */ 1532 configure: function (cfg) { 1533 //Make sure the baseUrl ends in a slash. 1534 if (cfg.baseUrl) { 1535 if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') { 1536 cfg.baseUrl += '/'; 1537 } 1538 } 1539 1540 // Convert old style urlArgs string to a function. 1541 if (typeof cfg.urlArgs === 'string') { 1542 var urlArgs = cfg.urlArgs; 1543 cfg.urlArgs = function(id, url) { 1544 return (url.indexOf('?') === -1 ? '?' : '&') + urlArgs; 1545 }; 1546 } 1547 1548 //Save off the paths since they require special processing, 1549 //they are additive. 1550 var shim = config.shim, 1551 objs = { 1552 paths: true, 1553 bundles: true, 1554 config: true, 1555 map: true 1556 }; 1557 1558 eachProp(cfg, function (value, prop) { 1559 if (objs[prop]) { 1560 if (!config[prop]) { 1561 config[prop] = {}; 1562 } 1563 mixin(config[prop], value, true, true); 1564 } else { 1565 config[prop] = value; 1566 } 1567 }); 1568 1569 //Reverse map the bundles 1570 if (cfg.bundles) { 1571 eachProp(cfg.bundles, function (value, prop) { 1572 each(value, function (v) { 1573 if (v !== prop) { 1574 bundlesMap[v] = prop; 1575 } 1576 }); 1577 }); 1578 } 1579 1580 //Merge shim 1581 if (cfg.shim) { 1582 eachProp(cfg.shim, function (value, id) { 1583 //Normalize the structure 1584 if (isArray(value)) { 1585 value = { 1586 deps: value 1587 }; 1588 } 1589 if ((value.exports || value.init) && !value.exportsFn) { 1590 value.exportsFn = context.makeShimExports(value); 1591 } 1592 shim[id] = value; 1593 }); 1594 config.shim = shim; 1595 } 1596 1597 //Adjust packages if necessary. 1598 if (cfg.packages) { 1599 each(cfg.packages, function (pkgObj) { 1600 var location, name; 1601 1602 pkgObj = typeof pkgObj === 'string' ? {name: pkgObj} : pkgObj; 1603 1604 name = pkgObj.name; 1605 location = pkgObj.location; 1606 if (location) { 1607 config.paths[name] = pkgObj.location; 1608 } 1609 1610 //Save pointer to main module ID for pkg name. 1611 //Remove leading dot in main, so main paths are normalized, 1612 //and remove any trailing .js, since different package 1613 //envs have different conventions: some use a module name, 1614 //some use a file name. 1615 config.pkgs[name] = pkgObj.name + '/' + (pkgObj.main || 'main') 1616 .replace(currDirRegExp, '') 1617 .replace(jsSuffixRegExp, ''); 1618 }); 1619 } 1620 1621 //If there are any "waiting to execute" modules in the registry, 1622 //update the maps for them, since their info, like URLs to load, 1623 //may have changed. 1624 eachProp(registry, function (mod, id) { 1625 //If module already has init called, since it is too 1626 //late to modify them, and ignore unnormalized ones 1627 //since they are transient. 1628 if (!mod.inited && !mod.map.unnormalized) { 1629 mod.map = makeModuleMap(id, null, true); 1630 } 1631 }); 1632 1633 //If a deps array or a config callback is specified, then call 1634 //require with those args. This is useful when require is defined as a 1635 //config object before require.js is loaded. 1636 if (cfg.deps || cfg.callback) { 1637 context.require(cfg.deps || [], cfg.callback); 1638 } 1639 }, 1640 1641 makeShimExports: function (value) { 1642 function fn() { 1643 var ret; 1644 if (value.init) { 1645 ret = value.init.apply(global, arguments); 1646 } 1647 return ret || (value.exports && getGlobal(value.exports)); 1648 } 1649 return fn; 1650 }, 1651 1652 makeRequire: function (relMap, options) { 1653 options = options || {}; 1654 1655 function localRequire(deps, callback, errback) { 1656 var id, map, requireMod; 1657 1658 if (options.enableBuildCallback && callback && isFunction(callback)) { 1659 callback.__requireJsBuild = true; 1660 } 1661 1662 if (typeof deps === 'string') { 1663 if (isFunction(callback)) { 1664 //Invalid call 1665 return onError(makeError('requireargs', 'Invalid require call'), errback); 1666 } 1667 1668 //If require|exports|module are requested, get the 1669 //value for them from the special handlers. Caveat: 1670 //this only works while module is being defined. 1671 if (relMap && hasProp(handlers, deps)) { 1672 return handlers[deps](registry[relMap.id]); 1673 } 1674 1675 //Synchronous access to one module. If require.get is 1676 //available (as in the Node adapter), prefer that. 1677 if (req.get) { 1678 return req.get(context, deps, relMap, localRequire); 1679 } 1680 1681 //Normalize module name, if it contains . or .. 1682 map = makeModuleMap(deps, relMap, false, true); 1683 id = map.id; 1684 1685 if (!hasProp(defined, id)) { 1686 return onError(makeError('notloaded', 'Module name "' + 1687 id + 1688 '" has not been loaded yet for context: ' + 1689 contextName + 1690 (relMap ? '' : '. Use require([])'))); 1691 } 1692 return defined[id]; 1693 } 1694 1695 //Grab defines waiting in the global queue. 1696 intakeDefines(); 1697 1698 //Mark all the dependencies as needing to be loaded. 1699 context.nextTick(function () { 1700 //Some defines could have been added since the 1701 //require call, collect them. 1702 intakeDefines(); 1703 1704 requireMod = getModule(makeModuleMap(null, relMap)); 1705 1706 //Store if map config should be applied to this require 1707 //call for dependencies. 1708 requireMod.skipMap = options.skipMap; 1709 1710 requireMod.init(deps, callback, errback, { 1711 enabled: true 1712 }); 1713 1714 checkLoaded(); 1715 }); 1716 1717 return localRequire; 1718 } 1719 1720 mixin(localRequire, { 1721 isBrowser: isBrowser, 1722 1723 /** 1724 * Converts a module name + .extension into an URL path. 1725 * *Requires* the use of a module name. It does not support using 1726 * plain URLs like nameToUrl. 1727 */ 1728 toUrl: function (moduleNamePlusExt) { 1729 var ext, 1730 index = moduleNamePlusExt.lastIndexOf('.'), 1731 segment = moduleNamePlusExt.split('/')[0], 1732 isRelative = segment === '.' || segment === '..'; 1733 1734 //Have a file extension alias, and it is not the 1735 //dots from a relative path. 1736 if (index !== -1 && (!isRelative || index > 1)) { 1737 ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length); 1738 moduleNamePlusExt = moduleNamePlusExt.substring(0, index); 1739 } 1740 1741 return context.nameToUrl(normalize(moduleNamePlusExt, 1742 relMap && relMap.id, true), ext, true); 1743 }, 1744 1745 defined: function (id) { 1746 return hasProp(defined, makeModuleMap(id, relMap, false, true).id); 1747 }, 1748 1749 specified: function (id) { 1750 id = makeModuleMap(id, relMap, false, true).id; 1751 return hasProp(defined, id) || hasProp(registry, id); 1752 } 1753 }); 1754 1755 //Only allow undef on top level require calls 1756 if (!relMap) { 1757 localRequire.undef = function (id) { 1758 //Bind any waiting define() calls to this context, 1759 //fix for #408 1760 takeGlobalQueue(); 1761 1762 var map = makeModuleMap(id, relMap, true), 1763 mod = getOwn(registry, id); 1764 1765 mod.undefed = true; 1766 removeScript(id); 1767 1768 delete defined[id]; 1769 delete urlFetched[map.url]; 1770 delete undefEvents[id]; 1771 1772 //Clean queued defines too. Go backwards 1773 //in array so that the splices do not 1774 //mess up the iteration. 1775 eachReverse(defQueue, function(args, i) { 1776 if (args[0] === id) { 1777 defQueue.splice(i, 1); 1778 } 1779 }); 1780 delete context.defQueueMap[id]; 1781 1782 if (mod) { 1783 //Hold on to listeners in case the 1784 //module will be attempted to be reloaded 1785 //using a different config. 1786 if (mod.events.defined) { 1787 undefEvents[id] = mod.events; 1788 } 1789 1790 cleanRegistry(id); 1791 } 1792 }; 1793 } 1794 1795 return localRequire; 1796 }, 1797 1798 /** 1799 * Called to enable a module if it is still in the registry 1800 * awaiting enablement. A second arg, parent, the parent module, 1801 * is passed in for context, when this method is overridden by 1802 * the optimizer. Not shown here to keep code compact. 1803 */ 1804 enable: function (depMap) { 1805 var mod = getOwn(registry, depMap.id); 1806 if (mod) { 1807 getModule(depMap).enable(); 1808 } 1809 }, 1810 1811 /** 1812 * Internal method used by environment adapters to complete a load event. 1813 * A load event could be a script load or just a load pass from a synchronous 1814 * load call. 1815 * @param {String} moduleName the name of the module to potentially complete. 1816 */ 1817 completeLoad: function (moduleName) { 1818 var found, args, mod, 1819 shim = getOwn(config.shim, moduleName) || {}, 1820 shExports = shim.exports; 1821 1822 takeGlobalQueue(); 1823 1824 while (defQueue.length) { 1825 args = defQueue.shift(); 1826 if (args[0] === null) { 1827 args[0] = moduleName; 1828 //If already found an anonymous module and bound it 1829 //to this name, then this is some other anon module 1830 //waiting for its completeLoad to fire. 1831 if (found) { 1832 break; 1833 } 1834 found = true; 1835 } else if (args[0] === moduleName) { 1836 //Found matching define call for this script! 1837 found = true; 1838 } 1839 1840 callGetModule(args); 1841 } 1842 context.defQueueMap = {}; 1843 1844 //Do this after the cycle of callGetModule in case the result 1845 //of those calls/init calls changes the registry. 1846 mod = getOwn(registry, moduleName); 1847 1848 if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) { 1849 if (config.enforceDefine && (!shExports || !getGlobal(shExports))) { 1850 if (hasPathFallback(moduleName)) { 1851 return; 1852 } else { 1853 return onError(makeError('nodefine', 1854 'No define call for ' + moduleName, 1855 null, 1856 [moduleName])); 1857 } 1858 } else { 1859 //A script that does not call define(), so just simulate 1860 //the call for it. 1861 callGetModule([moduleName, (shim.deps || []), shim.exportsFn]); 1862 } 1863 } 1864 1865 checkLoaded(); 1866 }, 1867 1868 /** 1869 * Converts a module name to a file path. Supports cases where 1870 * moduleName may actually be just an URL. 1871 * Note that it **does not** call normalize on the moduleName, 1872 * it is assumed to have already been normalized. This is an 1873 * internal API, not a public one. Use toUrl for the public API. 1874 */ 1875 nameToUrl: function (moduleName, ext, skipExt) { 1876 var paths, syms, i, parentModule, url, 1877 parentPath, bundleId, 1878 pkgMain = getOwn(config.pkgs, moduleName); 1879 1880 if (pkgMain) { 1881 moduleName = pkgMain; 1882 } 1883 1884 bundleId = getOwn(bundlesMap, moduleName); 1885 1886 if (bundleId) { 1887 return context.nameToUrl(bundleId, ext, skipExt); 1888 } 1889 1890 //If a colon is in the URL, it indicates a protocol is used and it is just 1891 //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?) 1892 //or ends with .js, then assume the user meant to use an url and not a module id. 1893 //The slash is important for protocol-less URLs as well as full paths. 1894 if (req.jsExtRegExp.test(moduleName)) { 1895 //Just a plain path, not module name lookup, so just return it. 1896 //Add extension if it is included. This is a bit wonky, only non-.js things pass 1897 //an extension, this method probably needs to be reworked. 1898 url = moduleName + (ext || ''); 1899 } else { 1900 //A module that needs to be converted to a path. 1901 paths = config.paths; 1902 1903 syms = moduleName.split('/'); 1904 //For each module name segment, see if there is a path 1905 //registered for it. Start with most specific name 1906 //and work up from it. 1907 for (i = syms.length; i > 0; i -= 1) { 1908 parentModule = syms.slice(0, i).join('/'); 1909 1910 parentPath = getOwn(paths, parentModule); 1911 if (parentPath) { 1912 //If an array, it means there are a few choices, 1913 //Choose the one that is desired 1914 if (isArray(parentPath)) { 1915 parentPath = parentPath[0]; 1916 } 1917 syms.splice(0, i, parentPath); 1918 break; 1919 } 1920 } 1921 1922 //Join the path parts together, then figure out if baseUrl is needed. 1923 url = syms.join('/'); 1924 url += (ext || (/^data\:|^blob\:|\?/.test(url) || skipExt ? '' : '.js')); 1925 url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url; 1926 } 1927 1928 return config.urlArgs && !/^blob\:/.test(url) ? 1929 url + config.urlArgs(moduleName, url) : url; 1930 }, 1931 1932 //Delegates to req.load. Broken out as a separate function to 1933 //allow overriding in the optimizer. 1934 load: function (id, url) { 1935 req.load(context, id, url); 1936 }, 1937 1938 /** 1939 * Executes a module callback function. Broken out as a separate function 1940 * solely to allow the build system to sequence the files in the built 1941 * layer in the right sequence. 1942 * 1943 * @private 1944 */ 1945 execCb: function (name, callback, args, exports) { 1946 return callback.apply(exports, args); 1947 }, 1948 1949 /** 1950 * callback for script loads, used to check status of loading. 1951 * 1952 * @param {Event} evt the event from the browser for the script 1953 * that was loaded. 1954 */ 1955 onScriptLoad: function (evt) { 1956 //Using currentTarget instead of target for Firefox 2.0's sake. Not 1957 //all old browsers will be supported, but this one was easy enough 1958 //to support and still makes sense. 1959 if (evt.type === 'load' || 1960 (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) { 1961 //Reset interactive script so a script node is not held onto for 1962 //to long. 1963 interactiveScript = null; 1964 1965 //Pull out the name of the module and the context. 1966 var data = getScriptData(evt); 1967 context.completeLoad(data.id); 1968 } 1969 }, 1970 1971 /** 1972 * Callback for script errors. 1973 */ 1974 onScriptError: function (evt) { 1975 var data = getScriptData(evt); 1976 if (!hasPathFallback(data.id)) { 1977 var parents = []; 1978 eachProp(registry, function(value, key) { 1979 if (key.indexOf('_@r') !== 0) { 1980 each(value.depMaps, function(depMap) { 1981 if (depMap.id === data.id) { 1982 parents.push(key); 1983 return true; 1984 } 1985 }); 1986 } 1987 }); 1988 return onError(makeError('scripterror', 'Script error for "' + data.id + 1989 (parents.length ? 1990 '", needed by: ' + parents.join(', ') : 1991 '"'), evt, [data.id])); 1992 } 1993 } 1994 }; 1995 1996 context.require = context.makeRequire(); 1997 return context; 1998 } 1999 2000 /** 2001 * Main entry point. 2002 * 2003 * If the only argument to require is a string, then the module that 2004 * is represented by that string is fetched for the appropriate context. 2005 * 2006 * If the first argument is an array, then it will be treated as an array 2007 * of dependency string names to fetch. An optional function callback can 2008 * be specified to execute when all of those dependencies are available. 2009 * 2010 * Make a local req variable to help Caja compliance (it assumes things 2011 * on a require that are not standardized), and to give a short 2012 * name for minification/local scope use. 2013 */ 2014 req = requirejs = function (deps, callback, errback, optional) { 2015 2016 //Find the right context, use default 2017 var context, config, 2018 contextName = defContextName; 2019 2020 // Determine if have config object in the call. 2021 if (!isArray(deps) && typeof deps !== 'string') { 2022 // deps is a config object 2023 config = deps; 2024 if (isArray(callback)) { 2025 // Adjust args if there are dependencies 2026 deps = callback; 2027 callback = errback; 2028 errback = optional; 2029 } else { 2030 deps = []; 2031 } 2032 } 2033 2034 if (config && config.context) { 2035 contextName = config.context; 2036 } 2037 2038 context = getOwn(contexts, contextName); 2039 if (!context) { 2040 context = contexts[contextName] = req.s.newContext(contextName); 2041 } 2042 2043 if (config) { 2044 context.configure(config); 2045 } 2046 2047 return context.require(deps, callback, errback); 2048 }; 2049 2050 /** 2051 * Support require.config() to make it easier to cooperate with other 2052 * AMD loaders on globally agreed names. 2053 */ 2054 req.config = function (config) { 2055 return req(config); 2056 }; 2057 2058 /** 2059 * Execute something after the current tick 2060 * of the event loop. Override for other envs 2061 * that have a better solution than setTimeout. 2062 * @param {Function} fn function to execute later. 2063 */ 2064 req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) { 2065 setTimeout(fn, 4); 2066 } : function (fn) { fn(); }; 2067 2068 /** 2069 * Export require as a global, but only if it does not already exist. 2070 */ 2071 if (!require) { 2072 require = req; 2073 } 2074 2075 req.version = version; 2076 2077 //Used to filter out dependencies that are already paths. 2078 req.jsExtRegExp = /^\/|:|\?|\.js$/; 2079 req.isBrowser = isBrowser; 2080 s = req.s = { 2081 contexts: contexts, 2082 newContext: newContext 2083 }; 2084 2085 //Create default context. 2086 req({}); 2087 2088 //Exports some context-sensitive methods on global require. 2089 each([ 2090 'toUrl', 2091 'undef', 2092 'defined', 2093 'specified' 2094 ], function (prop) { 2095 //Reference from contexts instead of early binding to default context, 2096 //so that during builds, the latest instance of the default context 2097 //with its config gets used. 2098 req[prop] = function () { 2099 var ctx = contexts[defContextName]; 2100 return ctx.require[prop].apply(ctx, arguments); 2101 }; 2102 }); 2103 2104 if (isBrowser) { 2105 head = s.head = document.getElementsByTagName('head')[0]; 2106 //If BASE tag is in play, using appendChild is a problem for IE6. 2107 //When that browser dies, this can be removed. Details in this jQuery bug: 2108 //http://dev.jquery.com/ticket/2709 2109 baseElement = document.getElementsByTagName('base')[0]; 2110 if (baseElement) { 2111 head = s.head = baseElement.parentNode; 2112 } 2113 } 2114 2115 /** 2116 * Any errors that require explicitly generates will be passed to this 2117 * function. Intercept/override it if you want custom error handling. 2118 * @param {Error} err the error object. 2119 */ 2120 req.onError = defaultOnError; 2121 2122 /** 2123 * Creates the node for the load command. Only used in browser envs. 2124 */ 2125 req.createNode = function (config, moduleName, url) { 2126 var node = config.xhtml ? 2127 document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') : 2128 document.createElement('script'); 2129 node.type = config.scriptType || 'text/javascript'; 2130 node.charset = 'utf-8'; 2131 node.async = true; 2132 return node; 2133 }; 2134 2135 /** 2136 * Does the request to load a module for the browser case. 2137 * Make this a separate function to allow other environments 2138 * to override it. 2139 * 2140 * @param {Object} context the require context to find state. 2141 * @param {String} moduleName the name of the module. 2142 * @param {Object} url the URL to the module. 2143 */ 2144 req.load = function (context, moduleName, url) { 2145 var config = (context && context.config) || {}, 2146 node; 2147 if (isBrowser) { 2148 //In the browser so use a script tag 2149 node = req.createNode(config, moduleName, url); 2150 2151 node.setAttribute('data-requirecontext', context.contextName); 2152 node.setAttribute('data-requiremodule', moduleName); 2153 2154 //Set up load listener. Test attachEvent first because IE9 has 2155 //a subtle issue in its addEventListener and script onload firings 2156 //that do not match the behavior of all other browsers with 2157 //addEventListener support, which fire the onload event for a 2158 //script right after the script execution. See: 2159 //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution 2160 //UNFORTUNATELY Opera implements attachEvent but does not follow the script 2161 //script execution mode. 2162 if (node.attachEvent && 2163 //Check if node.attachEvent is artificially added by custom script or 2164 //natively supported by browser 2165 //read https://github.com/requirejs/requirejs/issues/187 2166 //if we can NOT find [native code] then it must NOT natively supported. 2167 //in IE8, node.attachEvent does not have toString() 2168 //Note the test for "[native code" with no closing brace, see: 2169 //https://github.com/requirejs/requirejs/issues/273 2170 !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && 2171 !isOpera) { 2172 //Probably IE. IE (at least 6-8) do not fire 2173 //script onload right after executing the script, so 2174 //we cannot tie the anonymous define call to a name. 2175 //However, IE reports the script as being in 'interactive' 2176 //readyState at the time of the define call. 2177 useInteractive = true; 2178 2179 node.attachEvent('onreadystatechange', context.onScriptLoad); 2180 //It would be great to add an error handler here to catch 2181 //404s in IE9+. However, onreadystatechange will fire before 2182 //the error handler, so that does not help. If addEventListener 2183 //is used, then IE will fire error before load, but we cannot 2184 //use that pathway given the connect.microsoft.com issue 2185 //mentioned above about not doing the 'script execute, 2186 //then fire the script load event listener before execute 2187 //next script' that other browsers do. 2188 //Best hope: IE10 fixes the issues, 2189 //and then destroys all installs of IE 6-9. 2190 //node.attachEvent('onerror', context.onScriptError); 2191 } else { 2192 node.addEventListener('load', context.onScriptLoad, false); 2193 node.addEventListener('error', context.onScriptError, false); 2194 } 2195 node.src = url; 2196 2197 //Calling onNodeCreated after all properties on the node have been 2198 //set, but before it is placed in the DOM. 2199 if (config.onNodeCreated) { 2200 config.onNodeCreated(node, config, moduleName, url); 2201 } 2202 2203 //For some cache cases in IE 6-8, the script executes before the end 2204 //of the appendChild execution, so to tie an anonymous define 2205 //call to the module name (which is stored on the node), hold on 2206 //to a reference to this node, but clear after the DOM insertion. 2207 currentlyAddingScript = node; 2208 if (baseElement) { 2209 head.insertBefore(node, baseElement); 2210 } else { 2211 head.appendChild(node); 2212 } 2213 currentlyAddingScript = null; 2214 2215 return node; 2216 } else if (isWebWorker) { 2217 try { 2218 //In a web worker, use importScripts. This is not a very 2219 //efficient use of importScripts, importScripts will block until 2220 //its script is downloaded and evaluated. However, if web workers 2221 //are in play, the expectation is that a build has been done so 2222 //that only one script needs to be loaded anyway. This may need 2223 //to be reevaluated if other use cases become common. 2224 2225 // Post a task to the event loop to work around a bug in WebKit 2226 // where the worker gets garbage-collected after calling 2227 // importScripts(): https://webkit.org/b/153317 2228 setTimeout(function() {}, 0); 2229 importScripts(url); 2230 2231 //Account for anonymous modules 2232 context.completeLoad(moduleName); 2233 } catch (e) { 2234 context.onError(makeError('importscripts', 2235 'importScripts failed for ' + 2236 moduleName + ' at ' + url, 2237 e, 2238 [moduleName])); 2239 } 2240 } 2241 }; 2242 2243 function getInteractiveScript() { 2244 if (interactiveScript && interactiveScript.readyState === 'interactive') { 2245 return interactiveScript; 2246 } 2247 2248 eachReverse(scripts(), function (script) { 2249 if (script.readyState === 'interactive') { 2250 return (interactiveScript = script); 2251 } 2252 }); 2253 return interactiveScript; 2254 } 2255 2256 //Look for a data-main script attribute, which could also adjust the baseUrl. 2257 if (isBrowser && !cfg.skipDataMain) { 2258 //Figure out baseUrl. Get it from the script tag with require.js in it. 2259 eachReverse(scripts(), function (script) { 2260 //Set the 'head' where we can append children by 2261 //using the script's parent. 2262 if (!head) { 2263 head = script.parentNode; 2264 } 2265 2266 //Look for a data-main attribute to set main script for the page 2267 //to load. If it is there, the path to data main becomes the 2268 //baseUrl, if it is not already set. 2269 dataMain = script.getAttribute('data-main'); 2270 if (dataMain) { 2271 //Preserve dataMain in case it is a path (i.e. contains '?') 2272 mainScript = dataMain; 2273 2274 //Set final baseUrl if there is not already an explicit one, 2275 //but only do so if the data-main value is not a loader plugin 2276 //module ID. 2277 if (!cfg.baseUrl && mainScript.indexOf('!') === -1) { 2278 //Pull off the directory of data-main for use as the 2279 //baseUrl. 2280 src = mainScript.split('/'); 2281 mainScript = src.pop(); 2282 subPath = src.length ? src.join('/') + '/' : './'; 2283 2284 cfg.baseUrl = subPath; 2285 } 2286 2287 //Strip off any trailing .js since mainScript is now 2288 //like a module name. 2289 mainScript = mainScript.replace(jsSuffixRegExp, ''); 2290 2291 //If mainScript is still a path, fall back to dataMain 2292 if (req.jsExtRegExp.test(mainScript)) { 2293 mainScript = dataMain; 2294 } 2295 2296 //Put the data-main script in the files to load. 2297 cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript]; 2298 2299 return true; 2300 } 2301 }); 2302 } 2303 2304 /** 2305 * The function that handles definitions of modules. Differs from 2306 * require() in that a string for the module should be the first argument, 2307 * and the function to execute after dependencies are loaded should 2308 * return a value to define the module corresponding to the first argument's 2309 * name. 2310 */ 2311 define = function (name, deps, callback) { 2312 var node, context; 2313 2314 //Allow for anonymous modules 2315 if (typeof name !== 'string') { 2316 //Adjust args appropriately 2317 callback = deps; 2318 deps = name; 2319 name = null; 2320 } 2321 2322 //This module may not have dependencies 2323 if (!isArray(deps)) { 2324 callback = deps; 2325 deps = null; 2326 } 2327
2328 //If no name, and callback is a function, then figure out if it a 2329 //CommonJS thing with dependencies. 2330 if (!deps && isFunction(callback)) { 2331 deps = []; 2332 //Remove comments from the callback string, 2333 //look for require calls, and pull them into the dependencies, 2334 //but only if there are function args. 2335 if (callback.length) { 2336 callback 2337 .toString() 2338 .replace(commentRegExp, commentReplace) 2339 .replace(cjsRequireRegExp, function (match, dep) { 2340 deps.push(dep); 2341 }); 2342 2343 //May be a CommonJS thing even without require calls, but still 2344 //could use exports, and module. Avoid doing exports and module 2345 //work though if it just needs require. 2346 //REQUIRES the function to expect the CommonJS variables in the 2347 //order listed below. 2348 deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps); 2349 } 2350 } 2351 2352 //If in IE 6-8 and hit an anonymous define() call, do the interactive 2353 //work. 2354 if (useInteractive) { 2355 node = currentlyAddingScript || getInteractiveScript(); 2356 if (node) { 2357 if (!name) { 2358 name = node.getAttribute('data-requiremodule'); 2359 } 2360 context = contexts[node.getAttribute('data-requirecontext')]; 2361 } 2362 } 2363 2364 //Always save off evaluating the def call until the script onload handler. 2365 //This allows multiple modules to be in a file without prematurely 2366 //tracing dependencies, and allows for anonymous module support, 2367 //where the module name is not known until the script onload event 2368 //occurs. If no context, use the global queue, and get it processed 2369 //in the onscript load callback. 2370 if (context) { 2371 context.defQueue.push([name, deps, callback]); 2372 context.defQueueMap[name] = true; 2373 } else { 2374 globalDefQueue.push([name, deps, callback]); 2375 } 2376 }; 2377 2378 define.amd = { 2379 jQuery: true 2380 }; 2381 2382 /** 2383 * Executes the text. Normally just uses eval, but can be modified 2384 * to use a better, environment-specific call. Only used for transpiling 2385 * loader plugins, not for plain JS modules. 2386 * @param {String} text the text to execute/evaluate. 2387 */ 2388 req.exec = function (text) { 2389 /*jslint evil: true */ 2390 return eval(text); 2391 }; 2392 2393 //Set up with config info. 2394 req(cfg); 2395}(this, (typeof setTimeout === 'undefined' ? undefined : setTimeout))); 2396 2397 2398 2399 this.requirejsVars = { 2400 require: require, 2401 requirejs: require, 2402 define: define 2403 }; 2404 2405 if (env === 'browser') { 2406 //sloppy since eval enclosed with use strict causes problems if the source 2407//text is not strict-compliant. 2408/*jslint sloppy: true, evil: true */ 2409/*global require, XMLHttpRequest */ 2410 2411(function () { 2412 // Separate function to avoid eval pollution, same with arguments use. 2413 function exec() { 2414 eval(arguments[0]); 2415 } 2416 2417 require.load = function (context, moduleName, url) { 2418 var xhr = new XMLHttpRequest(); 2419 2420 xhr.open('GET', url, true); 2421 xhr.send(); 2422 2423 xhr.onreadystatechange = function () { 2424 if (xhr.readyState === 4) { 2425 exec(xhr.responseText); 2426 2427 //Support anonymous modules. 2428 context.completeLoad(moduleName); 2429 } 2430 }; 2431 }; 2432}()); 2433 } else if (env === 'rhino') { 2434 /*global require: false, java: false, load: false */ 2435 2436(function () { 2437 'use strict'; 2438 require.load = function (context, moduleName, url) { 2439 2440 load(url); 2441 2442 //Support anonymous modules. 2443 context.completeLoad(moduleName); 2444 }; 2445 2446}()); 2447 } else if (env === 'node') { 2448 this.requirejsVars.nodeRequire = nodeRequire; 2449 require.nodeRequire = nodeRequire; 2450 2451 //Explicity not strict since this file contains an eval call, and do not want 2452//to enforce strict on code evaluated that way. See 2453//https://github.com/requirejs/r.js/issues/774 2454/*jslint regexp: false, sloppy: true*/ 2455/*global require: false, define: false, requirejsVars: false, process: false */ 2456 2457/** 2458 * This adapter assumes that x.js has loaded it and set up 2459 * some variables. This adapter just allows limited RequireJS 2460 * usage from within the requirejs directory. The general 2461 * node adapater is r.js. 2462 */ 2463 2464(function () { 2465 var nodeReq = requirejsVars.nodeRequire, 2466 req = requirejsVars.require, 2467 def = requirejsVars.define, 2468 fs = nodeReq('fs'), 2469 path = nodeReq('path'), 2470 vm = nodeReq('vm'), 2471 //In Node 0.7+ existsSync is on fs. 2472 exists = fs.existsSync || path.existsSync, 2473 hasOwn = Object.prototype.hasOwnProperty; 2474 2475 function hasProp(obj, prop) { 2476 return hasOwn.call(obj, prop); 2477 } 2478 2479 function syncTick(fn) { 2480 fn(); 2481 } 2482 2483 function makeError(message, moduleName) { 2484 var err = new Error(message); 2485 err.requireModules = [moduleName]; 2486 return err; 2487 } 2488 2489 //Supply an implementation that allows synchronous get of a module. 2490 req.get = function (context, moduleName, relModuleMap, localRequire) { 2491 if (moduleName === "require" || moduleName === "exports" || moduleName === "module") { 2492 context.onError(makeError("Explicit require of " + moduleName + " is not allowed.", moduleName)); 2493 } 2494 2495 var ret, oldTick, 2496 moduleMap = context.makeModuleMap(moduleName, relModuleMap, false, true); 2497 2498 //Normalize module name, if it contains . or .. 2499 moduleName = moduleMap.id; 2500 2501 if (hasProp(context.defined, moduleName)) { 2502 ret = context.defined[moduleName]; 2503 } else { 2504 if (ret === undefined) { 2505 //Make sure nextTick for this type of call is sync-based. 2506 oldTick = context.nextTick; 2507 context.nextTick = syncTick; 2508 try { 2509 if (moduleMap.prefix) { 2510 //A plugin, call requirejs to handle it. Now that 2511 //nextTick is syncTick, the require will complete 2512 //synchronously. 2513 localRequire([moduleMap.originalName]); 2514 2515 //Now that plugin is loaded, can regenerate the moduleMap 2516 //to get the final, normalized ID. 2517 moduleMap = context.makeModuleMap(moduleMap.originalName, relModuleMap, false, true); 2518 moduleName = moduleMap.id; 2519 } else { 2520 //Try to dynamically fetch it. 2521 req.load(context, moduleName, moduleMap.url); 2522 2523 //Enable the module 2524 context.enable(moduleMap, relModuleMap); 2525 } 2526 2527 //Break any cycles by requiring it normally, but this will 2528 //finish synchronously 2529 context.require([moduleName]); 2530 2531 //The above calls are sync, so can do the next thing safely. 2532 ret = context.defined[moduleName]; 2533 } finally { 2534 context.nextTick = oldTick; 2535 } 2536 } 2537 } 2538 2539 return ret; 2540 }; 2541 2542 req.nextTick = function (fn) { 2543 process.nextTick(fn); 2544 }; 2545 2546 //Add wrapper around the code so that it gets the requirejs
2547 //API instead of the Node API, and it is done lexically so 2548 //that it survives later execution. 2549 req.makeNodeWrapper = function (contents) { 2550 return '(function (require, requirejs, define) { ' + 2551 contents + 2552 '\n}(requirejsVars.require, requirejsVars.requirejs, requirejsVars.define));'; 2553 }; 2554 2555 req.load = function (context, moduleName, url) { 2556 var contents, err, 2557 config = context.config; 2558 2559 if (config.shim[moduleName] && (!config.suppress || !config.suppress.nodeShim)) { 2560 console.warn('Shim config not supported in Node, may or may not work. Detected ' + 2561 'for module: ' + moduleName); 2562 } 2563 2564 if (exists(url)) { 2565 contents = fs.readFileSync(url, 'utf8'); 2566 2567 contents = req.makeNodeWrapper(contents); 2568 try { 2569 vm.runInThisContext(contents, fs.realpathSync(url)); 2570 } catch (e) { 2571 err = new Error('Evaluating ' + url + ' as module "' + 2572 moduleName + '" failed with error: ' + e); 2573 err.originalError = e; 2574 err.moduleName = moduleName; 2575 err.requireModules = [moduleName]; 2576 err.fileName = url; 2577 return context.onError(err); 2578 } 2579 } else { 2580 def(moduleName, function () { 2581 //Get the original name, since relative requires may be 2582 //resolved differently in node (issue #202). Also, if relative, 2583 //make it relative to the URL of the item requesting it 2584 //(issue #393) 2585 var dirName, 2586 map = hasProp(context.registry, moduleName) && 2587 context.registry[moduleName].map, 2588 parentMap = map && map.parentMap, 2589 originalName = map && map.originalName; 2590 2591 if (originalName.charAt(0) === '.' && parentMap) { 2592 dirName = parentMap.url.split('/'); 2593 dirName.pop(); 2594 originalName = dirName.join('/') + '/' + originalName; 2595 } 2596 2597 try { 2598 return (context.config.nodeRequire || req.nodeRequire)(originalName); 2599 } catch (e) { 2600 err = new Error('Tried loading "' + moduleName + '" at ' + 2601 url + ' then tried node\'s require("' + 2602 originalName + '") and it failed ' + 2603 'with error: ' + e); 2604 err.originalError = e; 2605 err.moduleName = originalName; 2606 err.requireModules = [moduleName]; 2607 throw err; 2608 } 2609 }); 2610 } 2611 2612 //Support anonymous modules. 2613 context.completeLoad(moduleName); 2614 }; 2615 2616 //Override to provide the function wrapper for define/require. 2617 req.exec = function (text) { 2618 /*jslint evil: true */ 2619 text = req.makeNodeWrapper(text); 2620 return eval(text); 2621 }; 2622}()); 2623 2624 } else if (env === 'xpconnect') { 2625 /*jslint */ 2626/*global require, load */ 2627 2628(function () { 2629 'use strict'; 2630 require.load = function (context, moduleName, url) { 2631 2632 load(url); 2633 2634 //Support anonymous modules. 2635 context.completeLoad(moduleName); 2636 }; 2637 2638}()); 2639 2640 } 2641 2642 //Support a default file name to execute. Useful for hosted envs 2643 //like Joyent where it defaults to a server.js as the only executed 2644 //script. But only do it if this is not an optimization run. 2645 if (commandOption !== 'o' && (!fileName || !jsSuffixRegExp.test(fileName))) { 2646 fileName = 'main.js'; 2647 } 2648 2649 /** 2650 * Loads the library files that can be used for the optimizer, or for other 2651 * tasks. 2652 */ 2653 function loadLib() { 2654 /*jslint strict: false */ 2655/*global Packages: false, process: false, window: false, navigator: false, 2656 document: false, define: false */ 2657 2658/** 2659 * A plugin that modifies any /env/ path to be the right path based on 2660 * the host environment. Right now only works for Node, Rhino and browser. 2661 */ 2662(function () { 2663 var pathRegExp = /(\/|^)env\/|\{env\}/, 2664 env = 'unknown'; 2665 2666 if (typeof process !== 'undefined' && process.versions && !!process.versions.node) { 2667 env = 'node'; 2668 } else if (typeof Packages !== 'undefined') { 2669 env = 'rhino'; 2670 } else if ((typeof navigator !== 'undefined' && typeof document !== 'undefined') || 2671 (typeof importScripts !== 'undefined' && typeof self !== 'undefined')) { 2672 env = 'browser'; 2673 } else if (typeof Components !== 'undefined' && Components.classes && Components.interfaces) { 2674 env = 'xpconnect'; 2675 } 2676 2677 define('env', { 2678 get: function () { 2679 return env; 2680 }, 2681 2682 load: function (name, req, load, config) { 2683 //Allow override in the config. 2684 if (config.env) { 2685 env = config.env; 2686 } 2687 2688 name = name.replace(pathRegExp, function (match, prefix) { 2689 if (match.indexOf('{') === -1) { 2690 return prefix + env + '/'; 2691 } else { 2692 return env; 2693 } 2694 }); 2695 2696 req([name], function (mod) { 2697 load(mod); 2698 }); 2699 } 2700 });
2701}()); 2702/*jslint plusplus: true */ 2703/*global define, java */ 2704 2705define('lang', function () { 2706 'use strict'; 2707 2708 var lang, isJavaObj, 2709 hasOwn = Object.prototype.hasOwnProperty; 2710 2711 function hasProp(obj, prop) { 2712 return hasOwn.call(obj, prop); 2713 } 2714 2715 isJavaObj = function () { 2716 return false; 2717 }; 2718 2719 //Rhino, but not Nashorn (detected by importPackage not existing) 2720 //Can have some strange foreign objects. 2721 if (typeof java !== 'undefined' && java.lang && java.lang.Object && typeof importPackage !== 'undefined') { 2722 isJavaObj = function (obj) { 2723 return obj instanceof java.lang.Object; 2724 }; 2725 } 2726 2727 lang = { 2728 backSlashRegExp: /\\/g, 2729 ostring: Object.prototype.toString, 2730 2731 isArray: Array.isArray || function (it) { 2732 return lang.ostring.call(it) === "[object Array]"; 2733 }, 2734 2735 isFunction: function(it) { 2736 return lang.ostring.call(it) === "[object Function]"; 2737 }, 2738 2739 isRegExp: function(it) { 2740 return it && it instanceof RegExp; 2741 }, 2742 2743 hasProp: hasProp, 2744 2745 //returns true if the object does not have an own property prop, 2746 //or if it does, it is a falsy value. 2747 falseProp: function (obj, prop) { 2748 return !hasProp(obj, prop) || !obj[prop]; 2749 }, 2750 2751 //gets own property value for given prop on object 2752 getOwn: function (obj, prop) { 2753 return hasProp(obj, prop) && obj[prop]; 2754 }, 2755 2756 _mixin: function(dest, source, override){ 2757 var name; 2758 for (name in source) { 2759 if(source.hasOwnProperty(name) && 2760 (override || !dest.hasOwnProperty(name))) { 2761 dest[name] = source[name]; 2762 } 2763 } 2764 2765 return dest; // Object 2766 }, 2767 2768 /** 2769 * mixin({}, obj1, obj2) is allowed. If the last argument is a boolean, 2770 * then the source objects properties are force copied over to dest. 2771 */ 2772 mixin: function(dest){ 2773 var parameters = Array.prototype.slice.call(arguments), 2774 override, i, l; 2775 2776 if (!dest) { dest = {}; } 2777 2778 if (parameters.length > 2 && typeof arguments[parameters.length-1] === 'boolean') { 2779 override = parameters.pop(); 2780 } 2781 2782 for (i = 1, l = parameters.length; i < l; i++) { 2783 lang._mixin(dest, parameters[i], override); 2784 } 2785 return dest; // Object 2786 }, 2787 2788 /** 2789 * Does a deep mix of source into dest, where source values override 2790 * dest values if a winner is needed. 2791 * @param {Object} dest destination object that receives the mixed 2792 * values. 2793 * @param {Object} source source object contributing properties to mix 2794 * in. 2795 * @return {[Object]} returns dest object with the modification. 2796 */ 2797 deepMix: function(dest, source) { 2798 lang.eachProp(source, function (value, prop) { 2799 if (typeof value === 'object' && value && 2800 !lang.isArray(value) && !lang.isFunction(value) && 2801 !(value instanceof RegExp)) { 2802 2803 if (!dest[prop]) { 2804 dest[prop] = {}; 2805 } 2806 lang.deepMix(dest[prop], value); 2807 } else { 2808 dest[prop] = value; 2809 } 2810 }); 2811 return dest; 2812 }, 2813 2814 /** 2815 * Does a type of deep copy. Do not give it anything fancy, best 2816 * for basic object copies of objects that also work well as 2817 * JSON-serialized things, or has properties pointing to functions. 2818 * For non-array/object values, just returns the same object. 2819 * @param {Object} obj copy properties from this object 2820 * @param {Object} [ignoredProps] optional object whose own properties 2821 * are keys that should be ignored. 2822 * @return {Object} 2823 */ 2824 deeplikeCopy: function (obj, ignoredProps) { 2825 var type, result; 2826 2827 if (lang.isArray(obj)) { 2828 result = [];
2829 obj.forEach(function(value) { 2830 result.push(lang.deeplikeCopy(value, ignoredProps)); 2831 }); 2832 return result; 2833 } 2834 2835 type = typeof obj; 2836 if (obj === null || obj === undefined || type === 'boolean' || 2837 type === 'string' || type === 'number' || lang.isFunction(obj) || 2838 lang.isRegExp(obj)|| isJavaObj(obj)) { 2839 return obj; 2840 } 2841 2842 //Anything else is an object, hopefully. 2843 result = {}; 2844 lang.eachProp(obj, function(value, key) { 2845 if (!ignoredProps || !hasProp(ignoredProps, key)) { 2846 result[key] = lang.deeplikeCopy(value, ignoredProps); 2847 } 2848 }); 2849 return result; 2850 }, 2851 2852 delegate: (function () { 2853 // boodman/crockford delegation w/ cornford optimization 2854 function TMP() {} 2855 return function (obj, props) { 2856 TMP.prototype = obj; 2857 var tmp = new TMP(); 2858 TMP.prototype = null; 2859 if (props) { 2860 lang.mixin(tmp, props); 2861 } 2862 return tmp; // Object 2863 }; 2864 }()), 2865 2866 /** 2867 * Helper function for iterating over an array. If the func returns 2868 * a true value, it will break out of the loop. 2869 */ 2870 each: function each(ary, func) { 2871 if (ary) { 2872 var i; 2873 for (i = 0; i < ary.length; i += 1) { 2874 if (func(ary[i], i, ary)) { 2875 break; 2876 } 2877 } 2878 } 2879 }, 2880 2881 /** 2882 * Cycles over properties in an object and calls a function for each 2883 * property value. If the function returns a truthy value, then the 2884 * iteration is stopped. 2885 */ 2886 eachProp: function eachProp(obj, func) { 2887 var prop; 2888 for (prop in obj) { 2889 if (hasProp(obj, prop)) { 2890 if (func(obj[prop], prop)) { 2891 break; 2892 } 2893 } 2894 } 2895 }, 2896 2897 //Similar to Function.prototype.bind, but the "this" object is specified 2898 //first, since it is easier to read/figure out what "this" will be. 2899 bind: function bind(obj, fn) { 2900 return function () { 2901 return fn.apply(obj, arguments); 2902 }; 2903 }, 2904 2905 //Escapes a content string to be be a string that has characters escaped 2906 //for inclusion as part of a JS string. 2907 jsEscape: function (content) { 2908 return content.replace(/(["'\\])/g, '\\$1') 2909 .replace(/[\f]/g, "\\f") 2910 .replace(/[\b]/g, "\\b") 2911 .replace(/[\n]/g, "\\n") 2912 .replace(/[\t]/g, "\\t") 2913 .replace(/[\r]/g, "\\r"); 2914 } 2915 }; 2916 return lang; 2917}); 2918/** 2919 * prim 0.0.1 Copyright (c) 2012-2014, The Dojo Foundation All Rights Reserved. 2920 * Available via the MIT or new BSD license. 2921 * see: http://github.com/requirejs/prim for details 2922 */ 2923 2924/*global setImmediate, process, setTimeout, define, module */ 2925 2926//Set prime.hideResolutionConflict = true to allow "resolution-races" 2927//in promise-tests to pass. 2928//Since the goal of prim is to be a small impl for trusted code, it is 2929//more important to normally throw in this case so that we can find 2930//logic errors quicker. 2931 2932var prim; 2933(function () { 2934 'use strict'; 2935 var op = Object.prototype, 2936 hasOwn = op.hasOwnProperty; 2937 2938 function hasProp(obj, prop) { 2939 return hasOwn.call(obj, prop); 2940 } 2941 2942 /** 2943 * Helper function for iterating over an array. If the func returns 2944 * a true value, it will break out of the loop. 2945 */ 2946 function each(ary, func) { 2947 if (ary) { 2948 var i; 2949 for (i = 0; i < ary.length; i += 1) { 2950 if (ary[i]) { 2951 func(ary[i], i, ary); 2952 } 2953 } 2954 } 2955 } 2956 2957 function check(p) { 2958 if (hasProp(p, 'e') || hasProp(p, 'v')) { 2959 if (!prim.hideResolutionConflict) { 2960 throw new Error('Prim promise already resolved: ' + 2961 JSON.stringify(p)); 2962 } 2963 return false; 2964 } 2965 return true; 2966 } 2967 2968 function notify(ary, value) { 2969 prim.nextTick(function () { 2970 each(ary, function (item) { 2971 item(value); 2972 }); 2973 }); 2974 } 2975 2976 prim = function prim() { 2977 var p, 2978 ok = [], 2979 fail = []; 2980 2981 return (p = { 2982 callback: function (yes, no) { 2983 if (no) { 2984 p.errback(no); 2985 } 2986 2987 if (hasProp(p, 'v')) { 2988 prim.nextTick(function () { 2989 yes(p.v); 2990 }); 2991 } else { 2992 ok.push(yes); 2993 } 2994 }, 2995 2996 errback: function (no) { 2997 if (hasProp(p, 'e')) { 2998 prim.nextTick(function () { 2999 no(p.e); 3000 }); 3001 } else { 3002 fail.push(no); 3003 } 3004 }, 3005 3006 finished: function () { 3007 return hasProp(p, 'e') || hasProp(p, 'v'); 3008 }, 3009 3010 rejected: function () { 3011 return hasProp(p, 'e'); 3012 }, 3013 3014 resolve: function (v) { 3015 if (check(p)) { 3016 p.v = v; 3017 notify(ok, v); 3018 } 3019 return p; 3020 }, 3021 reject: function (e) { 3022 if (check(p)) { 3023 p.e = e; 3024 notify(fail, e); 3025 } 3026 return p; 3027 }, 3028 3029 start: function (fn) { 3030 p.resolve(); 3031 return p.promise.then(fn); 3032 }, 3033 3034 promise: { 3035 then: function (yes, no) { 3036 var next = prim(); 3037 3038 p.callback(function (v) { 3039 try { 3040 if (yes && typeof yes === 'function') { 3041 v = yes(v); 3042 } 3043 3044 if (v && v.then) { 3045 v.then(next.resolve, next.reject); 3046 } else { 3047 next.resolve(v); 3048 } 3049 } catch (e) { 3050 next.reject(e); 3051 } 3052 }, function (e) { 3053 var err; 3054 3055 try { 3056 if (!no || typeof no !== 'function') { 3057 next.reject(e); 3058 } else { 3059 err = no(e); 3060 3061 if (err && err.then) { 3062 err.then(next.resolve, next.reject); 3063 } else { 3064 next.resolve(err); 3065 } 3066 } 3067 } catch (e2) { 3068 next.reject(e2); 3069 } 3070 }); 3071 3072 return next.promise; 3073 }, 3074 3075 fail: function (no) { 3076 return p.promise.then(null, no); 3077 }, 3078 3079 end: function () { 3080 p.errback(function (e) { 3081 throw e; 3082 }); 3083 } 3084 } 3085 }); 3086 }; 3087 3088 prim.serial = function (ary) { 3089 var result = prim().resolve().promise; 3090 each(ary, function (item) { 3091 result = result.then(function () { 3092 return item(); 3093 }); 3094 }); 3095 return result; 3096 }; 3097 3098 prim.nextTick = typeof setImmediate === 'function' ? setImmediate : 3099 (typeof process !== 'undefined' && process.nextTick ? 3100 process.nextTick : (typeof setTimeout !== 'undefined' ? 3101 function (fn) { 3102 setTimeout(fn, 0); 3103 } : function (fn) { 3104 fn(); 3105 })); 3106 3107 if (typeof define === 'function' && define.amd) { 3108 define('prim', function () { return prim; }); 3109 } else if (typeof module !== 'undefined' && module.exports) { 3110 module.exports = prim; 3111 } 3112}()); 3113if(env === 'browser') { 3114/*jslint strict: false */ 3115/*global define: false, load: false */ 3116 3117//Just a stub for use with uglify's consolidator.js 3118define('browser/assert', function () { 3119 return {}; 3120}); 3121 3122} 3123 3124if(env === 'node') { 3125/*jslint strict: false */ 3126/*global define: false, load: false */ 3127 3128//Needed so that rhino/assert can return a stub for uglify's consolidator.js 3129define('node/assert', ['assert'], function (assert) { 3130 return assert; 3131}); 3132 3133} 3134 3135if(env === 'rhino') { 3136/*jslint strict: false */ 3137/*global define: false, load: false */ 3138 3139//Just a stub for use with uglify's consolidator.js 3140define('rhino/assert', function () { 3141 return {}; 3142}); 3143 3144} 3145 3146if(env === 'xpconnect') { 3147/*jslint strict: false */ 3148/*global define: false, load: false */ 3149 3150//Just a stub for use with uglify's consolidator.js 3151define('xpconnect/assert', function () { 3152 return {}; 3153}); 3154 3155} 3156 3157if(env === 'browser') { 3158/*jslint strict: false */ 3159/*global define: false, process: false */ 3160 3161define('browser/args', function () { 3162 //Always expect config via an API call 3163 return []; 3164}); 3165 3166} 3167 3168if(env === 'node') { 3169/*jslint strict: false */ 3170/*global define: false, process: false */ 3171 3172define('node/args', function () { 3173 //Do not return the "node" or "r.js" arguments 3174 var args = process.argv.slice(2); 3175 3176 //Ignore any command option used for main x.js branching 3177 if (args[0] && args[0].indexOf('-') === 0) { 3178 args = args.slice(1); 3179 } 3180 3181 return args; 3182}); 3183 3184} 3185 3186if(env === 'rhino') { 3187/*jslint strict: false */ 3188/*global define: false, process: false */ 3189 3190var jsLibRhinoArgs = (typeof rhinoArgs !== 'undefined' && rhinoArgs) || [].concat(Array.prototype.slice.call(arguments, 0)); 3191 3192define('rhino/args', function () { 3193 var args = jsLibRhinoArgs; 3194 3195 //Ignore any command option used for main x.js branching 3196 if (args[0] && args[0].indexOf('-') === 0) { 3197 args = args.slice(1); 3198 } 3199 3200 return args; 3201}); 3202 3203} 3204 3205if(env === 'xpconnect') { 3206/*jslint strict: false */ 3207/*global define, xpconnectArgs */ 3208 3209var jsLibXpConnectArgs = (typeof xpconnectArgs !== 'undefined' && xpconnectArgs) || [].concat(Array.prototype.slice.call(arguments, 0)); 3210 3211define('xpconnect/args', function () { 3212 var args = jsLibXpConnectArgs; 3213 3214 //Ignore any command option used for main x.js branching 3215 if (args[0] && args[0].indexOf('-') === 0) { 3216 args = args.slice(1); 3217 } 3218 3219 return args; 3220}); 3221 3222} 3223 3224if(env === 'browser') { 3225/*jslint strict: false */ 3226/*global define: false, console: false */ 3227 3228define('browser/load', ['./file'], function (file) { 3229 function load(fileName) { 3230 eval(file.readFile(fileName)); 3231 } 3232 3233 return load; 3234}); 3235 3236} 3237 3238if(env === 'node') { 3239/*jslint strict: false */ 3240/*global define: false, console: false */ 3241 3242define('node/load', ['fs'], function (fs) { 3243 function load(fileName) { 3244 var contents = fs.readFileSync(fileName, 'utf8'); 3245 process.compile(contents, fileName); 3246 } 3247 3248 return load; 3249}); 3250 3251} 3252 3253if(env === 'rhino') { 3254/*jslint strict: false */ 3255/*global define: false, load: false */ 3256 3257define('rhino/load', function () { 3258 return load; 3259}); 3260 3261} 3262 3263if(env === 'xpconnect') { 3264/*jslint strict: false */ 3265/*global define: false, load: false */ 3266 3267define('xpconnect/load', function () { 3268 return load; 3269}); 3270 3271} 3272 3273if(env === 'browser') { 3274/*jslint sloppy: true, nomen: true */
3275/*global require, define, console, XMLHttpRequest, requirejs, location */ 3276 3277define('browser/file', ['prim'], function (prim) { 3278 3279 var file, 3280 currDirRegExp = /^\.(\/|$)/; 3281 3282 function frontSlash(path) { 3283 return path.replace(/\\/g, '/'); 3284 } 3285 3286 function exists(path) { 3287 var status, xhr = new XMLHttpRequest(); 3288 3289 //Oh yeah, that is right SYNC IO. Behold its glory 3290 //and horrible blocking behavior. 3291 xhr.open('HEAD', path, false); 3292 xhr.send(); 3293 status = xhr.status; 3294 3295 return status === 200 || status === 304; 3296 } 3297 3298 function mkDir(dir) { 3299 console.log('mkDir is no-op in browser'); 3300 } 3301 3302 function mkFullDir(dir) { 3303 console.log('mkFullDir is no-op in browser'); 3304 } 3305 3306 file = { 3307 backSlashRegExp: /\\/g, 3308 exclusionRegExp: /^\./, 3309 getLineSeparator: function () { 3310 return '/'; 3311 }, 3312 3313 exists: function (fileName) { 3314 return exists(fileName); 3315 }, 3316 3317 parent: function (fileName) { 3318 var parts = fileName.split('/'); 3319 parts.pop(); 3320 return parts.join('/'); 3321 }, 3322 3323 /** 3324 * Gets the absolute file path as a string, normalized 3325 * to using front slashes for path separators. 3326 * @param {String} fileName 3327 */ 3328 absPath: function (fileName) { 3329 var dir; 3330 if (currDirRegExp.test(fileName)) { 3331 dir = frontSlash(location.href); 3332 if (dir.indexOf('/') !== -1) { 3333 dir = dir.split('/'); 3334 3335 //Pull off protocol and host, just want 3336 //to allow paths (other build parts, like 3337 //require._isSupportedBuildUrl do not support 3338 //full URLs), but a full path from 3339 //the root. 3340 dir.splice(0, 3); 3341 3342 dir.pop(); 3343 dir = '/' + dir.join('/'); 3344 } 3345 3346 fileName = dir + fileName.substring(1); 3347 } 3348 3349 return fileName; 3350 }, 3351 3352 normalize: function (fileName) { 3353 return fileName; 3354 }, 3355 3356 isFile: function (path) { 3357 return true; 3358 }, 3359 3360 isDirectory: function (path) { 3361 return false; 3362 }, 3363 3364 getFilteredFileList: function (startDir, regExpFilters, makeUnixPaths) { 3365 console.log('file.getFilteredFileList is no-op in browser'); 3366 }, 3367 3368 copyDir: function (srcDir, destDir, regExpFilter, onlyCopyNew) { 3369 console.log('file.copyDir is no-op in browser'); 3370 3371 }, 3372 3373 copyFile: function (srcFileName, destFileName, onlyCopyNew) { 3374 console.log('file.copyFile is no-op in browser'); 3375 }, 3376 3377 /** 3378 * Renames a file. May fail if "to" already exists or is on another drive. 3379 */ 3380 renameFile: function (from, to) { 3381 console.log('file.renameFile is no-op in browser'); 3382 }, 3383 3384 /** 3385 * Reads a *text* file. 3386 */ 3387 readFile: function (path, encoding) { 3388 var xhr = new XMLHttpRequest(); 3389 3390 //Oh yeah, that is right SYNC IO. Behold its glory 3391 //and horrible blocking behavior. 3392 xhr.open('GET', path, false); 3393 xhr.send(); 3394 3395 return xhr.responseText; 3396 }, 3397 3398 readFileAsync: function (path, encoding) { 3399 var xhr = new XMLHttpRequest(), 3400 d = prim(); 3401 3402 xhr.open('GET', path, true); 3403 xhr.send(); 3404 3405 xhr.onreadystatechange = function () { 3406 if (xhr.readyState === 4) { 3407 if (xhr.status > 400) { 3408 d.reject(new Error('Status: ' + xhr.status + ': ' + xhr.statusText)); 3409 } else { 3410 d.resolve(xhr.responseText); 3411 } 3412 } 3413 }; 3414 3415 return d.promise; 3416 }, 3417 3418 saveUtf8File: function (fileName, fileContents) { 3419 //summary: saves a *text* file using UTF-8 encoding. 3420 file.saveFile(fileName, fileContents, "utf8"); 3421 }, 3422 3423 saveFile: function (fileName, fileContents, encoding) { 3424 requirejs.browser.saveFile(fileName, fileContents, encoding); 3425 }, 3426 3427 deleteFile: function (fileName) { 3428 console.log('file.deleteFile is no-op in browser'); 3429 }, 3430 3431 /** 3432 * Deletes any empty directories under the given directory. 3433 */ 3434 deleteEmptyDirs: function (startDir) { 3435 console.log('file.deleteEmptyDirs is no-op in browser'); 3436 } 3437 }; 3438 3439 return file; 3440 3441}); 3442 3443} 3444 3445if(env === 'node') { 3446/*jslint plusplus: false, octal:false, strict: false */ 3447/*global define: false, process: false */ 3448 3449define('node/file', ['fs', 'path', 'prim'], function (fs, path, prim) { 3450 3451 var isWindows = process.platform === 'win32', 3452 windowsDriveRegExp = /^[a-zA-Z]\:\/$/, 3453 file; 3454 3455 function frontSlash(path) { 3456 return path.replace(/\\/g, '/'); 3457 } 3458 3459 function exists(path) {
3460 if (isWindows && path.charAt(path.length - 1) === '/' && 3461 path.charAt(path.length - 2) !== ':') { 3462 path = path.substring(0, path.length - 1); 3463 } 3464 3465 try { 3466 fs.statSync(path); 3467 return true; 3468 } catch (e) { 3469 return false; 3470 } 3471 } 3472 3473 function mkDir(dir) { 3474 if (!exists(dir) && (!isWindows || !windowsDriveRegExp.test(dir))) { 3475 fs.mkdirSync(dir, 511); 3476 } 3477 } 3478 3479 function mkFullDir(dir) { 3480 var parts = dir.split('/'), 3481 currDir = '', 3482 first = true; 3483 3484 parts.forEach(function (part) { 3485 //First part may be empty string if path starts with a slash. 3486 currDir += part + '/'; 3487 first = false; 3488 3489 if (part) { 3490 mkDir(currDir); 3491 } 3492 }); 3493 } 3494 3495 file = { 3496 backSlashRegExp: /\\/g, 3497 exclusionRegExp: /^\./, 3498 getLineSeparator: function () { 3499 return '/'; 3500 }, 3501 3502 exists: function (fileName) { 3503 return exists(fileName); 3504 }, 3505 3506 parent: function (fileName) { 3507 var parts = fileName.split('/'); 3508 parts.pop(); 3509 return parts.join('/'); 3510 }, 3511 3512 /** 3513 * Gets the absolute file path as a string, normalized 3514 * to using front slashes for path separators. 3515 * @param {String} fileName 3516 */ 3517 absPath: function (fileName) { 3518 return frontSlash(path.normalize(frontSlash(fs.realpathSync(fileName)))); 3519 }, 3520 3521 normalize: function (fileName) { 3522 return frontSlash(path.normalize(fileName)); 3523 }, 3524 3525 isFile: function (path) { 3526 return fs.statSync(path).isFile(); 3527 }, 3528 3529 isDirectory: function (path) { 3530 return fs.statSync(path).isDirectory(); 3531 }, 3532 3533 getFilteredFileList: function (/*String*/startDir, /*RegExp*/regExpFilters, /*boolean?*/makeUnixPaths) { 3534 //summary: Recurses startDir and finds matches to the files that match regExpFilters.include 3535 //and do not match regExpFilters.exclude. Or just one regexp can be passed in for regExpFilters, 3536 //and it will be treated as the "include" case. 3537 //Ignores files/directories that start with a period (.) unless exclusionRegExp 3538 //is set to another value. 3539 var files = [], topDir, regExpInclude, regExpExclude, dirFileArray, 3540 i, stat, filePath, ok, dirFiles, fileName; 3541 3542 topDir = startDir; 3543 3544 regExpInclude = regExpFilters.include || regExpFilters; 3545 regExpExclude = regExpFilters.exclude || null; 3546 3547 if (file.exists(topDir)) { 3548 dirFileArray = fs.readdirSync(topDir); 3549 for (i = 0; i < dirFileArray.length; i++) { 3550 fileName = dirFileArray[i]; 3551 filePath = path.join(topDir, fileName); 3552 stat = fs.statSync(filePath); 3553 if (stat.isFile()) { 3554 if (makeUnixPaths) { 3555 //Make sure we have a JS string. 3556 if (filePath.indexOf("/") === -1) { 3557 filePath = frontSlash(filePath); 3558 } 3559 } 3560 3561 ok = true; 3562 if (regExpInclude) { 3563 ok = filePath.match(regExpInclude); 3564 } 3565 if (ok && regExpExclude) { 3566 ok = !filePath.match(regExpExclude); 3567 } 3568 3569 if (ok && (!file.exclusionRegExp || 3570 !file.exclusionRegExp.test(fileName))) { 3571 files.push(filePath); 3572 } 3573 } else if (stat.isDirectory() && 3574 (!file.exclusionRegExp || !file.exclusionRegExp.test(fileName))) { 3575 dirFiles = this.getFilteredFileList(filePath, regExpFilters, makeUnixPaths); 3576 //Do not use push.apply for dir listings, can hit limit of max number 3577 //of arguments to a function call, #921.
3578 dirFiles.forEach(function (dirFile) { 3579 files.push(dirFile); 3580 }); 3581 } 3582 } 3583 } 3584 3585 return files; //Array 3586 }, 3587 3588 copyDir: function (/*String*/srcDir, /*String*/destDir, /*RegExp?*/regExpFilter, /*boolean?*/onlyCopyNew) { 3589 //summary: copies files from srcDir to destDir using the regExpFilter to determine if the 3590 //file should be copied. Returns a list file name strings of the destinations that were copied. 3591 regExpFilter = regExpFilter || /\w/; 3592 3593 //Normalize th directory names, but keep front slashes. 3594 //path module on windows now returns backslashed paths. 3595 srcDir = frontSlash(path.normalize(srcDir)); 3596 destDir = frontSlash(path.normalize(destDir)); 3597 3598 var fileNames = file.getFilteredFileList(srcDir, regExpFilter, true), 3599 copiedFiles = [], i, srcFileName, destFileName; 3600 3601 for (i = 0; i < fileNames.length; i++) { 3602 srcFileName = fileNames[i]; 3603 destFileName = srcFileName.replace(srcDir, destDir); 3604 3605 if (file.copyFile(srcFileName, destFileName, onlyCopyNew)) { 3606 copiedFiles.push(destFileName); 3607 } 3608 } 3609 3610 return copiedFiles.length ? copiedFiles : null; //Array or null 3611 }, 3612 3613 copyFile: function (/*String*/srcFileName, /*String*/destFileName, /*boolean?*/onlyCopyNew) { 3614 //summary: copies srcFileName to destFileName. If onlyCopyNew is set, it only copies the file if 3615 //srcFileName is newer than destFileName. Returns a boolean indicating if the copy occurred. 3616 var parentDir; 3617 3618 //logger.trace("Src filename: " + srcFileName); 3619 //logger.trace("Dest filename: " + destFileName); 3620 3621 //If onlyCopyNew is true, then compare dates and only copy if the src is newer 3622 //than dest. 3623 if (onlyCopyNew) { 3624 if (file.exists(destFileName) && fs.statSync(destFileName).mtime.getTime() >= fs.statSync(srcFileName).mtime.getTime()) { 3625 return false; //Boolean 3626 } 3627 } 3628 3629 //Make sure destination dir exists. 3630 parentDir = path.dirname(destFileName); 3631 if (!file.exists(parentDir)) { 3632 mkFullDir(parentDir); 3633 } 3634 3635 fs.writeFileSync(destFileName, fs.readFileSync(srcFileName, 'binary'), 'binary'); 3636 3637 return true; //Boolean 3638 }, 3639 3640 /** 3641 * Renames a file. May fail if "to" already exists or is on another drive. 3642 */ 3643 renameFile: function (from, to) { 3644 return fs.renameSync(from, to); 3645 }, 3646 3647 /** 3648 * Reads a *text* file. 3649 */ 3650 readFile: function (/*String*/path, /*String?*/encoding) { 3651 if (encoding === 'utf-8') { 3652 encoding = 'utf8'; 3653 } 3654 if (!encoding) { 3655 encoding = 'utf8'; 3656 } 3657 3658 var text = fs.readFileSync(path, encoding); 3659 3660 //Hmm, would not expect to get A BOM, but it seems to happen, 3661 //remove it just in case. 3662 if (text.indexOf('\uFEFF') === 0) { 3663 text = text.substring(1, text.length); 3664 } 3665 3666 return text; 3667 }, 3668 3669 readFileAsync: function (path, encoding) { 3670 var d = prim(); 3671 try { 3672 d.resolve(file.readFile(path, encoding)); 3673 } catch (e) { 3674 d.reject(e); 3675 } 3676 return d.promise; 3677 }, 3678 3679 saveUtf8File: function (/*String*/fileName, /*String*/fileContents) { 3680 //summary: saves a *text* file using UTF-8 encoding. 3681 file.saveFile(fileName, fileContents, "utf8"); 3682 }, 3683 3684 saveFile: function (/*String*/fileName, /*String*/fileContents, /*String?*/encoding) { 3685 //summary: saves a *text* file. 3686 var parentDir; 3687 3688 if (encoding === 'utf-8') { 3689 encoding = 'utf8'; 3690 } 3691 if (!encoding) { 3692 encoding = 'utf8'; 3693 } 3694 3695 //Make sure destination directories exist. 3696 parentDir = path.dirname(fileName); 3697 if (!file.exists(parentDir)) { 3698 mkFullDir(parentDir); 3699 } 3700 3701 fs.writeFileSync(fileName, fileContents, encoding); 3702 }, 3703 3704 deleteFile: function (/*String*/fileName) { 3705 //summary: deletes a file or directory if it exists. 3706 var files, i, stat; 3707 if (file.exists(fileName)) { 3708 stat = fs.lstatSync(fileName); 3709 if (stat.isDirectory()) { 3710 files = fs.readdirSync(fileName); 3711 for (i = 0; i < files.length; i++) { 3712 this.deleteFile(path.join(fileName, files[i])); 3713 } 3714 fs.rmdirSync(fileName); 3715 } else { 3716 fs.unlinkSync(fileName); 3717 } 3718 } 3719 }, 3720 3721 3722 /** 3723 * Deletes any empty directories under the given directory. 3724 */ 3725 deleteEmptyDirs: function (startDir) { 3726 var dirFileArray, i, fileName, filePath, stat; 3727 3728 if (file.exists(startDir)) { 3729 dirFileArray = fs.readdirSync(startDir); 3730 for (i = 0; i < dirFileArray.length; i++) { 3731 fileName = dirFileArray[i]; 3732 filePath = path.join(startDir, fileName); 3733 stat = fs.lstatSync(filePath); 3734 if (stat.isDirectory()) { 3735 file.deleteEmptyDirs(filePath); 3736 } 3737 } 3738 3739 //If directory is now empty, remove it. 3740 if (fs.readdirSync(startDir).length === 0) { 3741 file.deleteFile(startDir); 3742 } 3743 } 3744 } 3745 }; 3746 3747 return file; 3748 3749}); 3750 3751} 3752 3753if(env === 'rhino') { 3754//Helper functions to deal with file I/O. 3755 3756/*jslint plusplus: false */ 3757/*global java: false, define: false */ 3758 3759define('rhino/file', ['prim'], function (prim) { 3760 var file = {
3761 backSlashRegExp: /\\/g, 3762 3763 exclusionRegExp: /^\./, 3764 3765 getLineSeparator: function () { 3766 return file.lineSeparator; 3767 }, 3768 3769 lineSeparator: java.lang.System.getProperty("line.separator"), //Java String 3770 3771 exists: function (fileName) { 3772 return (new java.io.File(fileName)).exists(); 3773 }, 3774 3775 parent: function (fileName) { 3776 return file.absPath((new java.io.File(fileName)).getParentFile()); 3777 }, 3778 3779 normalize: function (fileName) { 3780 return file.absPath(fileName); 3781 }, 3782 3783 isFile: function (path) { 3784 return (new java.io.File(path)).isFile(); 3785 }, 3786 3787 isDirectory: function (path) { 3788 return (new java.io.File(path)).isDirectory(); 3789 }, 3790 3791 /** 3792 * Gets the absolute file path as a string, normalized 3793 * to using front slashes for path separators. 3794 * @param {java.io.File||String} file 3795 */ 3796 absPath: function (fileObj) { 3797 if (typeof fileObj === "string") { 3798 fileObj = new java.io.File(fileObj); 3799 } 3800 return (fileObj.getCanonicalPath() + "").replace(file.backSlashRegExp, "/"); 3801 }, 3802 3803 getFilteredFileList: function (/*String*/startDir, /*RegExp*/regExpFilters, /*boolean?*/makeUnixPaths, /*boolean?*/startDirIsJavaObject) { 3804 //summary: Recurses startDir and finds matches to the files that match regExpFilters.include 3805 //and do not match regExpFilters.exclude. Or just one regexp can be passed in for regExpFilters, 3806 //and it will be treated as the "include" case. 3807 //Ignores files/directories that start with a period (.) unless exclusionRegExp 3808 //is set to another value. 3809 var files = [], topDir, regExpInclude, regExpExclude, dirFileArray, 3810 i, fileObj, filePath, ok, dirFiles; 3811 3812 topDir = startDir; 3813 if (!startDirIsJavaObject) { 3814 topDir = new java.io.File(startDir); 3815 } 3816 3817 regExpInclude = regExpFilters.include || regExpFilters; 3818 regExpExclude = regExpFilters.exclude || null; 3819 3820 if (topDir.exists()) { 3821 dirFileArray = topDir.listFiles(); 3822 for (i = 0; i < dirFileArray.length; i++) { 3823 fileObj = dirFileArray[i]; 3824 if (fileObj.isFile()) { 3825 filePath = fileObj.getPath(); 3826 if (makeUnixPaths) { 3827 //Make sure we have a JS string. 3828 filePath = String(filePath); 3829 if (filePath.indexOf("/") === -1) { 3830 filePath = filePath.replace(/\\/g, "/"); 3831 } 3832 } 3833 3834 ok = true; 3835 if (regExpInclude) { 3836 ok = filePath.match(regExpInclude); 3837 } 3838 if (ok && regExpExclude) { 3839 ok = !filePath.match(regExpExclude); 3840 } 3841 3842 if (ok && (!file.exclusionRegExp || 3843 !file.exclusionRegExp.test(fileObj.getName()))) { 3844 files.push(filePath); 3845 } 3846 } else if (fileObj.isDirectory() && 3847 (!file.exclusionRegExp || !file.exclusionRegExp.test(fileObj.getName()))) { 3848 dirFiles = this.getFilteredFileList(fileObj, regExpFilters, makeUnixPaths, true); 3849 //Do not use push.apply for dir listings, can hit limit of max number 3850 //of arguments to a function call, #921. 3851 dirFiles.forEach(function (dirFile) { 3852 files.push(dirFile); 3853 }); 3854 } 3855 } 3856 } 3857 3858 return files; //Array 3859 }, 3860 3861 copyDir: function (/*String*/srcDir, /*String*/destDir, /*RegExp?*/regExpFilter, /*boolean?*/onlyCopyNew) { 3862 //summary: copies files from srcDir to destDir using the regExpFilter to determine if the 3863 //file should be copied. Returns a list file name strings of the destinations that were copied. 3864 regExpFilter = regExpFilter || /\w/; 3865 3866 var fileNames = file.getFilteredFileList(srcDir, regExpFilter, true), 3867 copiedFiles = [], i, srcFileName, destFileName; 3868 3869 for (i = 0; i < fileNames.length; i++) { 3870 srcFileName = fileNames[i]; 3871 destFileName = srcFileName.replace(srcDir, destDir); 3872 3873 if (file.copyFile(srcFileName, destFileName, onlyCopyNew)) { 3874 copiedFiles.push(destFileName); 3875 } 3876 } 3877 3878 return copiedFiles.length ? copiedFiles : null; //Array or null 3879 }, 3880 3881 copyFile: function (/*String*/srcFileName, /*String*/destFileName, /*boolean?*/onlyCopyNew) { 3882 //summary: copies srcFileName to destFileName. If onlyCopyNew is set, it only copies the file if 3883 //srcFileName is newer than destFileName. Returns a boolean indicating if the copy occurred.
3884 var destFile = new java.io.File(destFileName), srcFile, parentDir, 3885 srcChannel, destChannel; 3886 3887 //logger.trace("Src filename: " + srcFileName); 3888 //logger.trace("Dest filename: " + destFileName); 3889 3890 //If onlyCopyNew is true, then compare dates and only copy if the src is newer 3891 //than dest. 3892 if (onlyCopyNew) { 3893 srcFile = new java.io.File(srcFileName); 3894 if (destFile.exists() && destFile.lastModified() >= srcFile.lastModified()) { 3895 return false; //Boolean 3896 } 3897 } 3898 3899 //Make sure destination dir exists. 3900 parentDir = destFile.getParentFile(); 3901 if (!parentDir.exists()) { 3902 if (!parentDir.mkdirs()) { 3903 throw "Could not create directory: " + parentDir.getCanonicalPath(); 3904 } 3905 } 3906 3907 //Java's version of copy file. 3908 srcChannel = new java.io.FileInputStream(srcFileName).getChannel(); 3909 destChannel = new java.io.FileOutputStream(destFileName).getChannel(); 3910 destChannel.transferFrom(srcChannel, 0, srcChannel.size()); 3911 srcChannel.close(); 3912 destChannel.close(); 3913 3914 return true; //Boolean 3915 }, 3916 3917 /** 3918 * Renames a file. May fail if "to" already exists or is on another drive. 3919 */ 3920 renameFile: function (from, to) { 3921 return (new java.io.File(from)).renameTo((new java.io.File(to))); 3922 }, 3923 3924 readFile: function (/*String*/path, /*String?*/encoding) { 3925 //A file read function that can deal with BOMs 3926 encoding = encoding || "utf-8"; 3927 var fileObj = new java.io.File(path), 3928 input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(fileObj), encoding)), 3929 stringBuffer, line; 3930 try { 3931 stringBuffer = new java.lang.StringBuffer(); 3932 line = input.readLine(); 3933 3934 // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324 3935 // http://www.unicode.org/faq/utf_bom.html 3936 3937 // Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK: 3938 // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058 3939 if (line && line.length() && line.charAt(0) === 0xfeff) { 3940 // Eat the BOM, since we've already found the encoding on this file, 3941 // and we plan to concatenating this buffer with others; the BOM should 3942 // only appear at the top of a file. 3943 line = line.substring(1); 3944 } 3945 while (line !== null) { 3946 stringBuffer.append(line); 3947 stringBuffer.append(file.lineSeparator); 3948 line = input.readLine(); 3949 } 3950 //Make sure we return a JavaScript string and not a Java string. 3951 return String(stringBuffer.toString()); //String 3952 } finally { 3953 input.close(); 3954 } 3955 }, 3956 3957 readFileAsync: function (path, encoding) { 3958 var d = prim(); 3959 try { 3960 d.resolve(file.readFile(path, encoding)); 3961 } catch (e) { 3962 d.reject(e); 3963 } 3964 return d.promise; 3965 }, 3966 3967 saveUtf8File: function (/*String*/fileName, /*String*/fileContents) { 3968 //summary: saves a file using UTF-8 encoding. 3969 file.saveFile(fileName, fileContents, "utf-8"); 3970 }, 3971 3972 saveFile: function (/*String*/fileName, /*String*/fileContents, /*String?*/encoding) { 3973 //summary: saves a file. 3974 var outFile = new java.io.File(fileName), outWriter, parentDir, os; 3975 3976 parentDir = outFile.getAbsoluteFile().getParentFile(); 3977 if (!parentDir.exists()) { 3978 if (!parentDir.mkdirs()) { 3979 throw "Could not create directory: " + parentDir.getAbsolutePath(); 3980 } 3981 } 3982 3983 if (encoding) { 3984 outWriter = new java.io.OutputStreamWriter(new java.io.FileOutputStream(outFile), encoding); 3985 } else { 3986 outWriter = new java.io.OutputStreamWriter(new java.io.FileOutputStream(outFile)); 3987 } 3988 3989 os = new java.io.BufferedWriter(outWriter); 3990 try { 3991 //If in Nashorn, need to coerce the JS string to a Java string so that 3992 //writer.write method dispatch correctly detects the type. 3993 if (typeof importPackage !== 'undefined') { 3994 os.write(fileContents); 3995 } else { 3996 os.write(new java.lang.String(fileContents)); 3997 } 3998 } finally { 3999 os.close(); 4000 } 4001 }, 4002 4003 deleteFile: function (/*String*/fileName) { 4004 //summary: deletes a file or directory if it exists.
4005 var fileObj = new java.io.File(fileName), files, i; 4006 if (fileObj.exists()) { 4007 if (fileObj.isDirectory()) { 4008 files = fileObj.listFiles(); 4009 for (i = 0; i < files.length; i++) { 4010 this.deleteFile(files[i]); 4011 } 4012 } 4013 fileObj["delete"](); 4014 } 4015 }, 4016 4017 /** 4018 * Deletes any empty directories under the given directory. 4019 * The startDirIsJavaObject is private to this implementation's 4020 * recursion needs. 4021 */ 4022 deleteEmptyDirs: function (startDir, startDirIsJavaObject) { 4023 var topDir = startDir, 4024 dirFileArray, i, fileObj; 4025 4026 if (!startDirIsJavaObject) { 4027 topDir = new java.io.File(startDir); 4028 } 4029 4030 if (topDir.exists()) { 4031 dirFileArray = topDir.listFiles(); 4032 for (i = 0; i < dirFileArray.length; i++) { 4033 fileObj = dirFileArray[i]; 4034 if (fileObj.isDirectory()) { 4035 file.deleteEmptyDirs(fileObj, true); 4036 } 4037 } 4038 4039 //If the directory is empty now, delete it. 4040 if (topDir.listFiles().length === 0) { 4041 file.deleteFile(String(topDir.getPath())); 4042 } 4043 } 4044 } 4045 }; 4046 4047 return file; 4048}); 4049 4050} 4051 4052if(env === 'xpconnect') { 4053//Helper functions to deal with file I/O. 4054 4055/*jslint plusplus: false */ 4056/*global define, Components, xpcUtil */ 4057 4058define('xpconnect/file', ['prim'], function (prim) { 4059 var file, 4060 Cc = Components.classes, 4061 Ci = Components.interfaces, 4062 //Depends on xpcUtil which is set up in x.js 4063 xpfile = xpcUtil.xpfile; 4064 4065 function mkFullDir(dirObj) { 4066 //1 is DIRECTORY_TYPE, 511 is 0777 permissions 4067 if (!dirObj.exists()) { 4068 dirObj.create(1, 511); 4069 } 4070 } 4071 4072 file = { 4073 backSlashRegExp: /\\/g, 4074 4075 exclusionRegExp: /^\./, 4076 4077 getLineSeparator: function () { 4078 return file.lineSeparator; 4079 }, 4080 4081 lineSeparator: ('@mozilla.org/windows-registry-key;1' in Cc) ? 4082 '\r\n' : '\n', 4083 4084 exists: function (fileName) { 4085 return xpfile(fileName).exists(); 4086 }, 4087 4088 parent: function (fileName) { 4089 return xpfile(fileName).parent; 4090 }, 4091 4092 normalize: function (fileName) { 4093 return file.absPath(fileName); 4094 }, 4095 4096 isFile: function (path) { 4097 return xpfile(path).isFile(); 4098 }, 4099 4100 isDirectory: function (path) { 4101 return xpfile(path).isDirectory(); 4102 }, 4103 4104 /** 4105 * Gets the absolute file path as a string, normalized 4106 * to using front slashes for path separators. 4107 * @param {java.io.File||String} file 4108 */ 4109 absPath: function (fileObj) { 4110 if (typeof fileObj === "string") { 4111 fileObj = xpfile(fileObj); 4112 } 4113 return fileObj.path; 4114 }, 4115 4116 getFilteredFileList: function (/*String*/startDir, /*RegExp*/regExpFilters, /*boolean?*/makeUnixPaths, /*boolean?*/startDirIsObject) { 4117 //summary: Recurses startDir and finds matches to the files that match regExpFilters.include 4118 //and do not match regExpFilters.exclude. Or just one regexp can be passed in for regExpFilters, 4119 //and it will be treated as the "include" case. 4120 //Ignores files/directories that start with a period (.) unless exclusionRegExp 4121 //is set to another value. 4122 var files = [], topDir, regExpInclude, regExpExclude, dirFileArray, 4123 fileObj, filePath, ok, dirFiles; 4124 4125 topDir = startDir; 4126 if (!startDirIsObject) { 4127 topDir = xpfile(startDir); 4128 } 4129 4130 regExpInclude = regExpFilters.include || regExpFilters; 4131 regExpExclude = regExpFilters.exclude || null; 4132 4133 if (topDir.exists()) { 4134 dirFileArray = topDir.directoryEntries; 4135 while (dirFileArray.hasMoreElements()) { 4136 fileObj = dirFileArray.getNext().QueryInterface(Ci.nsILocalFile); 4137 if (fileObj.isFile()) { 4138 filePath = fileObj.path; 4139 if (makeUnixPaths) { 4140 if (filePath.indexOf("/") === -1) { 4141 filePath = filePath.replace(/\\/g, "/"); 4142 } 4143 } 4144 4145 ok = true; 4146 if (regExpInclude) { 4147 ok = filePath.match(regExpInclude); 4148 } 4149 if (ok && regExpExclude) { 4150 ok = !filePath.match(regExpExclude); 4151 } 4152 4153 if (ok && (!file.exclusionRegExp || 4154 !file.exclusionRegExp.test(fileObj.leafName))) { 4155 files.push(filePath); 4156 } 4157 } else if (fileObj.isDirectory() && 4158 (!file.exclusionRegExp || !file.exclusionRegExp.test(fileObj.leafName))) { 4159 dirFiles = this.getFilteredFileList(fileObj, regExpFilters, makeUnixPaths, true); 4160 //Do not use push.apply for dir listings, can hit limit of max number 4161 //of arguments to a function call, #921.
4162 dirFiles.forEach(function (dirFile) { 4163 files.push(dirFile); 4164 }); 4165 } 4166 } 4167 } 4168 4169 return files; //Array 4170 }, 4171 4172 copyDir: function (/*String*/srcDir, /*String*/destDir, /*RegExp?*/regExpFilter, /*boolean?*/onlyCopyNew) { 4173 //summary: copies files from srcDir to destDir using the regExpFilter to determine if the 4174 //file should be copied. Returns a list file name strings of the destinations that were copied. 4175 regExpFilter = regExpFilter || /\w/; 4176 4177 var fileNames = file.getFilteredFileList(srcDir, regExpFilter, true), 4178 copiedFiles = [], i, srcFileName, destFileName; 4179 4180 for (i = 0; i < fileNames.length; i += 1) { 4181 srcFileName = fileNames[i]; 4182 destFileName = srcFileName.replace(srcDir, destDir); 4183 4184 if (file.copyFile(srcFileName, destFileName, onlyCopyNew)) { 4185 copiedFiles.push(destFileName); 4186 } 4187 } 4188 4189 return copiedFiles.length ? copiedFiles : null; //Array or null 4190 }, 4191 4192 copyFile: function (/*String*/srcFileName, /*String*/destFileName, /*boolean?*/onlyCopyNew) { 4193 //summary: copies srcFileName to destFileName. If onlyCopyNew is set, it only copies the file if 4194 //srcFileName is newer than destFileName. Returns a boolean indicating if the copy occurred. 4195 var destFile = xpfile(destFileName), 4196 srcFile = xpfile(srcFileName); 4197 4198 //logger.trace("Src filename: " + srcFileName); 4199 //logger.trace("Dest filename: " + destFileName); 4200 4201 //If onlyCopyNew is true, then compare dates and only copy if the src is newer 4202 //than dest. 4203 if (onlyCopyNew) { 4204 if (destFile.exists() && destFile.lastModifiedTime >= srcFile.lastModifiedTime) { 4205 return false; //Boolean 4206 } 4207 } 4208 4209 srcFile.copyTo(destFile.parent, destFile.leafName); 4210 4211 return true; //Boolean 4212 }, 4213 4214 /** 4215 * Renames a file. May fail if "to" already exists or is on another drive. 4216 */ 4217 renameFile: function (from, to) { 4218 var toFile = xpfile(to); 4219 return xpfile(from).moveTo(toFile.parent, toFile.leafName); 4220 }, 4221 4222 readFile: xpcUtil.readFile, 4223 4224 readFileAsync: function (path, encoding) { 4225 var d = prim(); 4226 try { 4227 d.resolve(file.readFile(path, encoding)); 4228 } catch (e) { 4229 d.reject(e); 4230 } 4231 return d.promise; 4232 }, 4233 4234 saveUtf8File: function (/*String*/fileName, /*String*/fileContents) { 4235 //summary: saves a file using UTF-8 encoding. 4236 file.saveFile(fileName, fileContents, "utf-8"); 4237 }, 4238 4239 saveFile: function (/*String*/fileName, /*String*/fileContents, /*String?*/encoding) { 4240 var outStream, convertStream, 4241 fileObj = xpfile(fileName); 4242 4243 mkFullDir(fileObj.parent); 4244 4245 try { 4246 outStream = Cc['@mozilla.org/network/file-output-stream;1'] 4247 .createInstance(Ci.nsIFileOutputStream); 4248 //438 is decimal for 0777 4249 outStream.init(fileObj, 0x02 | 0x08 | 0x20, 511, 0); 4250 4251 convertStream = Cc['@mozilla.org/intl/converter-output-stream;1'] 4252 .createInstance(Ci.nsIConverterOutputStream); 4253 4254 convertStream.init(outStream, encoding, 0, 0); 4255 convertStream.writeString(fileContents); 4256 } catch (e) { 4257 throw new Error((fileObj && fileObj.path || '') + ': ' + e); 4258 } finally { 4259 if (convertStream) { 4260 convertStream.close(); 4261 } 4262 if (outStream) { 4263 outStream.close(); 4264 } 4265 } 4266 }, 4267 4268 deleteFile: function (/*String*/fileName) { 4269 //summary: deletes a file or directory if it exists. 4270 var fileObj = xpfile(fileName); 4271 if (fileObj.exists()) { 4272 fileObj.remove(true); 4273 } 4274 }, 4275 4276 /** 4277 * Deletes any empty directories under the given directory. 4278 * The startDirIsJavaObject is private to this implementation's 4279 * recursion needs. 4280 */ 4281 deleteEmptyDirs: function (startDir, startDirIsObject) { 4282 var topDir = startDir, 4283 dirFileArray, fileObj; 4284 4285 if (!startDirIsObject) { 4286 topDir = xpfile(startDir); 4287 } 4288 4289 if (topDir.exists()) { 4290 dirFileArray = topDir.directoryEntries; 4291 while (dirFileArray.hasMoreElements()) { 4292 fileObj = dirFileArray.getNext().QueryInterface(Ci.nsILocalFile); 4293 4294 if (fileObj.isDirectory()) { 4295 file.deleteEmptyDirs(fileObj, true); 4296 } 4297 } 4298 4299 //If the directory is empty now, delete it. 4300 dirFileArray = topDir.directoryEntries; 4301 if (!dirFileArray.hasMoreElements()) { 4302 file.deleteFile(topDir.path); 4303 } 4304 } 4305 } 4306 }; 4307 4308 return file; 4309}); 4310 4311} 4312 4313if(env === 'browser') { 4314/*global process */ 4315define('browser/quit', function () { 4316 'use strict'; 4317 return function (code) { 4318 }; 4319}); 4320} 4321 4322if(env === 'node') { 4323/*global process */ 4324define('node/quit', function () { 4325 'use strict'; 4326 return function (code) { 4327 var draining = 0; 4328 var exit = function () { 4329 if (draining === 0) { 4330 process.exit(code); 4331 } else { 4332 draining -= 1;
4333 } 4334 }; 4335 if (process.stdout.bufferSize) { 4336 draining += 1; 4337 process.stdout.once('drain', exit); 4338 } 4339 if (process.stderr.bufferSize) { 4340 draining += 1; 4341 process.stderr.once('drain', exit); 4342 } 4343 exit(); 4344 }; 4345}); 4346 4347} 4348 4349if(env === 'rhino') { 4350/*global quit */ 4351define('rhino/quit', function () { 4352 'use strict'; 4353 return function (code) { 4354 return quit(code); 4355 }; 4356}); 4357 4358} 4359 4360if(env === 'xpconnect') { 4361/*global quit */ 4362define('xpconnect/quit', function () { 4363 'use strict'; 4364 return function (code) { 4365 return quit(code); 4366 }; 4367}); 4368 4369} 4370 4371if(env === 'browser') { 4372/*jslint strict: false */ 4373/*global define: false, console: false */ 4374 4375define('browser/print', function () { 4376 function print(msg) { 4377 console.log(msg); 4378 } 4379 4380 return print; 4381}); 4382 4383} 4384 4385if(env === 'node') { 4386/*jslint strict: false */ 4387/*global define: false, console: false */ 4388 4389define('node/print', function () { 4390 function print(msg) { 4391 console.log(msg); 4392 } 4393 4394 return print; 4395}); 4396 4397} 4398 4399if(env === 'rhino') { 4400/*jslint strict: false */ 4401/*global define: false, print: false */ 4402 4403define('rhino/print', function () { 4404 return print; 4405}); 4406 4407} 4408 4409if(env === 'xpconnect') { 4410/*jslint strict: false */ 4411/*global define: false, print: false */ 4412 4413define('xpconnect/print', function () { 4414 return print; 4415}); 4416 4417} 4418/*jslint nomen: false, strict: false */ 4419/*global define: false */ 4420 4421define('logger', ['env!env/print'], function (print) { 4422 var logger = { 4423 TRACE: 0, 4424 INFO: 1, 4425 WARN: 2, 4426 ERROR: 3, 4427 SILENT: 4,
4428 level: 0, 4429 logPrefix: "", 4430 4431 logLevel: function( level ) { 4432 this.level = level; 4433 }, 4434 4435 trace: function (message) { 4436 if (this.level <= this.TRACE) { 4437 this._print(message); 4438 } 4439 }, 4440 4441 info: function (message) { 4442 if (this.level <= this.INFO) { 4443 this._print(message); 4444 } 4445 }, 4446 4447 warn: function (message) { 4448 if (this.level <= this.WARN) { 4449 this._print(message); 4450 } 4451 }, 4452 4453 error: function (message) { 4454 if (this.level <= this.ERROR) { 4455 this._print(message); 4456 } 4457 }, 4458 4459 _print: function (message) { 4460 this._sysPrint((this.logPrefix ? (this.logPrefix + " ") : "") + message); 4461 }, 4462 4463 _sysPrint: function (message) { 4464 print(message); 4465 } 4466 }; 4467 4468 return logger; 4469}); 4470//Just a blank file to use when building the optimizer with the optimizer, 4471//so that the build does not attempt to inline some env modules, 4472//like Node's fs and path. 4473 4474(function webpackUniversalModuleDefinition(root, factory) { 4475/* istanbul ignore next */ 4476 if(typeof define === 'function' && define.amd) 4477 define('esprima', [], factory); 4478 else if(typeof exports === 'object' && typeof module === 'object') 4479 module.exports = factory(); 4480/* istanbul ignore next */ 4481 else if(typeof exports === 'object') 4482 exports["esprima"] = factory(); 4483 else 4484 root["esprima"] = factory(); 4485})(this, function() { 4486return /******/ (function(modules) { // webpackBootstrap 4487/******/ // The module cache 4488/******/ var installedModules = {}; 4489 4490/******/ // The require function 4491/******/ function __webpack_require__(moduleId) { 4492 4493/******/ // Check if module is in cache 4494/* istanbul ignore if */ 4495/******/ if(installedModules[moduleId]) 4496/******/ return installedModules[moduleId].exports; 4497 4498/******/ // Create a new module (and put it into the cache) 4499/******/ var module = installedModules[moduleId] = { 4500/******/ exports: {}, 4501/******/ id: moduleId, 4502/******/ loaded: false 4503/******/ }; 4504 4505/******/ // Execute the module function 4506/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 4507 4508/******/ // Flag the module as loaded 4509/******/ module.loaded = true; 4510 4511/******/ // Return the exports of the module 4512/******/ return module.exports; 4513/******/ } 4514 4515 4516/******/ // expose the modules object (__webpack_modules__) 4517/******/ __webpack_require__.m = modules; 4518 4519/******/ // expose the module cache 4520/******/ __webpack_require__.c = installedModules; 4521 4522/******/ // __webpack_public_path__ 4523/******/ __webpack_require__.p = ""; 4524 4525/******/ // Load entry module and return exports 4526/******/ return __webpack_require__(0); 4527/******/ }) 4528/************************************************************************/ 4529/******/ ([ 4530/* 0 */ 4531/***/ function(module, exports, __webpack_require__) { 4532 4533 "use strict"; 4534 /* 4535 Copyright JS Foundation and other contributors, https://js.foundation/ 4536 4537 Redistribution and use in source and binary forms, with or without 4538 modification, are permitted provided that the following conditions are met: 4539 4540 * Redistributions of source code must retain the above copyright 4541 notice, this list of conditions and the following disclaimer. 4542 * Redistributions in binary form must reproduce the above copyright 4543 notice, this list of conditions and the following disclaimer in the 4544 documentation and/or other materials provided with the distribution. 4545 4546 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 4547 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4548 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4549 ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY 4550 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 4551 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4552 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 4553 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 4554 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 4555 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4556 */ 4557 Object.defineProperty(exports, "__esModule", { value: true });
vendor: 39,206 bytes, lines 4558-5436
4558 var comment_handler_1 = __webpack_require__(1); 4559 var jsx_parser_1 = __webpack_require__(3); 4560 var parser_1 = __webpack_require__(8); 4561 var tokenizer_1 = __webpack_require__(15); 4562 function parse(code, options, delegate) { 4563 var commentHandler = null; 4564 var proxyDelegate = function (node, metadata) { 4565 if (delegate) { 4566 delegate(node, metadata); 4567 } 4568 if (commentHandler) { 4569 commentHandler.visit(node, metadata); 4570 } 4571 }; 4572 var parserDelegate = (typeof delegate === 'function') ? proxyDelegate : null; 4573 var collectComment = false; 4574 if (options) { 4575 collectComment = (typeof options.comment === 'boolean' && options.comment); 4576 var attachComment = (typeof options.attachComment === 'boolean' && options.attachComment); 4577 if (collectComment || attachComment) { 4578 commentHandler = new comment_handler_1.CommentHandler(); 4579 commentHandler.attach = attachComment; 4580 options.comment = true; 4581 parserDelegate = proxyDelegate; 4582 } 4583 } 4584 var isModule = false; 4585 if (options && typeof options.sourceType === 'string') { 4586 isModule = (options.sourceType === 'module'); 4587 } 4588 var parser; 4589 if (options && typeof options.jsx === 'boolean' && options.jsx) { 4590 parser = new jsx_parser_1.JSXParser(code, options, parserDelegate); 4591 } 4592 else { 4593 parser = new parser_1.Parser(code, options, parserDelegate); 4594 } 4595 var program = isModule ? parser.parseModule() : parser.parseScript(); 4596 var ast = program; 4597 if (collectComment && commentHandler) { 4598 ast.comments = commentHandler.comments; 4599 } 4600 if (parser.config.tokens) { 4601 ast.tokens = parser.tokens; 4602 } 4603 if (parser.config.tolerant) { 4604 ast.errors = parser.errorHandler.errors; 4605 } 4606 return ast; 4607 } 4608 exports.parse = parse; 4609 function parseModule(code, options, delegate) { 4610 var parsingOptions = options || {}; 4611 parsingOptions.sourceType = 'module'; 4612 return parse(code, parsingOptions, delegate); 4613 } 4614 exports.parseModule = parseModule; 4615 function parseScript(code, options, delegate) { 4616 var parsingOptions = options || {}; 4617 parsingOptions.sourceType = 'script'; 4618 return parse(code, parsingOptions, delegate); 4619 } 4620 exports.parseScript = parseScript; 4621 function tokenize(code, options, delegate) { 4622 var tokenizer = new tokenizer_1.Tokenizer(code, options); 4623 var tokens; 4624 tokens = []; 4625 try { 4626 while (true) { 4627 var token = tokenizer.getNextToken(); 4628 if (!token) { 4629 break; 4630 } 4631 if (delegate) { 4632 token = delegate(token); 4633 } 4634 tokens.push(token); 4635 } 4636 } 4637 catch (e) { 4638 tokenizer.errorHandler.tolerate(e); 4639 } 4640 if (tokenizer.errorHandler.tolerant) { 4641 tokens.errors = tokenizer.errors(); 4642 } 4643 return tokens; 4644 } 4645 exports.tokenize = tokenize; 4646 var syntax_1 = __webpack_require__(2); 4647 exports.Syntax = syntax_1.Syntax; 4648 // Sync with *.json manifests. 4649 exports.version = '4.0.1'; 4650 4651 4652/***/ }, 4653/* 1 */ 4654/***/ function(module, exports, __webpack_require__) { 4655 4656 "use strict"; 4657 Object.defineProperty(exports, "__esModule", { value: true }); 4658 var syntax_1 = __webpack_require__(2); 4659 var CommentHandler = (function () { 4660 function CommentHandler() { 4661 this.attach = false; 4662 this.comments = []; 4663 this.stack = []; 4664 this.leading = []; 4665 this.trailing = []; 4666 } 4667 CommentHandler.prototype.insertInnerComments = function (node, metadata) { 4668 // innnerComments for properties empty block 4669 // `function a() {/** comments **\/}` 4670 if (node.type === syntax_1.Syntax.BlockStatement && node.body.length === 0) { 4671 var innerComments = []; 4672 for (var i = this.leading.length - 1; i >= 0; --i) { 4673 var entry = this.leading[i]; 4674 if (metadata.end.offset >= entry.start) { 4675 innerComments.unshift(entry.comment); 4676 this.leading.splice(i, 1); 4677 this.trailing.splice(i, 1); 4678 } 4679 } 4680 if (innerComments.length) { 4681 node.innerComments = innerComments; 4682 } 4683 } 4684 }; 4685 CommentHandler.prototype.findTrailingComments = function (metadata) { 4686 var trailingComments = []; 4687 if (this.trailing.length > 0) { 4688 for (var i = this.trailing.length - 1; i >= 0; --i) { 4689 var entry_1 = this.trailing[i]; 4690 if (entry_1.start >= metadata.end.offset) { 4691 trailingComments.unshift(entry_1.comment); 4692 } 4693 } 4694 this.trailing.length = 0; 4695 return trailingComments; 4696 } 4697 var entry = this.stack[this.stack.length - 1]; 4698 if (entry && entry.node.trailingComments) { 4699 var firstComment = entry.node.trailingComments[0]; 4700 if (firstComment && firstComment.range[0] >= metadata.end.offset) { 4701 trailingComments = entry.node.trailingComments; 4702 delete entry.node.trailingComments; 4703 } 4704 } 4705 return trailingComments; 4706 }; 4707 CommentHandler.prototype.findLeadingComments = function (metadata) { 4708 var leadingComments = []; 4709 var target; 4710 while (this.stack.length > 0) { 4711 var entry = this.stack[this.stack.length - 1]; 4712 if (entry && entry.start >= metadata.start.offset) { 4713 target = entry.node; 4714 this.stack.pop(); 4715 } 4716 else { 4717 break; 4718 } 4719 } 4720 if (target) { 4721 var count = target.leadingComments ? target.leadingComments.length : 0; 4722 for (var i = count - 1; i >= 0; --i) { 4723 var comment = target.leadingComments[i]; 4724 if (comment.range[1] <= metadata.start.offset) { 4725 leadingComments.unshift(comment); 4726 target.leadingComments.splice(i, 1); 4727 } 4728 } 4729 if (target.leadingComments && target.leadingComments.length === 0) { 4730 delete target.leadingComments; 4731 } 4732 return leadingComments; 4733 } 4734 for (var i = this.leading.length - 1; i >= 0; --i) { 4735 var entry = this.leading[i]; 4736 if (entry.start <= metadata.start.offset) { 4737 leadingComments.unshift(entry.comment); 4738 this.leading.splice(i, 1); 4739 } 4740 } 4741 return leadingComments; 4742 }; 4743 CommentHandler.prototype.visitNode = function (node, metadata) { 4744 if (node.type === syntax_1.Syntax.Program && node.body.length > 0) { 4745 return; 4746 } 4747 this.insertInnerComments(node, metadata); 4748 var trailingComments = this.findTrailingComments(metadata); 4749 var leadingComments = this.findLeadingComments(metadata); 4750 if (leadingComments.length > 0) { 4751 node.leadingComments = leadingComments; 4752 } 4753 if (trailingComments.length > 0) { 4754 node.trailingComments = trailingComments; 4755 } 4756 this.stack.push({ 4757 node: node, 4758 start: metadata.start.offset 4759 }); 4760 }; 4761 CommentHandler.prototype.visitComment = function (node, metadata) { 4762 var type = (node.type[0] === 'L') ? 'Line' : 'Block'; 4763 var comment = { 4764 type: type, 4765 value: node.value 4766 }; 4767 if (node.range) { 4768 comment.range = node.range; 4769 } 4770 if (node.loc) { 4771 comment.loc = node.loc; 4772 } 4773 this.comments.push(comment); 4774 if (this.attach) { 4775 var entry = { 4776 comment: { 4777 type: type, 4778 value: node.value, 4779 range: [metadata.start.offset, metadata.end.offset] 4780 }, 4781 start: metadata.start.offset 4782 }; 4783 if (node.loc) { 4784 entry.comment.loc = node.loc; 4785 } 4786 node.type = type; 4787 this.leading.push(entry); 4788 this.trailing.push(entry); 4789 } 4790 }; 4791 CommentHandler.prototype.visit = function (node, metadata) { 4792 if (node.type === 'LineComment') { 4793 this.visitComment(node, metadata); 4794 } 4795 else if (node.type === 'BlockComment') { 4796 this.visitComment(node, metadata); 4797 } 4798 else if (this.attach) { 4799 this.visitNode(node, metadata); 4800 } 4801 }; 4802 return CommentHandler; 4803 }()); 4804 exports.CommentHandler = CommentHandler; 4805 4806 4807/***/ }, 4808/* 2 */ 4809/***/ function(module, exports) { 4810 4811 "use strict"; 4812 Object.defineProperty(exports, "__esModule", { value: true }); 4813 exports.Syntax = { 4814 AssignmentExpression: 'AssignmentExpression', 4815 AssignmentPattern: 'AssignmentPattern', 4816 ArrayExpression: 'ArrayExpression', 4817 ArrayPattern: 'ArrayPattern', 4818 ArrowFunctionExpression: 'ArrowFunctionExpression', 4819 AwaitExpression: 'AwaitExpression', 4820 BlockStatement: 'BlockStatement', 4821 BinaryExpression: 'BinaryExpression', 4822 BreakStatement: 'BreakStatement', 4823 CallExpression: 'CallExpression', 4824 CatchClause: 'CatchClause', 4825 ClassBody: 'ClassBody', 4826 ClassDeclaration: 'ClassDeclaration', 4827 ClassExpression: 'ClassExpression', 4828 ConditionalExpression: 'ConditionalExpression', 4829 ContinueStatement: 'ContinueStatement', 4830 DoWhileStatement: 'DoWhileStatement', 4831 DebuggerStatement: 'DebuggerStatement', 4832 EmptyStatement: 'EmptyStatement', 4833 ExportAllDeclaration: 'ExportAllDeclaration', 4834 ExportDefaultDeclaration: 'ExportDefaultDeclaration', 4835 ExportNamedDeclaration: 'ExportNamedDeclaration', 4836 ExportSpecifier: 'ExportSpecifier', 4837 ExpressionStatement: 'ExpressionStatement', 4838 ForStatement: 'ForStatement', 4839 ForOfStatement: 'ForOfStatement', 4840 ForInStatement: 'ForInStatement', 4841 FunctionDeclaration: 'FunctionDeclaration', 4842 FunctionExpression: 'FunctionExpression', 4843 Identifier: 'Identifier', 4844 IfStatement: 'IfStatement', 4845 ImportDeclaration: 'ImportDeclaration', 4846 ImportDefaultSpecifier: 'ImportDefaultSpecifier', 4847 ImportNamespaceSpecifier: 'ImportNamespaceSpecifier', 4848 ImportSpecifier: 'ImportSpecifier', 4849 Literal: 'Literal', 4850 LabeledStatement: 'LabeledStatement', 4851 LogicalExpression: 'LogicalExpression', 4852 MemberExpression: 'MemberExpression', 4853 MetaProperty: 'MetaProperty', 4854 MethodDefinition: 'MethodDefinition', 4855 NewExpression: 'NewExpression', 4856 ObjectExpression: 'ObjectExpression', 4857 ObjectPattern: 'ObjectPattern', 4858 Program: 'Program', 4859 Property: 'Property', 4860 RestElement: 'RestElement', 4861 ReturnStatement: 'ReturnStatement', 4862 SequenceExpression: 'SequenceExpression', 4863 SpreadElement: 'SpreadElement', 4864 Super: 'Super', 4865 SwitchCase: 'SwitchCase', 4866 SwitchStatement: 'SwitchStatement', 4867 TaggedTemplateExpression: 'TaggedTemplateExpression', 4868 TemplateElement: 'TemplateElement', 4869 TemplateLiteral: 'TemplateLiteral', 4870 ThisExpression: 'ThisExpression', 4871 ThrowStatement: 'ThrowStatement', 4872 TryStatement: 'TryStatement', 4873 UnaryExpression: 'UnaryExpression', 4874 UpdateExpression: 'UpdateExpression', 4875 VariableDeclaration: 'VariableDeclaration', 4876 VariableDeclarator: 'VariableDeclarator', 4877 WhileStatement: 'WhileStatement', 4878 WithStatement: 'WithStatement', 4879 YieldExpression: 'YieldExpression' 4880 }; 4881 4882 4883/***/ }, 4884/* 3 */ 4885/***/ function(module, exports, __webpack_require__) { 4886 4887 "use strict"; 4888/* istanbul ignore next */ 4889 var __extends = (this && this.__extends) || (function () { 4890 var extendStatics = Object.setPrototypeOf || 4891 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 4892 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; 4893 return function (d, b) { 4894 extendStatics(d, b); 4895 function __() { this.constructor = d; } 4896 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 4897 }; 4898 })(); 4899 Object.defineProperty(exports, "__esModule", { value: true }); 4900 var character_1 = __webpack_require__(4); 4901 var JSXNode = __webpack_require__(5); 4902 var jsx_syntax_1 = __webpack_require__(6); 4903 var Node = __webpack_require__(7); 4904 var parser_1 = __webpack_require__(8); 4905 var token_1 = __webpack_require__(13); 4906 var xhtml_entities_1 = __webpack_require__(14); 4907 token_1.TokenName[100 /* Identifier */] = 'JSXIdentifier'; 4908 token_1.TokenName[101 /* Text */] = 'JSXText'; 4909 // Fully qualified element name, e.g. <svg:path> returns "svg:path" 4910 function getQualifiedElementName(elementName) { 4911 var qualifiedName; 4912 switch (elementName.type) { 4913 case jsx_syntax_1.JSXSyntax.JSXIdentifier: 4914 var id = elementName; 4915 qualifiedName = id.name; 4916 break; 4917 case jsx_syntax_1.JSXSyntax.JSXNamespacedName: 4918 var ns = elementName; 4919 qualifiedName = getQualifiedElementName(ns.namespace) + ':' + 4920 getQualifiedElementName(ns.name); 4921 break; 4922 case jsx_syntax_1.JSXSyntax.JSXMemberExpression: 4923 var expr = elementName; 4924 qualifiedName = getQualifiedElementName(expr.object) + '.' + 4925 getQualifiedElementName(expr.property); 4926 break; 4927 /* istanbul ignore next */ 4928 default: 4929 break; 4930 } 4931 return qualifiedName; 4932 } 4933 var JSXParser = (function (_super) { 4934 __extends(JSXParser, _super); 4935 function JSXParser(code, options, delegate) { 4936 return _super.call(this, code, options, delegate) || this; 4937 } 4938 JSXParser.prototype.parsePrimaryExpression = function () { 4939 return this.match('<') ? this.parseJSXRoot() : _super.prototype.parsePrimaryExpression.call(this); 4940 }; 4941 JSXParser.prototype.startJSX = function () { 4942 // Unwind the scanner before the lookahead token. 4943 this.scanner.index = this.startMarker.index; 4944 this.scanner.lineNumber = this.startMarker.line; 4945 this.scanner.lineStart = this.startMarker.index - this.startMarker.column; 4946 }; 4947 JSXParser.prototype.finishJSX = function () { 4948 // Prime the next lookahead. 4949 this.nextToken(); 4950 }; 4951 JSXParser.prototype.reenterJSX = function () { 4952 this.startJSX(); 4953 this.expectJSX('}'); 4954 // Pop the closing '}' added from the lookahead. 4955 if (this.config.tokens) { 4956 this.tokens.pop(); 4957 } 4958 }; 4959 JSXParser.prototype.createJSXNode = function () { 4960 this.collectComments(); 4961 return { 4962 index: this.scanner.index, 4963 line: this.scanner.lineNumber, 4964 column: this.scanner.index - this.scanner.lineStart 4965 }; 4966 }; 4967 JSXParser.prototype.createJSXChildNode = function () { 4968 return { 4969 index: this.scanner.index, 4970 line: this.scanner.lineNumber, 4971 column: this.scanner.index - this.scanner.lineStart 4972 }; 4973 }; 4974 JSXParser.prototype.scanXHTMLEntity = function (quote) { 4975 var result = '&'; 4976 var valid = true; 4977 var terminated = false; 4978 var numeric = false; 4979 var hex = false; 4980 while (!this.scanner.eof() && valid && !terminated) { 4981 var ch = this.scanner.source[this.scanner.index]; 4982 if (ch === quote) { 4983 break; 4984 } 4985 terminated = (ch === ';'); 4986 result += ch; 4987 ++this.scanner.index; 4988 if (!terminated) { 4989 switch (result.length) { 4990 case 2: 4991 // e.g. '{' 4992 numeric = (ch === '#'); 4993 break; 4994 case 3: 4995 if (numeric) { 4996 // e.g. 'A' 4997 hex = (ch === 'x'); 4998 valid = hex || character_1.Character.isDecimalDigit(ch.charCodeAt(0)); 4999 numeric = numeric && !hex; 5000 } 5001 break; 5002 default: 5003 valid = valid && !(numeric && !character_1.Character.isDecimalDigit(ch.charCodeAt(0))); 5004 valid = valid && !(hex && !character_1.Character.isHexDigit(ch.charCodeAt(0))); 5005 break; 5006 } 5007 } 5008 } 5009 if (valid && terminated && result.length > 2) { 5010 // e.g. 'A' becomes just '#x41' 5011 var str = result.substr(1, result.length - 2); 5012 if (numeric && str.length > 1) { 5013 result = String.fromCharCode(parseInt(str.substr(1), 10)); 5014 } 5015 else if (hex && str.length > 2) { 5016 result = String.fromCharCode(parseInt('0' + str.substr(1), 16)); 5017 } 5018 else if (!numeric && !hex && xhtml_entities_1.XHTMLEntities[str]) { 5019 result = xhtml_entities_1.XHTMLEntities[str]; 5020 } 5021 } 5022 return result; 5023 }; 5024 // Scan the next JSX token. This replaces Scanner#lex when in JSX mode. 5025 JSXParser.prototype.lexJSX = function () { 5026 var cp = this.scanner.source.charCodeAt(this.scanner.index); 5027 // < > / : = { } 5028 if (cp === 60 || cp === 62 || cp === 47 || cp === 58 || cp === 61 || cp === 123 || cp === 125) { 5029 var value = this.scanner.source[this.scanner.index++]; 5030 return { 5031 type: 7 /* Punctuator */, 5032 value: value, 5033 lineNumber: this.scanner.lineNumber, 5034 lineStart: this.scanner.lineStart, 5035 start: this.scanner.index - 1, 5036 end: this.scanner.index 5037 }; 5038 } 5039 // " ' 5040 if (cp === 34 || cp === 39) { 5041 var start = this.scanner.index; 5042 var quote = this.scanner.source[this.scanner.index++]; 5043 var str = ''; 5044 while (!this.scanner.eof()) { 5045 var ch = this.scanner.source[this.scanner.index++]; 5046 if (ch === quote) { 5047 break; 5048 } 5049 else if (ch === '&') { 5050 str += this.scanXHTMLEntity(quote); 5051 } 5052 else { 5053 str += ch; 5054 } 5055 } 5056 return { 5057 type: 8 /* StringLiteral */, 5058 value: str, 5059 lineNumber: this.scanner.lineNumber, 5060 lineStart: this.scanner.lineStart, 5061 start: start, 5062 end: this.scanner.index 5063 }; 5064 } 5065 // ... or . 5066 if (cp === 46) { 5067 var n1 = this.scanner.source.charCodeAt(this.scanner.index + 1); 5068 var n2 = this.scanner.source.charCodeAt(this.scanner.index + 2); 5069 var value = (n1 === 46 && n2 === 46) ? '...' : '.'; 5070 var start = this.scanner.index; 5071 this.scanner.index += value.length; 5072 return { 5073 type: 7 /* Punctuator */, 5074 value: value, 5075 lineNumber: this.scanner.lineNumber, 5076 lineStart: this.scanner.lineStart, 5077 start: start, 5078 end: this.scanner.index 5079 }; 5080 } 5081 // ` 5082 if (cp === 96) { 5083 // Only placeholder, since it will be rescanned as a real assignment expression. 5084 return { 5085 type: 10 /* Template */, 5086 value: '', 5087 lineNumber: this.scanner.lineNumber, 5088 lineStart: this.scanner.lineStart, 5089 start: this.scanner.index, 5090 end: this.scanner.index 5091 }; 5092 } 5093 // Identifer can not contain backslash (char code 92). 5094 if (character_1.Character.isIdentifierStart(cp) && (cp !== 92)) { 5095 var start = this.scanner.index; 5096 ++this.scanner.index; 5097 while (!this.scanner.eof()) { 5098 var ch = this.scanner.source.charCodeAt(this.scanner.index); 5099 if (character_1.Character.isIdentifierPart(ch) && (ch !== 92)) { 5100 ++this.scanner.index; 5101 } 5102 else if (ch === 45) { 5103 // Hyphen (char code 45) can be part of an identifier. 5104 ++this.scanner.index; 5105 } 5106 else { 5107 break; 5108 } 5109 } 5110 var id = this.scanner.source.slice(start, this.scanner.index); 5111 return { 5112 type: 100 /* Identifier */, 5113 value: id, 5114 lineNumber: this.scanner.lineNumber, 5115 lineStart: this.scanner.lineStart, 5116 start: start, 5117 end: this.scanner.index 5118 }; 5119 } 5120 return this.scanner.lex(); 5121 }; 5122 JSXParser.prototype.nextJSXToken = function () { 5123 this.collectComments(); 5124 this.startMarker.index = this.scanner.index; 5125 this.startMarker.line = this.scanner.lineNumber; 5126 this.startMarker.column = this.scanner.index - this.scanner.lineStart; 5127 var token = this.lexJSX(); 5128 this.lastMarker.index = this.scanner.index; 5129 this.lastMarker.line = this.scanner.lineNumber; 5130 this.lastMarker.column = this.scanner.index - this.scanner.lineStart; 5131 if (this.config.tokens) { 5132 this.tokens.push(this.convertToken(token)); 5133 } 5134 return token; 5135 }; 5136 JSXParser.prototype.nextJSXText = function () { 5137 this.startMarker.index = this.scanner.index; 5138 this.startMarker.line = this.scanner.lineNumber; 5139 this.startMarker.column = this.scanner.index - this.scanner.lineStart; 5140 var start = this.scanner.index; 5141 var text = ''; 5142 while (!this.scanner.eof()) { 5143 var ch = this.scanner.source[this.scanner.index]; 5144 if (ch === '{' || ch === '<') { 5145 break; 5146 } 5147 ++this.scanner.index; 5148 text += ch; 5149 if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) { 5150 ++this.scanner.lineNumber; 5151 if (ch === '\r' && this.scanner.source[this.scanner.index] === '\n') { 5152 ++this.scanner.index; 5153 } 5154 this.scanner.lineStart = this.scanner.index; 5155 } 5156 } 5157 this.lastMarker.index = this.scanner.index; 5158 this.lastMarker.line = this.scanner.lineNumber; 5159 this.lastMarker.column = this.scanner.index - this.scanner.lineStart; 5160 var token = { 5161 type: 101 /* Text */, 5162 value: text, 5163 lineNumber: this.scanner.lineNumber, 5164 lineStart: this.scanner.lineStart, 5165 start: start, 5166 end: this.scanner.index 5167 }; 5168 if ((text.length > 0) && this.config.tokens) { 5169 this.tokens.push(this.convertToken(token)); 5170 } 5171 return token; 5172 }; 5173 JSXParser.prototype.peekJSXToken = function () { 5174 var state = this.scanner.saveState(); 5175 this.scanner.scanComments(); 5176 var next = this.lexJSX(); 5177 this.scanner.restoreState(state); 5178 return next; 5179 }; 5180 // Expect the next JSX token to match the specified punctuator. 5181 // If not, an exception will be thrown. 5182 JSXParser.prototype.expectJSX = function (value) { 5183 var token = this.nextJSXToken(); 5184 if (token.type !== 7 /* Punctuator */ || token.value !== value) { 5185 this.throwUnexpectedToken(token); 5186 } 5187 }; 5188 // Return true if the next JSX token matches the specified punctuator. 5189 JSXParser.prototype.matchJSX = function (value) { 5190 var next = this.peekJSXToken(); 5191 return next.type === 7 /* Punctuator */ && next.value === value; 5192 }; 5193 JSXParser.prototype.parseJSXIdentifier = function () { 5194 var node = this.createJSXNode(); 5195 var token = this.nextJSXToken(); 5196 if (token.type !== 100 /* Identifier */) { 5197 this.throwUnexpectedToken(token); 5198 } 5199 return this.finalize(node, new JSXNode.JSXIdentifier(token.value)); 5200 }; 5201 JSXParser.prototype.parseJSXElementName = function () { 5202 var node = this.createJSXNode(); 5203 var elementName = this.parseJSXIdentifier(); 5204 if (this.matchJSX(':')) { 5205 var namespace = elementName; 5206 this.expectJSX(':'); 5207 var name_1 = this.parseJSXIdentifier(); 5208 elementName = this.finalize(node, new JSXNode.JSXNamespacedName(namespace, name_1)); 5209 } 5210 else if (this.matchJSX('.')) { 5211 while (this.matchJSX('.')) { 5212 var object = elementName; 5213 this.expectJSX('.'); 5214 var property = this.parseJSXIdentifier(); 5215 elementName = this.finalize(node, new JSXNode.JSXMemberExpression(object, property)); 5216 } 5217 } 5218 return elementName; 5219 }; 5220 JSXParser.prototype.parseJSXAttributeName = function () { 5221 var node = this.createJSXNode(); 5222 var attributeName; 5223 var identifier = this.parseJSXIdentifier(); 5224 if (this.matchJSX(':')) { 5225 var namespace = identifier; 5226 this.expectJSX(':'); 5227 var name_2 = this.parseJSXIdentifier(); 5228 attributeName = this.finalize(node, new JSXNode.JSXNamespacedName(namespace, name_2)); 5229 } 5230 else { 5231 attributeName = identifier; 5232 } 5233 return attributeName; 5234 }; 5235 JSXParser.prototype.parseJSXStringLiteralAttribute = function () { 5236 var node = this.createJSXNode(); 5237 var token = this.nextJSXToken(); 5238 if (token.type !== 8 /* StringLiteral */) { 5239 this.throwUnexpectedToken(token); 5240 } 5241 var raw = this.getTokenRaw(token); 5242 return this.finalize(node, new Node.Literal(token.value, raw)); 5243 }; 5244 JSXParser.prototype.parseJSXExpressionAttribute = function () { 5245 var node = this.createJSXNode(); 5246 this.expectJSX('{'); 5247 this.finishJSX(); 5248 if (this.match('}')) { 5249 this.tolerateError('JSX attributes must only be assigned a non-empty expression'); 5250 } 5251 var expression = this.parseAssignmentExpression(); 5252 this.reenterJSX(); 5253 return this.finalize(node, new JSXNode.JSXExpressionContainer(expression)); 5254 }; 5255 JSXParser.prototype.parseJSXAttributeValue = function () { 5256 return this.matchJSX('{') ? this.parseJSXExpressionAttribute() : 5257 this.matchJSX('<') ? this.parseJSXElement() : this.parseJSXStringLiteralAttribute(); 5258 }; 5259 JSXParser.prototype.parseJSXNameValueAttribute = function () { 5260 var node = this.createJSXNode(); 5261 var name = this.parseJSXAttributeName(); 5262 var value = null; 5263 if (this.matchJSX('=')) { 5264 this.expectJSX('='); 5265 value = this.parseJSXAttributeValue(); 5266 } 5267 return this.finalize(node, new JSXNode.JSXAttribute(name, value)); 5268 }; 5269 JSXParser.prototype.parseJSXSpreadAttribute = function () { 5270 var node = this.createJSXNode(); 5271 this.expectJSX('{'); 5272 this.expectJSX('...'); 5273 this.finishJSX(); 5274 var argument = this.parseAssignmentExpression(); 5275 this.reenterJSX(); 5276 return this.finalize(node, new JSXNode.JSXSpreadAttribute(argument)); 5277 }; 5278 JSXParser.prototype.parseJSXAttributes = function () { 5279 var attributes = []; 5280 while (!this.matchJSX('/') && !this.matchJSX('>')) { 5281 var attribute = this.matchJSX('{') ? this.parseJSXSpreadAttribute() : 5282 this.parseJSXNameValueAttribute(); 5283 attributes.push(attribute); 5284 } 5285 return attributes; 5286 }; 5287 JSXParser.prototype.parseJSXOpeningElement = function () { 5288 var node = this.createJSXNode(); 5289 this.expectJSX('<'); 5290 var name = this.parseJSXElementName(); 5291 var attributes = this.parseJSXAttributes(); 5292 var selfClosing = this.matchJSX('/'); 5293 if (selfClosing) { 5294 this.expectJSX('/'); 5295 } 5296 this.expectJSX('>'); 5297 return this.finalize(node, new JSXNode.JSXOpeningElement(name, selfClosing, attributes)); 5298 }; 5299 JSXParser.prototype.parseJSXBoundaryElement = function () { 5300 var node = this.createJSXNode(); 5301 this.expectJSX('<'); 5302 if (this.matchJSX('/')) { 5303 this.expectJSX('/'); 5304 var name_3 = this.parseJSXElementName(); 5305 this.expectJSX('>'); 5306 return this.finalize(node, new JSXNode.JSXClosingElement(name_3)); 5307 } 5308 var name = this.parseJSXElementName(); 5309 var attributes = this.parseJSXAttributes(); 5310 var selfClosing = this.matchJSX('/'); 5311 if (selfClosing) { 5312 this.expectJSX('/'); 5313 } 5314 this.expectJSX('>'); 5315 return this.finalize(node, new JSXNode.JSXOpeningElement(name, selfClosing, attributes)); 5316 }; 5317 JSXParser.prototype.parseJSXEmptyExpression = function () { 5318 var node = this.createJSXChildNode(); 5319 this.collectComments(); 5320 this.lastMarker.index = this.scanner.index; 5321 this.lastMarker.line = this.scanner.lineNumber; 5322 this.lastMarker.column = this.scanner.index - this.scanner.lineStart; 5323 return this.finalize(node, new JSXNode.JSXEmptyExpression()); 5324 }; 5325 JSXParser.prototype.parseJSXExpressionContainer = function () { 5326 var node = this.createJSXNode(); 5327 this.expectJSX('{'); 5328 var expression; 5329 if (this.matchJSX('}')) { 5330 expression = this.parseJSXEmptyExpression(); 5331 this.expectJSX('}'); 5332 } 5333 else { 5334 this.finishJSX(); 5335 expression = this.parseAssignmentExpression(); 5336 this.reenterJSX(); 5337 } 5338 return this.finalize(node, new JSXNode.JSXExpressionContainer(expression)); 5339 }; 5340 JSXParser.prototype.parseJSXChildren = function () { 5341 var children = []; 5342 while (!this.scanner.eof()) { 5343 var node = this.createJSXChildNode(); 5344 var token = this.nextJSXText(); 5345 if (token.start < token.end) { 5346 var raw = this.getTokenRaw(token); 5347 var child = this.finalize(node, new JSXNode.JSXText(token.value, raw)); 5348 children.push(child); 5349 } 5350 if (this.scanner.source[this.scanner.index] === '{') { 5351 var container = this.parseJSXExpressionContainer(); 5352 children.push(container); 5353 } 5354 else { 5355 break; 5356 } 5357 } 5358 return children; 5359 }; 5360 JSXParser.prototype.parseComplexJSXElement = function (el) { 5361 var stack = []; 5362 while (!this.scanner.eof()) { 5363 el.children = el.children.concat(this.parseJSXChildren()); 5364 var node = this.createJSXChildNode(); 5365 var element = this.parseJSXBoundaryElement(); 5366 if (element.type === jsx_syntax_1.JSXSyntax.JSXOpeningElement) { 5367 var opening = element; 5368 if (opening.selfClosing) { 5369 var child = this.finalize(node, new JSXNode.JSXElement(opening, [], null)); 5370 el.children.push(child); 5371 } 5372 else { 5373 stack.push(el); 5374 el = { node: node, opening: opening, closing: null, children: [] }; 5375 } 5376 } 5377 if (element.type === jsx_syntax_1.JSXSyntax.JSXClosingElement) { 5378 el.closing = element; 5379 var open_1 = getQualifiedElementName(el.opening.name); 5380 var close_1 = getQualifiedElementName(el.closing.name); 5381 if (open_1 !== close_1) { 5382 this.tolerateError('Expected corresponding JSX closing tag for %0', open_1); 5383 } 5384 if (stack.length > 0) { 5385 var child = this.finalize(el.node, new JSXNode.JSXElement(el.opening, el.children, el.closing)); 5386 el = stack[stack.length - 1]; 5387 el.children.push(child); 5388 stack.pop(); 5389 } 5390 else { 5391 break; 5392 } 5393 } 5394 } 5395 return el; 5396 }; 5397 JSXParser.prototype.parseJSXElement = function () { 5398 var node = this.createJSXNode(); 5399 var opening = this.parseJSXOpeningElement(); 5400 var children = []; 5401 var closing = null; 5402 if (!opening.selfClosing) { 5403 var el = this.parseComplexJSXElement({ node: node, opening: opening, closing: closing, children: children }); 5404 children = el.children; 5405 closing = el.closing; 5406 } 5407 return this.finalize(node, new JSXNode.JSXElement(opening, children, closing)); 5408 }; 5409 JSXParser.prototype.parseJSXRoot = function () { 5410 // Pop the opening '<' added from the lookahead. 5411 if (this.config.tokens) { 5412 this.tokens.pop(); 5413 } 5414 this.startJSX(); 5415 var element = this.parseJSXElement(); 5416 this.finishJSX(); 5417 return element; 5418 }; 5419 JSXParser.prototype.isStartOfExpression = function () { 5420 return _super.prototype.isStartOfExpression.call(this) || this.match('<'); 5421 }; 5422 return JSXParser; 5423 }(parser_1.Parser)); 5424 exports.JSXParser = JSXParser; 5425 5426 5427/***/ }, 5428/* 4 */ 5429/***/ function(module, exports) { 5430 5431 "use strict"; 5432 Object.defineProperty(exports, "__esModule", { value: true }); 5433 // See also tools/generate-unicode-regex.js. 5434 var Regex = { 5435 // Unicode v8.0.0 NonAsciiIdentifierStart: 5436 NonAsciiIdentifierStart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFB
5436D3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]/, 5437 // Unicode v8.0.0 NonAsciiIdentifierPart: 5438 NonAsciiIdentifierPart: /[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B4\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFB
5438D3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/ 5439 }; 5440 exports.Character = { 5441 /* tslint:disable:no-bitwise */ 5442 fromCodePoint: function (cp) { 5443 return (cp < 0x10000) ? String.fromCharCode(cp) : 5444 String.fromCharCode(0xD800 + ((cp - 0x10000) >> 10)) + 5445 String.fromCharCode(0xDC00 + ((cp - 0x10000) & 1023)); 5446 }, 5447 // https://tc39.github.io/ecma262/#sec-white-space 5448 isWhiteSpace: function (cp) { 5449 return (cp === 0x20) || (cp === 0x09) || (cp === 0x0B) || (cp === 0x0C) || (cp === 0xA0) || 5450 (cp >= 0x1680 && [0x1680, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(cp) >= 0); 5451 }, 5452 // https://tc39.github.io/ecma262/#sec-line-terminators 5453 isLineTerminator: function (cp) { 5454 return (cp === 0x0A) || (cp === 0x0D) || (cp === 0x2028) || (cp === 0x2029); 5455 }, 5456 // https://tc39.github.io/ecma262/#sec-names-and-keywords 5457 isIdentifierStart: function (cp) { 5458 return (cp === 0x24) || (cp === 0x5F) || 5459 (cp >= 0x41 && cp <= 0x5A) || 5460 (cp >= 0x61 && cp <= 0x7A) || 5461 (cp === 0x5C) || 5462 ((cp >= 0x80) && Regex.NonAsciiIdentifierStart.test(exports.Character.fromCodePoint(c
vendor: 8,586 bytes, lines 5462-5714
5462p))); 5463 }, 5464 isIdentifierPart: function (cp) { 5465 return (cp === 0x24) || (cp === 0x5F) || 5466 (cp >= 0x41 && cp <= 0x5A) || 5467 (cp >= 0x61 && cp <= 0x7A) || 5468 (cp >= 0x30 && cp <= 0x39) || 5469 (cp === 0x5C) || 5470 ((cp >= 0x80) && Regex.NonAsciiIdentifierPart.test(exports.Character.fromCodePoint(cp))); 5471 }, 5472 // https://tc39.github.io/ecma262/#sec-literals-numeric-literals 5473 isDecimalDigit: function (cp) { 5474 return (cp >= 0x30 && cp <= 0x39); // 0..9 5475 }, 5476 isHexDigit: function (cp) { 5477 return (cp >= 0x30 && cp <= 0x39) || 5478 (cp >= 0x41 && cp <= 0x46) || 5479 (cp >= 0x61 && cp <= 0x66); // a..f 5480 }, 5481 isOctalDigit: function (cp) { 5482 return (cp >= 0x30 && cp <= 0x37); // 0..7 5483 } 5484 }; 5485 5486 5487/***/ }, 5488/* 5 */ 5489/***/ function(module, exports, __webpack_require__) { 5490 5491 "use strict"; 5492 Object.defineProperty(exports, "__esModule", { value: true }); 5493 var jsx_syntax_1 = __webpack_require__(6); 5494 /* tslint:disable:max-classes-per-file */ 5495 var JSXClosingElement = (function () { 5496 function JSXClosingElement(name) { 5497 this.type = jsx_syntax_1.JSXSyntax.JSXClosingElement; 5498 this.name = name; 5499 } 5500 return JSXClosingElement; 5501 }()); 5502 exports.JSXClosingElement = JSXClosingElement; 5503 var JSXElement = (function () { 5504 function JSXElement(openingElement, children, closingElement) { 5505 this.type = jsx_syntax_1.JSXSyntax.JSXElement; 5506 this.openingElement = openingElement; 5507 this.children = children; 5508 this.closingElement = closingElement; 5509 } 5510 return JSXElement; 5511 }()); 5512 exports.JSXElement = JSXElement; 5513 var JSXEmptyExpression = (function () { 5514 function JSXEmptyExpression() { 5515 this.type = jsx_syntax_1.JSXSyntax.JSXEmptyExpression; 5516 } 5517 return JSXEmptyExpression; 5518 }()); 5519 exports.JSXEmptyExpression = JSXEmptyExpression; 5520 var JSXExpressionContainer = (function () { 5521 function JSXExpressionContainer(expression) { 5522 this.type = jsx_syntax_1.JSXSyntax.JSXExpressionContainer; 5523 this.expression = expression; 5524 } 5525 return JSXExpressionContainer; 5526 }()); 5527 exports.JSXExpressionContainer = JSXExpressionContainer; 5528 var JSXIdentifier = (function () { 5529 function JSXIdentifier(name) { 5530 this.type = jsx_syntax_1.JSXSyntax.JSXIdentifier; 5531 this.name = name; 5532 } 5533 return JSXIdentifier; 5534 }()); 5535 exports.JSXIdentifier = JSXIdentifier; 5536 var JSXMemberExpression = (function () { 5537 function JSXMemberExpression(object, property) { 5538 this.type = jsx_syntax_1.JSXSyntax.JSXMemberExpression; 5539 this.object = object; 5540 this.property = property; 5541 } 5542 return JSXMemberExpression; 5543 }()); 5544 exports.JSXMemberExpression = JSXMemberExpression; 5545 var JSXAttribute = (function () { 5546 function JSXAttribute(name, value) { 5547 this.type = jsx_syntax_1.JSXSyntax.JSXAttribute; 5548 this.name = name; 5549 this.value = value; 5550 } 5551 return JSXAttribute; 5552 }()); 5553 exports.JSXAttribute = JSXAttribute; 5554 var JSXNamespacedName = (function () { 5555 function JSXNamespacedName(namespace, name) { 5556 this.type = jsx_syntax_1.JSXSyntax.JSXNamespacedName; 5557 this.namespace = namespace; 5558 this.name = name; 5559 } 5560 return JSXNamespacedName; 5561 }()); 5562 exports.JSXNamespacedName = JSXNamespacedName; 5563 var JSXOpeningElement = (function () { 5564 function JSXOpeningElement(name, selfClosing, attributes) { 5565 this.type = jsx_syntax_1.JSXSyntax.JSXOpeningElement; 5566 this.name = name; 5567 this.selfClosing = selfClosing; 5568 this.attributes = attributes; 5569 } 5570 return JSXOpeningElement; 5571 }()); 5572 exports.JSXOpeningElement = JSXOpeningElement; 5573 var JSXSpreadAttribute = (function () { 5574 function JSXSpreadAttribute(argument) { 5575 this.type = jsx_syntax_1.JSXSyntax.JSXSpreadAttribute; 5576 this.argument = argument; 5577 } 5578 return JSXSpreadAttribute; 5579 }()); 5580 exports.JSXSpreadAttribute = JSXSpreadAttribute; 5581 var JSXText = (function () { 5582 function JSXText(value, raw) { 5583 this.type = jsx_syntax_1.JSXSyntax.JSXText; 5584 this.value = value; 5585 this.raw = raw; 5586 } 5587 return JSXText; 5588 }()); 5589 exports.JSXText = JSXText; 5590 5591 5592/***/ }, 5593/* 6 */ 5594/***/ function(module, exports) { 5595 5596 "use strict"; 5597 Object.defineProperty(exports, "__esModule", { value: true }); 5598 exports.JSXSyntax = { 5599 JSXAttribute: 'JSXAttribute', 5600 JSXClosingElement: 'JSXClosingElement', 5601 JSXElement: 'JSXElement', 5602 JSXEmptyExpression: 'JSXEmptyExpression', 5603 JSXExpressionContainer: 'JSXExpressionContainer', 5604 JSXIdentifier: 'JSXIdentifier', 5605 JSXMemberExpression: 'JSXMemberExpression', 5606 JSXNamespacedName: 'JSXNamespacedName', 5607 JSXOpeningElement: 'JSXOpeningElement', 5608 JSXSpreadAttribute: 'JSXSpreadAttribute', 5609 JSXText: 'JSXText' 5610 }; 5611 5612 5613/***/ }, 5614/* 7 */ 5615/***/ function(module, exports, __webpack_require__) { 5616 5617 "use strict"; 5618 Object.defineProperty(exports, "__esModule", { value: true }); 5619 var syntax_1 = __webpack_require__(2); 5620 /* tslint:disable:max-classes-per-file */ 5621 var ArrayExpression = (function () { 5622 function ArrayExpression(elements) { 5623 this.type = syntax_1.Syntax.ArrayExpression; 5624 this.elements = elements; 5625 } 5626 return ArrayExpression; 5627 }()); 5628 exports.ArrayExpression = ArrayExpression; 5629 var ArrayPattern = (function () { 5630 function ArrayPattern(elements) { 5631 this.type = syntax_1.Syntax.ArrayPattern; 5632 this.elements = elements; 5633 } 5634 return ArrayPattern; 5635 }()); 5636 exports.ArrayPattern = ArrayPattern; 5637 var ArrowFunctionExpression = (function () { 5638 function ArrowFunctionExpression(params, body, expression) { 5639 this.type = syntax_1.Syntax.ArrowFunctionExpression; 5640 this.id = null; 5641 this.params = params; 5642 this.body = body; 5643 this.generator = false; 5644 this.expression = expression; 5645 this.async = false; 5646 } 5647 return ArrowFunctionExpression; 5648 }()); 5649 exports.ArrowFunctionExpression = ArrowFunctionExpression; 5650 var AssignmentExpression = (function () { 5651 function AssignmentExpression(operator, left, right) { 5652 this.type = syntax_1.Syntax.AssignmentExpression; 5653 this.operator = operator; 5654 this.left = left; 5655 this.right = right; 5656 } 5657 return AssignmentExpression; 5658 }()); 5659 exports.AssignmentExpression = AssignmentExpression; 5660 var AssignmentPattern = (function () { 5661 function AssignmentPattern(left, right) { 5662 this.type = syntax_1.Syntax.AssignmentPattern; 5663 this.left = left; 5664 this.right = right; 5665 } 5666 return AssignmentPattern; 5667 }()); 5668 exports.AssignmentPattern = AssignmentPattern; 5669 var AsyncArrowFunctionExpression = (function () { 5670 function AsyncArrowFunctionExpression(params, body, expression) { 5671 this.type = syntax_1.Syntax.ArrowFunctionExpression; 5672 this.id = null; 5673 this.params = params; 5674 this.body = body; 5675 this.generator = false; 5676 this.expression = expression; 5677 this.async = true; 5678 } 5679 return AsyncArrowFunctionExpression; 5680 }()); 5681 exports.AsyncArrowFunctionExpression = AsyncArrowFunctionExpression; 5682 var AsyncFunctionDeclaration = (function () { 5683 function AsyncFunctionDeclaration(id, params, body) { 5684 this.type = syntax_1.Syntax.FunctionDeclaration; 5685 this.id = id; 5686 this.params = params; 5687 this.body = body; 5688 this.generator = false; 5689 this.expression = false; 5690 this.async = true; 5691 } 5692 return AsyncFunctionDeclaration; 5693 }()); 5694 exports.AsyncFunctionDeclaration = AsyncFunctionDeclaration; 5695 var AsyncFunctionExpression = (function () { 5696 function AsyncFunctionExpression(id, params, body) { 5697 this.type = syntax_1.Syntax.FunctionExpression; 5698 this.id = id; 5699 this.params = params; 5700 this.body = body; 5701 this.generator = false; 5702 this.expression = false; 5703 this.async = true; 5704 } 5705 return AsyncFunctionExpression; 5706 }()); 5707 exports.AsyncFunctionExpression = AsyncFunctionExpression; 5708 var AwaitExpression = (function () { 5709 function AwaitExpression(argument) { 5710 this.type = syntax_1.Syntax.AwaitExpression; 5711 this.argument = argument; 5712 } 5713 return AwaitExpression; 5714 }());
5715 exports.AwaitExpression = AwaitExpression; 5716 var BinaryExpression = (function () { 5717 function BinaryExpression(operator, left, right) { 5718 var logical = (operator === '||' || operator === '&&'); 5719 this.type = logical ? syntax_1.Syntax.LogicalExpression : syntax_1.Syntax.BinaryExpression; 5720 this.operator = operator; 5721 this.left = left; 5722 this.right = right; 5723 } 5724 return BinaryExpression; 5725 }()); 5726 exports.BinaryExpression = BinaryExpression; 5727 var BlockStatement = (function () { 5728 function BlockStatement(body) { 5729 this.type = syntax_1.Syntax.BlockStatement; 5730 this.body = body; 5731 } 5732 return BlockStatement; 5733 }()); 5734 exports.BlockStatement = BlockStatement; 5735 var BreakStatement = (function () { 5736 function BreakStatement(label) { 5737 this.type = syntax_1.Syntax.BreakStatement; 5738 this.label = label; 5739 } 5740 return BreakStatement; 5741 }()); 5742 exports.BreakStatement = BreakStatement; 5743 var CallExpression = (function () { 5744 function CallExpression(callee, args) { 5745 this.type = syntax_1.Syntax.CallExpression; 5746 this.callee = callee; 5747 this.arguments = args; 5748 } 5749 return CallExpression; 5750 }()); 5751 exports.CallExpression = CallExpression; 5752 var CatchClause = (function () { 5753 function CatchClause(param, body) { 5754 this.type = syntax_1.Syntax.CatchClause; 5755 this.param = param; 5756 this.body = body; 5757 } 5758 return CatchClause; 5759 }()); 5760 exports.CatchClause = CatchClause; 5761 var ClassBody = (function () { 5762 function ClassBody(body) { 5763 this.type = syntax_1.Syntax.ClassBody; 5764 this.body = body; 5765 } 5766 return ClassBody; 5767 }()); 5768 exports.ClassBody = ClassBody; 5769 var ClassDeclaration = (function () { 5770 function ClassDeclaration(id, superClass, body) { 5771 this.type = syntax_1.Syntax.ClassDeclaration; 5772 this.id = id; 5773 this.superClass = superClass; 5774 this.body = body; 5775 } 5776 return ClassDeclaration; 5777 }()); 5778 exports.ClassDeclaration = ClassDeclaration; 5779 var ClassExpression = (function () { 5780 function ClassExpression(id, superClass, body) { 5781 this.type = syntax_1.Syntax.ClassExpression; 5782 this.id = id; 5783 this.superClass = superClass; 5784 this.body = body; 5785 } 5786 return ClassExpression; 5787 }()); 5788 exports.ClassExpression = ClassExpression; 5789 var ComputedMemberExpression = (function () { 5790 function ComputedMemberExpression(object, property) { 5791 this.type = syntax_1.Syntax.MemberExpression; 5792 this.computed = true; 5793 this.object = object; 5794 this.property = property; 5795 } 5796 return ComputedMemberExpression; 5797 }()); 5798 exports.ComputedMemberExpression = ComputedMemberExpression; 5799 var ConditionalExpression = (function () { 5800 function ConditionalExpression(test, consequent, alternate) { 5801 this.type = syntax_1.Syntax.ConditionalExpression; 5802 this.test = test; 5803 this.consequent = consequent; 5804 this.alternate = alternate; 5805 } 5806 return ConditionalExpression; 5807 }()); 5808 exports.ConditionalExpression = ConditionalExpression; 5809 var ContinueStatement = (function () { 5810 function ContinueStatement(label) { 5811 this.type = syntax_1.Syntax.ContinueStatement; 5812 this.label = label; 5813 } 5814 return ContinueStatement; 5815 }()); 5816 exports.ContinueStatement = ContinueStatement; 5817 var DebuggerStatement = (function () { 5818 function DebuggerStatement() { 5819 this.type = syntax_1.Syntax.DebuggerStatement; 5820 } 5821 return DebuggerStatement; 5822 }()); 5823 exports.DebuggerStatement = DebuggerStatement; 5824 var Directive = (function () { 5825 function Directive(expression, directive) { 5826 this.type = syntax_1.Syntax.ExpressionStatement; 5827 this.expression = expression; 5828 this.directive = directive; 5829 } 5830 return Directive; 5831 }()); 5832 exports.Directive = Directive; 5833 var DoWhileStatement = (function () { 5834 function DoWhileStatement(body, test) { 5835 this.type = syntax_1.Syntax.DoWhileStatement; 5836 this.body = body; 5837 this.test = test; 5838 } 5839 return DoWhileStatement; 5840 }());
5841 exports.DoWhileStatement = DoWhileStatement; 5842 var EmptyStatement = (function () { 5843 function EmptyStatement() { 5844 this.type = syntax_1.Syntax.EmptyStatement; 5845 } 5846 return EmptyStatement; 5847 }()); 5848 exports.EmptyStatement = EmptyStatement; 5849 var ExportAllDeclaration = (function () { 5850 function ExportAllDeclaration(source) { 5851 this.type = syntax_1.Syntax.ExportAllDeclaration; 5852 this.source = source; 5853 } 5854 return ExportAllDeclaration; 5855 }()); 5856 exports.ExportAllDeclaration = ExportAllDeclaration; 5857 var ExportDefaultDeclaration = (function () { 5858 function ExportDefaultDeclaration(declaration) { 5859 this.type = syntax_1.Syntax.ExportDefaultDeclaration; 5860 this.declaration = declaration; 5861 } 5862 return ExportDefaultDeclaration; 5863 }()); 5864 exports.ExportDefaultDeclaration = ExportDefaultDeclaration; 5865 var ExportNamedDeclaration = (function () { 5866 function ExportNamedDeclaration(declaration, specifiers, source) { 5867 this.type = syntax_1.Syntax.ExportNamedDeclaration; 5868 this.declaration = declaration; 5869 this.specifiers = specifiers; 5870 this.source = source; 5871 } 5872 return ExportNamedDeclaration; 5873 }()); 5874 exports.ExportNamedDeclaration = ExportNamedDeclaration; 5875 var ExportSpecifier = (function () { 5876 function ExportSpecifier(local, exported) { 5877 this.type = syntax_1.Syntax.ExportSpecifier; 5878 this.exported = exported; 5879 this.local = local; 5880 } 5881 return ExportSpecifier; 5882 }()); 5883 exports.ExportSpecifier = ExportSpecifier; 5884 var ExpressionStatement = (function () { 5885 function ExpressionStatement(expression) { 5886 this.type = syntax_1.Syntax.ExpressionStatement; 5887 this.expression = expression; 5888 } 5889 return ExpressionStatement; 5890 }()); 5891 exports.ExpressionStatement = ExpressionStatement; 5892 var ForInStatement = (function () { 5893 function ForInStatement(left, right, body) { 5894 this.type = syntax_1.Syntax.ForInStatement; 5895 this.left = left; 5896 this.right = right; 5897 this.body = body; 5898 this.each = false; 5899 } 5900 return ForInStatement; 5901 }()); 5902 exports.ForInStatement = ForInStatement; 5903 var ForOfStatement = (function () { 5904 function ForOfStatement(left, right, body) { 5905 this.type = syntax_1.Syntax.ForOfStatement; 5906 this.left = left; 5907 this.right = right; 5908 this.body = body; 5909 } 5910 return ForOfStatement; 5911 }()); 5912 exports.ForOfStatement = ForOfStatement; 5913 var ForStatement = (function () { 5914 function ForStatement(init, test, update, body) { 5915 this.type = syntax_1.Syntax.ForStatement; 5916 this.init = init; 5917 this.test = test; 5918 this.update = update; 5919 this.body = body; 5920 } 5921 return ForStatement; 5922 }()); 5923 exports.ForStatement = ForStatement; 5924 var FunctionDeclaration = (function () { 5925 function FunctionDeclaration(id, params, body, generator) { 5926 this.type = syntax_1.Syntax.FunctionDeclaration; 5927 this.id = id; 5928 this.params = params; 5929 this.body = body; 5930 this.generator = generator; 5931 this.expression = false; 5932 this.async = false; 5933 } 5934 return FunctionDeclaration; 5935 }()); 5936 exports.FunctionDeclaration = FunctionDeclaration; 5937 var FunctionExpression = (function () { 5938 function FunctionExpression(id, params, body, generator) { 5939 this.type = syntax_1.Syntax.FunctionExpression; 5940 this.id = id; 5941 this.params = params; 5942 this.body = body; 5943 this.generator = generator; 5944 this.expression = false; 5945 this.async = false; 5946 } 5947 return FunctionExpression; 5948 }()); 5949 exports.FunctionExpression = FunctionExpression; 5950 var Identifier = (function () { 5951 function Identifier(name) { 5952 this.type = syntax_1.Syntax.Identifier; 5953 this.name = name; 5954 } 5955 return Identifier; 5956 }()); 5957 exports.Identifier = Identifier; 5958 var IfStatement = (function () { 5959 function IfStatement(test, consequent, alternate) { 5960 this.type = syntax_1.Syntax.IfStatement; 5961 this.test = test; 5962 this.consequent = consequent; 5963 this.alternate = alternate; 5964 } 5965 return IfStatement; 5966 }());
5967 exports.IfStatement = IfStatement; 5968 var ImportDeclaration = (function () { 5969 function ImportDeclaration(specifiers, source) { 5970 this.type = syntax_1.Syntax.ImportDeclaration; 5971 this.specifiers = specifiers; 5972 this.source = source; 5973 } 5974 return ImportDeclaration; 5975 }()); 5976 exports.ImportDeclaration = ImportDeclaration; 5977 var ImportDefaultSpecifier = (function () { 5978 function ImportDefaultSpecifier(local) { 5979 this.type = syntax_1.Syntax.ImportDefaultSpecifier; 5980 this.local = local; 5981 } 5982 return ImportDefaultSpecifier; 5983 }()); 5984 exports.ImportDefaultSpecifier = ImportDefaultSpecifier; 5985 var ImportNamespaceSpecifier = (function () { 5986 function ImportNamespaceSpecifier(local) { 5987 this.type = syntax_1.Syntax.ImportNamespaceSpecifier; 5988 this.local = local; 5989 } 5990 return ImportNamespaceSpecifier; 5991 }()); 5992 exports.ImportNamespaceSpecifier = ImportNamespaceSpecifier; 5993 var ImportSpecifier = (function () { 5994 function ImportSpecifier(local, imported) { 5995 this.type = syntax_1.Syntax.ImportSpecifier; 5996 this.local = local; 5997 this.imported = imported; 5998 } 5999 return ImportSpecifier; 6000 }()); 6001 exports.ImportSpecifier = ImportSpecifier; 6002 var LabeledStatement = (function () { 6003 function LabeledStatement(label, body) { 6004 this.type = syntax_1.Syntax.LabeledStatement; 6005 this.label = label; 6006 this.body = body; 6007 } 6008 return LabeledStatement; 6009 }()); 6010 exports.LabeledStatement = LabeledStatement; 6011 var Literal = (function () { 6012 function Literal(value, raw) { 6013 this.type = syntax_1.Syntax.Literal; 6014 this.value = value; 6015 this.raw = raw; 6016 } 6017 return Literal; 6018 }()); 6019 exports.Literal = Literal; 6020 var MetaProperty = (function () { 6021 function MetaProperty(meta, property) { 6022 this.type = syntax_1.Syntax.MetaProperty; 6023 this.meta = meta; 6024 this.property = property; 6025 } 6026 return MetaProperty; 6027 }()); 6028 exports.MetaProperty = MetaProperty; 6029 var MethodDefinition = (function () { 6030 function MethodDefinition(key, computed, value, kind, isStatic) { 6031 this.type = syntax_1.Syntax.MethodDefinition; 6032 this.key = key; 6033 this.computed = computed; 6034 this.value = value; 6035 this.kind = kind; 6036 this.static = isStatic; 6037 } 6038 return MethodDefinition; 6039 }()); 6040 exports.MethodDefinition = MethodDefinition; 6041 var Module = (function () { 6042 function Module(body) { 6043 this.type = syntax_1.Syntax.Program; 6044 this.body = body; 6045 this.sourceType = 'module'; 6046 } 6047 return Module; 6048 }()); 6049 exports.Module = Module; 6050 var NewExpression = (function () { 6051 function NewExpression(callee, args) { 6052 this.type = syntax_1.Syntax.NewExpression; 6053 this.callee = callee; 6054 this.arguments = args; 6055 } 6056 return NewExpression; 6057 }()); 6058 exports.NewExpression = NewExpression; 6059 var ObjectExpression = (function () { 6060 function ObjectExpression(properties) { 6061 this.type = syntax_1.Syntax.ObjectExpression; 6062 this.properties = properties; 6063 } 6064 return ObjectExpression; 6065 }()); 6066 exports.ObjectExpression = ObjectExpression; 6067 var ObjectPattern = (function () { 6068 function ObjectPattern(properties) { 6069 this.type = syntax_1.Syntax.ObjectPattern; 6070 this.properties = properties; 6071 } 6072 return ObjectPattern; 6073 }()); 6074 exports.ObjectPattern = ObjectPattern; 6075 var Property = (function () { 6076 function Property(kind, key, computed, value, method, shorthand) { 6077 this.type = syntax_1.Syntax.Property; 6078 this.key = key; 6079 this.computed = computed; 6080 this.value = value; 6081 this.kind = kind; 6082 this.method = method; 6083 this.shorthand = shorthand; 6084 } 6085 return Property; 6086 }()); 6087 exports.Property = Property; 6088 var RegexLiteral = (function () { 6089 function RegexLiteral(value, raw, pattern, flags) { 6090 this.type = syntax_1.Syntax.Literal; 6091 this.value = value; 6092 this.raw = raw; 6093 this.regex = { pattern: pattern, flags: flags }; 6094 } 6095 return RegexLiteral; 6096 }());
6097 exports.RegexLiteral = RegexLiteral; 6098 var RestElement = (function () { 6099 function RestElement(argument) { 6100 this.type = syntax_1.Syntax.RestElement; 6101 this.argument = argument; 6102 } 6103 return RestElement; 6104 }()); 6105 exports.RestElement = RestElement; 6106 var ReturnStatement = (function () { 6107 function ReturnStatement(argument) { 6108 this.type = syntax_1.Syntax.ReturnStatement; 6109 this.argument = argument; 6110 } 6111 return ReturnStatement; 6112 }()); 6113 exports.ReturnStatement = ReturnStatement; 6114 var Script = (function () { 6115 function Script(body) { 6116 this.type = syntax_1.Syntax.Program; 6117 this.body = body; 6118 this.sourceType = 'script'; 6119 } 6120 return Script; 6121 }()); 6122 exports.Script = Script; 6123 var SequenceExpression = (function () { 6124 function SequenceExpression(expressions) { 6125 this.type = syntax_1.Syntax.SequenceExpression; 6126 this.expressions = expressions; 6127 } 6128 return SequenceExpression; 6129 }()); 6130 exports.SequenceExpression = SequenceExpression; 6131 var SpreadElement = (function () { 6132 function SpreadElement(argument) { 6133 this.type = syntax_1.Syntax.SpreadElement; 6134 this.argument = argument; 6135 } 6136 return SpreadElement; 6137 }()); 6138 exports.SpreadElement = SpreadElement; 6139 var StaticMemberExpression = (function () { 6140 function StaticMemberExpression(object, property) { 6141 this.type = syntax_1.Syntax.MemberExpression; 6142 this.computed = false; 6143 this.object = object; 6144 this.property = property; 6145 } 6146 return StaticMemberExpression; 6147 }()); 6148 exports.StaticMemberExpression = StaticMemberExpression; 6149 var Super = (function () { 6150 function Super() { 6151 this.type = syntax_1.Syntax.Super; 6152 } 6153 return Super; 6154 }()); 6155 exports.Super = Super; 6156 var SwitchCase = (function () { 6157 function SwitchCase(test, consequent) { 6158 this.type = syntax_1.Syntax.SwitchCase; 6159 this.test = test; 6160 this.consequent = consequent; 6161 } 6162 return SwitchCase; 6163 }()); 6164 exports.SwitchCase = SwitchCase; 6165 var SwitchStatement = (function () { 6166 function SwitchStatement(discriminant, cases) { 6167 this.type = syntax_1.Syntax.SwitchStatement; 6168 this.discriminant = discriminant; 6169 this.cases = cases; 6170 } 6171 return SwitchStatement; 6172 }()); 6173 exports.SwitchStatement = SwitchStatement; 6174 var TaggedTemplateExpression = (function () { 6175 function TaggedTemplateExpression(tag, quasi) { 6176 this.type = syntax_1.Syntax.TaggedTemplateExpression; 6177 this.tag = tag; 6178 this.quasi = quasi; 6179 } 6180 return TaggedTemplateExpression; 6181 }()); 6182 exports.TaggedTemplateExpression = TaggedTemplateExpression; 6183 var TemplateElement = (function () { 6184 function TemplateElement(value, tail) { 6185 this.type = syntax_1.Syntax.TemplateElement; 6186 this.value = value; 6187 this.tail = tail; 6188 } 6189 return TemplateElement; 6190 }()); 6191 exports.TemplateElement = TemplateElement; 6192 var TemplateLiteral = (function () { 6193 function TemplateLiteral(quasis, expressions) { 6194 this.type = syntax_1.Syntax.TemplateLiteral; 6195 this.quasis = quasis; 6196 this.expressions = expressions; 6197 } 6198 return TemplateLiteral; 6199 }()); 6200 exports.TemplateLiteral = TemplateLiteral; 6201 var ThisExpression = (function () { 6202 function ThisExpression() { 6203 this.type = syntax_1.Syntax.ThisExpression; 6204 } 6205 return ThisExpression; 6206 }()); 6207 exports.ThisExpression = ThisExpression; 6208 var ThrowStatement = (function () { 6209 function ThrowStatement(argument) { 6210 this.type = syntax_1.Syntax.ThrowStatement; 6211 this.argument = argument; 6212 } 6213 return ThrowStatement; 6214 }()); 6215 exports.ThrowStatement = ThrowStatement; 6216 var TryStatement = (function () { 6217 function TryStatement(block, handler, finalizer) { 6218 this.type = syntax_1.Syntax.TryStatement; 6219 this.block = block; 6220 this.handler = handler; 6221 this.finalizer = finalizer; 6222 } 6223 return TryStatement; 6224 }());
vendor: 106,647 bytes, lines 6225-8590
6225 exports.TryStatement = TryStatement; 6226 var UnaryExpression = (function () { 6227 function UnaryExpression(operator, argument) { 6228 this.type = syntax_1.Syntax.UnaryExpression; 6229 this.operator = operator; 6230 this.argument = argument; 6231 this.prefix = true; 6232 } 6233 return UnaryExpression; 6234 }()); 6235 exports.UnaryExpression = UnaryExpression; 6236 var UpdateExpression = (function () { 6237 function UpdateExpression(operator, argument, prefix) { 6238 this.type = syntax_1.Syntax.UpdateExpression; 6239 this.operator = operator; 6240 this.argument = argument; 6241 this.prefix = prefix; 6242 } 6243 return UpdateExpression; 6244 }()); 6245 exports.UpdateExpression = UpdateExpression; 6246 var VariableDeclaration = (function () { 6247 function VariableDeclaration(declarations, kind) { 6248 this.type = syntax_1.Syntax.VariableDeclaration; 6249 this.declarations = declarations; 6250 this.kind = kind; 6251 } 6252 return VariableDeclaration; 6253 }()); 6254 exports.VariableDeclaration = VariableDeclaration; 6255 var VariableDeclarator = (function () { 6256 function VariableDeclarator(id, init) { 6257 this.type = syntax_1.Syntax.VariableDeclarator; 6258 this.id = id; 6259 this.init = init; 6260 } 6261 return VariableDeclarator; 6262 }()); 6263 exports.VariableDeclarator = VariableDeclarator; 6264 var WhileStatement = (function () { 6265 function WhileStatement(test, body) { 6266 this.type = syntax_1.Syntax.WhileStatement; 6267 this.test = test; 6268 this.body = body; 6269 } 6270 return WhileStatement; 6271 }()); 6272 exports.WhileStatement = WhileStatement; 6273 var WithStatement = (function () { 6274 function WithStatement(object, body) { 6275 this.type = syntax_1.Syntax.WithStatement; 6276 this.object = object; 6277 this.body = body; 6278 } 6279 return WithStatement; 6280 }()); 6281 exports.WithStatement = WithStatement; 6282 var YieldExpression = (function () { 6283 function YieldExpression(argument, delegate) { 6284 this.type = syntax_1.Syntax.YieldExpression; 6285 this.argument = argument; 6286 this.delegate = delegate; 6287 } 6288 return YieldExpression; 6289 }()); 6290 exports.YieldExpression = YieldExpression; 6291 6292 6293/***/ }, 6294/* 8 */ 6295/***/ function(module, exports, __webpack_require__) { 6296 6297 "use strict"; 6298 Object.defineProperty(exports, "__esModule", { value: true }); 6299 var assert_1 = __webpack_require__(9); 6300 var error_handler_1 = __webpack_require__(10); 6301 var messages_1 = __webpack_require__(11); 6302 var Node = __webpack_require__(7); 6303 var scanner_1 = __webpack_require__(12); 6304 var syntax_1 = __webpack_require__(2); 6305 var token_1 = __webpack_require__(13); 6306 var ArrowParameterPlaceHolder = 'ArrowParameterPlaceHolder'; 6307 var Parser = (function () { 6308 function Parser(code, options, delegate) { 6309 if (options === void 0) { options = {}; } 6310 this.config = { 6311 range: (typeof options.range === 'boolean') && options.range, 6312 loc: (typeof options.loc === 'boolean') && options.loc, 6313 source: null, 6314 tokens: (typeof options.tokens === 'boolean') && options.tokens, 6315 comment: (typeof options.comment === 'boolean') && options.comment, 6316 tolerant: (typeof options.tolerant === 'boolean') && options.tolerant 6317 }; 6318 if (this.config.loc && options.source && options.source !== null) { 6319 this.config.source = String(options.source); 6320 } 6321 this.delegate = delegate; 6322 this.errorHandler = new error_handler_1.ErrorHandler(); 6323 this.errorHandler.tolerant = this.config.tolerant; 6324 this.scanner = new scanner_1.Scanner(code, this.errorHandler); 6325 this.scanner.trackComment = this.config.comment; 6326 this.operatorPrecedence = { 6327 ')': 0, 6328 ';': 0, 6329 ',': 0, 6330 '=': 0, 6331 ']': 0, 6332 '||': 1, 6333 '&&': 2, 6334 '|': 3, 6335 '^': 4, 6336 '&': 5, 6337 '==': 6, 6338 '!=': 6, 6339 '===': 6, 6340 '!==': 6, 6341 '<': 7, 6342 '>': 7, 6343 '<=': 7, 6344 '>=': 7, 6345 '<<': 8, 6346 '>>': 8, 6347 '>>>': 8, 6348 '+': 9, 6349 '-': 9, 6350 '*': 11, 6351 '/': 11, 6352 '%': 11 6353 }; 6354 this.lookahead = { 6355 type: 2 /* EOF */, 6356 value: '', 6357 lineNumber: this.scanner.lineNumber, 6358 lineStart: 0, 6359 start: 0, 6360 end: 0 6361 }; 6362 this.hasLineTerminator = false; 6363 this.context = { 6364 isModule: false, 6365 await: false, 6366 allowIn: true, 6367 allowStrictDirective: true, 6368 allowYield: true, 6369 firstCoverInitializedNameError: null, 6370 isAssignmentTarget: false, 6371 isBindingElement: false, 6372 inFunctionBody: false, 6373 inIteration: false, 6374 inSwitch: false, 6375 labelSet: {}, 6376 strict: false 6377 }; 6378 this.tokens = []; 6379 this.startMarker = { 6380 index: 0, 6381 line: this.scanner.lineNumber, 6382 column: 0 6383 }; 6384 this.lastMarker = { 6385 index: 0, 6386 line: this.scanner.lineNumber, 6387 column: 0 6388 }; 6389 this.nextToken(); 6390 this.lastMarker = { 6391 index: this.scanner.index, 6392 line: this.scanner.lineNumber, 6393 column: this.scanner.index - this.scanner.lineStart 6394 }; 6395 } 6396 Parser.prototype.throwError = function (messageFormat) { 6397 var values = []; 6398 for (var _i = 1; _i < arguments.length; _i++) { 6399 values[_i - 1] = arguments[_i]; 6400 } 6401 var args = Array.prototype.slice.call(arguments, 1); 6402 var msg = messageFormat.replace(/%(\d)/g, function (whole, idx) { 6403 assert_1.assert(idx < args.length, 'Message reference must be in range'); 6404 return args[idx]; 6405 }); 6406 var index = this.lastMarker.index; 6407 var line = this.lastMarker.line; 6408 var column = this.lastMarker.column + 1; 6409 throw this.errorHandler.createError(index, line, column, msg); 6410 }; 6411 Parser.prototype.tolerateError = function (messageFormat) { 6412 var values = []; 6413 for (var _i = 1; _i < arguments.length; _i++) { 6414 values[_i - 1] = arguments[_i]; 6415 } 6416 var args = Array.prototype.slice.call(arguments, 1); 6417 var msg = messageFormat.replace(/%(\d)/g, function (whole, idx) { 6418 assert_1.assert(idx < args.length, 'Message reference must be in range'); 6419 return args[idx]; 6420 }); 6421 var index = this.lastMarker.index; 6422 var line = this.scanner.lineNumber; 6423 var column = this.lastMarker.column + 1; 6424 this.errorHandler.tolerateError(index, line, column, msg); 6425 }; 6426 // Throw an exception because of the token. 6427 Parser.prototype.unexpectedTokenError = function (token, message) { 6428 var msg = message || messages_1.Messages.UnexpectedToken; 6429 var value; 6430 if (token) { 6431 if (!message) { 6432 msg = (token.type === 2 /* EOF */) ? messages_1.Messages.UnexpectedEOS : 6433 (token.type === 3 /* Identifier */) ? messages_1.Messages.UnexpectedIdentifier : 6434 (token.type === 6 /* NumericLiteral */) ? messages_1.Messages.UnexpectedNumber : 6435 (token.type === 8 /* StringLiteral */) ? messages_1.Messages.UnexpectedString : 6436 (token.type === 10 /* Template */) ? messages_1.Messages.UnexpectedTemplate : 6437 messages_1.Messages.UnexpectedToken; 6438 if (token.type === 4 /* Keyword */) { 6439 if (this.scanner.isFutureReservedWord(token.value)) { 6440 msg = messages_1.Messages.UnexpectedReserved; 6441 } 6442 else if (this.context.strict && this.scanner.isStrictModeReservedWord(token.value)) { 6443 msg = messages_1.Messages.StrictReservedWord; 6444 } 6445 } 6446 } 6447 value = token.value; 6448 } 6449 else { 6450 value = 'ILLEGAL'; 6451 } 6452 msg = msg.replace('%0', value); 6453 if (token && typeof token.lineNumber === 'number') { 6454 var index = token.start; 6455 var line = token.lineNumber; 6456 var lastMarkerLineStart = this.lastMarker.index - this.lastMarker.column; 6457 var column = token.start - lastMarkerLineStart + 1; 6458 return this.errorHandler.createError(index, line, column, msg); 6459 } 6460 else { 6461 var index = this.lastMarker.index; 6462 var line = this.lastMarker.line; 6463 var column = this.lastMarker.column + 1; 6464 return this.errorHandler.createError(index, line, column, msg); 6465 } 6466 }; 6467 Parser.prototype.throwUnexpectedToken = function (token, message) { 6468 throw this.unexpectedTokenError(token, message); 6469 }; 6470 Parser.prototype.tolerateUnexpectedToken = function (token, message) { 6471 this.errorHandler.tolerate(this.unexpectedTokenError(token, message)); 6472 }; 6473 Parser.prototype.collectComments = function () { 6474 if (!this.config.comment) { 6475 this.scanner.scanComments(); 6476 } 6477 else { 6478 var comments = this.scanner.scanComments(); 6479 if (comments.length > 0 && this.delegate) { 6480 for (var i = 0; i < comments.length; ++i) { 6481 var e = comments[i]; 6482 var node = void 0; 6483 node = { 6484 type: e.multiLine ? 'BlockComment' : 'LineComment', 6485 value: this.scanner.source.slice(e.slice[0], e.slice[1]) 6486 }; 6487 if (this.config.range) { 6488 node.range = e.range; 6489 } 6490 if (this.config.loc) { 6491 node.loc = e.loc; 6492 } 6493 var metadata = { 6494 start: { 6495 line: e.loc.start.line, 6496 column: e.loc.start.column, 6497 offset: e.range[0] 6498 }, 6499 end: { 6500 line: e.loc.end.line, 6501 column: e.loc.end.column, 6502 offset: e.range[1] 6503 } 6504 }; 6505 this.delegate(node, metadata); 6506 } 6507 } 6508 } 6509 }; 6510 // From internal representation to an external structure 6511 Parser.prototype.getTokenRaw = function (token) { 6512 return this.scanner.source.slice(token.start, token.end); 6513 }; 6514 Parser.prototype.convertToken = function (token) { 6515 var t = { 6516 type: token_1.TokenName[token.type], 6517 value: this.getTokenRaw(token) 6518 }; 6519 if (this.config.range) { 6520 t.range = [token.start, token.end]; 6521 } 6522 if (this.config.loc) { 6523 t.loc = { 6524 start: { 6525 line: this.startMarker.line, 6526 column: this.startMarker.column 6527 }, 6528 end: { 6529 line: this.scanner.lineNumber, 6530 column: this.scanner.index - this.scanner.lineStart 6531 } 6532 }; 6533 } 6534 if (token.type === 9 /* RegularExpression */) { 6535 var pattern = token.pattern; 6536 var flags = token.flags; 6537 t.regex = { pattern: pattern, flags: flags }; 6538 } 6539 return t; 6540 }; 6541 Parser.prototype.nextToken = function () { 6542 var token = this.lookahead; 6543 this.lastMarker.index = this.scanner.index; 6544 this.lastMarker.line = this.scanner.lineNumber; 6545 this.lastMarker.column = this.scanner.index - this.scanner.lineStart; 6546 this.collectComments(); 6547 if (this.scanner.index !== this.startMarker.index) { 6548 this.startMarker.index = this.scanner.index; 6549 this.startMarker.line = this.scanner.lineNumber; 6550 this.startMarker.column = this.scanner.index - this.scanner.lineStart; 6551 } 6552 var next = this.scanner.lex(); 6553 this.hasLineTerminator = (token.lineNumber !== next.lineNumber); 6554 if (next && this.context.strict && next.type === 3 /* Identifier */) { 6555 if (this.scanner.isStrictModeReservedWord(next.value)) { 6556 next.type = 4 /* Keyword */; 6557 } 6558 } 6559 this.lookahead = next; 6560 if (this.config.tokens && next.type !== 2 /* EOF */) { 6561 this.tokens.push(this.convertToken(next)); 6562 } 6563 return token; 6564 }; 6565 Parser.prototype.nextRegexToken = function () { 6566 this.collectComments(); 6567 var token = this.scanner.scanRegExp(); 6568 if (this.config.tokens) { 6569 // Pop the previous token, '/' or '/=' 6570 // This is added from the lookahead token. 6571 this.tokens.pop(); 6572 this.tokens.push(this.convertToken(token)); 6573 } 6574 // Prime the next lookahead. 6575 this.lookahead = token; 6576 this.nextToken(); 6577 return token; 6578 }; 6579 Parser.prototype.createNode = function () { 6580 return { 6581 index: this.startMarker.index, 6582 line: this.startMarker.line, 6583 column: this.startMarker.column 6584 }; 6585 }; 6586 Parser.prototype.startNode = function (token, lastLineStart) { 6587 if (lastLineStart === void 0) { lastLineStart = 0; } 6588 var column = token.start - token.lineStart; 6589 var line = token.lineNumber; 6590 if (column < 0) { 6591 column += lastLineStart; 6592 line--; 6593 } 6594 return { 6595 index: token.start, 6596 line: line, 6597 column: column 6598 }; 6599 }; 6600 Parser.prototype.finalize = function (marker, node) { 6601 if (this.config.range) { 6602 node.range = [marker.index, this.lastMarker.index]; 6603 } 6604 if (this.config.loc) { 6605 node.loc = { 6606 start: { 6607 line: marker.line, 6608 column: marker.column, 6609 }, 6610 end: { 6611 line: this.lastMarker.line, 6612 column: this.lastMarker.column 6613 } 6614 }; 6615 if (this.config.source) { 6616 node.loc.source = this.config.source; 6617 } 6618 } 6619 if (this.delegate) { 6620 var metadata = { 6621 start: { 6622 line: marker.line, 6623 column: marker.column, 6624 offset: marker.index 6625 }, 6626 end: { 6627 line: this.lastMarker.line, 6628 column: this.lastMarker.column, 6629 offset: this.lastMarker.index 6630 } 6631 }; 6632 this.delegate(node, metadata); 6633 } 6634 return node; 6635 }; 6636 // Expect the next token to match the specified punctuator. 6637 // If not, an exception will be thrown. 6638 Parser.prototype.expect = function (value) { 6639 var token = this.nextToken(); 6640 if (token.type !== 7 /* Punctuator */ || token.value !== value) { 6641 this.throwUnexpectedToken(token); 6642 } 6643 }; 6644 // Quietly expect a comma when in tolerant mode, otherwise delegates to expect(). 6645 Parser.prototype.expectCommaSeparator = function () { 6646 if (this.config.tolerant) { 6647 var token = this.lookahead; 6648 if (token.type === 7 /* Punctuator */ && token.value === ',') { 6649 this.nextToken(); 6650 } 6651 else if (token.type === 7 /* Punctuator */ && token.value === ';') { 6652 this.nextToken(); 6653 this.tolerateUnexpectedToken(token); 6654 } 6655 else { 6656 this.tolerateUnexpectedToken(token, messages_1.Messages.UnexpectedToken); 6657 } 6658 } 6659 else { 6660 this.expect(','); 6661 } 6662 }; 6663 // Expect the next token to match the specified keyword. 6664 // If not, an exception will be thrown. 6665 Parser.prototype.expectKeyword = function (keyword) { 6666 var token = this.nextToken(); 6667 if (token.type !== 4 /* Keyword */ || token.value !== keyword) { 6668 this.throwUnexpectedToken(token); 6669 } 6670 }; 6671 // Return true if the next token matches the specified punctuator. 6672 Parser.prototype.match = function (value) { 6673 return this.lookahead.type === 7 /* Punctuator */ && this.lookahead.value === value; 6674 }; 6675 // Return true if the next token matches the specified keyword 6676 Parser.prototype.matchKeyword = function (keyword) { 6677 return this.lookahead.type === 4 /* Keyword */ && this.lookahead.value === keyword; 6678 }; 6679 // Return true if the next token matches the specified contextual keyword 6680 // (where an identifier is sometimes a keyword depending on the context) 6681 Parser.prototype.matchContextualKeyword = function (keyword) { 6682 return this.lookahead.type === 3 /* Identifier */ && this.lookahead.value === keyword; 6683 }; 6684 // Return true if the next token is an assignment operator 6685 Parser.prototype.matchAssign = function () { 6686 if (this.lookahead.type !== 7 /* Punctuator */) { 6687 return false; 6688 } 6689 var op = this.lookahead.value; 6690 return op === '=' || 6691 op === '*=' || 6692 op === '**=' || 6693 op === '/=' || 6694 op === '%=' || 6695 op === '+=' || 6696 op === '-=' || 6697 op === '<<=' || 6698 op === '>>=' || 6699 op === '>>>=' || 6700 op === '&=' || 6701 op === '^=' || 6702 op === '|='; 6703 }; 6704 // Cover grammar support. 6705 // 6706 // When an assignment expression position starts with an left parenthesis, the determination of the type 6707 // of the syntax is to be deferred arbitrarily long until the end of the parentheses pair (plus a lookahead) 6708 // or the first comma. This situation also defers the determination of all the expressions nested in the pair. 6709 // 6710 // There are three productions that can be parsed in a parentheses pair that needs to be determined 6711 // after the outermost pair is closed. They are: 6712 // 6713 // 1. AssignmentExpression 6714 // 2. BindingElements 6715 // 3. AssignmentTargets 6716 // 6717 // In order to avoid exponential backtracking, we use two flags to denote if the production can be 6718 // binding element or assignment target. 6719 // 6720 // The three productions have the relationship: 6721 // 6722 // BindingElements â AssignmentTargets â AssignmentExpression 6723 // 6724 // with a single exception that CoverInitializedName when used directly in an Expression, generates 6725 // an early error. Therefore, we need the third state, firstCoverInitializedNameError, to track the 6726 // first usage of CoverInitializedName and report it when we reached the end of the parentheses pair. 6727 // 6728 // isolateCoverGrammar function runs the given parser function with a new cover grammar context, and it does not 6729 // effect the current flags. This means the production the parser parses is only used as an expression. Therefore 6730 // the CoverInitializedName check is conducted. 6731 // 6732 // inheritCoverGrammar function runs the given parse function with a new cover grammar context, and it propagates 6733 // the flags outside of the parser. This means the production the parser parses is used as a part of a potential 6734 // pattern. The CoverInitializedName check is deferred. 6735 Parser.prototype.isolateCoverGrammar = function (parseFunction) { 6736 var previousIsBindingElement = this.context.isBindingElement; 6737 var previousIsAssignmentTarget = this.context.isAssignmentTarget; 6738 var previousFirstCoverInitializedNameError = this.context.firstCoverInitializedNameError; 6739 this.context.isBindingElement = true; 6740 this.context.isAssignmentTarget = true; 6741 this.context.firstCoverInitializedNameError = null; 6742 var result = parseFunction.call(this); 6743 if (this.context.firstCoverInitializedNameError !== null) { 6744 this.throwUnexpectedToken(this.context.firstCoverInitializedNameError); 6745 } 6746 this.context.isBindingElement = previousIsBindingElement; 6747 this.context.isAssignmentTarget = previousIsAssignmentTarget; 6748 this.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError; 6749 return result; 6750 }; 6751 Parser.prototype.inheritCoverGrammar = function (parseFunction) { 6752 var previousIsBindingElement = this.context.isBindingElement; 6753 var previousIsAssignmentTarget = this.context.isAssignmentTarget; 6754 var previousFirstCoverInitializedNameError = this.context.firstCoverInitializedNameError; 6755 this.context.isBindingElement = true; 6756 this.context.isAssignmentTarget = true; 6757 this.context.firstCoverInitializedNameError = null; 6758 var result = parseFunction.call(this); 6759 this.context.isBindingElement = this.context.isBindingElement && previousIsBindingElement; 6760 this.context.isAssignmentTarget = this.context.isAssignmentTarget && previousIsAssignmentTarget; 6761 this.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError || this.context.firstCoverInitializedNameError; 6762 return result; 6763 }; 6764 Parser.prototype.consumeSemicolon = function () { 6765 if (this.match(';')) { 6766 this.nextToken(); 6767 } 6768 else if (!this.hasLineTerminator) { 6769 if (this.lookahead.type !== 2 /* EOF */ && !this.match('}')) { 6770 this.throwUnexpectedToken(this.lookahead); 6771 } 6772 this.lastMarker.index = this.startMarker.index; 6773 this.lastMarker.line = this.startMarker.line; 6774 this.lastMarker.column = this.startMarker.column; 6775 } 6776 }; 6777 // https://tc39.github.io/ecma262/#sec-primary-expression 6778 Parser.prototype.parsePrimaryExpression = function () { 6779 var node = this.createNode(); 6780 var expr; 6781 var token, raw; 6782 switch (this.lookahead.type) { 6783 case 3 /* Identifier */: 6784 if ((this.context.isModule || this.context.await) && this.lookahead.value === 'await') { 6785 this.tolerateUnexpectedToken(this.lookahead); 6786 } 6787 expr = this.matchAsyncFunction() ? this.parseFunctionExpression() : this.finalize(node, new Node.Identifier(this.nextToken().value)); 6788 break; 6789 case 6 /* NumericLiteral */: 6790 case 8 /* StringLiteral */: 6791 if (this.context.strict && this.lookahead.octal) { 6792 this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.StrictOctalLiteral); 6793 } 6794 this.context.isAssignmentTarget = false; 6795 this.context.isBindingElement = false; 6796 token = this.nextToken(); 6797 raw = this.getTokenRaw(token); 6798 expr = this.finalize(node, new Node.Literal(token.value, raw)); 6799 break; 6800 case 1 /* BooleanLiteral */: 6801 this.context.isAssignmentTarget = false; 6802 this.context.isBindingElement = false; 6803 token = this.nextToken(); 6804 raw = this.getTokenRaw(token); 6805 expr = this.finalize(node, new Node.Literal(token.value === 'true', raw)); 6806 break; 6807 case 5 /* NullLiteral */: 6808 this.context.isAssignmentTarget = false; 6809 this.context.isBindingElement = false; 6810 token = this.nextToken(); 6811 raw = this.getTokenRaw(token); 6812 expr = this.finalize(node, new Node.Literal(null, raw)); 6813 break; 6814 case 10 /* Template */: 6815 expr = this.parseTemplateLiteral(); 6816 break; 6817 case 7 /* Punctuator */: 6818 switch (this.lookahead.value) { 6819 case '(': 6820 this.context.isBindingElement = false; 6821 expr = this.inheritCoverGrammar(this.parseGroupExpression); 6822 break; 6823 case '[': 6824 expr = this.inheritCoverGrammar(this.parseArrayInitializer); 6825 break; 6826 case '{': 6827 expr = this.inheritCoverGrammar(this.parseObjectInitializer); 6828 break; 6829 case '/': 6830 case '/=': 6831 this.context.isAssignmentTarget = false; 6832 this.context.isBindingElement = false; 6833 this.scanner.index = this.startMarker.index; 6834 token = this.nextRegexToken(); 6835 raw = this.getTokenRaw(token); 6836 expr = this.finalize(node, new Node.RegexLiteral(token.regex, raw, token.pattern, token.flags)); 6837 break; 6838 default: 6839 expr = this.throwUnexpectedToken(this.nextToken()); 6840 } 6841 break; 6842 case 4 /* Keyword */: 6843 if (!this.context.strict && this.context.allowYield && this.matchKeyword('yield')) { 6844 expr = this.parseIdentifierName(); 6845 } 6846 else if (!this.context.strict && this.matchKeyword('let')) { 6847 expr = this.finalize(node, new Node.Identifier(this.nextToken().value)); 6848 } 6849 else { 6850 this.context.isAssignmentTarget = false; 6851 this.context.isBindingElement = false; 6852 if (this.matchKeyword('function')) { 6853 expr = this.parseFunctionExpression(); 6854 } 6855 else if (this.matchKeyword('this')) { 6856 this.nextToken(); 6857 expr = this.finalize(node, new Node.ThisExpression()); 6858 } 6859 else if (this.matchKeyword('class')) { 6860 expr = this.parseClassExpression(); 6861 } 6862 else { 6863 expr = this.throwUnexpectedToken(this.nextToken()); 6864 } 6865 } 6866 break; 6867 default: 6868 expr = this.throwUnexpectedToken(this.nextToken()); 6869 } 6870 return expr; 6871 }; 6872 // https://tc39.github.io/ecma262/#sec-array-initializer 6873 Parser.prototype.parseSpreadElement = function () { 6874 var node = this.createNode(); 6875 this.expect('...'); 6876 var arg = this.inheritCoverGrammar(this.parseAssignmentExpression); 6877 return this.finalize(node, new Node.SpreadElement(arg)); 6878 }; 6879 Parser.prototype.parseArrayInitializer = function () { 6880 var node = this.createNode(); 6881 var elements = []; 6882 this.expect('['); 6883 while (!this.match(']')) { 6884 if (this.match(',')) { 6885 this.nextToken(); 6886 elements.push(null); 6887 } 6888 else if (this.match('...')) { 6889 var element = this.parseSpreadElement(); 6890 if (!this.match(']')) { 6891 this.context.isAssignmentTarget = false; 6892 this.context.isBindingElement = false; 6893 this.expect(','); 6894 } 6895 elements.push(element); 6896 } 6897 else { 6898 elements.push(this.inheritCoverGrammar(this.parseAssignmentExpression)); 6899 if (!this.match(']')) { 6900 this.expect(','); 6901 } 6902 } 6903 } 6904 this.expect(']'); 6905 return this.finalize(node, new Node.ArrayExpression(elements)); 6906 }; 6907 // https://tc39.github.io/ecma262/#sec-object-initializer 6908 Parser.prototype.parsePropertyMethod = function (params) { 6909 this.context.isAssignmentTarget = false; 6910 this.context.isBindingElement = false; 6911 var previousStrict = this.context.strict; 6912 var previousAllowStrictDirective = this.context.allowStrictDirective; 6913 this.context.allowStrictDirective = params.simple; 6914 var body = this.isolateCoverGrammar(this.parseFunctionSourceElements); 6915 if (this.context.strict && params.firstRestricted) { 6916 this.tolerateUnexpectedToken(params.firstRestricted, params.message); 6917 } 6918 if (this.context.strict && params.stricted) { 6919 this.tolerateUnexpectedToken(params.stricted, params.message); 6920 } 6921 this.context.strict = previousStrict; 6922 this.context.allowStrictDirective = previousAllowStrictDirective; 6923 return body; 6924 }; 6925 Parser.prototype.parsePropertyMethodFunction = function () { 6926 var isGenerator = false; 6927 var node = this.createNode(); 6928 var previousAllowYield = this.context.allowYield; 6929 this.context.allowYield = true; 6930 var params = this.parseFormalParameters(); 6931 var method = this.parsePropertyMethod(params); 6932 this.context.allowYield = previousAllowYield; 6933 return this.finalize(node, new Node.FunctionExpression(null, params.params, method, isGenerator)); 6934 }; 6935 Parser.prototype.parsePropertyMethodAsyncFunction = function () { 6936 var node = this.createNode(); 6937 var previousAllowYield = this.context.allowYield; 6938 var previousAwait = this.context.await; 6939 this.context.allowYield = false; 6940 this.context.await = true; 6941 var params = this.parseFormalParameters(); 6942 var method = this.parsePropertyMethod(params); 6943 this.context.allowYield = previousAllowYield; 6944 this.context.await = previousAwait; 6945 return this.finalize(node, new Node.AsyncFunctionExpression(null, params.params, method)); 6946 }; 6947 Parser.prototype.parseObjectPropertyKey = function () { 6948 var node = this.createNode(); 6949 var token = this.nextToken(); 6950 var key; 6951 switch (token.type) { 6952 case 8 /* StringLiteral */: 6953 case 6 /* NumericLiteral */: 6954 if (this.context.strict && token.octal) { 6955 this.tolerateUnexpectedToken(token, messages_1.Messages.StrictOctalLiteral); 6956 } 6957 var raw = this.getTokenRaw(token); 6958 key = this.finalize(node, new Node.Literal(token.value, raw)); 6959 break; 6960 case 3 /* Identifier */: 6961 case 1 /* BooleanLiteral */: 6962 case 5 /* NullLiteral */: 6963 case 4 /* Keyword */: 6964 key = this.finalize(node, new Node.Identifier(token.value)); 6965 break; 6966 case 7 /* Punctuator */: 6967 if (token.value === '[') { 6968 key = this.isolateCoverGrammar(this.parseAssignmentExpression); 6969 this.expect(']'); 6970 } 6971 else { 6972 key = this.throwUnexpectedToken(token); 6973 } 6974 break; 6975 default: 6976 key = this.throwUnexpectedToken(token); 6977 } 6978 return key; 6979 }; 6980 Parser.prototype.isPropertyKey = function (key, value) { 6981 return (key.type === syntax_1.Syntax.Identifier && key.name === value) || 6982 (key.type === syntax_1.Syntax.Literal && key.value === value); 6983 }; 6984 Parser.prototype.parseObjectProperty = function (hasProto) { 6985 var node = this.createNode(); 6986 var token = this.lookahead; 6987 var kind; 6988 var key = null; 6989 var value = null; 6990 var computed = false; 6991 var method = false; 6992 var shorthand = false; 6993 var isAsync = false; 6994 if (token.type === 3 /* Identifier */) { 6995 var id = token.value; 6996 this.nextToken(); 6997 computed = this.match('['); 6998 isAsync = !this.hasLineTerminator && (id === 'async') && 6999 !this.match(':') && !this.match('(') && !this.match('*') && !this.match(','); 7000 key = isAsync ? this.parseObjectPropertyKey() : this.finalize(node, new Node.Identifier(id)); 7001 } 7002 else if (this.match('*')) { 7003 this.nextToken(); 7004 } 7005 else { 7006 computed = this.match('['); 7007 key = this.parseObjectPropertyKey(); 7008 } 7009 var lookaheadPropertyKey = this.qualifiedPropertyName(this.lookahead); 7010 if (token.type === 3 /* Identifier */ && !isAsync && token.value === 'get' && lookaheadPropertyKey) { 7011 kind = 'get'; 7012 computed = this.match('['); 7013 key = this.parseObjectPropertyKey(); 7014 this.context.allowYield = false; 7015 value = this.parseGetterMethod(); 7016 } 7017 else if (token.type === 3 /* Identifier */ && !isAsync && token.value === 'set' && lookaheadPropertyKey) { 7018 kind = 'set'; 7019 computed = this.match('['); 7020 key = this.parseObjectPropertyKey(); 7021 value = this.parseSetterMethod(); 7022 } 7023 else if (token.type === 7 /* Punctuator */ && token.value === '*' && lookaheadPropertyKey) { 7024 kind = 'init'; 7025 computed = this.match('['); 7026 key = this.parseObjectPropertyKey(); 7027 value = this.parseGeneratorMethod(); 7028 method = true; 7029 } 7030 else { 7031 if (!key) { 7032 this.throwUnexpectedToken(this.lookahead); 7033 } 7034 kind = 'init'; 7035 if (this.match(':') && !isAsync) { 7036 if (!computed && this.isPropertyKey(key, '__proto__')) { 7037 if (hasProto.value) { 7038 this.tolerateError(messages_1.Messages.DuplicateProtoProperty); 7039 } 7040 hasProto.value = true; 7041 } 7042 this.nextToken(); 7043 value = this.inheritCoverGrammar(this.parseAssignmentExpression); 7044 } 7045 else if (this.match('(')) { 7046 value = isAsync ? this.parsePropertyMethodAsyncFunction() : this.parsePropertyMethodFunction(); 7047 method = true; 7048 } 7049 else if (token.type === 3 /* Identifier */) { 7050 var id = this.finalize(node, new Node.Identifier(token.value)); 7051 if (this.match('=')) { 7052 this.context.firstCoverInitializedNameError = this.lookahead; 7053 this.nextToken(); 7054 shorthand = true; 7055 var init = this.isolateCoverGrammar(this.parseAssignmentExpression); 7056 value = this.finalize(node, new Node.AssignmentPattern(id, init)); 7057 } 7058 else { 7059 shorthand = true; 7060 value = id; 7061 } 7062 } 7063 else { 7064 this.throwUnexpectedToken(this.nextToken()); 7065 } 7066 } 7067 return this.finalize(node, new Node.Property(kind, key, computed, value, method, shorthand)); 7068 }; 7069 Parser.prototype.parseObjectInitializer = function () { 7070 var node = this.createNode(); 7071 this.expect('{'); 7072 var properties = []; 7073 var hasProto = { value: false }; 7074 while (!this.match('}')) { 7075 properties.push(this.parseObjectProperty(hasProto)); 7076 if (!this.match('}')) { 7077 this.expectCommaSeparator(); 7078 } 7079 } 7080 this.expect('}'); 7081 return this.finalize(node, new Node.ObjectExpression(properties)); 7082 }; 7083 // https://tc39.github.io/ecma262/#sec-template-literals 7084 Parser.prototype.parseTemplateHead = function () { 7085 assert_1.assert(this.lookahead.head, 'Template literal must start with a template head'); 7086 var node = this.createNode(); 7087 var token = this.nextToken(); 7088 var raw = token.value; 7089 var cooked = token.cooked; 7090 return this.finalize(node, new Node.TemplateElement({ raw: raw, cooked: cooked }, token.tail)); 7091 }; 7092 Parser.prototype.parseTemplateElement = function () { 7093 if (this.lookahead.type !== 10 /* Template */) { 7094 this.throwUnexpectedToken(); 7095 } 7096 var node = this.createNode(); 7097 var token = this.nextToken(); 7098 var raw = token.value; 7099 var cooked = token.cooked; 7100 return this.finalize(node, new Node.TemplateElement({ raw: raw, cooked: cooked }, token.tail)); 7101 }; 7102 Parser.prototype.parseTemplateLiteral = function () { 7103 var node = this.createNode(); 7104 var expressions = []; 7105 var quasis = []; 7106 var quasi = this.parseTemplateHead(); 7107 quasis.push(quasi); 7108 while (!quasi.tail) { 7109 expressions.push(this.parseExpression()); 7110 quasi = this.parseTemplateElement(); 7111 quasis.push(quasi); 7112 } 7113 return this.finalize(node, new Node.TemplateLiteral(quasis, expressions)); 7114 }; 7115 // https://tc39.github.io/ecma262/#sec-grouping-operator 7116 Parser.prototype.reinterpretExpressionAsPattern = function (expr) { 7117 switch (expr.type) { 7118 case syntax_1.Syntax.Identifier: 7119 case syntax_1.Syntax.MemberExpression: 7120 case syntax_1.Syntax.RestElement: 7121 case syntax_1.Syntax.AssignmentPattern: 7122 break; 7123 case syntax_1.Syntax.SpreadElement: 7124 expr.type = syntax_1.Syntax.RestElement; 7125 this.reinterpretExpressionAsPattern(expr.argument); 7126 break; 7127 case syntax_1.Syntax.ArrayExpression: 7128 expr.type = syntax_1.Syntax.ArrayPattern; 7129 for (var i = 0; i < expr.elements.length; i++) { 7130 if (expr.elements[i] !== null) { 7131 this.reinterpretExpressionAsPattern(expr.elements[i]); 7132 } 7133 } 7134 break; 7135 case syntax_1.Syntax.ObjectExpression: 7136 expr.type = syntax_1.Syntax.ObjectPattern; 7137 for (var i = 0; i < expr.properties.length; i++) { 7138 this.reinterpretExpressionAsPattern(expr.properties[i].value); 7139 } 7140 break; 7141 case syntax_1.Syntax.AssignmentExpression: 7142 expr.type = syntax_1.Syntax.AssignmentPattern; 7143 delete expr.operator; 7144 this.reinterpretExpressionAsPattern(expr.left); 7145 break; 7146 default: 7147 // Allow other node type for tolerant parsing. 7148 break; 7149 } 7150 }; 7151 Parser.prototype.parseGroupExpression = function () { 7152 var expr; 7153 this.expect('('); 7154 if (this.match(')')) { 7155 this.nextToken(); 7156 if (!this.match('=>')) { 7157 this.expect('=>'); 7158 } 7159 expr = { 7160 type: ArrowParameterPlaceHolder, 7161 params: [], 7162 async: false 7163 }; 7164 } 7165 else { 7166 var startToken = this.lookahead; 7167 var params = []; 7168 if (this.match('...')) { 7169 expr = this.parseRestElement(params); 7170 this.expect(')'); 7171 if (!this.match('=>')) { 7172 this.expect('=>'); 7173 } 7174 expr = { 7175 type: ArrowParameterPlaceHolder, 7176 params: [expr], 7177 async: false 7178 }; 7179 } 7180 else { 7181 var arrow = false; 7182 this.context.isBindingElement = true; 7183 expr = this.inheritCoverGrammar(this.parseAssignmentExpression); 7184 if (this.match(',')) { 7185 var expressions = []; 7186 this.context.isAssignmentTarget = false; 7187 expressions.push(expr); 7188 while (this.lookahead.type !== 2 /* EOF */) { 7189 if (!this.match(',')) { 7190 break; 7191 } 7192 this.nextToken(); 7193 if (this.match(')')) { 7194 this.nextToken(); 7195 for (var i = 0; i < expressions.length; i++) { 7196 this.reinterpretExpressionAsPattern(expressions[i]); 7197 } 7198 arrow = true; 7199 expr = { 7200 type: ArrowParameterPlaceHolder, 7201 params: expressions, 7202 async: false 7203 }; 7204 } 7205 else if (this.match('...')) { 7206 if (!this.context.isBindingElement) { 7207 this.throwUnexpectedToken(this.lookahead); 7208 } 7209 expressions.push(this.parseRestElement(params)); 7210 this.expect(')'); 7211 if (!this.match('=>')) { 7212 this.expect('=>'); 7213 } 7214 this.context.isBindingElement = false; 7215 for (var i = 0; i < expressions.length; i++) { 7216 this.reinterpretExpressionAsPattern(expressions[i]); 7217 } 7218 arrow = true; 7219 expr = { 7220 type: ArrowParameterPlaceHolder, 7221 params: expressions, 7222 async: false 7223 }; 7224 } 7225 else { 7226 expressions.push(this.inheritCoverGrammar(this.parseAssignmentExpression)); 7227 } 7228 if (arrow) { 7229 break; 7230 } 7231 } 7232 if (!arrow) { 7233 expr = this.finalize(this.startNode(startToken), new Node.SequenceExpression(expressions)); 7234 } 7235 } 7236 if (!arrow) { 7237 this.expect(')'); 7238 if (this.match('=>')) { 7239 if (expr.type === syntax_1.Syntax.Identifier && expr.name === 'yield') { 7240 arrow = true; 7241 expr = { 7242 type: ArrowParameterPlaceHolder, 7243 params: [expr], 7244 async: false 7245 }; 7246 } 7247 if (!arrow) { 7248 if (!this.context.isBindingElement) { 7249 this.throwUnexpectedToken(this.lookahead); 7250 } 7251 if (expr.type === syntax_1.Syntax.SequenceExpression) { 7252 for (var i = 0; i < expr.expressions.length; i++) { 7253 this.reinterpretExpressionAsPattern(expr.expressions[i]); 7254 } 7255 } 7256 else { 7257 this.reinterpretExpressionAsPattern(expr); 7258 } 7259 var parameters = (expr.type === syntax_1.Syntax.SequenceExpression ? expr.expressions : [expr]); 7260 expr = { 7261 type: ArrowParameterPlaceHolder, 7262 params: parameters, 7263 async: false 7264 }; 7265 } 7266 } 7267 this.context.isBindingElement = false; 7268 } 7269 } 7270 } 7271 return expr; 7272 }; 7273 // https://tc39.github.io/ecma262/#sec-left-hand-side-expressions 7274 Parser.prototype.parseArguments = function () { 7275 this.expect('('); 7276 var args = []; 7277 if (!this.match(')')) { 7278 while (true) { 7279 var expr = this.match('...') ? this.parseSpreadElement() : 7280 this.isolateCoverGrammar(this.parseAssignmentExpression); 7281 args.push(expr); 7282 if (this.match(')')) { 7283 break; 7284 } 7285 this.expectCommaSeparator(); 7286 if (this.match(')')) { 7287 break; 7288 } 7289 } 7290 } 7291 this.expect(')'); 7292 return args; 7293 }; 7294 Parser.prototype.isIdentifierName = function (token) { 7295 return token.type === 3 /* Identifier */ || 7296 token.type === 4 /* Keyword */ || 7297 token.type === 1 /* BooleanLiteral */ || 7298 token.type === 5 /* NullLiteral */; 7299 }; 7300 Parser.prototype.parseIdentifierName = function () { 7301 var node = this.createNode(); 7302 var token = this.nextToken(); 7303 if (!this.isIdentifierName(token)) { 7304 this.throwUnexpectedToken(token); 7305 } 7306 return this.finalize(node, new Node.Identifier(token.value)); 7307 }; 7308 Parser.prototype.parseNewExpression = function () { 7309 var node = this.createNode(); 7310 var id = this.parseIdentifierName(); 7311 assert_1.assert(id.name === 'new', 'New expression must start with `new`'); 7312 var expr; 7313 if (this.match('.')) { 7314 this.nextToken(); 7315 if (this.lookahead.type === 3 /* Identifier */ && this.context.inFunctionBody && this.lookahead.value === 'target') { 7316 var property = this.parseIdentifierName(); 7317 expr = new Node.MetaProperty(id, property); 7318 } 7319 else { 7320 this.throwUnexpectedToken(this.lookahead); 7321 } 7322 } 7323 else { 7324 var callee = this.isolateCoverGrammar(this.parseLeftHandSideExpression); 7325 var args = this.match('(') ? this.parseArguments() : []; 7326 expr = new Node.NewExpression(callee, args); 7327 this.context.isAssignmentTarget = false; 7328 this.context.isBindingElement = false; 7329 } 7330 return this.finalize(node, expr); 7331 }; 7332 Parser.prototype.parseAsyncArgument = function () { 7333 var arg = this.parseAssignmentExpression(); 7334 this.context.firstCoverInitializedNameError = null; 7335 return arg; 7336 }; 7337 Parser.prototype.parseAsyncArguments = function () { 7338 this.expect('('); 7339 var args = []; 7340 if (!this.match(')')) { 7341 while (true) { 7342 var expr = this.match('...') ? this.parseSpreadElement() : 7343 this.isolateCoverGrammar(this.parseAsyncArgument); 7344 args.push(expr); 7345 if (this.match(')')) { 7346 break; 7347 } 7348 this.expectCommaSeparator(); 7349 if (this.match(')')) { 7350 break; 7351 } 7352 } 7353 } 7354 this.expect(')'); 7355 return args; 7356 }; 7357 Parser.prototype.parseLeftHandSideExpressionAllowCall = function () { 7358 var startToken = this.lookahead; 7359 var maybeAsync = this.matchContextualKeyword('async'); 7360 var previousAllowIn = this.context.allowIn; 7361 this.context.allowIn = true; 7362 var expr; 7363 if (this.matchKeyword('super') && this.context.inFunctionBody) { 7364 expr = this.createNode(); 7365 this.nextToken(); 7366 expr = this.finalize(expr, new Node.Super()); 7367 if (!this.match('(') && !this.match('.') && !this.match('[')) { 7368 this.throwUnexpectedToken(this.lookahead); 7369 } 7370 } 7371 else { 7372 expr = this.inheritCoverGrammar(this.matchKeyword('new') ? this.parseNewExpression : this.parsePrimaryExpression); 7373 } 7374 while (true) { 7375 if (this.match('.')) { 7376 this.context.isBindingElement = false; 7377 this.context.isAssignmentTarget = true; 7378 this.expect('.'); 7379 var property = this.parseIdentifierName(); 7380 expr = this.finalize(this.startNode(startToken), new Node.StaticMemberExpression(expr, property)); 7381 } 7382 else if (this.match('(')) { 7383 var asyncArrow = maybeAsync && (startToken.lineNumber === this.lookahead.lineNumber); 7384 this.context.isBindingElement = false; 7385 this.context.isAssignmentTarget = false; 7386 var args = asyncArrow ? this.parseAsyncArguments() : this.parseArguments(); 7387 expr = this.finalize(this.startNode(startToken), new Node.CallExpression(expr, args)); 7388 if (asyncArrow && this.match('=>')) { 7389 for (var i = 0; i < args.length; ++i) { 7390 this.reinterpretExpressionAsPattern(args[i]); 7391 } 7392 expr = { 7393 type: ArrowParameterPlaceHolder, 7394 params: args, 7395 async: true 7396 }; 7397 } 7398 } 7399 else if (this.match('[')) { 7400 this.context.isBindingElement = false; 7401 this.context.isAssignmentTarget = true; 7402 this.expect('['); 7403 var property = this.isolateCoverGrammar(this.parseExpression); 7404 this.expect(']'); 7405 expr = this.finalize(this.startNode(startToken), new Node.ComputedMemberExpression(expr, property)); 7406 } 7407 else if (this.lookahead.type === 10 /* Template */ && this.lookahead.head) { 7408 var quasi = this.parseTemplateLiteral(); 7409 expr = this.finalize(this.startNode(startToken), new Node.TaggedTemplateExpression(expr, quasi)); 7410 } 7411 else { 7412 break; 7413 } 7414 } 7415 this.context.allowIn = previousAllowIn; 7416 return expr; 7417 }; 7418 Parser.prototype.parseSuper = function () { 7419 var node = this.createNode(); 7420 this.expectKeyword('super'); 7421 if (!this.match('[') && !this.match('.')) { 7422 this.throwUnexpectedToken(this.lookahead); 7423 } 7424 return this.finalize(node, new Node.Super()); 7425 }; 7426 Parser.prototype.parseLeftHandSideExpression = function () { 7427 assert_1.assert(this.context.allowIn, 'callee of new expression always allow in keyword.'); 7428 var node = this.startNode(this.lookahead); 7429 var expr = (this.matchKeyword('super') && this.context.inFunctionBody) ? this.parseSuper() : 7430 this.inheritCoverGrammar(this.matchKeyword('new') ? this.parseNewExpression : this.parsePrimaryExpression); 7431 while (true) { 7432 if (this.match('[')) { 7433 this.context.isBindingElement = false; 7434 this.context.isAssignmentTarget = true; 7435 this.expect('['); 7436 var property = this.isolateCoverGrammar(this.parseExpression); 7437 this.expect(']'); 7438 expr = this.finalize(node, new Node.ComputedMemberExpression(expr, property)); 7439 } 7440 else if (this.match('.')) { 7441 this.context.isBindingElement = false; 7442 this.context.isAssignmentTarget = true; 7443 this.expect('.'); 7444 var property = this.parseIdentifierName(); 7445 expr = this.finalize(node, new Node.StaticMemberExpression(expr, property)); 7446 } 7447 else if (this.lookahead.type === 10 /* Template */ && this.lookahead.head) { 7448 var quasi = this.parseTemplateLiteral(); 7449 expr = this.finalize(node, new Node.TaggedTemplateExpression(expr, quasi)); 7450 } 7451 else { 7452 break; 7453 } 7454 } 7455 return expr; 7456 }; 7457 // https://tc39.github.io/ecma262/#sec-update-expressions 7458 Parser.prototype.parseUpdateExpression = function () { 7459 var expr; 7460 var startToken = this.lookahead; 7461 if (this.match('++') || this.match('--')) { 7462 var node = this.startNode(startToken); 7463 var token = this.nextToken(); 7464 expr = this.inheritCoverGrammar(this.parseUnaryExpression); 7465 if (this.context.strict && expr.type === syntax_1.Syntax.Identifier && this.scanner.isRestrictedWord(expr.name)) { 7466 this.tolerateError(messages_1.Messages.StrictLHSPrefix); 7467 } 7468 if (!this.context.isAssignmentTarget) { 7469 this.tolerateError(messages_1.Messages.InvalidLHSInAssignment); 7470 } 7471 var prefix = true; 7472 expr = this.finalize(node, new Node.UpdateExpression(token.value, expr, prefix)); 7473 this.context.isAssignmentTarget = false; 7474 this.context.isBindingElement = false; 7475 } 7476 else { 7477 expr = this.inheritCoverGrammar(this.parseLeftHandSideExpressionAllowCall); 7478 if (!this.hasLineTerminator && this.lookahead.type === 7 /* Punctuator */) { 7479 if (this.match('++') || this.match('--')) { 7480 if (this.context.strict && expr.type === syntax_1.Syntax.Identifier && this.scanner.isRestrictedWord(expr.name)) { 7481 this.tolerateError(messages_1.Messages.StrictLHSPostfix); 7482 } 7483 if (!this.context.isAssignmentTarget) { 7484 this.tolerateError(messages_1.Messages.InvalidLHSInAssignment); 7485 } 7486 this.context.isAssignmentTarget = false; 7487 this.context.isBindingElement = false; 7488 var operator = this.nextToken().value; 7489 var prefix = false; 7490 expr = this.finalize(this.startNode(startToken), new Node.UpdateExpression(operator, expr, prefix)); 7491 } 7492 } 7493 } 7494 return expr; 7495 }; 7496 // https://tc39.github.io/ecma262/#sec-unary-operators 7497 Parser.prototype.parseAwaitExpression = function () { 7498 var node = this.createNode(); 7499 this.nextToken(); 7500 var argument = this.parseUnaryExpression(); 7501 return this.finalize(node, new Node.AwaitExpression(argument)); 7502 }; 7503 Parser.prototype.parseUnaryExpression = function () { 7504 var expr; 7505 if (this.match('+') || this.match('-') || this.match('~') || this.match('!') || 7506 this.matchKeyword('delete') || this.matchKeyword('void') || this.matchKeyword('typeof')) { 7507 var node = this.startNode(this.lookahead); 7508 var token = this.nextToken(); 7509 expr = this.inheritCoverGrammar(this.parseUnaryExpression); 7510 expr = this.finalize(node, new Node.UnaryExpression(token.value, expr)); 7511 if (this.context.strict && expr.operator === 'delete' && expr.argument.type === syntax_1.Syntax.Identifier) { 7512 this.tolerateError(messages_1.Messages.StrictDelete); 7513 } 7514 this.context.isAssignmentTarget = false; 7515 this.context.isBindingElement = false; 7516 } 7517 else if (this.context.await && this.matchContextualKeyword('await')) { 7518 expr = this.parseAwaitExpression(); 7519 } 7520 else { 7521 expr = this.parseUpdateExpression(); 7522 } 7523 return expr; 7524 }; 7525 Parser.prototype.parseExponentiationExpression = function () { 7526 var startToken = this.lookahead; 7527 var expr = this.inheritCoverGrammar(this.parseUnaryExpression); 7528 if (expr.type !== syntax_1.Syntax.UnaryExpression && this.match('**')) { 7529 this.nextToken(); 7530 this.context.isAssignmentTarget = false; 7531 this.context.isBindingElement = false; 7532 var left = expr; 7533 var right = this.isolateCoverGrammar(this.parseExponentiationExpression); 7534 expr = this.finalize(this.startNode(startToken), new Node.BinaryExpression('**', left, right)); 7535 } 7536 return expr; 7537 }; 7538 // https://tc39.github.io/ecma262/#sec-exp-operator 7539 // https://tc39.github.io/ecma262/#sec-multiplicative-operators 7540 // https://tc39.github.io/ecma262/#sec-additive-operators 7541 // https://tc39.github.io/ecma262/#sec-bitwise-shift-operators 7542 // https://tc39.github.io/ecma262/#sec-relational-operators 7543 // https://tc39.github.io/ecma262/#sec-equality-operators 7544 // https://tc39.github.io/ecma262/#sec-binary-bitwise-operators 7545 // https://tc39.github.io/ecma262/#sec-binary-logical-operators 7546 Parser.prototype.binaryPrecedence = function (token) { 7547 var op = token.value; 7548 var precedence; 7549 if (token.type === 7 /* Punctuator */) { 7550 precedence = this.operatorPrecedence[op] || 0; 7551 } 7552 else if (token.type === 4 /* Keyword */) { 7553 precedence = (op === 'instanceof' || (this.context.allowIn && op === 'in')) ? 7 : 0; 7554 } 7555 else { 7556 precedence = 0; 7557 } 7558 return precedence; 7559 }; 7560 Parser.prototype.parseBinaryExpression = function () { 7561 var startToken = this.lookahead; 7562 var expr = this.inheritCoverGrammar(this.parseExponentiationExpression); 7563 var token = this.lookahead; 7564 var prec = this.binaryPrecedence(token); 7565 if (prec > 0) { 7566 this.nextToken(); 7567 this.context.isAssignmentTarget = false; 7568 this.context.isBindingElement = false; 7569 var markers = [startToken, this.lookahead]; 7570 var left = expr; 7571 var right = this.isolateCoverGrammar(this.parseExponentiationExpression); 7572 var stack = [left, token.value, right]; 7573 var precedences = [prec]; 7574 while (true) { 7575 prec = this.binaryPrecedence(this.lookahead); 7576 if (prec <= 0) { 7577 break; 7578 } 7579 // Reduce: make a binary expression from the three topmost entries. 7580 while ((stack.length > 2) && (prec <= precedences[precedences.length - 1])) { 7581 right = stack.pop(); 7582 var operator = stack.pop(); 7583 precedences.pop(); 7584 left = stack.pop(); 7585 markers.pop(); 7586 var node = this.startNode(markers[markers.length - 1]); 7587 stack.push(this.finalize(node, new Node.BinaryExpression(operator, left, right))); 7588 } 7589 // Shift. 7590 stack.push(this.nextToken().value); 7591 precedences.push(prec); 7592 markers.push(this.lookahead); 7593 stack.push(this.isolateCoverGrammar(this.parseExponentiationExpression)); 7594 } 7595 // Final reduce to clean-up the stack. 7596 var i = stack.length - 1; 7597 expr = stack[i]; 7598 var lastMarker = markers.pop(); 7599 while (i > 1) { 7600 var marker = markers.pop(); 7601 var lastLineStart = lastMarker && lastMarker.lineStart; 7602 var node = this.startNode(marker, lastLineStart); 7603 var operator = stack[i - 1]; 7604 expr = this.finalize(node, new Node.BinaryExpression(operator, stack[i - 2], expr)); 7605 i -= 2; 7606 lastMarker = marker; 7607 } 7608 } 7609 return expr; 7610 }; 7611 // https://tc39.github.io/ecma262/#sec-conditional-operator 7612 Parser.prototype.parseConditionalExpression = function () { 7613 var startToken = this.lookahead; 7614 var expr = this.inheritCoverGrammar(this.parseBinaryExpression); 7615 if (this.match('?')) { 7616 this.nextToken(); 7617 var previousAllowIn = this.context.allowIn; 7618 this.context.allowIn = true; 7619 var consequent = this.isolateCoverGrammar(this.parseAssignmentExpression); 7620 this.context.allowIn = previousAllowIn; 7621 this.expect(':'); 7622 var alternate = this.isolateCoverGrammar(this.parseAssignmentExpression); 7623 expr = this.finalize(this.startNode(startToken), new Node.ConditionalExpression(expr, consequent, alternate)); 7624 this.context.isAssignmentTarget = false; 7625 this.context.isBindingElement = false; 7626 } 7627 return expr; 7628 }; 7629 // https://tc39.github.io/ecma262/#sec-assignment-operators 7630 Parser.prototype.checkPatternParam = function (options, param) { 7631 switch (param.type) { 7632 case syntax_1.Syntax.Identifier: 7633 this.validateParam(options, param, param.name); 7634 break; 7635 case syntax_1.Syntax.RestElement: 7636 this.checkPatternParam(options, param.argument); 7637 break; 7638 case syntax_1.Syntax.AssignmentPattern: 7639 this.checkPatternParam(options, param.left); 7640 break; 7641 case syntax_1.Syntax.ArrayPattern: 7642 for (var i = 0; i < param.elements.length; i++) { 7643 if (param.elements[i] !== null) { 7644 this.checkPatternParam(options, param.elements[i]); 7645 } 7646 } 7647 break; 7648 case syntax_1.Syntax.ObjectPattern: 7649 for (var i = 0; i < param.properties.length; i++) { 7650 this.checkPatternParam(options, param.properties[i].value); 7651 } 7652 break; 7653 default: 7654 break; 7655 } 7656 options.simple = options.simple && (param instanceof Node.Identifier); 7657 }; 7658 Parser.prototype.reinterpretAsCoverFormalsList = function (expr) { 7659 var params = [expr]; 7660 var options; 7661 var asyncArrow = false; 7662 switch (expr.type) { 7663 case syntax_1.Syntax.Identifier: 7664 break; 7665 case ArrowParameterPlaceHolder: 7666 params = expr.params; 7667 asyncArrow = expr.async; 7668 break; 7669 default: 7670 return null; 7671 } 7672 options = { 7673 simple: true, 7674 paramSet: {} 7675 }; 7676 for (var i = 0; i < params.length; ++i) { 7677 var param = params[i]; 7678 if (param.type === syntax_1.Syntax.AssignmentPattern) { 7679 if (param.right.type === syntax_1.Syntax.YieldExpression) { 7680 if (param.right.argument) { 7681 this.throwUnexpectedToken(this.lookahead); 7682 } 7683 param.right.type = syntax_1.Syntax.Identifier; 7684 param.right.name = 'yield'; 7685 delete param.right.argument; 7686 delete param.right.delegate; 7687 } 7688 } 7689 else if (asyncArrow && param.type === syntax_1.Syntax.Identifier && param.name === 'await') { 7690 this.throwUnexpectedToken(this.lookahead); 7691 } 7692 this.checkPatternParam(options, param); 7693 params[i] = param; 7694 } 7695 if (this.context.strict || !this.context.allowYield) { 7696 for (var i = 0; i < params.length; ++i) { 7697 var param = params[i]; 7698 if (param.type === syntax_1.Syntax.YieldExpression) { 7699 this.throwUnexpectedToken(this.lookahead); 7700 } 7701 } 7702 } 7703 if (options.message === messages_1.Messages.StrictParamDupe) { 7704 var token = this.context.strict ? options.stricted : options.firstRestricted; 7705 this.throwUnexpectedToken(token, options.message); 7706 } 7707 return { 7708 simple: options.simple, 7709 params: params, 7710 stricted: options.stricted, 7711 firstRestricted: options.firstRestricted, 7712 message: options.message 7713 }; 7714 }; 7715 Parser.prototype.parseAssignmentExpression = function () { 7716 var expr; 7717 if (!this.context.allowYield && this.matchKeyword('yield')) { 7718 expr = this.parseYieldExpression(); 7719 } 7720 else { 7721 var startToken = this.lookahead; 7722 var token = startToken; 7723 expr = this.parseConditionalExpression(); 7724 if (token.type === 3 /* Identifier */ && (token.lineNumber === this.lookahead.lineNumber) && token.value === 'async') { 7725 if (this.lookahead.type === 3 /* Identifier */ || this.matchKeyword('yield')) { 7726 var arg = this.parsePrimaryExpression(); 7727 this.reinterpretExpressionAsPattern(arg); 7728 expr = { 7729 type: ArrowParameterPlaceHolder, 7730 params: [arg], 7731 async: true 7732 }; 7733 } 7734 } 7735 if (expr.type === ArrowParameterPlaceHolder || this.match('=>')) { 7736 // https://tc39.github.io/ecma262/#sec-arrow-function-definitions 7737 this.context.isAssignmentTarget = false; 7738 this.context.isBindingElement = false; 7739 var isAsync = expr.async; 7740 var list = this.reinterpretAsCoverFormalsList(expr); 7741 if (list) { 7742 if (this.hasLineTerminator) { 7743 this.tolerateUnexpectedToken(this.lookahead); 7744 } 7745 this.context.firstCoverInitializedNameError = null; 7746 var previousStrict = this.context.strict; 7747 var previousAllowStrictDirective = this.context.allowStrictDirective; 7748 this.context.allowStrictDirective = list.simple; 7749 var previousAllowYield = this.context.allowYield; 7750 var previousAwait = this.context.await; 7751 this.context.allowYield = true; 7752 this.context.await = isAsync; 7753 var node = this.startNode(startToken); 7754 this.expect('=>'); 7755 var body = void 0; 7756 if (this.match('{')) { 7757 var previousAllowIn = this.context.allowIn; 7758 this.context.allowIn = true; 7759 body = this.parseFunctionSourceElements(); 7760 this.context.allowIn = previousAllowIn; 7761 } 7762 else { 7763 body = this.isolateCoverGrammar(this.parseAssignmentExpression); 7764 } 7765 var expression = body.type !== syntax_1.Syntax.BlockStatement; 7766 if (this.context.strict && list.firstRestricted) { 7767 this.throwUnexpectedToken(list.firstRestricted, list.message); 7768 } 7769 if (this.context.strict && list.stricted) { 7770 this.tolerateUnexpectedToken(list.stricted, list.message); 7771 } 7772 expr = isAsync ? this.finalize(node, new Node.AsyncArrowFunctionExpression(list.params, body, expression)) : 7773 this.finalize(node, new Node.ArrowFunctionExpression(list.params, body, expression)); 7774 this.context.strict = previousStrict; 7775 this.context.allowStrictDirective = previousAllowStrictDirective; 7776 this.context.allowYield = previousAllowYield; 7777 this.context.await = previousAwait; 7778 } 7779 } 7780 else { 7781 if (this.matchAssign()) { 7782 if (!this.context.isAssignmentTarget) { 7783 this.tolerateError(messages_1.Messages.InvalidLHSInAssignment); 7784 } 7785 if (this.context.strict && expr.type === syntax_1.Syntax.Identifier) { 7786 var id = expr; 7787 if (this.scanner.isRestrictedWord(id.name)) { 7788 this.tolerateUnexpectedToken(token, messages_1.Messages.StrictLHSAssignment); 7789 } 7790 if (this.scanner.isStrictModeReservedWord(id.name)) { 7791 this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord); 7792 } 7793 } 7794 if (!this.match('=')) { 7795 this.context.isAssignmentTarget = false; 7796 this.context.isBindingElement = false; 7797 } 7798 else { 7799 this.reinterpretExpressionAsPattern(expr); 7800 } 7801 token = this.nextToken(); 7802 var operator = token.value; 7803 var right = this.isolateCoverGrammar(this.parseAssignmentExpression); 7804 expr = this.finalize(this.startNode(startToken), new Node.AssignmentExpression(operator, expr, right)); 7805 this.context.firstCoverInitializedNameError = null; 7806 } 7807 } 7808 } 7809 return expr; 7810 }; 7811 // https://tc39.github.io/ecma262/#sec-comma-operator 7812 Parser.prototype.parseExpression = function () { 7813 var startToken = this.lookahead; 7814 var expr = this.isolateCoverGrammar(this.parseAssignmentExpression); 7815 if (this.match(',')) { 7816 var expressions = []; 7817 expressions.push(expr); 7818 while (this.lookahead.type !== 2 /* EOF */) { 7819 if (!this.match(',')) { 7820 break; 7821 } 7822 this.nextToken(); 7823 expressions.push(this.isolateCoverGrammar(this.parseAssignmentExpression)); 7824 } 7825 expr = this.finalize(this.startNode(startToken), new Node.SequenceExpression(expressions)); 7826 } 7827 return expr; 7828 }; 7829 // https://tc39.github.io/ecma262/#sec-block 7830 Parser.prototype.parseStatementListItem = function () { 7831 var statement; 7832 this.context.isAssignmentTarget = true; 7833 this.context.isBindingElement = true; 7834 if (this.lookahead.type === 4 /* Keyword */) { 7835 switch (this.lookahead.value) { 7836 case 'export': 7837 if (!this.context.isModule) { 7838 this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.IllegalExportDeclaration); 7839 } 7840 statement = this.parseExportDeclaration(); 7841 break; 7842 case 'import': 7843 if (!this.context.isModule) { 7844 this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.IllegalImportDeclaration); 7845 } 7846 statement = this.parseImportDeclaration(); 7847 break; 7848 case 'const': 7849 statement = this.parseLexicalDeclaration({ inFor: false }); 7850 break; 7851 case 'function': 7852 statement = this.parseFunctionDeclaration(); 7853 break; 7854 case 'class': 7855 statement = this.parseClassDeclaration(); 7856 break; 7857 case 'let': 7858 statement = this.isLexicalDeclaration() ? this.parseLexicalDeclaration({ inFor: false }) : this.parseStatement(); 7859 break; 7860 default: 7861 statement = this.parseStatement(); 7862 break; 7863 } 7864 } 7865 else { 7866 statement = this.parseStatement(); 7867 } 7868 return statement; 7869 }; 7870 Parser.prototype.parseBlock = function () { 7871 var node = this.createNode(); 7872 this.expect('{'); 7873 var block = []; 7874 while (true) { 7875 if (this.match('}')) { 7876 break; 7877 } 7878 block.push(this.parseStatementListItem()); 7879 } 7880 this.expect('}'); 7881 return this.finalize(node, new Node.BlockStatement(block)); 7882 }; 7883 // https://tc39.github.io/ecma262/#sec-let-and-const-declarations 7884 Parser.prototype.parseLexicalBinding = function (kind, options) { 7885 var node = this.createNode(); 7886 var params = []; 7887 var id = this.parsePattern(params, kind); 7888 if (this.context.strict && id.type === syntax_1.Syntax.Identifier) { 7889 if (this.scanner.isRestrictedWord(id.name)) { 7890 this.tolerateError(messages_1.Messages.StrictVarName); 7891 } 7892 } 7893 var init = null; 7894 if (kind === 'const') { 7895 if (!this.matchKeyword('in') && !this.matchContextualKeyword('of')) { 7896 if (this.match('=')) { 7897 this.nextToken(); 7898 init = this.isolateCoverGrammar(this.parseAssignmentExpression); 7899 } 7900 else { 7901 this.throwError(messages_1.Messages.DeclarationMissingInitializer, 'const'); 7902 } 7903 } 7904 } 7905 else if ((!options.inFor && id.type !== syntax_1.Syntax.Identifier) || this.match('=')) { 7906 this.expect('='); 7907 init = this.isolateCoverGrammar(this.parseAssignmentExpression); 7908 } 7909 return this.finalize(node, new Node.VariableDeclarator(id, init)); 7910 }; 7911 Parser.prototype.parseBindingList = function (kind, options) { 7912 var list = [this.parseLexicalBinding(kind, options)]; 7913 while (this.match(',')) { 7914 this.nextToken(); 7915 list.push(this.parseLexicalBinding(kind, options)); 7916 } 7917 return list; 7918 }; 7919 Parser.prototype.isLexicalDeclaration = function () { 7920 var state = this.scanner.saveState(); 7921 this.scanner.scanComments(); 7922 var next = this.scanner.lex(); 7923 this.scanner.restoreState(state); 7924 return (next.type === 3 /* Identifier */) || 7925 (next.type === 7 /* Punctuator */ && next.value === '[') || 7926 (next.type === 7 /* Punctuator */ && next.value === '{') || 7927 (next.type === 4 /* Keyword */ && next.value === 'let') || 7928 (next.type === 4 /* Keyword */ && next.value === 'yield'); 7929 }; 7930 Parser.prototype.parseLexicalDeclaration = function (options) { 7931 var node = this.createNode(); 7932 var kind = this.nextToken().value; 7933 assert_1.assert(kind === 'let' || kind === 'const', 'Lexical declaration must be either let or const'); 7934 var declarations = this.parseBindingList(kind, options); 7935 this.consumeSemicolon(); 7936 return this.finalize(node, new Node.VariableDeclaration(declarations, kind)); 7937 }; 7938 // https://tc39.github.io/ecma262/#sec-destructuring-binding-patterns 7939 Parser.prototype.parseBindingRestElement = function (params, kind) { 7940 var node = this.createNode(); 7941 this.expect('...'); 7942 var arg = this.parsePattern(params, kind); 7943 return this.finalize(node, new Node.RestElement(arg)); 7944 }; 7945 Parser.prototype.parseArrayPattern = function (params, kind) { 7946 var node = this.createNode(); 7947 this.expect('['); 7948 var elements = []; 7949 while (!this.match(']')) { 7950 if (this.match(',')) { 7951 this.nextToken(); 7952 elements.push(null); 7953 } 7954 else { 7955 if (this.match('...')) { 7956 elements.push(this.parseBindingRestElement(params, kind)); 7957 break; 7958 } 7959 else { 7960 elements.push(this.parsePatternWithDefault(params, kind)); 7961 } 7962 if (!this.match(']')) { 7963 this.expect(','); 7964 } 7965 } 7966 } 7967 this.expect(']'); 7968 return this.finalize(node, new Node.ArrayPattern(elements)); 7969 }; 7970 Parser.prototype.parsePropertyPattern = function (params, kind) { 7971 var node = this.createNode(); 7972 var computed = false; 7973 var shorthand = false; 7974 var method = false; 7975 var key; 7976 var value; 7977 if (this.lookahead.type === 3 /* Identifier */) { 7978 var keyToken = this.lookahead; 7979 key = this.parseVariableIdentifier(); 7980 var init = this.finalize(node, new Node.Identifier(keyToken.value)); 7981 if (this.match('=')) { 7982 params.push(keyToken); 7983 shorthand = true; 7984 this.nextToken(); 7985 var expr = this.parseAssignmentExpression(); 7986 value = this.finalize(this.startNode(keyToken), new Node.AssignmentPattern(init, expr)); 7987 } 7988 else if (!this.match(':')) { 7989 params.push(keyToken); 7990 shorthand = true; 7991 value = init; 7992 } 7993 else { 7994 this.expect(':'); 7995 value = this.parsePatternWithDefault(params, kind); 7996 } 7997 } 7998 else { 7999 computed = this.match('['); 8000 key = this.parseObjectPropertyKey(); 8001 this.expect(':'); 8002 value = this.parsePatternWithDefault(params, kind); 8003 } 8004 return this.finalize(node, new Node.Property('init', key, computed, value, method, shorthand)); 8005 }; 8006 Parser.prototype.parseObjectPattern = function (params, kind) { 8007 var node = this.createNode(); 8008 var properties = []; 8009 this.expect('{'); 8010 while (!this.match('}')) { 8011 properties.push(this.parsePropertyPattern(params, kind)); 8012 if (!this.match('}')) { 8013 this.expect(','); 8014 } 8015 } 8016 this.expect('}'); 8017 return this.finalize(node, new Node.ObjectPattern(properties)); 8018 }; 8019 Parser.prototype.parsePattern = function (params, kind) { 8020 var pattern; 8021 if (this.match('[')) { 8022 pattern = this.parseArrayPattern(params, kind); 8023 } 8024 else if (this.match('{')) { 8025 pattern = this.parseObjectPattern(params, kind); 8026 } 8027 else { 8028 if (this.matchKeyword('let') && (kind === 'const' || kind === 'let')) { 8029 this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.LetInLexicalBinding); 8030 } 8031 params.push(this.lookahead); 8032 pattern = this.parseVariableIdentifier(kind); 8033 } 8034 return pattern; 8035 }; 8036 Parser.prototype.parsePatternWithDefault = function (params, kind) { 8037 var startToken = this.lookahead; 8038 var pattern = this.parsePattern(params, kind); 8039 if (this.match('=')) { 8040 this.nextToken(); 8041 var previousAllowYield = this.context.allowYield; 8042 this.context.allowYield = true; 8043 var right = this.isolateCoverGrammar(this.parseAssignmentExpression); 8044 this.context.allowYield = previousAllowYield; 8045 pattern = this.finalize(this.startNode(startToken), new Node.AssignmentPattern(pattern, right)); 8046 } 8047 return pattern; 8048 }; 8049 // https://tc39.github.io/ecma262/#sec-variable-statement 8050 Parser.prototype.parseVariableIdentifier = function (kind) { 8051 var node = this.createNode(); 8052 var token = this.nextToken(); 8053 if (token.type === 4 /* Keyword */ && token.value === 'yield') { 8054 if (this.context.strict) { 8055 this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord); 8056 } 8057 else if (!this.context.allowYield) { 8058 this.throwUnexpectedToken(token); 8059 } 8060 } 8061 else if (token.type !== 3 /* Identifier */) { 8062 if (this.context.strict && token.type === 4 /* Keyword */ && this.scanner.isStrictModeReservedWord(token.value)) { 8063 this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord); 8064 } 8065 else { 8066 if (this.context.strict || token.value !== 'let' || kind !== 'var') { 8067 this.throwUnexpectedToken(token); 8068 } 8069 } 8070 } 8071 else if ((this.context.isModule || this.context.await) && token.type === 3 /* Identifier */ && token.value === 'await') { 8072 this.tolerateUnexpectedToken(token); 8073 } 8074 return this.finalize(node, new Node.Identifier(token.value)); 8075 }; 8076 Parser.prototype.parseVariableDeclaration = function (options) { 8077 var node = this.createNode(); 8078 var params = []; 8079 var id = this.parsePattern(params, 'var'); 8080 if (this.context.strict && id.type === syntax_1.Syntax.Identifier) { 8081 if (this.scanner.isRestrictedWord(id.name)) { 8082 this.tolerateError(messages_1.Messages.StrictVarName); 8083 } 8084 } 8085 var init = null; 8086 if (this.match('=')) { 8087 this.nextToken(); 8088 init = this.isolateCoverGrammar(this.parseAssignmentExpression); 8089 } 8090 else if (id.type !== syntax_1.Syntax.Identifier && !options.inFor) { 8091 this.expect('='); 8092 } 8093 return this.finalize(node, new Node.VariableDeclarator(id, init)); 8094 }; 8095 Parser.prototype.parseVariableDeclarationList = function (options) { 8096 var opt = { inFor: options.inFor }; 8097 var list = []; 8098 list.push(this.parseVariableDeclaration(opt)); 8099 while (this.match(',')) { 8100 this.nextToken(); 8101 list.push(this.parseVariableDeclaration(opt)); 8102 } 8103 return list; 8104 }; 8105 Parser.prototype.parseVariableStatement = function () { 8106 var node = this.createNode(); 8107 this.expectKeyword('var'); 8108 var declarations = this.parseVariableDeclarationList({ inFor: false }); 8109 this.consumeSemicolon(); 8110 return this.finalize(node, new Node.VariableDeclaration(declarations, 'var')); 8111 }; 8112 // https://tc39.github.io/ecma262/#sec-empty-statement 8113 Parser.prototype.parseEmptyStatement = function () { 8114 var node = this.createNode(); 8115 this.expect(';'); 8116 return this.finalize(node, new Node.EmptyStatement()); 8117 }; 8118 // https://tc39.github.io/ecma262/#sec-expression-statement 8119 Parser.prototype.parseExpressionStatement = function () { 8120 var node = this.createNode(); 8121 var expr = this.parseExpression(); 8122 this.consumeSemicolon(); 8123 return this.finalize(node, new Node.ExpressionStatement(expr)); 8124 }; 8125 // https://tc39.github.io/ecma262/#sec-if-statement 8126 Parser.prototype.parseIfClause = function () { 8127 if (this.context.strict && this.matchKeyword('function')) { 8128 this.tolerateError(messages_1.Messages.StrictFunction); 8129 } 8130 return this.parseStatement(); 8131 }; 8132 Parser.prototype.parseIfStatement = function () { 8133 var node = this.createNode(); 8134 var consequent; 8135 var alternate = null; 8136 this.expectKeyword('if'); 8137 this.expect('('); 8138 var test = this.parseExpression(); 8139 if (!this.match(')') && this.config.tolerant) { 8140 this.tolerateUnexpectedToken(this.nextToken()); 8141 consequent = this.finalize(this.createNode(), new Node.EmptyStatement()); 8142 } 8143 else { 8144 this.expect(')'); 8145 consequent = this.parseIfClause(); 8146 if (this.matchKeyword('else')) { 8147 this.nextToken(); 8148 alternate = this.parseIfClause(); 8149 } 8150 } 8151 return this.finalize(node, new Node.IfStatement(test, consequent, alternate)); 8152 }; 8153 // https://tc39.github.io/ecma262/#sec-do-while-statement 8154 Parser.prototype.parseDoWhileStatement = function () { 8155 var node = this.createNode(); 8156 this.expectKeyword('do'); 8157 var previousInIteration = this.context.inIteration; 8158 this.context.inIteration = true; 8159 var body = this.parseStatement(); 8160 this.context.inIteration = previousInIteration; 8161 this.expectKeyword('while'); 8162 this.expect('('); 8163 var test = this.parseExpression(); 8164 if (!this.match(')') && this.config.tolerant) { 8165 this.tolerateUnexpectedToken(this.nextToken()); 8166 } 8167 else { 8168 this.expect(')'); 8169 if (this.match(';')) { 8170 this.nextToken(); 8171 } 8172 } 8173 return this.finalize(node, new Node.DoWhileStatement(body, test)); 8174 }; 8175 // https://tc39.github.io/ecma262/#sec-while-statement 8176 Parser.prototype.parseWhileStatement = function () { 8177 var node = this.createNode(); 8178 var body; 8179 this.expectKeyword('while'); 8180 this.expect('('); 8181 var test = this.parseExpression(); 8182 if (!this.match(')') && this.config.tolerant) { 8183 this.tolerateUnexpectedToken(this.nextToken()); 8184 body = this.finalize(this.createNode(), new Node.EmptyStatement()); 8185 } 8186 else { 8187 this.expect(')'); 8188 var previousInIteration = this.context.inIteration; 8189 this.context.inIteration = true; 8190 body = this.parseStatement(); 8191 this.context.inIteration = previousInIteration; 8192 } 8193 return this.finalize(node, new Node.WhileStatement(test, body)); 8194 }; 8195 // https://tc39.github.io/ecma262/#sec-for-statement 8196 // https://tc39.github.io/ecma262/#sec-for-in-and-for-of-statements 8197 Parser.prototype.parseForStatement = function () { 8198 var init = null; 8199 var test = null; 8200 var update = null; 8201 var forIn = true; 8202 var left, right; 8203 var node = this.createNode(); 8204 this.expectKeyword('for'); 8205 this.expect('('); 8206 if (this.match(';')) { 8207 this.nextToken(); 8208 } 8209 else { 8210 if (this.matchKeyword('var')) { 8211 init = this.createNode(); 8212 this.nextToken(); 8213 var previousAllowIn = this.context.allowIn; 8214 this.context.allowIn = false; 8215 var declarations = this.parseVariableDeclarationList({ inFor: true }); 8216 this.context.allowIn = previousAllowIn; 8217 if (declarations.length === 1 && this.matchKeyword('in')) { 8218 var decl = declarations[0]; 8219 if (decl.init && (decl.id.type === syntax_1.Syntax.ArrayPattern || decl.id.type === syntax_1.Syntax.ObjectPattern || this.context.strict)) { 8220 this.tolerateError(messages_1.Messages.ForInOfLoopInitializer, 'for-in'); 8221 } 8222 init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var')); 8223 this.nextToken(); 8224 left = init; 8225 right = this.parseExpression(); 8226 init = null; 8227 } 8228 else if (declarations.length === 1 && declarations[0].init === null && this.matchContextualKeyword('of')) { 8229 init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var')); 8230 this.nextToken(); 8231 left = init; 8232 right = this.parseAssignmentExpression(); 8233 init = null; 8234 forIn = false; 8235 } 8236 else { 8237 init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var')); 8238 this.expect(';'); 8239 } 8240 } 8241 else if (this.matchKeyword('const') || this.matchKeyword('let')) { 8242 init = this.createNode(); 8243 var kind = this.nextToken().value; 8244 if (!this.context.strict && this.lookahead.value === 'in') { 8245 init = this.finalize(init, new Node.Identifier(kind)); 8246 this.nextToken(); 8247 left = init; 8248 right = this.parseExpression(); 8249 init = null; 8250 } 8251 else { 8252 var previousAllowIn = this.context.allowIn; 8253 this.context.allowIn = false; 8254 var declarations = this.parseBindingList(kind, { inFor: true }); 8255 this.context.allowIn = previousAllowIn; 8256 if (declarations.length === 1 && declarations[0].init === null && this.matchKeyword('in')) { 8257 init = this.finalize(init, new Node.VariableDeclaration(declarations, kind)); 8258 this.nextToken(); 8259 left = init; 8260 right = this.parseExpression(); 8261 init = null; 8262 } 8263 else if (declarations.length === 1 && declarations[0].init === null && this.matchContextualKeyword('of')) { 8264 init = this.finalize(init, new Node.VariableDeclaration(declarations, kind)); 8265 this.nextToken(); 8266 left = init; 8267 right = this.parseAssignmentExpression(); 8268 init = null; 8269 forIn = false; 8270 } 8271 else { 8272 this.consumeSemicolon(); 8273 init = this.finalize(init, new Node.VariableDeclaration(declarations, kind)); 8274 } 8275 } 8276 } 8277 else { 8278 var initStartToken = this.lookahead; 8279 var previousAllowIn = this.context.allowIn; 8280 this.context.allowIn = false; 8281 init = this.inheritCoverGrammar(this.parseAssignmentExpression); 8282 this.context.allowIn = previousAllowIn; 8283 if (this.matchKeyword('in')) { 8284 if (!this.context.isAssignmentTarget || init.type === syntax_1.Syntax.AssignmentExpression) { 8285 this.tolerateError(messages_1.Messages.InvalidLHSInForIn); 8286 } 8287 this.nextToken(); 8288 this.reinterpretExpressionAsPattern(init); 8289 left = init; 8290 right = this.parseExpression(); 8291 init = null; 8292 } 8293 else if (this.matchContextualKeyword('of')) { 8294 if (!this.context.isAssignmentTarget || init.type === syntax_1.Syntax.AssignmentExpression) { 8295 this.tolerateError(messages_1.Messages.InvalidLHSInForLoop); 8296 } 8297 this.nextToken(); 8298 this.reinterpretExpressionAsPattern(init); 8299 left = init; 8300 right = this.parseAssignmentExpression(); 8301 init = null; 8302 forIn = false; 8303 } 8304 else { 8305 if (this.match(',')) { 8306 var initSeq = [init]; 8307 while (this.match(',')) { 8308 this.nextToken(); 8309 initSeq.push(this.isolateCoverGrammar(this.parseAssignmentExpression)); 8310 } 8311 init = this.finalize(this.startNode(initStartToken), new Node.SequenceExpression(initSeq)); 8312 } 8313 this.expect(';'); 8314 } 8315 } 8316 } 8317 if (typeof left === 'undefined') { 8318 if (!this.match(';')) { 8319 test = this.parseExpression(); 8320 } 8321 this.expect(';'); 8322 if (!this.match(')')) { 8323 update = this.parseExpression(); 8324 } 8325 } 8326 var body; 8327 if (!this.match(')') && this.config.tolerant) { 8328 this.tolerateUnexpectedToken(this.nextToken()); 8329 body = this.finalize(this.createNode(), new Node.EmptyStatement()); 8330 } 8331 else { 8332 this.expect(')'); 8333 var previousInIteration = this.context.inIteration; 8334 this.context.inIteration = true; 8335 body = this.isolateCoverGrammar(this.parseStatement); 8336 this.context.inIteration = previousInIteration; 8337 } 8338 return (typeof left === 'undefined') ? 8339 this.finalize(node, new Node.ForStatement(init, test, update, body)) : 8340 forIn ? this.finalize(node, new Node.ForInStatement(left, right, body)) : 8341 this.finalize(node, new Node.ForOfStatement(left, right, body)); 8342 }; 8343 // https://tc39.github.io/ecma262/#sec-continue-statement 8344 Parser.prototype.parseContinueStatement = function () { 8345 var node = this.createNode(); 8346 this.expectKeyword('continue'); 8347 var label = null; 8348 if (this.lookahead.type === 3 /* Identifier */ && !this.hasLineTerminator) { 8349 var id = this.parseVariableIdentifier(); 8350 label = id; 8351 var key = '$' + id.name; 8352 if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) { 8353 this.throwError(messages_1.Messages.UnknownLabel, id.name); 8354 } 8355 } 8356 this.consumeSemicolon(); 8357 if (label === null && !this.context.inIteration) { 8358 this.throwError(messages_1.Messages.IllegalContinue); 8359 } 8360 return this.finalize(node, new Node.ContinueStatement(label)); 8361 }; 8362 // https://tc39.github.io/ecma262/#sec-break-statement 8363 Parser.prototype.parseBreakStatement = function () { 8364 var node = this.createNode(); 8365 this.expectKeyword('break'); 8366 var label = null; 8367 if (this.lookahead.type === 3 /* Identifier */ && !this.hasLineTerminator) { 8368 var id = this.parseVariableIdentifier(); 8369 var key = '$' + id.name; 8370 if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) { 8371 this.throwError(messages_1.Messages.UnknownLabel, id.name); 8372 } 8373 label = id; 8374 } 8375 this.consumeSemicolon(); 8376 if (label === null && !this.context.inIteration && !this.context.inSwitch) { 8377 this.throwError(messages_1.Messages.IllegalBreak); 8378 } 8379 return this.finalize(node, new Node.BreakStatement(label)); 8380 }; 8381 // https://tc39.github.io/ecma262/#sec-return-statement 8382 Parser.prototype.parseReturnStatement = function () { 8383 if (!this.context.inFunctionBody) { 8384 this.tolerateError(messages_1.Messages.IllegalReturn); 8385 } 8386 var node = this.createNode(); 8387 this.expectKeyword('return'); 8388 var hasArgument = (!this.match(';') && !this.match('}') && 8389 !this.hasLineTerminator && this.lookahead.type !== 2 /* EOF */) || 8390 this.lookahead.type === 8 /* StringLiteral */ || 8391 this.lookahead.type === 10 /* Template */; 8392 var argument = hasArgument ? this.parseExpression() : null; 8393 this.consumeSemicolon(); 8394 return this.finalize(node, new Node.ReturnStatement(argument)); 8395 }; 8396 // https://tc39.github.io/ecma262/#sec-with-statement 8397 Parser.prototype.parseWithStatement = function () { 8398 if (this.context.strict) { 8399 this.tolerateError(messages_1.Messages.StrictModeWith); 8400 } 8401 var node = this.createNode(); 8402 var body; 8403 this.expectKeyword('with'); 8404 this.expect('('); 8405 var object = this.parseExpression(); 8406 if (!this.match(')') && this.config.tolerant) { 8407 this.tolerateUnexpectedToken(this.nextToken()); 8408 body = this.finalize(this.createNode(), new Node.EmptyStatement()); 8409 } 8410 else { 8411 this.expect(')'); 8412 body = this.parseStatement(); 8413 } 8414 return this.finalize(node, new Node.WithStatement(object, body)); 8415 }; 8416 // https://tc39.github.io/ecma262/#sec-switch-statement 8417 Parser.prototype.parseSwitchCase = function () { 8418 var node = this.createNode(); 8419 var test; 8420 if (this.matchKeyword('default')) { 8421 this.nextToken(); 8422 test = null; 8423 } 8424 else { 8425 this.expectKeyword('case'); 8426 test = this.parseExpression(); 8427 } 8428 this.expect(':'); 8429 var consequent = []; 8430 while (true) { 8431 if (this.match('}') || this.matchKeyword('default') || this.matchKeyword('case')) { 8432 break; 8433 } 8434 consequent.push(this.parseStatementListItem()); 8435 } 8436 return this.finalize(node, new Node.SwitchCase(test, consequent)); 8437 }; 8438 Parser.prototype.parseSwitchStatement = function () { 8439 var node = this.createNode(); 8440 this.expectKeyword('switch'); 8441 this.expect('('); 8442 var discriminant = this.parseExpression(); 8443 this.expect(')'); 8444 var previousInSwitch = this.context.inSwitch; 8445 this.context.inSwitch = true; 8446 var cases = []; 8447 var defaultFound = false; 8448 this.expect('{'); 8449 while (true) { 8450 if (this.match('}')) { 8451 break; 8452 } 8453 var clause = this.parseSwitchCase(); 8454 if (clause.test === null) { 8455 if (defaultFound) { 8456 this.throwError(messages_1.Messages.MultipleDefaultsInSwitch); 8457 } 8458 defaultFound = true; 8459 } 8460 cases.push(clause); 8461 } 8462 this.expect('}'); 8463 this.context.inSwitch = previousInSwitch; 8464 return this.finalize(node, new Node.SwitchStatement(discriminant, cases)); 8465 }; 8466 // https://tc39.github.io/ecma262/#sec-labelled-statements 8467 Parser.prototype.parseLabelledStatement = function () { 8468 var node = this.createNode(); 8469 var expr = this.parseExpression(); 8470 var statement; 8471 if ((expr.type === syntax_1.Syntax.Identifier) && this.match(':')) { 8472 this.nextToken(); 8473 var id = expr; 8474 var key = '$' + id.name; 8475 if (Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) { 8476 this.throwError(messages_1.Messages.Redeclaration, 'Label', id.name); 8477 } 8478 this.context.labelSet[key] = true; 8479 var body = void 0; 8480 if (this.matchKeyword('class')) { 8481 this.tolerateUnexpectedToken(this.lookahead); 8482 body = this.parseClassDeclaration(); 8483 } 8484 else if (this.matchKeyword('function')) { 8485 var token = this.lookahead; 8486 var declaration = this.parseFunctionDeclaration(); 8487 if (this.context.strict) { 8488 this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunction); 8489 } 8490 else if (declaration.generator) { 8491 this.tolerateUnexpectedToken(token, messages_1.Messages.GeneratorInLegacyContext); 8492 } 8493 body = declaration; 8494 } 8495 else { 8496 body = this.parseStatement(); 8497 } 8498 delete this.context.labelSet[key]; 8499 statement = new Node.LabeledStatement(id, body); 8500 } 8501 else { 8502 this.consumeSemicolon(); 8503 statement = new Node.ExpressionStatement(expr); 8504 } 8505 return this.finalize(node, statement); 8506 }; 8507 // https://tc39.github.io/ecma262/#sec-throw-statement 8508 Parser.prototype.parseThrowStatement = function () { 8509 var node = this.createNode(); 8510 this.expectKeyword('throw'); 8511 if (this.hasLineTerminator) { 8512 this.throwError(messages_1.Messages.NewlineAfterThrow); 8513 } 8514 var argument = this.parseExpression(); 8515 this.consumeSemicolon(); 8516 return this.finalize(node, new Node.ThrowStatement(argument)); 8517 }; 8518 // https://tc39.github.io/ecma262/#sec-try-statement 8519 Parser.prototype.parseCatchClause = function () { 8520 var node = this.createNode(); 8521 this.expectKeyword('catch'); 8522 this.expect('('); 8523 if (this.match(')')) { 8524 this.throwUnexpectedToken(this.lookahead); 8525 } 8526 var params = []; 8527 var param = this.parsePattern(params); 8528 var paramMap = {}; 8529 for (var i = 0; i < params.length; i++) { 8530 var key = '$' + params[i].value; 8531 if (Object.prototype.hasOwnProperty.call(paramMap, key)) { 8532 this.tolerateError(messages_1.Messages.DuplicateBinding, params[i].value); 8533 } 8534 paramMap[key] = true; 8535 } 8536 if (this.context.strict && param.type === syntax_1.Syntax.Identifier) { 8537 if (this.scanner.isRestrictedWord(param.name)) { 8538 this.tolerateError(messages_1.Messages.StrictCatchVariable); 8539 } 8540 } 8541 this.expect(')'); 8542 var body = this.parseBlock(); 8543 return this.finalize(node, new Node.CatchClause(param, body)); 8544 }; 8545 Parser.prototype.parseFinallyClause = function () { 8546 this.expectKeyword('finally'); 8547 return this.parseBlock(); 8548 }; 8549 Parser.prototype.parseTryStatement = function () { 8550 var node = this.createNode(); 8551 this.expectKeyword('try'); 8552 var block = this.parseBlock(); 8553 var handler = this.matchKeyword('catch') ? this.parseCatchClause() : null; 8554 var finalizer = this.matchKeyword('finally') ? this.parseFinallyClause() : null; 8555 if (!handler && !finalizer) { 8556 this.throwError(messages_1.Messages.NoCatchOrFinally); 8557 } 8558 return this.finalize(node, new Node.TryStatement(block, handler, finalizer)); 8559 }; 8560 // https://tc39.github.io/ecma262/#sec-debugger-statement 8561 Parser.prototype.parseDebuggerStatement = function () { 8562 var node = this.createNode(); 8563 this.expectKeyword('debugger'); 8564 this.consumeSemicolon(); 8565 return this.finalize(node, new Node.DebuggerStatement()); 8566 }; 8567 // https://tc39.github.io/ecma262/#sec-ecmascript-language-statements-and-declarations 8568 Parser.prototype.parseStatement = function () { 8569 var statement; 8570 switch (this.lookahead.type) { 8571 case 1 /* BooleanLiteral */: 8572 case 5 /* NullLiteral */: 8573 case 6 /* NumericLiteral */: 8574 case 8 /* StringLiteral */: 8575 case 10 /* Template */: 8576 case 9 /* RegularExpression */: 8577 statement = this.parseExpressionStatement(); 8578 break; 8579 case 7 /* Punctuator */: 8580 var value = this.lookahead.value; 8581 if (value === '{') { 8582 statement = this.parseBlock(); 8583 } 8584 else if (value === '(') { 8585 statement = this.parseExpressionStatement(); 8586 } 8587 else if (value === ';') { 8588 statement = this.parseEmptyStatement(); 8589 } 8590 else {
8591 statement = this.parseExpressionStatement(); 8592 } 8593 break; 8594 case 3 /* Identifier */: 8595 statement = this.matchAsyncFunction() ? this.parseFunctionDeclaration() : this.parseLabelledStatement(); 8596 break; 8597 case 4 /* Keyword */: 8598 switch (this.lookahead.value) { 8599 case 'break': 8600 statement = this.parseBreakStatement(); 8601 break; 8602 case 'continue': 8603 statement = this.parseContinueStatement(); 8604 break; 8605 case 'debugger': 8606 statement = this.parseDebuggerStatement(); 8607 break; 8608 case 'do': 8609 statement = this.parseDoWhileStatement(); 8610 break; 8611 case 'for': 8612 statement = this.parseForStatement(); 8613 break; 8614 case 'function': 8615 statement = this.parseFunctionDeclaration(); 8616 break; 8617 case 'if': 8618 statement = this.parseIfStatement(); 8619 break; 8620 case 'return':
vendor: 81,785 bytes, lines 8621-10557
8621 statement = this.parseReturnStatement(); 8622 break; 8623 case 'switch': 8624 statement = this.parseSwitchStatement(); 8625 break; 8626 case 'throw': 8627 statement = this.parseThrowStatement(); 8628 break; 8629 case 'try': 8630 statement = this.parseTryStatement(); 8631 break; 8632 case 'var': 8633 statement = this.parseVariableStatement(); 8634 break; 8635 case 'while': 8636 statement = this.parseWhileStatement(); 8637 break; 8638 case 'with': 8639 statement = this.parseWithStatement(); 8640 break; 8641 default: 8642 statement = this.parseExpressionStatement(); 8643 break; 8644 } 8645 break; 8646 default: 8647 statement = this.throwUnexpectedToken(this.lookahead); 8648 } 8649 return statement; 8650 }; 8651 // https://tc39.github.io/ecma262/#sec-function-definitions 8652 Parser.prototype.parseFunctionSourceElements = function () { 8653 var node = this.createNode(); 8654 this.expect('{'); 8655 var body = this.parseDirectivePrologues(); 8656 var previousLabelSet = this.context.labelSet; 8657 var previousInIteration = this.context.inIteration; 8658 var previousInSwitch = this.context.inSwitch; 8659 var previousInFunctionBody = this.context.inFunctionBody; 8660 this.context.labelSet = {}; 8661 this.context.inIteration = false; 8662 this.context.inSwitch = false; 8663 this.context.inFunctionBody = true; 8664 while (this.lookahead.type !== 2 /* EOF */) { 8665 if (this.match('}')) { 8666 break; 8667 } 8668 body.push(this.parseStatementListItem()); 8669 } 8670 this.expect('}'); 8671 this.context.labelSet = previousLabelSet; 8672 this.context.inIteration = previousInIteration; 8673 this.context.inSwitch = previousInSwitch; 8674 this.context.inFunctionBody = previousInFunctionBody; 8675 return this.finalize(node, new Node.BlockStatement(body)); 8676 }; 8677 Parser.prototype.validateParam = function (options, param, name) { 8678 var key = '$' + name; 8679 if (this.context.strict) { 8680 if (this.scanner.isRestrictedWord(name)) { 8681 options.stricted = param; 8682 options.message = messages_1.Messages.StrictParamName; 8683 } 8684 if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { 8685 options.stricted = param; 8686 options.message = messages_1.Messages.StrictParamDupe; 8687 } 8688 } 8689 else if (!options.firstRestricted) { 8690 if (this.scanner.isRestrictedWord(name)) { 8691 options.firstRestricted = param; 8692 options.message = messages_1.Messages.StrictParamName; 8693 } 8694 else if (this.scanner.isStrictModeReservedWord(name)) { 8695 options.firstRestricted = param; 8696 options.message = messages_1.Messages.StrictReservedWord; 8697 } 8698 else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { 8699 options.stricted = param; 8700 options.message = messages_1.Messages.StrictParamDupe; 8701 } 8702 } 8703 /* istanbul ignore next */ 8704 if (typeof Object.defineProperty === 'function') { 8705 Object.defineProperty(options.paramSet, key, { value: true, enumerable: true, writable: true, configurable: true }); 8706 } 8707 else { 8708 options.paramSet[key] = true; 8709 } 8710 }; 8711 Parser.prototype.parseRestElement = function (params) { 8712 var node = this.createNode(); 8713 this.expect('...'); 8714 var arg = this.parsePattern(params); 8715 if (this.match('=')) { 8716 this.throwError(messages_1.Messages.DefaultRestParameter); 8717 } 8718 if (!this.match(')')) { 8719 this.throwError(messages_1.Messages.ParameterAfterRestParameter); 8720 } 8721 return this.finalize(node, new Node.RestElement(arg)); 8722 }; 8723 Parser.prototype.parseFormalParameter = function (options) { 8724 var params = []; 8725 var param = this.match('...') ? this.parseRestElement(params) : this.parsePatternWithDefault(params); 8726 for (var i = 0; i < params.length; i++) { 8727 this.validateParam(options, params[i], params[i].value); 8728 } 8729 options.simple = options.simple && (param instanceof Node.Identifier); 8730 options.params.push(param); 8731 }; 8732 Parser.prototype.parseFormalParameters = function (firstRestricted) { 8733 var options; 8734 options = { 8735 simple: true, 8736 params: [], 8737 firstRestricted: firstRestricted 8738 }; 8739 this.expect('('); 8740 if (!this.match(')')) { 8741 options.paramSet = {}; 8742 while (this.lookahead.type !== 2 /* EOF */) { 8743 this.parseFormalParameter(options); 8744 if (this.match(')')) { 8745 break; 8746 } 8747 this.expect(','); 8748 if (this.match(')')) { 8749 break; 8750 } 8751 } 8752 } 8753 this.expect(')'); 8754 return { 8755 simple: options.simple, 8756 params: options.params, 8757 stricted: options.stricted, 8758 firstRestricted: options.firstRestricted, 8759 message: options.message 8760 }; 8761 }; 8762 Parser.prototype.matchAsyncFunction = function () { 8763 var match = this.matchContextualKeyword('async'); 8764 if (match) { 8765 var state = this.scanner.saveState(); 8766 this.scanner.scanComments(); 8767 var next = this.scanner.lex(); 8768 this.scanner.restoreState(state); 8769 match = (state.lineNumber === next.lineNumber) && (next.type === 4 /* Keyword */) && (next.value === 'function'); 8770 } 8771 return match; 8772 }; 8773 Parser.prototype.parseFunctionDeclaration = function (identifierIsOptional) { 8774 var node = this.createNode(); 8775 var isAsync = this.matchContextualKeyword('async'); 8776 if (isAsync) { 8777 this.nextToken(); 8778 } 8779 this.expectKeyword('function'); 8780 var isGenerator = isAsync ? false : this.match('*'); 8781 if (isGenerator) { 8782 this.nextToken(); 8783 } 8784 var message; 8785 var id = null; 8786 var firstRestricted = null; 8787 if (!identifierIsOptional || !this.match('(')) { 8788 var token = this.lookahead; 8789 id = this.parseVariableIdentifier(); 8790 if (this.context.strict) { 8791 if (this.scanner.isRestrictedWord(token.value)) { 8792 this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunctionName); 8793 } 8794 } 8795 else { 8796 if (this.scanner.isRestrictedWord(token.value)) { 8797 firstRestricted = token; 8798 message = messages_1.Messages.StrictFunctionName; 8799 } 8800 else if (this.scanner.isStrictModeReservedWord(token.value)) { 8801 firstRestricted = token; 8802 message = messages_1.Messages.StrictReservedWord; 8803 } 8804 } 8805 } 8806 var previousAllowAwait = this.context.await; 8807 var previousAllowYield = this.context.allowYield; 8808 this.context.await = isAsync; 8809 this.context.allowYield = !isGenerator; 8810 var formalParameters = this.parseFormalParameters(firstRestricted); 8811 var params = formalParameters.params; 8812 var stricted = formalParameters.stricted; 8813 firstRestricted = formalParameters.firstRestricted; 8814 if (formalParameters.message) { 8815 message = formalParameters.message; 8816 } 8817 var previousStrict = this.context.strict; 8818 var previousAllowStrictDirective = this.context.allowStrictDirective; 8819 this.context.allowStrictDirective = formalParameters.simple; 8820 var body = this.parseFunctionSourceElements(); 8821 if (this.context.strict && firstRestricted) { 8822 this.throwUnexpectedToken(firstRestricted, message); 8823 } 8824 if (this.context.strict && stricted) { 8825 this.tolerateUnexpectedToken(stricted, message); 8826 } 8827 this.context.strict = previousStrict; 8828 this.context.allowStrictDirective = previousAllowStrictDirective; 8829 this.context.await = previousAllowAwait; 8830 this.context.allowYield = previousAllowYield; 8831 return isAsync ? this.finalize(node, new Node.AsyncFunctionDeclaration(id, params, body)) : 8832 this.finalize(node, new Node.FunctionDeclaration(id, params, body, isGenerator)); 8833 }; 8834 Parser.prototype.parseFunctionExpression = function () { 8835 var node = this.createNode(); 8836 var isAsync = this.matchContextualKeyword('async'); 8837 if (isAsync) { 8838 this.nextToken(); 8839 } 8840 this.expectKeyword('function'); 8841 var isGenerator = isAsync ? false : this.match('*'); 8842 if (isGenerator) { 8843 this.nextToken(); 8844 } 8845 var message; 8846 var id = null; 8847 var firstRestricted; 8848 var previousAllowAwait = this.context.await; 8849 var previousAllowYield = this.context.allowYield; 8850 this.context.await = isAsync; 8851 this.context.allowYield = !isGenerator; 8852 if (!this.match('(')) { 8853 var token = this.lookahead; 8854 id = (!this.context.strict && !isGenerator && this.matchKeyword('yield')) ? this.parseIdentifierName() : this.parseVariableIdentifier(); 8855 if (this.context.strict) { 8856 if (this.scanner.isRestrictedWord(token.value)) { 8857 this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunctionName); 8858 } 8859 } 8860 else { 8861 if (this.scanner.isRestrictedWord(token.value)) { 8862 firstRestricted = token; 8863 message = messages_1.Messages.StrictFunctionName; 8864 } 8865 else if (this.scanner.isStrictModeReservedWord(token.value)) { 8866 firstRestricted = token; 8867 message = messages_1.Messages.StrictReservedWord; 8868 } 8869 } 8870 } 8871 var formalParameters = this.parseFormalParameters(firstRestricted); 8872 var params = formalParameters.params; 8873 var stricted = formalParameters.stricted; 8874 firstRestricted = formalParameters.firstRestricted; 8875 if (formalParameters.message) { 8876 message = formalParameters.message; 8877 } 8878 var previousStrict = this.context.strict; 8879 var previousAllowStrictDirective = this.context.allowStrictDirective; 8880 this.context.allowStrictDirective = formalParameters.simple; 8881 var body = this.parseFunctionSourceElements(); 8882 if (this.context.strict && firstRestricted) { 8883 this.throwUnexpectedToken(firstRestricted, message); 8884 } 8885 if (this.context.strict && stricted) { 8886 this.tolerateUnexpectedToken(stricted, message); 8887 } 8888 this.context.strict = previousStrict; 8889 this.context.allowStrictDirective = previousAllowStrictDirective; 8890 this.context.await = previousAllowAwait; 8891 this.context.allowYield = previousAllowYield; 8892 return isAsync ? this.finalize(node, new Node.AsyncFunctionExpression(id, params, body)) : 8893 this.finalize(node, new Node.FunctionExpression(id, params, body, isGenerator)); 8894 }; 8895 // https://tc39.github.io/ecma262/#sec-directive-prologues-and-the-use-strict-directive 8896 Parser.prototype.parseDirective = function () { 8897 var token = this.lookahead; 8898 var node = this.createNode(); 8899 var expr = this.parseExpression(); 8900 var directive = (expr.type === syntax_1.Syntax.Literal) ? this.getTokenRaw(token).slice(1, -1) : null; 8901 this.consumeSemicolon(); 8902 return this.finalize(node, directive ? new Node.Directive(expr, directive) : new Node.ExpressionStatement(expr)); 8903 }; 8904 Parser.prototype.parseDirectivePrologues = function () { 8905 var firstRestricted = null; 8906 var body = []; 8907 while (true) { 8908 var token = this.lookahead; 8909 if (token.type !== 8 /* StringLiteral */) { 8910 break; 8911 } 8912 var statement = this.parseDirective(); 8913 body.push(statement); 8914 var directive = statement.directive; 8915 if (typeof directive !== 'string') { 8916 break; 8917 } 8918 if (directive === 'use strict') { 8919 this.context.strict = true; 8920 if (firstRestricted) { 8921 this.tolerateUnexpectedToken(firstRestricted, messages_1.Messages.StrictOctalLiteral); 8922 } 8923 if (!this.context.allowStrictDirective) { 8924 this.tolerateUnexpectedToken(token, messages_1.Messages.IllegalLanguageModeDirective); 8925 } 8926 } 8927 else { 8928 if (!firstRestricted && token.octal) { 8929 firstRestricted = token; 8930 } 8931 } 8932 } 8933 return body; 8934 }; 8935 // https://tc39.github.io/ecma262/#sec-method-definitions 8936 Parser.prototype.qualifiedPropertyName = function (token) { 8937 switch (token.type) { 8938 case 3 /* Identifier */: 8939 case 8 /* StringLiteral */: 8940 case 1 /* BooleanLiteral */: 8941 case 5 /* NullLiteral */: 8942 case 6 /* NumericLiteral */: 8943 case 4 /* Keyword */: 8944 return true; 8945 case 7 /* Punctuator */: 8946 return token.value === '['; 8947 default: 8948 break; 8949 } 8950 return false; 8951 }; 8952 Parser.prototype.parseGetterMethod = function () { 8953 var node = this.createNode(); 8954 var isGenerator = false; 8955 var previousAllowYield = this.context.allowYield; 8956 this.context.allowYield = !isGenerator; 8957 var formalParameters = this.parseFormalParameters(); 8958 if (formalParameters.params.length > 0) { 8959 this.tolerateError(messages_1.Messages.BadGetterArity); 8960 } 8961 var method = this.parsePropertyMethod(formalParameters); 8962 this.context.allowYield = previousAllowYield; 8963 return this.finalize(node, new Node.FunctionExpression(null, formalParameters.params, method, isGenerator)); 8964 }; 8965 Parser.prototype.parseSetterMethod = function () { 8966 var node = this.createNode(); 8967 var isGenerator = false; 8968 var previousAllowYield = this.context.allowYield; 8969 this.context.allowYield = !isGenerator; 8970 var formalParameters = this.parseFormalParameters(); 8971 if (formalParameters.params.length !== 1) { 8972 this.tolerateError(messages_1.Messages.BadSetterArity); 8973 } 8974 else if (formalParameters.params[0] instanceof Node.RestElement) { 8975 this.tolerateError(messages_1.Messages.BadSetterRestParameter); 8976 } 8977 var method = this.parsePropertyMethod(formalParameters); 8978 this.context.allowYield = previousAllowYield; 8979 return this.finalize(node, new Node.FunctionExpression(null, formalParameters.params, method, isGenerator)); 8980 }; 8981 Parser.prototype.parseGeneratorMethod = function () { 8982 var node = this.createNode(); 8983 var isGenerator = true; 8984 var previousAllowYield = this.context.allowYield; 8985 this.context.allowYield = true; 8986 var params = this.parseFormalParameters(); 8987 this.context.allowYield = false; 8988 var method = this.parsePropertyMethod(params); 8989 this.context.allowYield = previousAllowYield; 8990 return this.finalize(node, new Node.FunctionExpression(null, params.params, method, isGenerator)); 8991 }; 8992 // https://tc39.github.io/ecma262/#sec-generator-function-definitions 8993 Parser.prototype.isStartOfExpression = function () { 8994 var start = true; 8995 var value = this.lookahead.value; 8996 switch (this.lookahead.type) { 8997 case 7 /* Punctuator */: 8998 start = (value === '[') || (value === '(') || (value === '{') || 8999 (value === '+') || (value === '-') || 9000 (value === '!') || (value === '~') || 9001 (value === '++') || (value === '--') || 9002 (value === '/') || (value === '/='); // regular expression literal 9003 break; 9004 case 4 /* Keyword */: 9005 start = (value === 'class') || (value === 'delete') || 9006 (value === 'function') || (value === 'let') || (value === 'new') || 9007 (value === 'super') || (value === 'this') || (value === 'typeof') || 9008 (value === 'void') || (value === 'yield'); 9009 break; 9010 default: 9011 break; 9012 } 9013 return start; 9014 }; 9015 Parser.prototype.parseYieldExpression = function () { 9016 var node = this.createNode(); 9017 this.expectKeyword('yield'); 9018 var argument = null; 9019 var delegate = false; 9020 if (!this.hasLineTerminator) { 9021 var previousAllowYield = this.context.allowYield; 9022 this.context.allowYield = false; 9023 delegate = this.match('*'); 9024 if (delegate) { 9025 this.nextToken(); 9026 argument = this.parseAssignmentExpression(); 9027 } 9028 else if (this.isStartOfExpression()) { 9029 argument = this.parseAssignmentExpression(); 9030 } 9031 this.context.allowYield = previousAllowYield; 9032 } 9033 return this.finalize(node, new Node.YieldExpression(argument, delegate)); 9034 }; 9035 // https://tc39.github.io/ecma262/#sec-class-definitions 9036 Parser.prototype.parseClassElement = function (hasConstructor) { 9037 var token = this.lookahead; 9038 var node = this.createNode(); 9039 var kind = ''; 9040 var key = null; 9041 var value = null; 9042 var computed = false; 9043 var method = false; 9044 var isStatic = false; 9045 var isAsync = false; 9046 if (this.match('*')) { 9047 this.nextToken(); 9048 } 9049 else { 9050 computed = this.match('['); 9051 key = this.parseObjectPropertyKey(); 9052 var id = key; 9053 if (id.name === 'static' && (this.qualifiedPropertyName(this.lookahead) || this.match('*'))) { 9054 token = this.lookahead; 9055 isStatic = true; 9056 computed = this.match('['); 9057 if (this.match('*')) { 9058 this.nextToken(); 9059 } 9060 else { 9061 key = this.parseObjectPropertyKey(); 9062 } 9063 } 9064 if ((token.type === 3 /* Identifier */) && !this.hasLineTerminator && (token.value === 'async')) { 9065 var punctuator = this.lookahead.value; 9066 if (punctuator !== ':' && punctuator !== '(' && punctuator !== '*') { 9067 isAsync = true; 9068 token = this.lookahead; 9069 key = this.parseObjectPropertyKey(); 9070 if (token.type === 3 /* Identifier */ && token.value === 'constructor') { 9071 this.tolerateUnexpectedToken(token, messages_1.Messages.ConstructorIsAsync); 9072 } 9073 } 9074 } 9075 } 9076 var lookaheadPropertyKey = this.qualifiedPropertyName(this.lookahead); 9077 if (token.type === 3 /* Identifier */) { 9078 if (token.value === 'get' && lookaheadPropertyKey) { 9079 kind = 'get'; 9080 computed = this.match('['); 9081 key = this.parseObjectPropertyKey(); 9082 this.context.allowYield = false; 9083 value = this.parseGetterMethod(); 9084 } 9085 else if (token.value === 'set' && lookaheadPropertyKey) { 9086 kind = 'set'; 9087 computed = this.match('['); 9088 key = this.parseObjectPropertyKey(); 9089 value = this.parseSetterMethod(); 9090 } 9091 } 9092 else if (token.type === 7 /* Punctuator */ && token.value === '*' && lookaheadPropertyKey) { 9093 kind = 'init'; 9094 computed = this.match('['); 9095 key = this.parseObjectPropertyKey(); 9096 value = this.parseGeneratorMethod(); 9097 method = true; 9098 } 9099 if (!kind && key && this.match('(')) { 9100 kind = 'init'; 9101 value = isAsync ? this.parsePropertyMethodAsyncFunction() : this.parsePropertyMethodFunction(); 9102 method = true; 9103 } 9104 if (!kind) { 9105 this.throwUnexpectedToken(this.lookahead); 9106 } 9107 if (kind === 'init') { 9108 kind = 'method'; 9109 } 9110 if (!computed) { 9111 if (isStatic && this.isPropertyKey(key, 'prototype')) { 9112 this.throwUnexpectedToken(token, messages_1.Messages.StaticPrototype); 9113 } 9114 if (!isStatic && this.isPropertyKey(key, 'constructor')) { 9115 if (kind !== 'method' || !method || (value && value.generator)) { 9116 this.throwUnexpectedToken(token, messages_1.Messages.ConstructorSpecialMethod); 9117 } 9118 if (hasConstructor.value) { 9119 this.throwUnexpectedToken(token, messages_1.Messages.DuplicateConstructor); 9120 } 9121 else { 9122 hasConstructor.value = true; 9123 } 9124 kind = 'constructor'; 9125 } 9126 } 9127 return this.finalize(node, new Node.MethodDefinition(key, computed, value, kind, isStatic)); 9128 }; 9129 Parser.prototype.parseClassElementList = function () { 9130 var body = []; 9131 var hasConstructor = { value: false }; 9132 this.expect('{'); 9133 while (!this.match('}')) { 9134 if (this.match(';')) { 9135 this.nextToken(); 9136 } 9137 else { 9138 body.push(this.parseClassElement(hasConstructor)); 9139 } 9140 } 9141 this.expect('}'); 9142 return body; 9143 }; 9144 Parser.prototype.parseClassBody = function () { 9145 var node = this.createNode(); 9146 var elementList = this.parseClassElementList(); 9147 return this.finalize(node, new Node.ClassBody(elementList)); 9148 }; 9149 Parser.prototype.parseClassDeclaration = function (identifierIsOptional) { 9150 var node = this.createNode(); 9151 var previousStrict = this.context.strict; 9152 this.context.strict = true; 9153 this.expectKeyword('class'); 9154 var id = (identifierIsOptional && (this.lookahead.type !== 3 /* Identifier */)) ? null : this.parseVariableIdentifier(); 9155 var superClass = null; 9156 if (this.matchKeyword('extends')) { 9157 this.nextToken(); 9158 superClass = this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall); 9159 } 9160 var classBody = this.parseClassBody(); 9161 this.context.strict = previousStrict; 9162 return this.finalize(node, new Node.ClassDeclaration(id, superClass, classBody)); 9163 }; 9164 Parser.prototype.parseClassExpression = function () { 9165 var node = this.createNode(); 9166 var previousStrict = this.context.strict; 9167 this.context.strict = true; 9168 this.expectKeyword('class'); 9169 var id = (this.lookahead.type === 3 /* Identifier */) ? this.parseVariableIdentifier() : null; 9170 var superClass = null; 9171 if (this.matchKeyword('extends')) { 9172 this.nextToken(); 9173 superClass = this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall); 9174 } 9175 var classBody = this.parseClassBody(); 9176 this.context.strict = previousStrict; 9177 return this.finalize(node, new Node.ClassExpression(id, superClass, classBody)); 9178 }; 9179 // https://tc39.github.io/ecma262/#sec-scripts 9180 // https://tc39.github.io/ecma262/#sec-modules 9181 Parser.prototype.parseModule = function () { 9182 this.context.strict = true; 9183 this.context.isModule = true; 9184 this.scanner.isModule = true; 9185 var node = this.createNode(); 9186 var body = this.parseDirectivePrologues(); 9187 while (this.lookahead.type !== 2 /* EOF */) { 9188 body.push(this.parseStatementListItem()); 9189 } 9190 return this.finalize(node, new Node.Module(body)); 9191 }; 9192 Parser.prototype.parseScript = function () { 9193 var node = this.createNode(); 9194 var body = this.parseDirectivePrologues(); 9195 while (this.lookahead.type !== 2 /* EOF */) { 9196 body.push(this.parseStatementListItem()); 9197 } 9198 return this.finalize(node, new Node.Script(body)); 9199 }; 9200 // https://tc39.github.io/ecma262/#sec-imports 9201 Parser.prototype.parseModuleSpecifier = function () { 9202 var node = this.createNode(); 9203 if (this.lookahead.type !== 8 /* StringLiteral */) { 9204 this.throwError(messages_1.Messages.InvalidModuleSpecifier); 9205 } 9206 var token = this.nextToken(); 9207 var raw = this.getTokenRaw(token); 9208 return this.finalize(node, new Node.Literal(token.value, raw)); 9209 }; 9210 // import {<foo as bar>} ...; 9211 Parser.prototype.parseImportSpecifier = function () { 9212 var node = this.createNode(); 9213 var imported; 9214 var local; 9215 if (this.lookahead.type === 3 /* Identifier */) { 9216 imported = this.parseVariableIdentifier(); 9217 local = imported; 9218 if (this.matchContextualKeyword('as')) { 9219 this.nextToken(); 9220 local = this.parseVariableIdentifier(); 9221 } 9222 } 9223 else { 9224 imported = this.parseIdentifierName(); 9225 local = imported; 9226 if (this.matchContextualKeyword('as')) { 9227 this.nextToken(); 9228 local = this.parseVariableIdentifier(); 9229 } 9230 else { 9231 this.throwUnexpectedToken(this.nextToken()); 9232 } 9233 } 9234 return this.finalize(node, new Node.ImportSpecifier(local, imported)); 9235 }; 9236 // {foo, bar as bas} 9237 Parser.prototype.parseNamedImports = function () { 9238 this.expect('{'); 9239 var specifiers = []; 9240 while (!this.match('}')) { 9241 specifiers.push(this.parseImportSpecifier()); 9242 if (!this.match('}')) { 9243 this.expect(','); 9244 } 9245 } 9246 this.expect('}'); 9247 return specifiers; 9248 }; 9249 // import <foo> ...; 9250 Parser.prototype.parseImportDefaultSpecifier = function () { 9251 var node = this.createNode(); 9252 var local = this.parseIdentifierName(); 9253 return this.finalize(node, new Node.ImportDefaultSpecifier(local)); 9254 }; 9255 // import <* as foo> ...; 9256 Parser.prototype.parseImportNamespaceSpecifier = function () { 9257 var node = this.createNode(); 9258 this.expect('*'); 9259 if (!this.matchContextualKeyword('as')) { 9260 this.throwError(messages_1.Messages.NoAsAfterImportNamespace); 9261 } 9262 this.nextToken(); 9263 var local = this.parseIdentifierName(); 9264 return this.finalize(node, new Node.ImportNamespaceSpecifier(local)); 9265 }; 9266 Parser.prototype.parseImportDeclaration = function () { 9267 if (this.context.inFunctionBody) { 9268 this.throwError(messages_1.Messages.IllegalImportDeclaration); 9269 } 9270 var node = this.createNode(); 9271 this.expectKeyword('import'); 9272 var src; 9273 var specifiers = []; 9274 if (this.lookahead.type === 8 /* StringLiteral */) { 9275 // import 'foo'; 9276 src = this.parseModuleSpecifier(); 9277 } 9278 else { 9279 if (this.match('{')) { 9280 // import {bar} 9281 specifiers = specifiers.concat(this.parseNamedImports()); 9282 } 9283 else if (this.match('*')) { 9284 // import * as foo 9285 specifiers.push(this.parseImportNamespaceSpecifier()); 9286 } 9287 else if (this.isIdentifierName(this.lookahead) && !this.matchKeyword('default')) { 9288 // import foo 9289 specifiers.push(this.parseImportDefaultSpecifier()); 9290 if (this.match(',')) { 9291 this.nextToken(); 9292 if (this.match('*')) { 9293 // import foo, * as foo 9294 specifiers.push(this.parseImportNamespaceSpecifier()); 9295 } 9296 else if (this.match('{')) { 9297 // import foo, {bar} 9298 specifiers = specifiers.concat(this.parseNamedImports()); 9299 } 9300 else { 9301 this.throwUnexpectedToken(this.lookahead); 9302 } 9303 } 9304 } 9305 else { 9306 this.throwUnexpectedToken(this.nextToken()); 9307 } 9308 if (!this.matchContextualKeyword('from')) { 9309 var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause; 9310 this.throwError(message, this.lookahead.value); 9311 } 9312 this.nextToken(); 9313 src = this.parseModuleSpecifier(); 9314 } 9315 this.consumeSemicolon(); 9316 return this.finalize(node, new Node.ImportDeclaration(specifiers, src)); 9317 }; 9318 // https://tc39.github.io/ecma262/#sec-exports 9319 Parser.prototype.parseExportSpecifier = function () { 9320 var node = this.createNode(); 9321 var local = this.parseIdentifierName(); 9322 var exported = local; 9323 if (this.matchContextualKeyword('as')) { 9324 this.nextToken(); 9325 exported = this.parseIdentifierName(); 9326 } 9327 return this.finalize(node, new Node.ExportSpecifier(local, exported)); 9328 }; 9329 Parser.prototype.parseExportDeclaration = function () { 9330 if (this.context.inFunctionBody) { 9331 this.throwError(messages_1.Messages.IllegalExportDeclaration); 9332 } 9333 var node = this.createNode(); 9334 this.expectKeyword('export'); 9335 var exportDeclaration; 9336 if (this.matchKeyword('default')) { 9337 // export default ... 9338 this.nextToken(); 9339 if (this.matchKeyword('function')) { 9340 // export default function foo () {} 9341 // export default function () {} 9342 var declaration = this.parseFunctionDeclaration(true); 9343 exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration)); 9344 } 9345 else if (this.matchKeyword('class')) { 9346 // export default class foo {} 9347 var declaration = this.parseClassDeclaration(true); 9348 exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration)); 9349 } 9350 else if (this.matchContextualKeyword('async')) { 9351 // export default async function f () {} 9352 // export default async function () {} 9353 // export default async x => x 9354 var declaration = this.matchAsyncFunction() ? this.parseFunctionDeclaration(true) : this.parseAssignmentExpression(); 9355 exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration)); 9356 } 9357 else { 9358 if (this.matchContextualKeyword('from')) { 9359 this.throwError(messages_1.Messages.UnexpectedToken, this.lookahead.value); 9360 } 9361 // export default {}; 9362 // export default []; 9363 // export default (1 + 2); 9364 var declaration = this.match('{') ? this.parseObjectInitializer() : 9365 this.match('[') ? this.parseArrayInitializer() : this.parseAssignmentExpression(); 9366 this.consumeSemicolon(); 9367 exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration)); 9368 } 9369 } 9370 else if (this.match('*')) { 9371 // export * from 'foo'; 9372 this.nextToken(); 9373 if (!this.matchContextualKeyword('from')) { 9374 var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause; 9375 this.throwError(message, this.lookahead.value); 9376 } 9377 this.nextToken(); 9378 var src = this.parseModuleSpecifier(); 9379 this.consumeSemicolon(); 9380 exportDeclaration = this.finalize(node, new Node.ExportAllDeclaration(src)); 9381 } 9382 else if (this.lookahead.type === 4 /* Keyword */) { 9383 // export var f = 1; 9384 var declaration = void 0; 9385 switch (this.lookahead.value) { 9386 case 'let': 9387 case 'const': 9388 declaration = this.parseLexicalDeclaration({ inFor: false }); 9389 break; 9390 case 'var': 9391 case 'class': 9392 case 'function': 9393 declaration = this.parseStatementListItem(); 9394 break; 9395 default: 9396 this.throwUnexpectedToken(this.lookahead); 9397 } 9398 exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(declaration, [], null)); 9399 } 9400 else if (this.matchAsyncFunction()) { 9401 var declaration = this.parseFunctionDeclaration(); 9402 exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(declaration, [], null)); 9403 } 9404 else { 9405 var specifiers = []; 9406 var source = null; 9407 var isExportFromIdentifier = false; 9408 this.expect('{'); 9409 while (!this.match('}')) { 9410 isExportFromIdentifier = isExportFromIdentifier || this.matchKeyword('default'); 9411 specifiers.push(this.parseExportSpecifier()); 9412 if (!this.match('}')) { 9413 this.expect(','); 9414 } 9415 } 9416 this.expect('}'); 9417 if (this.matchContextualKeyword('from')) { 9418 // export {default} from 'foo'; 9419 // export {foo} from 'foo'; 9420 this.nextToken(); 9421 source = this.parseModuleSpecifier(); 9422 this.consumeSemicolon(); 9423 } 9424 else if (isExportFromIdentifier) { 9425 // export {default}; // missing fromClause 9426 var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause; 9427 this.throwError(message, this.lookahead.value); 9428 } 9429 else { 9430 // export {foo}; 9431 this.consumeSemicolon(); 9432 } 9433 exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(null, specifiers, source)); 9434 } 9435 return exportDeclaration; 9436 }; 9437 return Parser; 9438 }()); 9439 exports.Parser = Parser; 9440 9441 9442/***/ }, 9443/* 9 */ 9444/***/ function(module, exports) { 9445 9446 "use strict"; 9447 // Ensure the condition is true, otherwise throw an error. 9448 // This is only to have a better contract semantic, i.e. another safety net 9449 // to catch a logic error. The condition shall be fulfilled in normal case. 9450 // Do NOT use this to enforce a certain condition on any user input. 9451 Object.defineProperty(exports, "__esModule", { value: true }); 9452 function assert(condition, message) { 9453 /* istanbul ignore if */ 9454 if (!condition) { 9455 throw new Error('ASSERT: ' + message); 9456 } 9457 } 9458 exports.assert = assert; 9459 9460 9461/***/ }, 9462/* 10 */ 9463/***/ function(module, exports) { 9464 9465 "use strict"; 9466 /* tslint:disable:max-classes-per-file */ 9467 Object.defineProperty(exports, "__esModule", { value: true }); 9468 var ErrorHandler = (function () { 9469 function ErrorHandler() { 9470 this.errors = []; 9471 this.tolerant = false; 9472 } 9473 ErrorHandler.prototype.recordError = function (error) { 9474 this.errors.push(error); 9475 }; 9476 ErrorHandler.prototype.tolerate = function (error) { 9477 if (this.tolerant) { 9478 this.recordError(error); 9479 } 9480 else { 9481 throw error; 9482 } 9483 }; 9484 ErrorHandler.prototype.constructError = function (msg, column) { 9485 var error = new Error(msg); 9486 try { 9487 throw error; 9488 } 9489 catch (base) { 9490 /* istanbul ignore else */ 9491 if (Object.create && Object.defineProperty) { 9492 error = Object.create(base); 9493 Object.defineProperty(error, 'column', { value: column }); 9494 } 9495 } 9496 /* istanbul ignore next */ 9497 return error; 9498 }; 9499 ErrorHandler.prototype.createError = function (index, line, col, description) { 9500 var msg = 'Line ' + line + ': ' + description; 9501 var error = this.constructError(msg, col); 9502 error.index = index; 9503 error.lineNumber = line; 9504 error.description = description; 9505 return error; 9506 }; 9507 ErrorHandler.prototype.throwError = function (index, line, col, description) { 9508 throw this.createError(index, line, col, description); 9509 }; 9510 ErrorHandler.prototype.tolerateError = function (index, line, col, description) { 9511 var error = this.createError(index, line, col, description); 9512 if (this.tolerant) { 9513 this.recordError(error); 9514 } 9515 else { 9516 throw error; 9517 } 9518 }; 9519 return ErrorHandler; 9520 }()); 9521 exports.ErrorHandler = ErrorHandler; 9522 9523 9524/***/ }, 9525/* 11 */ 9526/***/ function(module, exports) { 9527 9528 "use strict"; 9529 Object.defineProperty(exports, "__esModule", { value: true }); 9530 // Error messages should be identical to V8. 9531 exports.Messages = { 9532 BadGetterArity: 'Getter must not have any formal parameters', 9533 BadSetterArity: 'Setter must have exactly one formal parameter', 9534 BadSetterRestParameter: 'Setter function argument must not be a rest parameter', 9535 ConstructorIsAsync: 'Class constructor may not be an async method', 9536 ConstructorSpecialMethod: 'Class constructor may not be an accessor', 9537 DeclarationMissingInitializer: 'Missing initializer in %0 declaration', 9538 DefaultRestParameter: 'Unexpected token =', 9539 DuplicateBinding: 'Duplicate binding %0', 9540 DuplicateConstructor: 'A class may only have one constructor', 9541 DuplicateProtoProperty: 'Duplicate __proto__ fields are not allowed in object literals', 9542 ForInOfLoopInitializer: '%0 loop variable declaration may not have an initializer', 9543 GeneratorInLegacyContext: 'Generator declarations are not allowed in legacy contexts', 9544 IllegalBreak: 'Illegal break statement', 9545 IllegalContinue: 'Illegal continue statement', 9546 IllegalExportDeclaration: 'Unexpected token', 9547 IllegalImportDeclaration: 'Unexpected token', 9548 IllegalLanguageModeDirective: 'Illegal \'use strict\' directive in function with non-simple parameter list', 9549 IllegalReturn: 'Illegal return statement', 9550 InvalidEscapedReservedWord: 'Keyword must not contain escaped characters', 9551 InvalidHexEscapeSequence: 'Invalid hexadecimal escape sequence', 9552 InvalidLHSInAssignment: 'Invalid left-hand side in assignment', 9553 InvalidLHSInForIn: 'Invalid left-hand side in for-in', 9554 InvalidLHSInForLoop: 'Invalid left-hand side in for-loop', 9555 InvalidModuleSpecifier: 'Unexpected token', 9556 InvalidRegExp: 'Invalid regular expression', 9557 LetInLexicalBinding: 'let is disallowed as a lexically bound name', 9558 MissingFromClause: 'Unexpected token', 9559 MultipleDefaultsInSwitch: 'More than one default clause in switch statement', 9560 NewlineAfterThrow: 'Illegal newline after throw', 9561 NoAsAfterImportNamespace: 'Unexpected token', 9562 NoCatchOrFinally: 'Missing catch or finally after try', 9563 ParameterAfterRestParameter: 'Rest parameter must be last formal parameter', 9564 Redeclaration: '%0 \'%1\' has already been declared', 9565 StaticPrototype: 'Classes may not have static property named prototype', 9566 StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode', 9567 StrictDelete: 'Delete of an unqualified identifier in strict mode.', 9568 StrictFunction: 'In strict mode code, functions can only be declared at top level or inside a block', 9569 StrictFunctionName: 'Function name may not be eval or arguments in strict mode', 9570 StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode', 9571 StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode', 9572 StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode', 9573 StrictModeWith: 'Strict mode code may not include a with statement', 9574 StrictOctalLiteral: 'Octal literals are not allowed in strict mode.', 9575 StrictParamDupe: 'Strict mode function may not have duplicate parameter names', 9576 StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode', 9577 StrictReservedWord: 'Use of future reserved word in strict mode', 9578 StrictVarName: 'Variable name may not be eval or arguments in strict mode', 9579 TemplateOctalLiteral: 'Octal literals are not allowed in template strings.', 9580 UnexpectedEOS: 'Unexpected end of input', 9581 UnexpectedIdentifier: 'Unexpected identifier', 9582 UnexpectedNumber: 'Unexpected number', 9583 UnexpectedReserved: 'Unexpected reserved word', 9584 UnexpectedString: 'Unexpected string', 9585 UnexpectedTemplate: 'Unexpected quasi %0', 9586 UnexpectedToken: 'Unexpected token %0', 9587 UnexpectedTokenIllegal: 'Unexpected token ILLEGAL', 9588 UnknownLabel: 'Undefined label \'%0\'', 9589 UnterminatedRegExp: 'Invalid regular expression: missing /' 9590 }; 9591 9592 9593/***/ }, 9594/* 12 */ 9595/***/ function(module, exports, __webpack_require__) { 9596 9597 "use strict"; 9598 Object.defineProperty(exports, "__esModule", { value: true }); 9599 var assert_1 = __webpack_require__(9); 9600 var character_1 = __webpack_require__(4); 9601 var messages_1 = __webpack_require__(11); 9602 function hexValue(ch) { 9603 return '0123456789abcdef'.indexOf(ch.toLowerCase()); 9604 } 9605 function octalValue(ch) { 9606 return '01234567'.indexOf(ch); 9607 } 9608 var Scanner = (function () { 9609 function Scanner(code, handler) { 9610 this.source = code; 9611 this.errorHandler = handler; 9612 this.trackComment = false; 9613 this.isModule = false; 9614 this.length = code.length; 9615 this.index = 0; 9616 this.lineNumber = (code.length > 0) ? 1 : 0; 9617 this.lineStart = 0; 9618 this.curlyStack = []; 9619 } 9620 Scanner.prototype.saveState = function () { 9621 return { 9622 index: this.index, 9623 lineNumber: this.lineNumber, 9624 lineStart: this.lineStart 9625 }; 9626 }; 9627 Scanner.prototype.restoreState = function (state) { 9628 this.index = state.index; 9629 this.lineNumber = state.lineNumber; 9630 this.lineStart = state.lineStart; 9631 }; 9632 Scanner.prototype.eof = function () { 9633 return this.index >= this.length; 9634 }; 9635 Scanner.prototype.throwUnexpectedToken = function (message) { 9636 if (message === void 0) { message = messages_1.Messages.UnexpectedTokenIllegal; } 9637 return this.errorHandler.throwError(this.index, this.lineNumber, this.index - this.lineStart + 1, message); 9638 }; 9639 Scanner.prototype.tolerateUnexpectedToken = function (message) { 9640 if (message === void 0) { message = messages_1.Messages.UnexpectedTokenIllegal; } 9641 this.errorHandler.tolerateError(this.index, this.lineNumber, this.index - this.lineStart + 1, message); 9642 }; 9643 // https://tc39.github.io/ecma262/#sec-comments 9644 Scanner.prototype.skipSingleLineComment = function (offset) { 9645 var comments = []; 9646 var start, loc; 9647 if (this.trackComment) { 9648 comments = []; 9649 start = this.index - offset; 9650 loc = { 9651 start: { 9652 line: this.lineNumber, 9653 column: this.index - this.lineStart - offset 9654 }, 9655 end: {} 9656 }; 9657 } 9658 while (!this.eof()) { 9659 var ch = this.source.charCodeAt(this.index); 9660 ++this.index; 9661 if (character_1.Character.isLineTerminator(ch)) { 9662 if (this.trackComment) { 9663 loc.end = { 9664 line: this.lineNumber, 9665 column: this.index - this.lineStart - 1 9666 }; 9667 var entry = { 9668 multiLine: false, 9669 slice: [start + offset, this.index - 1], 9670 range: [start, this.index - 1], 9671 loc: loc 9672 }; 9673 comments.push(entry); 9674 } 9675 if (ch === 13 && this.source.charCodeAt(this.index) === 10) { 9676 ++this.index; 9677 } 9678 ++this.lineNumber; 9679 this.lineStart = this.index; 9680 return comments; 9681 } 9682 } 9683 if (this.trackComment) { 9684 loc.end = { 9685 line: this.lineNumber, 9686 column: this.index - this.lineStart 9687 }; 9688 var entry = { 9689 multiLine: false, 9690 slice: [start + offset, this.index], 9691 range: [start, this.index], 9692 loc: loc 9693 }; 9694 comments.push(entry); 9695 } 9696 return comments; 9697 }; 9698 Scanner.prototype.skipMultiLineComment = function () { 9699 var comments = []; 9700 var start, loc; 9701 if (this.trackComment) { 9702 comments = []; 9703 start = this.index - 2; 9704 loc = { 9705 start: { 9706 line: this.lineNumber, 9707 column: this.index - this.lineStart - 2 9708 }, 9709 end: {} 9710 }; 9711 } 9712 while (!this.eof()) { 9713 var ch = this.source.charCodeAt(this.index); 9714 if (character_1.Character.isLineTerminator(ch)) { 9715 if (ch === 0x0D && this.source.charCodeAt(this.index + 1) === 0x0A) { 9716 ++this.index; 9717 } 9718 ++this.lineNumber; 9719 ++this.index; 9720 this.lineStart = this.index; 9721 } 9722 else if (ch === 0x2A) { 9723 // Block comment ends with '*/'. 9724 if (this.source.charCodeAt(this.index + 1) === 0x2F) { 9725 this.index += 2; 9726 if (this.trackComment) { 9727 loc.end = { 9728 line: this.lineNumber, 9729 column: this.index - this.lineStart 9730 }; 9731 var entry = { 9732 multiLine: true, 9733 slice: [start + 2, this.index - 2], 9734 range: [start, this.index], 9735 loc: loc 9736 }; 9737 comments.push(entry); 9738 } 9739 return comments; 9740 } 9741 ++this.index; 9742 } 9743 else { 9744 ++this.index; 9745 } 9746 } 9747 // Ran off the end of the file - the whole thing is a comment 9748 if (this.trackComment) { 9749 loc.end = { 9750 line: this.lineNumber, 9751 column: this.index - this.lineStart 9752 }; 9753 var entry = { 9754 multiLine: true, 9755 slice: [start + 2, this.index], 9756 range: [start, this.index], 9757 loc: loc 9758 }; 9759 comments.push(entry); 9760 } 9761 this.tolerateUnexpectedToken(); 9762 return comments; 9763 }; 9764 Scanner.prototype.scanComments = function () { 9765 var comments; 9766 if (this.trackComment) { 9767 comments = []; 9768 } 9769 var start = (this.index === 0); 9770 while (!this.eof()) { 9771 var ch = this.source.charCodeAt(this.index); 9772 if (character_1.Character.isWhiteSpace(ch)) { 9773 ++this.index; 9774 } 9775 else if (character_1.Character.isLineTerminator(ch)) { 9776 ++this.index; 9777 if (ch === 0x0D && this.source.charCodeAt(this.index) === 0x0A) { 9778 ++this.index; 9779 } 9780 ++this.lineNumber; 9781 this.lineStart = this.index; 9782 start = true; 9783 } 9784 else if (ch === 0x2F) { 9785 ch = this.source.charCodeAt(this.index + 1); 9786 if (ch === 0x2F) { 9787 this.index += 2; 9788 var comment = this.skipSingleLineComment(2); 9789 if (this.trackComment) { 9790 comments = comments.concat(comment); 9791 } 9792 start = true; 9793 } 9794 else if (ch === 0x2A) { 9795 this.index += 2; 9796 var comment = this.skipMultiLineComment(); 9797 if (this.trackComment) { 9798 comments = comments.concat(comment); 9799 } 9800 } 9801 else { 9802 break; 9803 } 9804 } 9805 else if (start && ch === 0x2D) { 9806 // U+003E is '>' 9807 if ((this.source.charCodeAt(this.index + 1) === 0x2D) && (this.source.charCodeAt(this.index + 2) === 0x3E)) { 9808 // '-->' is a single-line comment 9809 this.index += 3; 9810 var comment = this.skipSingleLineComment(3); 9811 if (this.trackComment) { 9812 comments = comments.concat(comment); 9813 } 9814 } 9815 else { 9816 break; 9817 } 9818 } 9819 else if (ch === 0x3C && !this.isModule) { 9820 if (this.source.slice(this.index + 1, this.index + 4) === '!--') { 9821 this.index += 4; // `<!--` 9822 var comment = this.skipSingleLineComment(4); 9823 if (this.trackComment) { 9824 comments = comments.concat(comment); 9825 } 9826 } 9827 else { 9828 break; 9829 } 9830 } 9831 else { 9832 break; 9833 } 9834 } 9835 return comments; 9836 }; 9837 // https://tc39.github.io/ecma262/#sec-future-reserved-words 9838 Scanner.prototype.isFutureReservedWord = function (id) { 9839 switch (id) { 9840 case 'enum': 9841 case 'export': 9842 case 'import': 9843 case 'super': 9844 return true; 9845 default: 9846 return false; 9847 } 9848 }; 9849 Scanner.prototype.isStrictModeReservedWord = function (id) { 9850 switch (id) { 9851 case 'implements': 9852 case 'interface': 9853 case 'package': 9854 case 'private': 9855 case 'protected': 9856 case 'public': 9857 case 'static': 9858 case 'yield': 9859 case 'let': 9860 return true; 9861 default: 9862 return false; 9863 } 9864 }; 9865 Scanner.prototype.isRestrictedWord = function (id) { 9866 return id === 'eval' || id === 'arguments'; 9867 }; 9868 // https://tc39.github.io/ecma262/#sec-keywords 9869 Scanner.prototype.isKeyword = function (id) { 9870 switch (id.length) { 9871 case 2: 9872 return (id === 'if') || (id === 'in') || (id === 'do'); 9873 case 3: 9874 return (id === 'var') || (id === 'for') || (id === 'new') || 9875 (id === 'try') || (id === 'let'); 9876 case 4: 9877 return (id === 'this') || (id === 'else') || (id === 'case') || 9878 (id === 'void') || (id === 'with') || (id === 'enum'); 9879 case 5: 9880 return (id === 'while') || (id === 'break') || (id === 'catch') || 9881 (id === 'throw') || (id === 'const') || (id === 'yield') || 9882 (id === 'class') || (id === 'super'); 9883 case 6: 9884 return (id === 'return') || (id === 'typeof') || (id === 'delete') || 9885 (id === 'switch') || (id === 'export') || (id === 'import'); 9886 case 7: 9887 return (id === 'default') || (id === 'finally') || (id === 'extends'); 9888 case 8: 9889 return (id === 'function') || (id === 'continue') || (id === 'debugger'); 9890 case 10: 9891 return (id === 'instanceof'); 9892 default: 9893 return false; 9894 } 9895 }; 9896 Scanner.prototype.codePointAt = function (i) { 9897 var cp = this.source.charCodeAt(i); 9898 if (cp >= 0xD800 && cp <= 0xDBFF) { 9899 var second = this.source.charCodeAt(i + 1); 9900 if (second >= 0xDC00 && second <= 0xDFFF) { 9901 var first = cp; 9902 cp = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000; 9903 } 9904 } 9905 return cp; 9906 }; 9907 Scanner.prototype.scanHexEscape = function (prefix) { 9908 var len = (prefix === 'u') ? 4 : 2; 9909 var code = 0; 9910 for (var i = 0; i < len; ++i) { 9911 if (!this.eof() && character_1.Character.isHexDigit(this.source.charCodeAt(this.index))) { 9912 code = code * 16 + hexValue(this.source[this.index++]); 9913 } 9914 else { 9915 return null; 9916 } 9917 } 9918 return String.fromCharCode(code); 9919 }; 9920 Scanner.prototype.scanUnicodeCodePointEscape = function () { 9921 var ch = this.source[this.index]; 9922 var code = 0; 9923 // At least, one hex digit is required. 9924 if (ch === '}') { 9925 this.throwUnexpectedToken(); 9926 } 9927 while (!this.eof()) { 9928 ch = this.source[this.index++]; 9929 if (!character_1.Character.isHexDigit(ch.charCodeAt(0))) { 9930 break; 9931 } 9932 code = code * 16 + hexValue(ch); 9933 } 9934 if (code > 0x10FFFF || ch !== '}') { 9935 this.throwUnexpectedToken(); 9936 } 9937 return character_1.Character.fromCodePoint(code); 9938 }; 9939 Scanner.prototype.getIdentifier = function () { 9940 var start = this.index++; 9941 while (!this.eof()) { 9942 var ch = this.source.charCodeAt(this.index); 9943 if (ch === 0x5C) { 9944 // Blackslash (U+005C) marks Unicode escape sequence. 9945 this.index = start; 9946 return this.getComplexIdentifier(); 9947 } 9948 else if (ch >= 0xD800 && ch < 0xDFFF) { 9949 // Need to handle surrogate pairs. 9950 this.index = start; 9951 return this.getComplexIdentifier(); 9952 } 9953 if (character_1.Character.isIdentifierPart(ch)) { 9954 ++this.index; 9955 } 9956 else { 9957 break; 9958 } 9959 } 9960 return this.source.slice(start, this.index); 9961 }; 9962 Scanner.prototype.getComplexIdentifier = function () { 9963 var cp = this.codePointAt(this.index); 9964 var id = character_1.Character.fromCodePoint(cp); 9965 this.index += id.length; 9966 // '\u' (U+005C, U+0075) denotes an escaped character. 9967 var ch; 9968 if (cp === 0x5C) { 9969 if (this.source.charCodeAt(this.index) !== 0x75) { 9970 this.throwUnexpectedToken(); 9971 } 9972 ++this.index; 9973 if (this.source[this.index] === '{') { 9974 ++this.index; 9975 ch = this.scanUnicodeCodePointEscape(); 9976 } 9977 else { 9978 ch = this.scanHexEscape('u'); 9979 if (ch === null || ch === '\\' || !character_1.Character.isIdentifierStart(ch.charCodeAt(0))) { 9980 this.throwUnexpectedToken(); 9981 } 9982 } 9983 id = ch; 9984 } 9985 while (!this.eof()) { 9986 cp = this.codePointAt(this.index); 9987 if (!character_1.Character.isIdentifierPart(cp)) { 9988 break; 9989 } 9990 ch = character_1.Character.fromCodePoint(cp); 9991 id += ch; 9992 this.index += ch.length; 9993 // '\u' (U+005C, U+0075) denotes an escaped character. 9994 if (cp === 0x5C) { 9995 id = id.substr(0, id.length - 1); 9996 if (this.source.charCodeAt(this.index) !== 0x75) { 9997 this.throwUnexpectedToken(); 9998 } 9999 ++this.index; 10000 if (this.source[this.index] === '{') { 10001 ++this.index; 10002 ch = this.scanUnicodeCodePointEscape(); 10003 } 10004 else { 10005 ch = this.scanHexEscape('u'); 10006 if (ch === null || ch === '\\' || !character_1.Character.isIdentifierPart(ch.charCodeAt(0))) { 10007 this.throwUnexpectedToken(); 10008 } 10009 } 10010 id += ch; 10011 } 10012 } 10013 return id; 10014 }; 10015 Scanner.prototype.octalToDecimal = function (ch) { 10016 // \0 is not octal escape sequence 10017 var octal = (ch !== '0'); 10018 var code = octalValue(ch); 10019 if (!this.eof() && character_1.Character.isOctalDigit(this.source.charCodeAt(this.index))) { 10020 octal = true; 10021 code = code * 8 + octalValue(this.source[this.index++]); 10022 // 3 digits are only allowed when string starts 10023 // with 0, 1, 2, 3 10024 if ('0123'.indexOf(ch) >= 0 && !this.eof() && character_1.Character.isOctalDigit(this.source.charCodeAt(this.index))) { 10025 code = code * 8 + octalValue(this.source[this.index++]); 10026 } 10027 } 10028 return { 10029 code: code, 10030 octal: octal 10031 }; 10032 }; 10033 // https://tc39.github.io/ecma262/#sec-names-and-keywords 10034 Scanner.prototype.scanIdentifier = function () { 10035 var type; 10036 var start = this.index; 10037 // Backslash (U+005C) starts an escaped character. 10038 var id = (this.source.charCodeAt(start) === 0x5C) ? this.getComplexIdentifier() : this.getIdentifier(); 10039 // There is no keyword or literal with only one character. 10040 // Thus, it must be an identifier. 10041 if (id.length === 1) { 10042 type = 3 /* Identifier */; 10043 } 10044 else if (this.isKeyword(id)) { 10045 type = 4 /* Keyword */; 10046 } 10047 else if (id === 'null') { 10048 type = 5 /* NullLiteral */; 10049 } 10050 else if (id === 'true' || id === 'false') { 10051 type = 1 /* BooleanLiteral */; 10052 } 10053 else { 10054 type = 3 /* Identifier */; 10055 } 10056 if (type !== 3 /* Identifier */ && (start + id.length !== this.index)) { 10057 var restore = this.index; 10058 this.index = start; 10059 this.tolerateUnexpectedToken(messages_1.Messages.InvalidEscapedReservedWord); 10060 this.index = restore; 10061 } 10062 return { 10063 type: type, 10064 value: id, 10065 lineNumber: this.lineNumber, 10066 lineStart: this.lineStart, 10067 start: start, 10068 end: this.index 10069 }; 10070 }; 10071 // https://tc39.github.io/ecma262/#sec-punctuators 10072 Scanner.prototype.scanPunctuator = function () { 10073 var start = this.index; 10074 // Check for most common single-character punctuators. 10075 var str = this.source[this.index]; 10076 switch (str) { 10077 case '(': 10078 case '{': 10079 if (str === '{') { 10080 this.curlyStack.push('{'); 10081 } 10082 ++this.index; 10083 break; 10084 case '.': 10085 ++this.index; 10086 if (this.source[this.index] === '.' && this.source[this.index + 1] === '.') { 10087 // Spread operator: ... 10088 this.index += 2; 10089 str = '...'; 10090 } 10091 break; 10092 case '}': 10093 ++this.index; 10094 this.curlyStack.pop(); 10095 break; 10096 case ')': 10097 case ';': 10098 case ',': 10099 case '[': 10100 case ']': 10101 case ':': 10102 case '?': 10103 case '~': 10104 ++this.index; 10105 break; 10106 default: 10107 // 4-character punctuator. 10108 str = this.source.substr(this.index, 4); 10109 if (str === '>>>=') { 10110 this.index += 4; 10111 } 10112 else { 10113 // 3-character punctuators. 10114 str = str.substr(0, 3); 10115 if (str === '===' || str === '!==' || str === '>>>' || 10116 str === '<<=' || str === '>>=' || str === '**=') { 10117 this.index += 3; 10118 } 10119 else { 10120 // 2-character punctuators. 10121 str = str.substr(0, 2); 10122 if (str === '&&' || str === '||' || str === '==' || str === '!=' || 10123 str === '+=' || str === '-=' || str === '*=' || str === '/=' || 10124 str === '++' || str === '--' || str === '<<' || str === '>>' || 10125 str === '&=' || str === '|=' || str === '^=' || str === '%=' || 10126 str === '<=' || str === '>=' || str === '=>' || str === '**') { 10127 this.index += 2; 10128 } 10129 else { 10130 // 1-character punctuators. 10131 str = this.source[this.index]; 10132 if ('<>=!+-*%&|^/'.indexOf(str) >= 0) { 10133 ++this.index; 10134 } 10135 } 10136 } 10137 } 10138 } 10139 if (this.index === start) { 10140 this.throwUnexpectedToken(); 10141 } 10142 return { 10143 type: 7 /* Punctuator */, 10144 value: str, 10145 lineNumber: this.lineNumber, 10146 lineStart: this.lineStart, 10147 start: start, 10148 end: this.index 10149 }; 10150 }; 10151 // https://tc39.github.io/ecma262/#sec-literals-numeric-literals 10152 Scanner.prototype.scanHexLiteral = function (start) { 10153 var num = ''; 10154 while (!this.eof()) { 10155 if (!character_1.Character.isHexDigit(this.source.charCodeAt(this.index))) { 10156 break; 10157 } 10158 num += this.source[this.index++]; 10159 } 10160 if (num.length === 0) { 10161 this.throwUnexpectedToken(); 10162 } 10163 if (character_1.Character.isIdentifierStart(this.source.charCodeAt(this.index))) { 10164 this.throwUnexpectedToken(); 10165 } 10166 return { 10167 type: 6 /* NumericLiteral */, 10168 value: parseInt('0x' + num, 16), 10169 lineNumber: this.lineNumber, 10170 lineStart: this.lineStart, 10171 start: start, 10172 end: this.index 10173 }; 10174 }; 10175 Scanner.prototype.scanBinaryLiteral = function (start) { 10176 var num = ''; 10177 var ch; 10178 while (!this.eof()) { 10179 ch = this.source[this.index]; 10180 if (ch !== '0' && ch !== '1') { 10181 break; 10182 } 10183 num += this.source[this.index++]; 10184 } 10185 if (num.length === 0) { 10186 // only 0b or 0B 10187 this.throwUnexpectedToken(); 10188 } 10189 if (!this.eof()) { 10190 ch = this.source.charCodeAt(this.index); 10191 /* istanbul ignore else */ 10192 if (character_1.Character.isIdentifierStart(ch) || character_1.Character.isDecimalDigit(ch)) { 10193 this.throwUnexpectedToken(); 10194 } 10195 } 10196 return { 10197 type: 6 /* NumericLiteral */, 10198 value: parseInt(num, 2), 10199 lineNumber: this.lineNumber, 10200 lineStart: this.lineStart, 10201 start: start, 10202 end: this.index 10203 }; 10204 }; 10205 Scanner.prototype.scanOctalLiteral = function (prefix, start) { 10206 var num = ''; 10207 var octal = false; 10208 if (character_1.Character.isOctalDigit(prefix.charCodeAt(0))) { 10209 octal = true; 10210 num = '0' + this.source[this.index++]; 10211 } 10212 else { 10213 ++this.index; 10214 } 10215 while (!this.eof()) { 10216 if (!character_1.Character.isOctalDigit(this.source.charCodeAt(this.index))) { 10217 break; 10218 } 10219 num += this.source[this.index++]; 10220 } 10221 if (!octal && num.length === 0) { 10222 // only 0o or 0O 10223 this.throwUnexpectedToken(); 10224 } 10225 if (character_1.Character.isIdentifierStart(this.source.charCodeAt(this.index)) || character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) { 10226 this.throwUnexpectedToken(); 10227 } 10228 return { 10229 type: 6 /* NumericLiteral */, 10230 value: parseInt(num, 8), 10231 octal: octal, 10232 lineNumber: this.lineNumber, 10233 lineStart: this.lineStart, 10234 start: start, 10235 end: this.index 10236 }; 10237 }; 10238 Scanner.prototype.isImplicitOctalLiteral = function () { 10239 // Implicit octal, unless there is a non-octal digit. 10240 // (Annex B.1.1 on Numeric Literals) 10241 for (var i = this.index + 1; i < this.length; ++i) { 10242 var ch = this.source[i]; 10243 if (ch === '8' || ch === '9') { 10244 return false; 10245 } 10246 if (!character_1.Character.isOctalDigit(ch.charCodeAt(0))) { 10247 return true; 10248 } 10249 } 10250 return true; 10251 }; 10252 Scanner.prototype.scanNumericLiteral = function () { 10253 var start = this.index; 10254 var ch = this.source[start]; 10255 assert_1.assert(character_1.Character.isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'), 'Numeric literal must start with a decimal digit or a decimal point'); 10256 var num = ''; 10257 if (ch !== '.') { 10258 num = this.source[this.index++]; 10259 ch = this.source[this.index]; 10260 // Hex number starts with '0x'. 10261 // Octal number starts with '0'. 10262 // Octal number in ES6 starts with '0o'. 10263 // Binary number in ES6 starts with '0b'. 10264 if (num === '0') { 10265 if (ch === 'x' || ch === 'X') { 10266 ++this.index; 10267 return this.scanHexLiteral(start); 10268 } 10269 if (ch === 'b' || ch === 'B') { 10270 ++this.index; 10271 return this.scanBinaryLiteral(start); 10272 } 10273 if (ch === 'o' || ch === 'O') { 10274 return this.scanOctalLiteral(ch, start); 10275 } 10276 if (ch && character_1.Character.isOctalDigit(ch.charCodeAt(0))) { 10277 if (this.isImplicitOctalLiteral()) { 10278 return this.scanOctalLiteral(ch, start); 10279 } 10280 } 10281 } 10282 while (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) { 10283 num += this.source[this.index++]; 10284 } 10285 ch = this.source[this.index]; 10286 } 10287 if (ch === '.') { 10288 num += this.source[this.index++]; 10289 while (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) { 10290 num += this.source[this.index++]; 10291 } 10292 ch = this.source[this.index]; 10293 } 10294 if (ch === 'e' || ch === 'E') { 10295 num += this.source[this.index++]; 10296 ch = this.source[this.index]; 10297 if (ch === '+' || ch === '-') { 10298 num += this.source[this.index++]; 10299 } 10300 if (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) { 10301 while (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) { 10302 num += this.source[this.index++]; 10303 } 10304 } 10305 else { 10306 this.throwUnexpectedToken(); 10307 } 10308 } 10309 if (character_1.Character.isIdentifierStart(this.source.charCodeAt(this.index))) { 10310 this.throwUnexpectedToken(); 10311 } 10312 return { 10313 type: 6 /* NumericLiteral */, 10314 value: parseFloat(num), 10315 lineNumber: this.lineNumber, 10316 lineStart: this.lineStart, 10317 start: start, 10318 end: this.index 10319 }; 10320 }; 10321 // https://tc39.github.io/ecma262/#sec-literals-string-literals 10322 Scanner.prototype.scanStringLiteral = function () { 10323 var start = this.index; 10324 var quote = this.source[start]; 10325 assert_1.assert((quote === '\'' || quote === '"'), 'String literal must starts with a quote'); 10326 ++this.index; 10327 var octal = false; 10328 var str = ''; 10329 while (!this.eof()) { 10330 var ch = this.source[this.index++]; 10331 if (ch === quote) { 10332 quote = ''; 10333 break; 10334 } 10335 else if (ch === '\\') { 10336 ch = this.source[this.index++]; 10337 if (!ch || !character_1.Character.isLineTerminator(ch.charCodeAt(0))) { 10338 switch (ch) { 10339 case 'u': 10340 if (this.source[this.index] === '{') { 10341 ++this.index; 10342 str += this.scanUnicodeCodePointEscape(); 10343 } 10344 else { 10345 var unescaped_1 = this.scanHexEscape(ch); 10346 if (unescaped_1 === null) { 10347 this.throwUnexpectedToken(); 10348 } 10349 str += unescaped_1; 10350 } 10351 break; 10352 case 'x': 10353 var unescaped = this.scanHexEscape(ch); 10354 if (unescaped === null) { 10355 this.throwUnexpectedToken(messages_1.Messages.InvalidHexEscapeSequence); 10356 } 10357 str += unescaped; 10358 break; 10359 case 'n': 10360 str += '\n'; 10361 break; 10362 case 'r': 10363 str += '\r'; 10364 break; 10365 case 't': 10366 str += '\t'; 10367 break; 10368 case 'b': 10369 str += '\b'; 10370 break; 10371 case 'f': 10372 str += '\f'; 10373 break; 10374 case 'v': 10375 str += '\x0B'; 10376 break; 10377 case '8': 10378 case '9': 10379 str += ch; 10380 this.tolerateUnexpectedToken(); 10381 break; 10382 default: 10383 if (ch && character_1.Character.isOctalDigit(ch.charCodeAt(0))) { 10384 var octToDec = this.octalToDecimal(ch); 10385 octal = octToDec.octal || octal; 10386 str += String.fromCharCode(octToDec.code); 10387 } 10388 else { 10389 str += ch; 10390 } 10391 break; 10392 } 10393 } 10394 else { 10395 ++this.lineNumber; 10396 if (ch === '\r' && this.source[this.index] === '\n') { 10397 ++this.index; 10398 } 10399 this.lineStart = this.index; 10400 } 10401 } 10402 else if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) { 10403 break; 10404 } 10405 else { 10406 str += ch; 10407 } 10408 } 10409 if (quote !== '') { 10410 this.index = start; 10411 this.throwUnexpectedToken(); 10412 } 10413 return { 10414 type: 8 /* StringLiteral */, 10415 value: str, 10416 octal: octal, 10417 lineNumber: this.lineNumber, 10418 lineStart: this.lineStart, 10419 start: start, 10420 end: this.index 10421 }; 10422 }; 10423 // https://tc39.github.io/ecma262/#sec-template-literal-lexical-components 10424 Scanner.prototype.scanTemplate = function () { 10425 var cooked = ''; 10426 var terminated = false; 10427 var start = this.index; 10428 var head = (this.source[start] === '`'); 10429 var tail = false; 10430 var rawOffset = 2; 10431 ++this.index; 10432 while (!this.eof()) { 10433 var ch = this.source[this.index++]; 10434 if (ch === '`') { 10435 rawOffset = 1; 10436 tail = true; 10437 terminated = true; 10438 break; 10439 } 10440 else if (ch === '$') { 10441 if (this.source[this.index] === '{') { 10442 this.curlyStack.push('${'); 10443 ++this.index; 10444 terminated = true; 10445 break; 10446 } 10447 cooked += ch; 10448 } 10449 else if (ch === '\\') { 10450 ch = this.source[this.index++]; 10451 if (!character_1.Character.isLineTerminator(ch.charCodeAt(0))) { 10452 switch (ch) { 10453 case 'n': 10454 cooked += '\n'; 10455 break; 10456 case 'r': 10457 cooked += '\r'; 10458 break; 10459 case 't': 10460 cooked += '\t'; 10461 break; 10462 case 'u': 10463 if (this.source[this.index] === '{') { 10464 ++this.index; 10465 cooked += this.scanUnicodeCodePointEscape(); 10466 } 10467 else { 10468 var restore = this.index; 10469 var unescaped_2 = this.scanHexEscape(ch); 10470 if (unescaped_2 !== null) { 10471 cooked += unescaped_2; 10472 } 10473 else { 10474 this.index = restore; 10475 cooked += ch; 10476 } 10477 } 10478 break; 10479 case 'x': 10480 var unescaped = this.scanHexEscape(ch); 10481 if (unescaped === null) { 10482 this.throwUnexpectedToken(messages_1.Messages.InvalidHexEscapeSequence); 10483 } 10484 cooked += unescaped; 10485 break; 10486 case 'b': 10487 cooked += '\b'; 10488 break; 10489 case 'f': 10490 cooked += '\f'; 10491 break; 10492 case 'v': 10493 cooked += '\v'; 10494 break; 10495 default: 10496 if (ch === '0') { 10497 if (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) { 10498 // Illegal: \01 \02 and so on 10499 this.throwUnexpectedToken(messages_1.Messages.TemplateOctalLiteral); 10500 } 10501 cooked += '\0'; 10502 } 10503 else if (character_1.Character.isOctalDigit(ch.charCodeAt(0))) { 10504 // Illegal: \1 \2 10505 this.throwUnexpectedToken(messages_1.Messages.TemplateOctalLiteral); 10506 } 10507 else { 10508 cooked += ch; 10509 } 10510 break; 10511 } 10512 } 10513 else { 10514 ++this.lineNumber; 10515 if (ch === '\r' && this.source[this.index] === '\n') { 10516 ++this.index; 10517 } 10518 this.lineStart = this.index; 10519 } 10520 } 10521 else if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) { 10522 ++this.lineNumber; 10523 if (ch === '\r' && this.source[this.index] === '\n') { 10524 ++this.index; 10525 } 10526 this.lineStart = this.index; 10527 cooked += '\n'; 10528 } 10529 else { 10530 cooked += ch; 10531 } 10532 } 10533 if (!terminated) { 10534 this.throwUnexpectedToken(); 10535 } 10536 if (!head) { 10537 this.curlyStack.pop(); 10538 } 10539 return { 10540 type: 10 /* Template */, 10541 value: this.source.slice(start + 1, this.index - rawOffset), 10542 cooked: cooked, 10543 head: head, 10544 tail: tail, 10545 lineNumber: this.lineNumber, 10546 lineStart: this.lineStart, 10547 start: start, 10548 end: this.index 10549 }; 10550 }; 10551 // https://tc39.github.io/ecma262/#sec-literals-regular-expression-literals 10552 Scanner.prototype.testRegExp = function (pattern, flags) { 10553 // The BMP character to use as a replacement for astral symbols when 10554 // translating an ES6 "u"-flagged pattern to an ES5-compatible 10555 // approximation. 10556 // Note: replacing with '\uFFFF' enables false positives in unlikely 10557 // scenarios. For example, `[\u{1044f}-\u{10440}
10557]` is an invalid 10558 // pattern that would not be detected by this substitution. 10559 var astralSubstitute = '\uFFFF'; 10560 var tmp = pattern; 10561 var self = this; 10562 if (flags.indexOf('u') >= 0) { 10563 tmp = tmp 10564 .replace(/\\u\{([0-9a-fA-F]+)\}|\\u([a-fA-F0-9]{4})/g, function ($0, $1, $2) { 10565 var codePoint = parseInt($1 || $2, 16); 10566 if (codePoint > 0x10FFFF) { 10567 self.throwUnexpectedToken(messages_1.Messages.InvalidRegExp); 10568 } 10569 if (codePoint <= 0xFFFF) { 10570 return String.fromCharCode(codePoint); 10571 } 10572 return astralSubstitute; 10573 }) 10574 .replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, astralSubstitute); 10575 } 10576 // First, detect invalid regular expressions. 10577 try { 10578 RegExp(tmp); 10579 } 10580 catch (e) { 10581 this.throwUnexpectedToken(messages_1.Messages.InvalidRegExp); 10582 } 10583 // Return a regular expression object for this pattern-flag pair, or 10584 // `null` in case the current environment doesn't support the flags it 10585 // uses. 10586 try { 10587 return new RegExp(pattern, flags); 10588 } 10589 catch (exception) { 10590 /* istanbul ignore next */ 10591 return null; 10592 } 10593 }; 10594 Scanner.prototype.scanRegExpBody = function () { 10595 var ch = this.source[this.index]; 10596 assert_1.assert(ch === '/', 'Regular expression literal must start with a slash'); 10597 var str = this.source[this.index++]; 10598 var classMarker = false; 10599 var terminated = false; 10600 while (!this.eof()) { 10601 ch = this.source[this.index++]; 10602 str += ch; 10603 if (ch === '\\') { 10604 ch = this.source[this.index++]; 10605 // https://tc39.github.io/ecma262/#sec-literals-regular-expression-literals 10606 if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) { 10607 this.throwUnexpectedToken(messages_1.Messages.UnterminatedRegExp); 10608 } 10609 str += ch; 10610 } 10611 else if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) { 10612 this.throwUnexpectedToken(messages_1.Messages.UnterminatedRegExp); 10613 } 10614 else if (classMarker) { 10615 if (ch === ']') { 10616 classMarker = false; 10617 } 10618 } 10619 else { 10620 if (ch === '/') { 10621 terminated = true; 10622 break; 10623 } 10624 else if (ch === '[') { 10625 classMarker = true; 10626 } 10627 } 10628 } 10629 if (!terminated) { 10630 this.throwUnexpectedToken(messages_1.Messages.UnterminatedRegExp); 10631 } 10632 // Exclude leading and trailing slash. 10633 return str.substr(1, str.length - 2); 10634 }; 10635 Scanner.prototype.scanRegExpFlags = function () { 10636 var str = ''; 10637 var flags = ''; 10638 while (!this.eof()) { 10639 var ch = this.source[this.index]; 10640 if (!character_1.Character.isIdentifierPart(ch.charCodeAt(0))) { 10641 break; 10642 } 10643 ++this.index; 10644 if (ch === '\\' && !this.eof()) { 10645 ch = this.source[this.index]; 10646 if (ch === 'u') { 10647 ++this.index; 10648 var restore = this.index; 10649 var char = this.scanHexEscape('u'); 10650 if (char !== null) { 10651 flags += char; 10652 for (str += '\\u'; restore < this.index; ++restore) { 10653 str += this.source[restore]; 10654 } 10655 } 10656 else { 10657 this.index = restore; 10658 flags += 'u'; 10659 str += '\\u'; 10660 } 10661 this.tolerateUnexpectedToken(); 10662 } 10663 else { 10664 str += '\\'; 10665 this.tolerateUnexpectedToken(); 10666 } 10667 } 10668 else { 10669 flags += ch; 10670 str += ch; 10671 } 10672 } 10673 return flags; 10674 }; 10675 Scanner.prototype.scanRegExp = function () { 10676 var start = this.index; 10677 var pattern = this.scanRegExpBody(); 10678 var flags = this.scanRegExpFlags(); 10679 var value = this.testRegExp(pattern, flags); 10680 return { 10681 type: 9 /* RegularExpression */, 10682 value: '', 10683 pattern: pattern, 10684 flags: flags, 10685 regex: value, 10686 lineNumber: this.lineNumber, 10687 lineStart: this.lineStart, 10688 start: start, 10689 end: this.index 10690 }; 10691 }; 10692 Scanner.prototype.lex = function () { 10693 if (this.eof()) { 10694 return { 10695 type: 2 /* EOF */, 10696 value: '', 10697 lineNumber: this.lineNumber, 10698 lineStart: this.lineStart, 10699 start: this.index, 10700 end: this.index 10701 }; 10702 } 10703 var cp = this.source.charCodeAt(this.index); 10704 if (character_1.Character.isIdentifierStart(cp)) { 10705 return this.scanIdentifier(); 10706 } 10707 // Very common: ( and ) and ; 10708 if (cp === 0x28 || cp === 0x29 || cp === 0x3B) { 10709 return this.scanPunctuator(); 10710 } 10711 // String literal starts with single quote (U+0027) or double quote (U+0022). 10712 if (cp === 0x27 || cp === 0x22) { 10713 return this.scanStringLiteral(); 10714 } 10715 // Dot (.) U+002E can also start a floating-point number, hence the need 10716 // to check the next character. 10717 if (cp === 0x2E) { 10718 if (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index + 1))) { 10719 return this.scanNumericLiteral(); 10720 } 10721 return this.scanPunctuator(); 10722 } 10723 if (character_1.Character.isDecimalDigit(cp)) { 10724 return this.scanNumericLiteral(); 10725 } 10726 // Template literals start with ` (U+0060) for template head 10727 // or } (U+007D) for template middle or template tail.
vendor: 13,776 bytes, lines 10728-11175
10728 if (cp === 0x60 || (cp === 0x7D && this.curlyStack[this.curlyStack.length - 1] === '${')) { 10729 return this.scanTemplate(); 10730 } 10731 // Possible identifier start in a surrogate pair. 10732 if (cp >= 0xD800 && cp < 0xDFFF) { 10733 if (character_1.Character.isIdentifierStart(this.codePointAt(this.index))) { 10734 return this.scanIdentifier(); 10735 } 10736 } 10737 return this.scanPunctuator(); 10738 }; 10739 return Scanner; 10740 }()); 10741 exports.Scanner = Scanner; 10742 10743 10744/***/ }, 10745/* 13 */ 10746/***/ function(module, exports) { 10747 10748 "use strict"; 10749 Object.defineProperty(exports, "__esModule", { value: true }); 10750 exports.TokenName = {}; 10751 exports.TokenName[1 /* BooleanLiteral */] = 'Boolean'; 10752 exports.TokenName[2 /* EOF */] = '<end>'; 10753 exports.TokenName[3 /* Identifier */] = 'Identifier'; 10754 exports.TokenName[4 /* Keyword */] = 'Keyword'; 10755 exports.TokenName[5 /* NullLiteral */] = 'Null'; 10756 exports.TokenName[6 /* NumericLiteral */] = 'Numeric'; 10757 exports.TokenName[7 /* Punctuator */] = 'Punctuator'; 10758 exports.TokenName[8 /* StringLiteral */] = 'String'; 10759 exports.TokenName[9 /* RegularExpression */] = 'RegularExpression'; 10760 exports.TokenName[10 /* Template */] = 'Template'; 10761 10762 10763/***/ }, 10764/* 14 */ 10765/***/ function(module, exports) { 10766 10767 "use strict"; 10768 // Generated by generate-xhtml-entities.js. DO NOT MODIFY! 10769 Object.defineProperty(exports, "__esModule", { value: true }); 10770 exports.XHTMLEntities = { 10771 quot: '\u0022', 10772 amp: '\u0026', 10773 apos: '\u0027', 10774 gt: '\u003E', 10775 nbsp: '\u00A0', 10776 iexcl: '\u00A1', 10777 cent: '\u00A2', 10778 pound: '\u00A3', 10779 curren: '\u00A4', 10780 yen: '\u00A5', 10781 brvbar: '\u00A6', 10782 sect: '\u00A7', 10783 uml: '\u00A8', 10784 copy: '\u00A9', 10785 ordf: '\u00AA', 10786 laquo: '\u00AB', 10787 not: '\u00AC', 10788 shy: '\u00AD', 10789 reg: '\u00AE', 10790 macr: '\u00AF', 10791 deg: '\u00B0', 10792 plusmn: '\u00B1', 10793 sup2: '\u00B2', 10794 sup3: '\u00B3', 10795 acute: '\u00B4', 10796 micro: '\u00B5', 10797 para: '\u00B6', 10798 middot: '\u00B7', 10799 cedil: '\u00B8', 10800 sup1: '\u00B9', 10801 ordm: '\u00BA', 10802 raquo: '\u00BB', 10803 frac14: '\u00BC', 10804 frac12: '\u00BD', 10805 frac34: '\u00BE', 10806 iquest: '\u00BF', 10807 Agrave: '\u00C0', 10808 Aacute: '\u00C1', 10809 Acirc: '\u00C2', 10810 Atilde: '\u00C3', 10811 Auml: '\u00C4', 10812 Aring: '\u00C5', 10813 AElig: '\u00C6', 10814 Ccedil: '\u00C7', 10815 Egrave: '\u00C8', 10816 Eacute: '\u00C9', 10817 Ecirc: '\u00CA', 10818 Euml: '\u00CB', 10819 Igrave: '\u00CC', 10820 Iacute: '\u00CD', 10821 Icirc: '\u00CE', 10822 Iuml: '\u00CF', 10823 ETH: '\u00D0', 10824 Ntilde: '\u00D1', 10825 Ograve: '\u00D2', 10826 Oacute: '\u00D3', 10827 Ocirc: '\u00D4', 10828 Otilde: '\u00D5', 10829 Ouml: '\u00D6', 10830 times: '\u00D7', 10831 Oslash: '\u00D8', 10832 Ugrave: '\u00D9', 10833 Uacute: '\u00DA', 10834 Ucirc: '\u00DB', 10835 Uuml: '\u00DC', 10836 Yacute: '\u00DD', 10837 THORN: '\u00DE', 10838 szlig: '\u00DF', 10839 agrave: '\u00E0', 10840 aacute: '\u00E1', 10841 acirc: '\u00E2', 10842 atilde: '\u00E3', 10843 auml: '\u00E4', 10844 aring: '\u00E5', 10845 aelig: '\u00E6', 10846 ccedil: '\u00E7', 10847 egrave: '\u00E8', 10848 eacute: '\u00E9', 10849 ecirc: '\u00EA', 10850 euml: '\u00EB', 10851 igrave: '\u00EC', 10852 iacute: '\u00ED', 10853 icirc: '\u00EE', 10854 iuml: '\u00EF', 10855 eth: '\u00F0', 10856 ntilde: '\u00F1', 10857 ograve: '\u00F2', 10858 oacute: '\u00F3', 10859 ocirc: '\u00F4', 10860 otilde: '\u00F5', 10861 ouml: '\u00F6', 10862 divide: '\u00F7', 10863 oslash: '\u00F8', 10864 ugrave: '\u00F9', 10865 uacute: '\u00FA', 10866 ucirc: '\u00FB', 10867 uuml: '\u00FC', 10868 yacute: '\u00FD', 10869 thorn: '\u00FE', 10870 yuml: '\u00FF', 10871 OElig: '\u0152', 10872 oelig: '\u0153', 10873 Scaron: '\u0160', 10874 scaron: '\u0161', 10875 Yuml: '\u0178', 10876 fnof: '\u0192', 10877 circ: '\u02C6', 10878 tilde: '\u02DC', 10879 Alpha: '\u0391', 10880 Beta: '\u0392', 10881 Gamma: '\u0393', 10882 Delta: '\u0394', 10883 Epsilon: '\u0395', 10884 Zeta: '\u0396', 10885 Eta: '\u0397', 10886 Theta: '\u0398', 10887 Iota: '\u0399', 10888 Kappa: '\u039A', 10889 Lambda: '\u039B', 10890 Mu: '\u039C', 10891 Nu: '\u039D', 10892 Xi: '\u039E', 10893 Omicron: '\u039F', 10894 Pi: '\u03A0', 10895 Rho: '\u03A1', 10896 Sigma: '\u03A3', 10897 Tau: '\u03A4', 10898 Upsilon: '\u03A5', 10899 Phi: '\u03A6', 10900 Chi: '\u03A7', 10901 Psi: '\u03A8', 10902 Omega: '\u03A9', 10903 alpha: '\u03B1', 10904 beta: '\u03B2', 10905 gamma: '\u03B3', 10906 delta: '\u03B4', 10907 epsilon: '\u03B5', 10908 zeta: '\u03B6', 10909 eta: '\u03B7', 10910 theta: '\u03B8', 10911 iota: '\u03B9', 10912 kappa: '\u03BA', 10913 lambda: '\u03BB', 10914 mu: '\u03BC', 10915 nu: '\u03BD', 10916 xi: '\u03BE', 10917 omicron: '\u03BF', 10918 pi: '\u03C0', 10919 rho: '\u03C1', 10920 sigmaf: '\u03C2', 10921 sigma: '\u03C3', 10922 tau: '\u03C4', 10923 upsilon: '\u03C5', 10924 phi: '\u03C6', 10925 chi: '\u03C7', 10926 psi: '\u03C8', 10927 omega: '\u03C9', 10928 thetasym: '\u03D1', 10929 upsih: '\u03D2', 10930 piv: '\u03D6', 10931 ensp: '\u2002', 10932 emsp: '\u2003', 10933 thinsp: '\u2009', 10934 zwnj: '\u200C', 10935 zwj: '\u200D', 10936 lrm: '\u200E', 10937 rlm: '\u200F', 10938 ndash: '\u2013', 10939 mdash: '\u2014', 10940 lsquo: '\u2018', 10941 rsquo: '\u2019', 10942 sbquo: '\u201A', 10943 ldquo: '\u201C', 10944 rdquo: '\u201D', 10945 bdquo: '\u201E', 10946 dagger: '\u2020', 10947 Dagger: '\u2021', 10948 bull: '\u2022', 10949 hellip: '\u2026', 10950 permil: '\u2030', 10951 prime: '\u2032', 10952 Prime: '\u2033', 10953 lsaquo: '\u2039', 10954 rsaquo: '\u203A', 10955 oline: '\u203E', 10956 frasl: '\u2044', 10957 euro: '\u20AC', 10958 image: '\u2111', 10959 weierp: '\u2118', 10960 real: '\u211C', 10961 trade: '\u2122', 10962 alefsym: '\u2135', 10963 larr: '\u2190', 10964 uarr: '\u2191', 10965 rarr: '\u2192', 10966 darr: '\u2193', 10967 harr: '\u2194', 10968 crarr: '\u21B5', 10969 lArr: '\u21D0', 10970 uArr: '\u21D1', 10971 rArr: '\u21D2', 10972 dArr: '\u21D3', 10973 hArr: '\u21D4', 10974 forall: '\u2200', 10975 part: '\u2202', 10976 exist: '\u2203', 10977 empty: '\u2205', 10978 nabla: '\u2207', 10979 isin: '\u2208', 10980 notin: '\u2209', 10981 ni: '\u220B', 10982 prod: '\u220F', 10983 sum: '\u2211', 10984 minus: '\u2212', 10985 lowast: '\u2217', 10986 radic: '\u221A', 10987 prop: '\u221D', 10988 infin: '\u221E', 10989 ang: '\u2220', 10990 and: '\u2227', 10991 or: '\u2228', 10992 cap: '\u2229', 10993 cup: '\u222A', 10994 int: '\u222B', 10995 there4: '\u2234', 10996 sim: '\u223C', 10997 cong: '\u2245', 10998 asymp: '\u2248', 10999 ne: '\u2260', 11000 equiv: '\u2261', 11001 le: '\u2264', 11002 ge: '\u2265', 11003 sub: '\u2282', 11004 sup: '\u2283', 11005 nsub: '\u2284', 11006 sube: '\u2286', 11007 supe: '\u2287', 11008 oplus: '\u2295', 11009 otimes: '\u2297', 11010 perp: '\u22A5', 11011 sdot: '\u22C5', 11012 lceil: '\u2308', 11013 rceil: '\u2309', 11014 lfloor: '\u230A', 11015 rfloor: '\u230B', 11016 loz: '\u25CA', 11017 spades: '\u2660', 11018 clubs: '\u2663', 11019 hearts: '\u2665', 11020 diams: '\u2666', 11021 lang: '\u27E8', 11022 rang: '\u27E9' 11023 }; 11024 11025 11026/***/ }, 11027/* 15 */ 11028/***/ function(module, exports, __webpack_require__) { 11029 11030 "use strict"; 11031 Object.defineProperty(exports, "__esModule", { value: true }); 11032 var error_handler_1 = __webpack_require__(10); 11033 var scanner_1 = __webpack_require__(12); 11034 var token_1 = __webpack_require__(13); 11035 var Reader = (function () { 11036 function Reader() { 11037 this.values = []; 11038 this.curly = this.paren = -1; 11039 } 11040 // A function following one of those tokens is an expression. 11041 Reader.prototype.beforeFunctionExpression = function (t) { 11042 return ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new', 11043 'return', 'case', 'delete', 'throw', 'void', 11044 // assignment operators 11045 '=', '+=', '-=', '*=', '**=', '/=', '%=', '<<=', '>>=', '>>>=', 11046 '&=', '|=', '^=', ',', 11047 // binary/unary operators 11048 '+', '-', '*', '**', '/', '%', '++', '--', '<<', '>>', '>>>', '&', 11049 '|', '^', '!', '~', '&&', '||', '?', ':', '===', '==', '>=', 11050 '<=', '<', '>', '!=', '!=='].indexOf(t) >= 0; 11051 }; 11052 // Determine if forward slash (/) is an operator or part of a regular expression 11053 // https://github.com/mozilla/sweet.js/wiki/design 11054 Reader.prototype.isRegexStart = function () { 11055 var previous = this.values[this.values.length - 1]; 11056 var regex = (previous !== null); 11057 switch (previous) { 11058 case 'this': 11059 case ']': 11060 regex = false; 11061 break; 11062 case ')': 11063 var keyword = this.values[this.paren - 1]; 11064 regex = (keyword === 'if' || keyword === 'while' || keyword === 'for' || keyword === 'with'); 11065 break; 11066 case '}': 11067 // Dividing a function by anything makes little sense, 11068 // but we have to check for that. 11069 regex = false; 11070 if (this.values[this.curly - 3] === 'function') { 11071 // Anonymous function, e.g. function(){} /42 11072 var check = this.values[this.curly - 4]; 11073 regex = check ? !this.beforeFunctionExpression(check) : false; 11074 } 11075 else if (this.values[this.curly - 4] === 'function') { 11076 // Named function, e.g. function f(){} /42/ 11077 var check = this.values[this.curly - 5]; 11078 regex = check ? !this.beforeFunctionExpression(check) : true; 11079 } 11080 break; 11081 default: 11082 break; 11083 } 11084 return regex; 11085 }; 11086 Reader.prototype.push = function (token) { 11087 if (token.type === 7 /* Punctuator */ || token.type === 4 /* Keyword */) { 11088 if (token.value === '{') { 11089 this.curly = this.values.length; 11090 } 11091 else if (token.value === '(') { 11092 this.paren = this.values.length; 11093 } 11094 this.values.push(token.value); 11095 } 11096 else { 11097 this.values.push(null); 11098 } 11099 }; 11100 return Reader; 11101 }()); 11102 var Tokenizer = (function () { 11103 function Tokenizer(code, config) { 11104 this.errorHandler = new error_handler_1.ErrorHandler(); 11105 this.errorHandler.tolerant = config ? (typeof config.tolerant === 'boolean' && config.tolerant) : false; 11106 this.scanner = new scanner_1.Scanner(code, this.errorHandler); 11107 this.scanner.trackComment = config ? (typeof config.comment === 'boolean' && config.comment) : false; 11108 this.trackRange = config ? (typeof config.range === 'boolean' && config.range) : false; 11109 this.trackLoc = config ? (typeof config.loc === 'boolean' && config.loc) : false; 11110 this.buffer = []; 11111 this.reader = new Reader(); 11112 } 11113 Tokenizer.prototype.errors = function () { 11114 return this.errorHandler.errors; 11115 }; 11116 Tokenizer.prototype.getNextToken = function () { 11117 if (this.buffer.length === 0) { 11118 var comments = this.scanner.scanComments(); 11119 if (this.scanner.trackComment) { 11120 for (var i = 0; i < comments.length; ++i) { 11121 var e = comments[i]; 11122 var value = this.scanner.source.slice(e.slice[0], e.slice[1]); 11123 var comment = { 11124 type: e.multiLine ? 'BlockComment' : 'LineComment', 11125 value: value 11126 }; 11127 if (this.trackRange) { 11128 comment.range = e.range; 11129 } 11130 if (this.trackLoc) { 11131 comment.loc = e.loc; 11132 } 11133 this.buffer.push(comment); 11134 } 11135 } 11136 if (!this.scanner.eof()) { 11137 var loc = void 0; 11138 if (this.trackLoc) { 11139 loc = { 11140 start: { 11141 line: this.scanner.lineNumber, 11142 column: this.scanner.index - this.scanner.lineStart 11143 }, 11144 end: {} 11145 }; 11146 } 11147 var startRegex = (this.scanner.source[this.scanner.index] === '/') && this.reader.isRegexStart(); 11148 var token = startRegex ? this.scanner.scanRegExp() : this.scanner.lex(); 11149 this.reader.push(token); 11150 var entry = { 11151 type: token_1.TokenName[token.type], 11152 value: this.scanner.source.slice(token.start, token.end) 11153 }; 11154 if (this.trackRange) { 11155 entry.range = [token.start, token.end]; 11156 } 11157 if (this.trackLoc) { 11158 loc.end = { 11159 line: this.scanner.lineNumber, 11160 column: this.scanner.index - this.scanner.lineStart 11161 }; 11162 entry.loc = loc; 11163 } 11164 if (token.type === 9 /* RegularExpression */) { 11165 var pattern = token.pattern; 11166 var flags = token.flags; 11167 entry.regex = { pattern: pattern, flags: flags }; 11168 } 11169 this.buffer.push(entry); 11170 } 11171 } 11172 return this.buffer.shift(); 11173 }; 11174 return Tokenizer; 11175 }());
vendor: 5,227 bytes, lines 11176-11341
11176 exports.Tokenizer = Tokenizer; 11177 11178 11179/***/ } 11180/******/ ]) 11181}); 11182; 11183/*global define, Reflect */ 11184 11185/* 11186 * xpcshell has a smaller stack on linux and windows (1MB vs 9MB on mac), 11187 * and the recursive nature of esprima can cause it to overflow pretty 11188 * quickly. So favor it built in Reflect parser: 11189 * https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API 11190 */ 11191define('esprimaAdapter', ['./esprima', 'env'], function (esprima, env) { 11192 if (env.get() === 'xpconnect' && typeof Reflect !== 'undefined') { 11193 return Reflect; 11194 } else { 11195 return esprima; 11196 } 11197}); 11198(function webpackUniversalModuleDefinition(root, factory) { 11199var exports, module; 11200 if(typeof exports === 'object' && typeof module === 'object') 11201 module.exports = factory(); 11202 else if(typeof define === 'function' && define.amd) 11203 define('source-map', [], factory); 11204 else if(typeof exports === 'object') 11205 exports["sourceMap"] = factory(); 11206 else 11207 root["sourceMap"] = factory(); 11208})(this, function() { 11209return /******/ (function(modules) { // webpackBootstrap 11210/******/ // The module cache 11211/******/ var installedModules = {}; 11212 11213/******/ // The require function 11214/******/ function __webpack_require__(moduleId) { 11215 11216/******/ // Check if module is in cache 11217/******/ if(installedModules[moduleId]) 11218/******/ return installedModules[moduleId].exports; 11219 11220/******/ // Create a new module (and put it into the cache) 11221/******/ var module = installedModules[moduleId] = { 11222/******/ exports: {}, 11223/******/ id: moduleId, 11224/******/ loaded: false 11225/******/ }; 11226 11227/******/ // Execute the module function 11228/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 11229 11230/******/ // Flag the module as loaded 11231/******/ module.loaded = true; 11232 11233/******/ // Return the exports of the module 11234/******/ return module.exports; 11235/******/ } 11236 11237 11238/******/ // expose the modules object (__webpack_modules__) 11239/******/ __webpack_require__.m = modules; 11240 11241/******/ // expose the module cache 11242/******/ __webpack_require__.c = installedModules; 11243 11244/******/ // __webpack_public_path__ 11245/******/ __webpack_require__.p = ""; 11246 11247/******/ // Load entry module and return exports 11248/******/ return __webpack_require__(0); 11249/******/ }) 11250/************************************************************************/ 11251/******/ ([ 11252/* 0 */ 11253/***/ function(module, exports, __webpack_require__) { 11254 11255 /* 11256 * Copyright 2009-2011 Mozilla Foundation and contributors 11257 * Licensed under the New BSD license. See LICENSE.txt or: 11258 * http://opensource.org/licenses/BSD-3-Clause 11259 */ 11260 exports.SourceMapGenerator = __webpack_require__(1).SourceMapGenerator; 11261 exports.SourceMapConsumer = __webpack_require__(7).SourceMapConsumer; 11262 exports.SourceNode = __webpack_require__(10).SourceNode; 11263 11264 11265/***/ }, 11266/* 1 */ 11267/***/ function(module, exports, __webpack_require__) { 11268 11269 /* -*- Mode: js; js-indent-level: 2; -*- */ 11270 /* 11271 * Copyright 2011 Mozilla Foundation and contributors 11272 * Licensed under the New BSD license. See LICENSE or: 11273 * http://opensource.org/licenses/BSD-3-Clause 11274 */ 11275 11276 var base64VLQ = __webpack_require__(2); 11277 var util = __webpack_require__(4); 11278 var ArraySet = __webpack_require__(5).ArraySet; 11279 var MappingList = __webpack_require__(6).MappingList; 11280 11281 /** 11282 * An instance of the SourceMapGenerator represents a source map which is 11283 * being built incrementally. You may pass an object with the following 11284 * properties: 11285 * 11286 * - file: The filename of the generated source. 11287 * - sourceRoot: A root for all relative URLs in this source map. 11288 */ 11289 function SourceMapGenerator(aArgs) { 11290 if (!aArgs) { 11291 aArgs = {}; 11292 } 11293 this._file = util.getArg(aArgs, 'file', null); 11294 this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null); 11295 this._skipValidation = util.getArg(aArgs, 'skipValidation', false); 11296 this._sources = new ArraySet(); 11297 this._names = new ArraySet(); 11298 this._mappings = new MappingList(); 11299 this._sourcesContents = null; 11300 } 11301 11302 SourceMapGenerator.prototype._version = 3; 11303 11304 /** 11305 * Creates a new SourceMapGenerator based on a SourceMapConsumer 11306 * 11307 * @param aSourceMapConsumer The SourceMap. 11308 */ 11309 SourceMapGenerator.fromSourceMap = 11310 function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) { 11311 var sourceRoot = aSourceMapConsumer.sourceRoot; 11312 var generator = new SourceMapGenerator({ 11313 file: aSourceMapConsumer.file, 11314 sourceRoot: sourceRoot 11315 }); 11316 aSourceMapConsumer.eachMapping(function (mapping) { 11317 var newMapping = { 11318 generated: { 11319 line: mapping.generatedLine, 11320 column: mapping.generatedColumn 11321 } 11322 }; 11323 11324 if (mapping.source != null) { 11325 newMapping.source = mapping.source; 11326 if (sourceRoot != null) { 11327 newMapping.source = util.relative(sourceRoot, newMapping.source); 11328 } 11329 11330 newMapping.original = { 11331 line: mapping.originalLine, 11332 column: mapping.originalColumn 11333 }; 11334 11335 if (mapping.name != null) { 11336 newMapping.name = mapping.name; 11337 } 11338 } 11339 11340 generator.addMapping(newMapping); 11341 });
vendor: 12,142 bytes, lines 11342-11684
11342 aSourceMapConsumer.sources.forEach(function (sourceFile) { 11343 var content = aSourceMapConsumer.sourceContentFor(sourceFile); 11344 if (content != null) { 11345 generator.setSourceContent(sourceFile, content); 11346 } 11347 }); 11348 return generator; 11349 }; 11350 11351 /** 11352 * Add a single mapping from original source line and column to the generated 11353 * source's line and column for this source map being created. The mapping 11354 * object should have the following properties: 11355 * 11356 * - generated: An object with the generated line and column positions. 11357 * - original: An object with the original line and column positions. 11358 * - source: The original source file (relative to the sourceRoot). 11359 * - name: An optional original token name for this mapping. 11360 */ 11361 SourceMapGenerator.prototype.addMapping = 11362 function SourceMapGenerator_addMapping(aArgs) { 11363 var generated = util.getArg(aArgs, 'generated'); 11364 var original = util.getArg(aArgs, 'original', null); 11365 var source = util.getArg(aArgs, 'source', null); 11366 var name = util.getArg(aArgs, 'name', null); 11367 11368 if (!this._skipValidation) { 11369 this._validateMapping(generated, original, source, name); 11370 } 11371 11372 if (source != null) { 11373 source = String(source); 11374 if (!this._sources.has(source)) { 11375 this._sources.add(source); 11376 } 11377 } 11378 11379 if (name != null) { 11380 name = String(name); 11381 if (!this._names.has(name)) { 11382 this._names.add(name); 11383 } 11384 } 11385 11386 this._mappings.add({ 11387 generatedLine: generated.line, 11388 generatedColumn: generated.column, 11389 originalLine: original != null && original.line, 11390 originalColumn: original != null && original.column, 11391 source: source, 11392 name: name 11393 }); 11394 }; 11395 11396 /** 11397 * Set the source content for a source file. 11398 */ 11399 SourceMapGenerator.prototype.setSourceContent = 11400 function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) { 11401 var source = aSourceFile; 11402 if (this._sourceRoot != null) { 11403 source = util.relative(this._sourceRoot, source); 11404 } 11405 11406 if (aSourceContent != null) { 11407 // Add the source content to the _sourcesContents map. 11408 // Create a new _sourcesContents map if the property is null. 11409 if (!this._sourcesContents) { 11410 this._sourcesContents = Object.create(null); 11411 } 11412 this._sourcesContents[util.toSetString(source)] = aSourceContent; 11413 } else if (this._sourcesContents) { 11414 // Remove the source file from the _sourcesContents map. 11415 // If the _sourcesContents map is empty, set the property to null. 11416 delete this._sourcesContents[util.toSetString(source)]; 11417 if (Object.keys(this._sourcesContents).length === 0) { 11418 this._sourcesContents = null; 11419 } 11420 } 11421 }; 11422 11423 /** 11424 * Applies the mappings of a sub-source-map for a specific source file to the 11425 * source map being generated. Each mapping to the supplied source file is 11426 * rewritten using the supplied source map. Note: The resolution for the 11427 * resulting mappings is the minimium of this map and the supplied map. 11428 * 11429 * @param aSourceMapConsumer The source map to be applied. 11430 * @param aSourceFile Optional. The filename of the source file. 11431 * If omitted, SourceMapConsumer's file property will be used. 11432 * @param aSourceMapPath Optional. The dirname of the path to the source map 11433 * to be applied. If relative, it is relative to the SourceMapConsumer. 11434 * This parameter is needed when the two source maps aren't in the same 11435 * directory, and the source map to be applied contains relative source 11436 * paths. If so, those relative source paths need to be rewritten 11437 * relative to the SourceMapGenerator. 11438 */ 11439 SourceMapGenerator.prototype.applySourceMap = 11440 function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) { 11441 var sourceFile = aSourceFile; 11442 // If aSourceFile is omitted, we will use the file property of the SourceMap 11443 if (aSourceFile == null) { 11444 if (aSourceMapConsumer.file == null) { 11445 throw new Error( 11446 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' + 11447 'or the source map\'s "file" property. Both were omitted.' 11448 ); 11449 } 11450 sourceFile = aSourceMapConsumer.file; 11451 } 11452 var sourceRoot = this._sourceRoot; 11453 // Make "sourceFile" relative if an absolute Url is passed. 11454 if (sourceRoot != null) { 11455 sourceFile = util.relative(sourceRoot, sourceFile); 11456 } 11457 // Applying the SourceMap can add and remove items from the sources and 11458 // the names array. 11459 var newSources = new ArraySet(); 11460 var newNames = new ArraySet(); 11461 11462 // Find mappings for the "sourceFile" 11463 this._mappings.unsortedForEach(function (mapping) { 11464 if (mapping.source === sourceFile && mapping.originalLine != null) { 11465 // Check if it can be mapped by the source map, then update the mapping. 11466 var original = aSourceMapConsumer.originalPositionFor({ 11467 line: mapping.originalLine, 11468 column: mapping.originalColumn 11469 }); 11470 if (original.source != null) { 11471 // Copy mapping 11472 mapping.source = original.source; 11473 if (aSourceMapPath != null) { 11474 mapping.source = util.join(aSourceMapPath, mapping.source) 11475 } 11476 if (sourceRoot != null) { 11477 mapping.source = util.relative(sourceRoot, mapping.source); 11478 } 11479 mapping.originalLine = original.line; 11480 mapping.originalColumn = original.column; 11481 if (original.name != null) { 11482 mapping.name = original.name; 11483 } 11484 } 11485 } 11486 11487 var source = mapping.source; 11488 if (source != null && !newSources.has(source)) { 11489 newSources.add(source); 11490 } 11491 11492 var name = mapping.name; 11493 if (name != null && !newNames.has(name)) { 11494 newNames.add(name); 11495 } 11496 11497 }, this); 11498 this._sources = newSources; 11499 this._names = newNames; 11500 11501 // Copy sourcesContents of applied map. 11502 aSourceMapConsumer.sources.forEach(function (sourceFile) { 11503 var content = aSourceMapConsumer.sourceContentFor(sourceFile); 11504 if (content != null) { 11505 if (aSourceMapPath != null) { 11506 sourceFile = util.join(aSourceMapPath, sourceFile); 11507 } 11508 if (sourceRoot != null) { 11509 sourceFile = util.relative(sourceRoot, sourceFile); 11510 } 11511 this.setSourceContent(sourceFile, content); 11512 } 11513 }, this); 11514 }; 11515 11516 /** 11517 * A mapping can have one of the three levels of data: 11518 * 11519 * 1. Just the generated position. 11520 * 2. The Generated position, original position, and original source. 11521 * 3. Generated and original position, original source, as well as a name 11522 * token. 11523 * 11524 * To maintain consistency, we validate that any new mapping being added falls 11525 * in to one of these categories. 11526 */ 11527 SourceMapGenerator.prototype._validateMapping = 11528 function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, 11529 aName) { 11530 if (aGenerated && 'line' in aGenerated && 'column' in aGenerated 11531 && aGenerated.line > 0 && aGenerated.column >= 0 11532 && !aOriginal && !aSource && !aName) { 11533 // Case 1. 11534 return; 11535 } 11536 else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated 11537 && aOriginal && 'line' in aOriginal && 'column' in aOriginal 11538 && aGenerated.line > 0 && aGenerated.column >= 0 11539 && aOriginal.line > 0 && aOriginal.column >= 0 11540 && aSource) { 11541 // Cases 2 and 3. 11542 return; 11543 } 11544 else { 11545 throw new Error('Invalid mapping: ' + JSON.stringify({ 11546 generated: aGenerated, 11547 source: aSource, 11548 original: aOriginal, 11549 name: aName 11550 })); 11551 } 11552 }; 11553 11554 /** 11555 * Serialize the accumulated mappings in to the stream of base 64 VLQs 11556 * specified by the source map format. 11557 */ 11558 SourceMapGenerator.prototype._serializeMappings = 11559 function SourceMapGenerator_serializeMappings() { 11560 var previousGeneratedColumn = 0; 11561 var previousGeneratedLine = 1; 11562 var previousOriginalColumn = 0; 11563 var previousOriginalLine = 0; 11564 var previousName = 0; 11565 var previousSource = 0; 11566 var result = ''; 11567 var next; 11568 var mapping; 11569 var nameIdx; 11570 var sourceIdx; 11571 11572 var mappings = this._mappings.toArray(); 11573 for (var i = 0, len = mappings.length; i < len; i++) { 11574 mapping = mappings[i]; 11575 next = '' 11576 11577 if (mapping.generatedLine !== previousGeneratedLine) { 11578 previousGeneratedColumn = 0; 11579 while (mapping.generatedLine !== previousGeneratedLine) { 11580 next += ';'; 11581 previousGeneratedLine++; 11582 } 11583 } 11584 else { 11585 if (i > 0) { 11586 if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) { 11587 continue; 11588 } 11589 next += ','; 11590 } 11591 } 11592 11593 next += base64VLQ.encode(mapping.generatedColumn 11594 - previousGeneratedColumn); 11595 previousGeneratedColumn = mapping.generatedColumn; 11596 11597 if (mapping.source != null) { 11598 sourceIdx = this._sources.indexOf(mapping.source); 11599 next += base64VLQ.encode(sourceIdx - previousSource); 11600 previousSource = sourceIdx; 11601 11602 // lines are stored 0-based in SourceMap spec version 3 11603 next += base64VLQ.encode(mapping.originalLine - 1 11604 - previousOriginalLine); 11605 previousOriginalLine = mapping.originalLine - 1; 11606 11607 next += base64VLQ.encode(mapping.originalColumn 11608 - previousOriginalColumn); 11609 previousOriginalColumn = mapping.originalColumn; 11610 11611 if (mapping.name != null) { 11612 nameIdx = this._names.indexOf(mapping.name); 11613 next += base64VLQ.encode(nameIdx - previousName); 11614 previousName = nameIdx; 11615 } 11616 } 11617 11618 result += next; 11619 } 11620 11621 return result; 11622 }; 11623 11624 SourceMapGenerator.prototype._generateSourcesContent = 11625 function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) { 11626 return aSources.map(function (source) { 11627 if (!this._sourcesContents) { 11628 return null; 11629 } 11630 if (aSourceRoot != null) { 11631 source = util.relative(aSourceRoot, source); 11632 } 11633 var key = util.toSetString(source); 11634 return Object.prototype.hasOwnProperty.call(this._sourcesContents, key) 11635 ? this._sourcesContents[key] 11636 : null; 11637 }, this); 11638 }; 11639 11640 /** 11641 * Externalize the source map. 11642 */ 11643 SourceMapGenerator.prototype.toJSON = 11644 function SourceMapGenerator_toJSON() { 11645 var map = { 11646 version: this._version, 11647 sources: this._sources.toArray(), 11648 names: this._names.toArray(), 11649 mappings: this._serializeMappings() 11650 }; 11651 if (this._file != null) { 11652 map.file = this._file; 11653 } 11654 if (this._sourceRoot != null) { 11655 map.sourceRoot = this._sourceRoot; 11656 } 11657 if (this._sourcesContents) { 11658 map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); 11659 } 11660 11661 return map; 11662 }; 11663 11664 /** 11665 * Render the source map being generated to a string. 11666 */ 11667 SourceMapGenerator.prototype.toString = 11668 function SourceMapGenerator_toString() { 11669 return JSON.stringify(this.toJSON()); 11670 }; 11671 11672 exports.SourceMapGenerator = SourceMapGenerator; 11673 11674 11675/***/ }, 11676/* 2 */ 11677/***/ function(module, exports, __webpack_require__) { 11678 11679 /* -*- Mode: js; js-indent-level: 2; -*- */ 11680 /* 11681 * Copyright 2011 Mozilla Foundation and contributors 11682 * Licensed under the New BSD license. See LICENSE or: 11683 * http://opensource.org/licenses/BSD-3-Clause 11684 *
11685 * Based on the Base 64 VLQ implementation in Closure Compiler: 11686 * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java 11687 * 11688 * Copyright 2011 The Closure Compiler Authors. All rights reserved. 11689 * Redistribution and use in source and binary forms, with or without 11690 * modification, are permitted provided that the following conditions are 11691 * met: 11692 * 11693 * * Redistributions of source code must retain the above copyright 11694 * notice, this list of conditions and the following disclaimer. 11695 * * Redistributions in binary form must reproduce the above 11696 * copyright notice, this list of conditions and the following 11697 * disclaimer in the documentation and/or other materials provided 11698 * with the distribution. 11699 * * Neither the name of Google Inc. nor the names of its 11700 * contributors may be used to endorse or promote products derived 11701 * from this software without specific prior written permission. 11702 * 11703 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 11704 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 11705 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 11706 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 11707 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 11708 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 11709 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 11710 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 11711 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 11712 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 11713 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11714 */ 11715 11716 var base64 = __webpack_require__(3); 11717 11718 // A single base 64 digit can contain 6 bits of data. For the base 64 variable 11719 // length quantities we use in the source map spec, the first bit is the sign, 11720 // the next four bits are the actual value, and the 6th bit is the 11721 // continuation bit. The continuation bit tells us whether there are more 11722 // digits in this value following this digit. 11723 // 11724 // Continuation 11725 // | Sign 11726 // | | 11727 // V V 11728 // 101011 11729 11730 var VLQ_BASE_SHIFT = 5; 11731 11732 // binary: 100000 11733 var VLQ_BASE = 1 << VLQ_BASE_SHIFT; 11734 11735 // binary: 011111 11736 var VLQ_BASE_MASK = VLQ_BASE - 1; 11737 11738 // binary: 100000 11739 var VLQ_CONTINUATION_BIT = VLQ_BASE; 11740 11741 /** 11742 * Converts from a two-complement value to a value where the sign bit is 11743 * placed in the least significant bit. For example, as decimals: 11744 * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) 11745 * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) 11746 */ 11747 function toVLQSigned(aValue) { 11748 return aValue < 0 11749 ? ((-aValue) << 1) + 1 11750 : (aValue << 1) + 0; 11751 } 11752 11753 /** 11754 * Converts to a two-complement value from a value where the sign bit is 11755 * placed in the least significant bit. For example, as decimals: 11756 * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 11757 * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 11758 */ 11759 function fromVLQSigned(aValue) { 11760 var isNegative = (aValue & 1) === 1; 11761 var shifted = aValue >> 1; 11762 return isNegative 11763 ? -shifted 11764 : shifted; 11765 } 11766 11767 /** 11768 * Returns the base 64 VLQ encoded value. 11769 */ 11770 exports.encode = function base64VLQ_encode(aValue) { 11771 var encoded = ""; 11772 var digit; 11773 11774 var vlq = toVLQSigned(aValue); 11775 11776 do { 11777 digit = vlq & VLQ_BASE_MASK; 11778 vlq >>>= VLQ_BASE_SHIFT; 11779 if (vlq > 0) { 11780 // There are still more digits in this value, so we must make sure the 11781 // continuation bit is marked. 11782 digit |= VLQ_CONTINUATION_BIT; 11783 } 11784 encoded += base64.encode(digit); 11785 } while (vlq > 0); 11786 11787 return encoded; 11788 }; 11789 11790 /** 11791 * Decodes the next base 64 VLQ value from the given string and returns the 11792 * value and the rest of the string via the out parameter. 11793 */ 11794 exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { 11795 var strLen = aStr.length; 11796 var result = 0; 11797 var shift = 0; 11798 var continuation, digit; 11799 11800 do { 11801 if (aIndex >= strLen) { 11802 throw new Error("Expected more digits in base 64 VLQ value."); 11803 } 11804 11805 digit = base64.decode(aStr.charCodeAt(aIndex++)); 11806 if (digit === -1) { 11807 throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1)); 11808 } 11809 11810 continuation = !!(digit & VLQ_CONTINUATION_BIT); 11811 digit &= VLQ_BASE_MASK; 11812 result = result + (digit << shift); 11813 shift += VLQ_BASE_SHIFT; 11814 } while (continuation); 11815 11816 aOutParam.value = fromVLQSigned(result); 11817 aOutParam.rest = aIndex; 11818 }; 11819 11820 11821/***/ }, 11822/* 3 */
vendor: 4,213 bytes, lines 11823-11990
11823/***/ function(module, exports) { 11824 11825 /* -*- Mode: js; js-indent-level: 2; -*- */ 11826 /* 11827 * Copyright 2011 Mozilla Foundation and contributors 11828 * Licensed under the New BSD license. See LICENSE or: 11829 * http://opensource.org/licenses/BSD-3-Clause 11830 */ 11831 11832 var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); 11833 11834 /** 11835 * Encode an integer in the range of 0 to 63 to a single base 64 digit. 11836 */ 11837 exports.encode = function (number) { 11838 if (0 <= number && number < intToCharMap.length) { 11839 return intToCharMap[number]; 11840 } 11841 throw new TypeError("Must be between 0 and 63: " + number); 11842 }; 11843 11844 /** 11845 * Decode a single base 64 character code digit to an integer. Returns -1 on 11846 * failure. 11847 */ 11848 exports.decode = function (charCode) { 11849 var bigA = 65; // 'A' 11850 var bigZ = 90; // 'Z' 11851 11852 var littleA = 97; // 'a' 11853 var littleZ = 122; // 'z' 11854 11855 var zero = 48; // '0' 11856 var nine = 57; // '9' 11857 11858 var plus = 43; // '+' 11859 var slash = 47; // '/' 11860 11861 var littleOffset = 26; 11862 var numberOffset = 52; 11863 11864 // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ 11865 if (bigA <= charCode && charCode <= bigZ) { 11866 return (charCode - bigA); 11867 } 11868 11869 // 26 - 51: abcdefghijklmnopqrstuvwxyz 11870 if (littleA <= charCode && charCode <= littleZ) { 11871 return (charCode - littleA + littleOffset); 11872 } 11873 11874 // 52 - 61: 0123456789 11875 if (zero <= charCode && charCode <= nine) { 11876 return (charCode - zero + numberOffset); 11877 } 11878 11879 // 62: + 11880 if (charCode == plus) { 11881 return 62; 11882 } 11883 11884 // 63: / 11885 if (charCode == slash) { 11886 return 63; 11887 } 11888 11889 // Invalid base64 digit. 11890 return -1; 11891 }; 11892 11893 11894/***/ }, 11895/* 4 */ 11896/***/ function(module, exports) { 11897 11898 /* -*- Mode: js; js-indent-level: 2; -*- */ 11899 /* 11900 * Copyright 2011 Mozilla Foundation and contributors 11901 * Licensed under the New BSD license. See LICENSE or: 11902 * http://opensource.org/licenses/BSD-3-Clause 11903 */ 11904 11905 /** 11906 * This is a helper function for getting values from parameter/options 11907 * objects. 11908 * 11909 * @param args The object we are extracting values from 11910 * @param name The name of the property we are getting. 11911 * @param defaultValue An optional value to return if the property is missing 11912 * from the object. If this is not specified and the property is missing, an 11913 * error will be thrown. 11914 */ 11915 function getArg(aArgs, aName, aDefaultValue) { 11916 if (aName in aArgs) { 11917 return aArgs[aName]; 11918 } else if (arguments.length === 3) { 11919 return aDefaultValue; 11920 } else { 11921 throw new Error('"' + aName + '" is a required argument.'); 11922 } 11923 } 11924 exports.getArg = getArg; 11925 11926 var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/; 11927 var dataUrlRegexp = /^data:.+\,.+$/; 11928 11929 function urlParse(aUrl) { 11930 var match = aUrl.match(urlRegexp); 11931 if (!match) { 11932 return null; 11933 } 11934 return { 11935 scheme: match[1], 11936 auth: match[2], 11937 host: match[3], 11938 port: match[4], 11939 path: match[5] 11940 }; 11941 } 11942 exports.urlParse = urlParse; 11943 11944 function urlGenerate(aParsedUrl) { 11945 var url = ''; 11946 if (aParsedUrl.scheme) { 11947 url += aParsedUrl.scheme + ':'; 11948 } 11949 url += '//'; 11950 if (aParsedUrl.auth) { 11951 url += aParsedUrl.auth + '@'; 11952 } 11953 if (aParsedUrl.host) { 11954 url += aParsedUrl.host; 11955 } 11956 if (aParsedUrl.port) { 11957 url += ":" + aParsedUrl.port 11958 } 11959 if (aParsedUrl.path) { 11960 url += aParsedUrl.path; 11961 } 11962 return url; 11963 } 11964 exports.urlGenerate = urlGenerate; 11965 11966 /** 11967 * Normalizes a path, or the path portion of a URL: 11968 * 11969 * - Replaces consequtive slashes with one slash. 11970 * - Removes unnecessary '.' parts. 11971 * - Removes unnecessary '<dir>/..' parts. 11972 * 11973 * Based on code in the Node.js 'path' core module. 11974 * 11975 * @param aPath The path or url to normalize. 11976 */ 11977 function normalize(aPath) { 11978 var path = aPath; 11979 var url = urlParse(aPath); 11980 if (url) { 11981 if (!url.path) { 11982 return aPath; 11983 } 11984 path = url.path; 11985 } 11986 var isAbsolute = exports.isAbsolute(path); 11987 11988 var parts = path.split(/\/+/); 11989 for (var part, up = 0, i = parts.length - 1; i >= 0; i--) { 11990 part = parts[i];
vendor: 4,898 bytes, lines 11991-12172
11991 if (part === '.') { 11992 parts.splice(i, 1); 11993 } else if (part === '..') { 11994 up++; 11995 } else if (up > 0) { 11996 if (part === '') { 11997 // The first part is blank if the path is absolute. Trying to go 11998 // above the root is a no-op. Therefore we can remove all '..' parts 11999 // directly after the root. 12000 parts.splice(i + 1, up); 12001 up = 0; 12002 } else { 12003 parts.splice(i, 2); 12004 up--; 12005 } 12006 } 12007 } 12008 path = parts.join('/'); 12009 12010 if (path === '') { 12011 path = isAbsolute ? '/' : '.'; 12012 } 12013 12014 if (url) { 12015 url.path = path; 12016 return urlGenerate(url); 12017 } 12018 return path; 12019 } 12020 exports.normalize = normalize; 12021 12022 /** 12023 * Joins two paths/URLs. 12024 * 12025 * @param aRoot The root path or URL. 12026 * @param aPath The path or URL to be joined with the root. 12027 * 12028 * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a 12029 * scheme-relative URL: Then the scheme of aRoot, if any, is prepended 12030 * first. 12031 * - Otherwise aPath is a path. If aRoot is a URL, then its path portion 12032 * is updated with the result and aRoot is returned. Otherwise the result 12033 * is returned. 12034 * - If aPath is absolute, the result is aPath. 12035 * - Otherwise the two paths are joined with a slash. 12036 * - Joining for example 'http://' and 'www.example.com' is also supported. 12037 */ 12038 function join(aRoot, aPath) { 12039 if (aRoot === "") { 12040 aRoot = "."; 12041 } 12042 if (aPath === "") { 12043 aPath = "."; 12044 } 12045 var aPathUrl = urlParse(aPath); 12046 var aRootUrl = urlParse(aRoot); 12047 if (aRootUrl) { 12048 aRoot = aRootUrl.path || '/'; 12049 } 12050 12051 // `join(foo, '//www.example.org')` 12052 if (aPathUrl && !aPathUrl.scheme) { 12053 if (aRootUrl) { 12054 aPathUrl.scheme = aRootUrl.scheme; 12055 } 12056 return urlGenerate(aPathUrl); 12057 } 12058 12059 if (aPathUrl || aPath.match(dataUrlRegexp)) { 12060 return aPath; 12061 } 12062 12063 // `join('http://', 'www.example.com')` 12064 if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { 12065 aRootUrl.host = aPath; 12066 return urlGenerate(aRootUrl); 12067 } 12068 12069 var joined = aPath.charAt(0) === '/' 12070 ? aPath 12071 : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath); 12072 12073 if (aRootUrl) { 12074 aRootUrl.path = joined; 12075 return urlGenerate(aRootUrl); 12076 } 12077 return joined; 12078 } 12079 exports.join = join; 12080 12081 exports.isAbsolute = function (aPath) { 12082 return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp); 12083 }; 12084 12085 /** 12086 * Make a path relative to a URL or another path. 12087 * 12088 * @param aRoot The root path or URL. 12089 * @param aPath The path or URL to be made relative to aRoot. 12090 */ 12091 function relative(aRoot, aPath) { 12092 if (aRoot === "") { 12093 aRoot = "."; 12094 } 12095 12096 aRoot = aRoot.replace(/\/$/, ''); 12097 12098 // It is possible for the path to be above the root. In this case, simply 12099 // checking whether the root is a prefix of the path won't work. Instead, we 12100 // need to remove components from the root one by one, until either we find 12101 // a prefix that fits, or we run out of components to remove. 12102 var level = 0; 12103 while (aPath.indexOf(aRoot + '/') !== 0) { 12104 var index = aRoot.lastIndexOf("/"); 12105 if (index < 0) { 12106 return aPath; 12107 } 12108 12109 // If the only part of the root that is left is the scheme (i.e. http://, 12110 // file:///, etc.), one or more slashes (/), or simply nothing at all, we 12111 // have exhausted all components, so the path is not relative to the root. 12112 aRoot = aRoot.slice(0, index); 12113 if (aRoot.match(/^([^\/]+:\/)?\/*$/)) { 12114 return aPath; 12115 } 12116 12117 ++level; 12118 } 12119 12120 // Make sure we add a "../" for each component we removed from the root. 12121 return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1); 12122 } 12123 exports.relative = relative; 12124 12125 var supportsNullProto = (function () { 12126 var obj = Object.create(null); 12127 return !('__proto__' in obj); 12128 }()); 12129 12130 function identity (s) { 12131 return s; 12132 } 12133 12134 /** 12135 * Because behavior goes wacky when you set `__proto__` on objects, we 12136 * have to prefix all the strings in our set with an arbitrary character. 12137 * 12138 * See https://github.com/mozilla/source-map/pull/31 and 12139 * https://github.com/mozilla/source-map/issues/30 12140 * 12141 * @param String aStr 12142 */ 12143 function toSetString(aStr) { 12144 if (isProtoString(aStr)) { 12145 return '$' + aStr; 12146 } 12147 12148 return aStr; 12149 } 12150 exports.toSetString = supportsNullProto ? identity : toSetString; 12151 12152 function fromSetString(aStr) { 12153 if (isProtoString(aStr)) { 12154 return aStr.slice(1); 12155 } 12156 12157 return aStr; 12158 } 12159 exports.fromSetString = supportsNullProto ? identity : fromSetString; 12160 12161 function isProtoString(s) { 12162 if (!s) { 12163 return false; 12164 } 12165 12166 var length = s.length; 12167 12168 if (length < 9 /* "__proto__".length */) { 12169 return false; 12170 } 12171 12172 if (s.charCodeAt(length - 1) !== 95 /* '_' */ ||
vendor: 6,429 bytes, lines 12173-12408
12173 s.charCodeAt(length - 2) !== 95 /* '_' */ || 12174 s.charCodeAt(length - 3) !== 111 /* 'o' */ || 12175 s.charCodeAt(length - 4) !== 116 /* 't' */ || 12176 s.charCodeAt(length - 5) !== 111 /* 'o' */ || 12177 s.charCodeAt(length - 6) !== 114 /* 'r' */ || 12178 s.charCodeAt(length - 7) !== 112 /* 'p' */ || 12179 s.charCodeAt(length - 8) !== 95 /* '_' */ || 12180 s.charCodeAt(length - 9) !== 95 /* '_' */) { 12181 return false; 12182 } 12183 12184 for (var i = length - 10; i >= 0; i--) { 12185 if (s.charCodeAt(i) !== 36 /* '$' */) { 12186 return false; 12187 } 12188 } 12189 12190 return true; 12191 } 12192 12193 /** 12194 * Comparator between two mappings where the original positions are compared. 12195 * 12196 * Optionally pass in `true` as `onlyCompareGenerated` to consider two 12197 * mappings with the same original source/line/column, but different generated 12198 * line and column the same. Useful when searching for a mapping with a 12199 * stubbed out mapping. 12200 */ 12201 function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { 12202 var cmp = mappingA.source - mappingB.source; 12203 if (cmp !== 0) { 12204 return cmp; 12205 } 12206 12207 cmp = mappingA.originalLine - mappingB.originalLine; 12208 if (cmp !== 0) { 12209 return cmp; 12210 } 12211 12212 cmp = mappingA.originalColumn - mappingB.originalColumn; 12213 if (cmp !== 0 || onlyCompareOriginal) { 12214 return cmp; 12215 } 12216 12217 cmp = mappingA.generatedColumn - mappingB.generatedColumn; 12218 if (cmp !== 0) { 12219 return cmp; 12220 } 12221 12222 cmp = mappingA.generatedLine - mappingB.generatedLine; 12223 if (cmp !== 0) { 12224 return cmp; 12225 } 12226 12227 return mappingA.name - mappingB.name; 12228 } 12229 exports.compareByOriginalPositions = compareByOriginalPositions; 12230 12231 /** 12232 * Comparator between two mappings with deflated source and name indices where 12233 * the generated positions are compared. 12234 * 12235 * Optionally pass in `true` as `onlyCompareGenerated` to consider two 12236 * mappings with the same generated line and column, but different 12237 * source/name/original line and column the same. Useful when searching for a 12238 * mapping with a stubbed out mapping. 12239 */ 12240 function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) { 12241 var cmp = mappingA.generatedLine - mappingB.generatedLine; 12242 if (cmp !== 0) { 12243 return cmp; 12244 } 12245 12246 cmp = mappingA.generatedColumn - mappingB.generatedColumn; 12247 if (cmp !== 0 || onlyCompareGenerated) { 12248 return cmp; 12249 } 12250 12251 cmp = mappingA.source - mappingB.source; 12252 if (cmp !== 0) { 12253 return cmp; 12254 } 12255 12256 cmp = mappingA.originalLine - mappingB.originalLine; 12257 if (cmp !== 0) { 12258 return cmp; 12259 } 12260 12261 cmp = mappingA.originalColumn - mappingB.originalColumn; 12262 if (cmp !== 0) { 12263 return cmp; 12264 } 12265 12266 return mappingA.name - mappingB.name; 12267 } 12268 exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated; 12269 12270 function strcmp(aStr1, aStr2) { 12271 if (aStr1 === aStr2) { 12272 return 0; 12273 } 12274 12275 if (aStr1 > aStr2) { 12276 return 1; 12277 } 12278 12279 return -1; 12280 } 12281 12282 /** 12283 * Comparator between two mappings with inflated source and name strings where 12284 * the generated positions are compared. 12285 */ 12286 function compareByGeneratedPositionsInflated(mappingA, mappingB) { 12287 var cmp = mappingA.generatedLine - mappingB.generatedLine; 12288 if (cmp !== 0) { 12289 return cmp; 12290 } 12291 12292 cmp = mappingA.generatedColumn - mappingB.generatedColumn; 12293 if (cmp !== 0) { 12294 return cmp; 12295 } 12296 12297 cmp = strcmp(mappingA.source, mappingB.source); 12298 if (cmp !== 0) { 12299 return cmp; 12300 } 12301 12302 cmp = mappingA.originalLine - mappingB.originalLine; 12303 if (cmp !== 0) { 12304 return cmp; 12305 } 12306 12307 cmp = mappingA.originalColumn - mappingB.originalColumn; 12308 if (cmp !== 0) { 12309 return cmp; 12310 } 12311 12312 return strcmp(mappingA.name, mappingB.name); 12313 } 12314 exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; 12315 12316 12317/***/ }, 12318/* 5 */ 12319/***/ function(module, exports, __webpack_require__) { 12320 12321 /* -*- Mode: js; js-indent-level: 2; -*- */ 12322 /* 12323 * Copyright 2011 Mozilla Foundation and contributors 12324 * Licensed under the New BSD license. See LICENSE or: 12325 * http://opensource.org/licenses/BSD-3-Clause 12326 */ 12327 12328 var util = __webpack_require__(4); 12329 var has = Object.prototype.hasOwnProperty; 12330 12331 /** 12332 * A data structure which is a combination of an array and a set. Adding a new 12333 * member is O(1), testing for membership is O(1), and finding the index of an 12334 * element is O(1). Removing elements from the set is not supported. Only 12335 * strings are supported for membership. 12336 */ 12337 function ArraySet() { 12338 this._array = []; 12339 this._set = Object.create(null); 12340 } 12341 12342 /** 12343 * Static method for creating ArraySet instances from an existing array. 12344 */ 12345 ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) { 12346 var set = new ArraySet(); 12347 for (var i = 0, len = aArray.length; i < len; i++) { 12348 set.add(aArray[i], aAllowDuplicates); 12349 } 12350 return set; 12351 }; 12352 12353 /** 12354 * Return how many unique items are in this ArraySet. If duplicates have been 12355 * added, than those do not count towards the size. 12356 * 12357 * @returns Number 12358 */ 12359 ArraySet.prototype.size = function ArraySet_size() { 12360 return Object.getOwnPropertyNames(this._set).length; 12361 }; 12362 12363 /** 12364 * Add the given string to this set. 12365 * 12366 * @param String aStr 12367 */ 12368 ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) { 12369 var sStr = util.toSetString(aStr); 12370 var isDuplicate = has.call(this._set, sStr); 12371 var idx = this._array.length; 12372 if (!isDuplicate || aAllowDuplicates) { 12373 this._array.push(aStr); 12374 } 12375 if (!isDuplicate) { 12376 this._set[sStr] = idx; 12377 } 12378 }; 12379 12380 /** 12381 * Is the given string a member of this set? 12382 * 12383 * @param String aStr 12384 */ 12385 ArraySet.prototype.has = function ArraySet_has(aStr) { 12386 var sStr = util.toSetString(aStr); 12387 return has.call(this._set, sStr); 12388 }; 12389 12390 /** 12391 * What is the index of the given string in the array? 12392 * 12393 * @param String aStr 12394 */ 12395 ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) { 12396 var sStr = util.toSetString(aStr); 12397 if (has.call(this._set, sStr)) { 12398 return this._set[sStr]; 12399 } 12400 throw new Error('"' + aStr + '" is not in the set.'); 12401 }; 12402 12403 /** 12404 * What is the element at the given index? 12405 * 12406 * @param Number aIdx 12407 */ 12408 ArraySet.prototype.at = function ArraySet_at(aIdx) {
vendor: 5,992 bytes, lines 12409-12586
12409 if (aIdx >= 0 && aIdx < this._array.length) { 12410 return this._array[aIdx]; 12411 } 12412 throw new Error('No element indexed by ' + aIdx); 12413 }; 12414 12415 /** 12416 * Returns the array representation of this set (which has the proper indices 12417 * indicated by indexOf). Note that this is a copy of the internal array used 12418 * for storing the members so that no one can mess with internal state. 12419 */ 12420 ArraySet.prototype.toArray = function ArraySet_toArray() { 12421 return this._array.slice(); 12422 }; 12423 12424 exports.ArraySet = ArraySet; 12425 12426 12427/***/ }, 12428/* 6 */ 12429/***/ function(module, exports, __webpack_require__) { 12430 12431 /* -*- Mode: js; js-indent-level: 2; -*- */ 12432 /* 12433 * Copyright 2014 Mozilla Foundation and contributors 12434 * Licensed under the New BSD license. See LICENSE or: 12435 * http://opensource.org/licenses/BSD-3-Clause 12436 */ 12437 12438 var util = __webpack_require__(4); 12439 12440 /** 12441 * Determine whether mappingB is after mappingA with respect to generated 12442 * position. 12443 */ 12444 function generatedPositionAfter(mappingA, mappingB) { 12445 // Optimized for most common case 12446 var lineA = mappingA.generatedLine; 12447 var lineB = mappingB.generatedLine; 12448 var columnA = mappingA.generatedColumn; 12449 var columnB = mappingB.generatedColumn; 12450 return lineB > lineA || lineB == lineA && columnB >= columnA || 12451 util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0; 12452 } 12453 12454 /** 12455 * A data structure to provide a sorted view of accumulated mappings in a 12456 * performance conscious manner. It trades a neglibable overhead in general 12457 * case for a large speedup in case of mappings being added in order. 12458 */ 12459 function MappingList() { 12460 this._array = []; 12461 this._sorted = true; 12462 // Serves as infimum 12463 this._last = {generatedLine: -1, generatedColumn: 0}; 12464 } 12465 12466 /** 12467 * Iterate through internal items. This method takes the same arguments that 12468 * `Array.prototype.forEach` takes. 12469 * 12470 * NOTE: The order of the mappings is NOT guaranteed. 12471 */ 12472 MappingList.prototype.unsortedForEach = 12473 function MappingList_forEach(aCallback, aThisArg) { 12474 this._array.forEach(aCallback, aThisArg); 12475 }; 12476 12477 /** 12478 * Add the given source mapping. 12479 * 12480 * @param Object aMapping 12481 */ 12482 MappingList.prototype.add = function MappingList_add(aMapping) { 12483 if (generatedPositionAfter(this._last, aMapping)) { 12484 this._last = aMapping; 12485 this._array.push(aMapping); 12486 } else { 12487 this._sorted = false; 12488 this._array.push(aMapping); 12489 } 12490 }; 12491 12492 /** 12493 * Returns the flat, sorted array of mappings. The mappings are sorted by 12494 * generated position. 12495 * 12496 * WARNING: This method returns internal data without copying, for 12497 * performance. The return value must NOT be mutated, and should be treated as 12498 * an immutable borrow. If you want to take ownership, you must make your own 12499 * copy. 12500 */ 12501 MappingList.prototype.toArray = function MappingList_toArray() { 12502 if (!this._sorted) { 12503 this._array.sort(util.compareByGeneratedPositionsInflated); 12504 this._sorted = true; 12505 } 12506 return this._array; 12507 }; 12508 12509 exports.MappingList = MappingList; 12510 12511 12512/***/ }, 12513/* 7 */ 12514/***/ function(module, exports, __webpack_require__) { 12515 12516 /* -*- Mode: js; js-indent-level: 2; -*- */ 12517 /* 12518 * Copyright 2011 Mozilla Foundation and contributors 12519 * Licensed under the New BSD license. See LICENSE or: 12520 * http://opensource.org/licenses/BSD-3-Clause 12521 */ 12522 12523 var util = __webpack_require__(4); 12524 var binarySearch = __webpack_require__(8); 12525 var ArraySet = __webpack_require__(5).ArraySet; 12526 var base64VLQ = __webpack_require__(2); 12527 var quickSort = __webpack_require__(9).quickSort; 12528 12529 function SourceMapConsumer(aSourceMap) { 12530 var sourceMap = aSourceMap; 12531 if (typeof aSourceMap === 'string') { 12532 sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); 12533 } 12534 12535 return sourceMap.sections != null 12536 ? new IndexedSourceMapConsumer(sourceMap) 12537 : new BasicSourceMapConsumer(sourceMap); 12538 } 12539 12540 SourceMapConsumer.fromSourceMap = function(aSourceMap) { 12541 return BasicSourceMapConsumer.fromSourceMap(aSourceMap); 12542 } 12543 12544 /** 12545 * The version of the source mapping spec that we are consuming. 12546 */ 12547 SourceMapConsumer.prototype._version = 3; 12548 12549 // `__generatedMappings` and `__originalMappings` are arrays that hold the 12550 // parsed mapping coordinates from the source map's "mappings" attribute. They 12551 // are lazily instantiated, accessed via the `_generatedMappings` and 12552 // `_originalMappings` getters respectively, and we only parse the mappings 12553 // and create these arrays once queried for a source location. We jump through 12554 // these hoops because there can be many thousands of mappings, and parsing 12555 // them is expensive, so we only want to do it if we must. 12556 // 12557 // Each object in the arrays is of the form: 12558 // 12559 // { 12560 // generatedLine: The line number in the generated code, 12561 // generatedColumn: The column number in the generated code, 12562 // source: The path to the original source file that generated this 12563 // chunk of code, 12564 // originalLine: The line number in the original source that 12565 // corresponds to this chunk of generated code, 12566 // originalColumn: The column number in the original source that 12567 // corresponds to this chunk of generated code, 12568 // name: The name of the original symbol which generated this chunk of 12569 // code. 12570 // } 12571 // 12572 // All properties except for `generatedLine` and `generatedColumn` can be 12573 // `null`. 12574 // 12575 // `_generatedMappings` is ordered by the generated positions. 12576 // 12577 // `_originalMappings` is ordered by the original positions. 12578 12579 SourceMapConsumer.prototype.__generatedMappings = null; 12580 Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', { 12581 get: function () { 12582 if (!this.__generatedMappings) { 12583 this._parseMappings(this._mappings, this.sourceRoot); 12584 } 12585 12586 return this.__generatedMappings;
12587 } 12588 }); 12589 12590 SourceMapConsumer.prototype.__originalMappings = null; 12591 Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', { 12592 get: function () { 12593 if (!this.__originalMappings) { 12594 this._parseMappings(this._mappings, this.sourceRoot); 12595 } 12596 12597 return this.__originalMappings; 12598 } 12599 }); 12600 12601 SourceMapConsumer.prototype._charIsMappingSeparator = 12602 function SourceMapConsumer_charIsMappingSeparator(aStr, index) { 12603 var c = aStr.charAt(index); 12604 return c === ";" || c === ","; 12605 }; 12606 12607 /** 12608 * Parse the mappings in a string in to a data structure which we can easily 12609 * query (the ordered arrays in the `this.__generatedMappings` and 12610 * `this.__originalMappings` properties). 12611 */ 12612 SourceMapConsumer.prototype._parseMappings = 12613 function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { 12614 throw new Error("Subclasses must implement _parseMappings"); 12615 }; 12616 12617 SourceMapConsumer.GENERATED_ORDER = 1; 12618 SourceMapConsumer.ORIGINAL_ORDER = 2; 12619 12620 SourceMapConsumer.GREATEST_LOWER_BOUND = 1; 12621 SourceMapConsumer.LEAST_UPPER_BOUND = 2; 12622 12623 /** 12624 * Iterate over each mapping between an original source/line/column and a 12625 * generated line/column in this source map. 12626 * 12627 * @param Function aCallback 12628 * The function that is called with each mapping. 12629 * @param Object aContext 12630 * Optional. If specified, this object will be the value of `this` every 12631 * time that `aCallback` is called. 12632 * @param aOrder 12633 * Either `SourceMapConsumer.GENERATED_ORDER` or 12634 * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to 12635 * iterate over the mappings sorted by the generated file's line/column 12636 * order or the original's source/line/column order, respectively. Defaults to 12637 * `SourceMapConsumer.GENERATED_ORDER`. 12638 */ 12639 SourceMapConsumer.prototype.eachMapping = 12640 function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { 12641 var context = aContext || null; 12642 var order = aOrder || SourceMapConsumer.GENERATED_ORDER; 12643 12644 var mappings;
vendor: 9,516 bytes, lines 12645-12868
12645 switch (order) { 12646 case SourceMapConsumer.GENERATED_ORDER: 12647 mappings = this._generatedMappings; 12648 break; 12649 case SourceMapConsumer.ORIGINAL_ORDER: 12650 mappings = this._originalMappings; 12651 break; 12652 default: 12653 throw new Error("Unknown order of iteration."); 12654 } 12655 12656 var sourceRoot = this.sourceRoot; 12657 mappings.map(function (mapping) { 12658 var source = mapping.source === null ? null : this._sources.at(mapping.source); 12659 if (source != null && sourceRoot != null) { 12660 source = util.join(sourceRoot, source); 12661 } 12662 return { 12663 source: source, 12664 generatedLine: mapping.generatedLine, 12665 generatedColumn: mapping.generatedColumn, 12666 originalLine: mapping.originalLine, 12667 originalColumn: mapping.originalColumn, 12668 name: mapping.name === null ? null : this._names.at(mapping.name) 12669 }; 12670 }, this).forEach(aCallback, context); 12671 }; 12672 12673 /** 12674 * Returns all generated line and column information for the original source, 12675 * line, and column provided. If no column is provided, returns all mappings 12676 * corresponding to a either the line we are searching for or the next 12677 * closest line that has any mappings. Otherwise, returns all mappings 12678 * corresponding to the given line and either the column we are searching for 12679 * or the next closest column that has any offsets. 12680 * 12681 * The only argument is an object with the following properties: 12682 * 12683 * - source: The filename of the original source. 12684 * - line: The line number in the original source. 12685 * - column: Optional. the column number in the original source. 12686 * 12687 * and an array of objects is returned, each with the following properties: 12688 * 12689 * - line: The line number in the generated source, or null. 12690 * - column: The column number in the generated source, or null. 12691 */ 12692 SourceMapConsumer.prototype.allGeneratedPositionsFor = 12693 function SourceMapConsumer_allGeneratedPositionsFor(aArgs) { 12694 var line = util.getArg(aArgs, 'line'); 12695 12696 // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping 12697 // returns the index of the closest mapping less than the needle. By 12698 // setting needle.originalColumn to 0, we thus find the last mapping for 12699 // the given line, provided such a mapping exists. 12700 var needle = { 12701 source: util.getArg(aArgs, 'source'), 12702 originalLine: line, 12703 originalColumn: util.getArg(aArgs, 'column', 0) 12704 }; 12705 12706 if (this.sourceRoot != null) { 12707 needle.source = util.relative(this.sourceRoot, needle.source); 12708 } 12709 if (!this._sources.has(needle.source)) { 12710 return []; 12711 } 12712 needle.source = this._sources.indexOf(needle.source); 12713 12714 var mappings = []; 12715 12716 var index = this._findMapping(needle, 12717 this._originalMappings, 12718 "originalLine", 12719 "originalColumn", 12720 util.compareByOriginalPositions, 12721 binarySearch.LEAST_UPPER_BOUND); 12722 if (index >= 0) { 12723 var mapping = this._originalMappings[index]; 12724 12725 if (aArgs.column === undefined) { 12726 var originalLine = mapping.originalLine; 12727 12728 // Iterate until either we run out of mappings, or we run into 12729 // a mapping for a different line than the one we found. Since 12730 // mappings are sorted, this is guaranteed to find all mappings for 12731 // the line we found. 12732 while (mapping && mapping.originalLine === originalLine) { 12733 mappings.push({ 12734 line: util.getArg(mapping, 'generatedLine', null), 12735 column: util.getArg(mapping, 'generatedColumn', null), 12736 lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) 12737 }); 12738 12739 mapping = this._originalMappings[++index]; 12740 } 12741 } else { 12742 var originalColumn = mapping.originalColumn; 12743 12744 // Iterate until either we run out of mappings, or we run into 12745 // a mapping for a different line than the one we were searching for. 12746 // Since mappings are sorted, this is guaranteed to find all mappings for 12747 // the line we are searching for. 12748 while (mapping && 12749 mapping.originalLine === line && 12750 mapping.originalColumn == originalColumn) { 12751 mappings.push({ 12752 line: util.getArg(mapping, 'generatedLine', null), 12753 column: util.getArg(mapping, 'generatedColumn', null), 12754 lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) 12755 }); 12756 12757 mapping = this._originalMappings[++index]; 12758 } 12759 } 12760 } 12761 12762 return mappings; 12763 }; 12764 12765 exports.SourceMapConsumer = SourceMapConsumer; 12766 12767 /** 12768 * A BasicSourceMapConsumer instance represents a parsed source map which we can 12769 * query for information about the original file positions by giving it a file 12770 * position in the generated source. 12771 * 12772 * The only parameter is the raw source map (either as a JSON string, or 12773 * already parsed to an object). According to the spec, source maps have the 12774 * following attributes: 12775 * 12776 * - version: Which version of the source map spec this map is following. 12777 * - sources: An array of URLs to the original source files. 12778 * - names: An array of identifiers which can be referrenced by individual mappings. 12779 * - sourceRoot: Optional. The URL root from which all sources are relative. 12780 * - sourcesContent: Optional. An array of contents of the original source files. 12781 * - mappings: A string of base64 VLQs which contain the actual mappings. 12782 * - file: Optional. The generated file this source map is associated with. 12783 * 12784 * Here is an example source map, taken from the source map spec[0]: 12785 * 12786 * { 12787 * version : 3, 12788 * file: "out.js", 12789 * sourceRoot : "", 12790 * sources: ["foo.js", "bar.js"], 12791 * names: ["src", "maps", "are", "fun"], 12792 * mappings: "AA,AB;;ABCDE;" 12793 * } 12794 * 12795 * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1# 12796 */ 12797 function BasicSourceMapConsumer(aSourceMap) { 12798 var sourceMap = aSourceMap; 12799 if (typeof aSourceMap === 'string') { 12800 sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); 12801 } 12802 12803 var version = util.getArg(sourceMap, 'version'); 12804 var sources = util.getArg(sourceMap, 'sources'); 12805 // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which 12806 // requires the array) to play nice here. 12807 var names = util.getArg(sourceMap, 'names', []); 12808 var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null); 12809 var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null); 12810 var mappings = util.getArg(sourceMap, 'mappings'); 12811 var file = util.getArg(sourceMap, 'file', null); 12812 12813 // Once again, Sass deviates from the spec and supplies the version as a 12814 // string rather than a number, so we use loose equality checking here. 12815 if (version != this._version) { 12816 throw new Error('Unsupported version: ' + version); 12817 } 12818 12819 sources = sources 12820 .map(String) 12821 // Some source maps produce relative source paths like "./foo.js" instead of 12822 // "foo.js". Normalize these first so that future comparisons will succeed. 12823 // See bugzil.la/1090768. 12824 .map(util.normalize) 12825 // Always ensure that absolute sources are internally stored relative to 12826 // the source root, if the source root is absolute. Not doing this would 12827 // be particularly problematic when the source root is a prefix of the 12828 // source (valid, but why??). See github issue #199 and bugzil.la/1188982. 12829 .map(function (source) { 12830 return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source) 12831 ? util.relative(sourceRoot, source) 12832 : source; 12833 }); 12834 12835 // Pass `true` below to allow duplicate names and sources. While source maps 12836 // are intended to be compressed and deduplicated, the TypeScript compiler 12837 // sometimes generates source maps with duplicates in them. See Github issue 12838 // #72 and bugzil.la/889492. 12839 this._names = ArraySet.fromArray(names.map(String), true); 12840 this._sources = ArraySet.fromArray(sources, true); 12841 12842 this.sourceRoot = sourceRoot; 12843 this.sourcesContent = sourcesContent; 12844 this._mappings = mappings; 12845 this.file = file; 12846 } 12847 12848 BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); 12849 BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer; 12850 12851 /** 12852 * Create a BasicSourceMapConsumer from a SourceMapGenerator. 12853 * 12854 * @param SourceMapGenerator aSourceMap 12855 * The source map that will be consumed. 12856 * @returns BasicSourceMapConsumer 12857 */ 12858 BasicSourceMapConsumer.fromSourceMap = 12859 function SourceMapConsumer_fromSourceMap(aSourceMap) { 12860 var smc = Object.create(BasicSourceMapConsumer.prototype); 12861 12862 var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true); 12863 var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true); 12864 smc.sourceRoot = aSourceMap._sourceRoot; 12865 smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(), 12866 smc.sourceRoot); 12867 smc.file = aSourceMap._file; 12868
vendor: 4,610 bytes, lines 12869-13007
12869 // Because we are modifying the entries (by converting string sources and 12870 // names to indices into the sources and names ArraySets), we have to make 12871 // a copy of the entry or else bad things happen. Shared mutable state 12872 // strikes again! See github issue #191. 12873 12874 var generatedMappings = aSourceMap._mappings.toArray().slice(); 12875 var destGeneratedMappings = smc.__generatedMappings = []; 12876 var destOriginalMappings = smc.__originalMappings = []; 12877 12878 for (var i = 0, length = generatedMappings.length; i < length; i++) { 12879 var srcMapping = generatedMappings[i]; 12880 var destMapping = new Mapping; 12881 destMapping.generatedLine = srcMapping.generatedLine; 12882 destMapping.generatedColumn = srcMapping.generatedColumn; 12883 12884 if (srcMapping.source) { 12885 destMapping.source = sources.indexOf(srcMapping.source); 12886 destMapping.originalLine = srcMapping.originalLine; 12887 destMapping.originalColumn = srcMapping.originalColumn; 12888 12889 if (srcMapping.name) { 12890 destMapping.name = names.indexOf(srcMapping.name); 12891 } 12892 12893 destOriginalMappings.push(destMapping); 12894 } 12895 12896 destGeneratedMappings.push(destMapping); 12897 } 12898 12899 quickSort(smc.__originalMappings, util.compareByOriginalPositions); 12900 12901 return smc; 12902 }; 12903 12904 /** 12905 * The version of the source mapping spec that we are consuming. 12906 */ 12907 BasicSourceMapConsumer.prototype._version = 3; 12908 12909 /** 12910 * The list of original sources. 12911 */ 12912 Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', { 12913 get: function () { 12914 return this._sources.toArray().map(function (s) { 12915 return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s; 12916 }, this); 12917 } 12918 }); 12919 12920 /** 12921 * Provide the JIT with a nice shape / hidden class. 12922 */ 12923 function Mapping() { 12924 this.generatedLine = 0; 12925 this.generatedColumn = 0; 12926 this.source = null; 12927 this.originalLine = null; 12928 this.originalColumn = null; 12929 this.name = null; 12930 } 12931 12932 /** 12933 * Parse the mappings in a string in to a data structure which we can easily 12934 * query (the ordered arrays in the `this.__generatedMappings` and 12935 * `this.__originalMappings` properties). 12936 */ 12937 BasicSourceMapConsumer.prototype._parseMappings = 12938 function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { 12939 var generatedLine = 1; 12940 var previousGeneratedColumn = 0; 12941 var previousOriginalLine = 0; 12942 var previousOriginalColumn = 0; 12943 var previousSource = 0; 12944 var previousName = 0; 12945 var length = aStr.length; 12946 var index = 0; 12947 var cachedSegments = {}; 12948 var temp = {}; 12949 var originalMappings = []; 12950 var generatedMappings = []; 12951 var mapping, str, segment, end, value; 12952 12953 while (index < length) { 12954 if (aStr.charAt(index) === ';') { 12955 generatedLine++; 12956 index++; 12957 previousGeneratedColumn = 0; 12958 } 12959 else if (aStr.charAt(index) === ',') { 12960 index++; 12961 } 12962 else { 12963 mapping = new Mapping(); 12964 mapping.generatedLine = generatedLine; 12965 12966 // Because each offset is encoded relative to the previous one, 12967 // many segments often have the same encoding. We can exploit this 12968 // fact by caching the parsed variable length fields of each segment, 12969 // allowing us to avoid a second parse if we encounter the same 12970 // segment again. 12971 for (end = index; end < length; end++) { 12972 if (this._charIsMappingSeparator(aStr, end)) { 12973 break; 12974 } 12975 } 12976 str = aStr.slice(index, end); 12977 12978 segment = cachedSegments[str]; 12979 if (segment) { 12980 index += str.length; 12981 } else { 12982 segment = []; 12983 while (index < end) { 12984 base64VLQ.decode(aStr, index, temp); 12985 value = temp.value; 12986 index = temp.rest; 12987 segment.push(value); 12988 } 12989 12990 if (segment.length === 2) { 12991 throw new Error('Found a source, but no line and column'); 12992 } 12993 12994 if (segment.length === 3) { 12995 throw new Error('Found a source and line, but no column'); 12996 } 12997 12998 cachedSegments[str] = segment; 12999 } 13000 13001 // Generated column. 13002 mapping.generatedColumn = previousGeneratedColumn + segment[0]; 13003 previousGeneratedColumn = mapping.generatedColumn; 13004 13005 if (segment.length > 1) { 13006 // Original source. 13007 mapping.source = previousSource + segment[1];
vendor: 4,285 bytes, lines 13008-13112
13008 previousSource += segment[1]; 13009 13010 // Original line. 13011 mapping.originalLine = previousOriginalLine + segment[2]; 13012 previousOriginalLine = mapping.originalLine; 13013 // Lines are stored 0-based 13014 mapping.originalLine += 1; 13015 13016 // Original column. 13017 mapping.originalColumn = previousOriginalColumn + segment[3]; 13018 previousOriginalColumn = mapping.originalColumn; 13019 13020 if (segment.length > 4) { 13021 // Original name. 13022 mapping.name = previousName + segment[4]; 13023 previousName += segment[4]; 13024 } 13025 } 13026 13027 generatedMappings.push(mapping); 13028 if (typeof mapping.originalLine === 'number') { 13029 originalMappings.push(mapping); 13030 } 13031 } 13032 } 13033 13034 quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated); 13035 this.__generatedMappings = generatedMappings; 13036 13037 quickSort(originalMappings, util.compareByOriginalPositions); 13038 this.__originalMappings = originalMappings; 13039 }; 13040 13041 /** 13042 * Find the mapping that best matches the hypothetical "needle" mapping that 13043 * we are searching for in the given "haystack" of mappings. 13044 */ 13045 BasicSourceMapConsumer.prototype._findMapping = 13046 function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, 13047 aColumnName, aComparator, aBias) { 13048 // To return the position we are searching for, we must first find the 13049 // mapping for the given position and then return the opposite position it 13050 // points to. Because the mappings are sorted, we can use binary search to 13051 // find the best mapping. 13052 13053 if (aNeedle[aLineName] <= 0) { 13054 throw new TypeError('Line must be greater than or equal to 1, got ' 13055 + aNeedle[aLineName]); 13056 } 13057 if (aNeedle[aColumnName] < 0) { 13058 throw new TypeError('Column must be greater than or equal to 0, got ' 13059 + aNeedle[aColumnName]); 13060 } 13061 13062 return binarySearch.search(aNeedle, aMappings, aComparator, aBias); 13063 }; 13064 13065 /** 13066 * Compute the last column for each generated mapping. The last column is 13067 * inclusive. 13068 */ 13069 BasicSourceMapConsumer.prototype.computeColumnSpans = 13070 function SourceMapConsumer_computeColumnSpans() { 13071 for (var index = 0; index < this._generatedMappings.length; ++index) { 13072 var mapping = this._generatedMappings[index]; 13073 13074 // Mappings do not contain a field for the last generated columnt. We 13075 // can come up with an optimistic estimate, however, by assuming that 13076 // mappings are contiguous (i.e. given two consecutive mappings, the 13077 // first mapping ends where the second one starts). 13078 if (index + 1 < this._generatedMappings.length) { 13079 var nextMapping = this._generatedMappings[index + 1]; 13080 13081 if (mapping.generatedLine === nextMapping.generatedLine) { 13082 mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1; 13083 continue; 13084 } 13085 } 13086 13087 // The last mapping for each line spans the entire line. 13088 mapping.lastGeneratedColumn = Infinity; 13089 } 13090 }; 13091 13092 /** 13093 * Returns the original source, line, and column information for the generated 13094 * source's line and column positions provided. The only argument is an object 13095 * with the following properties: 13096 * 13097 * - line: The line number in the generated source. 13098 * - column: The column number in the generated source. 13099 * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or 13100 * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the 13101 * closest element that is smaller than or greater than the one we are 13102 * searching for, respectively, if the exact element cannot be found. 13103 * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. 13104 * 13105 * and an object is returned with the following properties: 13106 * 13107 * - source: The original source file, or null. 13108 * - line: The line number in the original source, or null. 13109 * - column: The column number in the original source, or null. 13110 * - name: The original identifier, or null. 13111 */ 13112 BasicSourceMapConsumer.prototype.originalPositionFor =
vendor: 15,341 bytes, lines 13113-13554
13113 function SourceMapConsumer_originalPositionFor(aArgs) { 13114 var needle = { 13115 generatedLine: util.getArg(aArgs, 'line'), 13116 generatedColumn: util.getArg(aArgs, 'column') 13117 }; 13118 13119 var index = this._findMapping( 13120 needle, 13121 this._generatedMappings, 13122 "generatedLine", 13123 "generatedColumn", 13124 util.compareByGeneratedPositionsDeflated, 13125 util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) 13126 ); 13127 13128 if (index >= 0) { 13129 var mapping = this._generatedMappings[index]; 13130 13131 if (mapping.generatedLine === needle.generatedLine) { 13132 var source = util.getArg(mapping, 'source', null); 13133 if (source !== null) { 13134 source = this._sources.at(source); 13135 if (this.sourceRoot != null) { 13136 source = util.join(this.sourceRoot, source); 13137 } 13138 } 13139 var name = util.getArg(mapping, 'name', null); 13140 if (name !== null) { 13141 name = this._names.at(name); 13142 } 13143 return { 13144 source: source, 13145 line: util.getArg(mapping, 'originalLine', null), 13146 column: util.getArg(mapping, 'originalColumn', null), 13147 name: name 13148 }; 13149 } 13150 } 13151 13152 return { 13153 source: null, 13154 line: null, 13155 column: null, 13156 name: null 13157 }; 13158 }; 13159 13160 /** 13161 * Return true if we have the source content for every source in the source 13162 * map, false otherwise. 13163 */ 13164 BasicSourceMapConsumer.prototype.hasContentsOfAllSources = 13165 function BasicSourceMapConsumer_hasContentsOfAllSources() { 13166 if (!this.sourcesContent) { 13167 return false; 13168 } 13169 return this.sourcesContent.length >= this._sources.size() && 13170 !this.sourcesContent.some(function (sc) { return sc == null; }); 13171 }; 13172 13173 /** 13174 * Returns the original source content. The only argument is the url of the 13175 * original source file. Returns null if no original source content is 13176 * available. 13177 */ 13178 BasicSourceMapConsumer.prototype.sourceContentFor = 13179 function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { 13180 if (!this.sourcesContent) { 13181 return null; 13182 } 13183 13184 if (this.sourceRoot != null) { 13185 aSource = util.relative(this.sourceRoot, aSource); 13186 } 13187 13188 if (this._sources.has(aSource)) { 13189 return this.sourcesContent[this._sources.indexOf(aSource)]; 13190 } 13191 13192 var url; 13193 if (this.sourceRoot != null 13194 && (url = util.urlParse(this.sourceRoot))) { 13195 // XXX: file:// URIs and absolute paths lead to unexpected behavior for 13196 // many users. We can help them out when they expect file:// URIs to 13197 // behave like it would if they were running a local HTTP server. See 13198 // https://bugzilla.mozilla.org/show_bug.cgi?id=885597. 13199 var fileUriAbsPath = aSource.replace(/^file:\/\//, ""); 13200 if (url.scheme == "file" 13201 && this._sources.has(fileUriAbsPath)) { 13202 return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)] 13203 } 13204 13205 if ((!url.path || url.path == "/") 13206 && this._sources.has("/" + aSource)) { 13207 return this.sourcesContent[this._sources.indexOf("/" + aSource)]; 13208 } 13209 } 13210 13211 // This function is used recursively from 13212 // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we 13213 // don't want to throw if we can't find the source - we just want to 13214 // return null, so we provide a flag to exit gracefully. 13215 if (nullOnMissing) { 13216 return null; 13217 } 13218 else { 13219 throw new Error('"' + aSource + '" is not in the SourceMap.'); 13220 } 13221 }; 13222 13223 /** 13224 * Returns the generated line and column information for the original source, 13225 * line, and column positions provided. The only argument is an object with 13226 * the following properties: 13227 * 13228 * - source: The filename of the original source. 13229 * - line: The line number in the original source. 13230 * - column: The column number in the original source. 13231 * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or 13232 * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the 13233 * closest element that is smaller than or greater than the one we are 13234 * searching for, respectively, if the exact element cannot be found. 13235 * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. 13236 * 13237 * and an object is returned with the following properties: 13238 * 13239 * - line: The line number in the generated source, or null. 13240 * - column: The column number in the generated source, or null. 13241 */ 13242 BasicSourceMapConsumer.prototype.generatedPositionFor = 13243 function SourceMapConsumer_generatedPositionFor(aArgs) { 13244 var source = util.getArg(aArgs, 'source'); 13245 if (this.sourceRoot != null) { 13246 source = util.relative(this.sourceRoot, source); 13247 } 13248 if (!this._sources.has(source)) { 13249 return { 13250 line: null, 13251 column: null, 13252 lastColumn: null 13253 }; 13254 } 13255 source = this._sources.indexOf(source); 13256 13257 var needle = { 13258 source: source, 13259 originalLine: util.getArg(aArgs, 'line'), 13260 originalColumn: util.getArg(aArgs, 'column') 13261 }; 13262 13263 var index = this._findMapping( 13264 needle, 13265 this._originalMappings, 13266 "originalLine", 13267 "originalColumn", 13268 util.compareByOriginalPositions, 13269 util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) 13270 ); 13271 13272 if (index >= 0) { 13273 var mapping = this._originalMappings[index]; 13274 13275 if (mapping.source === needle.source) { 13276 return { 13277 line: util.getArg(mapping, 'generatedLine', null), 13278 column: util.getArg(mapping, 'generatedColumn', null), 13279 lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) 13280 }; 13281 } 13282 } 13283 13284 return { 13285 line: null, 13286 column: null, 13287 lastColumn: null 13288 }; 13289 }; 13290 13291 exports.BasicSourceMapConsumer = BasicSourceMapConsumer; 13292 13293 /** 13294 * An IndexedSourceMapConsumer instance represents a parsed source map which 13295 * we can query for information. It differs from BasicSourceMapConsumer in 13296 * that it takes "indexed" source maps (i.e. ones with a "sections" field) as 13297 * input. 13298 * 13299 * The only parameter is a raw source map (either as a JSON string, or already 13300 * parsed to an object). According to the spec for indexed source maps, they 13301 * have the following attributes: 13302 * 13303 * - version: Which version of the source map spec this map is following. 13304 * - file: Optional. The generated file this source map is associated with. 13305 * - sections: A list of section definitions. 13306 * 13307 * Each value under the "sections" field has two fields: 13308 * - offset: The offset into the original specified at which this section 13309 * begins to apply, defined as an object with a "line" and "column" 13310 * field. 13311 * - map: A source map definition. This source map could also be indexed, 13312 * but doesn't have to be. 13313 * 13314 * Instead of the "map" field, it's also possible to have a "url" field 13315 * specifying a URL to retrieve a source map from, but that's currently 13316 * unsupported. 13317 * 13318 * Here's an example source map, taken from the source map spec[0], but 13319 * modified to omit a section which uses the "url" field. 13320 * 13321 * { 13322 * version : 3, 13323 * file: "app.js", 13324 * sections: [{ 13325 * offset: {line:100, column:10}, 13326 * map: { 13327 * version : 3, 13328 * file: "section.js", 13329 * sources: ["foo.js", "bar.js"], 13330 * names: ["src", "maps", "are", "fun"], 13331 * mappings: "AAAA,E;;ABCDE;" 13332 * } 13333 * }], 13334 * } 13335 * 13336 * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt 13337 */ 13338 function IndexedSourceMapConsumer(aSourceMap) { 13339 var sourceMap = aSourceMap; 13340 if (typeof aSourceMap === 'string') { 13341 sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); 13342 } 13343 13344 var version = util.getArg(sourceMap, 'version'); 13345 var sections = util.getArg(sourceMap, 'sections'); 13346 13347 if (version != this._version) { 13348 throw new Error('Unsupported version: ' + version); 13349 } 13350 13351 this._sources = new ArraySet(); 13352 this._names = new ArraySet(); 13353 13354 var lastOffset = { 13355 line: -1, 13356 column: 0 13357 }; 13358 this._sections = sections.map(function (s) { 13359 if (s.url) { 13360 // The url field will require support for asynchronicity. 13361 // See https://github.com/mozilla/source-map/issues/16 13362 throw new Error('Support for url field in sections not implemented.'); 13363 } 13364 var offset = util.getArg(s, 'offset'); 13365 var offsetLine = util.getArg(offset, 'line'); 13366 var offsetColumn = util.getArg(offset, 'column'); 13367 13368 if (offsetLine < lastOffset.line || 13369 (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) { 13370 throw new Error('Section offsets must be ordered and non-overlapping.'); 13371 } 13372 lastOffset = offset; 13373 13374 return { 13375 generatedOffset: { 13376 // The offset fields are 0-based, but we use 1-based indices when 13377 // encoding/decoding from VLQ. 13378 generatedLine: offsetLine + 1, 13379 generatedColumn: offsetColumn + 1 13380 }, 13381 consumer: new SourceMapConsumer(util.getArg(s, 'map')) 13382 } 13383 }); 13384 } 13385 13386 IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); 13387 IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer; 13388 13389 /** 13390 * The version of the source mapping spec that we are consuming. 13391 */ 13392 IndexedSourceMapConsumer.prototype._version = 3; 13393 13394 /** 13395 * The list of original sources. 13396 */ 13397 Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', { 13398 get: function () { 13399 var sources = []; 13400 for (var i = 0; i < this._sections.length; i++) { 13401 for (var j = 0; j < this._sections[i].consumer.sources.length; j++) { 13402 sources.push(this._sections[i].consumer.sources[j]); 13403 } 13404 } 13405 return sources; 13406 } 13407 }); 13408 13409 /** 13410 * Returns the original source, line, and column information for the generated 13411 * source's line and column positions provided. The only argument is an object 13412 * with the following properties: 13413 * 13414 * - line: The line number in the generated source. 13415 * - column: The column number in the generated source. 13416 * 13417 * and an object is returned with the following properties: 13418 * 13419 * - source: The original source file, or null. 13420 * - line: The line number in the original source, or null. 13421 * - column: The column number in the original source, or null. 13422 * - name: The original identifier, or null. 13423 */ 13424 IndexedSourceMapConsumer.prototype.originalPositionFor = 13425 function IndexedSourceMapConsumer_originalPositionFor(aArgs) { 13426 var needle = { 13427 generatedLine: util.getArg(aArgs, 'line'), 13428 generatedColumn: util.getArg(aArgs, 'column') 13429 }; 13430 13431 // Find the section containing the generated position we're trying to map 13432 // to an original position. 13433 var sectionIndex = binarySearch.search(needle, this._sections, 13434 function(needle, section) { 13435 var cmp = needle.generatedLine - section.generatedOffset.generatedLine; 13436 if (cmp) { 13437 return cmp; 13438 } 13439 13440 return (needle.generatedColumn - 13441 section.generatedOffset.generatedColumn); 13442 }); 13443 var section = this._sections[sectionIndex]; 13444 13445 if (!section) { 13446 return { 13447 source: null, 13448 line: null, 13449 column: null, 13450 name: null 13451 }; 13452 } 13453 13454 return section.consumer.originalPositionFor({ 13455 line: needle.generatedLine - 13456 (section.generatedOffset.generatedLine - 1), 13457 column: needle.generatedColumn - 13458 (section.generatedOffset.generatedLine === needle.generatedLine 13459 ? section.generatedOffset.generatedColumn - 1 13460 : 0), 13461 bias: aArgs.bias 13462 }); 13463 }; 13464 13465 /** 13466 * Return true if we have the source content for every source in the source 13467 * map, false otherwise. 13468 */ 13469 IndexedSourceMapConsumer.prototype.hasContentsOfAllSources = 13470 function IndexedSourceMapConsumer_hasContentsOfAllSources() { 13471 return this._sections.every(function (s) { 13472 return s.consumer.hasContentsOfAllSources(); 13473 }); 13474 }; 13475 13476 /** 13477 * Returns the original source content. The only argument is the url of the 13478 * original source file. Returns null if no original source content is 13479 * available. 13480 */ 13481 IndexedSourceMapConsumer.prototype.sourceContentFor = 13482 function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { 13483 for (var i = 0; i < this._sections.length; i++) { 13484 var section = this._sections[i]; 13485 13486 var content = section.consumer.sourceContentFor(aSource, true); 13487 if (content) { 13488 return content; 13489 } 13490 } 13491 if (nullOnMissing) { 13492 return null; 13493 } 13494 else { 13495 throw new Error('"' + aSource + '" is not in the SourceMap.'); 13496 } 13497 }; 13498 13499 /** 13500 * Returns the generated line and column information for the original source, 13501 * line, and column positions provided. The only argument is an object with 13502 * the following properties: 13503 * 13504 * - source: The filename of the original source. 13505 * - line: The line number in the original source. 13506 * - column: The column number in the original source. 13507 * 13508 * and an object is returned with the following properties: 13509 * 13510 * - line: The line number in the generated source, or null. 13511 * - column: The column number in the generated source, or null. 13512 */ 13513 IndexedSourceMapConsumer.prototype.generatedPositionFor = 13514 function IndexedSourceMapConsumer_generatedPositionFor(aArgs) { 13515 for (var i = 0; i < this._sections.length; i++) { 13516 var section = this._sections[i]; 13517 13518 // Only consider this section if the requested source is in the list of 13519 // sources of the consumer. 13520 if (section.consumer.sources.indexOf(util.getArg(aArgs, 'source')) === -1) { 13521 continue; 13522 } 13523 var generatedPosition = section.consumer.generatedPositionFor(aArgs); 13524 if (generatedPosition) { 13525 var ret = { 13526 line: generatedPosition.line + 13527 (section.generatedOffset.generatedLine - 1), 13528 column: generatedPosition.column + 13529 (section.generatedOffset.generatedLine === generatedPosition.line 13530 ? section.generatedOffset.generatedColumn - 1 13531 : 0) 13532 }; 13533 return ret; 13534 } 13535 } 13536 13537 return { 13538 line: null, 13539 column: null 13540 }; 13541 }; 13542 13543 /** 13544 * Parse the mappings in a string in to a data structure which we can easily 13545 * query (the ordered arrays in the `this.__generatedMappings` and 13546 * `this.__originalMappings` properties). 13547 */ 13548 IndexedSourceMapConsumer.prototype._parseMappings = 13549 function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) { 13550 this.__generatedMappings = []; 13551 this.__originalMappings = []; 13552 for (var i = 0; i < this._sections.length; i++) { 13553 var section = this._sections[i]; 13554 var sectionMappings = section.consumer._generatedMappings;
vendor: 10,770 bytes, lines 13555-13854
13555 for (var j = 0; j < sectionMappings.length; j++) { 13556 var mapping = sectionMappings[j]; 13557 13558 var source = section.consumer._sources.at(mapping.source); 13559 if (section.consumer.sourceRoot !== null) { 13560 source = util.join(section.consumer.sourceRoot, source); 13561 } 13562 this._sources.add(source); 13563 source = this._sources.indexOf(source); 13564 13565 var name = section.consumer._names.at(mapping.name); 13566 this._names.add(name); 13567 name = this._names.indexOf(name); 13568 13569 // The mappings coming from the consumer for the section have 13570 // generated positions relative to the start of the section, so we 13571 // need to offset them to be relative to the start of the concatenated 13572 // generated file. 13573 var adjustedMapping = { 13574 source: source, 13575 generatedLine: mapping.generatedLine + 13576 (section.generatedOffset.generatedLine - 1), 13577 generatedColumn: mapping.generatedColumn + 13578 (section.generatedOffset.generatedLine === mapping.generatedLine 13579 ? section.generatedOffset.generatedColumn - 1 13580 : 0), 13581 originalLine: mapping.originalLine, 13582 originalColumn: mapping.originalColumn, 13583 name: name 13584 }; 13585 13586 this.__generatedMappings.push(adjustedMapping); 13587 if (typeof adjustedMapping.originalLine === 'number') { 13588 this.__originalMappings.push(adjustedMapping); 13589 } 13590 } 13591 } 13592 13593 quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated); 13594 quickSort(this.__originalMappings, util.compareByOriginalPositions); 13595 }; 13596 13597 exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; 13598 13599 13600/***/ }, 13601/* 8 */ 13602/***/ function(module, exports) { 13603 13604 /* -*- Mode: js; js-indent-level: 2; -*- */ 13605 /* 13606 * Copyright 2011 Mozilla Foundation and contributors 13607 * Licensed under the New BSD license. See LICENSE or: 13608 * http://opensource.org/licenses/BSD-3-Clause 13609 */ 13610 13611 exports.GREATEST_LOWER_BOUND = 1; 13612 exports.LEAST_UPPER_BOUND = 2; 13613 13614 /** 13615 * Recursive implementation of binary search. 13616 * 13617 * @param aLow Indices here and lower do not contain the needle. 13618 * @param aHigh Indices here and higher do not contain the needle. 13619 * @param aNeedle The element being searched for. 13620 * @param aHaystack The non-empty array being searched. 13621 * @param aCompare Function which takes two elements and returns -1, 0, or 1. 13622 * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or 13623 * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the 13624 * closest element that is smaller than or greater than the one we are 13625 * searching for, respectively, if the exact element cannot be found. 13626 */ 13627 function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) { 13628 // This function terminates when one of the following is true: 13629 // 13630 // 1. We find the exact element we are looking for. 13631 // 13632 // 2. We did not find the exact element, but we can return the index of 13633 // the next-closest element. 13634 // 13635 // 3. We did not find the exact element, and there is no next-closest 13636 // element than the one we are searching for, so we return -1. 13637 var mid = Math.floor((aHigh - aLow) / 2) + aLow; 13638 var cmp = aCompare(aNeedle, aHaystack[mid], true); 13639 if (cmp === 0) { 13640 // Found the element we are looking for. 13641 return mid; 13642 } 13643 else if (cmp > 0) { 13644 // Our needle is greater than aHaystack[mid]. 13645 if (aHigh - mid > 1) { 13646 // The element is in the upper half. 13647 return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias); 13648 } 13649 13650 // The exact needle element was not found in this haystack. Determine if 13651 // we are in termination case (3) or (2) and return the appropriate thing. 13652 if (aBias == exports.LEAST_UPPER_BOUND) { 13653 return aHigh < aHaystack.length ? aHigh : -1; 13654 } else { 13655 return mid; 13656 } 13657 } 13658 else { 13659 // Our needle is less than aHaystack[mid]. 13660 if (mid - aLow > 1) { 13661 // The element is in the lower half. 13662 return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias); 13663 } 13664 13665 // we are in termination case (3) or (2) and return the appropriate thing. 13666 if (aBias == exports.LEAST_UPPER_BOUND) { 13667 return mid; 13668 } else { 13669 return aLow < 0 ? -1 : aLow; 13670 } 13671 } 13672 } 13673 13674 /** 13675 * This is an implementation of binary search which will always try and return 13676 * the index of the closest element if there is no exact hit. This is because 13677 * mappings between original and generated line/col pairs are single points, 13678 * and there is an implicit region between each of them, so a miss just means 13679 * that you aren't on the very start of a region. 13680 * 13681 * @param aNeedle The element you are looking for. 13682 * @param aHaystack The array that is being searched. 13683 * @param aCompare A function which takes the needle and an element in the 13684 * array and returns -1, 0, or 1 depending on whether the needle is less 13685 * than, equal to, or greater than the element, respectively. 13686 * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or 13687 * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the 13688 * closest element that is smaller than or greater than the one we are 13689 * searching for, respectively, if the exact element cannot be found. 13690 * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'. 13691 */ 13692 exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { 13693 if (aHaystack.length === 0) { 13694 return -1; 13695 } 13696 13697 var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, 13698 aCompare, aBias || exports.GREATEST_LOWER_BOUND); 13699 if (index < 0) { 13700 return -1; 13701 } 13702 13703 // We have found either the exact element, or the next-closest element than 13704 // the one we are searching for. However, there may be more than one such 13705 // element. Make sure we always return the smallest of these. 13706 while (index - 1 >= 0) { 13707 if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) { 13708 break; 13709 } 13710 --index; 13711 } 13712 13713 return index; 13714 }; 13715 13716 13717/***/ }, 13718/* 9 */ 13719/***/ function(module, exports) { 13720 13721 /* -*- Mode: js; js-indent-level: 2; -*- */ 13722 /* 13723 * Copyright 2011 Mozilla Foundation and contributors 13724 * Licensed under the New BSD license. See LICENSE or: 13725 * http://opensource.org/licenses/BSD-3-Clause 13726 */ 13727 13728 // It turns out that some (most?) JavaScript engines don't self-host 13729 // `Array.prototype.sort`. This makes sense because C++ will likely remain 13730 // faster than JS when doing raw CPU-intensive sorting. However, when using a 13731 // custom comparator function, calling back and forth between the VM's C++ and 13732 // JIT'd JS is rather slow *and* loses JIT type information, resulting in 13733 // worse generated code for the comparator function than would be optimal. In 13734 // fact, when sorting with a comparator, these costs outweigh the benefits of 13735 // sorting in C++. By using our own JS-implemented Quick Sort (below), we get 13736 // a ~3500ms mean speed-up in `bench/bench.html`. 13737 13738 /** 13739 * Swap the elements indexed by `x` and `y` in the array `ary`. 13740 * 13741 * @param {Array} ary 13742 * The array. 13743 * @param {Number} x 13744 * The index of the first item. 13745 * @param {Number} y 13746 * The index of the second item. 13747 */ 13748 function swap(ary, x, y) { 13749 var temp = ary[x]; 13750 ary[x] = ary[y]; 13751 ary[y] = temp; 13752 } 13753 13754 /** 13755 * Returns a random integer within the range `low .. high` inclusive. 13756 * 13757 * @param {Number} low 13758 * The lower bound on the range. 13759 * @param {Number} high 13760 * The upper bound on the range. 13761 */ 13762 function randomIntInRange(low, high) { 13763 return Math.round(low + (Math.random() * (high - low))); 13764 } 13765 13766 /** 13767 * The Quick Sort algorithm. 13768 * 13769 * @param {Array} ary 13770 * An array to sort. 13771 * @param {function} comparator 13772 * Function to use to compare two items. 13773 * @param {Number} p 13774 * Start index of the array 13775 * @param {Number} r 13776 * End index of the array 13777 */ 13778 function doQuickSort(ary, comparator, p, r) { 13779 // If our lower bound is less than our upper bound, we (1) partition the 13780 // array into two pieces and (2) recurse on each half. If it is not, this is 13781 // the empty array and our base case. 13782 13783 if (p < r) { 13784 // (1) Partitioning. 13785 // 13786 // The partitioning chooses a pivot between `p` and `r` and moves all 13787 // elements that are less than or equal to the pivot to the before it, and 13788 // all the elements that are greater than it after it. The effect is that 13789 // once partition is done, the pivot is in the exact place it will be when 13790 // the array is put in sorted order, and it will not need to be moved 13791 // again. This runs in O(n) time. 13792 13793 // Always choose a random pivot so that an input array which is reverse 13794 // sorted does not cause O(n^2) running time. 13795 var pivotIndex = randomIntInRange(p, r); 13796 var i = p - 1; 13797 13798 swap(ary, pivotIndex, r); 13799 var pivot = ary[r]; 13800 13801 // Immediately after `j` is incremented in this loop, the following hold 13802 // true: 13803 // 13804 // * Every element in `ary[p .. i]` is less than or equal to the pivot. 13805 // 13806 // * Every element in `ary[i+1 .. j-1]` is greater than the pivot. 13807 for (var j = p; j < r; j++) { 13808 if (comparator(ary[j], pivot) <= 0) { 13809 i += 1; 13810 swap(ary, i, j); 13811 } 13812 } 13813 13814 swap(ary, i + 1, j); 13815 var q = i + 1; 13816 13817 // (2) Recurse on each half. 13818 13819 doQuickSort(ary, comparator, p, q - 1); 13820 doQuickSort(ary, comparator, q + 1, r); 13821 } 13822 } 13823 13824 /** 13825 * Sort the given array in-place with the given comparator function. 13826 * 13827 * @param {Array} ary 13828 * An array to sort. 13829 * @param {function} comparator 13830 * Function to use to compare two items. 13831 */ 13832 exports.quickSort = function (ary, comparator) { 13833 doQuickSort(ary, comparator, 0, ary.length - 1); 13834 }; 13835 13836 13837/***/ }, 13838/* 10 */ 13839/***/ function(module, exports, __webpack_require__) { 13840 13841 /* -*- Mode: js; js-indent-level: 2; -*- */ 13842 /* 13843 * Copyright 2011 Mozilla Foundation and contributors 13844 * Licensed under the New BSD license. See LICENSE or: 13845 * http://opensource.org/licenses/BSD-3-Clause 13846 */ 13847 13848 var SourceMapGenerator = __webpack_require__(1).SourceMapGenerator; 13849 var util = __webpack_require__(4); 13850 13851 // Matches a Windows-style `\r\n` newline or a `\n` newline used by all other 13852 // operating systems these days (capturing the result). 13853 var REGEX_NEWLINE = /(\r?\n)/; 13854
vendor: 4,127 bytes, lines 13855-13947
13855 // Newline character code for charCodeAt() comparisons 13856 var NEWLINE_CODE = 10; 13857 13858 // Private symbol for identifying `SourceNode`s when multiple versions of 13859 // the source-map library are loaded. This MUST NOT CHANGE across 13860 // versions! 13861 var isSourceNode = "$$$isSourceNode$$$"; 13862 13863 /** 13864 * SourceNodes provide a way to abstract over interpolating/concatenating 13865 * snippets of generated JavaScript source code while maintaining the line and 13866 * column information associated with the original source code. 13867 * 13868 * @param aLine The original line number. 13869 * @param aColumn The original column number. 13870 * @param aSource The original source's filename. 13871 * @param aChunks Optional. An array of strings which are snippets of 13872 * generated JS, or other SourceNodes. 13873 * @param aName The original identifier. 13874 */ 13875 function SourceNode(aLine, aColumn, aSource, aChunks, aName) { 13876 this.children = []; 13877 this.sourceContents = {}; 13878 this.line = aLine == null ? null : aLine; 13879 this.column = aColumn == null ? null : aColumn; 13880 this.source = aSource == null ? null : aSource; 13881 this.name = aName == null ? null : aName; 13882 this[isSourceNode] = true; 13883 if (aChunks != null) this.add(aChunks); 13884 } 13885 13886 /** 13887 * Creates a SourceNode from generated code and a SourceMapConsumer. 13888 * 13889 * @param aGeneratedCode The generated code 13890 * @param aSourceMapConsumer The SourceMap for the generated code 13891 * @param aRelativePath Optional. The path that relative sources in the 13892 * SourceMapConsumer should be relative to. 13893 */ 13894 SourceNode.fromStringWithSourceMap = 13895 function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) { 13896 // The SourceNode we want to fill with the generated code 13897 // and the SourceMap 13898 var node = new SourceNode(); 13899 13900 // All even indices of this array are one line of the generated code, 13901 // while all odd indices are the newlines between two adjacent lines 13902 // (since `REGEX_NEWLINE` captures its match). 13903 // Processed fragments are removed from this array, by calling `shiftNextLine`. 13904 var remainingLines = aGeneratedCode.split(REGEX_NEWLINE); 13905 var shiftNextLine = function() { 13906 var lineContents = remainingLines.shift(); 13907 // The last line of a file might not have a newline. 13908 var newLine = remainingLines.shift() || ""; 13909 return lineContents + newLine; 13910 }; 13911 13912 // We need to remember the position of "remainingLines" 13913 var lastGeneratedLine = 1, lastGeneratedColumn = 0; 13914 13915 // The generate SourceNodes we need a code range. 13916 // To extract it current and last mapping is used. 13917 // Here we store the last mapping. 13918 var lastMapping = null; 13919 13920 aSourceMapConsumer.eachMapping(function (mapping) { 13921 if (lastMapping !== null) { 13922 // We add the code from "lastMapping" to "mapping": 13923 // First check if there is a new line in between. 13924 if (lastGeneratedLine < mapping.generatedLine) { 13925 // Associate first line with "lastMapping" 13926 addMappingWithCode(lastMapping, shiftNextLine()); 13927 lastGeneratedLine++; 13928 lastGeneratedColumn = 0; 13929 // The remaining code is added without mapping 13930 } else { 13931 // There is no new line in between. 13932 // Associate the code between "lastGeneratedColumn" and 13933 // "mapping.generatedColumn" with "lastMapping" 13934 var nextLine = remainingLines[0]; 13935 var code = nextLine.substr(0, mapping.generatedColumn - 13936 lastGeneratedColumn); 13937 remainingLines[0] = nextLine.substr(mapping.generatedColumn - 13938 lastGeneratedColumn); 13939 lastGeneratedColumn = mapping.generatedColumn; 13940 addMappingWithCode(lastMapping, code); 13941 // No more remaining code, continue 13942 lastMapping = mapping; 13943 return; 13944 } 13945 } 13946 // We add the generated code until the first mapping 13947 // to the SourceNode without any mapping.
vendor: 7,750 bytes, lines 13948-14183
13948 // Each line is added as separate string. 13949 while (lastGeneratedLine < mapping.generatedLine) { 13950 node.add(shiftNextLine()); 13951 lastGeneratedLine++; 13952 } 13953 if (lastGeneratedColumn < mapping.generatedColumn) { 13954 var nextLine = remainingLines[0]; 13955 node.add(nextLine.substr(0, mapping.generatedColumn)); 13956 remainingLines[0] = nextLine.substr(mapping.generatedColumn); 13957 lastGeneratedColumn = mapping.generatedColumn; 13958 } 13959 lastMapping = mapping; 13960 }, this); 13961 // We have processed all mappings. 13962 if (remainingLines.length > 0) { 13963 if (lastMapping) { 13964 // Associate the remaining code in the current line with "lastMapping" 13965 addMappingWithCode(lastMapping, shiftNextLine()); 13966 } 13967 // and add the remaining lines without any mapping 13968 node.add(remainingLines.join("")); 13969 } 13970 13971 // Copy sourcesContent into SourceNode 13972 aSourceMapConsumer.sources.forEach(function (sourceFile) { 13973 var content = aSourceMapConsumer.sourceContentFor(sourceFile); 13974 if (content != null) { 13975 if (aRelativePath != null) { 13976 sourceFile = util.join(aRelativePath, sourceFile); 13977 } 13978 node.setSourceContent(sourceFile, content); 13979 } 13980 }); 13981 13982 return node; 13983 13984 function addMappingWithCode(mapping, code) { 13985 if (mapping === null || mapping.source === undefined) { 13986 node.add(code); 13987 } else { 13988 var source = aRelativePath 13989 ? util.join(aRelativePath, mapping.source) 13990 : mapping.source; 13991 node.add(new SourceNode(mapping.originalLine, 13992 mapping.originalColumn, 13993 source, 13994 code, 13995 mapping.name)); 13996 } 13997 } 13998 }; 13999 14000 /** 14001 * Add a chunk of generated JS to this source node. 14002 * 14003 * @param aChunk A string snippet of generated JS code, another instance of 14004 * SourceNode, or an array where each member is one of those things. 14005 */ 14006 SourceNode.prototype.add = function SourceNode_add(aChunk) { 14007 if (Array.isArray(aChunk)) { 14008 aChunk.forEach(function (chunk) { 14009 this.add(chunk); 14010 }, this); 14011 } 14012 else if (aChunk[isSourceNode] || typeof aChunk === "string") { 14013 if (aChunk) { 14014 this.children.push(aChunk); 14015 } 14016 } 14017 else { 14018 throw new TypeError( 14019 "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk 14020 ); 14021 } 14022 return this; 14023 }; 14024 14025 /** 14026 * Add a chunk of generated JS to the beginning of this source node. 14027 * 14028 * @param aChunk A string snippet of generated JS code, another instance of 14029 * SourceNode, or an array where each member is one of those things. 14030 */ 14031 SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) { 14032 if (Array.isArray(aChunk)) { 14033 for (var i = aChunk.length-1; i >= 0; i--) { 14034 this.prepend(aChunk[i]); 14035 } 14036 } 14037 else if (aChunk[isSourceNode] || typeof aChunk === "string") { 14038 this.children.unshift(aChunk); 14039 } 14040 else { 14041 throw new TypeError( 14042 "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk 14043 ); 14044 } 14045 return this; 14046 }; 14047 14048 /** 14049 * Walk over the tree of JS snippets in this node and its children. The 14050 * walking function is called once for each snippet of JS and is passed that 14051 * snippet and the its original associated source's line/column location. 14052 * 14053 * @param aFn The traversal function. 14054 */ 14055 SourceNode.prototype.walk = function SourceNode_walk(aFn) { 14056 var chunk; 14057 for (var i = 0, len = this.children.length; i < len; i++) { 14058 chunk = this.children[i]; 14059 if (chunk[isSourceNode]) { 14060 chunk.walk(aFn); 14061 } 14062 else { 14063 if (chunk !== '') { 14064 aFn(chunk, { source: this.source, 14065 line: this.line, 14066 column: this.column, 14067 name: this.name }); 14068 } 14069 } 14070 } 14071 }; 14072 14073 /** 14074 * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between 14075 * each of `this.children`. 14076 * 14077 * @param aSep The separator. 14078 */ 14079 SourceNode.prototype.join = function SourceNode_join(aSep) { 14080 var newChildren; 14081 var i; 14082 var len = this.children.length; 14083 if (len > 0) { 14084 newChildren = []; 14085 for (i = 0; i < len-1; i++) { 14086 newChildren.push(this.children[i]); 14087 newChildren.push(aSep); 14088 } 14089 newChildren.push(this.children[i]); 14090 this.children = newChildren; 14091 } 14092 return this; 14093 }; 14094 14095 /** 14096 * Call String.prototype.replace on the very right-most source snippet. Useful 14097 * for trimming whitespace from the end of a source node, etc. 14098 * 14099 * @param aPattern The pattern to replace. 14100 * @param aReplacement The thing to replace the pattern with. 14101 */ 14102 SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) { 14103 var lastChild = this.children[this.children.length - 1]; 14104 if (lastChild[isSourceNode]) { 14105 lastChild.replaceRight(aPattern, aReplacement); 14106 } 14107 else if (typeof lastChild === 'string') { 14108 this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement); 14109 } 14110 else { 14111 this.children.push(''.replace(aPattern, aReplacement)); 14112 } 14113 return this; 14114 }; 14115 14116 /** 14117 * Set the source content for a source file. This will be added to the SourceMapGenerator 14118 * in the sourcesContent field. 14119 * 14120 * @param aSourceFile The filename of the source file 14121 * @param aSourceContent The content of the source file 14122 */ 14123 SourceNode.prototype.setSourceContent = 14124 function SourceNode_setSourceContent(aSourceFile, aSourceContent) { 14125 this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; 14126 }; 14127 14128 /** 14129 * Walk over the tree of SourceNodes. The walking function is called for each 14130 * source file content and is passed the filename and source content. 14131 * 14132 * @param aFn The traversal function. 14133 */ 14134 SourceNode.prototype.walkSourceContents = 14135 function SourceNode_walkSourceContents(aFn) { 14136 for (var i = 0, len = this.children.length; i < len; i++) { 14137 if (this.children[i][isSourceNode]) { 14138 this.children[i].walkSourceContents(aFn); 14139 } 14140 } 14141 14142 var sources = Object.keys(this.sourceContents); 14143 for (var i = 0, len = sources.length; i < len; i++) { 14144 aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]); 14145 } 14146 }; 14147 14148 /** 14149 * Return the string representation of this source node. Walks over the tree 14150 * and concatenates all the various snippets together to one string. 14151 */ 14152 SourceNode.prototype.toString = function SourceNode_toString() { 14153 var str = ""; 14154 this.walk(function (chunk) { 14155 str += chunk; 14156 }); 14157 return str; 14158 }; 14159 14160 /** 14161 * Returns the string representation of this source node along with a source 14162 * map. 14163 */ 14164 SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) { 14165 var generated = { 14166 code: "", 14167 line: 1, 14168 column: 0 14169 }; 14170 var map = new SourceMapGenerator(aArgs); 14171 var sourceMappingActive = false; 14172 var lastOriginalSource = null; 14173 var lastOriginalLine = null; 14174 var lastOriginalColumn = null; 14175 var lastOriginalName = null; 14176 this.walk(function (chunk, original) { 14177 generated.code += chunk; 14178 if (original.source !== null 14179 && original.line !== null 14180 && original.column !== null) { 14181 if(lastOriginalSource !== original.source 14182 || lastOriginalLine !== original.line 14183 || lastOriginalColumn !== original.column
14184 || lastOriginalName !== original.name) { 14185 map.addMapping({ 14186 source: original.source, 14187 original: { 14188 line: original.line, 14189 column: original.column 14190 }, 14191 generated: { 14192 line: generated.line, 14193 column: generated.column 14194 }, 14195 name: original.name 14196 }); 14197 } 14198 lastOriginalSource = original.source; 14199 lastOriginalLine = original.line; 14200 lastOriginalColumn = original.column; 14201 lastOriginalName = original.name; 14202 sourceMappingActive = true; 14203 } else if (sourceMappingActive) { 14204 map.addMapping({ 14205 generated: { 14206 line: generated.line, 14207 column: generated.column 14208 } 14209 }); 14210 lastOriginalSource = null; 14211 sourceMappingActive = false; 14212 } 14213 for (var idx = 0, length = chunk.length; idx < length; idx++) { 14214 if (chunk.charCodeAt(idx) === NEWLINE_CODE) { 14215 generated.line++; 14216 generated.column = 0; 14217 // Mappings end at eol 14218 if (idx + 1 === length) { 14219 lastOriginalSource = null; 14220 sourceMappingActive = false; 14221 } else if (sourceMappingActive) { 14222 map.addMapping({ 14223 source: original.source, 14224 original: { 14225 line: original.line, 14226 column: original.column 14227 }, 14228 generated: { 14229 line: generated.line, 14230 column: generated.column 14231 }, 14232 name: original.name 14233 }); 14234 } 14235 } else { 14236 generated.column++; 14237 } 14238 } 14239 }); 14240 this.walkSourceContents(function (sourceFile, sourceContent) { 14241 map.setSourceContent(sourceFile, sourceContent); 14242 }); 14243 14244 return { code: generated.code, map: map }; 14245 }; 14246 14247 exports.SourceNode = SourceNode; 14248 14249 14250/***/ } 14251/******/ ]) 14252}); 14253;//Distributed under the BSD license: 14254//Copyright 2012 (c) Mihai Bazon <[email protected]> 14255define('uglifyjs', ['exports', 'source-map', 'logger', 'env!env/file'], function (exports, MOZ_SourceMap, logger, rjsFile) { 14256 14257/*********************************************************************** 14258 14259 A JavaScript tokenizer / parser / beautifier / compressor. 14260 https://github.com/mishoo/UglifyJS2 14261 14262 -------------------------------- (C) --------------------------------- 14263 14264 Author: Mihai Bazon 14265 <[email protected]> 14266 http://mihai.bazon.net/blog 14267 14268 Distributed under the BSD license: 14269 14270 Copyright 2012 (c) Mihai Bazon <[email protected]> 14271 14272 Redistribution and use in source and binary forms, with or without 14273 modification, are permitted provided that the following conditions 14274 are met: 14275 14276 * Redistributions of source code must retain the above 14277 copyright notice, this list of conditions and the following 14278 disclaimer. 14279 14280 * Redistributions in binary form must reproduce the above 14281 copyright notice, this list of conditions and the following 14282 disclaimer in the documentation and/or other materials 14283 provided with the distribution. 14284 14285 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER âAS ISâ AND ANY 14286 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14287 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 14288 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE 14289 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 14290 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 14291 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 14292 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 14293 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 14294 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 14295 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 14296 SUCH DAMAGE. 14297 14298 ***********************************************************************/ 14299 14300"use strict"; 14301 14302function array_to_hash(a) { 14303 var ret = Object.create(null); 14304 for (var i = 0; i < a.length; ++i) 14305 ret[a[i]] = true; 14306 return ret; 14307}; 14308 14309function slice(a, start) { 14310 return Array.prototype.slice.call(a, start || 0); 14311}; 14312 14313function characters(str) { 14314 return str.split(""); 14315};
14316 14317function member(name, array) { 14318 return array.indexOf(name) >= 0; 14319}; 14320 14321function find_if(func, array) { 14322 for (var i = 0, n = array.length; i < n; ++i) { 14323 if (func(array[i])) 14324 return array[i]; 14325 } 14326}; 14327 14328function repeat_string(str, i) { 14329 if (i <= 0) return ""; 14330 if (i == 1) return str; 14331 var d = repeat_string(str, i >> 1); 14332 d += d; 14333 if (i & 1) d += str; 14334 return d; 14335}; 14336 14337function configure_error_stack(fn) { 14338 Object.defineProperty(fn.prototype, "stack", { 14339 get: function() { 14340 var err = new Error(this.message); 14341 err.name = this.name; 14342 try { 14343 throw err; 14344 } catch(e) { 14345 return e.stack; 14346 } 14347 } 14348 }); 14349} 14350 14351function DefaultsError(msg, defs) { 14352 this.message = msg; 14353 this.defs = defs; 14354}; 14355DefaultsError.prototype = Object.create(Error.prototype); 14356DefaultsError.prototype.constructor = DefaultsError; 14357DefaultsError.prototype.name = "DefaultsError"; 14358configure_error_stack(DefaultsError); 14359 14360DefaultsError.croak = function(msg, defs) { 14361 throw new DefaultsError(msg, defs); 14362}; 14363 14364function defaults(args, defs, croak) { 14365 if (args === true) 14366 args = {}; 14367 var ret = args || {}; 14368 if (croak) for (var i in ret) if (HOP(ret, i) && !HOP(defs, i)) 14369 DefaultsError.croak("`" + i + "` is not a supported option", defs); 14370 for (var i in defs) if (HOP(defs, i)) { 14371 ret[i] = (args && HOP(args, i)) ? args[i] : defs[i]; 14372 } 14373 return ret; 14374}; 14375 14376function merge(obj, ext) { 14377 var count = 0; 14378 for (var i in ext) if (HOP(ext, i)) { 14379 obj[i] = ext[i]; 14380 count++; 14381 } 14382 return count; 14383}; 14384 14385function noop() {} 14386function return_false() { return false; } 14387function return_true() { return true; } 14388function return_this() { return this; } 14389function return_null() { return null; } 14390 14391var MAP = (function(){ 14392 function MAP(a, f, backwards) { 14393 var ret = [], top = [], i; 14394 function doit() { 14395 var val = f(a[i], i); 14396 var is_last = val instanceof Last; 14397 if (is_last) val = val.v; 14398 if (val instanceof AtTop) { 14399 val = val.v; 14400 if (val instanceof Splice) { 14401 top.push.apply(top, backwards ? val.v.slice().reverse() : val.v); 14402 } else { 14403 top.push(val); 14404 } 14405 } 14406 else if (val !== skip) { 14407 if (val instanceof Splice) { 14408 ret.push.apply(ret, backwards ? val.v.slice().reverse() : val.v); 14409 } else { 14410 ret.push(val); 14411 } 14412 } 14413 return is_last; 14414 }; 14415 if (a instanceof Array) { 14416 if (backwards) { 14417 for (i = a.length; --i >= 0;) if (doit()) break; 14418 ret.reverse(); 14419 top.reverse(); 14420 } else { 14421 for (i = 0; i < a.length; ++i) if (doit()) break; 14422 } 14423 } 14424 else { 14425 for (i in a) if (HOP(a, i)) if (doit()) break; 14426 } 14427 return top.concat(ret); 14428 }; 14429 MAP.at_top = function(val) { return new AtTop(val) }; 14430 MAP.splice = function(val) { return new Splice(val) }; 14431 MAP.last = function(val) { return new Last(val) }; 14432 var skip = MAP.skip = {}; 14433 function AtTop(val) { this.v = val }; 14434 function Splice(val) { this.v = val }; 14435 function Last(val) { this.v = val }; 14436 return MAP; 14437})(); 14438 14439function push_uniq(array, el) { 14440 if (array.indexOf(el) < 0) 14441 array.push(el); 14442}; 14443 14444function string_template(text, props) { 14445 return text.replace(/\{(.+?)\}/g, function(str, p){ 14446 return props && props[p]; 14447 }); 14448}; 14449 14450function remove(array, el) { 14451 for (var i = array.length; --i >= 0;) { 14452 if (array[i] === el) array.splice(i, 1); 14453 } 14454}; 14455 14456function mergeSort(array, cmp) { 14457 if (array.length < 2) return array.slice(); 14458 function merge(a, b) { 14459 var r = [], ai = 0, bi = 0, i = 0; 14460 while (ai < a.length && bi < b.length) { 14461 cmp(a[ai], b[bi]) <= 0 14462 ? r[i++] = a[ai++] 14463 : r[i++] = b[bi++]; 14464 }
14465 if (ai < a.length) r.push.apply(r, a.slice(ai)); 14466 if (bi < b.length) r.push.apply(r, b.slice(bi)); 14467 return r; 14468 }; 14469 function _ms(a) { 14470 if (a.length <= 1) 14471 return a; 14472 var m = Math.floor(a.length / 2), left = a.slice(0, m), right = a.slice(m); 14473 left = _ms(left); 14474 right = _ms(right); 14475 return merge(left, right); 14476 }; 14477 return _ms(array); 14478}; 14479 14480function set_difference(a, b) { 14481 return a.filter(function(el){ 14482 return b.indexOf(el) < 0; 14483 }); 14484}; 14485 14486function set_intersection(a, b) { 14487 return a.filter(function(el){ 14488 return b.indexOf(el) >= 0; 14489 }); 14490}; 14491 14492// this function is taken from Acorn [1], written by Marijn Haverbeke 14493// [1] https://github.com/marijnh/acorn 14494function makePredicate(words) { 14495 if (!(words instanceof Array)) words = words.split(" "); 14496 var f = "", cats = []; 14497 out: for (var i = 0; i < words.length; ++i) { 14498 for (var j = 0; j < cats.length; ++j) 14499 if (cats[j][0].length == words[i].length) { 14500 cats[j].push(words[i]); 14501 continue out; 14502 } 14503 cats.push([words[i]]); 14504 } 14505 function quote(word) { 14506 return JSON.stringify(word).replace(/[\u2028\u2029]/g, function(s) { 14507 switch (s) { 14508 case "\u2028": return "\\u2028"; 14509 case "\u2029": return "\\u2029"; 14510 } 14511 return s; 14512 }); 14513 } 14514 function compareTo(arr) { 14515 if (arr.length == 1) return f += "return str === " + quote(arr[0]) + ";"; 14516 f += "switch(str){"; 14517 for (var i = 0; i < arr.length; ++i) f += "case " + quote(arr[i]) + ":"; 14518 f += "return true}return false;"; 14519 } 14520 // When there are more than three length categories, an outer 14521 // switch first dispatches on the lengths, to save on comparisons. 14522 if (cats.length > 3) { 14523 cats.sort(function(a, b) {return b.length - a.length;}); 14524 f += "switch(str.length){"; 14525 for (var i = 0; i < cats.length; ++i) { 14526 var cat = cats[i]; 14527 f += "case " + cat[0].length + ":"; 14528 compareTo(cat); 14529 } 14530 f += "}"; 14531 // Otherwise, simply generate a flat `switch` statement. 14532 } else { 14533 compareTo(words); 14534 } 14535 return new Function("str", f); 14536}; 14537 14538function all(array, predicate) { 14539 for (var i = array.length; --i >= 0;) 14540 if (!predicate(array[i])) 14541 return false; 14542 return true; 14543}; 14544 14545function Dictionary() { 14546 this._values = Object.create(null); 14547 this._size = 0; 14548}; 14549Dictionary.prototype = { 14550 set: function(key, val) { 14551 if (!this.has(key)) ++this._size; 14552 this._values["$" + key] = val; 14553 return this; 14554 }, 14555 add: function(key, val) { 14556 if (this.has(key)) { 14557 this.get(key).push(val); 14558 } else { 14559 this.set(key, [ val ]); 14560 } 14561 return this; 14562 }, 14563 get: function(key) { return this._values["$" + key] }, 14564 del: function(key) { 14565 if (this.has(key)) { 14566 --this._size; 14567 delete this._values["$" + key]; 14568 } 14569 return this; 14570 }, 14571 has: function(key) { return ("$" + key) in this._values }, 14572 each: function(f) { 14573 for (var i in this._values) 14574 f(this._values[i], i.substr(1)); 14575 }, 14576 size: function() { 14577 return this._size; 14578 }, 14579 map: function(f) { 14580 var ret = []; 14581 for (var i in this._values) 14582 ret.push(f(this._values[i], i.substr(1))); 14583 return ret; 14584 }, 14585 toObject: function() { return this._values } 14586}; 14587Dictionary.fromObject = function(obj) { 14588 var dict = new Dictionary(); 14589 dict._size = merge(dict._values, obj); 14590 return dict; 14591}; 14592 14593function HOP(obj, prop) { 14594 return Object.prototype.hasOwnProperty.call(obj, prop); 14595} 14596 14597// return true if the node at the top of the stack (that means the 14598// innermost node in the current output) is lexically the first in 14599// a statement. 14600function first_in_statement(stack) { 14601 var node = stack.parent(-1); 14602 for (var i = 0, p; p = stack.parent(i); i++) {
14603 if (p instanceof AST_Statement && p.body === node) 14604 return true; 14605 if ((p instanceof AST_Seq && p.car === node ) || 14606 (p instanceof AST_Call && p.expression === node && !(p instanceof AST_New) ) || 14607 (p instanceof AST_Dot && p.expression === node ) || 14608 (p instanceof AST_Sub && p.expression === node ) || 14609 (p instanceof AST_Conditional && p.condition === node ) || 14610 (p instanceof AST_Binary && p.left === node ) || 14611 (p instanceof AST_UnaryPostfix && p.expression === node )) 14612 { 14613 node = p; 14614 } else { 14615 return false; 14616 } 14617 } 14618} 14619 14620/*********************************************************************** 14621 14622 A JavaScript tokenizer / parser / beautifier / compressor. 14623 https://github.com/mishoo/UglifyJS2 14624 14625 -------------------------------- (C) --------------------------------- 14626 14627 Author: Mihai Bazon 14628 <[email protected]> 14629 http://mihai.bazon.net/blog 14630 14631 Distributed under the BSD license: 14632 14633 Copyright 2012 (c) Mihai Bazon <[email protected]> 14634 14635 Redistribution and use in source and binary forms, with or without 14636 modification, are permitted provided that the following conditions 14637 are met: 14638 14639 * Redistributions of source code must retain the above 14640 copyright notice, this list of conditions and the following 14641 disclaimer. 14642 14643 * Redistributions in binary form must reproduce the above 14644 copyright notice, this list of conditions and the following 14645 disclaimer in the documentation and/or other materials 14646 provided with the distribution. 14647 14648 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER âAS ISâ AND ANY 14649 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14650 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 14651 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE 14652 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 14653 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 14654 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 14655 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 14656 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 14657 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 14658 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 14659 SUCH DAMAGE. 14660 14661 ***********************************************************************/ 14662 14663"use strict"; 14664 14665function DEFNODE(type, props, methods, base) { 14666 if (arguments.length < 4) base = AST_Node; 14667 if (!props) props = []; 14668 else props = props.split(/\s+/); 14669 var self_props = props; 14670 if (base && base.PROPS) 14671 props = props.concat(base.PROPS); 14672 var code = "return function AST_" + type + "(props){ if (props) { "; 14673 for (var i = props.length; --i >= 0;) { 14674 code += "this." + props[i] + " = props." + props[i] + ";"; 14675 } 14676 var proto = base && new base; 14677 if (proto && proto.initialize || (methods && methods.initialize)) 14678 code += "this.initialize();"; 14679 code += "}}"; 14680 var ctor = new Function(code)(); 14681 if (proto) { 14682 ctor.prototype = proto; 14683 ctor.BASE = base; 14684 } 14685 if (base) base.SUBCLASSES.push(ctor); 14686 ctor.prototype.CTOR = ctor; 14687 ctor.PROPS = props || null; 14688 ctor.SELF_PROPS = self_props; 14689 ctor.SUBCLASSES = []; 14690 if (type) { 14691 ctor.prototype.TYPE = ctor.TYPE = type; 14692 } 14693 if (methods) for (i in methods) if (HOP(methods, i)) { 14694 if (/^\$/.test(i)) { 14695 ctor[i.substr(1)] = methods[i]; 14696 } else { 14697 ctor.prototype[i] = methods[i]; 14698 } 14699 } 14700 ctor.DEFMETHOD = function(name, method) { 14701 this.prototype[name] = method; 14702 }; 14703 if (typeof exports !== "undefined") { 14704 exports["AST_" + type] = ctor; 14705 } 14706 return ctor; 14707}; 14708 14709var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before file raw", { 14710}, null); 14711 14712var AST_Node = DEFNODE("Node", "start end", { 14713 _clone: function(deep) { 14714 if (deep) { 14715 var self = this.clone(); 14716 return self.transform(new TreeTransformer(function(node) { 14717 if (node !== self) { 14718 return node.clone(true); 14719 } 14720 })); 14721 } 14722 return new this.CTOR(this); 14723 }, 14724 clone: function(deep) { 14725 return this._clone(deep);
14726 }, 14727 $documentation: "Base class of all AST nodes", 14728 $propdoc: { 14729 start: "[AST_Token] The first token of this node", 14730 end: "[AST_Token] The last token of this node" 14731 }, 14732 _walk: function(visitor) { 14733 return visitor._visit(this); 14734 }, 14735 walk: function(visitor) { 14736 return this._walk(visitor); // not sure the indirection will be any help 14737 } 14738}, null); 14739 14740AST_Node.warn_function = null; 14741AST_Node.warn = function(txt, props) { 14742 if (AST_Node.warn_function) 14743 AST_Node.warn_function(string_template(txt, props)); 14744}; 14745 14746/* -----[ statements ]----- */ 14747 14748var AST_Statement = DEFNODE("Statement", null, { 14749 $documentation: "Base class of all statements", 14750}); 14751 14752var AST_Debugger = DEFNODE("Debugger", null, { 14753 $documentation: "Represents a debugger statement", 14754}, AST_Statement); 14755 14756var AST_Directive = DEFNODE("Directive", "value scope quote", { 14757 $documentation: "Represents a directive, like \"use strict\";", 14758 $propdoc: { 14759 value: "[string] The value of this directive as a plain string (it's not an AST_String!)", 14760 scope: "[AST_Scope/S] The scope that this directive affects", 14761 quote: "[string] the original quote character" 14762 }, 14763}, AST_Statement); 14764 14765var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", { 14766 $documentation: "A statement consisting of an expression, i.e. a = 1 + 2", 14767 $propdoc: { 14768 body: "[AST_Node] an expression node (should not be instanceof AST_Statement)" 14769 }, 14770 _walk: function(visitor) { 14771 return visitor._visit(this, function(){ 14772 this.body._walk(visitor); 14773 }); 14774 } 14775}, AST_Statement); 14776 14777function walk_body(node, visitor) { 14778 var body = node.body; 14779 if (body instanceof AST_Statement) { 14780 body._walk(visitor); 14781 } 14782 else for (var i = 0, len = body.length; i < len; i++) { 14783 body[i]._walk(visitor); 14784 } 14785}; 14786 14787var AST_Block = DEFNODE("Block", "body", { 14788 $documentation: "A body of statements (usually bracketed)", 14789 $propdoc: { 14790 body: "[AST_Statement*] an array of statements" 14791 }, 14792 _walk: function(visitor) { 14793 return visitor._visit(this, function(){ 14794 walk_body(this, visitor); 14795 }); 14796 } 14797}, AST_Statement); 14798 14799var AST_BlockStatement = DEFNODE("BlockStatement", null, { 14800 $documentation: "A block statement", 14801}, AST_Block); 14802 14803var AST_EmptyStatement = DEFNODE("EmptyStatement", null, { 14804 $documentation: "The empty statement (empty block or simply a semicolon)", 14805 _walk: function(visitor) { 14806 return visitor._visit(this); 14807 } 14808}, AST_Statement); 14809 14810var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", { 14811 $documentation: "Base class for all statements that contain one nested body: `For`, `ForIn`, `Do`, `While`, `With`", 14812 $propdoc: { 14813 body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement" 14814 }, 14815 _walk: function(visitor) { 14816 return visitor._visit(this, function(){ 14817 this.body._walk(visitor); 14818 }); 14819 } 14820}, AST_Statement); 14821 14822var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", { 14823 $documentation: "Statement with a label", 14824 $propdoc: { 14825 label: "[AST_Label] a label definition" 14826 }, 14827 _walk: function(visitor) { 14828 return visitor._visit(this, function(){ 14829 this.label._walk(visitor); 14830 this.body._walk(visitor); 14831 }); 14832 }, 14833 clone: function(deep) { 14834 var node = this._clone(deep); 14835 if (deep) { 14836 var label = node.label; 14837 var def = this.label; 14838 node.walk(new TreeWalker(function(node) { 14839 if (node instanceof AST_LoopControl 14840 && node.label && node.label.thedef === def) { 14841 node.label.thedef = label; 14842 label.references.push(node); 14843 } 14844 })); 14845 } 14846 return node; 14847 } 14848}, AST_StatementWithBody); 14849 14850var AST_IterationStatement = DEFNODE("IterationStatement", null, {
vendor: 5,699 bytes, lines 14851-14990
14851 $documentation: "Internal class. All loops inherit from it." 14852}, AST_StatementWithBody); 14853 14854var AST_DWLoop = DEFNODE("DWLoop", "condition", { 14855 $documentation: "Base class for do/while statements", 14856 $propdoc: { 14857 condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement" 14858 } 14859}, AST_IterationStatement); 14860 14861var AST_Do = DEFNODE("Do", null, { 14862 $documentation: "A `do` statement", 14863 _walk: function(visitor) { 14864 return visitor._visit(this, function(){ 14865 this.body._walk(visitor); 14866 this.condition._walk(visitor); 14867 }); 14868 } 14869}, AST_DWLoop); 14870 14871var AST_While = DEFNODE("While", null, { 14872 $documentation: "A `while` statement", 14873 _walk: function(visitor) { 14874 return visitor._visit(this, function(){ 14875 this.condition._walk(visitor); 14876 this.body._walk(visitor); 14877 }); 14878 } 14879}, AST_DWLoop); 14880 14881var AST_For = DEFNODE("For", "init condition step", { 14882 $documentation: "A `for` statement", 14883 $propdoc: { 14884 init: "[AST_Node?] the `for` initialization code, or null if empty", 14885 condition: "[AST_Node?] the `for` termination clause, or null if empty", 14886 step: "[AST_Node?] the `for` update clause, or null if empty" 14887 }, 14888 _walk: function(visitor) { 14889 return visitor._visit(this, function(){ 14890 if (this.init) this.init._walk(visitor); 14891 if (this.condition) this.condition._walk(visitor); 14892 if (this.step) this.step._walk(visitor); 14893 this.body._walk(visitor); 14894 }); 14895 } 14896}, AST_IterationStatement); 14897 14898var AST_ForIn = DEFNODE("ForIn", "init name object", { 14899 $documentation: "A `for ... in` statement", 14900 $propdoc: { 14901 init: "[AST_Node] the `for/in` initialization code", 14902 name: "[AST_SymbolRef?] the loop variable, only if `init` is AST_Var", 14903 object: "[AST_Node] the object that we're looping through" 14904 }, 14905 _walk: function(visitor) { 14906 return visitor._visit(this, function(){ 14907 this.init._walk(visitor); 14908 this.object._walk(visitor); 14909 this.body._walk(visitor); 14910 }); 14911 } 14912}, AST_IterationStatement); 14913 14914var AST_With = DEFNODE("With", "expression", { 14915 $documentation: "A `with` statement", 14916 $propdoc: { 14917 expression: "[AST_Node] the `with` expression" 14918 }, 14919 _walk: function(visitor) { 14920 return visitor._visit(this, function(){ 14921 this.expression._walk(visitor); 14922 this.body._walk(visitor); 14923 }); 14924 } 14925}, AST_StatementWithBody); 14926 14927/* -----[ scope and functions ]----- */ 14928 14929var AST_Scope = DEFNODE("Scope", "directives variables functions uses_with uses_eval parent_scope enclosed cname", { 14930 $documentation: "Base class for all statements introducing a lexical scope", 14931 $propdoc: { 14932 directives: "[string*/S] an array of directives declared in this scope", 14933 variables: "[Object/S] a map of name -> SymbolDef for all variables/functions defined in this scope", 14934 functions: "[Object/S] like `variables`, but only lists function declarations", 14935 uses_with: "[boolean/S] tells whether this scope uses the `with` statement", 14936 uses_eval: "[boolean/S] tells whether this scope contains a direct call to the global `eval`", 14937 parent_scope: "[AST_Scope?/S] link to the parent scope", 14938 enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes", 14939 cname: "[integer/S] current index for mangling variables (used internally by the mangler)", 14940 }, 14941}, AST_Block); 14942 14943var AST_Toplevel = DEFNODE("Toplevel", "globals", { 14944 $documentation: "The toplevel scope", 14945 $propdoc: { 14946 globals: "[Object/S] a map of name -> SymbolDef for all undeclared names", 14947 }, 14948 wrap_enclose: function(arg_parameter_pairs) { 14949 var self = this; 14950 var args = []; 14951 var parameters = []; 14952 14953 arg_parameter_pairs.forEach(function(pair) { 14954 var splitAt = pair.lastIndexOf(":"); 14955 14956 args.push(pair.substr(0, splitAt)); 14957 parameters.push(pair.substr(splitAt + 1)); 14958 }); 14959 14960 var wrapped_tl = "(function(" + parameters.join(",") + "){ '$ORIG'; })(" + args.join(",") + ")"; 14961 wrapped_tl = parse(wrapped_tl); 14962 wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){ 14963 if (node instanceof AST_Directive && node.value == "$ORIG") { 14964 return MAP.splice(self.body); 14965 } 14966 })); 14967 return wrapped_tl; 14968 }, 14969 wrap_commonjs: function(name, export_all) { 14970 var self = this; 14971 var to_export = []; 14972 if (export_all) { 14973 self.figure_out_scope(); 14974 self.walk(new TreeWalker(function(node){ 14975 if (node instanceof AST_SymbolDeclaration && node.definition().global) { 14976 if (!find_if(function(n){ return n.name == node.name }, to_export)) 14977 to_export.push(node); 14978 } 14979 })); 14980 } 14981 var wrapped_tl = "(function(exports, global){ '$ORIG'; '$EXPORTS'; global['" + name + "'] = exports; }({}, (function(){return this}())))"; 14982 wrapped_tl = parse(wrapped_tl); 14983 wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){ 14984 if (node instanceof AST_Directive) { 14985 switch (node.value) { 14986 case "$ORIG": 14987 return MAP.splice(self.body); 14988 case "$EXPORTS": 14989 var body = []; 14990 to_export.forEach(function(sym){
14991 body.push(new AST_SimpleStatement({ 14992 body: new AST_Assign({ 14993 left: new AST_Sub({ 14994 expression: new AST_SymbolRef({ name: "exports" }), 14995 property: new AST_String({ value: sym.name }), 14996 }), 14997 operator: "=", 14998 right: new AST_SymbolRef(sym), 14999 }), 15000 })); 15001 }); 15002 return MAP.splice(body); 15003 } 15004 } 15005 })); 15006 return wrapped_tl; 15007 } 15008}, AST_Scope); 15009 15010var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", { 15011 $documentation: "Base class for functions", 15012 $propdoc: { 15013 name: "[AST_SymbolDeclaration?] the name of this function", 15014 argnames: "[AST_SymbolFunarg*] array of function arguments", 15015 uses_arguments: "[boolean/S] tells whether this function accesses the arguments array" 15016 }, 15017 _walk: function(visitor) { 15018 return visitor._visit(this, function(){ 15019 if (this.name) this.name._walk(visitor); 15020 var argnames = this.argnames; 15021 for (var i = 0, len = argnames.length; i < len; i++) { 15022 argnames[i]._walk(visitor); 15023 } 15024 walk_body(this, visitor); 15025 }); 15026 } 15027}, AST_Scope); 15028 15029var AST_Accessor = DEFNODE("Accessor", null, { 15030 $documentation: "A setter/getter function. The `name` property is always null." 15031}, AST_Lambda); 15032 15033var AST_Function = DEFNODE("Function", null, { 15034 $documentation: "A function expression" 15035}, AST_Lambda); 15036 15037var AST_Defun = DEFNODE("Defun", null, { 15038 $documentation: "A function definition" 15039}, AST_Lambda); 15040 15041/* -----[ JUMPS ]----- */ 15042 15043var AST_Jump = DEFNODE("Jump", null, { 15044 $documentation: "Base class for âjumpsâ (for now that's `return`, `throw`, `break` and `continue`)" 15045}, AST_Statement); 15046 15047var AST_Exit = DEFNODE("Exit", "value", { 15048 $documentation: "Base class for âexitsâ (`return` and `throw`)", 15049 $propdoc: { 15050 value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return" 15051 }, 15052 _walk: function(visitor) { 15053 return visitor._visit(this, this.value && function(){ 15054 this.value._walk(visitor); 15055 }); 15056 } 15057}, AST_Jump); 15058 15059var AST_Return = DEFNODE("Return", null, { 15060 $documentation: "A `return` statement" 15061}, AST_Exit); 15062 15063var AST_Throw = DEFNODE("Throw", null, { 15064 $documentation: "A `throw` statement" 15065}, AST_Exit); 15066 15067var AST_LoopControl = DEFNODE("LoopControl", "label", { 15068 $documentation: "Base class for loop control statements (`break` and `continue`)", 15069 $propdoc: { 15070 label: "[AST_LabelRef?] the label, or null if none", 15071 }, 15072 _walk: function(visitor) { 15073 return visitor._visit(this, this.label && function(){ 15074 this.label._walk(visitor); 15075 }); 15076 } 15077}, AST_Jump); 15078 15079var AST_Break = DEFNODE("Break", null, { 15080 $documentation: "A `break` statement" 15081}, AST_LoopControl); 15082 15083var AST_Continue = DEFNODE("Continue", null, { 15084 $documentation: "A `continue` statement" 15085}, AST_LoopControl); 15086 15087/* -----[ IF ]----- */ 15088 15089var AST_If = DEFNODE("If", "condition alternative", { 15090 $documentation: "A `if` statement", 15091 $propdoc: { 15092 condition: "[AST_Node] the `if` condition", 15093 alternative: "[AST_Statement?] the `else` part, or null if not present" 15094 }, 15095 _walk: function(visitor) { 15096 return visitor._visit(this, function(){ 15097 this.condition._walk(visitor); 15098 this.body._walk(visitor); 15099 if (this.alternative) this.alternative._walk(visitor); 15100 }); 15101 } 15102}, AST_StatementWithBody); 15103 15104/* -----[ SWITCH ]----- */ 15105 15106var AST_Switch = DEFNODE("Switch", "expression", { 15107 $documentation: "A `switch` statement", 15108 $propdoc: { 15109 expression: "[AST_Node] the `switch` âdiscriminantâ" 15110 }, 15111 _walk: function(visitor) { 15112 return visitor._visit(this, function(){ 15113 this.expression._walk(visitor); 15114 walk_body(this, visitor); 15115 }); 15116 } 15117}, AST_Block); 15118 15119var AST_SwitchBranch = DEFNODE("SwitchBranch", null, { 15120 $documentation: "Base class for `switch` branches", 15121}, AST_Block); 15122 15123var AST_Default = DEFNODE("Default", null, { 15124 $documentation: "A `default` switch branch", 15125}, AST_SwitchBranch); 15126 15127var AST_Case = DEFNODE("Case", "expression", { 15128 $documentation: "A `case` switch branch", 15129 $propdoc: { 15130 expression: "[AST_Node] the `case` expression" 15131 }, 15132 _walk: function(visitor) { 15133 return visitor._visit(this, function(){ 15134 this.expression._walk(visitor); 15135 walk_body(this, visitor); 15136 }); 15137 } 15138}, AST_SwitchBranch); 15139 15140/* -----[ EXCEPTIONS ]----- */ 15141 15142var AST_Try = DEFNODE("Try", "bcatch bfinally", { 15143 $documentation: "A `try` statement", 15144 $propdoc: { 15145 bcatch: "[AST_Catch?] the catch block, or null if not present", 15146 bfinally: "[AST_Finally?] the finally block, or null if not present" 15147 }, 15148 _walk: function(visitor) { 15149 return visitor._visit(this, function(){ 15150 walk_body(this, visitor); 15151 if (this.bcatch) this.bcatch._walk(visitor); 15152 if (this.bfinally) this.bfinally._walk(visitor); 15153 }); 15154 } 15155}, AST_Block); 15156 15157var AST_Catch = DEFNODE("Catch", "argname", { 15158 $documentation: "A `catch` node; only makes sense as part of a `try` statement", 15159 $propdoc: { 15160 argname: "[AST_SymbolCatch] symbol for the exception" 15161 }, 15162 _walk: function(visitor) { 15163 return visitor._visit(this, function(){ 15164 this.argname._walk(visitor); 15165 walk_body(this, visitor); 15166 }); 15167 } 15168}, AST_Block); 15169 15170var AST_Finally = DEFNODE("Finally", null, { 15171 $documentation: "A `finally` node; only makes sense as part of a `try` statement" 15172}, AST_Block); 15173 15174/* -----[ VAR/CONST ]----- */ 15175 15176var AST_Definitions = DEFNODE("Definitions", "definitions", { 15177 $documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)", 15178 $propdoc: { 15179 definitions: "[AST_VarDef*] array of variable definitions" 15180 }, 15181 _walk: function(visitor) { 15182 return visitor._visit(this, function(){ 15183 var definitions = this.definitions; 15184 for (var i = 0, len = definitions.length; i < len; i++) { 15185 definitions[i]._walk(visitor); 15186 } 15187 }); 15188 } 15189}, AST_Statement); 15190 15191var AST_Var = DEFNODE("Var", null, { 15192 $documentation: "A `var` statement" 15193}, AST_Definitions); 15194 15195var AST_Const = DEFNODE("Const", null, { 15196 $documentation: "A `const` statement" 15197}, AST_Definitions); 15198 15199var AST_VarDef = DEFNODE("VarDef", "name value", { 15200 $documentation: "A variable declaration; only appears in a AST_Definitions node", 15201 $propdoc: { 15202 name: "[AST_SymbolVar|AST_SymbolConst] name of the variable", 15203 value: "[AST_Node?] initializer, or null of there's no initializer" 15204 }, 15205 _walk: function(visitor) { 15206 return visitor._visit(this, function(){ 15207 this.name._walk(visitor); 15208 if (this.value) this.value._walk(visitor); 15209 }); 15210 } 15211}); 15212 15213/* -----[ OTHER ]----- */ 15214 15215var AST_Call = DEFNODE("Call", "expression args", { 15216 $documentation: "A function call expression", 15217 $propdoc: { 15218 expression: "[AST_Node] expression to invoke as function", 15219 args: "[AST_Node*] array of arguments" 15220 }, 15221 _walk: function(visitor) { 15222 return visitor._visit(this, function(){ 15223 this.expression._walk(visitor); 15224 var args = this.args; 15225 for (var i = 0, len = args.length; i < len; i++) { 15226 args[i]._walk(visitor); 15227 } 15228 }); 15229 } 15230}); 15231 15232var AST_New = DEFNODE("New", null, { 15233 $documentation: "An object instantiation. Derives from a function call since it has exactly the same properties" 15234}, AST_Call); 15235 15236var AST_Seq = DEFNODE("Seq", "car cdr", { 15237 $documentation: "A sequence expression (two comma-separated expressions)", 15238 $propdoc: { 15239 car: "[AST_Node] first element in sequence", 15240 cdr: "[AST_Node] second element in sequence" 15241 }, 15242 $cons: function(x, y) { 15243 var seq = new AST_Seq(x); 15244 seq.car = x; 15245 seq.cdr = y; 15246 return seq; 15247 }, 15248 $from_array: function(array) { 15249 if (array.length == 0) return null; 15250 if (array.length == 1) return array[0].clone(); 15251 var list = null; 15252 for (var i = array.length; --i >= 0;) { 15253 list = AST_Seq.cons(array[i], list); 15254 } 15255 var p = list; 15256 while (p) { 15257 if (p.cdr && !p.cdr.cdr) {
15258 p.cdr = p.cdr.car; 15259 break; 15260 } 15261 p = p.cdr; 15262 } 15263 return list; 15264 }, 15265 to_array: function() { 15266 var p = this, a = []; 15267 while (p) { 15268 a.push(p.car); 15269 if (p.cdr && !(p.cdr instanceof AST_Seq)) { 15270 a.push(p.cdr); 15271 break; 15272 } 15273 p = p.cdr; 15274 } 15275 return a; 15276 }, 15277 add: function(node) { 15278 var p = this; 15279 while (p) { 15280 if (!(p.cdr instanceof AST_Seq)) { 15281 var cell = AST_Seq.cons(p.cdr, node); 15282 return p.cdr = cell; 15283 } 15284 p = p.cdr; 15285 } 15286 }, 15287 len: function() { 15288 if (this.cdr instanceof AST_Seq) { 15289 return this.cdr.len() + 1; 15290 } else { 15291 return 2; 15292 } 15293 }, 15294 _walk: function(visitor) { 15295 return visitor._visit(this, function(){ 15296 this.car._walk(visitor); 15297 if (this.cdr) this.cdr._walk(visitor); 15298 }); 15299 } 15300}); 15301 15302var AST_PropAccess = DEFNODE("PropAccess", "expression property", { 15303 $documentation: "Base class for property access expressions, i.e. `a.foo` or `a[\"foo\"]`", 15304 $propdoc: { 15305 expression: "[AST_Node] the âcontainerâ expression", 15306 property: "[AST_Node|string] the property to access. For AST_Dot this is always a plain string, while for AST_Sub it's an arbitrary AST_Node" 15307 } 15308}); 15309 15310var AST_Dot = DEFNODE("Dot", null, { 15311 $documentation: "A dotted property access expression", 15312 _walk: function(visitor) { 15313 return visitor._visit(this, function(){ 15314 this.expression._walk(visitor); 15315 }); 15316 } 15317}, AST_PropAccess); 15318 15319var AST_Sub = DEFNODE("Sub", null, { 15320 $documentation: "Index-style property access, i.e. `a[\"foo\"]`", 15321 _walk: function(visitor) { 15322 return visitor._visit(this, function(){ 15323 this.expression._walk(visitor); 15324 this.property._walk(visitor); 15325 }); 15326 } 15327}, AST_PropAccess); 15328 15329var AST_Unary = DEFNODE("Unary", "operator expression", { 15330 $documentation: "Base class for unary expressions", 15331 $propdoc: { 15332 operator: "[string] the operator", 15333 expression: "[AST_Node] expression that this unary operator applies to" 15334 }, 15335 _walk: function(visitor) { 15336 return visitor._visit(this, function(){ 15337 this.expression._walk(visitor); 15338 }); 15339 } 15340}); 15341 15342var AST_UnaryPrefix = DEFNODE("UnaryPrefix", null, { 15343 $documentation: "Unary prefix expression, i.e. `typeof i` or `++i`" 15344}, AST_Unary); 15345 15346var AST_UnaryPostfix = DEFNODE("UnaryPostfix", null, { 15347 $documentation: "Unary postfix expression, i.e. `i++`" 15348}, AST_Unary); 15349 15350var AST_Binary = DEFNODE("Binary", "left operator right", { 15351 $documentation: "Binary expression, i.e. `a + b`", 15352 $propdoc: { 15353 left: "[AST_Node] left-hand side expression", 15354 operator: "[string] the operator", 15355 right: "[AST_Node] right-hand side expression" 15356 }, 15357 _walk: function(visitor) { 15358 return visitor._visit(this, function(){ 15359 this.left._walk(visitor); 15360 this.right._walk(visitor); 15361 }); 15362 } 15363}); 15364 15365var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative", { 15366 $documentation: "Conditional expression using the ternary operator, i.e. `a ? b : c`", 15367 $propdoc: { 15368 condition: "[AST_Node]", 15369 consequent: "[AST_Node]", 15370 alternative: "[AST_Node]" 15371 }, 15372 _walk: function(visitor) { 15373 return visitor._visit(this, function(){ 15374 this.condition._walk(visitor); 15375 this.consequent._walk(visitor); 15376 this.alternative._walk(visitor); 15377 }); 15378 } 15379}); 15380 15381var AST_Assign = DEFNODE("Assign", null, { 15382 $documentation: "An assignment expression â `a = b + 5`", 15383}, AST_Binary); 15384 15385/* -----[ LITERALS ]----- */ 15386 15387var AST_Array = DEFNODE("Array", "elements", { 15388 $documentation: "An array literal", 15389 $propdoc: { 15390 elements: "[AST_Node*] array of elements" 15391 }, 15392 _walk: function(visitor) { 15393 return visitor._visit(this, function(){ 15394 var elements = this.elements; 15395 for (var i = 0, len = elements.length; i < len; i++) { 15396 elements[i]._walk(visitor); 15397 } 15398 }); 15399 } 15400}); 15401 15402var AST_Object = DEFNODE("Object", "properties", { 15403 $documentation: "An object literal", 15404 $propdoc: { 15405 properties: "[AST_ObjectProperty*] array of properties" 15406 }, 15407 _walk: function(visitor) { 15408 return visitor._visit(this, function(){ 15409 var properties = this.properties; 15410 for (var i = 0, len = properties.length; i < len; i++) { 15411 properties[i]._walk(visitor); 15412 } 15413 }); 15414 } 15415}); 15416 15417var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", { 15418 $documentation: "Base class for literal object properties", 15419 $propdoc: { 15420 key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an AST_SymbolAccessor.", 15421 value: "[AST_Node] property value. For setters and getters this is an AST_Acce
15421ssor." 15422 }, 15423 _walk: function(visitor) { 15424 return visitor._visit(this, function(){ 15425 this.value._walk(visitor); 15426 }); 15427 } 15428}); 15429 15430var AST_ObjectKeyVal = DEFNODE("ObjectKeyVal", "quote", { 15431 $documentation: "A key: value object property", 15432 $propdoc: { 15433 quote: "[string] the original quote character" 15434 } 15435}, AST_ObjectProperty); 15436 15437var AST_ObjectSetter = DEFNODE("ObjectSetter", null, { 15438 $documentation: "An object setter property", 15439}, AST_ObjectProperty); 15440 15441var AST_ObjectGetter = DEFNODE("ObjectGetter", null, { 15442 $documentation: "An object getter property", 15443}, AST_ObjectProperty); 15444 15445var AST_Symbol = DEFNODE("Symbol", "scope name thedef", { 15446 $propdoc: { 15447 name: "[string] name of this symbol", 15448 scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)", 15449 thedef: "[SymbolDef/S] the definition of this symbol" 15450 }, 15451 $documentation: "Base class for all symbols", 15452}); 15453 15454var AST_SymbolAccessor = DEFNODE("SymbolAccessor", null, { 15455 $documentation: "The name of a property accessor (setter/getter function)" 15456}, AST_Symbol); 15457 15458var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", { 15459 $documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)", 15460}, AST_Symbol); 15461 15462var AST_SymbolVar = DEFNODE("SymbolVar", null, { 15463 $documentation: "Symbol defining a variable", 15464}, AST_SymbolDeclaration); 15465 15466var AST_SymbolConst = DEFNODE("SymbolConst", null, { 15467 $documentation: "A constant declaration" 15468}, AST_SymbolDeclaration); 15469 15470var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, { 15471 $documentation: "Symbol naming a function argument", 15472}, AST_SymbolVar); 15473 15474var AST_SymbolDefun = DEFNODE("SymbolDefun", null, { 15475 $documentation: "Symbol defining a function", 15476}, AST_SymbolDeclaration); 15477 15478var AST_SymbolLambda = DEFNODE("SymbolLambda", null, { 15479 $documentation: "Symbol naming a function expression", 15480}, AST_SymbolDeclaration); 15481 15482var AST_SymbolCatch = DEFNODE("SymbolCatch", null, { 15483 $documentation: "Symbol naming the exception in catch", 15484}, AST_SymbolDeclaration); 15485 15486var AST_Label = DEFNODE("Label", "references", { 15487 $documentation: "Symbol naming a label (declaration)", 15488 $propdoc: { 15489 references: "[AST_LoopControl*] a list of nodes referring to this label" 15490 }, 15491 initialize: function() { 15492 this.references = []; 15493 this.thedef = this; 15494 } 15495}, AST_Symbol); 15496 15497var AST_SymbolRef = DEFNODE("SymbolRef", null, { 15498 $documentation: "Reference to some symbol (not definition/declaration)", 15499}, AST_Symbol); 15500 15501var AST_LabelRef = DEFNODE("LabelRef", null, { 15502 $documentation: "Reference to a label symbol", 15503}, AST_Symbol); 15504 15505var AST_This = DEFNODE("This", null, { 15506 $documentation: "The `this` symbol", 15507}, AST_Symbol); 15508 15509var AST_Constant = DEFNODE("Constant", null, { 15510 $documentation: "Base class for all constants", 15511 getValue: function() { 15512 return this.value; 15513 } 15514}); 15515 15516var AST_String = DEFNODE("String", "value quote", { 15517 $documentation: "A string literal", 15518 $propdoc: { 15519 value: "[string] the contents of this string", 15520 quote: "[string] the original quote character" 15521 } 15522}, AST_Constant); 15523 15524var AST_Number = DEFNODE("Number", "value literal", { 15525 $documentation: "A number literal", 15526 $propdoc: { 15527 value: "[number] the numeric value", 15528 literal: "[string] numeric value as string (optional)" 15529 } 15530}, AST_Constant); 15531 15532var AST_RegExp = DEFNODE("RegExp", "value", { 15533 $documentation: "A regexp literal", 15534 $propdoc: { 15535 value: "[RegExp] the actual regexp" 15536 } 15537}, AST_Constant); 15538 15539var AST_Atom = DEFNODE("Atom", null, { 15540 $documentation: "Base class for atoms", 15541}, AST_Constant); 15542 15543var AST_Null = DEFNODE("Null", null, { 15544 $documentation: "The `null` atom", 15545 value: null 15546}, AST_Atom); 15547 15548var AST_NaN = DEFNODE("NaN", null, { 15549 $documentation: "The impossible value", 15550 value: 0/0 15551}, AST_Atom); 15552 15553var AST_Undefined = DEFNODE("Undefined", null, { 15554 $documentation: "The `undefined` value", 15555 value: (function(){}()) 15556}, AST_Atom); 15557 15558var AST_Hole = DEFNODE("Hole", null, { 15559 $documentation: "A hole in an array", 15560 value: (function(){}()) 15561}, AST_Atom); 15562 15563var AST_Infinity = DEFNODE("Infinity", null, { 15564 $documentation: "The `Infinity` value", 15565 value: 1/0 15566}, AST_Atom); 15567 15568var AST_Boolean = DEFNODE("Boolean", null, { 15569 $documentation: "Base class for booleans", 15570}, AST_Atom); 15571 15572var AST_False = DEFNODE("False", null, { 15573 $documentation: "The `false` atom", 15574 value: false 15575}, AST_Boolean); 15576 15577var AST_True = DEFNODE("True", null, { 15578 $documentation: "The `true` atom", 15579 value: true 15580}, AST_Boolean); 15581 15582/* -----[ TreeWalker ]----- */ 15583 15584function TreeWalker(callback) { 15585 this.visit = callback; 15586 this.stack = []; 15587 this.directives = Object.create(null); 15588}; 15589TreeWalker.prototype = { 15590 _visit: function(node, descend) { 15591 this.push(node); 15592 var ret = this.visit(node, descend ? function(){ 15593 descend.call(node); 15594 } : noop); 15595 if (!ret && descend) { 15596 descend.call(node); 15597 } 15598 this.pop(node); 15599 return ret; 15600 }, 15601 parent: function(n) { 15602 return this.stack[this.stack.length - 2 - (n || 0)]; 15603 }, 15604 push: function (node) { 15605 if (node instanceof AST_Lambda) { 15606 this.directives = Object.create(this.directives); 15607 } else if (node instanceof AST_Directive && !this.directives[node.value]) { 15608 this.directives[node.value] = node; 15609 } 15610 this.stack.push(node); 15611 }, 15612 pop: function(node) { 15613 this.stack.pop(); 15614 if (node instanceof AST_Lambda) { 15615 this.directives = Object.getPrototypeOf(this.directives); 15616 } 15617 }, 15618 self: function() { 15619 return this.stack[this.stack.length - 1]; 15620 }, 15621 find_parent: function(type) { 15622 var stack = this.stack; 15623 for (var i = stack.length; --i >= 0;) { 15624 var x = stack[i]; 15625 if (x instanceof type) return x; 15626 } 15627 }, 15628 has_directive: function(type) { 15629 var dir = this.directives[type]; 15630 if (dir) return dir; 15631 var node = this.stack[this.stack.length - 1]; 15632 if (node instanceof AST_Scope) { 15633 for (var i = 0; i < node.body.length; ++i) { 15634 var st = node.body[i]; 15635 if (!(st instanceof AST_Directive)) break; 15636 if (st.value == type) return st; 15637 } 15638 } 15639 }, 15640 in_boolean_context: function() { 15641 var stack = this.stack; 15642 var i = stack.length, self = stack[--i]; 15643 while (i > 0) { 15644 var p = stack[--i]; 15645 if ((p instanceof AST_If && p.condition === self) || 15646 (p instanceof AST_Conditional && p.condition === self) || 15647 (p instanceof AST_DWLoop && p.condition === self) || 15648 (p instanceof AST_For && p.condition === self) || 15649 (p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self)) 15650 { 15651 return true; 15652 } 15653 if (!(p instanceof AST_Binary && (p.operator == "&&" || p.operator == "||"))) 15654 return false; 15655 self = p; 15656 } 15657 }, 15658 loopcontrol_target: function(node) { 15659 var stack = this.stack; 15660 if (node.label) for (var i = stack.length; --i >= 0;) { 15661 var x = stack[i]; 15662 if (x instanceof AST_LabeledStatement && x.label.name == node.label.name) 15663 return x.body; 15664 } else for (var i = stack.length; --i >= 0;) { 15665 var x = stack[i]; 15666 if (x instanceof AST_IterationStatement 15667 || node instanceof AST_Break && x instanceof AST_Switch) 15668 return x; 15669 } 15670 } 15671}; 15672 15673/*********************************************************************** 15674 15675 A JavaScript tokenizer / parser / beautifier / compressor. 15676 https://github.com/mishoo/UglifyJS2 15677 15678 -------------------------------- (C) --------------------------------- 15679 15680 Author: Mihai Bazon 15681 <[email protected]> 15682 http://mihai.bazon.net/blog 15683 15684 Distributed under the BSD license: 15685 15686 Copyright 2012 (c) Mihai Bazon <[email protected]> 15687 Parser based on parse-js (http://marijn.haverbeke.nl/parse-js/). 15688 15689 Redistribution and use in source and binary forms, with or without 15690 modification, are permitted provided that the following conditions 15691 are met: 15692 15693 * Redistributions of source code must retain the above 15694 copyright notice, this list of conditions and the following 15695 disclaimer. 15696 15697 * Redistributions in binary form must reproduce the above 15698 copyright notice, this list of conditions and the following 15699 disclaimer in the documentation and/or other materials 15700 provided with the distribution. 15701 15702 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER âAS ISâ AND ANY 15703 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15704 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 15705 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE 15706 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
15707 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 15708 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 15709 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 15710 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 15711 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 15712 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 15713 SUCH DAMAGE. 15714 15715 ***********************************************************************/ 15716 15717"use strict"; 15718 15719var KEYWORDS = 'break case catch const continue debugger default delete do else finally for function if in instanceof new return switch throw try typeof var void while with'; 15720var KEYWORDS_ATOM = 'false null true'; 15721var RESERVED_WORDS = 'abstract boolean byte char class double enum export extends final float goto implements import int interface let long native package private protected public short static super synchronized this throws transient volatile yield' 15722 + " " + KEYWORDS_ATOM + " " + KEYWORDS; 15723var KEYWORDS_BEFORE_EXPRESSION = 'return new delete throw else case'; 15724 15725KEYWORDS = makePredicate(KEYWORDS); 15726RESERVED_WORDS = makePredicate(RESERVED_WORDS); 15727KEYWORDS_BEFORE_EXPRESSION = makePredicate(KEYWORDS_BEFORE_EXPRESSION); 15728KEYWORDS_ATOM = makePredicate(KEYWORDS_ATOM); 15729 15730var OPERATOR_CHARS = makePredicate(characters("+-*&%=<>!?|~^")); 15731 15732var RE_HEX_NUMBER = /^0x[0-9a-f]+$/i; 15733var RE_OCT_NUMBER = /^0[0-7]+$/; 15734 15735var OPERATORS = makePredicate([ 15736 "in", 15737 "instanceof", 15738 "typeof", 15739 "new", 15740 "void", 15741 "delete", 15742 "++", 15743 "--", 15744 "+", 15745 "-", 15746 "!", 15747 "~", 15748 "&", 15749 "|", 15750 "^", 15751 "*", 15752 "/", 15753 "%", 15754 ">>", 15755 "<<", 15756 ">>>", 15757 "<", 15758 ">", 15759 "<=", 15760 ">=", 15761 "==", 15762 "===", 15763 "!=", 15764 "!==", 15765 "?", 15766 "=", 15767 "+=", 15768 "-=", 15769 "/=", 15770 "*=", 15771 "%=", 15772 ">>=", 15773 "<<=", 15774 ">>>=", 15775 "|=", 15776 "^=", 15777 "&=", 15778 "&&", 15779 "||" 15780]); 15781 15782var WHITESPACE_CHARS = makePredicate(characters(" \u00a0\n\r\t\f\u000b\u200b\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000\uFEFF")); 15783 15784var NEWLINE_CHARS = makePredicate(characters("\n\r\u2028\u2029")); 15785 15786var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,;:")); 15787 15788var PUNC_CHARS = makePredicate(characters("[]{}(),;:")); 15789 15790var REGEXP_MODIFIERS = makePredicate(characters("gmsiy")); 15791 15792/* -----[ Tokenizer ]----- */ 15793 15794// regexps adapted from http://xregexp.com/plugins/#unicode 15795var UNICODE = { 15796 letter: new RegExp("[\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u08A0-\\u08B2\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u
157960AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F8\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6EF\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA7AD\\uA7B0\\uA7B1\\uA7F7-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB5F\\uAB64\\uAB65\\uABC0-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]"), 15797 digit: new RegExp("[\\u0030-\\u0039\\u0660-\\u0669\\u06F0-\\u06F9\\u07C0-\\u07C9\\u0966-\\u096F\\u09E6-\\u09EF\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0BE6-\\u0BEF\\u0C66-\\u0C6F\\u0CE6-\\u0CEF\\u0D66-\\u0D6F\\u0DE6-\\u
157970DEF\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F29\\u1040-\\u1049\\u1090-\\u1099\\u17E0-\\u17E9\\u1810-\\u1819\\u1946-\\u194F\\u19D0-\\u19D9\\u1A80-\\u1A89\\u1A90-\\u1A99\\u1B50-\\u1B59\\u1BB0-\\u1BB9\\u1C40-\\u1C49\\u1C50-\\u1C59\\uA620-\\uA629\\uA8D0-\\uA8D9\\uA900-\\uA909\\uA9D0-\\uA9D9\\uA9F0-\\uA9F9\\uAA50-\\uAA59\\uABF0-\\uABF9\\uFF10-\\uFF19]"), 15798 non_spacing_mark: new RegExp("[\\u0300-\\u036F\\u0483-\\u0487\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065E\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0900-\\u0902\\u093C\\u0941-\\u0948\\u094D\\u0951-\\u0955\\u0962\\u0963\\u0981\\u09BC\\u09C1-\\u09C4\\u09CD\\u09E2\\u09E3\\u0A01\\u0A02\\u0A3C\\u0A41\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81\\u0A82\\u0ABC\\u0AC1-\\u0AC5\\u0AC7\\u0AC8\\u0ACD\\u0AE2\\u0AE3\\u0B01\\u0B3C\\u0B3F\\u0B41-\\u0B44\\u0B4D\\u0B56\\u0B62\\u0B63\\u0B82\\u0BC0\\u0BCD\\u0C3E-\\u0C40\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0CBC\\u0CBF\\u0CC6\\u0CCC\\u0CCD\\u0CE2\\u0CE3\\u0D41-\\u0D44\\u0D4D\\u0D62\\u0D63\\u0DCA\\u0DD2-\\u0DD4\\u0DD6\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F71-\\u0F7E\\u0F80-\\u0F84\\u0F86\\u0F87\\u0F90-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102D-\\u1030\\u1032-\\u1037\\u1039\\u103A\\u103D\\u103E\\u1058\\u1059\\u105E-\\u1060\\u1071-\\u1074\\u1082\\u1085\\u1086\\u108D\\u109D\\u135F\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17B7-\\u17BD\\u17C6\\u17C9-\\u17D3\\u17DD\\u180B-\\u180D\\u18A9\\u1920-\\u1922\\u1927\\u1928\\u1932\\u1939-\\u193B\\u1A17\\u1A18\\u1A56\\u1A58-\\u1A5E\\u1A60\\u1A62\\u1A65-\\u1A6C\\u1A73-\\u1A7C\\u1A7F\\u1B00-\\u1B03\\u1B34\\u1B36-\\u1B3A\\u1B3C\\u1B42\\u1B6B-\\u1B73\\u1B80\\u1B81\\u1BA2-\\u1BA5\\u1BA8\\u1BA9\\u1C2C-\\u1C33\\u1C36\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE0\\u1CE2-\\u1CE8\\u1CED\\u1DC0-\\u1DE6\\u1DFD-\\u1DFF\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2CEF-\\u2CF1\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F\\uA67C\\uA67D\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA825\\uA826\\uA8C4\\uA8E0-\\uA8F1\\uA926-\\uA92D\\uA947-\\uA951\\uA980-\\uA982\\uA9B3\\uA9B6-\\uA9B9\\uA9BC\\uAA29-\\uAA2E\\uAA31\\uAA32\\uAA35\\uAA36\\uAA43\\uAA4C\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uABE5\\uABE8\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE26]"), 15799 space_combining_mark: new RegExp("[\\u0903\\u093E-\\u0940\\u0949-\\u094C\\u094E\\u0982\\u0983\\u09BE-\\u09C0\\u09C7\\u09C8\\u09CB\\u09CC\\u09D7\\u0A03\\u0A3E-\\u0A40\\u0A83\\u0ABE-\\u0AC0\\u0AC9\\u0ACB\\u0ACC\\u0B02\\u0B03\\u0B3E\\u0B40\\u0B47\\u0B48\\u0B4B\\u0B4C\\u0B57\\u0BBE\\u0BBF\\u0BC1\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCC\\u0BD7\\u0C01-\\u0C03\\u0C41-\\u0C44\\u0C82\\u0C83\\u0CBE\\u0CC0-\\u0CC4\\u0CC7\\u0CC8\\u0CCA\\u0CCB\\u0CD5\\u0CD6\\u0D02\\u0D03\\u0D3E-\\u0D40\\u0D46-\\u0D48\\u0D4A-\\u0D4C\\u0D57\\u0D82\\u0D83\\u0DCF-\\u0DD1\\u0DD8-\\u0DDF\\u0DF2\\u0DF3\\u0F3E\\u0F3F\\u0F7F\\u102B\\u102C\\u1031\\u1038\\u103B\\u103C\\u1056\\u1057\\u1062-\\u1064\\u1067-\\u106D\\u1083\\u1084\\u1087-\\u108C\\u108F\\u109A-\\u109C\\u17B6\\u17BE-\\u17C5\\u17C7\\u17C8\\u1923-\\u1926\\u1929-\\u192B\\u1930\\u1931\\u1933-\\u1938\\u19B0-\\u19C0\\u19C8\\u19C9\\u1A19-\\u1A1B\\u1A55\\u1A57\\u1A61\\u1A63\\u1A64\\u1A6D-\\u1A72\\u1B04\\u1B35\\u1B3B\\u1B3D-\\u1B41\\u1B43\\u1B44\\u1B82\\u1BA1\\u1BA6\\u1BA7\\u1BAA\\u1C24-\\u1C2B\\u1C34\\u1C35\\u1CE1\\u1CF2\\uA823\\uA824\\uA827\\uA880\\uA881\\uA8B4-\\uA8C3\\uA952\\uA953\\uA983\\uA9B4\\uA9B5\\uA9BA\\uA9BB\\uA9BD-\\uA9C0\\uAA2F\\uAA30\\uAA33\\uAA34\\uAA4D\\uAA7B\\uABE3\\uABE4\\uABE6\\uABE7\\uABE9\\uABEA\\uABEC]"), 15800 connector_punctuation: new RegExp("[\\u005F\\u203F\\u2040\\u2054\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFF3F]") 15801}; 15802 15803function is_letter(code) { 15804 return (code >= 97 && code <= 122) 15805 || (code >= 65 && code <= 90) 15806 || (code >= 0xaa && UNICODE.letter.test(String.fromCharCode(code))); 15807}; 15808 15809function is_digit(code) { 15810 return code >= 48 && code <= 57; 15811}; 15812 15813function is_alphanumeric_char(code) { 15814 return is_digit(code) || is_letter(code); 15815};
15816 15817function is_unicode_digit(code) { 15818 return UNICODE.digit.test(String.fromCharCode(code)); 15819} 15820 15821function is_unicode_combining_mark(ch) { 15822 return UNICODE.non_spacing_mark.test(ch) || UNICODE.space_combining_mark.test(ch); 15823}; 15824 15825function is_unicode_connector_punctuation(ch) { 15826 return UNICODE.connector_punctuation.test(ch); 15827}; 15828 15829function is_identifier(name) { 15830 return !RESERVED_WORDS(name) && /^[a-z_$][a-z0-9_$]*$/i.test(name); 15831}; 15832 15833function is_identifier_start(code) { 15834 return code == 36 || code == 95 || is_letter(code); 15835}; 15836 15837function is_identifier_char(ch) { 15838 var code = ch.charCodeAt(0); 15839 return is_identifier_start(code) 15840 || is_digit(code) 15841 || code == 8204 // \u200c: zero-width non-joiner <ZWNJ> 15842 || code == 8205 // \u200d: zero-width joiner <ZWJ> (in my ECMA-262 PDF, this is also 200c) 15843 || is_unicode_combining_mark(ch) 15844 || is_unicode_connector_punctuation(ch) 15845 || is_unicode_digit(code) 15846 ; 15847}; 15848 15849function is_identifier_string(str){ 15850 return /^[a-z_$][a-z0-9_$]*$/i.test(str); 15851}; 15852 15853function parse_js_number(num) { 15854 if (RE_HEX_NUMBER.test(num)) { 15855 return parseInt(num.substr(2), 16); 15856 } else if (RE_OCT_NUMBER.test(num)) { 15857 return parseInt(num.substr(1), 8); 15858 } else { 15859 var val = parseFloat(num); 15860 if (val == num) return val; 15861 } 15862}; 15863 15864function JS_Parse_Error(message, filename, line, col, pos) { 15865 this.message = message; 15866 this.filename = filename; 15867 this.line = line; 15868 this.col = col; 15869 this.pos = pos; 15870}; 15871JS_Parse_Error.prototype = Object.create(Error.prototype); 15872JS_Parse_Error.prototype.constructor = JS_Parse_Error; 15873JS_Parse_Error.prototype.name = "SyntaxError"; 15874configure_error_stack(JS_Parse_Error); 15875 15876function js_error(message, filename, line, col, pos) { 15877 throw new JS_Parse_Error(message, filename, line, col, pos); 15878}; 15879 15880function is_token(token, type, val) { 15881 return token.type == type && (val == null || token.value == val); 15882}; 15883 15884var EX_EOF = {}; 15885 15886function tokenizer($TEXT, filename, html5_comments, shebang) { 15887 15888 var S = { 15889 text : $TEXT, 15890 filename : filename, 15891 pos : 0, 15892 tokpos : 0, 15893 line : 1, 15894 tokline : 0, 15895 col : 0, 15896 tokcol : 0, 15897 newline_before : false, 15898 regex_allowed : false, 15899 comments_before : [], 15900 directives : {}, 15901 directive_stack : [] 15902 }; 15903 15904 function peek() { return S.text.charAt(S.pos); }; 15905 15906 function next(signal_eof, in_string) { 15907 var ch = S.text.charAt(S.pos++); 15908 if (signal_eof && !ch) 15909 throw EX_EOF; 15910 if (NEWLINE_CHARS(ch)) { 15911 S.newline_before = S.newline_before || !in_string; 15912 ++S.line; 15913 S.col = 0; 15914 if (!in_string && ch == "\r" && peek() == "\n") { 15915 // treat a \r\n sequence as a single \n 15916 ++S.pos; 15917 ch = "\n"; 15918 } 15919 } else { 15920 ++S.col; 15921 } 15922 return ch; 15923 }; 15924 15925 function forward(i) { 15926 while (i-- > 0) next(); 15927 }; 15928 15929 function looking_at(str) { 15930 return S.text.substr(S.pos, str.length) == str; 15931 }; 15932 15933 function find_eol() { 15934 var text = S.text; 15935 for (var i = S.pos, n = S.text.length; i < n; ++i) { 15936 var ch = text[i]; 15937 if (NEWLINE_CHARS(ch)) 15938 return i; 15939 } 15940 return -1; 15941 }; 15942 15943 function find(what, signal_eof) { 15944 var pos = S.text.indexOf(what, S.pos); 15945 if (signal_eof && pos == -1) throw EX_EOF; 15946 return pos; 15947 }; 15948 15949 function start_token() { 15950 S.tokline = S.line; 15951 S.tokcol = S.col; 15952 S.tokpos = S.pos; 15953 }; 15954 15955 var prev_was_dot = false; 15956 function token(type, value, is_comment) { 15957 S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX(value)) || 15958 (type == "keyword" && KEYWORDS_BEFORE_EXPRESSION(value)) || 15959 (type == "punc" && PUNC_BEFORE_EXPRESSION(value))); 15960 if (type == "punc" && value == ".") { 15961 prev_was_dot = true; 15962 } else if (!is_comment) { 15963 prev_was_dot = false; 15964 } 15965 var ret = { 15966 type : type, 15967 value : value, 15968 line : S.tokline, 15969 col : S.tokcol, 15970 pos : S.tokpos, 15971 endline : S.line, 15972 endcol : S.col, 15973 endpos : S.pos, 15974 nlb : S.newline_before, 15975 file : filename 15976 }; 15977 if (/^(?:num|string|regexp)$/i.test(type)) { 15978 ret.raw = $TEXT.substring(ret.pos, ret.endpos); 15979 } 15980 if (!is_comment) { 15981 ret.comments_before = S.comments_before; 15982 S.comments_before = []; 15983 // make note of any newlines in the comments that came before 15984 for (var i = 0, len = ret.comments_before.length; i < len; i++) { 15985 ret.nlb = ret.nlb || ret.comments_before[i].nlb; 15986 } 15987 } 15988 S.newline_before = false; 15989 return new AST_Token(ret); 15990 }; 15991 15992 function skip_whitespace() { 15993 while (WHITESPACE_CHARS(peek())) 15994 next(); 15995 }; 15996 15997 function read_while(pred) { 15998 var ret = "", ch, i = 0; 15999 while ((ch = peek()) && pred(ch, i++)) 16000 ret += next(); 16001 return ret; 16002 }; 16003 16004 function parse_error(err) { 16005 js_error(err, filename, S.tokline, S.tokcol, S.tokpos); 16006 }; 16007 16008 function read_num(prefix) { 16009 var has_e = false, after_e = false, has_x = false, has_dot = prefix == "."; 16010 var num = read_while(function(ch, i){
16011 var code = ch.charCodeAt(0); 16012 switch (code) { 16013 case 120: case 88: // xX 16014 return has_x ? false : (has_x = true); 16015 case 101: case 69: // eE 16016 return has_x ? true : has_e ? false : (has_e = after_e = true); 16017 case 45: // - 16018 return after_e || (i == 0 && !prefix); 16019 case 43: // + 16020 return after_e; 16021 case (after_e = false, 46): // . 16022 return (!has_dot && !has_x && !has_e) ? (has_dot = true) : false; 16023 } 16024 return is_alphanumeric_char(code); 16025 }); 16026 if (prefix) num = prefix + num; 16027 if (RE_OCT_NUMBER.test(num) && next_token.has_directive("use strict")) { 16028 parse_error("Legacy octal literals are not allowed in strict mode"); 16029 } 16030 var valid = parse_js_number(num); 16031 if (!isNaN(valid)) { 16032 return token("num", valid); 16033 } else { 16034 parse_error("Invalid syntax: " + num); 16035 } 16036 }; 16037 16038 function read_escaped_char(in_string) { 16039 var ch = next(true, in_string); 16040 switch (ch.charCodeAt(0)) { 16041 case 110 : return "\n"; 16042 case 114 : return "\r"; 16043 case 116 : return "\t"; 16044 case 98 : return "\b"; 16045 case 118 : return "\u000b"; // \v 16046 case 102 : return "\f"; 16047 case 120 : return String.fromCharCode(hex_bytes(2)); // \x 16048 case 117 : return String.fromCharCode(hex_bytes(4)); // \u 16049 case 10 : return ""; // newline 16050 case 13 : // \r 16051 if (peek() == "\n") { // DOS newline 16052 next(true, in_string); 16053 return ""; 16054 } 16055 } 16056 if (ch >= "0" && ch <= "7") 16057 return read_octal_escape_sequence(ch); 16058 return ch; 16059 }; 16060 16061 function read_octal_escape_sequence(ch) { 16062 // Read 16063 var p = peek(); 16064 if (p >= "0" && p <= "7") { 16065 ch += next(true); 16066 if (ch[0] <= "3" && (p = peek()) >= "0" && p <= "7") 16067 ch += next(true); 16068 } 16069 16070 // Parse 16071 if (ch === "0") return "\0"; 16072 if (ch.length > 0 && next_token.has_directive("use strict")) 16073 parse_error("Legacy octal escape sequences are not allowed in strict mode"); 16074 return String.fromCharCode(parseInt(ch, 8)); 16075 } 16076 16077 function hex_bytes(n) { 16078 var num = 0; 16079 for (; n > 0; --n) { 16080 var digit = parseInt(next(true), 16); 16081 if (isNaN(digit)) 16082 parse_error("Invalid hex-character pattern in string"); 16083 num = (num << 4) | digit; 16084 } 16085 return num; 16086 }; 16087 16088 var read_string = with_eof_error("Unterminated string constant", function(quote_char){ 16089 var quote = next(), ret = ""; 16090 for (;;) { 16091 var ch = next(true, true); 16092 if (ch == "\\") ch = read_escaped_char(true); 16093 else if (NEWLINE_CHARS(ch)) parse_error("Unterminated string constant"); 16094 else if (ch == quote) break; 16095 ret += ch; 16096 } 16097 var tok = token("string", ret); 16098 tok.quote = quote_char; 16099 return tok; 16100 }); 16101 16102 function skip_line_comment(type) { 16103 var regex_allowed = S.regex_allowed; 16104 var i = find_eol(), ret; 16105 if (i == -1) { 16106 ret = S.text.substr(S.pos); 16107 S.pos = S.text.length; 16108 } else { 16109 ret = S.text.substring(S.pos, i); 16110 S.pos = i; 16111 } 16112 S.col = S.tokcol + (S.pos - S.tokpos); 16113 S.comments_before.push(token(type, ret, true)); 16114 S.regex_allowed = regex_allowed; 16115 return next_token; 16116 }; 16117 16118 var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function(){ 16119 var regex_allowed = S.regex_allowed; 16120 var i = find("*/", true); 16121 var text = S.text.substring(S.pos, i).replace(/\r\n|\r|\u2028|\u2029/g, '\n'); 16122 // update stream position 16123 forward(text.length /* doesn't count \r\n as 2 char while S.pos - i does */ + 2); 16124 S.comments_before.push(token("comment2", text, true)); 16125 S.regex_allowed = regex_allowed; 16126 return next_token; 16127 });
16128 16129 function read_name() { 16130 var backslash = false, name = "", ch, escaped = false, hex; 16131 while ((ch = peek()) != null) { 16132 if (!backslash) { 16133 if (ch == "\\") escaped = backslash = true, next(); 16134 else if (is_identifier_char(ch)) name += next(); 16135 else break; 16136 } 16137 else { 16138 if (ch != "u") parse_error("Expecting UnicodeEscapeSequence -- uXXXX"); 16139 ch = read_escaped_char(); 16140 if (!is_identifier_char(ch)) parse_error("Unicode char: " + ch.charCodeAt(0) + " is not valid in identifier"); 16141 name += ch; 16142 backslash = false; 16143 } 16144 } 16145 if (KEYWORDS(name) && escaped) { 16146 hex = name.charCodeAt(0).toString(16).toUpperCase(); 16147 name = "\\u" + "0000".substr(hex.length) + hex + name.slice(1); 16148 } 16149 return name; 16150 }; 16151 16152 var read_regexp = with_eof_error("Unterminated regular expression", function(regexp){ 16153 var prev_backslash = false, ch, in_class = false; 16154 while ((ch = next(true))) if (NEWLINE_CHARS(ch)) { 16155 parse_error("Unexpected line terminator"); 16156 } else if (prev_backslash) { 16157 regexp += "\\" + ch; 16158 prev_backslash = false; 16159 } else if (ch == "[") { 16160 in_class = true; 16161 regexp += ch; 16162 } else if (ch == "]" && in_class) { 16163 in_class = false; 16164 regexp += ch; 16165 } else if (ch == "/" && !in_class) { 16166 break; 16167 } else if (ch == "\\") { 16168 prev_backslash = true; 16169 } else { 16170 regexp += ch; 16171 } 16172 var mods = read_name(); 16173 try { 16174 return token("regexp", new RegExp(regexp, mods)); 16175 } catch(e) { 16176 parse_error(e.message); 16177 } 16178 }); 16179 16180 function read_operator(prefix) { 16181 function grow(op) { 16182 if (!peek()) return op; 16183 var bigger = op + peek(); 16184 if (OPERATORS(bigger)) { 16185 next(); 16186 return grow(bigger); 16187 } else { 16188 return op; 16189 } 16190 }; 16191 return token("operator", grow(prefix || next())); 16192 }; 16193 16194 function handle_slash() { 16195 next(); 16196 switch (peek()) { 16197 case "/": 16198 next(); 16199 return skip_line_comment("comment1"); 16200 case "*": 16201 next(); 16202 return skip_multiline_comment(); 16203 } 16204 return S.regex_allowed ? read_regexp("") : read_operator("/"); 16205 }; 16206 16207 function handle_dot() { 16208 next(); 16209 return is_digit(peek().charCodeAt(0)) 16210 ? read_num(".") 16211 : token("punc", "."); 16212 }; 16213 16214 function read_word() { 16215 var word = read_name(); 16216 if (prev_was_dot) return token("name", word); 16217 return KEYWORDS_ATOM(word) ? token("atom", word) 16218 : !KEYWORDS(word) ? token("name", word) 16219 : OPERATORS(word) ? token("operator", word) 16220 : token("keyword", word); 16221 }; 16222 16223 function with_eof_error(eof_error, cont) { 16224 return function(x) { 16225 try { 16226 return cont(x); 16227 } catch(ex) { 16228 if (ex === EX_EOF) parse_error(eof_error); 16229 else throw ex; 16230 } 16231 }; 16232 }; 16233 16234 function next_token(force_regexp) { 16235 if (force_regexp != null) 16236 return read_regexp(force_regexp); 16237 if (shebang && S.pos == 0 && looking_at("#!")) { 16238 start_token(); 16239 forward(2); 16240 skip_line_comment("comment5"); 16241 } 16242 for (;;) { 16243 skip_whitespace(); 16244 start_token(); 16245 if (html5_comments) { 16246 if (looking_at("<!--")) { 16247 forward(4); 16248 skip_line_comment("comment3"); 16249 continue; 16250 } 16251 if (looking_at("-->") && S.newline_before) { 16252 forward(3); 16253 skip_line_comment("comment4"); 16254 continue; 16255 } 16256 } 16257 var ch = peek(); 16258 if (!ch) return token("eof");
16259 var code = ch.charCodeAt(0); 16260 switch (code) { 16261 case 34: case 39: return read_string(ch); 16262 case 46: return handle_dot(); 16263 case 47: { 16264 var tok = handle_slash(); 16265 if (tok === next_token) continue; 16266 return tok; 16267 } 16268 } 16269 if (is_digit(code)) return read_num(); 16270 if (PUNC_CHARS(ch)) return token("punc", next()); 16271 if (OPERATOR_CHARS(ch)) return read_operator(); 16272 if (code == 92 || is_identifier_start(code)) return read_word(); 16273 break; 16274 } 16275 parse_error("Unexpected character '" + ch + "'"); 16276 }; 16277 16278 next_token.context = function(nc) { 16279 if (nc) S = nc; 16280 return S; 16281 }; 16282 16283 next_token.add_directive = function(directive) { 16284 S.directive_stack[S.directive_stack.length - 1].push(directive); 16285 16286 if (S.directives[directive] === undefined) { 16287 S.directives[directive] = 1; 16288 } else { 16289 S.directives[directive]++; 16290 } 16291 } 16292 16293 next_token.push_directives_stack = function() { 16294 S.directive_stack.push([]); 16295 } 16296 16297 next_token.pop_directives_stack = function() { 16298 var directives = S.directive_stack[S.directive_stack.length - 1]; 16299 16300 for (var i = 0; i < directives.length; i++) { 16301 S.directives[directives[i]]--; 16302 } 16303 16304 S.directive_stack.pop(); 16305 } 16306 16307 next_token.has_directive = function(directive) { 16308 return S.directives[directive] !== undefined && 16309 S.directives[directive] > 0; 16310 } 16311 16312 return next_token; 16313 16314}; 16315 16316/* -----[ Parser (constants) ]----- */ 16317 16318var UNARY_PREFIX = makePredicate([ 16319 "typeof", 16320 "void", 16321 "delete", 16322 "--", 16323 "++", 16324 "!", 16325 "~", 16326 "-", 16327 "+" 16328]); 16329 16330var UNARY_POSTFIX = makePredicate([ "--", "++" ]); 16331 16332var ASSIGNMENT = makePredicate([ "=", "+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]); 16333 16334var PRECEDENCE = (function(a, ret){ 16335 for (var i = 0; i < a.length; ++i) { 16336 var b = a[i]; 16337 for (var j = 0; j < b.length; ++j) { 16338 ret[b[j]] = i + 1; 16339 } 16340 } 16341 return ret; 16342})( 16343 [ 16344 ["||"], 16345 ["&&"], 16346 ["|"], 16347 ["^"], 16348 ["&"], 16349 ["==", "===", "!=", "!=="], 16350 ["<", ">", "<=", ">=", "in", "instanceof"], 16351 [">>", "<<", ">>>"], 16352 ["+", "-"], 16353 ["*", "/", "%"] 16354 ], 16355 {} 16356); 16357 16358var STATEMENTS_WITH_LABELS = array_to_hash([ "for", "do", "while", "switch" ]); 16359 16360var ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "name" ]); 16361 16362/* -----[ Parser ]----- */ 16363 16364function parse($TEXT, options) { 16365 16366 options = defaults(options, { 16367 bare_returns : false, 16368 cli : false, 16369 expression : false, 16370 filename : null, 16371 html5_comments : true, 16372 shebang : true, 16373 strict : false, 16374 toplevel : null, 16375 }); 16376 16377 var S = { 16378 input : (typeof $TEXT == "string" 16379 ? tokenizer($TEXT, options.filename, 16380 options.html5_comments, options.shebang) 16381 : $TEXT), 16382 token : null, 16383 prev : null, 16384 peeked : null, 16385 in_function : 0, 16386 in_directives : true, 16387 in_loop : 0, 16388 labels : [] 16389 }; 16390 16391 S.token = next(); 16392 16393 function is(type, value) { 16394 return is_token(S.token, type, value); 16395 }; 16396 16397 function peek() { return S.peeked || (S.peeked = S.input()); }; 16398 16399 function next() { 16400 S.prev = S.token; 16401 if (S.peeked) { 16402 S.token = S.peeked; 16403 S.peeked = null; 16404 } else { 16405 S.token = S.input(); 16406 } 16407 S.in_directives = S.in_directives && ( 16408 S.token.type == "string" || is("punc", ";") 16409 ); 16410 return S.token; 16411 }; 16412 16413 function prev() { 16414 return S.prev; 16415 }; 16416 16417 function croak(msg, line, col, pos) { 16418 var ctx = S.input.context(); 16419 js_error(msg, 16420 ctx.filename, 16421 line != null ? line : ctx.tokline, 16422 col != null ? col : ctx.tokcol, 16423 pos != null ? pos : ctx.tokpos); 16424 }; 16425 16426 function token_error(token, msg) { 16427 croak(msg, token.line, token.col); 16428 }; 16429 16430 function unexpected(token) { 16431 if (token == null) 16432 token = S.token; 16433 token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")"); 16434 }; 16435 16436 function expect_token(type, val) { 16437 if (is(type, val)) { 16438 return next(); 16439 } 16440 token_error(S.token, "Unexpected token " + S.token.type + " «" + S.token.value + "»" + ", expected " + type + " «" + val + "»"); 16441 }; 16442 16443 function expect(punc) { return expect_token("punc", punc); }; 16444 16445 function can_insert_semicolon() { 16446 return !options.strict && ( 16447 S.token.nlb || is("eof") || is("punc", "}") 16448 ); 16449 }; 16450 16451 function semicolon(optional) { 16452 if (is("punc", ";")) next(); 16453 else if (!optional && !can_insert_semicolon()) unexpected(); 16454 }; 16455 16456 function parenthesised() { 16457 expect("("); 16458 var exp = expression(true); 16459 expect(")"); 16460 return exp; 16461 }; 16462 16463 function embed_tokens(parser) { 16464 return function() { 16465 var start = S.token; 16466 var expr = parser(); 16467 var end = prev(); 16468 expr.start = start; 16469 expr.end = end; 16470 return expr; 16471 }; 16472 }; 16473 16474 function handle_regexp() { 16475 if (is("operator", "/") || is("operator", "/=")) { 16476 S.peeked = null; 16477 S.token = S.input(S.token.value.substr(1)); // force regexp 16478 } 16479 }; 16480 16481 var statement = embed_tokens(function() { 16482 handle_regexp(); 16483 switch (S.token.type) { 16484 case "string": 16485 if (S.in_directives) { 16486 var token = peek(); 16487 if (S.token.raw.indexOf("\\") == -1 16488 && (token.nlb 16489 || is_token(token, "eof") 16490 || is_token(token, "punc", ";") 16491 || is_token(token, "punc", "}"))) { 16492 S.input.add_directive(S.token.value); 16493 } else { 16494 S.in_directives = false; 16495 } 16496 }
vendor: 4,060 bytes, lines 16497-16628
16497 var dir = S.in_directives, stat = simple_statement(); 16498 return dir ? new AST_Directive(stat.body) : stat; 16499 case "num": 16500 case "regexp": 16501 case "operator": 16502 case "atom": 16503 return simple_statement(); 16504 16505 case "name": 16506 return is_token(peek(), "punc", ":") 16507 ? labeled_statement() 16508 : simple_statement(); 16509 16510 case "punc": 16511 switch (S.token.value) { 16512 case "{": 16513 return new AST_BlockStatement({ 16514 start : S.token, 16515 body : block_(), 16516 end : prev() 16517 }); 16518 case "[": 16519 case "(": 16520 return simple_statement(); 16521 case ";": 16522 S.in_directives = false; 16523 next(); 16524 return new AST_EmptyStatement(); 16525 default: 16526 unexpected(); 16527 } 16528 16529 case "keyword": 16530 switch (S.token.value) { 16531 case "break": 16532 next(); 16533 return break_cont(AST_Break); 16534 16535 case "continue": 16536 next(); 16537 return break_cont(AST_Continue); 16538 16539 case "debugger": 16540 next(); 16541 semicolon(); 16542 return new AST_Debugger(); 16543 16544 case "do": 16545 next(); 16546 var body = in_loop(statement); 16547 expect_token("keyword", "while"); 16548 var condition = parenthesised(); 16549 semicolon(true); 16550 return new AST_Do({ 16551 body : body, 16552 condition : condition 16553 }); 16554 16555 case "while": 16556 next(); 16557 return new AST_While({ 16558 condition : parenthesised(), 16559 body : in_loop(statement) 16560 }); 16561 16562 case "for": 16563 next(); 16564 return for_(); 16565 16566 case "function": 16567 next(); 16568 return function_(AST_Defun); 16569 16570 case "if": 16571 next(); 16572 return if_(); 16573 16574 case "return": 16575 if (S.in_function == 0 && !options.bare_returns) 16576 croak("'return' outside of function"); 16577 next(); 16578 var value = null; 16579 if (is("punc", ";")) { 16580 next(); 16581 } else if (!can_insert_semicolon()) { 16582 value = expression(true); 16583 semicolon(); 16584 } 16585 return new AST_Return({ 16586 value: value 16587 }); 16588 16589 case "switch": 16590 next(); 16591 return new AST_Switch({ 16592 expression : parenthesised(), 16593 body : in_loop(switch_body_) 16594 }); 16595 16596 case "throw": 16597 next(); 16598 if (S.token.nlb) 16599 croak("Illegal newline after 'throw'"); 16600 var value = expression(true); 16601 semicolon(); 16602 return new AST_Throw({ 16603 value: value 16604 }); 16605 16606 case "try": 16607 next(); 16608 return try_(); 16609 16610 case "var": 16611 next(); 16612 var node = var_(); 16613 semicolon(); 16614 return node; 16615 16616 case "const": 16617 next(); 16618 var node = const_(); 16619 semicolon(); 16620 return node; 16621 16622 case "with": 16623 if (S.input.has_directive("use strict")) { 16624 croak("Strict mode may not include a with statement"); 16625 } 16626 next(); 16627 return new AST_With({ 16628 expression : parenthesised(),
16629 body : statement() 16630 }); 16631 } 16632 } 16633 unexpected(); 16634 }); 16635 16636 function labeled_statement() { 16637 var label = as_symbol(AST_Label); 16638 if (find_if(function(l){ return l.name == label.name }, S.labels)) { 16639 // ECMA-262, 12.12: An ECMAScript program is considered 16640 // syntactically incorrect if it contains a 16641 // LabelledStatement that is enclosed by a 16642 // LabelledStatement with the same Identifier as label. 16643 croak("Label " + label.name + " defined twice"); 16644 } 16645 expect(":"); 16646 S.labels.push(label); 16647 var stat = statement(); 16648 S.labels.pop(); 16649 if (!(stat instanceof AST_IterationStatement)) { 16650 // check for `continue` that refers to this label. 16651 // those should be reported as syntax errors. 16652 // https://github.com/mishoo/UglifyJS2/issues/287 16653 label.references.forEach(function(ref){ 16654 if (ref instanceof AST_Continue) { 16655 ref = ref.label.start; 16656 croak("Continue label `" + label.name + "` refers to non-IterationStatement.", 16657 ref.line, ref.col, ref.pos); 16658 } 16659 }); 16660 } 16661 return new AST_LabeledStatement({ body: stat, label: label }); 16662 }; 16663 16664 function simple_statement(tmp) { 16665 return new AST_SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) }); 16666 }; 16667 16668 function break_cont(type) { 16669 var label = null, ldef; 16670 if (!can_insert_semicolon()) { 16671 label = as_symbol(AST_LabelRef, true); 16672 } 16673 if (label != null) { 16674 ldef = find_if(function(l){ return l.name == label.name }, S.labels); 16675 if (!ldef) 16676 croak("Undefined label " + label.name); 16677 label.thedef = ldef; 16678 } 16679 else if (S.in_loop == 0) 16680 croak(type.TYPE + " not inside a loop or switch"); 16681 semicolon(); 16682 var stat = new type({ label: label }); 16683 if (ldef) ldef.references.push(stat); 16684 return stat; 16685 }; 16686 16687 function for_() { 16688 expect("("); 16689 var init = null; 16690 if (!is("punc", ";")) { 16691 init = is("keyword", "var") 16692 ? (next(), var_(true)) 16693 : expression(true, true); 16694 if (is("operator", "in")) { 16695 if (init instanceof AST_Var && init.definitions.length > 1) 16696 croak("Only one variable declaration allowed in for..in loop"); 16697 next(); 16698 return for_in(init); 16699 } 16700 } 16701 return regular_for(init); 16702 }; 16703 16704 function regular_for(init) { 16705 expect(";"); 16706 var test = is("punc", ";") ? null : expression(true); 16707 expect(";"); 16708 var step = is("punc", ")") ? null : expression(true); 16709 expect(")"); 16710 return new AST_For({ 16711 init : init, 16712 condition : test, 16713 step : step, 16714 body : in_loop(statement) 16715 }); 16716 }; 16717 16718 function for_in(init) { 16719 var lhs = init instanceof AST_Var ? init.definitions[0].name : null; 16720 var obj = expression(true); 16721 expect(")"); 16722 return new AST_ForIn({ 16723 init : init, 16724 name : lhs, 16725 object : obj, 16726 body : in_loop(statement) 16727 }); 16728 }; 16729 16730 var function_ = function(ctor) { 16731 var in_statement = ctor === AST_Defun; 16732 var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null; 16733 if (in_statement && !name) 16734 unexpected(); 16735 expect("("); 16736 return new ctor({ 16737 name: name, 16738 argnames: (function(first, a){ 16739 while (!is("punc", ")")) { 16740 if (first) first = false; else expect(","); 16741 a.push(as_symbol(AST_SymbolFunarg)); 16742 } 16743 next(); 16744 return a; 16745 })(true, []), 16746 body: (function(loop, labels){ 16747 ++S.in_function; 16748 S.in_directives = true; 16749 S.input.push_directives_stack(); 16750 S.in_loop = 0; 16751 S.labels = []; 16752 var a = block_(); 16753 S.input.pop_directives_stack(); 16754 --S.in_function; 16755 S.in_loop = loop; 16756 S.labels = labels; 16757 return a; 16758 })(S.in_loop, S.labels) 16759 }); 16760 }; 16761 16762 function if_() {
16763 var cond = parenthesised(), body = statement(), belse = null; 16764 if (is("keyword", "else")) { 16765 next(); 16766 belse = statement(); 16767 } 16768 return new AST_If({ 16769 condition : cond, 16770 body : body, 16771 alternative : belse 16772 }); 16773 }; 16774 16775 function block_() { 16776 expect("{"); 16777 var a = []; 16778 while (!is("punc", "}")) { 16779 if (is("eof")) unexpected(); 16780 a.push(statement()); 16781 } 16782 next(); 16783 return a; 16784 }; 16785 16786 function switch_body_() { 16787 expect("{"); 16788 var a = [], cur = null, branch = null, tmp; 16789 while (!is("punc", "}")) { 16790 if (is("eof")) unexpected(); 16791 if (is("keyword", "case")) { 16792 if (branch) branch.end = prev(); 16793 cur = []; 16794 branch = new AST_Case({ 16795 start : (tmp = S.token, next(), tmp), 16796 expression : expression(true), 16797 body : cur 16798 }); 16799 a.push(branch); 16800 expect(":"); 16801 } 16802 else if (is("keyword", "default")) { 16803 if (branch) branch.end = prev(); 16804 cur = []; 16805 branch = new AST_Default({ 16806 start : (tmp = S.token, next(), expect(":"), tmp), 16807 body : cur 16808 }); 16809 a.push(branch); 16810 } 16811 else { 16812 if (!cur) unexpected(); 16813 cur.push(statement()); 16814 } 16815 } 16816 if (branch) branch.end = prev(); 16817 next(); 16818 return a; 16819 }; 16820 16821 function try_() { 16822 var body = block_(), bcatch = null, bfinally = null; 16823 if (is("keyword", "catch")) { 16824 var start = S.token; 16825 next(); 16826 expect("("); 16827 var name = as_symbol(AST_SymbolCatch); 16828 expect(")"); 16829 bcatch = new AST_Catch({ 16830 start : start, 16831 argname : name, 16832 body : block_(), 16833 end : prev() 16834 }); 16835 } 16836 if (is("keyword", "finally")) { 16837 var start = S.token; 16838 next(); 16839 bfinally = new AST_Finally({ 16840 start : start, 16841 body : block_(), 16842 end : prev() 16843 }); 16844 } 16845 if (!bcatch && !bfinally) 16846 croak("Missing catch/finally blocks"); 16847 return new AST_Try({ 16848 body : body, 16849 bcatch : bcatch, 16850 bfinally : bfinally 16851 }); 16852 }; 16853 16854 function vardefs(no_in, in_const) { 16855 var a = []; 16856 for (;;) { 16857 a.push(new AST_VarDef({ 16858 start : S.token, 16859 name : as_symbol(in_const ? AST_SymbolConst : AST_SymbolVar), 16860 value : is("operator", "=") ? (next(), expression(false, no_in)) : null, 16861 end : prev() 16862 })); 16863 if (!is("punc", ",")) 16864 break; 16865 next(); 16866 } 16867 return a; 16868 }; 16869 16870 var var_ = function(no_in) { 16871 return new AST_Var({ 16872 start : prev(), 16873 definitions : vardefs(no_in, false), 16874 end : prev() 16875 }); 16876 }; 16877 16878 var const_ = function() { 16879 return new AST_Const({ 16880 start : prev(), 16881 definitions : vardefs(false, true), 16882 end : prev() 16883 }); 16884 }; 16885 16886 var new_ = function(allow_calls) { 16887 var start = S.token; 16888 expect_token("operator", "new"); 16889 var newexp = expr_atom(false), args; 16890 if (is("punc", "(")) { 16891 next(); 16892 args = expr_list(")"); 16893 } else { 16894 args = []; 16895 } 16896 return subscripts(new AST_New({ 16897 start : start, 16898 expression : newexp, 16899 args : args, 16900 end : prev() 16901 }), allow_calls); 16902 }; 16903 16904 function as_atom_node() { 16905 var tok = S.token, ret; 16906 switch (tok.type) { 16907 case "name": 16908 case "keyword": 16909 ret = _make_symbol(AST_SymbolRef); 16910 break; 16911 case "num": 16912 ret = new AST_Number({ start: tok, end: tok, value: tok.value });
16913 break; 16914 case "string": 16915 ret = new AST_String({ 16916 start : tok, 16917 end : tok, 16918 value : tok.value, 16919 quote : tok.quote 16920 }); 16921 break; 16922 case "regexp": 16923 ret = new AST_RegExp({ start: tok, end: tok, value: tok.value }); 16924 break; 16925 case "atom": 16926 switch (tok.value) { 16927 case "false": 16928 ret = new AST_False({ start: tok, end: tok }); 16929 break; 16930 case "true": 16931 ret = new AST_True({ start: tok, end: tok }); 16932 break; 16933 case "null": 16934 ret = new AST_Null({ start: tok, end: tok }); 16935 break; 16936 } 16937 break; 16938 case "operator": 16939 if (!is_identifier_string(tok.value)) { 16940 croak("Invalid getter/setter name: " + tok.value, 16941 tok.line, tok.col, tok.pos); 16942 } 16943 ret = _make_symbol(AST_SymbolRef); 16944 break; 16945 } 16946 next(); 16947 return ret; 16948 }; 16949 16950 var expr_atom = function(allow_calls) { 16951 if (is("operator", "new")) { 16952 return new_(allow_calls); 16953 } 16954 var start = S.token; 16955 if (is("punc")) { 16956 switch (start.value) { 16957 case "(": 16958 next(); 16959 var ex = expression(true); 16960 ex.start = start; 16961 ex.end = S.token; 16962 expect(")"); 16963 return subscripts(ex, allow_calls); 16964 case "[": 16965 return subscripts(array_(), allow_calls); 16966 case "{": 16967 return subscripts(object_(), allow_calls); 16968 } 16969 unexpected(); 16970 } 16971 if (is("keyword", "function")) { 16972 next(); 16973 var func = function_(AST_Function); 16974 func.start = start; 16975 func.end = prev(); 16976 return subscripts(func, allow_calls); 16977 } 16978 if (ATOMIC_START_TOKEN[S.token.type]) { 16979 return subscripts(as_atom_node(), allow_calls); 16980 } 16981 unexpected(); 16982 }; 16983 16984 function expr_list(closing, allow_trailing_comma, allow_empty) { 16985 var first = true, a = []; 16986 while (!is("punc", closing)) { 16987 if (first) first = false; else expect(","); 16988 if (allow_trailing_comma && is("punc", closing)) break; 16989 if (is("punc", ",") && allow_empty) { 16990 a.push(new AST_Hole({ start: S.token, end: S.token })); 16991 } else { 16992 a.push(expression(false)); 16993 } 16994 } 16995 next(); 16996 return a; 16997 }; 16998 16999 var array_ = embed_tokens(function() { 17000 expect("["); 17001 return new AST_Array({ 17002 elements: expr_list("]", !options.strict, true) 17003 }); 17004 }); 17005 17006 var create_accessor = embed_tokens(function() { 17007 return function_(AST_Accessor); 17008 }); 17009 17010 var object_ = embed_tokens(function() { 17011 expect("{"); 17012 var first = true, a = []; 17013 while (!is("punc", "}")) { 17014 if (first) first = false; else expect(","); 17015 if (!options.strict && is("punc", "}")) 17016 // allow trailing comma 17017 break; 17018 var start = S.token; 17019 var type = start.type; 17020 var name = as_property_name(); 17021 if (type == "name" && !is("punc", ":")) { 17022 var key = new AST_SymbolAccessor({ 17023 start: S.token, 17024 name: as_property_name(), 17025 end: prev() 17026 }); 17027 if (name == "get") { 17028 a.push(new AST_ObjectGetter({ 17029 start : start, 17030 key : key, 17031 value : create_accessor(), 17032 end : prev() 17033 })); 17034 continue; 17035 } 17036 if (name == "set") { 17037 a.push(new AST_ObjectSetter({ 17038 start : start, 17039 key : key, 17040 value : create_accessor(), 17041 end : prev() 17042 })); 17043 continue; 17044 } 17045 } 17046 expect(":"); 17047 a.push(new AST_ObjectKeyVal({ 17048 start : start, 17049 quote : start.quote, 17050 key : name, 17051 value : expression(false), 17052 end : prev() 17053 })); 17054 } 17055 next(); 17056 return new AST_Object({ properties: a }); 17057 });
17058 17059 function as_property_name() { 17060 var tmp = S.token; 17061 switch (tmp.type) { 17062 case "operator": 17063 if (!KEYWORDS(tmp.value)) unexpected(); 17064 case "num": 17065 case "string": 17066 case "name": 17067 case "keyword": 17068 case "atom": 17069 next(); 17070 return tmp.value; 17071 default: 17072 unexpected(); 17073 } 17074 }; 17075 17076 function as_name() { 17077 var tmp = S.token; 17078 if (tmp.type != "name") unexpected(); 17079 next(); 17080 return tmp.value; 17081 }; 17082 17083 function _make_symbol(type) { 17084 var name = S.token.value; 17085 return new (name == "this" ? AST_This : type)({ 17086 name : String(name), 17087 start : S.token, 17088 end : S.token 17089 }); 17090 }; 17091 17092 function as_symbol(type, noerror) { 17093 if (!is("name")) { 17094 if (!noerror) croak("Name expected"); 17095 return null; 17096 } 17097 var sym = _make_symbol(type); 17098 next(); 17099 return sym; 17100 }; 17101 17102 var subscripts = function(expr, allow_calls) { 17103 var start = expr.start; 17104 if (is("punc", ".")) { 17105 next(); 17106 return subscripts(new AST_Dot({ 17107 start : start, 17108 expression : expr, 17109 property : as_name(), 17110 end : prev() 17111 }), allow_calls); 17112 } 17113 if (is("punc", "[")) { 17114 next(); 17115 var prop = expression(true); 17116 expect("]"); 17117 return subscripts(new AST_Sub({ 17118 start : start, 17119 expression : expr, 17120 property : prop, 17121 end : prev() 17122 }), allow_calls); 17123 } 17124 if (allow_calls && is("punc", "(")) { 17125 next(); 17126 return subscripts(new AST_Call({ 17127 start : start, 17128 expression : expr, 17129 args : expr_list(")"), 17130 end : prev() 17131 }), true); 17132 } 17133 return expr; 17134 }; 17135 17136 var maybe_unary = function(allow_calls) { 17137 var start = S.token; 17138 if (is("operator") && UNARY_PREFIX(start.value)) { 17139 next(); 17140 handle_regexp(); 17141 var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(allow_calls)); 17142 ex.start = start; 17143 ex.end = prev(); 17144 return ex; 17145 } 17146 var val = expr_atom(allow_calls); 17147 while (is("operator") && UNARY_POSTFIX(S.token.value) && !S.token.nlb) { 17148 val = make_unary(AST_UnaryPostfix, S.token, val); 17149 val.start = start; 17150 val.end = S.token; 17151 next(); 17152 } 17153 return val; 17154 }; 17155 17156 function make_unary(ctor, token, expr) { 17157 var op = token.value; 17158 if ((op == "++" || op == "--") && !is_assignable(expr)) 17159 croak("Invalid use of " + op + " operator", token.line, token.col, token.pos); 17160 return new ctor({ operator: op, expression: expr }); 17161 }; 17162 17163 var expr_op = function(left, min_prec, no_in) { 17164 var op = is("operator") ? S.token.value : null; 17165 if (op == "in" && no_in) op = null; 17166 var prec = op != null ? PRECEDENCE[op] : null; 17167 if (prec != null && prec > min_prec) { 17168 next(); 17169 var right = expr_op(maybe_unary(true), prec, no_in); 17170 return expr_op(new AST_Binary({ 17171 start : left.start, 17172 left : left, 17173 operator : op, 17174 right : right, 17175 end : right.end 17176 }), min_prec, no_in); 17177 } 17178 return left; 17179 }; 17180 17181 function expr_ops(no_in) { 17182 return expr_op(maybe_unary(true), 0, no_in); 17183 }; 17184 17185 var maybe_conditional = function(no_in) { 17186 var start = S.token; 17187 var expr = expr_ops(no_in); 17188 if (is("operator", "?")) { 17189 next(); 17190 var yes = expression(false); 17191 expect(":"); 17192 return new AST_Conditional({ 17193 start : start, 17194 condition : expr, 17195 consequent : yes, 17196 alternative : expression(false, no_in), 17197 end : prev() 17198 }); 17199 } 17200 return expr; 17201 }; 17202 17203 function is_assignable(expr) { 17204 if (options.cli) return true; 17205 return expr instanceof AST_PropAccess || expr instanceof AST_SymbolRef; 17206 }; 17207 17208 var maybe_assign = function(no_in) { 17209 var start = S.token; 17210 var left = maybe_conditional(no_in), val = S.token.value; 17211 if (is("operator") && ASSIGNMENT(val)) { 17212 if (is_assignable(left)) { 17213 next(); 17214 return new AST_Assign({ 17215 start : start, 17216 left : left, 17217 operator : val, 17218 right : maybe_assign(no_in), 17219 end : prev() 17220 }); 17221 } 17222 croak("Invalid assignment"); 17223 } 17224 return left; 17225 }; 17226 17227 var expression = function(commas, no_in) { 17228 var start = S.token; 17229 var expr = maybe_assign(no_in); 17230 if (commas && is("punc", ",")) { 17231 next(); 17232 return new AST_Seq({ 17233 start : start, 17234 car : expr, 17235 cdr : expression(true, no_in), 17236 end : peek() 17237 }); 17238 } 17239 return expr; 17240 }; 17241 17242 function in_loop(cont) { 17243 ++S.in_loop; 17244 var ret = cont(); 17245 --S.in_loop; 17246 return ret; 17247 }; 17248 17249 if (options.expression) { 17250 return expression(true); 17251 } 17252 17253 return (function(){ 17254 var start = S.token; 17255 var body = []; 17256 S.input.push_directives_stack(); 17257 while (!is("eof"))
17258 body.push(statement()); 17259 S.input.pop_directives_stack(); 17260 var end = prev(); 17261 var toplevel = options.toplevel; 17262 if (toplevel) { 17263 toplevel.body = toplevel.body.concat(body); 17264 toplevel.end = end; 17265 } else { 17266 toplevel = new AST_Toplevel({ start: start, body: body, end: end }); 17267 } 17268 return toplevel; 17269 })(); 17270 17271}; 17272 17273/*********************************************************************** 17274 17275 A JavaScript tokenizer / parser / beautifier / compressor. 17276 https://github.com/mishoo/UglifyJS2 17277 17278 -------------------------------- (C) --------------------------------- 17279 17280 Author: Mihai Bazon 17281 <[email protected]> 17282 http://mihai.bazon.net/blog 17283 17284 Distributed under the BSD license: 17285 17286 Copyright 2012 (c) Mihai Bazon <[email protected]> 17287 17288 Redistribution and use in source and binary forms, with or without 17289 modification, are permitted provided that the following conditions 17290 are met: 17291 17292 * Redistributions of source code must retain the above 17293 copyright notice, this list of conditions and the following 17294 disclaimer. 17295 17296 * Redistributions in binary form must reproduce the above 17297 copyright notice, this list of conditions and the following 17298 disclaimer in the documentation and/or other materials 17299 provided with the distribution. 17300 17301 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER âAS ISâ AND ANY 17302 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17303 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17304 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE 17305 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 17306 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 17307 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 17308 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 17309 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 17310 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 17311 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 17312 SUCH DAMAGE. 17313 17314 ***********************************************************************/ 17315 17316"use strict"; 17317 17318// Tree transformer helpers. 17319 17320function TreeTransformer(before, after) { 17321 TreeWalker.call(this); 17322 this.before = before; 17323 this.after = after; 17324} 17325TreeTransformer.prototype = new TreeWalker; 17326 17327(function(undefined){ 17328 17329 function _(node, descend) { 17330 node.DEFMETHOD("transform", function(tw, in_list){ 17331 var x, y; 17332 tw.push(this); 17333 if (tw.before) x = tw.before(this, descend, in_list); 17334 if (x === undefined) { 17335 if (!tw.after) { 17336 x = this; 17337 descend(x, tw); 17338 } else { 17339 tw.stack[tw.stack.length - 1] = x = this; 17340 descend(x, tw); 17341 y = tw.after(x, in_list); 17342 if (y !== undefined) x = y; 17343 } 17344 } 17345 tw.pop(this); 17346 return x; 17347 }); 17348 }; 17349 17350 function do_list(list, tw) { 17351 return MAP(list, function(node){ 17352 return node.transform(tw, true); 17353 }); 17354 }; 17355 17356 _(AST_Node, noop); 17357 17358 _(AST_LabeledStatement, function(self, tw){ 17359 self.label = self.label.transform(tw); 17360 self.body = self.body.transform(tw); 17361 }); 17362 17363 _(AST_SimpleStatement, function(self, tw){ 17364 self.body = self.body.transform(tw); 17365 }); 17366 17367 _(AST_Block, function(self, tw){ 17368 self.body = do_list(self.body, tw); 17369 }); 17370 17371 _(AST_DWLoop, function(self, tw){ 17372 self.condition = self.condition.transform(tw); 17373 self.body = self.body.transform(tw); 17374 }); 17375 17376 _(AST_For, function(self, tw){ 17377 if (self.init) self.init = self.init.transform(tw); 17378 if (self.condition) self.condition = self.condition.transform(tw); 17379 if (self.step) self.step = self.step.transform(tw); 17380 self.body = self.body.transform(tw); 17381 });
17382 17383 _(AST_ForIn, function(self, tw){ 17384 self.init = self.init.transform(tw); 17385 self.object = self.object.transform(tw); 17386 self.body = self.body.transform(tw); 17387 }); 17388 17389 _(AST_With, function(self, tw){ 17390 self.expression = self.expression.transform(tw); 17391 self.body = self.body.transform(tw); 17392 }); 17393 17394 _(AST_Exit, function(self, tw){ 17395 if (self.value) self.value = self.value.transform(tw); 17396 }); 17397 17398 _(AST_LoopControl, function(self, tw){ 17399 if (self.label) self.label = self.label.transform(tw); 17400 }); 17401 17402 _(AST_If, function(self, tw){ 17403 self.condition = self.condition.transform(tw); 17404 self.body = self.body.transform(tw); 17405 if (self.alternative) self.alternative = self.alternative.transform(tw); 17406 }); 17407 17408 _(AST_Switch, function(self, tw){ 17409 self.expression = self.expression.transform(tw); 17410 self.body = do_list(self.body, tw); 17411 }); 17412 17413 _(AST_Case, function(self, tw){ 17414 self.expression = self.expression.transform(tw); 17415 self.body = do_list(self.body, tw); 17416 }); 17417 17418 _(AST_Try, function(self, tw){ 17419 self.body = do_list(self.body, tw); 17420 if (self.bcatch) self.bcatch = self.bcatch.transform(tw); 17421 if (self.bfinally) self.bfinally = self.bfinally.transform(tw); 17422 }); 17423 17424 _(AST_Catch, function(self, tw){ 17425 self.argname = self.argname.transform(tw); 17426 self.body = do_list(self.body, tw); 17427 }); 17428 17429 _(AST_Definitions, function(self, tw){ 17430 self.definitions = do_list(self.definitions, tw); 17431 }); 17432 17433 _(AST_VarDef, function(self, tw){ 17434 self.name = self.name.transform(tw); 17435 if (self.value) self.value = self.value.transform(tw); 17436 }); 17437 17438 _(AST_Lambda, function(self, tw){ 17439 if (self.name) self.name = self.name.transform(tw); 17440 self.argnames = do_list(self.argnames, tw); 17441 self.body = do_list(self.body, tw); 17442 }); 17443 17444 _(AST_Call, function(self, tw){ 17445 self.expression = self.expression.transform(tw); 17446 self.args = do_list(self.args, tw); 17447 }); 17448 17449 _(AST_Seq, function(self, tw){ 17450 self.car = self.car.transform(tw); 17451 self.cdr = self.cdr.transform(tw); 17452 }); 17453 17454 _(AST_Dot, function(self, tw){ 17455 self.expression = self.expression.transform(tw); 17456 }); 17457 17458 _(AST_Sub, function(self, tw){ 17459 self.expression = self.expression.transform(tw); 17460 self.property = self.property.transform(tw); 17461 }); 17462 17463 _(AST_Unary, function(self, tw){ 17464 self.expression = self.expression.transform(tw); 17465 }); 17466 17467 _(AST_Binary, function(self, tw){ 17468 self.left = self.left.transform(tw); 17469 self.right = self.right.transform(tw); 17470 }); 17471 17472 _(AST_Conditional, function(self, tw){ 17473 self.condition = self.condition.transform(tw); 17474 self.consequent = self.consequent.transform(tw); 17475 self.alternative = self.alternative.transform(tw); 17476 }); 17477 17478 _(AST_Array, function(self, tw){ 17479 self.elements = do_list(self.elements, tw); 17480 }); 17481 17482 _(AST_Object, function(self, tw){ 17483 self.properties = do_list(self.properties, tw); 17484 }); 17485 17486 _(AST_ObjectProperty, function(self, tw){ 17487 self.value = self.value.transform(tw); 17488 }); 17489 17490})(); 17491 17492/*********************************************************************** 17493 17494 A JavaScript tokenizer / parser / beautifier / compressor. 17495 https://github.com/mishoo/UglifyJS2 17496 17497 -------------------------------- (C) --------------------------------- 17498 17499 Author: Mihai Bazon 17500 <[email protected]> 17501 http://mihai.bazon.net/blog 17502 17503 Distributed under the BSD license: 17504 17505 Copyright 2012 (c) Mihai Bazon <[email protected]> 17506 17507 Redistribution and use in source and binary forms, with or without 17508 modification, are permitted provided that the following conditions 17509 are met: 17510 17511 * Redistributions of source code must retain the above 17512 copyright notice, this list of conditions and the following 17513 disclaimer. 17514 17515 * Redistributions in binary form must reproduce the above 17516 copyright notice, this list of conditions and the following 17517 disclaimer in the documentation and/or other materials 17518 provided with the distribution. 17519 17520 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER âAS ISâ AND ANY 17521 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17522 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17523 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE 17524 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
17525 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 17526 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 17527 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 17528 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 17529 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 17530 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 17531 SUCH DAMAGE. 17532 17533 ***********************************************************************/ 17534 17535"use strict"; 17536 17537function SymbolDef(scope, index, orig) { 17538 this.name = orig.name; 17539 this.orig = [ orig ]; 17540 this.scope = scope; 17541 this.references = []; 17542 this.global = false; 17543 this.mangled_name = null; 17544 this.undeclared = false; 17545 this.index = index; 17546 this.id = SymbolDef.next_id++; 17547}; 17548 17549SymbolDef.next_id = 1; 17550 17551SymbolDef.prototype = { 17552 unmangleable: function(options) { 17553 if (!options) options = {}; 17554 17555 return (this.global && !options.toplevel) 17556 || this.undeclared 17557 || (!options.eval && (this.scope.uses_eval || this.scope.uses_with)) 17558 || (options.keep_fnames 17559 && (this.orig[0] instanceof AST_SymbolLambda 17560 || this.orig[0] instanceof AST_SymbolDefun)); 17561 }, 17562 mangle: function(options) { 17563 var cache = options.cache && options.cache.props; 17564 if (this.global && cache && cache.has(this.name)) { 17565 this.mangled_name = cache.get(this.name); 17566 } 17567 else if (!this.mangled_name && !this.unmangleable(options)) { 17568 var s = this.scope; 17569 var sym = this.orig[0]; 17570 if (!options.screw_ie8 && sym instanceof AST_SymbolLambda) 17571 s = s.parent_scope; 17572 var def; 17573 if (this.defun && (def = this.defun.variables.get(this.name))) { 17574 this.mangled_name = def.mangled_name || def.name; 17575 } else 17576 this.mangled_name = s.next_mangled(options, this); 17577 if (this.global && cache) { 17578 cache.set(this.name, this.mangled_name); 17579 } 17580 } 17581 } 17582}; 17583 17584AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ 17585 options = defaults(options, { 17586 cache: null, 17587 screw_ie8: true, 17588 }); 17589 17590 // pass 1: setup scope chaining and handle definitions 17591 var self = this; 17592 var scope = self.parent_scope = null; 17593 var labels = new Dictionary(); 17594 var defun = null; 17595 var tw = new TreeWalker(function(node, descend){ 17596 if (node instanceof AST_Catch) { 17597 var save_scope = scope; 17598 scope = new AST_Scope(node); 17599 scope.init_scope_vars(save_scope); 17600 descend(); 17601 scope = save_scope; 17602 return true; 17603 } 17604 if (node instanceof AST_Scope) { 17605 node.init_scope_vars(scope); 17606 var save_scope = scope; 17607 var save_defun = defun; 17608 var save_labels = labels; 17609 defun = scope = node; 17610 labels = new Dictionary(); 17611 descend(); 17612 scope = save_scope; 17613 defun = save_defun; 17614 labels = save_labels; 17615 return true; // don't descend again in TreeWalker 17616 } 17617 if (node instanceof AST_LabeledStatement) { 17618 var l = node.label; 17619 if (labels.has(l.name)) { 17620 throw new Error(string_template("Label {name} defined twice", l)); 17621 } 17622 labels.set(l.name, l); 17623 descend(); 17624 labels.del(l.name); 17625 return true; // no descend again 17626 } 17627 if (node instanceof AST_With) { 17628 for (var s = scope; s; s = s.parent_scope) 17629 s.uses_with = true; 17630 return; 17631 } 17632 if (node instanceof AST_Symbol) { 17633 node.scope = scope; 17634 } 17635 if (node instanceof AST_Label) { 17636 node.thedef = node; 17637 node.references = []; 17638 } 17639 if (node instanceof AST_SymbolLambda) { 17640 defun.def_function(node); 17641 } 17642 else if (node instanceof AST_SymbolDefun) { 17643 // Careful here, the scope where this should be defined is 17644 // the parent scope. The reason is that we enter a new 17645 // scope when we encounter the AST_Defun node (which is 17646 // instanceof AST_Scope) but we get to the symbol a bit 17647 // later. 17648 (node.scope = defun.parent_scope).def_function(node); 17649 } 17650 else if (node instanceof AST_SymbolVar 17651 || node instanceof AST_SymbolConst) { 17652 defun.def_variable(node); 17653 if (defun !== scope) { 17654 node.mark_enclosed(options); 17655 var def = scope.find_variable(node); 17656 if (node.thedef !== def) { 17657 node.thedef = def; 17658 node.reference(options); 17659 } 17660 } 17661 } 17662 else if (node instanceof AST_SymbolCatch) { 17663 scope.def_variable(node).defun = defun; 17664 } 17665 else if (node instanceof AST_LabelRef) { 17666 var sym = labels.get(node.name); 17667 if (!sym) throw new Error(string_template("Undefined label {name} [{line},{col}]", { 17668 name: node.name, 17669 line: node.start.line, 17670 col: node.start.col 17671 })); 17672 node.thedef = sym; 17673 } 17674 });
17675 self.walk(tw); 17676 17677 // pass 2: find back references and eval 17678 var func = null; 17679 var globals = self.globals = new Dictionary(); 17680 var tw = new TreeWalker(function(node, descend){ 17681 if (node instanceof AST_Lambda) { 17682 var prev_func = func; 17683 func = node; 17684 descend(); 17685 func = prev_func; 17686 return true; 17687 } 17688 if (node instanceof AST_LoopControl && node.label) { 17689 node.label.thedef.references.push(node); 17690 return true; 17691 } 17692 if (node instanceof AST_SymbolRef) { 17693 var name = node.name; 17694 if (name == "eval" && tw.parent() instanceof AST_Call) { 17695 for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope) { 17696 s.uses_eval = true; 17697 } 17698 } 17699 var sym = node.scope.find_variable(name); 17700 if (node.scope instanceof AST_Lambda && name == "arguments") { 17701 node.scope.uses_arguments = true; 17702 } 17703 if (!sym) { 17704 sym = self.def_global(node); 17705 } 17706 node.thedef = sym; 17707 node.reference(options); 17708 return true; 17709 } 17710 }); 17711 self.walk(tw); 17712 17713 // pass 3: fix up any scoping issue with IE8 17714 if (!options.screw_ie8) { 17715 self.walk(new TreeWalker(function(node, descend) { 17716 if (node instanceof AST_SymbolCatch) { 17717 var name = node.name; 17718 var refs = node.thedef.references; 17719 var scope = node.thedef.defun; 17720 var def = scope.find_variable(name) || self.globals.get(name) || scope.def_variable(node); 17721 refs.forEach(function(ref) { 17722 ref.thedef = def; 17723 ref.reference(options); 17724 }); 17725 node.thedef = def; 17726 return true; 17727 } 17728 })); 17729 } 17730 17731 if (options.cache) { 17732 this.cname = options.cache.cname; 17733 } 17734}); 17735 17736AST_Toplevel.DEFMETHOD("def_global", function(node){ 17737 var globals = this.globals, name = node.name; 17738 if (globals.has(name)) { 17739 return globals.get(name); 17740 } else { 17741 var g = new SymbolDef(this, globals.size(), node); 17742 g.undeclared = true; 17743 g.global = true; 17744 globals.set(name, g); 17745 return g; 17746 } 17747}); 17748 17749AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope){ 17750 this.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions) 17751 this.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope) 17752 this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement 17753 this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval` 17754 this.parent_scope = parent_scope; // the parent scope 17755 this.enclosed = []; // a list of variables from this or outer scope(s) that are referenced from this or inner scopes 17756 this.cname = -1; // the current index for mangling functions/variables 17757}); 17758 17759AST_Lambda.DEFMETHOD("init_scope_vars", function(){ 17760 AST_Scope.prototype.init_scope_vars.apply(this, arguments); 17761 this.uses_arguments = false; 17762 this.def_variable(new AST_SymbolVar({ 17763 name: "arguments", 17764 start: this.start, 17765 end: this.end 17766 })); 17767}); 17768 17769AST_Symbol.DEFMETHOD("mark_enclosed", function(options) { 17770 var def = this.definition(); 17771 var s = this.scope; 17772 while (s) { 17773 push_uniq(s.enclosed, def); 17774 if (options.keep_fnames) { 17775 s.functions.each(function(d) { 17776 push_uniq(def.scope.enclosed, d); 17777 }); 17778 } 17779 if (s === def.scope) break; 17780 s = s.parent_scope; 17781 } 17782}); 17783 17784AST_Symbol.DEFMETHOD("reference", function(options) { 17785 this.definition().references.push(this); 17786 this.mark_enclosed(options); 17787}); 17788 17789AST_Scope.DEFMETHOD("find_variable", function(name){ 17790 if (name instanceof AST_Symbol) name = name.name; 17791 return this.variables.get(name) 17792 || (this.parent_scope && this.parent_scope.find_variable(name)); 17793}); 17794 17795AST_Scope.DEFMETHOD("def_function", function(symbol){ 17796 this.functions.set(symbol.name, this.def_variable(symbol)); 17797}); 17798 17799AST_Scope.DEFMETHOD("def_variable", function(symbol){ 17800 var def; 17801 if (!this.variables.has(symbol.name)) { 17802 def = new SymbolDef(this, this.variables.size(), symbol); 17803 this.variables.set(symbol.name, def); 17804 def.global = !this.parent_scope; 17805 } else { 17806 def = this.variables.get(symbol.name); 17807 def.orig.push(symbol); 17808 } 17809 return symbol.thedef = def; 17810}); 17811 17812AST_Scope.DEFMETHOD("next_mangled", function(options){ 17813 var ext = this.enclosed; 17814 out: while (true) { 17815 var m = base54(++this.cname); 17816 if (!is_identifier(m)) continue; // skip over "do" 17817 17818 // https://github.com/mishoo/UglifyJS2/issues/242 -- do n
17818ot 17819 // shadow a name excepted from mangling. 17820 if (options.except.indexOf(m) >= 0) continue; 17821 17822 // we must ensure that the mangled name does not shadow a name 17823 // from some parent scope that is referenced in this or in 17824 // inner scopes. 17825 for (var i = ext.length; --i >= 0;) { 17826 var sym = ext[i]; 17827 var name = sym.mangled_name || (sym.unmangleable(options) && sym.name); 17828 if (m == name) continue out; 17829 } 17830 return m; 17831 } 17832}); 17833 17834AST_Function.DEFMETHOD("next_mangled", function(options, def){ 17835 // #179, #326 17836 // in Safari strict mode, something like (function x(x){...}) is a syntax error; 17837 // a function expression's argument cannot shadow the function expression's name 17838 17839 var tricky_def = def.orig[0] instanceof AST_SymbolFunarg && this.name && this.name.definition(); 17840 17841 // the function's mangled_name is null when keep_fnames is true 17842 var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null; 17843 17844 while (true) { 17845 var name = AST_Lambda.prototype.next_mangled.call(this, options, def); 17846 if (!tricky_name || tricky_name != name) 17847 return name; 17848 } 17849}); 17850 17851AST_Symbol.DEFMETHOD("unmangleable", function(options){ 17852 return this.definition().unmangleable(options); 17853}); 17854 17855// labels are always mangleable 17856AST_Label.DEFMETHOD("unmangleable", function(){ 17857 return false; 17858}); 17859 17860AST_Symbol.DEFMETHOD("unreferenced", function(){ 17861 return this.definition().references.length == 0 17862 && !(this.scope.uses_eval || this.scope.uses_with); 17863}); 17864 17865AST_Symbol.DEFMETHOD("undeclared", function(){ 17866 return this.definition().undeclared; 17867}); 17868 17869AST_LabelRef.DEFMETHOD("undeclared", function(){ 17870 return false; 17871}); 17872 17873AST_Label.DEFMETHOD("undeclared", function(){ 17874 return false; 17875}); 17876 17877AST_Symbol.DEFMETHOD("definition", function(){ 17878 return this.thedef; 17879}); 17880 17881AST_Symbol.DEFMETHOD("global", function(){ 17882 return this.definition().global; 17883}); 17884 17885AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){ 17886 return defaults(options, { 17887 eval : false, 17888 except : [], 17889 keep_fnames : false, 17890 screw_ie8 : true, 17891 sort : false, // Ignored. Flag retained for backwards compatibility. 17892 toplevel : false, 17893 }); 17894}); 17895 17896AST_Toplevel.DEFMETHOD("mangle_names", function(options){ 17897 options = this._default_mangler_options(options); 17898 17899 // Never mangle arguments 17900 options.except.push('arguments'); 17901 17902 // We only need to mangle declaration nodes. Special logic wired 17903 // into the code generator will display the mangled name if it's 17904 // present (and for AST_SymbolRef-s it'll use the mangled name of 17905 // the AST_SymbolDeclaration that it points to). 17906 var lname = -1; 17907 var to_mangle = []; 17908 17909 if (options.cache) { 17910 this.globals.each(function(symbol){ 17911 if (options.except.indexOf(symbol.name) < 0) { 17912 to_mangle.push(symbol); 17913 } 17914 }); 17915 } 17916 17917 var tw = new TreeWalker(function(node, descend){ 17918 if (node instanceof AST_LabeledStatement) { 17919 // lname is incremented when we get to the AST_Label 17920 var save_nesting = lname; 17921 descend(); 17922 lname = save_nesting; 17923 return true; // don't descend again in TreeWalker 17924 } 17925 if (node instanceof AST_Scope) { 17926 var p = tw.parent(), a = []; 17927 node.variables.each(function(symbol){ 17928 if (options.except.indexOf(symbol.name) < 0) { 17929 a.push(symbol); 17930 } 17931 }); 17932 to_mangle.push.apply(to_mangle, a); 17933 return; 17934 } 17935 if (node instanceof AST_Label) { 17936 var name; 17937 do name = base54(++lname); while (!is_identifier(name)); 17938 node.mangled_name = name; 17939 return true; 17940 } 17941 if (options.screw_ie8 && node instanceof AST_SymbolCatch) { 17942 to_mangle.push(node.definition()); 17943 return; 17944 } 17945 });
vendor: 4,741 bytes, lines 17946-18071
17946 this.walk(tw); 17947 to_mangle.forEach(function(def){ def.mangle(options) }); 17948 17949 if (options.cache) { 17950 options.cache.cname = this.cname; 17951 } 17952}); 17953 17954AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){ 17955 options = this._default_mangler_options(options); 17956 var tw = new TreeWalker(function(node){ 17957 if (node instanceof AST_Constant) 17958 base54.consider(node.print_to_string()); 17959 else if (node instanceof AST_Return) 17960 base54.consider("return"); 17961 else if (node instanceof AST_Throw) 17962 base54.consider("throw"); 17963 else if (node instanceof AST_Continue) 17964 base54.consider("continue"); 17965 else if (node instanceof AST_Break) 17966 base54.consider("break"); 17967 else if (node instanceof AST_Debugger) 17968 base54.consider("debugger"); 17969 else if (node instanceof AST_Directive) 17970 base54.consider(node.value); 17971 else if (node instanceof AST_While) 17972 base54.consider("while"); 17973 else if (node instanceof AST_Do) 17974 base54.consider("do while"); 17975 else if (node instanceof AST_If) { 17976 base54.consider("if"); 17977 if (node.alternative) base54.consider("else"); 17978 } 17979 else if (node instanceof AST_Var) 17980 base54.consider("var"); 17981 else if (node instanceof AST_Const) 17982 base54.consider("const"); 17983 else if (node instanceof AST_Lambda) 17984 base54.consider("function"); 17985 else if (node instanceof AST_For) 17986 base54.consider("for"); 17987 else if (node instanceof AST_ForIn) 17988 base54.consider("for in"); 17989 else if (node instanceof AST_Switch) 17990 base54.consider("switch"); 17991 else if (node instanceof AST_Case) 17992 base54.consider("case"); 17993 else if (node instanceof AST_Default) 17994 base54.consider("default"); 17995 else if (node instanceof AST_With) 17996 base54.consider("with"); 17997 else if (node instanceof AST_ObjectSetter) 17998 base54.consider("set" + node.key); 17999 else if (node instanceof AST_ObjectGetter) 18000 base54.consider("get" + node.key); 18001 else if (node instanceof AST_ObjectKeyVal) 18002 base54.consider(node.key); 18003 else if (node instanceof AST_New) 18004 base54.consider("new"); 18005 else if (node instanceof AST_This) 18006 base54.consider("this"); 18007 else if (node instanceof AST_Try) 18008 base54.consider("try"); 18009 else if (node instanceof AST_Catch) 18010 base54.consider("catch"); 18011 else if (node instanceof AST_Finally) 18012 base54.consider("finally"); 18013 else if (node instanceof AST_Symbol && node.unmangleable(options)) 18014 base54.consider(node.name); 18015 else if (node instanceof AST_Unary || node instanceof AST_Binary) 18016 base54.consider(node.operator); 18017 else if (node instanceof AST_Dot) 18018 base54.consider(node.property); 18019 }); 18020 this.walk(tw); 18021 base54.sort(); 18022}); 18023 18024var base54 = (function() { 18025 var string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789"; 18026 var chars, frequency; 18027 function reset() { 18028 frequency = Object.create(null); 18029 chars = string.split("").map(function(ch){ return ch.charCodeAt(0) }); 18030 chars.forEach(function(ch){ frequency[ch] = 0 }); 18031 } 18032 base54.consider = function(str){ 18033 for (var i = str.length; --i >= 0;) { 18034 var code = str.charCodeAt(i); 18035 if (code in frequency) ++frequency[code]; 18036 } 18037 }; 18038 base54.sort = function() { 18039 chars = mergeSort(chars, function(a, b){ 18040 if (is_digit(a) && !is_digit(b)) return 1; 18041 if (is_digit(b) && !is_digit(a)) return -1; 18042 return frequency[b] - frequency[a]; 18043 }); 18044 }; 18045 base54.reset = reset; 18046 reset(); 18047 base54.get = function(){ return chars }; 18048 base54.freq = function(){ return frequency }; 18049 function base54(num) { 18050 var ret = "", base = 54; 18051 num++; 18052 do { 18053 num--; 18054 ret += String.fromCharCode(chars[num % base]); 18055 num = Math.floor(num / base); 18056 base = 64; 18057 } while (num > 0); 18058 return ret; 18059 }; 18060 return base54; 18061})(); 18062 18063AST_Toplevel.DEFMETHOD("scope_warnings", function(options){ 18064 options = defaults(options, { 18065 assign_to_global : true, 18066 eval : true, 18067 func_arguments : true, 18068 nested_defuns : true, 18069 undeclared : false, // this makes a lot of noise 18070 unreferenced : true, 18071 });
18072 var tw = new TreeWalker(function(node){ 18073 if (options.undeclared 18074 && node instanceof AST_SymbolRef 18075 && node.undeclared()) 18076 { 18077 // XXX: this also warns about JS standard names, 18078 // i.e. Object, Array, parseInt etc. Should add a list of 18079 // exceptions. 18080 AST_Node.warn("Undeclared symbol: {name} [{file}:{line},{col}]", { 18081 name: node.name, 18082 file: node.start.file, 18083 line: node.start.line, 18084 col: node.start.col 18085 }); 18086 } 18087 if (options.assign_to_global) 18088 { 18089 var sym = null; 18090 if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef) 18091 sym = node.left; 18092 else if (node instanceof AST_ForIn && node.init instanceof AST_SymbolRef) 18093 sym = node.init; 18094 if (sym 18095 && (sym.undeclared() 18096 || (sym.global() && sym.scope !== sym.definition().scope))) { 18097 AST_Node.warn("{msg}: {name} [{file}:{line},{col}]", { 18098 msg: sym.undeclared() ? "Accidental global?" : "Assignment to global", 18099 name: sym.name, 18100 file: sym.start.file, 18101 line: sym.start.line, 18102 col: sym.start.col 18103 }); 18104 } 18105 } 18106 if (options.eval 18107 && node instanceof AST_SymbolRef 18108 && node.undeclared() 18109 && node.name == "eval") { 18110 AST_Node.warn("Eval is used [{file}:{line},{col}]", node.start); 18111 } 18112 if (options.unreferenced 18113 && (node instanceof AST_SymbolDeclaration || node instanceof AST_Label) 18114 && !(node instanceof AST_SymbolCatch) 18115 && node.unreferenced()) { 18116 AST_Node.warn("{type} {name} is declared but not referenced [{file}:{line},{col}]", { 18117 type: node instanceof AST_Label ? "Label" : "Symbol", 18118 name: node.name, 18119 file: node.start.file, 18120 line: node.start.line, 18121 col: node.start.col 18122 }); 18123 } 18124 if (options.func_arguments 18125 && node instanceof AST_Lambda 18126 && node.uses_arguments) { 18127 AST_Node.warn("arguments used in function {name} [{file}:{line},{col}]", { 18128 name: node.name ? node.name.name : "anonymous", 18129 file: node.start.file, 18130 line: node.start.line, 18131 col: node.start.col 18132 }); 18133 } 18134 if (options.nested_defuns 18135 && node instanceof AST_Defun 18136 && !(tw.parent() instanceof AST_Scope)) { 18137 AST_Node.warn("Function {name} declared in nested statement \"{type}\" [{file}:{line},{col}]", { 18138 name: node.name.name, 18139 type: tw.parent().TYPE, 18140 file: node.start.file, 18141 line: node.start.line, 18142 col: node.start.col 18143 }); 18144 } 18145 }); 18146 this.walk(tw); 18147}); 18148 18149/*********************************************************************** 18150 18151 A JavaScript tokenizer / parser / beautifier / compressor. 18152 https://github.com/mishoo/UglifyJS2 18153 18154 -------------------------------- (C) --------------------------------- 18155 18156 Author: Mihai Bazon 18157 <[email protected]> 18158 http://mihai.bazon.net/blog 18159 18160 Distributed under the BSD license: 18161 18162 Copyright 2012 (c) Mihai Bazon <[email protected]> 18163 18164 Redistribution and use in source and binary forms, with or without 18165 modification, are permitted provided that the following conditions 18166 are met: 18167 18168 * Redistributions of source code must retain the above 18169 copyright notice, this list of conditions and the following 18170 disclaimer. 18171 18172 * Redistributions in binary form must reproduce the above 18173 copyright notice, this list of conditions and the following 18174 disclaimer in the documentation and/or other materials 18175 provided with the distribution. 18176 18177 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER âAS ISâ AND ANY 18178 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18179 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18180 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE 18181 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
18182 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 18183 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 18184 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 18185 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 18186 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 18187 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 18188 SUCH DAMAGE. 18189 18190 ***********************************************************************/ 18191 18192"use strict"; 18193 18194var EXPECT_DIRECTIVE = /^$|[;{][\s\n]*$/; 18195 18196function is_some_comments(comment) { 18197 // multiline comment 18198 return comment.type == "comment2" && /@preserve|@license|@cc_on/i.test(comment.value); 18199} 18200 18201function OutputStream(options) { 18202 18203 options = defaults(options, { 18204 ascii_only : false, 18205 beautify : false, 18206 bracketize : false, 18207 comments : false, 18208 indent_level : 4, 18209 indent_start : 0, 18210 inline_script : true, 18211 keep_quoted_props: false, 18212 max_line_len : false, 18213 preamble : null, 18214 preserve_line : false, 18215 quote_keys : false, 18216 quote_style : 0, 18217 screw_ie8 : true, 18218 semicolons : true, 18219 shebang : true, 18220 source_map : null, 18221 space_colon : true, 18222 unescape_regexps : false, 18223 width : 80, 18224 wrap_iife : false, 18225 }, true); 18226 18227 // Convert comment option to RegExp if neccessary and set up comments filter 18228 var comment_filter = return_false; // Default case, throw all comments away 18229 if (options.comments) { 18230 var comments = options.comments; 18231 if (typeof options.comments === "string" && /^\/.*\/[a-zA-Z]*$/.test(options.comments)) { 18232 var regex_pos = options.comments.lastIndexOf("/"); 18233 comments = new RegExp( 18234 options.comments.substr(1, regex_pos - 1), 18235 options.comments.substr(regex_pos + 1) 18236 ); 18237 } 18238 if (comments instanceof RegExp) { 18239 comment_filter = function(comment) { 18240 return comment.type != "comment5" && comments.test(comment.value); 18241 }; 18242 } 18243 else if (typeof comments === "function") { 18244 comment_filter = function(comment) { 18245 return comment.type != "comment5" && comments(this, comment); 18246 }; 18247 } 18248 else if (comments === "some") { 18249 comment_filter = is_some_comments; 18250 } else { // NOTE includes "all" option 18251 comment_filter = return_true; 18252 } 18253 } 18254 18255 var indentation = 0; 18256 var current_col = 0; 18257 var current_line = 1; 18258 var current_pos = 0; 18259 var OUTPUT = ""; 18260 18261 function to_ascii(str, identifier) { 18262 return str.replace(/[\u0000-\u001f\u007f-\uffff]/g, function(ch) { 18263 var code = ch.charCodeAt(0).toString(16); 18264 if (code.length <= 2 && !identifier) { 18265 while (code.length < 2) code = "0" + code; 18266 return "\\x" + code; 18267 } else { 18268 while (code.length < 4) code = "0" + code; 18269 return "\\u" + code; 18270 } 18271 }); 18272 }; 18273 18274 function make_string(str, quote) { 18275 var dq = 0, sq = 0; 18276 str = str.replace(/[\\\b\f\n\r\v\t\x22\x27\u2028\u2029\0\ufeff]/g, 18277 function(s, i){ 18278 switch (s) { 18279 case '"': ++dq; return '"'; 18280 case "'": ++sq; return "'"; 18281 case "\\": return "\\\\"; 18282 case "\n": return "\\n"; 18283 case "\r": return "\\r"; 18284 case "\t": return "\\t"; 18285 case "\b": return "\\b"; 18286 case "\f": return "\\f"; 18287 case "\x0B": return options.screw_ie8 ? "\\v" : "\\x0B"; 18288 case "\u2028": return "\\u2028"; 18289 case "\u2029": return "\\u2029"; 18290 case "\ufeff": return "\\ufeff"; 18291 case "\0": 18292 return /[0-7]/.test(str.charAt(i+1)) ? "\\x00" : "\\0"; 18293 } 18294 return s; 18295 }); 18296 function quote_single() { 18297 return "'" + str.replace(/\x27/g, "\\'") + "'"; 18298 } 18299 function quote_double() { 18300 return '"' + str.replace(/\x22/g, '\\"') + '"'; 18301 } 18302 if (options.ascii_only) str = to_ascii(str); 18303 switch (options.quote_style) { 18304 case 1: 18305 return quote_single(); 18306 case 2: 18307 return quote_double(); 18308 case 3: 18309 return quote == "'" ? quote_single() : quote_double(); 18310 default: 18311 return dq > sq ? quote_single() : quote_double(); 18312 } 18313 }; 18314 18315 function encode_string(str, quote) { 18316 var ret = make_string(str, quote); 18317 if (options.inline_script) { 18318 ret = ret.replace(/<\x2fscript([>\/\t\n\f\r ])/gi, "<\\/script$1"); 18319 ret = ret.replace(/\x3c!--/g, "\\x3c!--"); 18320 ret = ret.replace(/--\x3e/g, "--\\x3e"); 18321 } 18322 return ret; 18323 }; 18324 18325 function make_name(name) { 18326 name = name.toString(); 18327 if (options.ascii_only) 18328 name = to_ascii(name, true); 18329 return name; 18330 }; 18331 18332 function make_indent(back) { 18333 return repeat_string(" ", options.indent_start + indentation - back * options.indent_level); 18334 }; 18335 18336 /* -----[ beautification/minification ]----- */ 18337 18338 var might_need_space = false; 18339 var might_need_semicolon = false; 18340 var might_add_newline = 0; 18341 var last = ""; 18342 18343 var ensure_line_len = options.max_line_len ? function() { 18344 if (current_col > options.max_line_len) { 18345 if (might_add_newline) { 18346 var left = OUTPUT.slice(0, might_add_newline); 18347 var right = OUTPUT.slice(might_add_newline); 18348 OUTPUT = left + "\n" + right; 18349 current_line++; 18350 current_pos++; 18351 current_col = right.length; 18352 } 18353 if (current_col > options.max_line_len) { 18354 AST_Node.warn("Output exceeds {max_line_len} characters", options); 18355 } 18356 } 18357 might_add_newline = 0; 18358 } : noop; 18359 18360 var requireSemicolonChars = makePredicate("( [ + * / - , ."); 18361 18362 function print(str) { 18363 str = String(str); 18364 var ch = str.charAt(0);
18365 var prev = last.charAt(last.length - 1); 18366 if (might_need_semicolon) { 18367 might_need_semicolon = false; 18368 18369 if (prev == ":" && ch == "}" || (!ch || ";}".indexOf(ch) < 0) && prev != ";") { 18370 if (options.semicolons || requireSemicolonChars(ch)) { 18371 OUTPUT += ";"; 18372 current_col++; 18373 current_pos++; 18374 } else { 18375 ensure_line_len(); 18376 OUTPUT += "\n"; 18377 current_pos++; 18378 current_line++; 18379 current_col = 0; 18380 18381 if (/^\s+$/.test(str)) { 18382 // reset the semicolon flag, since we didn't print one 18383 // now and might still have to later 18384 might_need_semicolon = true; 18385 } 18386 } 18387 18388 if (!options.beautify) 18389 might_need_space = false; 18390 } 18391 } 18392 18393 if (!options.beautify && options.preserve_line && stack[stack.length - 1]) { 18394 var target_line = stack[stack.length - 1].start.line; 18395 while (current_line < target_line) { 18396 ensure_line_len(); 18397 OUTPUT += "\n"; 18398 current_pos++; 18399 current_line++; 18400 current_col = 0; 18401 might_need_space = false; 18402 } 18403 } 18404 18405 if (might_need_space) { 18406 if ((is_identifier_char(prev) 18407 && (is_identifier_char(ch) || ch == "\\")) 18408 || (ch == "/" && ch == prev) 18409 || ((ch == "+" || ch == "-") && ch == last)) 18410 { 18411 OUTPUT += " "; 18412 current_col++; 18413 current_pos++; 18414 } 18415 might_need_space = false; 18416 } 18417 OUTPUT += str; 18418 current_pos += str.length; 18419 var a = str.split(/\r?\n/), n = a.length - 1; 18420 current_line += n; 18421 current_col += a[0].length; 18422 if (n > 0) { 18423 ensure_line_len(); 18424 current_col = a[n].length; 18425 } 18426 last = str; 18427 }; 18428 18429 var space = options.beautify ? function() { 18430 print(" "); 18431 } : function() { 18432 might_need_space = true; 18433 }; 18434 18435 var indent = options.beautify ? function(half) { 18436 if (options.beautify) { 18437 print(make_indent(half ? 0.5 : 0)); 18438 } 18439 } : noop; 18440 18441 var with_indent = options.beautify ? function(col, cont) { 18442 if (col === true) col = next_indent(); 18443 var save_indentation = indentation; 18444 indentation = col; 18445 var ret = cont(); 18446 indentation = save_indentation; 18447 return ret; 18448 } : function(col, cont) { return cont() }; 18449 18450 var newline = options.beautify ? function() { 18451 print("\n"); 18452 } : options.max_line_len ? function() { 18453 ensure_line_len(); 18454 might_add_newline = OUTPUT.length; 18455 } : noop; 18456 18457 var semicolon = options.beautify ? function() { 18458 print(";"); 18459 } : function() { 18460 might_need_semicolon = true; 18461 }; 18462 18463 function force_semicolon() { 18464 might_need_semicolon = false; 18465 print(";"); 18466 }; 18467 18468 function next_indent() { 18469 return indentation + options.indent_level; 18470 }; 18471 18472 function with_block(cont) { 18473 var ret; 18474 print("{"); 18475 newline(); 18476 with_indent(next_indent(), function(){ 18477 ret = cont(); 18478 }); 18479 indent(); 18480 print("}"); 18481 return ret; 18482 }; 18483 18484 function with_parens(cont) { 18485 print("("); 18486 //XXX: still nice to have that for argument lists 18487 //var ret = with_indent(current_col, cont); 18488 var ret = cont(); 18489 print(")"); 18490 return ret; 18491 }; 18492 18493 function with_square(cont) { 18494 print("["); 18495 //var ret = with_indent(current_col, cont); 18496 var ret = cont(); 18497 print("]"); 18498 return ret; 18499 }; 18500 18501 function comma() { 18502 print(","); 18503 space(); 18504 }; 18505 18506 function colon() { 18507 print(":"); 18508 if (options.space_colon) space(); 18509 }; 18510 18511 var add_mapping = options.source_map ? function(token, name) { 18512 try { 18513 if (token) options.source_map.add( 18514 token.file || "?", 18515 current_line, current_col, 18516 token.line, token.col, 18517 (!name && token.type == "name") ? token.value : name 18518 ); 18519 } catch(ex) { 18520 AST_Node.warn("Couldn't figure out mapping for {file}:{line},{col} â {cline},{ccol} [{name}]", { 18521 file: token.file, 18522 line: token.line, 18523 col: token.col, 18524 cline: current_line, 18525 ccol: current_col, 18526 name: name || "" 18527 }) 18528 } 18529 } : noop; 18530 18531 function get() { 18532 if (might_add_newline) { 18533 ensure_line_len(); 18534 } 18535 return OUTPUT; 18536 }; 18537 18538 var stack = []; 18539 return { 18540 get : get, 18541 toString : get, 18542 indent : indent, 18543 indentation : function() { return indentation }, 18544 current_width : function() { return current_col - indentation }, 18545 should_break : function() { return options.width && this.current_width() >= options.width }, 18546 newline : newline, 18547 print : print, 18548 space : space, 18549 comma : comma, 18550 colon : colon, 18551 last : function() { return last }, 18552 semicolon : semicolon,
18553 force_semicolon : force_semicolon, 18554 to_ascii : to_ascii, 18555 print_name : function(name) { print(make_name(name)) }, 18556 print_string : function(str, quote, escape_directive) { 18557 var encoded = encode_string(str, quote); 18558 if (escape_directive === true && encoded.indexOf("\\") === -1) { 18559 // Insert semicolons to break directive prologue 18560 if (!EXPECT_DIRECTIVE.test(OUTPUT)) { 18561 force_semicolon(); 18562 } 18563 force_semicolon(); 18564 } 18565 print(encoded); 18566 }, 18567 encode_string : encode_string, 18568 next_indent : next_indent, 18569 with_indent : with_indent, 18570 with_block : with_block, 18571 with_parens : with_parens, 18572 with_square : with_square, 18573 add_mapping : add_mapping, 18574 option : function(opt) { return options[opt] }, 18575 comment_filter : comment_filter, 18576 line : function() { return current_line }, 18577 col : function() { return current_col }, 18578 pos : function() { return current_pos }, 18579 push_node : function(node) { stack.push(node) }, 18580 pop_node : function() { return stack.pop() }, 18581 parent : function(n) { 18582 return stack[stack.length - 2 - (n || 0)]; 18583 } 18584 }; 18585 18586}; 18587 18588/* -----[ code generators ]----- */ 18589 18590(function(){ 18591 18592 /* -----[ utils ]----- */ 18593 18594 function DEFPRINT(nodetype, generator) { 18595 nodetype.DEFMETHOD("_codegen", generator); 18596 }; 18597 18598 var use_asm = false; 18599 var in_directive = false; 18600 18601 AST_Node.DEFMETHOD("print", function(stream, force_parens){ 18602 var self = this, generator = self._codegen, prev_use_asm = use_asm; 18603 if (self instanceof AST_Directive && self.value == "use asm" && stream.parent() instanceof AST_Scope) { 18604 use_asm = true; 18605 } 18606 function doit() { 18607 self.add_comments(stream); 18608 self.add_source_map(stream); 18609 generator(self, stream); 18610 } 18611 stream.push_node(self); 18612 if (force_parens || self.needs_parens(stream)) { 18613 stream.with_parens(doit); 18614 } else { 18615 doit(); 18616 } 18617 stream.pop_node(); 18618 if (self instanceof AST_Scope) { 18619 use_asm = prev_use_asm; 18620 } 18621 }); 18622 18623 AST_Node.DEFMETHOD("print_to_string", function(options){ 18624 var s = OutputStream(options); 18625 if (!options) s._readonly = true; 18626 this.print(s); 18627 return s.get(); 18628 }); 18629 18630 /* -----[ comments ]----- */ 18631 18632 AST_Node.DEFMETHOD("add_comments", function(output){ 18633 if (output._readonly) return; 18634 var self = this; 18635 var start = self.start; 18636 if (start && !start._comments_dumped) { 18637 start._comments_dumped = true; 18638 var comments = start.comments_before || []; 18639 18640 // XXX: ugly fix for https://github.com/mishoo/UglifyJS2/issues/112 18641 // and https://github.com/mishoo/UglifyJS2/issues/372 18642 if (self instanceof AST_Exit && self.value) { 18643 self.value.walk(new TreeWalker(function(node){ 18644 if (node.start && node.start.comments_before) { 18645 comments = comments.concat(node.start.comments_before); 18646 node.start.comments_before = []; 18647 } 18648 if (node instanceof AST_Function || 18649 node instanceof AST_Array || 18650 node instanceof AST_Object) 18651 { 18652 return true; // don't go inside. 18653 } 18654 })); 18655 } 18656 18657 if (output.pos() == 0) { 18658 if (comments.length > 0 && output.option("shebang") && comments[0].type == "comment5") { 18659 output.print("#!" + comments.shift().value + "\n"); 18660 output.indent(); 18661 } 18662 var preamble = output.option("preamble"); 18663 if (preamble) { 18664 output.print(preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n")); 18665 } 18666 } 18667 18668 comments = comments.filter(output.comment_filter, self); 18669 18670 // Keep single line comments after nlb, after nlb 18671 if (!output.option("beautify") && comments.length > 0 && 18672 /comment[134]/.test(comments[0].type) && 18673 output.col() !== 0 && comments[0].nlb) 18674 { 18675 output.print("\n"); 18676 } 18677
18678 comments.forEach(function(c){ 18679 if (/comment[134]/.test(c.type)) { 18680 output.print("//" + c.value + "\n"); 18681 output.indent(); 18682 } 18683 else if (c.type == "comment2") { 18684 output.print("/*" + c.value + "*/"); 18685 if (start.nlb) { 18686 output.print("\n"); 18687 output.indent(); 18688 } else { 18689 output.space(); 18690 } 18691 } 18692 }); 18693 } 18694 }); 18695 18696 /* -----[ PARENTHESES ]----- */ 18697 18698 function PARENS(nodetype, func) { 18699 if (Array.isArray(nodetype)) { 18700 nodetype.forEach(function(nodetype){ 18701 PARENS(nodetype, func); 18702 }); 18703 } else { 18704 nodetype.DEFMETHOD("needs_parens", func); 18705 } 18706 }; 18707 18708 PARENS(AST_Node, function(){ 18709 return false; 18710 }); 18711 18712 // a function expression needs parens around it when it's provably 18713 // the first token to appear in a statement. 18714 PARENS(AST_Function, function(output){ 18715 if (first_in_statement(output)) { 18716 return true; 18717 } 18718 18719 if (output.option('wrap_iife')) { 18720 var p = output.parent(); 18721 return p instanceof AST_Call && p.expression === this; 18722 } 18723 18724 return false; 18725 }); 18726 18727 // same goes for an object literal, because otherwise it would be 18728 // interpreted as a block of code. 18729 PARENS(AST_Object, function(output){ 18730 return first_in_statement(output); 18731 }); 18732 18733 PARENS(AST_Unary, function(output){ 18734 var p = output.parent(); 18735 return p instanceof AST_PropAccess && p.expression === this 18736 || p instanceof AST_Call && p.expression === this; 18737 }); 18738 18739 PARENS(AST_Seq, function(output){ 18740 var p = output.parent(); 18741 return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4) 18742 || p instanceof AST_Unary // !(foo, bar, baz) 18743 || p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8 18744 || p instanceof AST_VarDef // var a = (1, 2), b = a + a; ==> b == 4 18745 || p instanceof AST_PropAccess // (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2 18746 || p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ] 18747 || p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2 18748 || p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30) 18749 * ==> 20 (side effect, set a := 10 and b := 20) */ 18750 ; 18751 }); 18752 18753 PARENS(AST_Binary, function(output){ 18754 var p = output.parent(); 18755 // (foo && bar)() 18756 if (p instanceof AST_Call && p.expression === this) 18757 return true; 18758 // typeof (foo && bar) 18759 if (p instanceof AST_Unary) 18760 return true; 18761 // (foo && bar)["prop"], (foo && bar).prop 18762 if (p instanceof AST_PropAccess && p.expression === this) 18763 return true; 18764 // this deals with precedence: 3 * (2 + 1) 18765 if (p instanceof AST_Binary) { 18766 var po = p.operator, pp = PRECEDENCE[po]; 18767 var so = this.operator, sp = PRECEDENCE[so]; 18768 if (pp > sp 18769 || (pp == sp 18770 && this === p.right)) { 18771 return true; 18772 } 18773 } 18774 }); 18775 18776 PARENS(AST_PropAccess, function(output){ 18777 var p = output.parent(); 18778 if (p instanceof AST_New && p.expression === this) { 18779 // i.e. new (foo.bar().baz) 18780 // 18781 // if there's one call into this subtree, then we need 18782 // parens around it too, otherwise the call will be 18783 // interpreted as passing the arguments to the upper New 18784 // expression. 18785 try { 18786 this.walk(new TreeWalker(function(node){ 18787 if (node instanceof AST_Call) throw p; 18788 })); 18789 } catch(ex) { 18790 if (ex !== p) throw ex; 18791 return true; 18792 } 18793 } 18794 });
vendor: 12,194 bytes, lines 18795-19160
18795 18796 PARENS(AST_Call, function(output){ 18797 var p = output.parent(), p1; 18798 if (p instanceof AST_New && p.expression === this) 18799 return true; 18800 18801 // workaround for Safari bug. 18802 // https://bugs.webkit.org/show_bug.cgi?id=123506 18803 return this.expression instanceof AST_Function 18804 && p instanceof AST_PropAccess 18805 && p.expression === this 18806 && (p1 = output.parent(1)) instanceof AST_Assign 18807 && p1.left === p; 18808 }); 18809 18810 PARENS(AST_New, function(output){ 18811 var p = output.parent(); 18812 if (!need_constructor_parens(this, output) 18813 && (p instanceof AST_PropAccess // (new Date).getTime(), (new Date)["getTime"]() 18814 || p instanceof AST_Call && p.expression === this)) // (new foo)(bar) 18815 return true; 18816 }); 18817 18818 PARENS(AST_Number, function(output){ 18819 var p = output.parent(); 18820 if (p instanceof AST_PropAccess && p.expression === this) { 18821 var value = this.getValue(); 18822 if (value < 0 || /^0/.test(make_num(value))) { 18823 return true; 18824 } 18825 } 18826 }); 18827 18828 PARENS([ AST_Assign, AST_Conditional ], function (output){ 18829 var p = output.parent(); 18830 // !(a = false) â true 18831 if (p instanceof AST_Unary) 18832 return true; 18833 // 1 + (a = 2) + 3 â 6, side effect setting a = 2 18834 if (p instanceof AST_Binary && !(p instanceof AST_Assign)) 18835 return true; 18836 // (a = func)() âorâ new (a = Object)() 18837 if (p instanceof AST_Call && p.expression === this) 18838 return true; 18839 // (a = foo) ? bar : baz 18840 if (p instanceof AST_Conditional && p.condition === this) 18841 return true; 18842 // (a = foo)["prop"] âorâ (a = foo).prop 18843 if (p instanceof AST_PropAccess && p.expression === this) 18844 return true; 18845 }); 18846 18847 /* -----[ PRINTERS ]----- */ 18848 18849 DEFPRINT(AST_Directive, function(self, output){ 18850 output.print_string(self.value, self.quote); 18851 output.semicolon(); 18852 }); 18853 DEFPRINT(AST_Debugger, function(self, output){ 18854 output.print("debugger"); 18855 output.semicolon(); 18856 }); 18857 18858 /* -----[ statements ]----- */ 18859 18860 function display_body(body, is_toplevel, output, allow_directives) { 18861 var last = body.length - 1; 18862 in_directive = allow_directives; 18863 body.forEach(function(stmt, i){ 18864 if (in_directive === true && !(stmt instanceof AST_Directive || 18865 stmt instanceof AST_EmptyStatement || 18866 (stmt instanceof AST_SimpleStatement && stmt.body instanceof AST_String) 18867 )) { 18868 in_directive = false; 18869 } 18870 if (!(stmt instanceof AST_EmptyStatement)) { 18871 output.indent(); 18872 stmt.print(output); 18873 if (!(i == last && is_toplevel)) { 18874 output.newline(); 18875 if (is_toplevel) output.newline(); 18876 } 18877 } 18878 if (in_directive === true && 18879 stmt instanceof AST_SimpleStatement && 18880 stmt.body instanceof AST_String 18881 ) { 18882 in_directive = false; 18883 } 18884 }); 18885 in_directive = false; 18886 }; 18887 18888 AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output){ 18889 force_statement(this.body, output); 18890 }); 18891 18892 DEFPRINT(AST_Statement, function(self, output){ 18893 self.body.print(output); 18894 output.semicolon(); 18895 }); 18896 DEFPRINT(AST_Toplevel, function(self, output){ 18897 display_body(self.body, true, output, true); 18898 output.print(""); 18899 }); 18900 DEFPRINT(AST_LabeledStatement, function(self, output){ 18901 self.label.print(output); 18902 output.colon(); 18903 self.body.print(output); 18904 }); 18905 DEFPRINT(AST_SimpleStatement, function(self, output){ 18906 self.body.print(output); 18907 output.semicolon(); 18908 }); 18909 function print_bracketed(body, output, allow_directives) { 18910 if (body.length > 0) output.with_block(function(){ 18911 display_body(body, false, output, allow_directives); 18912 }); 18913 else output.print("{}"); 18914 }; 18915 DEFPRINT(AST_BlockStatement, function(self, output){ 18916 print_bracketed(self.body, output); 18917 }); 18918 DEFPRINT(AST_EmptyStatement, function(self, output){ 18919 output.semicolon(); 18920 }); 18921 DEFPRINT(AST_Do, function(self, output){ 18922 output.print("do"); 18923 output.space(); 18924 make_block(self.body, output); 18925 output.space(); 18926 output.print("while"); 18927 output.space(); 18928 output.with_parens(function(){ 18929 self.condition.print(output); 18930 }); 18931 output.semicolon(); 18932 }); 18933 DEFPRINT(AST_While, function(self, output){ 18934 output.print("while"); 18935 output.space(); 18936 output.with_parens(function(){ 18937 self.condition.print(output); 18938 }); 18939 output.space(); 18940 self._do_print_body(output); 18941 }); 18942 DEFPRINT(AST_For, function(self, output){ 18943 output.print("for"); 18944 output.space(); 18945 output.with_parens(function(){ 18946 if (self.init) { 18947 if (self.init instanceof AST_Definitions) { 18948 self.init.print(output); 18949 } else { 18950 parenthesize_for_noin(self.init, output, true); 18951 } 18952 output.print(";"); 18953 output.space(); 18954 } else { 18955 output.print(";"); 18956 } 18957 if (self.condition) { 18958 self.condition.print(output); 18959 output.print(";"); 18960 output.space(); 18961 } else { 18962 output.print(";"); 18963 } 18964 if (self.step) { 18965 self.step.print(output); 18966 } 18967 }); 18968 output.space(); 18969 self._do_print_body(output); 18970 }); 18971 DEFPRINT(AST_ForIn, function(self, output){ 18972 output.print("for"); 18973 output.space(); 18974 output.with_parens(function(){ 18975 self.init.print(output); 18976 output.space(); 18977 output.print("in"); 18978 output.space(); 18979 self.object.print(output); 18980 }); 18981 output.space(); 18982 self._do_print_body(output); 18983 }); 18984 DEFPRINT(AST_With, function(self, output){ 18985 output.print("with"); 18986 output.space(); 18987 output.with_parens(function(){ 18988 self.expression.print(output); 18989 }); 18990 output.space(); 18991 self._do_print_body(output); 18992 }); 18993 18994 /* -----[ functions ]----- */ 18995 AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword){ 18996 var self = this; 18997 if (!nokeyword) { 18998 output.print("function"); 18999 } 19000 if (self.name) { 19001 output.space(); 19002 self.name.print(output); 19003 } 19004 output.with_parens(function(){ 19005 self.argnames.forEach(function(arg, i){ 19006 if (i) output.comma(); 19007 arg.print(output); 19008 }); 19009 }); 19010 output.space(); 19011 print_bracketed(self.body, output, true); 19012 }); 19013 DEFPRINT(AST_Lambda, function(self, output){ 19014 self._do_print(output); 19015 }); 19016 19017 /* -----[ exits ]----- */ 19018 AST_Exit.DEFMETHOD("_do_print", function(output, kind){ 19019 output.print(kind); 19020 if (this.value) { 19021 output.space(); 19022 this.value.print(output); 19023 } 19024 output.semicolon(); 19025 }); 19026 DEFPRINT(AST_Return, function(self, output){ 19027 self._do_print(output, "return"); 19028 }); 19029 DEFPRINT(AST_Throw, function(self, output){ 19030 self._do_print(output, "throw"); 19031 }); 19032 19033 /* -----[ loop control ]----- */ 19034 AST_LoopControl.DEFMETHOD("_do_print", function(output, kind){ 19035 output.print(kind); 19036 if (this.label) { 19037 output.space(); 19038 this.label.print(output); 19039 } 19040 output.semicolon(); 19041 }); 19042 DEFPRINT(AST_Break, function(self, output){ 19043 self._do_print(output, "break"); 19044 }); 19045 DEFPRINT(AST_Continue, function(self, output){ 19046 self._do_print(output, "continue"); 19047 }); 19048 19049 /* -----[ if ]----- */ 19050 function make_then(self, output) { 19051 var b = self.body; 19052 if (output.option("bracketize") 19053 || !output.option("screw_ie8") && b instanceof AST_Do) 19054 return make_block(b, output); 19055 // The squeezer replaces "block"-s that contain only a single 19056 // statement with the statement itself; technically, the AST 19057 // is correct, but this can create problems when we output an 19058 // IF having an ELSE clause where the THEN clause ends in an 19059 // IF *without* an ELSE block (then the outer ELSE would refer 19060 // to the inner IF). This function checks for this case and 19061 // adds the block brackets if needed. 19062 if (!b) return output.force_semicolon(); 19063 while (true) { 19064 if (b instanceof AST_If) { 19065 if (!b.alternative) { 19066 make_block(self.body, output); 19067 return; 19068 } 19069 b = b.alternative; 19070 } 19071 else if (b instanceof AST_StatementWithBody) { 19072 b = b.body; 19073 } 19074 else break; 19075 } 19076 force_statement(self.body, output); 19077 }; 19078 DEFPRINT(AST_If, function(self, output){ 19079 output.print("if"); 19080 output.space(); 19081 output.with_parens(function(){ 19082 self.condition.print(output); 19083 }); 19084 output.space(); 19085 if (self.alternative) { 19086 make_then(self, output); 19087 output.space(); 19088 output.print("else"); 19089 output.space(); 19090 if (self.alternative instanceof AST_If) 19091 self.alternative.print(output); 19092 else 19093 force_statement(self.alternative, output); 19094 } else { 19095 self._do_print_body(output); 19096 } 19097 }); 19098 19099 /* -----[ switch ]----- */ 19100 DEFPRINT(AST_Switch, function(self, output){ 19101 output.print("switch"); 19102 output.space(); 19103 output.with_parens(function(){ 19104 self.expression.print(output); 19105 }); 19106 output.space(); 19107 var last = self.body.length - 1; 19108 if (last < 0) output.print("{}"); 19109 else output.with_block(function(){ 19110 self.body.forEach(function(branch, i){ 19111 output.indent(true); 19112 branch.print(output); 19113 if (i < last && branch.body.length > 0) 19114 output.newline(); 19115 }); 19116 }); 19117 }); 19118 AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output){ 19119 output.newline(); 19120 this.body.forEach(function(stmt){ 19121 output.indent(); 19122 stmt.print(output); 19123 output.newline(); 19124 }); 19125 }); 19126 DEFPRINT(AST_Default, function(self, output){ 19127 output.print("default:"); 19128 self._do_print_body(output); 19129 }); 19130 DEFPRINT(AST_Case, function(self, output){ 19131 output.print("case"); 19132 output.space(); 19133 self.expression.print(output); 19134 output.print(":"); 19135 self._do_print_body(output); 19136 }); 19137 19138 /* -----[ exceptions ]----- */ 19139 DEFPRINT(AST_Try, function(self, output){ 19140 output.print("try"); 19141 output.space(); 19142 print_bracketed(self.body, output); 19143 if (self.bcatch) { 19144 output.space(); 19145 self.bcatch.print(output); 19146 } 19147 if (self.bfinally) { 19148 output.space(); 19149 self.bfinally.print(output); 19150 } 19151 }); 19152 DEFPRINT(AST_Catch, function(self, output){ 19153 output.print("catch"); 19154 output.space(); 19155 output.with_parens(function(){ 19156 self.argname.print(output); 19157 }); 19158 output.space(); 19159 print_bracketed(self.body, output); 19160 });
19161 DEFPRINT(AST_Finally, function(self, output){ 19162 output.print("finally"); 19163 output.space(); 19164 print_bracketed(self.body, output); 19165 }); 19166 19167 /* -----[ var/const ]----- */ 19168 AST_Definitions.DEFMETHOD("_do_print", function(output, kind){ 19169 output.print(kind); 19170 output.space(); 19171 this.definitions.forEach(function(def, i){ 19172 if (i) output.comma(); 19173 def.print(output); 19174 }); 19175 var p = output.parent(); 19176 var in_for = p instanceof AST_For || p instanceof AST_ForIn; 19177 var avoid_semicolon = in_for && p.init === this; 19178 if (!avoid_semicolon) 19179 output.semicolon(); 19180 }); 19181 DEFPRINT(AST_Var, function(self, output){ 19182 self._do_print(output, "var"); 19183 }); 19184 DEFPRINT(AST_Const, function(self, output){ 19185 self._do_print(output, "const"); 19186 }); 19187 19188 function parenthesize_for_noin(node, output, noin) { 19189 if (!noin) node.print(output); 19190 else try { 19191 // need to take some precautions here: 19192 // https://github.com/mishoo/UglifyJS2/issues/60 19193 node.walk(new TreeWalker(function(node){ 19194 if (node instanceof AST_Binary && node.operator == "in") 19195 throw output; 19196 })); 19197 node.print(output); 19198 } catch(ex) { 19199 if (ex !== output) throw ex; 19200 node.print(output, true); 19201 } 19202 }; 19203 19204 DEFPRINT(AST_VarDef, function(self, output){ 19205 self.name.print(output); 19206 if (self.value) { 19207 output.space(); 19208 output.print("="); 19209 output.space(); 19210 var p = output.parent(1); 19211 var noin = p instanceof AST_For || p instanceof AST_ForIn; 19212 parenthesize_for_noin(self.value, output, noin); 19213 } 19214 }); 19215 19216 /* -----[ other expressions ]----- */ 19217 DEFPRINT(AST_Call, function(self, output){ 19218 self.expression.print(output); 19219 if (self instanceof AST_New && !need_constructor_parens(self, output)) 19220 return; 19221 output.with_parens(function(){ 19222 self.args.forEach(function(expr, i){ 19223 if (i) output.comma(); 19224 expr.print(output); 19225 }); 19226 }); 19227 }); 19228 DEFPRINT(AST_New, function(self, output){ 19229 output.print("new"); 19230 output.space(); 19231 AST_Call.prototype._codegen(self, output); 19232 }); 19233 19234 AST_Seq.DEFMETHOD("_do_print", function(output){ 19235 this.car.print(output); 19236 if (this.cdr) { 19237 output.comma(); 19238 if (output.should_break()) { 19239 output.newline(); 19240 output.indent(); 19241 } 19242 this.cdr.print(output); 19243 } 19244 }); 19245 DEFPRINT(AST_Seq, function(self, output){ 19246 self._do_print(output); 19247 // var p = output.parent(); 19248 // if (p instanceof AST_Statement) { 19249 // output.with_indent(output.next_indent(), function(){ 19250 // self._do_print(output); 19251 // }); 19252 // } else { 19253 // self._do_print(output); 19254 // } 19255 }); 19256 DEFPRINT(AST_Dot, function(self, output){ 19257 var expr = self.expression; 19258 expr.print(output); 19259 if (expr instanceof AST_Number && expr.getValue() >= 0) { 19260 if (!/[xa-f.)]/i.test(output.last())) { 19261 output.print("."); 19262 } 19263 } 19264 output.print("."); 19265 // the name after dot would be mapped about here. 19266 output.add_mapping(self.end); 19267 output.print_name(self.property); 19268 }); 19269 DEFPRINT(AST_Sub, function(self, output){ 19270 self.expression.print(output); 19271 output.print("["); 19272 self.property.print(output); 19273 output.print("]"); 19274 }); 19275 DEFPRINT(AST_UnaryPrefix, function(self, output){ 19276 var op = self.operator; 19277 output.print(op); 19278 if (/^[a-z]/i.test(op) 19279 || (/[+-]$/.test(op) 19280 && self.expression instanceof AST_UnaryPrefix 19281 && /^[+-]/.test(self.expression.operator))) { 19282 output.space(); 19283 }
19284 self.expression.print(output); 19285 }); 19286 DEFPRINT(AST_UnaryPostfix, function(self, output){ 19287 self.expression.print(output); 19288 output.print(self.operator); 19289 }); 19290 DEFPRINT(AST_Binary, function(self, output){ 19291 var op = self.operator; 19292 self.left.print(output); 19293 if (op[0] == ">" /* ">>" ">>>" ">" ">=" */ 19294 && self.left instanceof AST_UnaryPostfix 19295 && self.left.operator == "--") { 19296 // space is mandatory to avoid outputting --> 19297 output.print(" "); 19298 } else { 19299 // the space is optional depending on "beautify" 19300 output.space(); 19301 } 19302 output.print(op); 19303 if ((op == "<" || op == "<<") 19304 && self.right instanceof AST_UnaryPrefix 19305 && self.right.operator == "!" 19306 && self.right.expression instanceof AST_UnaryPrefix 19307 && self.right.expression.operator == "--") { 19308 // space is mandatory to avoid outputting <!-- 19309 output.print(" "); 19310 } else { 19311 // the space is optional depending on "beautify" 19312 output.space(); 19313 } 19314 self.right.print(output); 19315 }); 19316 DEFPRINT(AST_Conditional, function(self, output){ 19317 self.condition.print(output); 19318 output.space(); 19319 output.print("?"); 19320 output.space(); 19321 self.consequent.print(output); 19322 output.space(); 19323 output.colon(); 19324 self.alternative.print(output); 19325 }); 19326 19327 /* -----[ literals ]----- */ 19328 DEFPRINT(AST_Array, function(self, output){ 19329 output.with_square(function(){ 19330 var a = self.elements, len = a.length; 19331 if (len > 0) output.space(); 19332 a.forEach(function(exp, i){ 19333 if (i) output.comma(); 19334 exp.print(output); 19335 // If the final element is a hole, we need to make sure it 19336 // doesn't look like a trailing comma, by inserting an actual 19337 // trailing comma. 19338 if (i === len - 1 && exp instanceof AST_Hole) 19339 output.comma(); 19340 }); 19341 if (len > 0) output.space(); 19342 }); 19343 }); 19344 DEFPRINT(AST_Object, function(self, output){ 19345 if (self.properties.length > 0) output.with_block(function(){ 19346 self.properties.forEach(function(prop, i){ 19347 if (i) { 19348 output.print(","); 19349 output.newline(); 19350 } 19351 output.indent(); 19352 prop.print(output); 19353 }); 19354 output.newline(); 19355 }); 19356 else output.print("{}"); 19357 }); 19358 19359 function print_property_name(key, quote, output) { 19360 if (output.option("quote_keys")) { 19361 output.print_string(key + ""); 19362 } else if ((typeof key == "number" 19363 || !output.option("beautify") 19364 && +key + "" == key) 19365 && parseFloat(key) >= 0) { 19366 output.print(make_num(key)); 19367 } else if (RESERVED_WORDS(key) ? output.option("screw_ie8") : is_identifier_string(key)) { 19368 if (quote && output.option("keep_quoted_props")) { 19369 output.print_string(key, quote); 19370 } else { 19371 output.print_name(key); 19372 } 19373 } else { 19374 output.print_string(key, quote); 19375 } 19376 } 19377 19378 DEFPRINT(AST_ObjectKeyVal, function(self, output){ 19379 print_property_name(self.key, self.quote, output); 19380 output.colon(); 19381 self.value.print(output); 19382 }); 19383 AST_ObjectProperty.DEFMETHOD("_print_getter_setter", function(type, output) { 19384 output.print(type); 19385 output.space(); 19386 print_property_name(this.key.name, this.quote, output); 19387 this.value._do_print(output, true); 19388 }); 19389 DEFPRINT(AST_ObjectSetter, function(self, output){ 19390 self._print_getter_setter("set", output); 19391 }); 19392 DEFPRINT(AST_ObjectGetter, function(self, output){ 19393 self._print_getter_setter("get", output); 19394 });
19395 DEFPRINT(AST_Symbol, function(self, output){ 19396 var def = self.definition(); 19397 output.print_name(def ? def.mangled_name || def.name : self.name); 19398 }); 19399 DEFPRINT(AST_Hole, noop); 19400 DEFPRINT(AST_This, function(self, output){ 19401 output.print("this"); 19402 }); 19403 DEFPRINT(AST_Constant, function(self, output){ 19404 output.print(self.getValue()); 19405 }); 19406 DEFPRINT(AST_String, function(self, output){ 19407 output.print_string(self.getValue(), self.quote, in_directive); 19408 }); 19409 DEFPRINT(AST_Number, function(self, output){ 19410 if (use_asm && self.start && self.start.raw != null) { 19411 output.print(self.start.raw); 19412 } else { 19413 output.print(make_num(self.getValue())); 19414 } 19415 }); 19416 19417 function regexp_safe_literal(code) { 19418 return [ 19419 0x5c , // \ 19420 0x2f , // / 19421 0x2e , // . 19422 0x2b , // + 19423 0x2a , // * 19424 0x3f , // ? 19425 0x28 , // ( 19426 0x29 , // ) 19427 0x5b , // [ 19428 0x5d , // ] 19429 0x7b , // { 19430 0x7d , // } 19431 0x24 , // $ 19432 0x5e , // ^ 19433 0x3a , // : 19434 0x7c , // | 19435 0x21 , // ! 19436 0x0a , // \n 19437 0x0d , // \r 19438 0x00 , // \0 19439 0xfeff , // Unicode BOM 19440 0x2028 , // unicode "line separator" 19441 0x2029 , // unicode "paragraph separator" 19442 ].indexOf(code) < 0; 19443 }; 19444 19445 DEFPRINT(AST_RegExp, function(self, output){ 19446 var str = self.getValue().toString(); 19447 if (output.option("ascii_only")) { 19448 str = output.to_ascii(str); 19449 } else if (output.option("unescape_regexps")) { 19450 str = str.split("\\\\").map(function(str){ 19451 return str.replace(/\\u[0-9a-fA-F]{4}|\\x[0-9a-fA-F]{2}/g, function(s){ 19452 var code = parseInt(s.substr(2), 16); 19453 return regexp_safe_literal(code) ? String.fromCharCode(code) : s; 19454 }); 19455 }).join("\\\\"); 19456 } 19457 output.print(str); 19458 var p = output.parent(); 19459 if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === self) 19460 output.print(" "); 19461 }); 19462 19463 function force_statement(stat, output) { 19464 if (output.option("bracketize")) { 19465 make_block(stat, output); 19466 } else { 19467 if (!stat || stat instanceof AST_EmptyStatement) 19468 output.force_semicolon(); 19469 else 19470 stat.print(output); 19471 } 19472 }; 19473 19474 // self should be AST_New. decide if we want to show parens or not. 19475 function need_constructor_parens(self, output) { 19476 // Always print parentheses with arguments 19477 if (self.args.length > 0) return true; 19478 19479 return output.option("beautify"); 19480 }; 19481 19482 function best_of(a) { 19483 var best = a[0], len = best.length; 19484 for (var i = 1; i < a.length; ++i) { 19485 if (a[i].length < len) { 19486 best = a[i]; 19487 len = best.length; 19488 } 19489 } 19490 return best; 19491 }; 19492 19493 function make_num(num) { 19494 var str = num.toString(10), a = [ str.replace(/^0\./, ".").replace('e+', 'e') ], m; 19495 if (Math.floor(num) === num) { 19496 if (num >= 0) { 19497 a.push("0x" + num.toString(16).toLowerCase(), // probably pointless 19498 "0" + num.toString(8)); // same. 19499 } else { 19500 a.push("-0x" + (-num).toString(16).toLowerCase(), // probably pointless 19501 "-0" + (-num).toString(8)); // same. 19502 } 19503 if ((m = /^(.*?)(0+)$/.exec(num))) { 19504 a.push(m[1] + "e" + m[2].length); 19505 } 19506 } else if ((m = /^0?\.(0+)(.*)$/.exec(num))) { 19507 a.push(m[2] + "e-" + (m[1].length + m[2].length), 19508 str.substr(str.indexOf("."))); 19509 } 19510 return best_of(a); 19511 }; 19512 19513 function make_block(stmt, output) { 19514 if (!stmt || stmt instanceof AST_EmptyStatement) 19515 output.print("{}"); 19516 else if (stmt instanceof AST_BlockStatement) 19517 stmt.print(output); 19518 else output.with_block(function(){ 19519 output.indent(); 19520 stmt.print(output); 19521 output.newline(); 19522 }); 19523 }; 19524 19525 /* -----[ source map generators ]----- */ 19526 19527 function DEFMAP(nodetype, generator) { 19528 nodetype.DEFMETHOD("add_source_map", function(stream){ 19529 generator(this, stream); 19530 }); 19531 }; 19532 19533 // We could easily add info for ALL nodes, but it seems to me that 19534 // would be quite wasteful, hence this noop in the base class. 19535 DEFMAP(AST_Node, noop); 19536 19537 function basic_sourcemap_gen(self, output) { 19538 output.add_mapping(self.start); 19539 }; 19540 19541 // XXX: I'm not exactly sure if we need it for all of these nodes, 19542 // or if we should add even more. 19543 19544 DEFMAP(AST_Directive, basic_sourcemap_gen); 19545 DEFMAP(AST_Debugger, basic_sourcemap_gen); 19546 DEFMAP(AST_Symbol, basic_sourcemap_gen); 19547 DEFMAP(AST_Jump, basic_sourcemap_gen); 19548 DEFMAP(AST_StatementWithBody, basic_sourcemap_gen); 19549 DEFMAP(AST_LabeledStatement, noop); // since the label symbol will mark it 19550 DEFMAP(AST_Lambda, basic_sourcemap_gen); 19551 DEFMAP(AST_Switch, basic_sourcemap_gen); 19552 DEFMAP(AST_SwitchBranch, basic_sourcemap_gen); 19553 DEFMAP(AST_BlockStatement, basic_sourcemap_gen); 19554 DEFMAP(AST_Toplevel, noop); 19555 DEFMAP(AST_New, basic_sourcemap_gen); 19556 DEFMAP(AST_Try, basic_sourcemap_gen); 19557 DEFMAP(AST_Catch, basic_sourcemap_gen); 19558 DEFMAP(AST_Finally, basic_sourcemap_gen); 19559 DEFMAP(AST_Definitions, basic_sourcemap_gen); 19560 DEFMAP(AST_Constant, basic_sourcemap_gen); 19561 DEFMAP(AST_ObjectSetter, function(self, output){ 19562 output.add_mapping(self.start, self.key.name); 19563 });
19564 DEFMAP(AST_ObjectGetter, function(self, output){ 19565 output.add_mapping(self.start, self.key.name); 19566 }); 19567 DEFMAP(AST_ObjectProperty, function(self, output){ 19568 output.add_mapping(self.start, self.key); 19569 }); 19570 19571})(); 19572 19573/*********************************************************************** 19574 19575 A JavaScript tokenizer / parser / beautifier / compressor. 19576 https://github.com/mishoo/UglifyJS2 19577 19578 -------------------------------- (C) --------------------------------- 19579 19580 Author: Mihai Bazon 19581 <[email protected]> 19582 http://mihai.bazon.net/blog 19583 19584 Distributed under the BSD license: 19585 19586 Copyright 2012 (c) Mihai Bazon <[email protected]> 19587 19588 Redistribution and use in source and binary forms, with or without 19589 modification, are permitted provided that the following conditions 19590 are met: 19591 19592 * Redistributions of source code must retain the above 19593 copyright notice, this list of conditions and the following 19594 disclaimer. 19595 19596 * Redistributions in binary form must reproduce the above 19597 copyright notice, this list of conditions and the following 19598 disclaimer in the documentation and/or other materials 19599 provided with the distribution. 19600 19601 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER âAS ISâ AND ANY 19602 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19603 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19604 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE 19605 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 19606 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19607 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 19608 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 19609 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 19610 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 19611 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 19612 SUCH DAMAGE. 19613 19614 ***********************************************************************/ 19615 19616"use strict"; 19617 19618function Compressor(options, false_by_default) { 19619 if (!(this instanceof Compressor)) 19620 return new Compressor(options, false_by_default); 19621 TreeTransformer.call(this, this.before, this.after); 19622 this.options = defaults(options, { 19623 angular : false, 19624 booleans : !false_by_default, 19625 cascade : !false_by_default, 19626 collapse_vars : !false_by_default, 19627 comparisons : !false_by_default, 19628 conditionals : !false_by_default, 19629 dead_code : !false_by_default, 19630 drop_console : false, 19631 drop_debugger : !false_by_default, 19632 evaluate : !false_by_default, 19633 expression : false, 19634 global_defs : {}, 19635 hoist_funs : !false_by_default, 19636 hoist_vars : false, 19637 if_return : !false_by_default, 19638 join_vars : !false_by_default, 19639 keep_fargs : true, 19640 keep_fnames : false, 19641 keep_infinity : false, 19642 loops : !false_by_default, 19643 negate_iife : !false_by_default, 19644 passes : 1, 19645 properties : !false_by_default, 19646 pure_getters : !false_by_default && "strict", 19647 pure_funcs : null, 19648 reduce_vars : !false_by_default, 19649 screw_ie8 : true, 19650 sequences : !false_by_default, 19651 side_effects : !false_by_default, 19652 switches : !false_by_default, 19653 top_retain : null, 19654 toplevel : !!(options && options["top_retain"]), 19655 unsafe : false, 19656 unsafe_comps : false, 19657 unsafe_math : false, 19658 unsafe_proto : false, 19659 unsafe_regexp : false, 19660 unused : !false_by_default, 19661 warnings : true, 19662 }, true); 19663 var pure_funcs = this.options["pure_funcs"]; 19664 if (typeof pure_funcs == "function") { 19665 this.pure_funcs = pure_funcs; 19666 } else { 19667 this.pure_funcs = pure_funcs ? function(node) { 19668 return pure_funcs.indexOf(node.expression.print_to_string()) < 0; 19669 } : return_true; 19670 } 19671 var top_retain = this.options["top_retain"]; 19672 if (top_retain instanceof RegExp) { 19673 this.top_retain = function(def) { 19674 return top_retain.test(def.name); 19675 }; 19676 } else if (typeof top_retain == "function") { 19677 this.top_retain = top_retain; 19678 } else if (top_retain) { 19679 if (typeof top_retain == "string") { 19680 top_retain = top_retain.split(/,/); 19681 } 19682 this.top_retain = function(def) { 19683 return top_retain.indexOf(def.name) >= 0; 19684 }; 19685 } 19686 var sequences = this.options["sequences"]; 19687 this.sequences_limit = sequences == 1 ? 200 : sequences | 0; 19688 this.warnings_produced = {}; 19689};
19690 19691Compressor.prototype = new TreeTransformer; 19692merge(Compressor.prototype, { 19693 option: function(key) { return this.options[key] }, 19694 compress: function(node) { 19695 if (this.option("expression")) { 19696 node = node.process_expression(true); 19697 } 19698 var passes = +this.options.passes || 1; 19699 for (var pass = 0; pass < passes && pass < 3; ++pass) { 19700 if (pass > 0 || this.option("reduce_vars")) 19701 node.reset_opt_flags(this, true); 19702 node = node.transform(this); 19703 } 19704 if (this.option("expression")) { 19705 node = node.process_expression(false); 19706 } 19707 return node; 19708 }, 19709 info: function() { 19710 if (this.options.warnings == "verbose") { 19711 AST_Node.warn.apply(AST_Node, arguments); 19712 } 19713 }, 19714 warn: function(text, props) { 19715 if (this.options.warnings) { 19716 // only emit unique warnings 19717 var message = string_template(text, props); 19718 if (!(message in this.warnings_produced)) { 19719 this.warnings_produced[message] = true; 19720 AST_Node.warn.apply(AST_Node, arguments); 19721 } 19722 } 19723 }, 19724 clear_warnings: function() { 19725 this.warnings_produced = {}; 19726 }, 19727 before: function(node, descend, in_list) { 19728 if (node._squeezed) return node; 19729 var was_scope = false; 19730 if (node instanceof AST_Scope) { 19731 node = node.hoist_declarations(this); 19732 was_scope = true; 19733 } 19734 // Before https://github.com/mishoo/UglifyJS2/pull/1602 AST_Node.optimize() 19735 // would call AST_Node.transform() if a different instance of AST_Node is 19736 // produced after OPT(). 19737 // This corrupts TreeWalker.stack, which cause AST look-ups to malfunction. 19738 // Migrate and defer all children's AST_Node.transform() to below, which 19739 // will now happen after this parent AST_Node has been properly substituted 19740 // thus gives a consistent AST snapshot. 19741 descend(node, this); 19742 // Existing code relies on how AST_Node.optimize() worked, and omitting the 19743 // following replacement call would result in degraded efficiency of both 19744 // output and performance. 19745 descend(node, this); 19746 var opt = node.optimize(this); 19747 if (was_scope && opt instanceof AST_Scope) { 19748 opt.drop_unused(this); 19749 descend(opt, this); 19750 } 19751 if (opt === node) opt._squeezed = true; 19752 return opt; 19753 } 19754}); 19755 19756(function(){ 19757 19758 function OPT(node, optimizer) { 19759 node.DEFMETHOD("optimize", function(compressor){ 19760 var self = this; 19761 if (self._optimized) return self; 19762 if (compressor.has_directive("use asm")) return self; 19763 var opt = optimizer(self, compressor); 19764 opt._optimized = true; 19765 return opt; 19766 }); 19767 }; 19768 19769 OPT(AST_Node, function(self, compressor){ 19770 return self; 19771 }); 19772 19773 AST_Node.DEFMETHOD("equivalent_to", function(node){ 19774 return this.TYPE == node.TYPE && this.print_to_string() == node.print_to_string(); 19775 }); 19776 19777 AST_Node.DEFMETHOD("process_expression", function(insert, compressor) { 19778 var self = this; 19779 var tt = new TreeTransformer(function(node) { 19780 if (insert && node instanceof AST_SimpleStatement) { 19781 return make_node(AST_Return, node, { 19782 value: node.body 19783 }); 19784 } 19785 if (!insert && node instanceof AST_Return) { 19786 if (compressor) { 19787 var value = node.value && node.value.drop_side_effect_free(compressor, true); 19788 return value ? make_node(AST_SimpleStatement, node, { 19789 body: value 19790 }) : make_node(AST_EmptyStatement, node); 19791 } 19792 return make_node(AST_SimpleStatement, node, { 19793 body: node.value || make_node(AST_UnaryPrefix, node, { 19794 operator: "void", 19795 expression: make_node(AST_Number, node, { 19796 value: 0 19797 }) 19798 }) 19799 }); 19800 } 19801 if (node instanceof AST_Lambda && node !== self) { 19802 return node; 19803 } 19804 if (node instanceof AST_Block) { 19805 var index = node.body.length - 1; 19806 if (index >= 0) { 19807 node.body[index] = node.body[index].transform(tt); 19808 } 19809 } 19810 if (node instanceof AST_If) { 19811 node.body = node.body.transform(tt); 19812 if (node.alternative) { 19813 node.alternative = node.alternative.transform(tt); 19814 } 19815 } 19816 if (node instanceof AST_With) { 19817 node.body = node.body.transform(tt); 19818 } 19819 return node; 19820 }); 19821 return self.transform(tt); 19822 });
19823 19824 AST_Node.DEFMETHOD("reset_opt_flags", function(compressor, rescan){ 19825 var reduce_vars = rescan && compressor.option("reduce_vars"); 19826 var toplevel = compressor.option("toplevel"); 19827 var safe_ids = Object.create(null); 19828 var suppressor = new TreeWalker(function(node) { 19829 if (node instanceof AST_Symbol) { 19830 var d = node.definition(); 19831 if (node instanceof AST_SymbolRef) d.references.push(node); 19832 d.fixed = false; 19833 } 19834 }); 19835 var tw = new TreeWalker(function(node, descend){ 19836 node._squeezed = false; 19837 node._optimized = false; 19838 if (reduce_vars) { 19839 if (node instanceof AST_Toplevel) node.globals.each(reset_def); 19840 if (node instanceof AST_Scope) node.variables.each(reset_def); 19841 if (node instanceof AST_SymbolRef) { 19842 var d = node.definition(); 19843 d.references.push(node); 19844 if (d.fixed === undefined || !is_safe(d) 19845 || is_modified(node, 0, node.fixed_value() instanceof AST_Lambda)) { 19846 d.fixed = false; 19847 } else { 19848 var parent = tw.parent(); 19849 if (parent instanceof AST_Assign && parent.operator == "=" && node === parent.right 19850 || parent instanceof AST_Call && node !== parent.expression 19851 || parent instanceof AST_Return && node === parent.value && node.scope !== d.scope 19852 || parent instanceof AST_VarDef && node === parent.value) { 19853 d.escaped = true; 19854 } 19855 } 19856 } 19857 if (node instanceof AST_SymbolCatch) { 19858 node.definition().fixed = false; 19859 } 19860 if (node instanceof AST_VarDef) { 19861 var d = node.name.definition(); 19862 if (d.fixed == null) { 19863 if (node.value) { 19864 d.fixed = function() { 19865 return node.value; 19866 }; 19867 mark(d, false); 19868 descend(); 19869 } else { 19870 d.fixed = null; 19871 } 19872 mark(d, true); 19873 return true; 19874 } else if (node.value) { 19875 d.fixed = false; 19876 } 19877 } 19878 if (node instanceof AST_Defun) { 19879 var d = node.name.definition(); 19880 if (!toplevel && d.global || is_safe(d)) { 19881 d.fixed = false; 19882 } else { 19883 d.fixed = node; 19884 mark(d, true); 19885 } 19886 var save_ids = safe_ids; 19887 safe_ids = Object.create(null); 19888 descend(); 19889 safe_ids = save_ids; 19890 return true; 19891 } 19892 if (node instanceof AST_Function) { 19893 push(); 19894 var iife; 19895 if (!node.name 19896 && (iife = tw.parent()) instanceof AST_Call 19897 && iife.expression === node) { 19898 // Virtually turn IIFE parameters into variable definitions: 19899 // (function(a,b) {...})(c,d) => (function() {var a=c,b=d; ...})() 19900 // So existing transformation rules can work on them. 19901 node.argnames.forEach(function(arg, i) { 19902 var d = arg.definition(); 19903 if (!node.uses_arguments && d.fixed === undefined) { 19904 d.fixed = function() { 19905 return iife.args[i] || make_node(AST_Undefined, iife); 19906 }; 19907 mark(d, true); 19908 } else { 19909 d.fixed = false; 19910 } 19911 }); 19912 } 19913 descend(); 19914 pop(); 19915 return true; 19916 }
19917 if (node instanceof AST_Accessor) { 19918 var save_ids = safe_ids; 19919 safe_ids = Object.create(null); 19920 descend(); 19921 safe_ids = save_ids; 19922 return true; 19923 } 19924 if (node instanceof AST_Binary 19925 && (node.operator == "&&" || node.operator == "||")) { 19926 node.left.walk(tw); 19927 push(); 19928 node.right.walk(tw); 19929 pop(); 19930 return true; 19931 } 19932 if (node instanceof AST_Conditional) { 19933 node.condition.walk(tw); 19934 push(); 19935 node.consequent.walk(tw); 19936 pop(); 19937 push(); 19938 node.alternative.walk(tw); 19939 pop(); 19940 return true; 19941 } 19942 if (node instanceof AST_If || node instanceof AST_DWLoop) { 19943 node.condition.walk(tw); 19944 push(); 19945 node.body.walk(tw); 19946 pop(); 19947 if (node.alternative) { 19948 push(); 19949 node.alternative.walk(tw); 19950 pop(); 19951 } 19952 return true; 19953 } 19954 if (node instanceof AST_LabeledStatement) { 19955 push(); 19956 node.body.walk(tw); 19957 pop(); 19958 return true; 19959 } 19960 if (node instanceof AST_For) { 19961 if (node.init) node.init.walk(tw); 19962 push(); 19963 if (node.condition) node.condition.walk(tw); 19964 node.body.walk(tw); 19965 if (node.step) node.step.walk(tw); 19966 pop(); 19967 return true; 19968 } 19969 if (node instanceof AST_ForIn) { 19970 node.init.walk(suppressor); 19971 node.object.walk(tw); 19972 push(); 19973 node.body.walk(tw); 19974 pop(); 19975 return true; 19976 } 19977 if (node instanceof AST_Try) { 19978 push(); 19979 walk_body(node, tw); 19980 pop(); 19981 if (node.bcatch) { 19982 push(); 19983 node.bcatch.walk(tw); 19984 pop(); 19985 } 19986 if (node.bfinally) node.bfinally.walk(tw); 19987 return true; 19988 } 19989 if (node instanceof AST_SwitchBranch) { 19990 push(); 19991 descend(); 19992 pop(); 19993 return true; 19994 } 19995 } 19996 }); 19997 this.walk(tw); 19998 19999 function mark(def, safe) { 20000 safe_ids[def.id] = safe; 20001 } 20002 20003 function is_safe(def) { 20004 if (safe_ids[def.id]) { 20005 if (def.fixed == null) { 20006 var orig = def.orig[0]; 20007 if (orig instanceof AST_SymbolFunarg || orig.name == "arguments") return false; 20008 def.fixed = make_node(AST_Undefined, orig); 20009 } 20010 return true; 20011 } 20012 } 20013 20014 function push() { 20015 safe_ids = Object.create(safe_ids); 20016 } 20017 20018 function pop() { 20019 safe_ids = Object.getPrototypeOf(safe_ids); 20020 } 20021 20022 function reset_def(def) { 20023 def.escaped = false; 20024 if (def.scope.uses_eval) { 20025 def.fixed = false; 20026 } else if (toplevel || !def.global || def.orig[0] instanceof AST_SymbolConst) { 20027 def.fixed = undefined; 20028 } else { 20029 def.fixed = false; 20030 } 20031 def.references = []; 20032 def.should_replace = undefined; 20033 } 20034 20035 function is_modified(node, level, func) { 20036 var parent = tw.parent(level); 20037 if (is_lhs(node, parent) 20038 || !func && parent instanceof AST_Call && parent.expression === no
20038de) { 20039 return true; 20040 } else if (parent instanceof AST_PropAccess && parent.expression === node) { 20041 return !func && is_modified(parent, level + 1); 20042 } 20043 } 20044 }); 20045 20046 AST_SymbolRef.DEFMETHOD("fixed_value", function() { 20047 var fixed = this.definition().fixed; 20048 if (!fixed || fixed instanceof AST_Node) return fixed; 20049 return fixed(); 20050 }); 20051 20052 function is_reference_const(ref) { 20053 if (!(ref instanceof AST_SymbolRef)) return false; 20054 var orig = ref.definition().orig; 20055 for (var i = orig.length; --i >= 0;) { 20056 if (orig[i] instanceof AST_SymbolConst) return true; 20057 } 20058 } 20059 20060 function find_variable(compressor, name) { 20061 var scope, i = 0; 20062 while (scope = compressor.parent(i++)) { 20063 if (scope instanceof AST_Scope) break; 20064 if (scope instanceof AST_Catch) { 20065 scope = scope.argname.definition().scope; 20066 break; 20067 } 20068 } 20069 return scope.find_variable(name); 20070 } 20071 20072 function make_node(ctor, orig, props) { 20073 if (!props) props = {}; 20074 if (orig) { 20075 if (!props.start) props.start = orig.start; 20076 if (!props.end) props.end = orig.end; 20077 } 20078 return new ctor(props); 20079 }; 20080 20081 function make_node_from_constant(val, orig) { 20082 switch (typeof val) { 20083 case "string": 20084 return make_node(AST_String, orig, { 20085 value: val 20086 }); 20087 case "number": 20088 if (isNaN(val)) return make_node(AST_NaN, orig); 20089 if (isFinite(val)) { 20090 return 1 / val < 0 ? make_node(AST_UnaryPrefix, orig, { 20091 operator: "-", 20092 expression: make_node(AST_Number, orig, { value: -val }) 20093 }) : make_node(AST_Number, orig, { value: val }); 20094 } 20095 return val < 0 ? make_node(AST_UnaryPrefix, orig, { 20096 operator: "-", 20097 expression: make_node(AST_Infinity, orig) 20098 }) : make_node(AST_Infinity, orig); 20099 case "boolean": 20100 return make_node(val ? AST_True : AST_False, orig); 20101 case "undefined": 20102 return make_node(AST_Undefined, orig); 20103 default: 20104 if (val === null) { 20105 return make_node(AST_Null, orig, { value: null }); 20106 } 20107 if (val instanceof RegExp) { 20108 return make_node(AST_RegExp, orig, { value: val }); 20109 } 20110 throw new Error(string_template("Can't handle constant of type: {type}", { 20111 type: typeof val 20112 })); 20113 } 20114 }; 20115 20116 // we shouldn't compress (1,func)(something) to 20117 // func(something) because that changes the meaning of 20118 // the func (becomes lexical instead of global). 20119 function maintain_this_binding(parent, orig, val) { 20120 if (parent instanceof AST_UnaryPrefix && parent.operator == "delete" 20121 || parent instanceof AST_Call && parent.expression === orig 20122 && (val instanceof AST_PropAccess || val instanceof AST_SymbolRef && val.name == "eval")) { 20123 return make_node(AST_Seq, orig, { 20124 car: make_node(AST_Number, orig, { 20125 value: 0 20126 }), 20127 cdr: val 20128 }); 20129 } 20130 return val; 20131 } 20132 20133 function as_statement_array(thing) { 20134 if (thing === null) return []; 20135 if (thing instanceof AST_BlockStatement) return thing.body; 20136 if (thing instanceof AST_EmptyStatement) return []; 20137 if (thing instanceof AST_Statement) return [ thing ]; 20138 throw new Error("Can't convert thing to statement array"); 20139 }; 20140 20141 function is_empty(thing) { 20142 if (thing === null) return true; 20143 if (thing instanceof AST_EmptyStatement) return true; 20144 if (thing instanceof AST_BlockStatement) return thing.body.length == 0; 20145 return false; 20146 }; 20147 20148 function loop_body(x) { 20149 if (x instanceof AST_Switch) return x; 20150 if (x instanceof AST_For || x instanceof AST_ForIn || x instanceof AST_DWLoop) { 20151 return (x.body instanceof AST_BlockStatement ? x.body : x); 20152 } 20153 return x; 20154 }; 20155 20156 function is_iife_call(node) { 20157 if (node instanceof AST_Call && !(node instanceof AST_New)) { 20158 return node.expression instanceof AST_Function || is_iife_call(node.expression); 20159 } 20160 return false; 20161 } 20162 20163 function tighten_body(statements, compressor) {
20164 var CHANGED, max_iter = 10; 20165 do { 20166 CHANGED = false; 20167 if (compressor.option("angular")) { 20168 statements = process_for_angular(statements); 20169 } 20170 statements = eliminate_spurious_blocks(statements); 20171 if (compressor.option("dead_code")) { 20172 statements = eliminate_dead_code(statements, compressor); 20173 } 20174 if (compressor.option("if_return")) { 20175 statements = handle_if_return(statements, compressor); 20176 } 20177 if (compressor.sequences_limit > 0) { 20178 statements = sequencesize(statements, compressor); 20179 } 20180 if (compressor.option("join_vars")) { 20181 statements = join_consecutive_vars(statements, compressor); 20182 } 20183 if (compressor.option("collapse_vars")) { 20184 statements = collapse_single_use_vars(statements, compressor); 20185 } 20186 } while (CHANGED && max_iter-- > 0); 20187 20188 return statements; 20189 20190 function collapse_single_use_vars(statements, compressor) { 20191 // Iterate statements backwards looking for a statement with a var/const 20192 // declaration immediately preceding it. Grab the rightmost var definition 20193 // and if it has exactly one reference then attempt to replace its reference 20194 // in the statement with the var value and then erase the var definition. 20195 20196 var self = compressor.self(); 20197 var var_defs_removed = false; 20198 var toplevel = compressor.option("toplevel"); 20199 for (var stat_index = statements.length; --stat_index >= 0;) { 20200 var stat = statements[stat_index]; 20201 if (stat instanceof AST_Definitions) continue; 20202 20203 // Process child blocks of statement if present. 20204 [stat, stat.body, stat.alternative, stat.bcatch, stat.bfinally].forEach(function(node) { 20205 node && node.body && collapse_single_use_vars(node.body, compressor); 20206 }); 20207 20208 // The variable definition must precede a statement. 20209 if (stat_index <= 0) break; 20210 var prev_stat_index = stat_index - 1; 20211 var prev_stat = statements[prev_stat_index]; 20212 if (!(prev_stat instanceof AST_Definitions)) continue; 20213 var var_defs = prev_stat.definitions; 20214 if (var_defs == null) continue; 20215 20216 var var_names_seen = {}; 20217 var side_effects_encountered = false; 20218 var lvalues_encountered = false; 20219 var lvalues = {}; 20220 20221 // Scan variable definitions from right to left. 20222 for (var var_defs_index = var_defs.length; --var_defs_index >= 0;) { 20223 20224 // Obtain var declaration and var name with basic sanity check. 20225 var var_decl = var_defs[var_defs_index]; 20226 if (var_decl.value == null) break; 20227 var var_name = var_decl.name.name; 20228 if (!var_name || !var_name.length) break; 20229 20230 // Bail if we've seen a var definition of same name before. 20231 if (var_name in var_names_seen) break; 20232 var_names_seen[var_name] = true; 20233 20234 // Only interested in cases with just one reference to the variable. 20235 var def = self.find_variable && self.find_variable(var_name); 20236 if (!def || !def.references || def.references.length !== 1 20237 || var_name == "arguments" || (!toplevel && def.global)) { 20238 side_effects_encountered = true; 20239 continue; 20240 } 20241 var ref = def.references[0]; 20242 20243 // Don't replace ref if eval() or with statement in scope. 20244 if (ref.scope.uses_eval || ref.scope.uses_with) break; 20245 20246 // Constant single use vars can be replaced in any scope. 20247 if (var_decl.value.is_constant()) { 20248 var ctt = new TreeTransformer(function(node) { 20249 var parent = ctt.parent(); 20250 if (parent instanceof AST_IterationStatement
20251 && (parent.condition === node || parent.init === node)) { 20252 return node; 20253 } 20254 if (node === ref) 20255 return replace_var(node, parent, true); 20256 }); 20257 stat.transform(ctt); 20258 continue; 20259 } 20260 20261 // Restrict var replacement to constants if side effects encountered. 20262 if (side_effects_encountered |= lvalues_encountered) continue; 20263 20264 var value_has_side_effects = var_decl.value.has_side_effects(compressor); 20265 // Non-constant single use vars can only be replaced in same scope. 20266 if (ref.scope !== self) { 20267 side_effects_encountered |= value_has_side_effects; 20268 continue; 20269 } 20270 20271 // Detect lvalues in var value. 20272 var tw = new TreeWalker(function(node){ 20273 if (node instanceof AST_SymbolRef && is_lvalue(node, tw.parent())) { 20274 lvalues[node.name] = lvalues_encountered = true; 20275 } 20276 }); 20277 var_decl.value.walk(tw); 20278 20279 // Replace the non-constant single use var in statement if side effect free. 20280 var unwind = false; 20281 var tt = new TreeTransformer( 20282 function preorder(node) { 20283 if (unwind) return node; 20284 var parent = tt.parent(); 20285 if (node instanceof AST_Lambda 20286 || node instanceof AST_Try 20287 || node instanceof AST_With 20288 || node instanceof AST_Case 20289 || node instanceof AST_IterationStatement 20290 || (parent instanceof AST_If && node !== parent.condition) 20291 || (parent instanceof AST_Conditional && node !== parent.condition) 20292 || (node instanceof AST_SymbolRef 20293 && value_has_side_effects 20294 && !are_references_in_scope(node.definition(), self)) 20295 || (parent instanceof AST_Binary 20296 && (parent.operator == "&&" || parent.operator == "||") 20297 && node === parent.right) 20298 || (parent instanceof AST_Switch && node !== parent.expression)) { 20299 return side_effects_encountered = unwind = true, node; 20300 } 20301 function are_references_in_scope(def, scope) { 20302 if (def.orig.length === 1 20303 && def.orig[0] instanceof AST_SymbolDefun) return true; 20304 if (def.scope !== scope) return false; 20305 var refs = def.references; 20306 for (var i = 0, len = refs.length; i < len; i++) { 20307 if (refs[i].scope !== scope) return false; 20308 } 20309 return true; 20310 } 20311 }, 20312 function postorder(node) { 20313 if (unwind) return node; 20314 if (node === ref) 20315 return unwind = true, replace_var(node, tt.parent(), false); 20316 if (side_effects_encountered |= node.has_side_effects(compressor)) 20317 return unwind = true, node; 20318 if (lvalues_encountered && node instanceof AST_SymbolRef && node.name in lvalues) { 20319 side_effects_encountered = true; 20320 return unwind = true, node; 20321 } 20322 } 20323 ); 20324 stat.transform(tt); 20325 } 20326 } 20327 20328 // Remove extraneous empty statments in block after remov
20328ing var definitions. 20329 // Leave at least one statement in `statements`. 20330 if (var_defs_removed) for (var i = statements.length; --i >= 0;) { 20331 if (statements.length > 1 && statements[i] instanceof AST_EmptyStatement) 20332 statements.splice(i, 1); 20333 } 20334 20335 return statements; 20336 20337 function is_lvalue(node, parent) { 20338 return node instanceof AST_SymbolRef && is_lhs(node, parent); 20339 } 20340 function replace_var(node, parent, is_constant) { 20341 if (is_lvalue(node, parent)) return node; 20342 20343 // Remove var definition and return its value to the TreeTransformer to replace. 20344 var value = maintain_this_binding(parent, node, var_decl.value); 20345 var_decl.value = null; 20346 20347 var_defs.splice(var_defs_index, 1); 20348 if (var_defs.length === 0) { 20349 statements[prev_stat_index] = make_node(AST_EmptyStatement, self); 20350 var_defs_removed = true; 20351 } 20352 // Further optimize statement after substitution. 20353 stat.reset_opt_flags(compressor); 20354 20355 compressor.info("Collapsing " + (is_constant ? "constant" : "variable") + 20356 " " + var_name + " [{file}:{line},{col}]", node.start); 20357 CHANGED = true; 20358 return value; 20359 } 20360 } 20361 20362 function process_for_angular(statements) { 20363 function has_inject(comment) { 20364 return /@ngInject/.test(comment.value); 20365 } 20366 function make_arguments_names_list(func) { 20367 return func.argnames.map(function(sym){ 20368 return make_node(AST_String, sym, { value: sym.name }); 20369 }); 20370 } 20371 function make_array(orig, elements) { 20372 return make_node(AST_Array, orig, { elements: elements }); 20373 } 20374 function make_injector(func, name) { 20375 return make_node(AST_SimpleStatement, func, { 20376 body: make_node(AST_Assign, func, { 20377 operator: "=", 20378 left: make_node(AST_Dot, name, { 20379 expression: make_node(AST_SymbolRef, name, name), 20380 property: "$inject" 20381 }), 20382 right: make_array(func, make_arguments_names_list(func)) 20383 }) 20384 }); 20385 } 20386 function check_expression(body) { 20387 if (body && body.args) { 20388 // if this is a function call check all of arguments passed 20389 body.args.forEach(function(argument, index, array) { 20390 var comments = argument.start.comments_before; 20391 // if the argument is function preceded by @ngInject 20392 if (argument instanceof AST_Lambda && comments.length && has_inject(comments[0])) { 20393 // replace the function with an array of names of its parameters and function at the end 20394 array[index] = make_array(argument, make_arguments_names_list(argument).concat(argument)); 20395 } 20396 }); 20397 // if this is chained call check previous one recursively 20398 if (body.expression && body.expression.expression) { 20399 check_expression(body.expression.expression); 20400 } 20401 } 20402 } 20403 return statements.reduce(function(a, stat){ 20404 a.push(stat); 20405 20406 if (stat.body && stat.body.args) { 20407 check_expression(stat.body); 20408 } else { 20409 var token = stat.start; 20410 var comments = token.comments_before; 20411 if (comments && comments.length > 0) { 20412 var last = comments.pop(); 20413 if (has_inject(last)) { 20414 // case 1: defun 20415 if (stat instanceof AST_Defun) { 20416 a.push(make_injector(stat, stat.name)); 20417 } 20418 else if (stat instanceof AST_Definitions) { 20419 stat.definitions.forEach(function(def) { 20420 if (def.value && def.value instanceof AST_Lambda) { 20421 a.push(make_injector(def.value, def.name)); 20422 } 20423 }); 20424 } 20425 else { 20426 compressor.warn("Unknown statement marked with @ngInject [{file}:{line},{col}]", token); 20427 } 20428 } 20429 } 20430 } 20431 20432 return a; 20433 }, []); 20434 } 20435 20436 function eliminate_spurious_blocks(statements) { 20437 var seen_dirs = []; 20438 return statements.reduce(function(a, stat){ 20439 if (stat instanceof AST_BlockStatement) { 20440 CHANGED = true; 20441 a.push.apply(a, eliminate_spurious_blocks(stat.body)); 20442 } else if (stat instanceof AST_EmptyStatement) { 20443 CHANGED = true; 20444 } else if (stat instanceof AST_Directive) { 20445 if (seen_dirs.indexOf(stat.value) < 0) { 20446 a.push(stat); 20447 seen_dirs.push(stat.value); 20448 } else { 20449 CHANGED = true; 20450 } 20451 } else { 20452 a.push(stat); 20453 } 20454 return a; 20455 }, []); 20456 }; 20457 20458 function handle_if_return(statements, compressor) { 20459 var self = compressor.self(); 20460 var multiple_if_returns = has_multiple_if_returns(statements); 20461 var in_lambda = self instanceof AST_Lambda; 20462 var ret = []; // Optimized statements, build from tail to front 20463 loop: for (var i = statements.length; --i >= 0;) { 20464 var stat = statements[i]; 20465 switch (true) { 20466 case (in_lambda && stat instanceof AST_Return && !stat.value && ret.length == 0): 20467 CHANGED = true; 20468 // note, ret.length is probably always zero 20469 // because we drop unreachable code before this 20470 // step. nevertheless, it's good to check. 20471 continue loop; 20472 case stat instanceof AST_If: 20473 if (stat.body instanceof AST_Return) { 20474 //--- 20475 // pretty silly case, but: 20476 // if (foo()) return; return; ==> foo(); return; 20477 if (((in_lambda && ret.length == 0) 20478 || (ret[0] instanceof AST_Return && !ret[0].value)) 20479 && !stat.body.value && !stat.alternative) { 20480 CHANGED = true; 20481 var cond = make_node(AST_SimpleStatement, stat.condition, { 20482 body: stat.condition 20483 }); 20484 ret.unshift(cond); 20485 continue loop; 20486 } 20487 //--- 20488 // if (foo()) return x; return y; ==> return foo() ? x : y; 20489 if (ret[0] instanceof AST_Return && stat.body.value && ret[0].value && !stat.alternative) { 20490 CHANGED = true; 20491 stat = stat.clone(); 20492 stat.alternative = ret[0]; 20493 ret[0] = stat.transform(compressor); 20494 continue loop; 20495 } 20496 //--- 20497 // if (foo()) return x; [ return ; ] ==> return foo() ? x : undefined; 20498 if (multiple_if_returns && (ret.length == 0 || ret[0] instanceof AST_Return) 20499 && stat.body.value && !stat.alternative && in_lambda) { 20500 CHANGED = true; 20501 stat = stat.clone(); 20502 stat.alternative = ret[0] || make_node(AST_Return, stat, { 20503 value: null 20504 }); 20505 ret[0] = stat.transform(compressor); 20506 continue loop; 20507 } 20508 //--- 20509 // if (foo()) return; [ else x... ]; y... ==> if (!foo()) { x...; y... } 20510 if (!stat.body.value && in_lambda) { 20511 CHANGED = true; 20512 stat = stat.clone(); 20513 stat.condition = stat.condition.negate(compressor); 20514 var body = as_statement_array(stat.alternative).concat(ret); 20515 var funs = extract_functions_from_statement_array(body); 20516 stat.body = make_node(AST_BlockStatement, stat, { 20517 body: body 20518 }); 20519 stat.alternative = null; 20520 ret = funs.concat([ stat.transform(compressor) ]); 20521 continue loop; 20522 } 20523 20524 //--- 20525 // if (a) return b; if (c) return d; e; ==> return a ? b : c ? d : void e; 20526 // 20527 // if sequences is not enabled, this can lead to an endless loop (issue #866). 20528 // however, with sequences on this helps producing slightly better output for 20529 // the example code. 20530 if (compressor.option("sequences") 20531 && i > 0 && statements[i - 1] instanceof AST_If && statements[i - 1].body instanceof AST_Return 20532 && ret.length == 1 && in_lambda && ret[0] instanceof AST_SimpleStatement 20533 && !stat.alternative) { 20534 CHANGED = true;
20535 ret.push(make_node(AST_Return, ret[0], { 20536 value: null 20537 }).transform(compressor)); 20538 ret.unshift(stat); 20539 continue loop; 20540 } 20541 } 20542 20543 var ab = aborts(stat.body); 20544 var lct = ab instanceof AST_LoopControl ? compressor.loopcontrol_target(ab) : null; 20545 if (ab && ((ab instanceof AST_Return && !ab.value && in_lambda) 20546 || (ab instanceof AST_Continue && self === loop_body(lct)) 20547 || (ab instanceof AST_Break && lct instanceof AST_BlockStatement && self === lct))) { 20548 if (ab.label) { 20549 remove(ab.label.thedef.references, ab); 20550 } 20551 CHANGED = true; 20552 var body = as_statement_array(stat.body).slice(0, -1); 20553 stat = stat.clone(); 20554 stat.condition = stat.condition.negate(compressor); 20555 stat.body = make_node(AST_BlockStatement, stat, { 20556 body: as_statement_array(stat.alternative).concat(ret) 20557 }); 20558 stat.alternative = make_node(AST_BlockStatement, stat, { 20559 body: body 20560 }); 20561 ret = [ stat.transform(compressor) ]; 20562 continue loop; 20563 } 20564 20565 var ab = aborts(stat.alternative); 20566 var lct = ab instanceof AST_LoopControl ? compressor.loopcontrol_target(ab) : null; 20567 if (ab && ((ab instanceof AST_Return && !ab.value && in_lambda) 20568 || (ab instanceof AST_Continue && self === loop_body(lct)) 20569 || (ab instanceof AST_Break && lct instanceof AST_BlockStatement && self === lct))) { 20570 if (ab.label) { 20571 remove(ab.label.thedef.references, ab); 20572 } 20573 CHANGED = true; 20574 stat = stat.clone(); 20575 stat.body = make_node(AST_BlockStatement, stat.body, { 20576 body: as_statement_array(stat.body).concat(ret) 20577 }); 20578 stat.alternative = make_node(AST_BlockStatement, stat.alternative, { 20579 body: as_statement_array(stat.alternative).slice(0, -1) 20580 }); 20581 ret = [ stat.transform(compressor) ]; 20582 continue loop; 20583 } 20584 20585 ret.unshift(stat); 20586 break; 20587 default: 20588 ret.unshift(stat); 20589 break; 20590 } 20591 } 20592 return ret; 20593 20594 function has_multiple_if_returns(statements) { 20595 var n = 0; 20596 for (var i = statements.length; --i >= 0;) { 20597 var stat = statements[i]; 20598 if (stat instanceof AST_If && stat.body instanceof AST_Return) { 20599 if (++n > 1) return true; 20600 } 20601 } 20602 return false; 20603 } 20604 }; 20605 20606 function eliminate_dead_code(statements, compressor) { 20607 var has_quit = false; 20608 var orig = statements.length; 20609 var self = compressor.self(); 20610 statements = statements.reduce(function(a, stat){ 20611 if (has_quit) { 20612 extract_declarations_from_unreachable_code(compressor, stat, a); 20613 } else { 20614 if (stat instanceof AST_LoopControl) { 20615 var lct = compressor.loopcontrol_target(stat); 20616 if ((stat instanceof AST_Break 20617 && !(lct instanceof AST_IterationStatement) 20618 && loop_body(lct) === self) || (stat instanceof AST_Continue 20619 && loop_body(lct) === self)) { 20620 if (stat.label) { 20621 remove(stat.label.thedef.references, stat); 20622 } 20623 } else { 20624 a.push(stat); 20625 } 20626 } else { 20627 a.push(stat); 20628 } 20629 if (aborts(stat)) has_quit = true; 20630 } 20631 return a; 20632 }, []); 20633 CHANGED = statements.length != orig; 20634 return statements; 20635 }; 20636 20637 function sequencesize(statements, compressor) { 20638 if (statements.length < 2) return statements; 20639 var seq = [], ret = []; 20640 function push_seq() { 20641 seq = AST_Seq.from_array(seq); 20642 if (seq) ret.push(make_node(AST_SimpleStatement, seq, { 20643 body: seq 20644 })); 20645 seq = []; 20646 };
20647 statements.forEach(function(stat){ 20648 if (stat instanceof AST_SimpleStatement) { 20649 if (seqLength(seq) >= compressor.sequences_limit) push_seq(); 20650 var body = stat.body; 20651 if (seq.length > 0) body = body.drop_side_effect_free(compressor); 20652 if (body) seq.push(body); 20653 } else { 20654 push_seq(); 20655 ret.push(stat); 20656 } 20657 }); 20658 push_seq(); 20659 ret = sequencesize_2(ret, compressor); 20660 CHANGED = ret.length != statements.length; 20661 return ret; 20662 }; 20663 20664 function seqLength(a) { 20665 for (var len = 0, i = 0; i < a.length; ++i) { 20666 var stat = a[i]; 20667 if (stat instanceof AST_Seq) { 20668 len += stat.len(); 20669 } else { 20670 len++; 20671 } 20672 } 20673 return len; 20674 }; 20675 20676 function sequencesize_2(statements, compressor) { 20677 function cons_seq(right) { 20678 ret.pop(); 20679 var left = prev.body; 20680 if (left instanceof AST_Seq) { 20681 left.add(right); 20682 } else { 20683 left = AST_Seq.cons(left, right); 20684 } 20685 return left.transform(compressor); 20686 }; 20687 var ret = [], prev = null; 20688 statements.forEach(function(stat){ 20689 if (prev) { 20690 if (stat instanceof AST_For) { 20691 var opera = {}; 20692 try { 20693 prev.body.walk(new TreeWalker(function(node){ 20694 if (node instanceof AST_Binary && node.operator == "in") 20695 throw opera; 20696 })); 20697 if (stat.init && !(stat.init instanceof AST_Definitions)) { 20698 stat.init = cons_seq(stat.init); 20699 } 20700 else if (!stat.init) { 20701 stat.init = prev.body.drop_side_effect_free(compressor); 20702 ret.pop(); 20703 } 20704 } catch(ex) { 20705 if (ex !== opera) throw ex; 20706 } 20707 } 20708 else if (stat instanceof AST_If) { 20709 stat.condition = cons_seq(stat.condition); 20710 } 20711 else if (stat instanceof AST_With) { 20712 stat.expression = cons_seq(stat.expression); 20713 } 20714 else if (stat instanceof AST_Exit && stat.value) { 20715 stat.value = cons_seq(stat.value); 20716 } 20717 else if (stat instanceof AST_Exit) { 20718 stat.value = cons_seq(make_node(AST_Undefined, stat).transform(compressor)); 20719 } 20720 else if (stat instanceof AST_Switch) { 20721 stat.expression = cons_seq(stat.expression); 20722 } 20723 } 20724 ret.push(stat); 20725 prev = stat instanceof AST_SimpleStatement ? stat : null; 20726 }); 20727 return ret; 20728 }; 20729 20730 function join_consecutive_vars(statements, compressor) { 20731 var prev = null; 20732 return statements.reduce(function(a, stat){ 20733 if (stat instanceof AST_Definitions && prev && prev.TYPE == stat.TYPE) { 20734 prev.definitions = prev.definitions.concat(stat.definitions); 20735 CHANGED = true; 20736 } 20737 else if (stat instanceof AST_For 20738 && prev instanceof AST_Var 20739 && (!stat.init || stat.init.TYPE == prev.TYPE)) { 20740 CHANGED = true; 20741 a.pop(); 20742 if (stat.init) { 20743 stat.init.definitions = prev.definitions.concat(stat.init.definitions); 20744 } else { 20745 stat.init = prev; 20746 } 20747 a.push(stat); 20748 prev = stat; 20749 } 20750 else { 20751 prev = stat; 20752 a.push(stat); 20753 } 20754 return a; 20755 }, []); 20756 }; 20757 20758 }; 20759 20760 function extract_functions_from_statement_array(statements) { 20761 var funs = []; 20762 for (var i = statements.length - 1; i >= 0; --i) { 20763 var stat = statements[i]; 20764 if (stat instanceof AST_Defun) { 20765 statements.splice(i, 1); 20766 funs.unshift(stat); 20767 } 20768 } 20769 return funs; 20770 } 20771 20772 function extract_declarations_from_unreachable_code(compressor, stat, target) { 20773 if (!(stat instanceof AST_Defun)) { 20774 compressor.warn("Dropping unreachable code [{file}:{line},{col}]", stat.start); 20775 } 20776 stat.walk(new TreeWalker(function(node){ 20777 if (node instanceof AST_Definitions) { 20778 compressor.warn("Declarations in unreachable code! [{file}:{line},{col}]", node.start);
20779 node.remove_initializers(); 20780 target.push(node); 20781 return true; 20782 } 20783 if (node instanceof AST_Defun) { 20784 target.push(node); 20785 return true; 20786 } 20787 if (node instanceof AST_Scope) { 20788 return true; 20789 } 20790 })); 20791 }; 20792 20793 function is_undefined(node, compressor) { 20794 return node.is_undefined 20795 || node instanceof AST_Undefined 20796 || node instanceof AST_UnaryPrefix 20797 && node.operator == "void" 20798 && !node.expression.has_side_effects(compressor); 20799 } 20800 20801 // may_throw_on_access() 20802 // returns true if this node may be null, undefined or contain `AST_Accessor` 20803 (function(def) { 20804 AST_Node.DEFMETHOD("may_throw_on_access", function(compressor) { 20805 var pure_getters = compressor.option("pure_getters"); 20806 return !pure_getters || this._throw_on_access(pure_getters); 20807 }); 20808 20809 function is_strict(pure_getters) { 20810 return /strict/.test(pure_getters); 20811 } 20812 20813 def(AST_Node, is_strict); 20814 def(AST_Null, return_true); 20815 def(AST_Undefined, return_true); 20816 def(AST_Constant, return_false); 20817 def(AST_Array, return_false); 20818 def(AST_Object, function(pure_getters) { 20819 if (!is_strict(pure_getters)) return false; 20820 for (var i = this.properties.length; --i >=0;) 20821 if (this.properties[i].value instanceof AST_Accessor) return true; 20822 return false; 20823 }); 20824 def(AST_Function, return_false); 20825 def(AST_UnaryPostfix, return_false); 20826 def(AST_UnaryPrefix, function() { 20827 return this.operator == "void"; 20828 }); 20829 def(AST_Binary, function(pure_getters) { 20830 switch (this.operator) { 20831 case "&&": 20832 return this.left._throw_on_access(pure_getters); 20833 case "||": 20834 return this.left._throw_on_access(pure_getters) 20835 && this.right._throw_on_access(pure_getters); 20836 default: 20837 return false; 20838 } 20839 }) 20840 def(AST_Assign, function(pure_getters) { 20841 return this.operator == "=" 20842 && this.right._throw_on_access(pure_getters); 20843 }) 20844 def(AST_Conditional, function(pure_getters) { 20845 return this.consequent._throw_on_access(pure_getters) 20846 || this.alternative._throw_on_access(pure_getters); 20847 }) 20848 def(AST_Seq, function(pure_getters) { 20849 return this.cdr._throw_on_access(pure_getters); 20850 }); 20851 def(AST_SymbolRef, function(pure_getters) { 20852 if (this.is_undefined) return true; 20853 if (!is_strict(pure_getters)) return false; 20854 var fixed = this.fixed_value(); 20855 return !fixed || fixed._throw_on_access(pure_getters); 20856 }); 20857 })(function(node, func) { 20858 node.DEFMETHOD("_throw_on_access", func); 20859 }); 20860 20861 /* -----[ boolean/negation helpers ]----- */ 20862 20863 // methods to determine whether an expression has a boolean result type 20864 (function (def){
20865 var unary_bool = [ "!", "delete" ]; 20866 var binary_bool = [ "in", "instanceof", "==", "!=", "===", "!==", "<", "<=", ">=", ">" ]; 20867 def(AST_Node, return_false); 20868 def(AST_UnaryPrefix, function(){ 20869 return member(this.operator, unary_bool); 20870 }); 20871 def(AST_Binary, function(){ 20872 return member(this.operator, binary_bool) || 20873 ( (this.operator == "&&" || this.operator == "||") && 20874 this.left.is_boolean() && this.right.is_boolean() ); 20875 }); 20876 def(AST_Conditional, function(){ 20877 return this.consequent.is_boolean() && this.alternative.is_boolean(); 20878 }); 20879 def(AST_Assign, function(){ 20880 return this.operator == "=" && this.right.is_boolean(); 20881 }); 20882 def(AST_Seq, function(){ 20883 return this.cdr.is_boolean(); 20884 }); 20885 def(AST_True, return_true); 20886 def(AST_False, return_true); 20887 })(function(node, func){ 20888 node.DEFMETHOD("is_boolean", func); 20889 }); 20890 20891 // methods to determine if an expression has a numeric result type 20892 (function (def){
20893 def(AST_Node, return_false); 20894 def(AST_Number, return_true); 20895 var unary = makePredicate("+ - ~ ++ --"); 20896 def(AST_Unary, function(){ 20897 return unary(this.operator); 20898 }); 20899 var binary = makePredicate("- * / % & | ^ << >> >>>"); 20900 def(AST_Binary, function(compressor){ 20901 return binary(this.operator) || this.operator == "+" 20902 && this.left.is_number(compressor) 20903 && this.right.is_number(compressor); 20904 }); 20905 def(AST_Assign, function(compressor){ 20906 return binary(this.operator.slice(0, -1)) 20907 || this.operator == "=" && this.right.is_number(compressor); 20908 }); 20909 def(AST_Seq, function(compressor){ 20910 return this.cdr.is_number(compressor); 20911 }); 20912 def(AST_Conditional, function(compressor){ 20913 return this.consequent.is_number(compressor) && this.alternative.is_number(compressor); 20914 }); 20915 })(function(node, func){ 20916 node.DEFMETHOD("is_number", func); 20917 }); 20918 20919 // methods to determine if an expression has a string result type 20920 (function (def){
vendor: 1,214 bytes, lines 20921-20950
20921 def(AST_Node, return_false); 20922 def(AST_String, return_true); 20923 def(AST_UnaryPrefix, function(){ 20924 return this.operator == "typeof"; 20925 }); 20926 def(AST_Binary, function(compressor){ 20927 return this.operator == "+" && 20928 (this.left.is_string(compressor) || this.right.is_string(compressor)); 20929 }); 20930 def(AST_Assign, function(compressor){ 20931 return (this.operator == "=" || this.operator == "+=") && this.right.is_string(compressor); 20932 }); 20933 def(AST_Seq, function(compressor){ 20934 return this.cdr.is_string(compressor); 20935 }); 20936 def(AST_Conditional, function(compressor){ 20937 return this.consequent.is_string(compressor) && this.alternative.is_string(compressor); 20938 }); 20939 })(function(node, func){ 20940 node.DEFMETHOD("is_string", func); 20941 }); 20942 20943 var unary_side_effects = makePredicate("delete ++ --"); 20944 20945 function is_lhs(node, parent) { 20946 if (parent instanceof AST_Unary && unary_side_effects(parent.operator)) return parent.expression; 20947 if (parent instanceof AST_Assign && parent.left === node) return node; 20948 } 20949 20950 (function (def){
20951 AST_Node.DEFMETHOD("resolve_defines", function(compressor) { 20952 if (!compressor.option("global_defs")) return; 20953 var def = this._find_defs(compressor, ""); 20954 if (def) { 20955 var node, parent = this, level = 0; 20956 do { 20957 node = parent; 20958 parent = compressor.parent(level++); 20959 } while (parent instanceof AST_PropAccess && parent.expression === node); 20960 if (is_lhs(node, parent)) { 20961 compressor.warn('global_defs ' + this.print_to_string() + ' redefined [{file}:{line},{col}]', this.start); 20962 } else { 20963 return def; 20964 } 20965 } 20966 }); 20967 function to_node(value, orig) { 20968 if (value instanceof AST_Node) return make_node(value.CTOR, orig, value); 20969 if (Array.isArray(value)) return make_node(AST_Array, orig, { 20970 elements: value.map(function(value) { 20971 return to_node(value, orig); 20972 }) 20973 }); 20974 if (value && typeof value == "object") { 20975 var props = []; 20976 for (var key in value) { 20977 props.push(make_node(AST_ObjectKeyVal, orig, { 20978 key: key, 20979 value: to_node(value[key], orig) 20980 })); 20981 } 20982 return make_node(AST_Object, orig, { 20983 properties: props 20984 }); 20985 } 20986 return make_node_from_constant(value, orig); 20987 } 20988 def(AST_Node, noop); 20989 def(AST_Dot, function(compressor, suffix){ 20990 return this.expression._find_defs(compressor, "." + this.property + suffix); 20991 }); 20992 def(AST_SymbolRef, function(compressor, suffix){ 20993 if (!this.global()) return; 20994 var name; 20995 var defines = compressor.option("global_defs"); 20996 if (defines && HOP(defines, (name = this.name + suffix))) { 20997 var node = to_node(defines[name], this); 20998 var top = compressor.find_parent(AST_Toplevel); 20999 node.walk(new TreeWalker(function(node) { 21000 if (node instanceof AST_SymbolRef) { 21001 node.scope = top; 21002 node.thedef = top.def_global(node); 21003 } 21004 })); 21005 return node; 21006 } 21007 }); 21008 })(function(node, func){ 21009 node.DEFMETHOD("_find_defs", func); 21010 }); 21011 21012 function best_of_expression(ast1, ast2) { 21013 return ast1.print_to_string().length > 21014 ast2.print_to_string().length 21015 ? ast2 : ast1; 21016 } 21017 21018 function best_of_statement(ast1, ast2) { 21019 return best_of_expression(make_node(AST_SimpleStatement, ast1, { 21020 body: ast1 21021 }), make_node(AST_SimpleStatement, ast2, { 21022 body: ast2 21023 })).body; 21024 } 21025 21026 function best_of(compressor, ast1, ast2) { 21027 return (first_in_statement(compressor) ? best_of_statement : best_of_expression)(ast1, ast2); 21028 } 21029 21030 // methods to evaluate a constant expression 21031 (function (def){
21032 // If the node has been successfully reduced to a constant, 21033 // then its value is returned; otherwise the element itself 21034 // is returned. 21035 // They can be distinguished as constant value is never a 21036 // descendant of AST_Node. 21037 AST_Node.DEFMETHOD("evaluate", function(compressor){ 21038 if (!compressor.option("evaluate")) return this; 21039 try { 21040 var val = this._eval(compressor); 21041 return !val || val instanceof RegExp || typeof val != "object" ? val : this; 21042 } catch(ex) { 21043 if (ex !== def) throw ex; 21044 return this; 21045 } 21046 }); 21047 var unaryPrefix = makePredicate("! ~ - + void"); 21048 AST_Node.DEFMETHOD("is_constant", function(){ 21049 // Accomodate when compress option evaluate=false 21050 // as well as the common constant expressions !0 and -1 21051 if (this instanceof AST_Constant) { 21052 return !(this instanceof AST_RegExp); 21053 } else { 21054 return this instanceof AST_UnaryPrefix 21055 && this.expression instanceof AST_Constant 21056 && unaryPrefix(this.operator); 21057 } 21058 }); 21059 // Obtain the constant value of an expression already known to be constant. 21060 // Result only valid iff this.is_constant() is true. 21061 AST_Node.DEFMETHOD("constant_value", function(compressor){ 21062 // Accomodate when option evaluate=false. 21063 if (this instanceof AST_Constant && !(this instanceof AST_RegExp)) { 21064 return this.value; 21065 } 21066 // Accomodate the common constant expressions !0 and -1 when option evaluate=false. 21067 if (this instanceof AST_UnaryPrefix 21068 && this.expression instanceof AST_Constant) switch (this.operator) { 21069 case "!": 21070 return !this.expression.value; 21071 case "~": 21072 return ~this.expression.value; 21073 case "-": 21074 return -this.expression.value; 21075 case "+": 21076 return +this.expression.value; 21077 default: 21078 throw new Error(string_template("Cannot evaluate unary expression {value}", { 21079 value: this.print_to_string() 21080 })); 21081 } 21082 var result = this.evaluate(compressor); 21083 if (result !== this) { 21084 return result; 21085 } 21086 throw new Error(string_template("Cannot evaluate constant [{file}:{line},{col}]", this.start)); 21087 }); 21088 def(AST_Statement, function(){ 21089 throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]", this.start)); 21090 }); 21091 def(AST_Lambda, function(){ 21092 throw def; 21093 }); 21094 function ev(node, compressor) { 21095 if (!compressor) throw new Error("Compressor must be passed"); 21096 21097 return node._eval(compressor); 21098 }; 21099 def(AST_Node, function(){ 21100 throw def; // not constant 21101 }); 21102 def(AST_Constant, function(){ 21103 return this.getValue(); 21104 }); 21105 def(AST_Array, function(compressor){ 21106 if (compressor.option("unsafe")) { 21107 return this.elements.map(function(element) { 21108 return ev(element, compressor); 21109 }); 21110 } 21111 throw def; 21112 }); 21113 def(AST_Object, function(compressor){ 21114 if (compressor.option("unsafe")) { 21115 var val = {}; 21116 for (var i = 0, len = this.properties.length; i < len; i++) { 21117 var prop = this.properties[i]; 21118 var key = prop.key; 21119 if (key instanceof AST_Symbol) { 21120 key = key.name; 21121 } else if (key instanceof AST_Node) { 21122 key = ev(key, compressor); 21123 } 21124 if (typeof Object.prototype[key] === 'function') { 21125 throw def; 21126 } 21127 val[key] = ev(prop.value, compressor); 21128 } 21129 return val; 21130 } 21131 throw def; 21132 }); 21133 def(AST_UnaryPrefix, function(compressor){ 21134 var e = this.expression; 21135 switch (this.operator) { 21136 case "!": return !ev(e, compressor); 21137 case "typeof": 21138 // Function would be evaluated to an array and so typeof would 21139 // incorrectly return 'object'. Hence making is a special case. 21140 if (e instanceof AST_Function) return typeof function(){}; 21141 21142 e = ev(e, compressor); 21143 21144 // typeof <RegExp> returns "object" or "function" on different platforms 21145 // so cannot evaluate reliably 21146 if (e instanceof RegExp) throw def; 21147 21148 return typeof e; 21149 case "void": return void ev(e, compressor); 21150 case "~": return ~ev(e, compressor); 21151 case "-": return -ev(e, compressor); 21152 case "+": return +ev(e, compressor); 21153 } 21154 throw def; 21155 }); 21156 def(AST_Binary, function(c){ 21157 var left = this.left, right = this.right, result; 21158 switch (this.operator) { 21159 case "&&" : result = ev(left, c) && ev(right, c); break; 21160 case "||" : result = ev(left, c) || ev(right, c); break; 21161 case "|" : result = ev(left, c) | ev(right, c); break; 21162 case "&" : result = ev(left, c) & ev(right, c); break; 21163 case "^" : result = ev(left, c) ^ ev(right, c); break; 21164 case "+" : result = ev(left, c) + ev(right, c); break; 21165 case "*" : result = ev(left, c) * ev(right, c); break; 21166 case "/" : result = ev(left, c) / ev(right, c); break; 21167 case "%" : result = ev(left, c) % ev(right, c); break; 21168 case "-" : result = ev(left, c) - ev(right, c); break; 21169 case "<<" : result = ev(left, c) << ev(right, c); break; 21170 case ">>" : result = ev(left, c) >> ev(right, c); break; 21171 case ">>>" : result = ev(left, c) >>> ev(right, c); break; 21172 case "==" : result = ev(left, c) == ev(right, c); break; 21173 case "===" : result = ev(left, c) === ev(right, c); break; 21174 case "!=" : result = ev(left, c) != ev(right, c); break; 21175 case "!==" : result = ev(left, c) !== ev(right, c); break; 21176 case "<" : result = ev(left, c) < ev(right, c); break; 21177 case "<=" : result = ev(left, c) <= ev(right, c); break; 21178 case ">" : result = ev(left, c) > ev(right, c); break; 21179 case ">=" : result = ev(left, c) >= ev(right, c); break; 21180 default: 21181 throw def; 21182 } 21183 if (isNaN(result) && c.find_parent(AST_With)) { 21184 // leave original expression as is 21185 throw def; 21186 } 21187 return result; 21188 }); 21189 def(AST_Conditional, function(compressor){ 21190 return ev(this.condition, compressor) 21191 ? ev(this.consequent, compressor) 21192 : ev(this.alternative, compressor); 21193 }); 21194 def(AST_SymbolRef, function(compressor){ 21195 if (!compressor.option("reduce_vars") || this._evaluating) throw def; 21196 this._evaluating = true; 21197 try { 21198 var fixed = this.fixed_value(); 21199 if (!fixed) throw def; 21200 var value = ev(fixed, compressor); 21201 if (!HOP(fixed, "_eval")) fixed._eval = function() { 21202 return value; 21203 }; 21204 if (value && typeof value == "object" && this.definition().escaped) throw def; 21205 return value; 21206 } finally { 21207 this._evaluating = false; 21208 } 21209 }); 21210 def(AST_PropAccess, function(compressor){ 21211 if (compressor.option("unsafe")) { 21212 var key = this.property; 21213 if (key instanceof AST_Node) { 21214 key = ev(key, compressor); 21215 } 21216 var val = ev(this.expression, compressor); 21217 if (val && HOP(val, key)) { 21218 return val[key]; 21219 } 21220 } 21221 throw def; 21222 }); 21223 })(function(node, func){ 21224 node.DEFMETHOD("_eval", func); 21225 });
vendor: 7,754 bytes, lines 21226-21412
21226 21227 // method to negate an expression 21228 (function(def){ 21229 function basic_negation(exp) { 21230 return make_node(AST_UnaryPrefix, exp, { 21231 operator: "!", 21232 expression: exp 21233 }); 21234 } 21235 function best(orig, alt, first_in_statement) { 21236 var negated = basic_negation(orig); 21237 if (first_in_statement) { 21238 var stat = make_node(AST_SimpleStatement, alt, { 21239 body: alt 21240 }); 21241 return best_of_expression(negated, stat) === stat ? alt : negated; 21242 } 21243 return best_of_expression(negated, alt); 21244 } 21245 def(AST_Node, function(){ 21246 return basic_negation(this); 21247 }); 21248 def(AST_Statement, function(){ 21249 throw new Error("Cannot negate a statement"); 21250 }); 21251 def(AST_Function, function(){ 21252 return basic_negation(this); 21253 }); 21254 def(AST_UnaryPrefix, function(){ 21255 if (this.operator == "!") 21256 return this.expression; 21257 return basic_negation(this); 21258 }); 21259 def(AST_Seq, function(compressor){ 21260 var self = this.clone(); 21261 self.cdr = self.cdr.negate(compressor); 21262 return self; 21263 }); 21264 def(AST_Conditional, function(compressor, first_in_statement){ 21265 var self = this.clone(); 21266 self.consequent = self.consequent.negate(compressor); 21267 self.alternative = self.alternative.negate(compressor); 21268 return best(this, self, first_in_statement); 21269 }); 21270 def(AST_Binary, function(compressor, first_in_statement){ 21271 var self = this.clone(), op = this.operator; 21272 if (compressor.option("unsafe_comps")) { 21273 switch (op) { 21274 case "<=" : self.operator = ">" ; return self; 21275 case "<" : self.operator = ">=" ; return self; 21276 case ">=" : self.operator = "<" ; return self; 21277 case ">" : self.operator = "<=" ; return self; 21278 } 21279 } 21280 switch (op) { 21281 case "==" : self.operator = "!="; return self; 21282 case "!=" : self.operator = "=="; return self; 21283 case "===": self.operator = "!=="; return self; 21284 case "!==": self.operator = "==="; return self; 21285 case "&&": 21286 self.operator = "||"; 21287 self.left = self.left.negate(compressor, first_in_statement); 21288 self.right = self.right.negate(compressor); 21289 return best(this, self, first_in_statement); 21290 case "||": 21291 self.operator = "&&"; 21292 self.left = self.left.negate(compressor, first_in_statement); 21293 self.right = self.right.negate(compressor); 21294 return best(this, self, first_in_statement); 21295 } 21296 return basic_negation(this); 21297 }); 21298 })(function(node, func){ 21299 node.DEFMETHOD("negate", function(compressor, first_in_statement){ 21300 return func.call(this, compressor, first_in_statement); 21301 }); 21302 }); 21303 21304 AST_Call.DEFMETHOD("has_pure_annotation", function(compressor) { 21305 if (!compressor.option("side_effects")) return false; 21306 if (this.pure !== undefined) return this.pure; 21307 var pure = false; 21308 var comments, last_comment; 21309 if (this.start 21310 && (comments = this.start.comments_before) 21311 && comments.length 21312 && /[@#]__PURE__/.test((last_comment = comments[comments.length - 1]).value)) { 21313 pure = last_comment; 21314 } 21315 return this.pure = pure; 21316 }); 21317 21318 // determine if expression has side effects 21319 (function(def){ 21320 def(AST_Node, return_true); 21321 21322 def(AST_EmptyStatement, return_false); 21323 def(AST_Constant, return_false); 21324 def(AST_This, return_false); 21325 21326 def(AST_Call, function(compressor){ 21327 if (!this.has_pure_annotation(compressor) && compressor.pure_funcs(this)) return true; 21328 for (var i = this.args.length; --i >= 0;) { 21329 if (this.args[i].has_side_effects(compressor)) 21330 return true; 21331 } 21332 return false; 21333 }); 21334 21335 function any(list, compressor) { 21336 for (var i = list.length; --i >= 0;) 21337 if (list[i].has_side_effects(compressor)) 21338 return true; 21339 return false; 21340 } 21341 21342 def(AST_Block, function(compressor){ 21343 return any(this.body, compressor); 21344 }); 21345 def(AST_Switch, function(compressor){ 21346 return this.expression.has_side_effects(compressor) 21347 || any(this.body, compressor); 21348 }); 21349 def(AST_Case, function(compressor){ 21350 return this.expression.has_side_effects(compressor) 21351 || any(this.body, compressor); 21352 }); 21353 def(AST_Try, function(compressor){ 21354 return any(this.body, compressor) 21355 || this.bcatch && this.bcatch.has_side_effects(compressor) 21356 || this.bfinally && this.bfinally.has_side_effects(compressor); 21357 }); 21358 def(AST_If, function(compressor){ 21359 return this.condition.has_side_effects(compressor) 21360 || this.body && this.body.has_side_effects(compressor) 21361 || this.alternative && this.alternative.has_side_effects(compressor); 21362 }); 21363 def(AST_LabeledStatement, function(compressor){ 21364 return this.body.has_side_effects(compressor); 21365 }); 21366 def(AST_SimpleStatement, function(compressor){ 21367 return this.body.has_side_effects(compressor); 21368 }); 21369 def(AST_Defun, return_true); 21370 def(AST_Function, return_false); 21371 def(AST_Binary, function(compressor){ 21372 return this.left.has_side_effects(compressor) 21373 || this.right.has_side_effects(compressor); 21374 }); 21375 def(AST_Assign, return_true); 21376 def(AST_Conditional, function(compressor){ 21377 return this.condition.has_side_effects(compressor) 21378 || this.consequent.has_side_effects(compressor) 21379 || this.alternative.has_side_effects(compressor); 21380 }); 21381 def(AST_Unary, function(compressor){ 21382 return unary_side_effects(this.operator) 21383 || this.expression.has_side_effects(compressor); 21384 }); 21385 def(AST_SymbolRef, function(compressor){ 21386 return this.undeclared(); 21387 }); 21388 def(AST_Object, function(compressor){ 21389 return any(this.properties, compressor); 21390 }); 21391 def(AST_ObjectProperty, function(compressor){ 21392 return this.value.has_side_effects(compressor); 21393 }); 21394 def(AST_Array, function(compressor){ 21395 return any(this.elements, compressor); 21396 }); 21397 def(AST_Dot, function(compressor){ 21398 return this.expression.may_throw_on_access(compressor) 21399 || this.expression.has_side_effects(compressor); 21400 }); 21401 def(AST_Sub, function(compressor){ 21402 return this.expression.may_throw_on_access(compressor) 21403 || this.expression.has_side_effects(compressor) 21404 || this.property.has_side_effects(compressor); 21405 }); 21406 def(AST_Seq, function(compressor){ 21407 return this.car.has_side_effects(compressor) 21408 || this.cdr.has_side_effects(compressor); 21409 }); 21410 })(function(node, func){ 21411 node.DEFMETHOD("has_side_effects", func); 21412 });
21413 21414 // tell me if a statement aborts 21415 function aborts(thing) { 21416 return thing && thing.aborts(); 21417 }; 21418 (function(def){ 21419 def(AST_Statement, return_null); 21420 def(AST_Jump, return_this); 21421 function block_aborts(){ 21422 var n = this.body.length; 21423 return n > 0 && aborts(this.body[n - 1]); 21424 }; 21425 def(AST_BlockStatement, block_aborts); 21426 def(AST_SwitchBranch, block_aborts); 21427 def(AST_If, function(){ 21428 return this.alternative && aborts(this.body) && aborts(this.alternative) && this; 21429 }); 21430 })(function(node, func){ 21431 node.DEFMETHOD("aborts", func); 21432 }); 21433 21434 /* -----[ optimizers ]----- */ 21435 21436 OPT(AST_Directive, function(self, compressor){ 21437 if (compressor.has_directive(self.value) !== self) { 21438 return make_node(AST_EmptyStatement, self); 21439 } 21440 return self; 21441 }); 21442 21443 OPT(AST_Debugger, function(self, compressor){ 21444 if (compressor.option("drop_debugger")) 21445 return make_node(AST_EmptyStatement, self); 21446 return self; 21447 }); 21448 21449 OPT(AST_LabeledStatement, function(self, compressor){ 21450 if (self.body instanceof AST_Break 21451 && compressor.loopcontrol_target(self.body) === self.body) { 21452 return make_node(AST_EmptyStatement, self); 21453 } 21454 return self.label.references.length == 0 ? self.body : self; 21455 }); 21456 21457 OPT(AST_Block, function(self, compressor){ 21458 self.body = tighten_body(self.body, compressor); 21459 return self; 21460 }); 21461 21462 OPT(AST_BlockStatement, function(self, compressor){ 21463 self.body = tighten_body(self.body, compressor); 21464 switch (self.body.length) { 21465 case 1: return self.body[0]; 21466 case 0: return make_node(AST_EmptyStatement, self); 21467 } 21468 return self; 21469 }); 21470 21471 AST_Scope.DEFMETHOD("drop_unused", function(compressor){ 21472 var self = this; 21473 if (compressor.has_directive("use asm")) return self; 21474 var toplevel = compressor.option("toplevel"); 21475 if (compressor.option("unused") 21476 && (!(self instanceof AST_Toplevel) || toplevel) 21477 && !self.uses_eval 21478 && !self.uses_with) { 21479 var assign_as_unused = !/keep_assign/.test(compressor.option("unused")); 21480 var drop_funcs = /funcs/.test(toplevel); 21481 var drop_vars = /vars/.test(toplevel); 21482 if (!(self instanceof AST_Toplevel) || toplevel == true) { 21483 drop_funcs = drop_vars = true; 21484 } 21485 var in_use = []; 21486 var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use 21487 if (self instanceof AST_Toplevel && compressor.top_retain) { 21488 self.variables.each(function(def) { 21489 if (compressor.top_retain(def) && !(def.id in in_use_ids)) { 21490 in_use_ids[def.id] = true; 21491 in_use.push(def); 21492 } 21493 }); 21494 } 21495 var initializations = new Dictionary(); 21496 // pass 1: find out which symbols are directly used in 21497 // this scope (not in nested scopes). 21498 var scope = this; 21499 var tw = new TreeWalker(function(node, descend){ 21500 if (node !== self) { 21501 if (node instanceof AST_Defun) { 21502 if (!drop_funcs && scope === self) { 21503 var node_def = node.name.definition(); 21504 if (!(node_def.id in in_use_ids)) { 21505 in_use_ids[node_def.id] = true; 21506 in_use.push(node_def); 21507 } 21508 } 21509 initializations.add(node.name.name, node); 21510 return true; // don't go in nested scopes 21511 } 21512 if (node instanceof AST_Definitions && scope === self) { 21513 node.definitions.forEach(function(def){ 21514 if (!drop_vars) { 21515 var node_def = def.name.definition(); 21516 if (!(node_def.id in in_use_ids)) { 21517 in_use_ids[node_def.id] = true; 21518 in_use.push(node_def); 21519 } 21520 } 21521 if (def.value) { 21522 initializations.add(def.name.name, def.value); 21523 if (def.value.has_side_effects(compressor)) { 21524 def.value.walk(tw); 21525 } 21526 } 21527 }); 21528 return true; 21529 } 21530 if (assign_as_unused 21531 && node instanceof AST_Assign 21532 && node.operator == "=" 21533 && node.left instanceof AST_SymbolRef 21534 && !is_reference_const(node.left) 21535 && scope === self) { 21536 node.right.walk(tw); 21537 return true; 21538 } 21539 if (node instanceof AST_SymbolRef) { 21540 var node_def = node.definition(); 21541 if (!(node_def.id in in_use_ids)) { 21542 in_use_ids[node_def.id] = true; 21543 in_use.push(node_def); 21544 } 21545 return true; 21546 } 21547 if (node instanceof AST_Scope) { 21548 var save_scope = scope; 21549 scope = node; 21550 descend(); 21551 scope = save_scope; 21552 return true; 21553 } 21554 } 21555 }); 21556 self.walk(tw); 21557 // pass 2: for every used symbol we need to walk its 21558 // initialization code to figure out if it uses other 21559 // symbols (that may not be in_use). 21560 for (var i = 0; i < in_use.length; ++i) { 21561 in_use[i].orig.forEach(function(decl){ 21562 // undeclared globals will be instanceof AST_SymbolRef 21563 var init = initializations.get(decl.name); 21564 if (init) init.forEach(function(init){ 21565 var tw = new TreeWalker(function(node){ 21566 if (node instanceof AST_SymbolRef) { 21567 var node_def = node.definition(); 21568 if (!(node_def.id in in_use_ids)) { 21569 in_use_ids[node_def.id] = true; 21570 in_use.push(node_def); 21571 } 21572 } 21573 }); 21574 init.walk(tw); 21575 }); 21576 }); 21577 } 21578 // pass 3: we should drop declarations not in_use 21579 var tt = new TreeTransformer( 21580 function before(node, descend, in_list) { 21581 if (node instanceof AST_Function 21582 && node.name 21583 && !compressor.option("keep_fnames")) { 21584 var def = node.name.definition(); 21585 // any declarations with same name will overshadow 21586 // name of this anonymous function and can therefore 21587 // never be used anywhere 21588 if (!(def.id in in_use_ids) || def.orig.length > 1) 21589 node.name = null; 21590 } 21591 if (node instanceof AST_Lambda && !(node instanceof AST_Acce
21591ssor)) { 21592 var trim = !compressor.option("keep_fargs"); 21593 for (var a = node.argnames, i = a.length; --i >= 0;) { 21594 var sym = a[i]; 21595 if (!(sym.definition().id in in_use_ids)) { 21596 sym.__unused = true; 21597 if (trim) { 21598 a.pop(); 21599 compressor[sym.unreferenced() ? "warn" : "info"]("Dropping unused function argument {name} [{file}:{line},{col}]", { 21600 name : sym.name, 21601 file : sym.start.file, 21602 line : sym.start.line, 21603 col : sym.start.col 21604 }); 21605 } 21606 } 21607 else { 21608 trim = false; 21609 } 21610 } 21611 } 21612 if (drop_funcs && node instanceof AST_Defun && node !== self) { 21613 if (!(node.name.definition().id in in_use_ids)) { 21614 compressor[node.name.unreferenced() ? "warn" : "info"]("Dropping unused function {name} [{file}:{line},{col}]", { 21615 name : node.name.name, 21616 file : node.name.start.file, 21617 line : node.name.start.line, 21618 col : node.name.start.col 21619 }); 21620 return make_node(AST_EmptyStatement, node); 21621 } 21622 return node; 21623 } 21624 if (drop_vars && node instanceof AST_Definitions && !(tt.parent() instanceof AST_ForIn && tt.parent().init === node)) { 21625 var def = node.definitions.filter(function(def){ 21626 if (def.value) def.value = def.value.transform(tt); 21627 var sym = def.name.definition(); 21628 if (sym.id in in_use_ids) return true; 21629 if (sym.orig[0] instanceof AST_SymbolCatch) { 21630 def.value = def.value && def.value.drop_side_effect_free(compressor); 21631 return true; 21632 } 21633 var w = { 21634 name : def.name.name, 21635 file : def.name.start.file, 21636 line : def.name.start.line, 21637 col : def.name.start.col 21638 }; 21639 if (def.value && (def._unused_side_effects = def.value.drop_side_effect_free(compressor))) { 21640 compressor.warn("Side effects in initialization of unused variable {name} [{file}:{line},{col}]", w); 21641 return true; 21642 } 21643 compressor[def.name.unreferenced() ? "warn" : "info"]("Dropping unused variable {name} [{file}:{line},{col}]", w); 21644 return false; 21645 }); 21646 // place uninitialized names at the start 21647 def = mergeSort(def, function(a, b){ 21648 if (!a.value && b.value) return -1; 21649 if (!b.value && a.value) return 1; 21650 return 0; 21651 }); 21652 // for unused names whose initialization has 21653 // side effects, we can cascade the init. code 21654 // into the next one, or next statement. 21655 var side_effects = []; 21656 for (var i = 0; i < def.length;) { 21657 var x = def[i]; 21658 if (x._unused_side_effects) { 21659 side_effects.push(x._unused_side_effects); 21660 def.splice(i, 1); 21661 } else { 21662 if (side_effects.length > 0) { 21663 side_effects.push(x.value); 21664 x.value = AST_Seq.from_array(side_effects); 21665 side_effects = []; 21666 } 21667 ++i; 21668 } 21669 } 21670 if (side_effects.length > 0) { 21671 side_effects = make_node(AST_BlockStatement, node, { 21672 body: [ make_node(AST_SimpleStatement, node, { 21673 body: AST_Seq.from_array(side_effects) 21674 }) ] 21675 }); 21676 } else { 21677 side_effects = null; 21678 } 21679 if (def.length == 0 && !side_effects) { 21680 return make_node(AST_EmptyStatement, node); 21681 } 21682 if (def.length == 0) { 21683 return in_list ? MAP.splice(side_effects.body) : side_effects; 21684 } 21685 node.definitions = def; 21686 if (side_effects) { 21687 side_effects.body.unshift(node); 21688 return in_list ? MAP.splice(side_effects.body) : side_effects; 21689 } 21690 return node; 21691 } 21692 if (drop_vars && assign_as_unused 21693 && node instanceof AST_Assign 21694 && node.operator == "=" 21695 && node.left instanceof AST_SymbolRef) { 21696 var def = node.left.definition(); 21697 if (!(def.id in in_use_ids) 21698 && self.variables.get(def.name) === def) { 21699 return maintain_this_binding(tt.parent(), node, node.right.transform(tt)); 21700 } 21701 } 21702 // certain combination of unused name + side effect leads to: 21703 // https://github.com/mishoo/UglifyJS2/issues/44 21704 // https://github.com/mishoo/UglifyJS2/issues/1830
vendor: 4,282 bytes, lines 21705-21791
21705 // that's an invalid AST. 21706 // We fix it at this stage by moving the `var` outside the `for`. 21707 if (node instanceof AST_For) { 21708 descend(node, this); 21709 if (node.init instanceof AST_BlockStatement) { 21710 var block = node.init; 21711 node.init = block.body.pop(); 21712 block.body.push(node); 21713 return in_list ? MAP.splice(block.body) : block; 21714 } else if (is_empty(node.init)) { 21715 node.init = null; 21716 } 21717 return node; 21718 } 21719 if (node instanceof AST_LabeledStatement && node.body instanceof AST_For) { 21720 descend(node, this); 21721 if (node.body instanceof AST_BlockStatement) { 21722 var block = node.body; 21723 node.body = block.body.pop(); 21724 block.body.push(node); 21725 return in_list ? MAP.splice(block.body) : block; 21726 } 21727 return node; 21728 } 21729 if (node instanceof AST_Scope && node !== self) 21730 return node; 21731 } 21732 ); 21733 self.transform(tt); 21734 } 21735 }); 21736 21737 AST_Scope.DEFMETHOD("hoist_declarations", function(compressor){ 21738 var self = this; 21739 if (compressor.has_directive("use asm")) return self; 21740 var hoist_funs = compressor.option("hoist_funs"); 21741 var hoist_vars = compressor.option("hoist_vars"); 21742 if (hoist_funs || hoist_vars) { 21743 var dirs = []; 21744 var hoisted = []; 21745 var vars = new Dictionary(), vars_found = 0, var_decl = 0; 21746 // let's count var_decl first, we seem to waste a lot of 21747 // space if we hoist `var` when there's only one. 21748 self.walk(new TreeWalker(function(node){ 21749 if (node instanceof AST_Scope && node !== self) 21750 return true; 21751 if (node instanceof AST_Var) { 21752 ++var_decl; 21753 return true; 21754 } 21755 })); 21756 hoist_vars = hoist_vars && var_decl > 1; 21757 var tt = new TreeTransformer( 21758 function before(node) { 21759 if (node !== self) { 21760 if (node instanceof AST_Directive) { 21761 dirs.push(node); 21762 return make_node(AST_EmptyStatement, node); 21763 } 21764 if (node instanceof AST_Defun && hoist_funs) { 21765 hoisted.push(node); 21766 return make_node(AST_EmptyStatement, node); 21767 } 21768 if (node instanceof AST_Var && hoist_vars) { 21769 node.definitions.forEach(function(def){ 21770 vars.set(def.name.name, def); 21771 ++vars_found; 21772 }); 21773 var seq = node.to_assignments(compressor); 21774 var p = tt.parent(); 21775 if (p instanceof AST_ForIn && p.init === node) { 21776 if (seq == null) { 21777 var def = node.definitions[0].name; 21778 return make_node(AST_SymbolRef, def, def); 21779 } 21780 return seq; 21781 } 21782 if (p instanceof AST_For && p.init === node) { 21783 return seq; 21784 } 21785 if (!seq) return make_node(AST_EmptyStatement, node); 21786 return make_node(AST_SimpleStatement, node, { 21787 body: seq 21788 }); 21789 } 21790 if (node instanceof AST_Scope) 21791 return node;
21791 // to avoid descending in nested scopes 21792 } 21793 } 21794 ); 21795 self = self.transform(tt); 21796 if (vars_found > 0) { 21797 // collect only vars which don't show up in self's arguments list 21798 var defs = []; 21799 vars.each(function(def, name){ 21800 if (self instanceof AST_Lambda 21801 && find_if(function(x){ return x.name == def.name.name }, 21802 self.argnames)) { 21803 vars.del(name); 21804 } else { 21805 def = def.clone(); 21806 def.value = null; 21807 defs.push(def); 21808 vars.set(name, def); 21809 } 21810 }); 21811 if (defs.length > 0) { 21812 // try to merge in assignments 21813 for (var i = 0; i < self.body.length;) { 21814 if (self.body[i] instanceof AST_SimpleStatement) { 21815 var expr = self.body[i].body, sym, assign; 21816 if (expr instanceof AST_Assign 21817 && expr.operator == "=" 21818 && (sym = expr.left) instanceof AST_Symbol 21819 && vars.has(sym.name)) 21820 { 21821 var def = vars.get(sym.name); 21822 if (def.value) break; 21823 def.value = expr.right; 21824 remove(defs, def); 21825 defs.push(def); 21826 self.body.splice(i, 1); 21827 continue; 21828 } 21829 if (expr instanceof AST_Seq 21830 && (assign = expr.car) instanceof AST_Assign 21831 && assign.operator == "=" 21832 && (sym = assign.left) instanceof AST_Symbol 21833 && vars.has(sym.name)) 21834 { 21835 var def = vars.get(sym.name); 21836 if (def.value) break; 21837 def.value = assign.right; 21838 remove(defs, def); 21839 defs.push(def); 21840 self.body[i].body = expr.cdr; 21841 continue; 21842 } 21843 } 21844 if (self.body[i] instanceof AST_EmptyStatement) { 21845 self.body.splice(i, 1); 21846 continue; 21847 } 21848 if (self.body[i] instanceof AST_BlockStatement) { 21849 var tmp = [ i, 1 ].concat(self.body[i].body); 21850 self.body.splice.apply(self.body, tmp); 21851 continue; 21852 } 21853 break; 21854 } 21855 defs = make_node(AST_Var, self, { 21856 definitions: defs 21857 }); 21858 hoisted.push(defs); 21859 }; 21860 } 21861 self.body = dirs.concat(hoisted, self.body); 21862 } 21863 return self; 21864 }); 21865 21866 // drop_side_effect_free() 21867 // remove side-effect-free parts which only affects return value 21868 (function(def){ 21869 // Drop side-effect-free elements from an array of expressions. 21870 // Returns an array of expressions with side-effects or null 21871 // if all elements were dropped. Note: original array may be 21872 // returned if nothing changed. 21873 function trim(nodes, compressor, first_in_statement) { 21874 var ret = [], changed = false; 21875 for (var i = 0, len = nodes.length; i < len; i++) { 21876 var node = nodes[i].drop_side_effect_free(compressor, first_in_statement);
21877 changed |= node !== nodes[i]; 21878 if (node) { 21879 ret.push(node); 21880 first_in_statement = false; 21881 } 21882 } 21883 return changed ? ret.length ? ret : null : nodes; 21884 } 21885 21886 def(AST_Node, return_this); 21887 def(AST_Constant, return_null); 21888 def(AST_This, return_null); 21889 def(AST_Call, function(compressor, first_in_statement){ 21890 if (!this.has_pure_annotation(compressor) && compressor.pure_funcs(this)) { 21891 if (this.expression instanceof AST_Function 21892 && (!this.expression.name || !this.expression.name.definition().references.length)) { 21893 var node = this.clone(); 21894 node.expression = node.expression.process_expression(false, compressor); 21895 return node; 21896 } 21897 return this; 21898 } 21899 if (this.pure) { 21900 compressor.warn("Dropping __PURE__ call [{file}:{line},{col}]", this.start); 21901 this.pure.value = this.pure.value.replace(/[@#]__PURE__/g, ' '); 21902 } 21903 var args = trim(this.args, compressor, first_in_statement); 21904 return args && AST_Seq.from_array(args); 21905 }); 21906 def(AST_Accessor, return_null); 21907 def(AST_Function, return_null); 21908 def(AST_Binary, function(compressor, first_in_statement){ 21909 var right = this.right.drop_side_effect_free(compressor); 21910 if (!right) return this.left.drop_side_effect_free(compressor, first_in_statement); 21911 switch (this.operator) { 21912 case "&&": 21913 case "||": 21914 if (right === this.right) return this; 21915 var node = this.clone(); 21916 node.right = right; 21917 return node; 21918 default: 21919 var left = this.left.drop_side_effect_free(compressor, first_in_statement); 21920 if (!left) return this.right.drop_side_effect_free(compressor, first_in_statement); 21921 return make_node(AST_Seq, this, { 21922 car: left, 21923 cdr: right 21924 }); 21925 } 21926 }); 21927 def(AST_Assign, return_this); 21928 def(AST_Conditional, function(compressor){ 21929 var consequent = this.consequent.drop_side_effect_free(compressor); 21930 var alternative = this.alternative.drop_side_effect_free(compressor); 21931 if (consequent === this.consequent && alternative === this.alternative) return this; 21932 if (!consequent) return alternative ? make_node(AST_Binary, this, { 21933 operator: "||", 21934 left: this.condition, 21935 right: alternative 21936 }) : this.condition.drop_side_effect_free(compressor); 21937 if (!alternative) return make_node(AST_Binary, this, { 21938 operator: "&&", 21939 left: this.condition, 21940 right: consequent 21941 }); 21942 var node = this.clone(); 21943 node.consequent = consequent; 21944 node.alternative = alternative; 21945 return node; 21946 }); 21947 def(AST_Unary, function(compressor, first_in_statement){ 21948 if (unary_side_effects(this.operator)) return this; 21949 if (this.operator == "typeof" && this.expression instanceof AST_SymbolRef) return null; 21950 var expression = this.expression.drop_side_effect_free(compressor, first_in_statement); 21951 if (first_in_statement 21952 && this instanceof AST_UnaryPrefix 21953 && is_iife_call(expression)) { 21954 if (expression === this.expression && this.operator.length === 1) return this; 21955 return make_node(AST_UnaryPrefix, this, { 21956 operator: this.operator.length === 1 ? this.operator : "!", 21957 expression: expression 21958 }); 21959 } 21960 return expression; 21961 }); 21962 def(AST_SymbolRef, function() {
21963 return this.undeclared() ? this : null; 21964 }); 21965 def(AST_Object, function(compressor, first_in_statement){ 21966 var values = trim(this.properties, compressor, first_in_statement); 21967 return values && AST_Seq.from_array(values); 21968 }); 21969 def(AST_ObjectProperty, function(compressor, first_in_statement){ 21970 return this.value.drop_side_effect_free(compressor, first_in_statement); 21971 }); 21972 def(AST_Array, function(compressor, first_in_statement){ 21973 var values = trim(this.elements, compressor, first_in_statement); 21974 return values && AST_Seq.from_array(values); 21975 }); 21976 def(AST_Dot, function(compressor, first_in_statement){ 21977 if (this.expression.may_throw_on_access(compressor)) return this; 21978 return this.expression.drop_side_effect_free(compressor, first_in_statement); 21979 }); 21980 def(AST_Sub, function(compressor, first_in_statement){ 21981 if (this.expression.may_throw_on_access(compressor)) return this; 21982 var expression = this.expression.drop_side_effect_free(compressor, first_in_statement); 21983 if (!expression) return this.property.drop_side_effect_free(compressor, first_in_statement); 21984 var property = this.property.drop_side_effect_free(compressor); 21985 if (!property) return expression; 21986 return make_node(AST_Seq, this, { 21987 car: expression, 21988 cdr: property 21989 }); 21990 }); 21991 def(AST_Seq, function(compressor){ 21992 var cdr = this.cdr.drop_side_effect_free(compressor); 21993 if (cdr === this.cdr) return this; 21994 if (!cdr) return this.car; 21995 return make_node(AST_Seq, this, { 21996 car: this.car, 21997 cdr: cdr 21998 }); 21999 }); 22000 })(function(node, func){ 22001 node.DEFMETHOD("drop_side_effect_free", func); 22002 }); 22003 22004 OPT(AST_SimpleStatement, function(self, compressor){ 22005 if (compressor.option("side_effects")) { 22006 var body = self.body; 22007 var node = body.drop_side_effect_free(compressor, true); 22008 if (!node) { 22009 compressor.warn("Dropping side-effect-free statement [{file}:{line},{col}]", self.start); 22010 return make_node(AST_EmptyStatement, self); 22011 } 22012 if (node !== body) { 22013 return make_node(AST_SimpleStatement, self, { body: node }); 22014 } 22015 } 22016 return self; 22017 }); 22018 22019 OPT(AST_DWLoop, function(self, compressor){ 22020 if (!compressor.option("loops")) return self; 22021 var cond = self.condition.evaluate(compressor); 22022 if (cond !== self.condition) { 22023 if (cond) { 22024 return make_node(AST_For, self, { 22025 body: self.body 22026 }); 22027 } 22028 if (compressor.option("dead_code") && self instanceof AST_While) { 22029 var a = []; 22030 extract_declarations_from_unreachable_code(compressor, self.body, a); 22031 return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor); 22032 } 22033 if (self instanceof AST_Do) { 22034 var has_loop_control = false; 22035 var tw = new TreeWalker(function(node) { 22036 if (node instanceof AST_Scope || has_loop_control) return true; 22037 if (node instanceof AST_LoopControl && tw.loopcontrol_target(node) === self) 22038 return has_loop_control = true; 22039 }); 22040 var parent = compressor.parent(); 22041 (parent instanceof AST_LabeledStatement ? parent : self).walk(tw); 22042 if (!has_loop_control) return self.body; 22043 } 22044 } 22045 if (self instanceof AST_While) { 22046 return make_node(AST_For, self, self).optimize(compressor); 22047 } 22048 return self; 22049 }); 22050 22051 function if_break_in_loop(self, compressor) { 22052 function drop_it(rest) { 22053 rest = as_statement_array(rest); 22054 if (self.body instanceof AST_BlockStatement) { 22055 self.body = self.body.clone(); 22056 self.body.body = rest.concat(self.body.body.slice(1)); 22057 self.body = self.body.transform(compressor); 22058 } else { 22059 self.body = make_node(AST_BlockStatement, self.body, { 22060 body: rest 22061 }).transform(compressor); 22062 } 22063 if_break_in_loop(self, compressor); 22064 } 22065 var first = self.body instanceof AST_BlockStatement ? self.body.body[0] : self.body; 22066 if (first instanceof AST_If) { 22067 if (first.body instanceof AST_Break 22068 && compressor.loopcontrol_target(first.body) === compressor.self()) { 22069 if (self.condition) { 22070 self.condition = make_node(AST_Binary, self.condition, { 22071 left: self.condition, 22072 operator: "&&", 22073 right: first.condition.negate(compressor), 22074 }); 22075 } else { 22076 self.condition = first.condition.negate(compressor); 22077 } 22078 drop_it(first.alternative); 22079 } 22080 else if (first.alternative instanceof AST_Break 22081 && compressor.loopcontrol_target(first.alternative) === compressor.self()) { 22082 if (self.condition) { 22083 self.condition = make_node(AST_Binary, self.condition, { 22084 left: self.condition, 22085 operator: "&&", 22086 right: first.condition, 22087 }); 22088 } else { 22089 self.condition = first.condition; 22090 } 22091 drop_it(first.body); 22092 } 22093 } 22094 }; 22095 22096 OPT(AST_For, function(self, compressor){ 22097 if (!compressor.option("loops")) return self; 22098 if (self.condition) { 22099 var cond = self.condition.evaluate(compressor); 22100 if (compressor.option("dead_code") && !cond) { 22101 var a = []; 22102 if (self.init instanceof AST_Statement) { 22103 a.push(self.init); 22104 } 22105 else if (self.init) { 22106 a.push(make_node(AST_SimpleStatement, self.init, { 22107 body: self.init 22108 })); 22109 } 22110 extract_declarations_from_unreachable_code(compressor, self.body, a); 22111 return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor); 22112 } 22113 if (cond !== self.condition) { 22114 cond = make_node_from_constant(cond, self.condition).transform(compressor); 22115 self.condition = best_of_expression(cond, self.condition); 22116 } 22117 } 22118 if_break_in_loop(self, compressor); 22119 return self; 22120 });
22121 22122 OPT(AST_If, function(self, compressor){ 22123 if (is_empty(self.alternative)) self.alternative = null; 22124 22125 if (!compressor.option("conditionals")) return self; 22126 // if condition can be statically determined, warn and drop 22127 // one of the blocks. note, statically determined implies 22128 // âhas no side effectsâ; also it doesn't work for cases like 22129 // `x && true`, though it probably should. 22130 var cond = self.condition.evaluate(compressor); 22131 if (cond !== self.condition) { 22132 if (cond) { 22133 compressor.warn("Condition always true [{file}:{line},{col}]", self.condition.start); 22134 if (compressor.option("dead_code")) { 22135 var a = []; 22136 if (self.alternative) { 22137 extract_declarations_from_unreachable_code(compressor, self.alternative, a); 22138 } 22139 a.push(self.body); 22140 return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor); 22141 } 22142 } else { 22143 compressor.warn("Condition always false [{file}:{line},{col}]", self.condition.start); 22144 if (compressor.option("dead_code")) { 22145 var a = []; 22146 extract_declarations_from_unreachable_code(compressor, self.body, a); 22147 if (self.alternative) a.push(self.alternative); 22148 return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor); 22149 } 22150 } 22151 cond = make_node_from_constant(cond, self.condition).transform(compressor); 22152 self.condition = best_of_expression(cond, self.condition); 22153 } 22154 var negated = self.condition.negate(compressor); 22155 var self_condition_length = self.condition.print_to_string().length; 22156 var negated_length = negated.print_to_string().length; 22157 var negated_is_best = negated_length < self_condition_length;
vendor: 4,362 bytes, lines 22158-22250
22158 if (self.alternative && negated_is_best) { 22159 negated_is_best = false; // because we already do the switch here. 22160 // no need to swap values of self_condition_length and negated_length 22161 // here because they are only used in an equality comparison later on. 22162 self.condition = negated; 22163 var tmp = self.body; 22164 self.body = self.alternative || make_node(AST_EmptyStatement, self); 22165 self.alternative = tmp; 22166 } 22167 if (is_empty(self.body) && is_empty(self.alternative)) { 22168 return make_node(AST_SimpleStatement, self.condition, { 22169 body: self.condition.clone() 22170 }).optimize(compressor); 22171 } 22172 if (self.body instanceof AST_SimpleStatement 22173 && self.alternative instanceof AST_SimpleStatement) { 22174 return make_node(AST_SimpleStatement, self, { 22175 body: make_node(AST_Conditional, self, { 22176 condition : self.condition, 22177 consequent : self.body.body, 22178 alternative : self.alternative.body 22179 }) 22180 }).optimize(compressor); 22181 } 22182 if (is_empty(self.alternative) && self.body instanceof AST_SimpleStatement) { 22183 if (self_condition_length === negated_length && !negated_is_best 22184 && self.condition instanceof AST_Binary && self.condition.operator == "||") { 22185 // although the code length of self.condition and negated are the same, 22186 // negated does not require additional surrounding parentheses. 22187 // see https://github.com/mishoo/UglifyJS2/issues/979 22188 negated_is_best = true; 22189 } 22190 if (negated_is_best) return make_node(AST_SimpleStatement, self, { 22191 body: make_node(AST_Binary, self, { 22192 operator : "||", 22193 left : negated, 22194 right : self.body.body 22195 }) 22196 }).optimize(compressor); 22197 return make_node(AST_SimpleStatement, self, { 22198 body: make_node(AST_Binary, self, { 22199 operator : "&&", 22200 left : self.condition, 22201 right : self.body.body 22202 }) 22203 }).optimize(compressor); 22204 } 22205 if (self.body instanceof AST_EmptyStatement 22206 && self.alternative instanceof AST_SimpleStatement) { 22207 return make_node(AST_SimpleStatement, self, { 22208 body: make_node(AST_Binary, self, { 22209 operator : "||", 22210 left : self.condition, 22211 right : self.alternative.body 22212 }) 22213 }).optimize(compressor); 22214 } 22215 if (self.body instanceof AST_Exit 22216 && self.alternative instanceof AST_Exit 22217 && self.body.TYPE == self.alternative.TYPE) { 22218 return make_node(self.body.CTOR, self, { 22219 value: make_node(AST_Conditional, self, { 22220 condition : self.condition, 22221 consequent : self.body.value || make_node(AST_Undefined, self.body), 22222 alternative : self.alternative.value || make_node(AST_Undefined, self.alternative) 22223 }).transform(compressor) 22224 }).optimize(compressor); 22225 } 22226 if (self.body instanceof AST_If 22227 && !self.body.alternative 22228 && !self.alternative) { 22229 self = make_node(AST_If, self, { 22230 condition: make_node(AST_Binary, self.condition, { 22231 operator: "&&", 22232 left: self.condition, 22233 right: self.body.condition 22234 }), 22235 body: self.body.body, 22236 alternative: null 22237 }); 22238 } 22239 if (aborts(self.body)) { 22240 if (self.alternative) { 22241 var alt = self.alternative; 22242 self.alternative = null; 22243 return make_node(AST_BlockStatement, self, { 22244 body: [ self, alt ] 22245 }).optimize(compressor); 22246 } 22247 } 22248 if (aborts(self.alternative)) { 22249 var body = self.body; 22250 self.body = self.alternative;
22251 self.condition = negated_is_best ? negated : self.condition.negate(compressor); 22252 self.alternative = null; 22253 return make_node(AST_BlockStatement, self, { 22254 body: [ self, body ] 22255 }).optimize(compressor); 22256 } 22257 return self; 22258 }); 22259 22260 OPT(AST_Switch, function(self, compressor){ 22261 if (!compressor.option("switches")) return self; 22262 var branch; 22263 var value = self.expression.evaluate(compressor); 22264 if (value !== self.expression) { 22265 var expression = make_node_from_constant(value, self.expression).transform(compressor); 22266 self.expression = best_of_expression(expression, self.expression); 22267 } 22268 if (!compressor.option("dead_code")) return self; 22269 var decl = []; 22270 var body = []; 22271 var default_branch; 22272 var exact_match; 22273 for (var i = 0, len = self.body.length; i < len && !exact_match; i++) { 22274 branch = self.body[i]; 22275 if (branch instanceof AST_Default) { 22276 if (!default_branch) { 22277 default_branch = branch; 22278 } else { 22279 eliminate_branch(branch, body[body.length - 1]); 22280 } 22281 } else if (value !== self.expression) { 22282 var exp = branch.expression.evaluate(compressor); 22283 if (exp === value) { 22284 exact_match = branch; 22285 if (default_branch) { 22286 var default_index = body.indexOf(default_branch); 22287 body.splice(default_index, 1); 22288 eliminate_branch(default_branch, body[default_index - 1]); 22289 default_branch = null; 22290 } 22291 } else if (exp !== branch.expression) { 22292 eliminate_branch(branch, body[body.length - 1]); 22293 continue; 22294 } 22295 } 22296 if (aborts(branch)) { 22297 var prev = body[body.length - 1]; 22298 if (aborts(prev) && prev.body.length == branch.body.length 22299 && make_node(AST_BlockStatement, prev, prev).equivalent_to(make_node(AST_BlockStatement, branch, branch))) { 22300 prev.body = []; 22301 } 22302 } 22303 body.push(branch); 22304 } 22305 while (i < len) eliminate_branch(self.body[i++], body[body.length - 1]); 22306 if (body.length > 0) { 22307 body[0].body = decl.concat(body[0].body); 22308 } 22309 self.body = body; 22310 while (branch = body[body.length - 1]) { 22311 var stat = branch.body[branch.body.length - 1]; 22312 if (stat instanceof AST_Break && compressor.loopcontrol_target(stat) === self) 22313 branch.body.pop(); 22314 if (branch.body.length || branch instanceof AST_Case 22315 && (default_branch || branch.expression.has_side_effects(compressor))) break; 22316 if (body.pop() === default_branch) default_branch = null; 22317 } 22318 if (body.length == 0) { 22319 return make_node(AST_BlockStatement, self, { 22320 body: decl.concat(make_node(AST_SimpleStatement, self.expression, { 22321 body: self.expression 22322 })) 22323 }).optimize(compressor); 22324 } 22325 if (body.length == 1 && (body[0] === exact_match || body[0] === default_branch)) { 22326 var has_break = false; 22327 var tw = new TreeWalker(function(node) { 22328 if (has_break 22329 || node instanceof AST_Lambda 22330 || node instanceof AST_SimpleStatement) return true; 22331 if (node instanceof AST_Break && tw.loopcontrol_target(node) === self) 22332 has_break = true; 22333 }); 22334 self.walk(tw); 22335 if (!has_break) { 22336 body = body[0].body.slice(); 22337 body.unshift(make_node(AST_SimpleStatement, self.expression, { 22338 body: self.expression 22339 })); 22340 return make_node(AST_BlockStatement, self, { 22341 body: body 22342 }).optimize(compressor); 22343 } 22344 } 22345 return self; 22346 22347 function eliminate_branch(branch, prev) { 22348 if (prev && !aborts(prev)) { 22349 prev.body = prev.body.concat(branch.body); 22350 } else { 22351 extract_declarations_from_unreachable_code(compressor, branch, decl); 22352 } 22353 } 22354 });
22355 22356 OPT(AST_Try, function(self, compressor){ 22357 self.body = tighten_body(self.body, compressor); 22358 if (self.bcatch && self.bfinally && all(self.bfinally.body, is_empty)) self.bfinally = null; 22359 if (all(self.body, is_empty)) { 22360 var body = []; 22361 if (self.bcatch) extract_declarations_from_unreachable_code(compressor, self.bcatch, body); 22362 if (self.bfinally) body = body.concat(self.bfinally.body); 22363 return make_node(AST_BlockStatement, self, { 22364 body: body 22365 }).optimize(compressor); 22366 } 22367 return self; 22368 }); 22369 22370 AST_Definitions.DEFMETHOD("remove_initializers", function(){ 22371 this.definitions.forEach(function(def){ def.value = null }); 22372 }); 22373 22374 AST_Definitions.DEFMETHOD("to_assignments", function(compressor){ 22375 var reduce_vars = compressor.option("reduce_vars"); 22376 var assignments = this.definitions.reduce(function(a, def){ 22377 if (def.value) { 22378 var name = make_node(AST_SymbolRef, def.name, def.name); 22379 a.push(make_node(AST_Assign, def, { 22380 operator : "=", 22381 left : name, 22382 right : def.value 22383 })); 22384 if (reduce_vars) name.definition().fixed = false; 22385 } 22386 return a; 22387 }, []); 22388 if (assignments.length == 0) return null; 22389 return AST_Seq.from_array(assignments); 22390 }); 22391 22392 OPT(AST_Definitions, function(self, compressor){ 22393 if (self.definitions.length == 0) 22394 return make_node(AST_EmptyStatement, self); 22395 return self; 22396 }); 22397 22398 OPT(AST_Call, function(self, compressor){ 22399 var exp = self.expression; 22400 if (compressor.option("reduce_vars") 22401 && exp instanceof AST_SymbolRef) { 22402 var def = exp.definition(); 22403 var fixed = exp.fixed_value(); 22404 if (fixed instanceof AST_Defun) { 22405 def.fixed = fixed = make_node(AST_Function, fixed, fixed).clone(true); 22406 } 22407 if (fixed instanceof AST_Function) { 22408 exp = fixed; 22409 if (compressor.option("unused") 22410 && def.references.length == 1 22411 && !(def.scope.uses_arguments 22412 && def.orig[0] instanceof AST_SymbolFunarg) 22413 && !def.scope.uses_eval 22414 && compressor.find_parent(AST_Scope) === def.scope) { 22415 self.expression = exp; 22416 } 22417 } 22418 } 22419 if (compressor.option("unused") 22420 && exp instanceof AST_Function 22421 && !exp.uses_arguments 22422 && !exp.uses_eval) { 22423 var pos = 0, last = 0; 22424 for (var i = 0, len = self.args.length; i < len; i++) { 22425 var trim = i >= exp.argnames.length; 22426 if (trim || exp.argnames[i].__unused) { 22427 var node = self.args[i].drop_side_effect_free(compressor); 22428 if (node) { 22429 self.args[pos++] = node; 22430 } else if (!trim) { 22431 self.args[pos++] = make_node(AST_Number, self.args[i], { 22432 value: 0 22433 }); 22434 continue; 22435 } 22436 } else { 22437 self.args[pos++] = self.args[i]; 22438 } 22439 last = pos; 22440 } 22441 self.args.length = last; 22442 } 22443 if (compressor.option("unsafe")) { 22444 if (exp instanceof AST_SymbolRef && exp.undeclared()) { 22445 switch (exp.name) { 22446 case "Array": 22447 if (self.args.length != 1) { 22448 return make_node(AST_Array, self, { 22449 elements: self.args 22450 }).optimize(compressor); 22451 } 22452 break; 22453 case "Object": 22454 if (self.args.length == 0) { 22455 return make_node(AST_Object, self, { 22456 properties: [] 22457 }); 22458 } 22459 break; 22460 case "String": 22461 if (self.args.length == 0) return make_node(AST_String, self, { 22462 value: "" 22463 }); 22464 if (self.args.length <= 1) return make_node(AST_Binary, self, { 22465 left: self.args[0], 22466 operator: "+", 22467 right: make_node(AST_String, self, { value: "" }) 22468 }).optimize(compressor); 22469 break; 22470 case "Number": 22471 if (self.args.length == 0) return make_node(AST_Number, self, { 22472 value: 0 22473 }); 22474 if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, { 22475 expression: self.args[0], 22476 operator: "+" 22477 }).optimize(compressor); 22478 case "Boolean": 22479 if (self.args.length == 0) return make_node(AST_False, self); 22480 if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, { 22481 expression: make_node(AST_UnaryPrefix, self, { 22482 expression: self.args[0], 22483 operator: "!" 22484 }), 22485 operator: "!" 22486 }).optimize(compressor); 22487 break; 22488 case "Function": 22489 // new Function() => function(){} 22490 if (self.args.length == 0) return make_node(AST_Function, self, { 22491 argnames: [], 22492 body: [] 22493 }); 22494 if (all(self.args, function(x){ return x instanceof AST_String })) { 22495 // quite a corner-case, but we can handle it: 22496 // https://github.com/mishoo/UglifyJS2/issues/203 22497 // if the code argument is a constant, then we can minify it. 22498 try { 22499 var code = "(function(" + self.args.slice(0, -1).map(function(arg){ 22500 return arg.value; 22501 }).join(",") + "){" + self.args[self.args.length - 1].value + "})()"; 22502 var ast = parse(code); 22503 ast.figure_out_scope({ screw_ie8: compressor.option("screw_ie8") }); 22504 var comp = new Compressor(compressor.options); 22505 ast = ast.transform(comp); 22506 ast.figure_out_scope({ screw_ie8: compressor.option("screw_ie8") }); 22507 ast.mangle_names(); 22508 var fun; 22509 try { 22510 ast.walk(new TreeWalker(function(node){ 22511 if (node instanceof AST_Lambda) { 22512 fun = node; 22513 throw ast; 22514 } 22515 })); 22516 } catch(ex) { 22517 if (ex !== ast) throw ex; 22518 }; 22519 if (!fun) return self; 22520 var args = fun.argnames.map(function(arg, i){ 22521 return make_node(AST_String, self.args[i], { 22522 value: arg.print_to_string() 22523 }); 22524 }); 22525 var code = OutputStream(); 22526 AST_BlockStatement.prototype._codegen.call(fun, fun, code); 22527 code = code.toString().replace(/^\{|\}$/g, ""); 22528 args.push(make_node(AST_String, self.args[self.args.length - 1], { 22529 value: code 22530 })); 22531 self.args = args; 22532 return self; 22533 } catch(ex) { 22534 if (ex instanceof JS_Parse_Error) { 22535 compressor.warn("Error parsing code passed to
vendor: 4,623 bytes, lines 22535-22630
22535new Function [{file}:{line},{col}]", self.args[self.args.length - 1].start); 22536 compressor.warn(ex.toString()); 22537 } else { 22538 console.log(ex); 22539 throw ex; 22540 } 22541 } 22542 } 22543 break; 22544 } 22545 } 22546 else if (exp instanceof AST_Dot && exp.property == "toString" && self.args.length == 0) { 22547 return make_node(AST_Binary, self, { 22548 left: make_node(AST_String, self, { value: "" }), 22549 operator: "+", 22550 right: exp.expression 22551 }).optimize(compressor); 22552 } 22553 else if (exp instanceof AST_Dot && exp.expression instanceof AST_Array && exp.property == "join") EXIT: { 22554 var separator; 22555 if (self.args.length > 0) { 22556 separator = self.args[0].evaluate(compressor); 22557 if (separator === self.args[0]) break EXIT; // not a constant 22558 } 22559 var elements = []; 22560 var consts = []; 22561 exp.expression.elements.forEach(function(el) { 22562 var value = el.evaluate(compressor); 22563 if (value !== el) { 22564 consts.push(value); 22565 } else { 22566 if (consts.length > 0) { 22567 elements.push(make_node(AST_String, self, { 22568 value: consts.join(separator) 22569 })); 22570 consts.length = 0; 22571 } 22572 elements.push(el); 22573 } 22574 }); 22575 if (consts.length > 0) { 22576 elements.push(make_node(AST_String, self, { 22577 value: consts.join(separator) 22578 })); 22579 } 22580 if (elements.length == 0) return make_node(AST_String, self, { value: "" }); 22581 if (elements.length == 1) { 22582 if (elements[0].is_string(compressor)) { 22583 return elements[0]; 22584 } 22585 return make_node(AST_Binary, elements[0], { 22586 operator : "+", 22587 left : make_node(AST_String, self, { value: "" }), 22588 right : elements[0] 22589 }); 22590 } 22591 if (separator == "") { 22592 var first; 22593 if (elements[0].is_string(compressor) 22594 || elements[1].is_string(compressor)) { 22595 first = elements.shift(); 22596 } else { 22597 first = make_node(AST_String, self, { value: "" }); 22598 } 22599 return elements.reduce(function(prev, el){ 22600 return make_node(AST_Binary, el, { 22601 operator : "+", 22602 left : prev, 22603 right : el 22604 }); 22605 }, first).optimize(compressor); 22606 } 22607 // need this awkward cloning to not affect original element 22608 // best_of will decide which one to get through. 22609 var node = self.clone(); 22610 node.expression = node.expression.clone(); 22611 node.expression.expression = node.expression.expression.clone(); 22612 node.expression.expression.elements = elements; 22613 return best_of(compressor, self, node); 22614 } 22615 else if (exp instanceof AST_Dot && exp.expression.is_string(compressor) && exp.property == "charAt") { 22616 var arg = self.args[0]; 22617 var index = arg ? arg.evaluate(compressor) : 0; 22618 if (index !== arg) { 22619 return make_node(AST_Sub, exp, { 22620 expression: exp.expression, 22621 property: make_node_from_constant(index | 0, arg || exp) 22622 }).optimize(compressor); 22623 } 22624 } 22625 } 22626 if (exp instanceof AST_Function) { 22627 if (exp.body[0] instanceof AST_Return) { 22628 var value = exp.body[0].value; 22629 if (!value || value.is_constant()) { 22630 var args = self.args.concat(value || make_node(AST_Undefined, self));
22631 return AST_Seq.from_array(args).transform(compressor); 22632 } 22633 } 22634 if (compressor.option("side_effects") && all(exp.body, is_empty)) { 22635 var args = self.args.concat(make_node(AST_Undefined, self)); 22636 return AST_Seq.from_array(args).transform(compressor); 22637 } 22638 } 22639 if (compressor.option("drop_console")) { 22640 if (exp instanceof AST_PropAccess) { 22641 var name = exp.expression; 22642 while (name.expression) { 22643 name = name.expression; 22644 } 22645 if (name instanceof AST_SymbolRef 22646 && name.name == "console" 22647 && name.undeclared()) { 22648 return make_node(AST_Undefined, self).optimize(compressor); 22649 } 22650 } 22651 } 22652 if (compressor.option("negate_iife") 22653 && compressor.parent() instanceof AST_SimpleStatement 22654 && is_iife_call(self)) { 22655 return self.negate(compressor, true); 22656 } 22657 return self; 22658 }); 22659 22660 OPT(AST_New, function(self, compressor){ 22661 if (compressor.option("unsafe")) { 22662 var exp = self.expression; 22663 if (exp instanceof AST_SymbolRef && exp.undeclared()) { 22664 switch (exp.name) { 22665 case "Object": 22666 case "RegExp": 22667 case "Function": 22668 case "Error": 22669 case "Array": 22670 return make_node(AST_Call, self, self).transform(compressor); 22671 } 22672 } 22673 } 22674 return self; 22675 }); 22676 22677 OPT(AST_Seq, function(self, compressor){ 22678 if (!compressor.option("side_effects")) 22679 return self; 22680 self.car = self.car.drop_side_effect_free(compressor, first_in_statement(compressor)); 22681 if (!self.car) return maintain_this_binding(compressor.parent(), self, self.cdr); 22682 if (compressor.option("cascade")) { 22683 var left; 22684 if (self.car instanceof AST_Assign 22685 && !self.car.left.has_side_effects(compressor)) { 22686 left = self.car.left; 22687 } else if (self.car instanceof AST_Unary 22688 && (self.car.operator == "++" || self.car.operator == "--")) { 22689 left = self.car.expression; 22690 } 22691 if (left 22692 && !(left instanceof AST_SymbolRef 22693 && (left.definition().orig[0] instanceof AST_SymbolLambda 22694 || is_reference_const(left)))) { 22695 var parent, field; 22696 var cdr = self.cdr; 22697 while (true) { 22698 if (cdr.equivalent_to(left)) { 22699 var car = self.car instanceof AST_UnaryPostfix ? make_node(AST_UnaryPrefix, self.car, { 22700 operator: self.car.operator, 22701 expression: left 22702 }) : self.car; 22703 if (parent) { 22704 parent[field] = car; 22705 return self.cdr; 22706 } 22707 return car; 22708 } 22709 if (cdr instanceof AST_Binary && !(cdr instanceof AST_Assign)) { 22710 if (cdr.left.is_constant()) { 22711 if (cdr.operator == "||" || cdr.operator == "&&") break; 22712 field = "right"; 22713 } else { 22714 field = "left"; 22715 } 22716 } else if (cdr instanceof AST_Call 22717 || cdr instanceof AST_Unary && !unary_side_effects(cdr.operator)) { 22718 field = "expression"; 22719 } else break; 22720 parent = cdr; 22721 cdr = cdr[field]; 22722 } 22723 } 22724 } 22725 if (is_undefined(self.cdr, compressor)) { 22726 return make_node(AST_UnaryPrefix, self, { 22727 operator : "void", 22728 expression : self.car 22729 }); 22730 } 22731 return self; 22732 });
22733 22734 AST_Unary.DEFMETHOD("lift_sequences", function(compressor){ 22735 if (compressor.option("sequences")) { 22736 if (this.expression instanceof AST_Seq) { 22737 var seq = this.expression; 22738 var x = seq.to_array(); 22739 var e = this.clone(); 22740 e.expression = x.pop(); 22741 x.push(e); 22742 seq = AST_Seq.from_array(x).transform(compressor); 22743 return seq; 22744 } 22745 } 22746 return this; 22747 }); 22748 22749 OPT(AST_UnaryPostfix, function(self, compressor){ 22750 return self.lift_sequences(compressor); 22751 }); 22752 22753 OPT(AST_UnaryPrefix, function(self, compressor){ 22754 var e = self.expression; 22755 if (self.operator == "delete" 22756 && !(e instanceof AST_SymbolRef 22757 || e instanceof AST_PropAccess 22758 || e instanceof AST_NaN 22759 || e instanceof AST_Infinity 22760 || e instanceof AST_Undefined)) { 22761 if (e instanceof AST_Seq) { 22762 e = e.to_array(); 22763 e.push(make_node(AST_True, self)); 22764 return AST_Seq.from_array(e).optimize(compressor); 22765 } 22766 return make_node(AST_Seq, self, { 22767 car: e, 22768 cdr: make_node(AST_True, self) 22769 }).optimize(compressor); 22770 } 22771 var seq = self.lift_sequences(compressor); 22772 if (seq !== self) { 22773 return seq; 22774 } 22775 if (compressor.option("side_effects") && self.operator == "void") { 22776 e = e.drop_side_effect_free(compressor); 22777 if (e) { 22778 self.expression = e; 22779 return self; 22780 } else { 22781 return make_node(AST_Undefined, self).optimize(compressor); 22782 } 22783 } 22784 if (compressor.option("booleans") && compressor.in_boolean_context()) { 22785 switch (self.operator) { 22786 case "!": 22787 if (e instanceof AST_UnaryPrefix && e.operator == "!") { 22788 // !!foo ==> foo, if we're in boolean context 22789 return e.expression; 22790 } 22791 if (e instanceof AST_Binary) { 22792 self = best_of(compressor, self, e.negate(compressor, first_in_statement(compressor))); 22793 } 22794 break; 22795 case "typeof": 22796 // typeof always returns a non-empty string, thus it's 22797 // always true in booleans 22798 compressor.warn("Boolean expression always true [{file}:{line},{col}]", self.start); 22799 return (e instanceof AST_SymbolRef ? make_node(AST_True, self) : make_node(AST_Seq, self, { 22800 car: e, 22801 cdr: make_node(AST_True, self) 22802 })).optimize(compressor); 22803 } 22804 } 22805 if (self.operator == "-" && e instanceof AST_Infinity) { 22806 e = e.transform(compressor); 22807 } 22808 if (e instanceof AST_Binary 22809 && (self.operator == "+" || self.operator == "-") 22810 && (e.operator == "*" || e.operator == "/" || e.operator == "%")) { 22811 return make_node(AST_Binary, self, { 22812 operator: e.operator, 22813 left: make_node(AST_UnaryPrefix, e.left, { 22814 operator: self.operator, 22815 expression: e.left 22816 }), 22817 right: e.right 22818 }); 22819 } 22820 // avoids infinite recursion of numerals 22821 if (self.operator != "-" 22822 || !(e instanceof AST_Number || e instanceof AST_Infinity)) { 22823 var ev = self.evaluate(compressor); 22824 if (ev !== self) { 22825 ev = make_node_from_constant(ev, self).optimize(compressor); 22826 return best_of(compressor, ev, self); 22827 } 22828 } 22829 return self; 22830 }); 22831 22832 AST_Binary.DEFMETHOD("lift_sequences", function(compressor){ 22833 if (compressor.option("sequences")) { 22834 if (this.left instanceof AST_Seq) { 22835 var seq = this.left; 22836 var x = seq.to_array(); 22837 var e = this.clone(); 22838 e.left = x.pop(); 22839 x.push(e); 22840 return AST_Seq.from_array(x).optimize(compressor); 22841 } 22842 if (this.right instanceof AST_Seq && !this.left.has_side_effects(compressor)) { 22843 var assign = this.operator == "=" && this.left instanceof AST_SymbolRef; 22844 var root = this.right.clone(); 22845 var cursor, seq = root; 22846 while (assign || !seq.car.has_side_effects(compressor)) { 22847 cursor = seq; 22848 if (seq.cdr instanceof AST_Seq) { 22849 seq = seq.cdr = seq.cdr.clone(); 22850 } else break; 22851 } 22852 if (cursor) { 22853 var e = this.clone();
vendor: 16,384 bytes, lines 22854-23183
22854 e.right = cursor.cdr; 22855 cursor.cdr = e; 22856 return root.optimize(compressor); 22857 } 22858 } 22859 } 22860 return this; 22861 }); 22862 22863 var commutativeOperators = makePredicate("== === != !== * & | ^"); 22864 22865 OPT(AST_Binary, function(self, compressor){ 22866 function reversible() { 22867 return self.left.is_constant() 22868 || self.right.is_constant() 22869 || !self.left.has_side_effects(compressor) 22870 && !self.right.has_side_effects(compressor); 22871 } 22872 function reverse(op) { 22873 if (reversible()) { 22874 if (op) self.operator = op; 22875 var tmp = self.left; 22876 self.left = self.right; 22877 self.right = tmp; 22878 } 22879 } 22880 if (commutativeOperators(self.operator)) { 22881 if (self.right.is_constant() 22882 && !self.left.is_constant()) { 22883 // if right is a constant, whatever side effects the 22884 // left side might have could not influence the 22885 // result. hence, force switch. 22886 22887 if (!(self.left instanceof AST_Binary 22888 && PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) { 22889 reverse(); 22890 } 22891 } 22892 } 22893 self = self.lift_sequences(compressor); 22894 if (compressor.option("comparisons")) switch (self.operator) { 22895 case "===": 22896 case "!==": 22897 if ((self.left.is_string(compressor) && self.right.is_string(compressor)) || 22898 (self.left.is_number(compressor) && self.right.is_number(compressor)) || 22899 (self.left.is_boolean() && self.right.is_boolean())) { 22900 self.operator = self.operator.substr(0, 2); 22901 } 22902 // XXX: intentionally falling down to the next case 22903 case "==": 22904 case "!=": 22905 // "undefined" == typeof x => undefined === x 22906 if (self.left instanceof AST_String 22907 && self.left.value == "undefined" 22908 && self.right instanceof AST_UnaryPrefix 22909 && self.right.operator == "typeof") { 22910 var expr = self.right.expression; 22911 if (expr instanceof AST_SymbolRef ? !expr.undeclared() 22912 : !(expr instanceof AST_PropAccess) || compressor.option("screw_ie8")) { 22913 self.right = expr; 22914 self.left = make_node(AST_Undefined, self.left).optimize(compressor); 22915 if (self.operator.length == 2) self.operator += "="; 22916 } 22917 } 22918 break; 22919 } 22920 if (compressor.option("booleans") && self.operator == "+" && compressor.in_boolean_context()) { 22921 var ll = self.left.evaluate(compressor); 22922 var rr = self.right.evaluate(compressor); 22923 if (ll && typeof ll == "string") { 22924 compressor.warn("+ in boolean context always true [{file}:{line},{col}]", self.start); 22925 return make_node(AST_Seq, self, { 22926 car: self.right, 22927 cdr: make_node(AST_True, self) 22928 }).optimize(compressor); 22929 } 22930 if (rr && typeof rr == "string") { 22931 compressor.warn("+ in boolean context always true [{file}:{line},{col}]", self.start); 22932 return make_node(AST_Seq, self, { 22933 car: self.left, 22934 cdr: make_node(AST_True, self) 22935 }).optimize(compressor); 22936 } 22937 } 22938 if (compressor.option("comparisons") && self.is_boolean()) { 22939 if (!(compressor.parent() instanceof AST_Binary) 22940 || compressor.parent() instanceof AST_Assign) { 22941 var negated = make_node(AST_UnaryPrefix, self, { 22942 operator: "!", 22943 expression: self.negate(compressor, first_in_statement(compressor)) 22944 }); 22945 self = best_of(compressor, self, negated); 22946 } 22947 if (compressor.option("unsafe_comps")) { 22948 switch (self.operator) { 22949 case "<": reverse(">"); break; 22950 case "<=": reverse(">="); break; 22951 } 22952 } 22953 } 22954 if (self.operator == "+") { 22955 if (self.right instanceof AST_String 22956 && self.right.getValue() == "" 22957 && self.left.is_string(compressor)) { 22958 return self.left; 22959 } 22960 if (self.left instanceof AST_String 22961 && self.left.getValue() == "" 22962 && self.right.is_string(compressor)) { 22963 return self.right; 22964 } 22965 if (self.left instanceof AST_Binary 22966 && self.left.operator == "+" 22967 && self.left.left instanceof AST_String 22968 && self.left.left.getValue() == "" 22969 && self.right.is_string(compressor)) { 22970 self.left = self.left.right; 22971 return self.transform(compressor); 22972 } 22973 } 22974 if (compressor.option("evaluate")) { 22975 switch (self.operator) { 22976 case "&&": 22977 var ll = self.left.evaluate(compressor); 22978 if (!ll) { 22979 compressor.warn("Condition left of && always false [{file}:{line},{col}]", self.start); 22980 return maintain_this_binding(compressor.parent(), self, self.left).optimize(compressor); 22981 } else if (ll !== self.left) { 22982 compressor.warn("Condition left of && always true [{file}:{line},{col}]", self.start); 22983 return maintain_this_binding(compressor.parent(), self, self.right).optimize(compressor); 22984 } 22985 if (compressor.option("booleans") && compressor.in_boolean_context()) { 22986 var rr = self.right.evaluate(compressor); 22987 if (!rr) { 22988 compressor.warn("Boolean && always false [{file}:{line},{col}]", self.start); 22989 return make_node(AST_Seq, self, { 22990 car: self.left, 22991 cdr: make_node(AST_False, self) 22992 }).optimize(compressor); 22993 } else if (rr !== self.right) { 22994 compressor.warn("Dropping side-effect-free && in boolean context [{file}:{line},{col}]", self.start); 22995 return self.left.optimize(compressor); 22996 } 22997 } 22998 break; 22999 case "||": 23000 var ll = self.left.evaluate(compressor); 23001 if (!ll) { 23002 compressor.warn("Condition left of || always false [{file}:{line},{col}]", self.start); 23003 return maintain_this_binding(compressor.parent(), self, self.right).optimize(compressor); 23004 } else if (ll !== self.left) { 23005 compressor.warn("Condition left of || always true [{file}:{line},{col}]", self.start); 23006 return maintain_this_binding(compressor.parent(), self, self.left).optimize(compressor); 23007 } 23008 if (compressor.option("booleans") && compressor.in_boolean_context()) { 23009 var rr = self.right.evaluate(compressor); 23010 if (!rr) { 23011 compressor.warn("Dropping side-effect-free || in boolean context [{file}:{line},{col}]", self.start); 23012 return self.left.optimize(compressor); 23013 } else if (rr !== self.right) { 23014 compressor.warn("Boolean || always true [{file}:{line},{col}]", self.start); 23015 return make_node(AST_Seq, self, { 23016 car: self.left, 23017 cdr: make_node(AST_True, self) 23018 }).optimize(compressor); 23019 } 23020 } 23021 break; 23022 } 23023 var associative = true; 23024 switch (self.operator) { 23025 case "+": 23026 // "foo" + ("bar" + x) => "foobar" + x 23027 if (self.left instanceof AST_Constant 23028 && self.right instanceof AST_Binary 23029 && self.right.operator == "+" 23030 && self.right.left instanceof AST_Constant 23031 && self.right.is_string(compressor)) { 23032 self = make_node(AST_Binary, self, { 23033 operator: "+", 23034 left: make_node(AST_String, self.left, { 23035 value: "" + self.left.getValue() + self.right.left.getValue(), 23036 start: self.left.start, 23037 end: self.right.left.end 23038 }), 23039 right: self.right.right 23040 }); 23041 } 23042 // (x + "foo") + "bar" => x + "foobar" 23043 if (self.right instanceof AST_Constant 23044 && self.left instanceof AST_Binary 23045 && self.left.operator == "+" 23046 && self.left.right instanceof AST_Constant 23047 && self.left.is_string(compressor)) { 23048 self = make_node(AST_Binary, self, { 23049 operator: "+", 23050 left: self.left.left, 23051 right: make_node(AST_String, self.right, { 23052 value: "" + self.left.right.getValue() + self.right.getValue(), 23053 start: self.left.right.start, 23054 end: self.right.end 23055 }) 23056 }); 23057 } 23058 // (x + "foo") + ("bar" + y) => (x + "foobar") + y 23059 if (self.left instanceof AST_Binary 23060 && self.left.operator == "+" 23061 && self.left.is_string(compressor) 23062 && self.left.right instanceof AST_Constant 23063 && self.right instanceof AST_Binary 23064 && self.right.operator == "+" 23065 && self.right.left instanceof AST_Constant 23066 && self.right.is_string(compressor)) { 23067 self = make_node(AST_Binary, self, { 23068 operator: "+", 23069 left: make_node(AST_Binary, self.left, { 23070 operator: "+", 23071 left: self.left.left, 23072 right: make_node(AST_String, self.left.right, { 23073 value: "" + self.left.right.getValue() + self.right.left.getValue(), 23074 start: self.left.right.start, 23075 end: self.right.left.end 23076 }) 23077 }), 23078 right: self.right.right 23079 }); 23080 } 23081 // a + -b => a - b 23082 if (self.right instanceof AST_UnaryPrefix 23083 && self.right.operator == "-" 23084 && self.left.is_number(compressor)) { 23085 self = make_node(AST_Binary, self, { 23086 operator: "-", 23087 left: self.left, 23088 right: self.right.expression 23089 }); 23090 break; 23091 } 23092 // -a + b => b - a 23093 if (self.left instanceof AST_UnaryPrefix 23094 && self.left.operator == "-" 23095 && reversible() 23096 && self.right.is_number(compressor)) { 23097 self = make_node(AST_Binary, self, { 23098 operator: "-", 23099 left: self.right, 23100 right: self.left.expression 23101 }); 23102 break; 23103 } 23104 case "*": 23105 associative = compressor.option("unsafe_math"); 23106 case "&": 23107 case "|": 23108 case "^": 23109 // a + +b => +b + a 23110 if (self.left.is_number(compressor) 23111 && self.right.is_number(compressor) 23112 && reversible() 23113 && !(self.left instanceof AST_Binary 23114 && self.left.operator != self.operator 23115 && PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) { 23116 var reversed = make_node(AST_Binary, self, { 23117 operator: self.operator, 23118 left: self.right, 23119 right: self.left 23120 }); 23121 if (self.right instanceof AST_Constant 23122 && !(self.left instanceof AST_Constant)) { 23123 self = best_of(compressor, reversed, self); 23124 } else { 23125 self = best_of(compressor, self, reversed); 23126 } 23127 } 23128 if (associative && self.is_number(compressor)) { 23129 // a + (b + c) => (a + b) + c 23130 if (self.right instanceof AST_Binary 23131 && self.right.operator == self.operator) { 23132 self = make_node(AST_Binary, self, { 23133 operator: self.operator, 23134 left: make_node(AST_Binary, self.left, { 23135 operator: self.operator, 23136 left: self.left, 23137 right: self.right.left, 23138 start: self.left.start, 23139 end: self.right.left.end 23140 }), 23141 right: self.right.right 23142 }); 23143 } 23144 // (n + 2) + 3 => 5 + n 23145 // (2 * n) * 3 => 6 + n 23146 if (self.right instanceof AST_Constant 23147 && self.left instanceof AST_Binary 23148 && self.left.operator == self.operator) { 23149 if (self.left.left instanceof AST_Constant) { 23150 self = make_node(AST_Binary, self, { 23151 operator: self.operator, 23152 left: make_node(AST_Binary, self.left, { 23153 operator: self.operator, 23154 left: self.left.left, 23155 right: self.right, 23156 start: self.left.left.start, 23157 end: self.right.end 23158 }), 23159 right: self.left.right 23160 }); 23161 } else if (self.left.right instanceof AST_Constant) { 23162 self = make_node(AST_Binary, self, { 23163 operator: self.operator, 23164 left: make_node(AST_Binary, self.left, { 23165 operator: self.operator, 23166 left: self.left.right, 23167 right: self.right, 23168 start: self.left.right.start, 23169 end: self.right.end 23170 }), 23171 right: self.left.left 23172 }); 23173 } 23174 } 23175 // (a | 1) | (2 | d) => (3 | a) | b 23176 if (self.left instanceof AST_Binary 23177 && self.left.operator == self.operator 23178 && self.left.right instanceof AST_Constant 23179 && self.right instanceof AST_Binary 23180 && self.right.operator == self.operator 23181 && self.right.left instanceof AST_Constant) { 23182 self = make_node(AST_Binary, self, { 23183
23183 operator: self.operator, 23184 left: make_node(AST_Binary, self.left, { 23185 operator: self.operator, 23186 left: make_node(AST_Binary, self.left.left, { 23187 operator: self.operator, 23188 left: self.left.right, 23189 right: self.right.left, 23190 start: self.left.right.start, 23191 end: self.right.left.end 23192 }), 23193 right: self.left.left 23194 }), 23195 right: self.right.right 23196 }); 23197 } 23198 } 23199 } 23200 } 23201 // x && (y && z) ==> x && y && z 23202 // x || (y || z) ==> x || y || z 23203 // x + ("y" + z) ==> x + "y" + z 23204 // "x" + (y + "z")==> "x" + y + "z" 23205 if (self.right instanceof AST_Binary 23206 && self.right.operator == self.operator 23207 && (self.operator == "&&" 23208 || self.operator == "||" 23209 || (self.operator == "+" 23210 && (self.right.left.is_string(compressor) 23211 || (self.left.is_string(compressor) 23212 && self.right.right.is_string(compressor)))))) 23213 { 23214 self.left = make_node(AST_Binary, self.left, { 23215 operator : self.operator, 23216 left : self.left, 23217 right : self.right.left 23218 }); 23219 self.right = self.right.right; 23220 return self.transform(compressor); 23221 } 23222 var ev = self.evaluate(compressor); 23223 if (ev !== self) { 23224 ev = make_node_from_constant(ev, self).optimize(compressor); 23225 return best_of(compressor, ev, self); 23226 } 23227 return self; 23228 }); 23229 23230 OPT(AST_SymbolRef, function(self, compressor){ 23231 var def = self.resolve_defines(compressor); 23232 if (def) { 23233 return def.optimize(compressor); 23234 } 23235 // testing against !self.scope.uses_with first is an optimization 23236 if (compressor.option("screw_ie8") 23237 && self.undeclared() 23238 && (!self.scope.uses_with || !compressor.find_parent(AST_With))) { 23239 switch (self.name) { 23240 case "undefined": 23241 return make_node(AST_Undefined, self).optimize(compressor); 23242 case "NaN": 23243 return make_node(AST_NaN, self).optimize(compressor); 23244 case "Infinity": 23245 return make_node(AST_Infinity, self).optimize(compressor); 23246 } 23247 } 23248 if (compressor.option("evaluate") 23249 && compressor.option("reduce_vars") 23250 && is_lhs(self, compressor.parent()) !== self) { 23251 var d = self.definition(); 23252 var fixed = self.fixed_value(); 23253 if (fixed) { 23254 if (d.should_replace === undefined) { 23255 var init = fixed.evaluate(compressor); 23256 if (init !== fixed && (compressor.option("unsafe_regexp") || !(init instanceof RegExp))) { 23257 init = make_node_from_constant(init, fixed); 23258 var value = init.optimize(compressor).print_to_string().length; 23259 var fn; 23260 if (has_symbol_ref(fixed)) { 23261 fn = function() { 23262 var result = init.optimize(compressor); 23263 return result === init ? result.clone(true) : result; 23264 }; 23265 } else { 23266 value = Math.min(value, fixed.print_to_string().length); 23267 fn = function() { 23268 var result = best_of_expression(init.optimize(compressor), fixed); 23269 return result === init || result === fixed ? result.clone(true) : result; 23270 }; 23271 } 23272 var name = d.name.length; 23273 var overhead = 0; 23274 if (compressor.option("unused") && (!d.global || compressor.option("toplevel"))) { 23275 overhead = (name + 2 + value) / d.references.length; 23276 } 23277 d.should_replace = value <= name + overhead ? fn : false; 23278 } else { 23279 d.should_replace = false; 23280 } 23281 } 23282 if (d.should_replace) { 23283 return d.should_replace(); 23284 } 23285 } 23286 } 23287 return self; 23288 23289 function has_symbol_ref(value) { 23290 var found; 23291 value.walk(new TreeWalker(function(node) { 23292 if (node instanceof AST_SymbolRef) found = true; 23293 if (found) return true; 23294 })); 23295 return found; 23296 } 23297 });
23298 23299 function is_atomic(lhs, self) { 23300 return lhs instanceof AST_SymbolRef || lhs.TYPE === self.TYPE; 23301 } 23302 23303 OPT(AST_Undefined, function(self, compressor){ 23304 if (compressor.option("unsafe")) { 23305 var undef = find_variable(compressor, "undefined"); 23306 if (undef) { 23307 var ref = make_node(AST_SymbolRef, self, { 23308 name : "undefined", 23309 scope : undef.scope, 23310 thedef : undef 23311 }); 23312 ref.is_undefined = true; 23313 return ref; 23314 } 23315 } 23316 var lhs = is_lhs(compressor.self(), compressor.parent()); 23317 if (lhs && is_atomic(lhs, self)) return self; 23318 return make_node(AST_UnaryPrefix, self, { 23319 operator: "void", 23320 expression: make_node(AST_Number, self, { 23321 value: 0 23322 }) 23323 }); 23324 }); 23325 23326 OPT(AST_Infinity, function(self, compressor){ 23327 var lhs = is_lhs(compressor.self(), compressor.parent()); 23328 if (lhs && is_atomic(lhs, self)) return self; 23329 if (compressor.option("keep_infinity") 23330 && !(lhs && !is_atomic(lhs, self)) 23331 && !find_variable(compressor, "Infinity")) 23332 return self; 23333 return make_node(AST_Binary, self, { 23334 operator: "/", 23335 left: make_node(AST_Number, self, { 23336 value: 1 23337 }), 23338 right: make_node(AST_Number, self, { 23339 value: 0 23340 }) 23341 }); 23342 }); 23343 23344 OPT(AST_NaN, function(self, compressor){ 23345 var lhs = is_lhs(compressor.self(), compressor.parent()); 23346 if (lhs && !is_atomic(lhs, self) 23347 || find_variable(compressor, "NaN")) { 23348 return make_node(AST_Binary, self, { 23349 operator: "/", 23350 left: make_node(AST_Number, self, { 23351 value: 0 23352 }), 23353 right: make_node(AST_Number, self, { 23354 value: 0 23355 }) 23356 }); 23357 } 23358 return self; 23359 }); 23360 23361 var ASSIGN_OPS = [ '+', '-', '/', '*', '%', '>>', '<<', '>>>', '|', '^', '&' ]; 23362 var ASSIGN_OPS_COMMUTATIVE = [ '*', '|', '^', '&' ]; 23363 OPT(AST_Assign, function(self, compressor){ 23364 self = self.lift_sequences(compressor); 23365 if (self.operator == "=" && self.left instanceof AST_SymbolRef && self.right instanceof AST_Binary) { 23366 // x = expr1 OP expr2 23367 if (self.right.left instanceof AST_SymbolRef 23368 && self.right.left.name == self.left.name 23369 && member(self.right.operator, ASSIGN_OPS)) { 23370 // x = x - 2 ---> x -= 2 23371 self.operator = self.right.operator + "="; 23372 self.right = self.right.right; 23373 } 23374 else if (self.right.right instanceof AST_SymbolRef 23375 && self.right.right.name == self.left.name 23376 && member(self.right.operator, ASSIGN_OPS_COMMUTATIVE) 23377 && !self.right.left.has_side_effects(compressor)) { 23378 // x = 2 & x ---> x &= 2 23379 self.operator = self.right.operator + "="; 23380 self.right = self.right.left; 23381 } 23382 } 23383 return self; 23384 }); 23385 23386 OPT(AST_Conditional, function(self, compressor){ 23387 if (!compressor.option("conditionals")) return self; 23388 if (self.condition instanceof AST_Seq) { 23389 var car = self.condition.car; 23390 self.condition = self.condition.cdr; 23391 return AST_Seq.cons(car, self); 23392 } 23393 var cond = self.condition.evaluate(compressor); 23394 if (cond !== self.condition) { 23395 if (cond) { 23396 compressor.warn("Condition always true [{file}:{line},{col}]", self.start); 23397 return maintain_this_binding(compressor.parent(), self, self.consequent); 23398 } else { 23399 compressor.warn("Condition always false [{file}:{line},{col}]", self.start); 23400 return maintain_this_binding(compressor.parent(), self, self.alternative); 23401 } 23402 } 23403 var negated = cond.negate(compressor, first_in_statement
vendor: 5,728 bytes, lines 23403-23548
23403(compressor)); 23404 if (best_of(compressor, cond, negated) === negated) { 23405 self = make_node(AST_Conditional, self, { 23406 condition: negated, 23407 consequent: self.alternative, 23408 alternative: self.consequent 23409 }); 23410 } 23411 var condition = self.condition; 23412 var consequent = self.consequent; 23413 var alternative = self.alternative; 23414 // x?x:y --> x||y 23415 if (condition instanceof AST_SymbolRef 23416 && consequent instanceof AST_SymbolRef 23417 && condition.definition() === consequent.definition()) { 23418 return make_node(AST_Binary, self, { 23419 operator: "||", 23420 left: condition, 23421 right: alternative 23422 }); 23423 } 23424 // if (foo) exp = something; else exp = something_else; 23425 // | 23426 // v 23427 // exp = foo ? something : something_else; 23428 if (consequent instanceof AST_Assign 23429 && alternative instanceof AST_Assign 23430 && consequent.operator == alternative.operator 23431 && consequent.left.equivalent_to(alternative.left) 23432 && (!self.condition.has_side_effects(compressor) 23433 || consequent.operator == "=" 23434 && !consequent.left.has_side_effects(compressor))) { 23435 return make_node(AST_Assign, self, { 23436 operator: consequent.operator, 23437 left: consequent.left, 23438 right: make_node(AST_Conditional, self, { 23439 condition: self.condition, 23440 consequent: consequent.right, 23441 alternative: alternative.right 23442 }) 23443 }); 23444 } 23445 // x ? y(a) : y(b) --> y(x ? a : b) 23446 if (consequent instanceof AST_Call 23447 && alternative.TYPE === consequent.TYPE 23448 && consequent.args.length == 1 23449 && alternative.args.length == 1 23450 && consequent.expression.equivalent_to(alternative.expression) 23451 && !consequent.expression.has_side_effects(compressor)) { 23452 consequent.args[0] = make_node(AST_Conditional, self, { 23453 condition: self.condition, 23454 consequent: consequent.args[0], 23455 alternative: alternative.args[0] 23456 }); 23457 return consequent; 23458 } 23459 // x?y?z:a:a --> x&&y?z:a 23460 if (consequent instanceof AST_Conditional 23461 && consequent.alternative.equivalent_to(alternative)) { 23462 return make_node(AST_Conditional, self, { 23463 condition: make_node(AST_Binary, self, { 23464 left: self.condition, 23465 operator: "&&", 23466 right: consequent.condition 23467 }), 23468 consequent: consequent.consequent, 23469 alternative: alternative 23470 }); 23471 } 23472 // x ? y : y --> x, y 23473 if (consequent.equivalent_to(alternative)) { 23474 return make_node(AST_Seq, self, { 23475 car: self.condition, 23476 cdr: consequent 23477 }).optimize(compressor); 23478 } 23479 23480 if (is_true(self.consequent)) { 23481 if (is_false(self.alternative)) { 23482 // c ? true : false ---> !!c 23483 return booleanize(self.condition); 23484 } 23485 // c ? true : x ---> !!c || x 23486 return make_node(AST_Binary, self, { 23487 operator: "||", 23488 left: booleanize(self.condition), 23489 right: self.alternative 23490 }); 23491 } 23492 if (is_false(self.consequent)) { 23493 if (is_true(self.alternative)) { 23494 // c ? false : true ---> !c 23495 return booleanize(self.condition.negate(compressor)); 23496 } 23497 // c ? false : x ---> !c && x 23498 return make_node(AST_Binary, self, { 23499 operator: "&&", 23500 left: booleanize(self.condition.negate(compressor)), 23501 right: self.alternative 23502 }); 23503 } 23504 if (is_true(self.alternative)) { 23505 // c ? x : true ---> !c || x 23506 return make_node(AST_Binary, self, { 23507 operator: "||", 23508 left: booleanize(self.condition.negate(compressor)), 23509 right: self.consequent 23510 }); 23511 } 23512 if (is_false(self.alternative)) { 23513 // c ? x : false ---> !!c && x 23514 return make_node(AST_Binary, self, { 23515 operator: "&&", 23516 left: booleanize(self.condition), 23517 right: self.consequent 23518 }); 23519 } 23520 23521 return self; 23522 23523 function booleanize(node) { 23524 if (node.is_boolean()) return node; 23525 // !!expression 23526 return make_node(AST_UnaryPrefix, node, { 23527 operator: "!", 23528 expression: node.negate(compressor) 23529 }); 23530 } 23531 23532 // AST_True or !0 23533 function is_true(node) { 23534 return node instanceof AST_True 23535 || (node instanceof AST_UnaryPrefix 23536 && node.operator == "!" 23537 && node.expression instanceof AST_Constant 23538 && !node.expression.value); 23539 } 23540 // AST_False or !1 23541 function is_false(node) { 23542 return node instanceof AST_False 23543 || (node instanceof AST_UnaryPrefix 23544 && node.operator == "!" 23545 && node.expression instanceof AST_Constant 23546 && !!node.expression.value); 23547 } 23548 });
23549 23550 OPT(AST_Boolean, function(self, compressor){ 23551 if (compressor.option("booleans")) { 23552 var p = compressor.parent(); 23553 if (p instanceof AST_Binary && (p.operator == "==" 23554 || p.operator == "!=")) { 23555 compressor.warn("Non-strict equality against boolean: {operator} {value} [{file}:{line},{col}]", { 23556 operator : p.operator, 23557 value : self.value, 23558 file : p.start.file, 23559 line : p.start.line, 23560 col : p.start.col, 23561 }); 23562 return make_node(AST_Number, self, { 23563 value: +self.value 23564 }); 23565 } 23566 return make_node(AST_UnaryPrefix, self, { 23567 operator: "!", 23568 expression: make_node(AST_Number, self, { 23569 value: 1 - self.value 23570 }) 23571 }); 23572 } 23573 return self; 23574 }); 23575 23576 OPT(AST_Sub, function(self, compressor){ 23577 var prop = self.property; 23578 if (prop instanceof AST_String && compressor.option("properties")) { 23579 prop = prop.getValue(); 23580 if (RESERVED_WORDS(prop) ? compressor.option("screw_ie8") : is_identifier_string(prop)) { 23581 return make_node(AST_Dot, self, { 23582 expression : self.expression, 23583 property : prop 23584 }).optimize(compressor); 23585 } 23586 var v = parseFloat(prop); 23587 if (!isNaN(v) && v.toString() == prop) { 23588 self.property = make_node(AST_Number, self.property, { 23589 value: v 23590 }); 23591 } 23592 } 23593 var ev = self.evaluate(compressor); 23594 if (ev !== self) { 23595 ev = make_node_from_constant(ev, self).optimize(compressor); 23596 return best_of(compressor, ev, self); 23597 } 23598 return self; 23599 }); 23600 23601 OPT(AST_Dot, function(self, compressor){ 23602 var def = self.resolve_defines(compressor); 23603 if (def) { 23604 return def.optimize(compressor); 23605 } 23606 var prop = self.property; 23607 if (RESERVED_WORDS(prop) && !compressor.option("screw_ie8")) { 23608 return make_node(AST_Sub, self, { 23609 expression : self.expression, 23610 property : make_node(AST_String, self, { 23611 value: prop 23612 }) 23613 }).optimize(compressor); 23614 } 23615 if (compressor.option("unsafe_proto") 23616 && self.expression instanceof AST_Dot 23617 && self.expression.property == "prototype") { 23618 var exp = self.expression.expression; 23619 if (exp instanceof AST_SymbolRef && exp.undeclared()) switch (exp.name) { 23620 case "Array": 23621 self.expression = make_node(AST_Array, self.expression, { 23622 elements: [] 23623 }); 23624 break; 23625 case "Object": 23626 self.expression = make_node(AST_Object, self.expression, { 23627 properties: [] 23628 }); 23629 break; 23630 case "String": 23631 self.expression = make_node(AST_String, self.expression, { 23632 value: "" 23633 }); 23634 break; 23635 } 23636 } 23637 var ev = self.evaluate(compressor); 23638 if (ev !== self) { 23639 ev = make_node_from_constant(ev, self).optimize(compressor); 23640 return best_of(compressor, ev, self); 23641 } 23642 return self; 23643 }); 23644 23645 function literals_in_boolean_context(self, compressor) { 23646 if (compressor.option("booleans") && compressor.in_boolean_context()) { 23647 return best_of(compressor, self, make_node(AST_Seq, self, { 23648 car: self, 23649 cdr: make_node(AST_True, self) 23650 }).optimize(compressor)); 23651 } 23652 return self; 23653 }; 23654 OPT(AST_Array, literals_in_boolean_context); 23655 OPT(AST_Object, literals_in_boolean_context); 23656 OPT(AST_RegExp, literals_in_boolean_context); 23657 23658 OPT(AST_Return, function(self, compressor){ 23659 if (self.value && is_undefined(self.value, compressor)) { 23660 self.value = null; 23661 } 23662 return self; 23663 });
23664 23665 OPT(AST_VarDef, function(self, compressor){ 23666 var defines = compressor.option("global_defs"); 23667 if (defines && HOP(defines, self.name.name)) { 23668 compressor.warn('global_defs ' + self.name.name + ' redefined [{file}:{line},{col}]', self.start); 23669 } 23670 return self; 23671 }); 23672 23673})(); 23674 23675/*********************************************************************** 23676 23677 A JavaScript tokenizer / parser / beautifier / compressor. 23678 https://github.com/mishoo/UglifyJS2 23679 23680 -------------------------------- (C) --------------------------------- 23681 23682 Author: Mihai Bazon 23683 <[email protected]> 23684 http://mihai.bazon.net/blog 23685 23686 Distributed under the BSD license: 23687 23688 Copyright 2012 (c) Mihai Bazon <[email protected]> 23689 23690 Redistribution and use in source and binary forms, with or without 23691 modification, are permitted provided that the following conditions 23692 are met: 23693 23694 * Redistributions of source code must retain the above 23695 copyright notice, this list of conditions and the following 23696 disclaimer. 23697 23698 * Redistributions in binary form must reproduce the above 23699 copyright notice, this list of conditions and the following 23700 disclaimer in the documentation and/or other materials 23701 provided with the distribution. 23702 23703 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER âAS ISâ AND ANY 23704 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23705 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23706 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE 23707 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 23708 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23709 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23710 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23711 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 23712 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 23713 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23714 SUCH DAMAGE. 23715 23716 ***********************************************************************/ 23717 23718"use strict"; 23719 23720// a small wrapper around fitzgen's source-map library 23721function SourceMap(options) { 23722 options = defaults(options, { 23723 file : null, 23724 root : null, 23725 orig : null, 23726 23727 orig_line_diff : 0, 23728 dest_line_diff : 0, 23729 }); 23730 var generator = new MOZ_SourceMap.SourceMapGenerator({ 23731 file : options.file, 23732 sourceRoot : options.root 23733 }); 23734 var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig); 23735 23736 if (orig_map && Array.isArray(options.orig.sources)) { 23737 orig_map._sources.toArray().forEach(function(source) { 23738 var sourceContent = orig_map.sourceContentFor(source, true); 23739 if (sourceContent) { 23740 generator.setSourceContent(source, sourceContent); 23741 } 23742 }); 23743 } 23744 23745 function add(source, gen_line, gen_col, orig_line, orig_col, name) { 23746 if (orig_map) { 23747 var info = orig_map.originalPositionFor({ 23748 line: orig_line, 23749 column: orig_col 23750 }); 23751 if (info.source === null) { 23752 return; 23753 } 23754 source = info.source; 23755 orig_line = info.line; 23756 orig_col = info.column; 23757 name = info.name || name; 23758 } 23759 generator.addMapping({ 23760 generated : { line: gen_line + options.dest_line_diff, column: gen_col }, 23761 original : { line: orig_line + options.orig_line_diff, column: orig_col }, 23762 source : source, 23763 name : name 23764 }); 23765 }; 23766 return { 23767 add : add, 23768 get : function() { return generator }, 23769 toString : function() { return JSON.stringify(generator.toJSON()); } 23770 }; 23771};
23772 23773/*********************************************************************** 23774 23775 A JavaScript tokenizer / parser / beautifier / compressor. 23776 https://github.com/mishoo/UglifyJS2 23777 23778 -------------------------------- (C) --------------------------------- 23779 23780 Author: Mihai Bazon 23781 <[email protected]> 23782 http://mihai.bazon.net/blog 23783 23784 Distributed under the BSD license: 23785 23786 Copyright 2012 (c) Mihai Bazon <[email protected]> 23787 23788 Redistribution and use in source and binary forms, with or without 23789 modification, are permitted provided that the following conditions 23790 are met: 23791 23792 * Redistributions of source code must retain the above 23793 copyright notice, this list of conditions and the following 23794 disclaimer. 23795 23796 * Redistributions in binary form must reproduce the above 23797 copyright notice, this list of conditions and the following 23798 disclaimer in the documentation and/or other materials 23799 provided with the distribution. 23800 23801 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER âAS ISâ AND ANY 23802 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23803 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23804 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE 23805 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 23806 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23807 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23808 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23809 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 23810 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 23811 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23812 SUCH DAMAGE. 23813 23814 ***********************************************************************/ 23815 23816"use strict"; 23817 23818(function(){ 23819 23820 var normalize_directives = function(body) { 23821 var in_directive = true; 23822 23823 for (var i = 0; i < body.length; i++) { 23824 if (in_directive && body[i] instanceof AST_Statement && body[i].body instanceof AST_String) { 23825 body[i] = new AST_Directive({ 23826 start: body[i].start, 23827 end: body[i].end, 23828 value: body[i].body.value 23829 }); 23830 } else if (in_directive && !(body[i] instanceof AST_Statement && body[i].body instanceof AST_String)) { 23831 in_directive = false; 23832 } 23833 } 23834 23835 return body; 23836 }; 23837 23838 var MOZ_TO_ME = { 23839 Program: function(M) { 23840 return new AST_Toplevel({ 23841 start: my_start_token(M), 23842 end: my_end_token(M), 23843 body: normalize_directives(M.body.map(from_moz)) 23844 }); 23845 }, 23846 FunctionDeclaration: function(M) { 23847 return new AST_Defun({ 23848 start: my_start_token(M), 23849 end: my_end_token(M), 23850 name: from_moz(M.id), 23851 argnames: M.params.map(from_moz), 23852 body: normalize_directives(from_moz(M.body).body) 23853 }); 23854 }, 23855 FunctionExpression: function(M) { 23856 return new AST_Function({ 23857 start: my_start_token(M), 23858 end: my_end_token(M), 23859 name: from_moz(M.id), 23860 argnames: M.params.map(from_moz), 23861 body: normalize_directives(from_moz(M.body).body) 23862 }); 23863 }, 23864 ExpressionStatement: function(M) { 23865 return new AST_SimpleStatement({ 23866 start: my_start_token(M), 23867 end: my_end_token(M), 23868 body: from_moz(M.expression) 23869 }); 23870 }, 23871 TryStatement: function(M) { 23872 var handlers = M.handlers || [M.handler]; 23873 if (handlers.length > 1 || M.guardedHandlers && M.guardedHandlers.length) { 23874 throw new Error("Multiple catch clauses are not supported."); 23875 } 23876 return new AST_Try({ 23877 start : my_start_token(M), 23878 end : my_end_token(M), 23879 body : from_moz(M.block).body, 23880 bcatch : from_moz(handlers[0]), 23881 bfinally : M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null 23882 }); 23883 }, 23884 Property: function(M) { 23885 var key = M.key; 23886 var args = { 23887 start : my_start_token(key), 23888 end : my_end_token(M.value),
23889 key : key.type == "Identifier" ? key.name : key.value, 23890 value : from_moz(M.value) 23891 }; 23892 if (M.kind == "init") return new AST_ObjectKeyVal(args); 23893 args.key = new AST_SymbolAccessor({ 23894 name: args.key 23895 }); 23896 args.value = new AST_Accessor(args.value); 23897 if (M.kind == "get") return new AST_ObjectGetter(args); 23898 if (M.kind == "set") return new AST_ObjectSetter(args); 23899 }, 23900 ArrayExpression: function(M) { 23901 return new AST_Array({ 23902 start : my_start_token(M), 23903 end : my_end_token(M), 23904 elements : M.elements.map(function(elem){ 23905 return elem === null ? new AST_Hole() : from_moz(elem); 23906 }) 23907 }); 23908 }, 23909 ObjectExpression: function(M) { 23910 return new AST_Object({ 23911 start : my_start_token(M), 23912 end : my_end_token(M), 23913 properties : M.properties.map(function(prop){ 23914 prop.type = "Property"; 23915 return from_moz(prop) 23916 }) 23917 }); 23918 }, 23919 SequenceExpression: function(M) { 23920 return AST_Seq.from_array(M.expressions.map(from_moz)); 23921 }, 23922 MemberExpression: function(M) { 23923 return new (M.computed ? AST_Sub : AST_Dot)({ 23924 start : my_start_token(M), 23925 end : my_end_token(M), 23926 property : M.computed ? from_moz(M.property) : M.property.name, 23927 expression : from_moz(M.object) 23928 }); 23929 }, 23930 SwitchCase: function(M) { 23931 return new (M.test ? AST_Case : AST_Default)({ 23932 start : my_start_token(M), 23933 end : my_end_token(M), 23934 expression : from_moz(M.test), 23935 body : M.consequent.map(from_moz) 23936 }); 23937 }, 23938 VariableDeclaration: function(M) { 23939 return new (M.kind === "const" ? AST_Const : AST_Var)({ 23940 start : my_start_token(M), 23941 end : my_end_token(M), 23942 definitions : M.declarations.map(from_moz) 23943 }); 23944 }, 23945 Literal: function(M) { 23946 var val = M.value, args = { 23947 start : my_start_token(M), 23948 end : my_end_token(M) 23949 }; 23950 if (val === null) return new AST_Null(args); 23951 switch (typeof val) { 23952 case "string": 23953 args.value = val; 23954 return new AST_String(args); 23955 case "number": 23956 args.value = val; 23957 return new AST_Number(args); 23958 case "boolean": 23959 return new (val ? AST_True : AST_False)(args); 23960 default: 23961 var rx = M.regex; 23962 if (rx && rx.pattern) { 23963 // RegExpLiteral as per ESTree AST spec 23964 args.value = new RegExp(rx.pattern, rx.flags).toString(); 23965 } else { 23966 // support legacy RegExp 23967 args.value = M.regex && M.raw ? M.raw : val; 23968 } 23969 return new AST_RegExp(args); 23970 } 23971 }, 23972 Identifier: function(M) { 23973 var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2]; 23974 return new ( p.type == "LabeledStatement" ? AST_Label 23975 : p.type == "VariableDeclarator" && p.id === M ? (p.kind == "const" ? AST_SymbolConst : AST_SymbolVar) 23976 : p.type == "FunctionExpression" ? (p.id === M ? AST_SymbolLambda : AST_SymbolFunarg) 23977 : p.type == "FunctionDeclaration" ? (p.id === M ? AST_SymbolDefun : AST_SymbolFunarg) 23978 : p.type == "CatchClause" ? AST_SymbolCatch 23979 : p.type == "BreakStatement" || p.type == "ContinueStatement" ? AST_LabelRef 23980 : AST_SymbolRef)({ 23981 start : my_start_token(M), 23982 end : my_end_token(M), 23983 name : M.name 23984 }); 23985 } 23986 }; 23987 23988 MOZ_TO_ME.UpdateExpression = 23989 MOZ_TO_ME.UnaryExpression = function To_Moz_Unary(M) { 23990 var prefix = "prefix" in M ? M.prefix 23991 : M.type == "UnaryExpression" ? true : false; 23992 return new (prefix ? AST_UnaryPrefix : AST_UnaryPostfix)({
23993 start : my_start_token(M), 23994 end : my_end_token(M), 23995 operator : M.operator, 23996 expression : from_moz(M.argument) 23997 }); 23998 }; 23999 24000 map("EmptyStatement", AST_EmptyStatement); 24001 map("BlockStatement", AST_BlockStatement, "body@body"); 24002 map("IfStatement", AST_If, "test>condition, consequent>body, alternate>alternative"); 24003 map("LabeledStatement", AST_LabeledStatement, "label>label, body>body"); 24004 map("BreakStatement", AST_Break, "label>label"); 24005 map("ContinueStatement", AST_Continue, "label>label"); 24006 map("WithStatement", AST_With, "object>expression, body>body"); 24007 map("SwitchStatement", AST_Switch, "discriminant>expression, cases@body"); 24008 map("ReturnStatement", AST_Return, "argument>value"); 24009 map("ThrowStatement", AST_Throw, "argument>value"); 24010 map("WhileStatement", AST_While, "test>condition, body>body"); 24011 map("DoWhileStatement", AST_Do, "test>condition, body>body"); 24012 map("ForStatement", AST_For, "init>init, test>condition, update>step, body>body"); 24013 map("ForInStatement", AST_ForIn, "left>init, right>object, body>body"); 24014 map("DebuggerStatement", AST_Debugger); 24015 map("VariableDeclarator", AST_VarDef, "id>name, init>value"); 24016 map("CatchClause", AST_Catch, "param>argname, body%body"); 24017 24018 map("ThisExpression", AST_This); 24019 map("BinaryExpression", AST_Binary, "operator=operator, left>left, right>right"); 24020 map("LogicalExpression", AST_Binary, "operator=operator, left>left, right>right"); 24021 map("AssignmentExpression", AST_Assign, "operator=operator, left>left, right>right"); 24022 map("ConditionalExpression", AST_Conditional, "test>condition, consequent>consequent, alternate>alternative"); 24023 map("NewExpression", AST_New, "callee>expression, arguments@args"); 24024 map("CallExpression", AST_Call, "callee>expression, arguments@args"); 24025 24026 def_to_moz(AST_Toplevel, function To_Moz_Program(M) { 24027 return to_moz_scope("Program", M); 24028 }); 24029 24030 def_to_moz(AST_Defun, function To_Moz_FunctionDeclaration(M) { 24031 return { 24032 type: "FunctionDeclaration", 24033 id: to_moz(M.name), 24034 params: M.argnames.map(to_moz), 24035 body: to_moz_scope("BlockStatement", M) 24036 } 24037 }); 24038 24039 def_to_moz(AST_Function, function To_Moz_FunctionExpression(M) { 24040 return { 24041 type: "FunctionExpression", 24042 id: to_moz(M.name), 24043 params: M.argnames.map(to_moz), 24044 body: to_moz_scope("BlockStatement", M) 24045 } 24046 }); 24047 24048 def_to_moz(AST_Directive, function To_Moz_Directive(M) { 24049 return { 24050 type: "ExpressionStatement", 24051 expression: { 24052 type: "Literal", 24053 value: M.value 24054 } 24055 }; 24056 }); 24057 24058 def_to_moz(AST_SimpleStatement, function To_Moz_ExpressionStatement(M) { 24059 return { 24060 type: "ExpressionStatement", 24061 expression: to_moz(M.body) 24062 }; 24063 }); 24064 24065 def_to_moz(AST_SwitchBranch, function To_Moz_SwitchCase(M) { 24066 return { 24067 type: "SwitchCase", 24068 test: to_moz(M.expression), 24069 consequent: M.body.map(to_moz) 24070 }; 24071 }); 24072 24073 def_to_moz(AST_Try, function To_Moz_TryStatement(M) { 24074 return { 24075 type: "TryStatement", 24076 block: to_moz_block(M), 24077 handler: to_moz(M.bcatch), 24078 guardedHandlers: [], 24079 finalizer: to_moz(M.bfinally) 24080 }; 24081 }); 24082 24083 def_to_moz(AST_Catch, function To_Moz_CatchClause(M) { 24084 return { 24085 type: "CatchClause", 24086 param: to_moz(M.argname), 24087 guard: null, 24088 body: to_moz_block(M) 24089 }; 24090 }); 24091 24092 def_to_moz(AST_Definitions, function To_Moz_VariableDeclaration(M) { 24093 return { 24094 type: "VariableDeclaration", 24095 kind: M instanceof AST_Const ? "const" : "var", 24096 declarations: M.definitions.map(to_moz) 24097 }; 24098 }); 24099 24100 def_to_moz(AST_Seq, function To_Moz_SequenceExpression(M) { 24101 return { 24102 type: "SequenceExpression", 24103 expressions: M.to_array().map(to_moz) 24104 }; 24105 });
24106 24107 def_to_moz(AST_PropAccess, function To_Moz_MemberExpression(M) { 24108 var isComputed = M instanceof AST_Sub; 24109 return { 24110 type: "MemberExpression", 24111 object: to_moz(M.expression), 24112 computed: isComputed, 24113 property: isComputed ? to_moz(M.property) : {type: "Identifier", name: M.property} 24114 }; 24115 }); 24116 24117 def_to_moz(AST_Unary, function To_Moz_Unary(M) { 24118 return { 24119 type: M.operator == "++" || M.operator == "--" ? "UpdateExpression" : "UnaryExpression", 24120 operator: M.operator, 24121 prefix: M instanceof AST_UnaryPrefix, 24122 argument: to_moz(M.expression) 24123 }; 24124 }); 24125 24126 def_to_moz(AST_Binary, function To_Moz_BinaryExpression(M) { 24127 return { 24128 type: M.operator == "&&" || M.operator == "||" ? "LogicalExpression" : "BinaryExpression", 24129 left: to_moz(M.left), 24130 operator: M.operator, 24131 right: to_moz(M.right) 24132 }; 24133 }); 24134 24135 def_to_moz(AST_Array, function To_Moz_ArrayExpression(M) { 24136 return { 24137 type: "ArrayExpression", 24138 elements: M.elements.map(to_moz) 24139 }; 24140 }); 24141 24142 def_to_moz(AST_Object, function To_Moz_ObjectExpression(M) { 24143 return { 24144 type: "ObjectExpression", 24145 properties: M.properties.map(to_moz) 24146 }; 24147 }); 24148 24149 def_to_moz(AST_ObjectProperty, function To_Moz_Property(M) { 24150 var key = { 24151 type: "Literal", 24152 value: M.key instanceof AST_SymbolAccessor ? M.key.name : M.key 24153 }; 24154 var kind; 24155 if (M instanceof AST_ObjectKeyVal) { 24156 kind = "init"; 24157 } else 24158 if (M instanceof AST_ObjectGetter) { 24159 kind = "get"; 24160 } else 24161 if (M instanceof AST_ObjectSetter) { 24162 kind = "set"; 24163 } 24164 return { 24165 type: "Property", 24166 kind: kind, 24167 key: key, 24168 value: to_moz(M.value) 24169 }; 24170 }); 24171 24172 def_to_moz(AST_Symbol, function To_Moz_Identifier(M) { 24173 var def = M.definition(); 24174 return { 24175 type: "Identifier", 24176 name: def ? def.mangled_name || def.name : M.name 24177 }; 24178 }); 24179 24180 def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) { 24181 var value = M.value; 24182 return { 24183 type: "Literal", 24184 value: value, 24185 raw: value.toString(), 24186 regex: { 24187 pattern: value.source, 24188 flags: value.toString().match(/[gimuy]*$/)[0] 24189 } 24190 }; 24191 }); 24192 24193 def_to_moz(AST_Constant, function To_Moz_Literal(M) { 24194 var value = M.value; 24195 if (typeof value === 'number' && (value < 0 || (value === 0 && 1 / value < 0))) { 24196 return { 24197 type: "UnaryExpression", 24198 operator: "-", 24199 prefix: true, 24200 argument: { 24201 type: "Literal", 24202 value: -value, 24203 raw: M.start.raw 24204 } 24205 }; 24206 } 24207 return { 24208 type: "Literal", 24209 value: value, 24210 raw: M.start.raw 24211 }; 24212 }); 24213 24214 def_to_moz(AST_Atom, function To_Moz_Atom(M) { 24215 return { 24216 type: "Identifier", 24217 name: String(M.value) 24218 }; 24219 }); 24220 24221 AST_Boolean.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast); 24222 AST_Null.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast); 24223 AST_Hole.DEFMETHOD("to_mozilla_ast", function To_Moz_ArrayHole() { return null }); 24224 24225 AST_Block.DEFMETHOD("to_mozilla_ast", AST_BlockStatement.prototype.to_mozilla_ast); 24226 AST_Lambda.DEFMETHOD("to_mozilla_ast", AST_Function.prototype.to_mozilla_ast); 24227 24228 /* -----[ tools ]----- */ 24229 24230 function raw_token(moznode) { 24231 if (moznode.type == "Literal") { 24232 return moznode.raw != null ? moznode.raw : moznode.value + ""; 24233 } 24234 } 24235 24236 function my_start_token(moznode) { 24237 var loc = moznode.loc, start = loc && loc.start; 24238 var range = moznode.range; 24239 return new AST_Token({ 24240 file : loc && loc.source, 24241 line : start && start.line, 24242 col : start && start.column, 24243 pos : range ? range[0] : moznode.start, 24244 endline : start && start.line, 24245 endcol : start && start.column, 24246 endpos : range ? range[0] : moznode.start, 24247 raw : raw_token(moznode), 24248 }); 24249 }; 24250 24251 function my_end_token(moznode) { 24252 var loc = moznode.loc, end = loc && loc.end; 24253 var range = moznode.range; 24254 return new AST_Token({ 24255 file : loc && loc.source, 24256 line : end && end.line, 24257 col : end && end.column, 24258 pos : range ? range[1] : moznode.end, 24259 endline : end && end.line, 24260 endcol : end && end.column, 24261 endpos : range ? range[1] : moznode.end, 24262 raw : raw_token(moznode), 24263 }); 24264 }; 24265 24266 function map(moztype, mytype, propmap) { 24267 var moz_to_me = "function From_Moz_" + moztype + "(M){\n"; 24268 moz_to_me += "return new U2." + mytype.name + "({\n" + 24269 "start: my_start_token(M),\n" + 24270 "end: my_end_token(M)"; 24271 24272 var me_to_moz = "function To_Moz_" + moztype + "(M){\n"; 24273 me_to_moz += "return {\n" + 24274 "type: " + JSON.stringify(moztype); 24275
24276 if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop){ 24277 var m = /([a-z0-9$_]+)(=|@|>|%)([a-z0-9$_]+)/i.exec(prop); 24278 if (!m) throw new Error("Can't understand property map: " + prop); 24279 var moz = m[1], how = m[2], my = m[3]; 24280 moz_to_me += ",\n" + my + ": "; 24281 me_to_moz += ",\n" + moz + ": "; 24282 switch (how) { 24283 case "@": 24284 moz_to_me += "M." + moz + ".map(from_moz)"; 24285 me_to_moz += "M." + my + ".map(to_moz)"; 24286 break; 24287 case ">": 24288 moz_to_me += "from_moz(M." + moz + ")"; 24289 me_to_moz += "to_moz(M." + my + ")"; 24290 break; 24291 case "=": 24292 moz_to_me += "M." + moz; 24293 me_to_moz += "M." + my; 24294 break; 24295 case "%": 24296 moz_to_me += "from_moz(M." + moz + ").body"; 24297 me_to_moz += "to_moz_block(M)"; 24298 break; 24299 default: 24300 throw new Error("Can't understand operator in propmap: " + prop); 24301 } 24302 }); 24303 24304 moz_to_me += "\n})\n}"; 24305 me_to_moz += "\n}\n}"; 24306 24307 //moz_to_me = parse(moz_to_me).print_to_string({ beautify: true }); 24308 //me_to_moz = parse(me_to_moz).print_to_string({ beautify: true }); 24309 //console.log(moz_to_me); 24310 24311 moz_to_me = new Function("U2", "my_start_token", "my_end_token", "from_moz", "return(" + moz_to_me + ")")( 24312 exports, my_start_token, my_end_token, from_moz 24313 ); 24314 me_to_moz = new Function("to_moz", "to_moz_block", "to_moz_scope", "return(" + me_to_moz + ")")( 24315 to_moz, to_moz_block, to_moz_scope 24316 ); 24317 MOZ_TO_ME[moztype] = moz_to_me; 24318 def_to_moz(mytype, me_to_moz); 24319 }; 24320 24321 var FROM_MOZ_STACK = null; 24322 24323 function from_moz(node) { 24324 FROM_MOZ_STACK.push(node); 24325 var ret = node != null ? MOZ_TO_ME[node.type](node) : null; 24326 FROM_MOZ_STACK.pop(); 24327 return ret; 24328 }; 24329 24330 AST_Node.from_mozilla_ast = function(node){ 24331 var save_stack = FROM_MOZ_STACK; 24332 FROM_MOZ_STACK = []; 24333 var ast = from_moz(node); 24334 FROM_MOZ_STACK = save_stack; 24335 return ast; 24336 }; 24337 24338 function set_moz_loc(mynode, moznode, myparent) { 24339 var start = mynode.start; 24340 var end = mynode.end; 24341 if (start.pos != null && end.endpos != null) { 24342 moznode.range = [start.pos, end.endpos]; 24343 } 24344 if (start.line) { 24345 moznode.loc = { 24346 start: {line: start.line, column: start.col}, 24347 end: end.endline ? {line: end.endline, column: end.endcol} : null 24348 }; 24349 if (start.file) { 24350 moznode.loc.source = start.file; 24351 } 24352 } 24353 return moznode; 24354 }; 24355 24356 function def_to_moz(mytype, handler) { 24357 mytype.DEFMETHOD("to_mozilla_ast", function() { 24358 return set_moz_loc(this, handler(this)); 24359 }); 24360 }; 24361 24362 function to_moz(node) { 24363 return node != null ? node.to_mozilla_ast() : null; 24364 }; 24365 24366 function to_moz_block(node) { 24367 return { 24368 type: "BlockStatement", 24369 body: node.body.map(to_moz) 24370 }; 24371 }; 24372 24373 function to_moz_scope(type, node) { 24374 var body = node.body.map(to_moz); 24375 if (node.body[0] instanceof AST_SimpleStatement && node.body[0].body instanceof AST_String) { 24376 body.unshift(to_moz(new AST_EmptyStatement(node.body[0]))); 24377 } 24378 return { 24379 type: type, 24380 body: body 24381 }; 24382 }; 24383})(); 24384 24385/*********************************************************************** 24386 24387 A JavaScript tokenizer / parser / beautifier / compressor. 24388 https://github.com/mishoo/UglifyJS2 24389 24390 -------------------------------- (C) --------------------------------- 24391 24392 Author: Mihai Bazon 24393 <[email protected]> 24394 http://mihai.bazon.net/blog 24395 24396 Distributed under the BSD license: 24397 24398 Copyright 2012 (c) Mihai Bazon <[email protected]> 24399 24400 Redistribution and use in source and binary forms, with or without 24401 modification, are permitted provided that the following conditions 24402 are met: 24403 24404 * Redistributions of source code must retain the above 24405 copyright notice, this list of conditions and the following 24406 disclaimer. 24407 24408 * Redistributions in binary form must reproduce the above 24409 copyright notice, this list of conditions and the following 24410 disclaimer in the documentation and/or other materials 24411 provided with the distribution. 24412 24413 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER âAS ISâ AND ANY 24414 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24415 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24416 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE 24417 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
24418 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24419 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24420 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24421 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 24422 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 24423 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24424 SUCH DAMAGE. 24425 24426 ***********************************************************************/ 24427 24428"use strict"; 24429 24430function find_builtins() { 24431 // NaN will be included due to Number.NaN 24432 var a = [ 24433 "null", 24434 "true", 24435 "false", 24436 "Infinity", 24437 "-Infinity", 24438 "undefined", 24439 ]; 24440 [ Object, Array, Function, Number, 24441 String, Boolean, Error, Math, 24442 Date, RegExp 24443 ].forEach(function(ctor){ 24444 Object.getOwnPropertyNames(ctor).map(add); 24445 if (ctor.prototype) { 24446 Object.getOwnPropertyNames(ctor.prototype).map(add); 24447 } 24448 }); 24449 function add(name) { 24450 push_uniq(a, name); 24451 } 24452 return a; 24453} 24454 24455function mangle_properties(ast, options) { 24456 options = defaults(options, { 24457 cache: null, 24458 debug: false, 24459 ignore_quoted: false, 24460 only_cache: false, 24461 regex: null, 24462 reserved: null, 24463 }); 24464 24465 var reserved = options.reserved; 24466 if (reserved == null) 24467 reserved = find_builtins(); 24468 24469 var cache = options.cache; 24470 if (cache == null) { 24471 cache = { 24472 cname: -1, 24473 props: new Dictionary() 24474 }; 24475 } 24476 24477 var regex = options.regex; 24478 var ignore_quoted = options.ignore_quoted; 24479 24480 // note debug is either false (disabled), or a string of the debug suffix to use (enabled). 24481 // note debug may be enabled as an empty string, which is falsey. Also treat passing 'true' 24482 // the same as passing an empty string. 24483 var debug = (options.debug !== false); 24484 var debug_name_suffix; 24485 if (debug) { 24486 debug_name_suffix = (options.debug === true ? "" : options.debug); 24487 } 24488 24489 var names_to_mangle = []; 24490 var unmangleable = []; 24491 var ignored = {}; 24492 24493 // step 1: find candidates to mangle 24494 ast.walk(new TreeWalker(function(node){ 24495 if (node instanceof AST_ObjectKeyVal) { 24496 add(node.key, ignore_quoted && node.quote); 24497 } 24498 else if (node instanceof AST_ObjectProperty) { 24499 // setter or getter, since KeyVal is handled above 24500 add(node.key.name); 24501 } 24502 else if (node instanceof AST_Dot) { 24503 add(node.property); 24504 } 24505 else if (node instanceof AST_Sub) { 24506 addStrings(node.property, ignore_quoted); 24507 } 24508 })); 24509 24510 // step 2: transform the tree, renaming properties 24511 return ast.transform(new TreeTransformer(function(node){ 24512 if (node instanceof AST_ObjectKeyVal) { 24513 if (!(ignore_quoted && node.quote)) 24514 node.key = mangle(node.key); 24515 } 24516 else if (node instanceof AST_ObjectProperty) { 24517 // setter or getter 24518 node.key.name = mangle(node.key.name); 24519 } 24520 else if (node instanceof AST_Dot) { 24521 node.property = mangle(node.property); 24522 } 24523 else if (node instanceof AST_Sub) { 24524 if (!ignore_quoted) 24525 node.property = mangleStrings(node.property); 24526 } 24527 // else if (node instanceof AST_String) { 24528 // if (should_mangle(node.value)) { 24529 // AST_Node.warn( 24530 // "Found \"{prop}\" property candidate for mangling in an arbitrary string [{file}:{line},{col}]", { 24531 // file : node.start.file, 24532 // line : node.start.line, 24533 // col : node.start.col, 24534 // prop : node.value 24535 // } 24536 // ); 24537 // } 24538 // } 24539 })); 24540 24541 // only function declarations after this line 24542 24543 function can_mangle(name) { 24544 if (unmangleable.indexOf(name) >= 0) return false; 24545 if (reserved.indexOf(name) >= 0) return false; 24546 if (options.only_cache) { 24547 return cache.props.has(name); 24548 } 24549 if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false; 24550 return true; 24551 } 24552 24553 function should_mangle(name) { 24554 if (ignore_quoted && name in ignored) return false; 24555 if (regex && !regex.test(name)) return false; 24556 if (reserved.indexOf(name) >= 0) return false; 24557 return cache.props.has(name) 24558 || names_to_mangle.indexOf(name) >= 0; 24559 } 24560 24561 function add(name, ignore) { 24562 if (ignore) { 24563 ignored[name] = true; 24564 return; 24565 } 24566 24567 if (can_mangle(name)) 24568 push_uniq(names_to_mangle, name); 24569 24570 if (!should_mangle(name)) { 24571 push_uniq(unmangleable, name); 24572 } 24573 } 24574 24575 function mangle(name) { 24576 if (!should_mangle(name)) { 24577 return name; 24578 } 24579 24580 var mangled = cache.props.get(name); 24581 if (!mangled) { 24582 if (debug) { 24583 // debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_. 24584 var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_"; 24585 24586 if (can_mangle(debug_mangled) && !(ignore_quoted && debug_mangled in ignored)) { 24587 mangled = debug_mangled; 24588 } 24589 } 24590 24591 // either debug mode is off, or it is on and we could not use the mangled name 24592 if (!mangled) { 24593 // note can_mangle() does not check if the name collides with the 'ignored' set 24594 // (filled with quoted properties when ignore_quoted set). Make sure we add this 24595 // check so we don't collide with a quoted name. 24596 do { 24597 mangled = base54(++cache.cname); 24598 } while (!can_mangle(mangled) || (ignore_quoted && mangled in ignored)); 24599 } 24600 24601 cache.props.set(name, mangled); 24602 } 24603 return mangled; 24604 } 24605 24606 function addStrings(node, ignore) { 24607 var out = {}; 24608 try { 24609 (function walk(node){ 24610 node.walk(new TreeWalker(function(node){ 24611 if (node instanceof AST_Seq) { 24612 walk(node.cdr); 24613 return true; 24614 } 24615 if (node instanceof AST_String) { 24616 add(node.value, ignore); 24617 return true; 24618 } 24619 if (node instanceof AST_Conditional) { 24620 walk(node.consequent); 24621 walk(node.alternative); 24622 return true; 24623 } 24624 throw out; 24625 })); 24626 })(node); 24627 } catch(ex) { 24628 if (ex !== out) throw ex; 24629 } 24630 } 24631 24632 function mangleStrings(node) { 24633 return node.transform(new TreeTransformer(function(node){ 24634 if (node instanceof AST_Seq) { 24635 node.cdr = mangleStrings(node.cdr); 24636 } 24637 else if (node instanceof AST_String) { 24638 node.value = mangle(node.value); 24639 } 24640 else if (node instanceof AST_Conditional) { 24641 node.consequent = mangleStrings(node.consequent); 24642 node.alternative = mangleStrings(node.alternative); 24643 } 24644 return node; 24645 })); 24646 } 24647 24648} 24649 24650exports["Compressor"] = Compressor; 24651exports["DefaultsError"] = DefaultsError; 24652exports["Dictionary"] = Dictionary; 24653exports["JS_Parse_Error"] = JS_Parse_Error; 24654exports["MAP"] = MAP; 24655exports["OutputStream"] = OutputStream; 24656exports["SourceMap"] = SourceMap;
24657exports["TreeTransformer"] = TreeTransformer; 24658exports["TreeWalker"] = TreeWalker; 24659exports["base54"] = base54; 24660exports["defaults"] = defaults; 24661exports["mangle_properties"] = mangle_properties; 24662exports["merge"] = merge; 24663exports["parse"] = parse; 24664exports["push_uniq"] = push_uniq; 24665exports["string_template"] = string_template; 24666exports["tokenizer"] = tokenizer; 24667exports["is_identifier"] = is_identifier; 24668exports["SymbolDef"] = SymbolDef; 24669 24670AST_Node.warn_function = function(txt) { logger.error("uglifyjs WARN: " + txt); }; 24671 24672exports.AST_Node.warn_function = function(txt) { 24673 console.error("WARN: %s", txt); 24674}; 24675 24676function read_source_map(code) { 24677 var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code); 24678 if (!match) { 24679 exports.AST_Node.warn("inline source map not found"); 24680 return null; 24681 } 24682 return JSON.parse(new Buffer(match[2], "base64")); 24683} 24684 24685exports.minify = function(files, options, name) { 24686 options = exports.defaults(options, { 24687 compress : {}, 24688 fromString : false, 24689 inSourceMap : null, 24690 mangle : {}, 24691 mangleProperties : false, 24692 nameCache : null, 24693 outFileName : null, 24694 output : null, 24695 outSourceMap : null, 24696 parse : {}, 24697 sourceMapInline : false, 24698 sourceMapUrl : null, 24699 sourceRoot : null, 24700 spidermonkey : false, 24701 warnings : false, 24702 }); 24703 exports.base54.reset(); 24704 24705 var inMap = options.inSourceMap; 24706 if (typeof inMap == "string" && inMap != "inline") { 24707 inMap = JSON.parse(rjsFile.readFile(inMap, "utf8")); 24708 } 24709 24710 // 1. parse 24711 var toplevel = null, 24712 sourcesContent = {}; 24713 24714 if (options.spidermonkey) { 24715 if (inMap == "inline") { 24716 throw new Error("inline source map only works with built-in parser"); 24717 } 24718 toplevel = exports.AST_Node.from_mozilla_ast(files); 24719 } else { 24720 var addFile = function(file, fileUrl) { 24721 var code = options.fromString 24722 ? file 24723 : rjsFile.readFile(file, "utf8"); 24724 if (inMap == "inline") { 24725 inMap = read_source_map(code); 24726 } 24727 sourcesContent[fileUrl] = code; 24728 toplevel = exports.parse(code, { 24729 filename: fileUrl, 24730 toplevel: toplevel, 24731 bare_returns: options.parse ? options.parse.bare_returns : undefined 24732 }); 24733 } 24734 if (!options.fromString) { 24735 files = exports.simple_glob(files); 24736 if (inMap == "inline" && files.length > 1) { 24737 throw new Error("inline source map only works with singular input"); 24738 } 24739 } 24740 [].concat(files).forEach(function (files, i) { 24741 if (typeof files === 'string') { 24742 addFile(files, options.fromString ? i : files); 24743 } else { 24744 for (var fileUrl in files) { 24745 addFile(files[fileUrl], fileUrl); 24746 } 24747 } 24748 }); 24749 } 24750 if (options.wrap) { 24751 toplevel = toplevel.wrap_commonjs(options.wrap, options.exportAll); 24752 } 24753 24754 // 2. compress 24755 if (options.compress) { 24756 var compress = { warnings: options.warnings }; 24757 exports.merge(compress, options.compress); 24758 toplevel.figure_out_scope(options.mangle); 24759 var sq = exports.Compressor(compress); 24760 toplevel = sq.compress(toplevel); 24761 } 24762 24763 // 3. mangle properties 24764 if (options.mangleProperties || options.nameCache) { 24765 options.mangleProperties.cache = exports.readNameCache(options.nameCache, "props"); 24766 toplevel = exports.mangle_properties(toplevel, options.mangleProperties); 24767 exports.writeNameCache(options.nameCache, "props", options.mangleProperties.cache); 24768 } 24769 24770 // 4. mangle 24771 if (options.mangle) { 24772 toplevel.figure_out_scope(options.mangle); 24773 toplevel.compute_char_frequency(options.mangle); 24774 toplevel.mangle_names(options.mangle); 24775 } 24776 24777 // 5. output 24778 var output = { max_line_len: 32000 }; 24779 if (options.outSourceMap || options.sourceMapInline) { 24780 output.source_map = exports.SourceMap({ 24781 // prefer outFileName, otherwise use outSourceMap without .map suffix 24782 file: options.outFileName || (typeof options.outSourceMap === 'string' ? options.outSourceMap.replace(/\.map$/i, '') : null), 24783 orig: inMap, 24784 root: options.sourceRoot 24785 }); 24786 if (options.sourceMapIncludeSources) { 24787 for (var file in sourcesContent) { 24788 if (sourcesContent.hasOwnProperty(file)) { 24789 output.source_map.get().setSourceContent(file, sourcesContent[file]); 24790 } 24791 } 24792 } 24793 24794 } 24795 if (options.output) { 24796 exports.merge(output, options.output); 24797 } 24798 var stream = exports.OutputStream(output); 24799 toplevel.print(stream); 24800 24801 24802 var source_map = output.source_map; 24803 if (source_map) { 24804 source_map = source_map + ""; 24805 } 24806 24807 var mappingUrlPrefix = "\n//# sourceMappingURL="; 24808 if (options.sourceMapInline) { 24809 stream += mappingUrlPrefix + "data:application/json;charset=utf-8;base64," + new Buffer(source_map).toString("base64"); 24810 } else if (options.outSourceMap && typeof options.outSourceMap === "string" && options.sourceMapUrl !== false) { 24811 stream += mappingUrlPrefix + (typeof options.sourceMapUrl === "string" ? options.sourceMapUrl : options.outSourceMap); 24812 } 24813 24814 return { 24815 code : stream + "", 24816 map : source_map 24817 }; 24818};
24819 24820// exports.describe_ast = function() { 24821// function doitem(ctor) { 24822// var sub = {}; 24823// ctor.SUBCLASSES.forEach(function(ctor){ 24824// sub[ctor.TYPE] = doitem(ctor); 24825// }); 24826// var ret = {}; 24827// if (ctor.SELF_PROPS.length > 0) ret.props = ctor.SELF_PROPS; 24828// if (ctor.SUBCLASSES.length > 0) ret.sub = sub; 24829// return ret; 24830// } 24831// return doitem(exports.AST_Node).sub; 24832// } 24833 24834exports.describe_ast = function() { 24835 var out = exports.OutputStream({ beautify: true }); 24836 function doitem(ctor) { 24837 out.print("AST_" + ctor.TYPE); 24838 var props = ctor.SELF_PROPS.filter(function(prop){ 24839 return !/^\$/.test(prop); 24840 }); 24841 if (props.length > 0) { 24842 out.space(); 24843 out.with_parens(function(){ 24844 props.forEach(function(prop, i){ 24845 if (i) out.space(); 24846 out.print(prop); 24847 }); 24848 }); 24849 } 24850 if (ctor.documentation) { 24851 out.space(); 24852 out.print_string(ctor.documentation); 24853 } 24854 if (ctor.SUBCLASSES.length > 0) { 24855 out.space(); 24856 out.with_block(function(){ 24857 ctor.SUBCLASSES.forEach(function(ctor, i){ 24858 out.indent(); 24859 doitem(ctor); 24860 out.newline(); 24861 }); 24862 }); 24863 } 24864 }; 24865 doitem(exports.AST_Node); 24866 return out + ""; 24867}; 24868 24869function readReservedFile(filename, reserved) { 24870 if (!reserved) { 24871 reserved = { vars: [], props: [] }; 24872 } 24873 var data = rjsFile.readFile(filename, "utf8"); 24874 data = JSON.parse(data); 24875 if (data.vars) { 24876 data.vars.forEach(function(name){ 24877 exports.push_uniq(reserved.vars, name); 24878 }); 24879 } 24880 if (data.props) { 24881 data.props.forEach(function(name){ 24882 exports.push_uniq(reserved.props, name); 24883 }); 24884 } 24885 return reserved; 24886} 24887 24888exports.readReservedFile = readReservedFile; 24889 24890exports.readDefaultReservedFile = function(reserved) { 24891 return readReservedFile(require.resolve("./domprops.json"), reserved); 24892}; 24893 24894exports.readNameCache = function(filename, key) { 24895 var cache = null; 24896 if (filename) { 24897 try { 24898 var cache = rjsFile.readFile(filename, "utf8"); 24899 cache = JSON.parse(cache)[key]; 24900 if (!cache) throw "init"; 24901 cache.props = exports.Dictionary.fromObject(cache.props); 24902 } catch(ex) { 24903 cache = { 24904 cname: -1, 24905 props: new exports.Dictionary() 24906 }; 24907 } 24908 } 24909 return cache; 24910}; 24911 24912exports.writeNameCache = function(filename, key, cache) { 24913 if (filename) { 24914 var data; 24915 try { 24916 data = rjsFile.readFile(filename, "utf8"); 24917 data = JSON.parse(data); 24918 } catch(ex) { 24919 data = {}; 24920 } 24921 data[key] = { 24922 cname: cache.cname, 24923 props: cache.props.toObject() 24924 }; 24925 rjsFile.writeFile(filename, JSON.stringify(data, null, 2), "utf8"); 24926 } 24927}; 24928 24929// A file glob function that only supports "*" and "?" wildcards in the basename. 24930// Example: "foo/bar/*baz??.*.js" 24931// Argument `glob` may be a string or an array of strings. 24932// Returns an array of strings. Garbage in, garbage out. 24933exports.simple_glob = function simple_glob(glob) { 24934 if (Array.isArray(glob)) { 24935 return [].concat.apply([], glob.map(simple_glob)); 24936 } 24937 if (glob.match(/\*|\?/)) { 24938 var dir = path.dirname(glob); 24939 try { 24940 var entries = fs.readdirSync(dir); 24941 } catch (ex) {} 24942 if (entries) { 24943 var pattern = "^" + path.basename(glob) 24944 .replace(/[.+^$[\]\\(){}]/g, "\\$&") 24945 .replace(/\*/g, "[^/\\\\]*") 24946 .replace(/\?/g, "[^/\\\\]") + "$"; 24947 var mod = process.platform === "win32" ? "i" : ""; 24948 var rx = new RegExp(pattern, mod); 24949 var results = entries.filter(function(name) { 24950 return rx.test(name); 24951 }).map(function(name) { 24952 return path.join(dir, name); 24953 }); 24954 if (results.length) return results; 24955 } 24956 } 24957 return [ glob ]; 24958};
24959 24960 24961}); 24962/*jslint plusplus: true */ 24963/*global define: false */ 24964 24965define('parse', ['./esprimaAdapter', 'lang'], function (esprima, lang) { 24966 'use strict'; 24967 24968 function arrayToString(ary) { 24969 var output = '['; 24970 if (ary) { 24971 ary.forEach(function (item, i) { 24972 output += (i > 0 ? ',' : '') + '"' + lang.jsEscape(item) + '"'; 24973 }); 24974 } 24975 output += ']'; 24976 24977 return output; 24978 } 24979 24980 //This string is saved off because JSLint complains 24981 //about obj.arguments use, as 'reserved word' 24982 var argPropName = 'arguments', 24983 //Default object to use for "scope" checking for UMD identifiers. 24984 emptyScope = {}, 24985 mixin = lang.mixin, 24986 hasProp = lang.hasProp; 24987 24988 //From an esprima example for traversing its ast. 24989 function traverse(object, visitor) { 24990 var child; 24991 24992 if (!object) { 24993 return; 24994 } 24995 24996 if (visitor.call(null, object) === false) { 24997 return false; 24998 } 24999 for (var i = 0, keys = Object.keys(object); i < keys.length; i++) { 25000 child = object[keys[i]]; 25001 if (typeof child === 'object' && child !== null) { 25002 if (traverse(child, visitor) === false) { 25003 return false; 25004 } 25005 } 25006 } 25007 } 25008 25009 //Like traverse, but visitor returning false just 25010 //stops that subtree analysis, not the rest of tree 25011 //visiting. 25012 function traverseBroad(object, visitor) { 25013 var child; 25014 25015 if (!object) { 25016 return; 25017 } 25018 25019 if (visitor.call(null, object) === false) { 25020 return false; 25021 } 25022 for (var i = 0, keys = Object.keys(object); i < keys.length; i++) { 25023 child = object[key]; 25024 if (typeof child === 'object' && child !== null) { 25025 traverseBroad(child, visitor); 25026 } 25027 } 25028 } 25029 25030 /** 25031 * Pulls out dependencies from an array literal with just string members. 25032 * If string literals, will just return those string values in an array, 25033 * skipping other items in the array. 25034 * 25035 * @param {Node} node an AST node. 25036 * 25037 * @returns {Array} an array of strings. 25038 * If null is returned, then it means the input node was not a valid 25039 * dependency. 25040 */ 25041 function getValidDeps(node) { 25042 if (!node || node.type !== 'ArrayExpression' || !node.elements) { 25043 return; 25044 } 25045 25046 var deps = []; 25047 25048 node.elements.some(function (elem) { 25049 if (elem.type === 'Literal') { 25050 deps.push(elem.value); 25051 } 25052 }); 25053 25054 return deps.length ? deps : undefined; 25055 } 25056 25057 // Detects regular or arrow function expressions as the desired expression 25058 // type. 25059 function isFnExpression(node) { 25060 return (node && (node.type === 'FunctionExpression' || 25061 node.type === 'ArrowFunctionExpression')); 25062 } 25063 25064 /** 25065 * Main parse function. Returns a string of any valid require or 25066 * define/require.def calls as part of one JavaScript source string. 25067 * @param {String} moduleName the module name that represents this file. 25068 * It is used to create a default define if there is not one already for the 25069 * file. This allows properly tracing dependencies for builds. Otherwise, if 25070 * the file just has a require() call, the file dependencies will not be 25071 * properly reflected: the file will come before its dependencies. 25072 * @param {String} moduleName 25073 * @param {String} fileName 25074 * @param {String} fileContents 25075 * @param {Object} options optional options. insertNeedsDefine: true will 25076 * add calls to require.needsDefine() if appropriate. 25077 * @returns {String} JS source string or null, if no require or 25078 * define/require.def calls are found. 25079 */ 25080 function parse(moduleName, fileName, fileContents, options) { 25081 options = options || {}; 25082 25083 //Set up source input
25084 var i, moduleCall, depString, 25085 moduleDeps = [], 25086 result = '', 25087 moduleList = [], 25088 needsDefine = true, 25089 astRoot = esprima.parse(fileContents); 25090 25091 parse.recurse(astRoot, function (callName, config, name, deps, node, factoryIdentifier, fnExpScope) { 25092 if (!deps) { 25093 deps = []; 25094 } 25095 25096 if (callName === 'define' && (!name || name === moduleName)) { 25097 needsDefine = false; 25098 } 25099 25100 if (!name) { 25101 //If there is no module name, the dependencies are for 25102 //this file/default module name. 25103 moduleDeps = moduleDeps.concat(deps); 25104 } else { 25105 moduleList.push({ 25106 name: name, 25107 deps: deps 25108 }); 25109 } 25110 25111 if (callName === 'define' && factoryIdentifier && hasProp(fnExpScope, factoryIdentifier)) { 25112 return factoryIdentifier; 25113 } 25114 25115 //If define was found, no need to dive deeper, unless 25116 //the config explicitly wants to dig deeper. 25117 return !!options.findNestedDependencies; 25118 }, options); 25119 25120 if (options.insertNeedsDefine && needsDefine) { 25121 result += 'require.needsDefine("' + moduleName + '");'; 25122 } 25123 25124 if (moduleDeps.length || moduleList.length) { 25125 for (i = 0; i < moduleList.length; i++) { 25126 moduleCall = moduleList[i]; 25127 if (result) { 25128 result += '\n'; 25129 } 25130 25131 //If this is the main module for this file, combine any 25132 //"anonymous" dependencies (could come from a nested require 25133 //call) with this module. 25134 if (moduleCall.name === moduleName) { 25135 moduleCall.deps = moduleCall.deps.concat(moduleDeps); 25136 moduleDeps = []; 25137 } 25138 25139 depString = arrayToString(moduleCall.deps); 25140 result += 'define("' + moduleCall.name + '",' + 25141 depString + ');'; 25142 } 25143 if (moduleDeps.length) { 25144 if (result) { 25145 result += '\n'; 25146 } 25147 depString = arrayToString(moduleDeps); 25148 result += 'define("' + moduleName + '",' + depString + ');'; 25149 } 25150 } 25151 25152 return result || null; 25153 } 25154 25155 parse.traverse = traverse; 25156 parse.traverseBroad = traverseBroad; 25157 parse.isFnExpression = isFnExpression; 25158 25159 /** 25160 * Handles parsing a file recursively for require calls. 25161 * @param {Array} parentNode the AST node to start with. 25162 * @param {Function} onMatch function to call on a parse match. 25163 * @param {Object} [options] This is normally the build config options if 25164 * it is passed. 25165 * @param {Object} [fnExpScope] holds list of function expresssion 25166 * argument identifiers, set up internally, not passed in 25167 */ 25168 parse.recurse = function (object, onMatch, options, fnExpScope) { 25169 //Like traverse, but skips if branches that would not be processed 25170 //after has application that results in tests of true or false boolean 25171 //literal values. 25172 var keys, child, result, i, params, param, tempObject, 25173 hasHas = options && options.has; 25174 25175 fnExpScope = fnExpScope || emptyScope; 25176 25177 if (!object) { 25178 return; 25179 } 25180 25181 //If has replacement has resulted in if(true){} or if(false){}, take 25182 //the appropriate branch and skip the other one. 25183 if (hasHas && object.type === 'IfStatement' && object.test.type && 25184 object.test.type === 'Literal') { 25185 if (object.test.value) { 25186 //Take the if branch 25187 this.recurse(object.consequent, onMatch, options, fnExpScope); 25188 } else { 25189 //Take the else branch 25190 this.recurse(object.alternate, onMatch, options, fnExpScope); 25191 } 25192 } else { 25193 result = this.parseNode(object, onMatch, fnExpScope); 25194 if (result === false) { 25195 return; 25196 } else if (typeof result === 'string') { 25197 return result; 25198 } 25199 25200 //Build up a "scope" object that informs nested recurse calls if 25201 //the define call references an identifier that is likely a UMD 25202 //wrapped function expression argument. 25203 //Catch (function(a) {... wrappers 25204 if (object.type === 'ExpressionStatement' && object.expression && 25205 object.expression.type === 'CallExpression' && object.expression.callee && 25206 isFnExpression(object.expression.callee)) { 25207 tempObject = object.expression.callee; 25208 } 25209 // Catch !function(a) {... wrappers 25210 if (object.type === 'UnaryExpression' && object.argument && 25211 object.argument.type === 'CallExpression' && object.argument.callee && 25212 isFnExpression(object.argument.callee)) { 25213 tempObject = object.argument.callee; 25214 } 25215 if (tempObject && tempObject.params && tempObject.params.length) { 25216 params = tempObject.params; 25217 fnExpScope = mixin({}, fnExpScope, true); 25218 for (i = 0; i < params.length; i++) { 25219 param = params[i]; 25220 if (param.type === 'Identifier') { 25221 fnExpScope[param.name] = true; 25222 } 25223 } 25224 } 25225 25226 for (i = 0, keys = Object.keys(object); i < keys.length; i++) { 25227 child = object[keys[i]]; 25228 if (typeof child === 'object' && child !== null) { 25229 result = this.recurse(child, onMatch, options, fnExpScope); 25230 if (typeof result === 'string' && hasProp(fnExpScope, result)) { 25231 //The result was still in fnExpScope so break. Otherwise, 25232 //was a return from a a tree that had a UMD definition, 25233 //but now out of that scope so keep siblings. 25234 break; 25235 } 25236 } 25237 } 25238 25239 //Check for an identifier for a factory function identifier being 25240 //passed in as a function expression, indicating a UMD-type of 25241 //wrapping. 25242 if (typeof result === 'string') { 25243 if (hasProp(fnExpScope, result)) { 25244 //result still in scope, keep jumping out indicating the 25245 //identifier still in use. 25246 return result; 25247 } 25248 25249 return; 25250 } 25251 } 25252 }; 25253 25254 /** 25255 * Determines if the file defines the require/define module API. 25256 * Specifically, it looks for the `define.amd = ` expression. 25257 * @param {String} fileName 25258 * @param {String} fileContents 25259 * @returns {Boolean} 25260 */ 25261 parse.definesRequire = function (fileName, fileContents) { 25262 var foundDefine = false, 25263 foundDefineAmd = false; 25264 25265 traverse(esprima.parse(fileContents), function (node) { 25266 // Look for a top level declaration of a define, like 25267 // var requirejs, require, define, off Program body. 25268 if (node.type === 'Program' && node.body && node.body.length) { 25269 foundDefine = node.body.some(function(bodyNode) { 25270 // var define 25271 if (bodyNode.type === 'VariableDeclaration') { 25272 var decls = bodyNode.declarations; 25273 if (decls) { 25274 var hasVarDefine = decls.some(function(declNode) { 25275 return (declNode.type === 'VariableDeclarator' && 25276 declNode.id && 25277 declNode.id.type === 'Identifier' && 25278 declNode.id.name === 'define'); 25279 }); 25280 if (hasVarDefine) { 25281 return true; 25282 } 25283 } 25284 } 25285 25286 // function define() {} 25287 if (bodyNode.type === 'FunctionDeclaration' && 25288 bodyNode.id && 25289 bodyNode.id.type === 'Identifier' && 25290 bodyNode.id.name === 'define') { 25291 return true; 25292 } 25293 25294 25295 25296 25297 25298 25299 }); 25300 } 25301 25302 // Need define variable found first, before detecting define.amd. 25303 if (foundDefine && parse.hasDefineAmd(node)) { 25304 foundDefineAmd = true; 25305 25306 //Stop traversal 25307 return false; 25308 } 25309 }); 25310 25311 return foundDefine && foundDefineAmd; 25312 }; 25313 25314 /** 25315 * Finds require("") calls inside a CommonJS anonymous module wrapped in a 25316 * define(function(require, exports, module){}) wrapper. These dependencies 25317 * will be added to a modified define() call that lists the dependencies 25318 * on the outside of the function. 25319 * @param {String} fileName 25320 * @param {String|Object} fileContents: a string of contents, or an already 25321 * parsed AST tree. 25322 * @returns {Array} an array of module names that are dependencies. Always 25323 * returns an array, but could be of length zero. 25324 */ 25325 parse.getAnonDeps = function (fileName, fileContents) { 25326 var astRoot = typeof fileContents === 'string' ? 25327 esprima.parse(fileContents) : fileContents,
25328 defFunc = this.findAnonDefineFactory(astRoot); 25329 25330 return parse.getAnonDepsFromNode(defFunc); 25331 }; 25332 25333 /** 25334 * Finds require("") calls inside a CommonJS anonymous module wrapped 25335 * in a define function, given an AST node for the definition function. 25336 * @param {Node} node the AST node for the definition function. 25337 * @returns {Array} and array of dependency names. Can be of zero length. 25338 */ 25339 parse.getAnonDepsFromNode = function (node) { 25340 var deps = [], 25341 funcArgLength; 25342 25343 if (node) { 25344 this.findRequireDepNames(node, deps); 25345 25346 //If no deps, still add the standard CommonJS require, exports, 25347 //module, in that order, to the deps, but only if specified as 25348 //function args. In particular, if exports is used, it is favored 25349 //over the return value of the function, so only add it if asked. 25350 funcArgLength = node.params && node.params.length; 25351 if (funcArgLength) { 25352 deps = (funcArgLength > 1 ? ["require", "exports", "module"] : 25353 ["require"]).concat(deps); 25354 } 25355 } 25356 return deps; 25357 }; 25358 25359 parse.isDefineNodeWithArgs = function (node) { 25360 return node && node.type === 'CallExpression' && 25361 node.callee && node.callee.type === 'Identifier' && 25362 node.callee.name === 'define' && node[argPropName]; 25363 }; 25364 25365 /** 25366 * Finds the function in define(function (require, exports, module){}); 25367 * @param {Array} node 25368 * @returns {Boolean} 25369 */ 25370 parse.findAnonDefineFactory = function (node) { 25371 var match; 25372 25373 traverse(node, function (node) { 25374 var arg0, arg1; 25375 25376 if (parse.isDefineNodeWithArgs(node)) { 25377 25378 //Just the factory function passed to define 25379 arg0 = node[argPropName][0]; 25380 if (isFnExpression(arg0)) { 25381 match = arg0; 25382 return false; 25383 } 25384 25385 //A string literal module ID followed by the factory function. 25386 arg1 = node[argPropName][1]; 25387 if (arg0.type === 'Literal' && isFnExpression(arg1)) { 25388 match = arg1; 25389 return false; 25390 } 25391 } 25392 }); 25393 25394 return match; 25395 }; 25396 25397 /** 25398 * Finds any config that is passed to requirejs. That includes calls to 25399 * require/requirejs.config(), as well as require({}, ...) and 25400 * requirejs({}, ...) 25401 * @param {String} fileContents 25402 * 25403 * @returns {Object} a config details object with the following properties: 25404 * - config: {Object} the config object found. Can be undefined if no 25405 * config found. 25406 * - range: {Array} the start index and end index in the contents where 25407 * the config was found. Can be undefined if no config found. 25408 * Can throw an error if the config in the file cannot be evaluated in 25409 * a build context to valid JavaScript. 25410 */ 25411 parse.findConfig = function (fileContents) { 25412 /*jslint evil: true */ 25413 var jsConfig, foundConfig, stringData, foundRange, quote, quoteMatch, 25414 quoteRegExp = /(:\s|\[\s*)(['"])/, 25415 astRoot = esprima.parse(fileContents, { 25416 loc: true 25417 }); 25418 25419 traverse(astRoot, function (node) { 25420 var arg, 25421 requireType = parse.hasRequire(node); 25422 25423 if (requireType && (requireType === 'require' || 25424 requireType === 'requirejs' || 25425 requireType === 'requireConfig' || 25426 requireType === 'requirejsConfig')) { 25427 25428 arg = node[argPropName] && node[argPropName][0]; 25429 25430 if (arg && arg.type === 'ObjectExpression') { 25431 stringData = parse.nodeToString(fileContents, arg); 25432 jsConfig = stringData.value; 25433 foundRange = stringData.range; 25434 return false; 25435 } 25436 } else { 25437 arg = parse.getRequireObjectLiteral(node); 25438 if (arg) {
25439 stringData = parse.nodeToString(fileContents, arg); 25440 jsConfig = stringData.value; 25441 foundRange = stringData.range; 25442 return false; 25443 } 25444 } 25445 }); 25446 25447 if (jsConfig) { 25448 // Eval the config 25449 quoteMatch = quoteRegExp.exec(jsConfig); 25450 quote = (quoteMatch && quoteMatch[2]) || '"'; 25451 foundConfig = eval('(' + jsConfig + ')'); 25452 } 25453 25454 return { 25455 config: foundConfig, 25456 range: foundRange, 25457 quote: quote 25458 }; 25459 }; 25460 25461 /** Returns the node for the object literal assigned to require/requirejs, 25462 * for holding a declarative config. 25463 */ 25464 parse.getRequireObjectLiteral = function (node) { 25465 if (node.id && node.id.type === 'Identifier' && 25466 (node.id.name === 'require' || node.id.name === 'requirejs') && 25467 node.init && node.init.type === 'ObjectExpression') { 25468 return node.init; 25469 } 25470 }; 25471 25472 /** 25473 * Renames require/requirejs/define calls to be ns + '.' + require/requirejs/define 25474 * Does *not* do .config calls though. See pragma.namespace for the complete 25475 * set of namespace transforms. This function is used because require calls 25476 * inside a define() call should not be renamed, so a simple regexp is not 25477 * good enough. 25478 * @param {String} fileContents the contents to transform. 25479 * @param {String} ns the namespace, *not* including trailing dot. 25480 * @return {String} the fileContents with the namespace applied 25481 */ 25482 parse.renameNamespace = function (fileContents, ns) { 25483 var lines, 25484 locs = [], 25485 astRoot = esprima.parse(fileContents, { 25486 loc: true 25487 }); 25488 25489 parse.recurse(astRoot, function (callName, config, name, deps, node) { 25490 locs.push(node.loc); 25491 //Do not recurse into define functions, they should be using 25492 //local defines. 25493 return callName !== 'define'; 25494 }, {}); 25495 25496 if (locs.length) { 25497 lines = fileContents.split('\n'); 25498 25499 //Go backwards through the found locs, adding in the namespace name 25500 //in front. 25501 locs.reverse(); 25502 locs.forEach(function (loc) { 25503 var startIndex = loc.start.column, 25504 //start.line is 1-based, not 0 based. 25505 lineIndex = loc.start.line - 1, 25506 line = lines[lineIndex]; 25507 25508 lines[lineIndex] = line.substring(0, startIndex) + 25509 ns + '.' + 25510 line.substring(startIndex, 25511 line.length); 25512 }); 25513 25514 fileContents = lines.join('\n'); 25515 } 25516 25517 return fileContents; 25518 }; 25519 25520 /** 25521 * Finds all dependencies specified in dependency arrays and inside 25522 * simplified commonjs wrappers. 25523 * @param {String} fileName 25524 * @param {String} fileContents 25525 * 25526 * @returns {Array} an array of dependency strings. The dependencies 25527 * have not been normalized, they may be relative IDs. 25528 */ 25529 parse.findDependencies = function (fileName, fileContents, options) { 25530 var dependencies = [], 25531 astRoot = esprima.parse(fileContents); 25532 25533 parse.recurse(astRoot, function (callName, config, name, deps) { 25534 if (deps) { 25535 dependencies = dependencies.concat(deps); 25536 } 25537 }, options); 25538 25539 return dependencies; 25540 }; 25541 25542 /** 25543 * Finds only CJS dependencies, ones that are the form 25544 * require('stringLiteral') 25545 */ 25546 parse.findCjsDependencies = function (fileName, fileContents) { 25547 var dependencies = []; 25548 25549 traverse(esprima.parse(fileContents), function (node) { 25550 var arg; 25551 25552 if (node && node.type === 'CallExpression' && node.callee && 25553 node.callee.type === 'Identifier' && 25554 node.callee.name === 'require' && node[argPropName] && 25555 node[argPropName].length === 1) { 25556 arg = node[argPropName][0]; 25557 if (arg.type === 'Literal') { 25558 dependencies.push(arg.value); 25559 } 25560 } 25561 }); 25562
25563 return dependencies; 25564 }; 25565 25566 //function define() {} 25567 parse.hasDefDefine = function (node) { 25568 return node.type === 'FunctionDeclaration' && node.id && 25569 node.id.type === 'Identifier' && node.id.name === 'define'; 25570 }; 25571 25572 //define.amd = ... 25573 parse.hasDefineAmd = function (node) { 25574 return node && node.type === 'AssignmentExpression' && 25575 node.left && node.left.type === 'MemberExpression' && 25576 node.left.object && node.left.object.name === 'define' && 25577 node.left.property && node.left.property.name === 'amd'; 25578 }; 25579 25580 //define.amd reference, as in: if (define.amd) 25581 parse.refsDefineAmd = function (node) { 25582 return node && node.type === 'MemberExpression' && 25583 node.object && node.object.name === 'define' && 25584 node.object.type === 'Identifier' && 25585 node.property && node.property.name === 'amd' && 25586 node.property.type === 'Identifier'; 25587 }; 25588 25589 //require(), requirejs(), require.config() and requirejs.config() 25590 parse.hasRequire = function (node) { 25591 var callName, 25592 c = node && node.callee; 25593 25594 if (node && node.type === 'CallExpression' && c) { 25595 if (c.type === 'Identifier' && 25596 (c.name === 'require' || 25597 c.name === 'requirejs')) { 25598 //A require/requirejs({}, ...) call 25599 callName = c.name; 25600 } else if (c.type === 'MemberExpression' && 25601 c.object && 25602 c.object.type === 'Identifier' && 25603 (c.object.name === 'require' || 25604 c.object.name === 'requirejs') && 25605 c.property && c.property.name === 'config') { 25606 // require/requirejs.config({}) call 25607 callName = c.object.name + 'Config'; 25608 } 25609 } 25610 25611 return callName; 25612 }; 25613 25614 //define() 25615 parse.hasDefine = function (node) { 25616 return node && node.type === 'CallExpression' && node.callee && 25617 node.callee.type === 'Identifier' && 25618 node.callee.name === 'define'; 25619 }; 25620 25621 /** 25622 * If there is a named define in the file, returns the name. Does not 25623 * scan for mulitple names, just the first one. 25624 */ 25625 parse.getNamedDefine = function (fileContents) { 25626 var name; 25627 traverse(esprima.parse(fileContents), function (node) { 25628 if (node && node.type === 'CallExpression' && node.callee && 25629 node.callee.type === 'Identifier' && 25630 node.callee.name === 'define' && 25631 node[argPropName] && node[argPropName][0] && 25632 node[argPropName][0].type === 'Literal') { 25633 name = node[argPropName][0].value; 25634 return false; 25635 } 25636 }); 25637 25638 return name; 25639 }; 25640 25641 /** 25642 * Finds all the named define module IDs in a file. 25643 */ 25644 parse.getAllNamedDefines = function (fileContents, excludeMap) { 25645 var names = []; 25646 parse.recurse(esprima.parse(fileContents), 25647 function (callName, config, name, deps, node, factoryIdentifier, fnExpScope) { 25648 if (callName === 'define' && name) { 25649 if (!excludeMap.hasOwnProperty(name)) { 25650 names.push(name); 25651 } 25652 } 25653 25654 //If a UMD definition that points to a factory that is an Identifier, 25655 //indicate processing should not traverse inside the UMD definition. 25656 if (callName === 'define' && factoryIdentifier && hasProp(fnExpScope, factoryIdentifier)) { 25657 return factoryIdentifier; 25658 } 25659 25660 //If define was found, no need to dive deeper, unless 25661 //the config explicitly wants to dig deeper. 25662 return true; 25663 }, {}); 25664 25665 return names; 25666 }; 25667 25668 /** 25669 * Determines if define(), require({}|[]) or requirejs was called in the 25670 * file. Also finds out if define() is declared and if define.amd is called. 25671 */ 25672 parse.usesAmdOrRequireJs = function (fileName, fileContents) { 25673 var uses; 25674 25675 traverse(esprima.parse(fileContents), function (node) { 25676 var type, callName, arg; 25677 25678 if (parse.hasDefDefine(node)) { 25679 //function define() {} 25680 type = 'declaresDefine'; 25681 } else if (parse.hasDefineAmd(node)) { 25682 type = 'defineAmd'; 25683 } else { 25684 callName = parse.hasRequire(node); 25685 if (callName) { 25686 arg = node[argPropName] && node[argPropName][0]; 25687 if (arg && (arg.type === 'ObjectExpression' || 25688 arg.type === 'ArrayExpression')) { 25689 type = callName; 25690 } 25691 } else if (parse.hasDefine(node)) { 25692 type = 'define'; 25693 } 25694 } 25695 25696 if (type) { 25697 if (!uses) { 25698 uses = {}; 25699 } 25700 uses[type] = true; 25701 } 25702 }); 25703 25704 return uses; 25705 }; 25706 25707 /** 25708 * Determines if require(''), exports.x =, module.exports =, 25709 * __dirname, __filename are used. So, not strictly traditional CommonJS, 25710 * also checks for Node variants. 25711 */ 25712 parse.usesCommonJs = function (fileName, fileContents) { 25713 var uses = null, 25714 assignsExports = false; 25715 25716 25717 traverse(esprima.parse(fileContents), function (node) { 25718 var type, 25719 exp = node.expression || node.init; 25720 25721 if (node.type === 'Identifier' && 25722 (node.name === '__dirname' || node.name === '__filename')) { 25723 type = node.name.substring(2); 25724 } else if (node.type === 'VariableDeclarator' && node.id && 25725 node.id.type === 'Identifier' && 25726 node.id.name === 'exports') { 25727 //Hmm, a variable assignment for exports, so does not use cjs 25728 //exports. 25729 type = 'varExports'; 25730 } else if (exp && exp.type === 'AssignmentExpression' && exp.left && 25731 exp.left.type === 'MemberExpression' && exp.left.object) { 25732 if (exp.left.object.name === 'module' && exp.left.property && 25733 exp.left.property.name === 'exports') { 25734 type = 'moduleExports'; 25735 } else if (exp.left.object.name === 'exports' && 25736 exp.left.property) { 25737 type = 'exports'; 25738 } else if (exp.left.object.type === 'MemberExpression' && 25739 exp.left.object.object.name === 'module' && 25740 exp.left.object.property.name === 'exports' && 25741 exp.left.object.property.type === 'Identifier') { 25742 type = 'moduleExports'; 25743 } 25744 25745 } else if (node && node.type === 'CallExpression' && node.callee && 25746 node.callee.type === 'Identifier' && 25747 node.callee.name === 'require' && node[argPropName] && 25748 node[argPropName].length === 1 && 25749 node[argPropName][0].type === 'Literal') { 25750 type = 'require'; 25751 } 25752 25753 if (type) { 25754 if (type === 'varExports') { 25755 assignsExports = true; 25756 } else if (type !== 'exports' || !assignsExports) { 25757 if (!uses) { 25758 uses = {}; 25759 } 25760 uses[type] = true; 25761 } 25762 } 25763 }); 25764 25765 return uses; 25766 }; 25767 25768 25769 parse.findRequireDepNames = function (node, deps) { 25770 traverse(node, function (node) { 25771 var arg; 25772 25773 if (node && node.type === 'CallExpression' && node.callee && 25774 node.callee.type === 'Identifier' && 25775 node.callee.name === 'require' && 25776 node[argPropName] && node[argPropName].length === 1) { 25777 25778 arg = node[argPropName][0]; 25779 if (arg.type === 'Literal') { 25780 deps.push(arg.value); 25781 } 25782 } 25783 }); 25784 }; 25785 25786 /** 25787 * Determines if a specific node is a valid require or define/require.def 25788 * call. 25789 * @param {Array} node 25790 * @param {Function} onMatch a function to call when a match is found. 25791 * It is passed the match name, and the config, name, deps possible args. 25792 * The config, name and deps args are not normalized. 25793 * @param {Object} fnExpScope an object whose keys are all function 25794 * expression identifiers that should be in scope. Useful for UMD wrapper 25795 * detection to avoid parsing more into the wrapped UMD code. 25796 * 25797 * @returns {String}
25797 a JS source string with the valid require/define call. 25798 * Otherwise null. 25799 */ 25800 parse.parseNode = function (node, onMatch, fnExpScope) { 25801 var name, deps, cjsDeps, arg, factory, exp, refsDefine, bodyNode, 25802 args = node && node[argPropName], 25803 callName = parse.hasRequire(node), 25804 isUmd = false; 25805 25806 if (callName === 'require' || callName === 'requirejs') { 25807 //A plain require/requirejs call 25808 arg = node[argPropName] && node[argPropName][0]; 25809 if (arg && arg.type !== 'ArrayExpression') { 25810 if (arg.type === 'ObjectExpression') { 25811 //A config call, try the second arg. 25812 arg = node[argPropName][1]; 25813 } 25814 } 25815 25816 deps = getValidDeps(arg); 25817 if (!deps) { 25818 return; 25819 } 25820 25821 return onMatch("require", null, null, deps, node); 25822 } else if (parse.hasDefine(node) && args && args.length) { 25823 name = args[0]; 25824 deps = args[1]; 25825 factory = args[2]; 25826 25827 if (name.type === 'ArrayExpression') { 25828 //No name, adjust args 25829 factory = deps; 25830 deps = name; 25831 name = null; 25832 } else if (isFnExpression(name)) { 25833 //Just the factory, no name or deps 25834 factory = name; 25835 name = deps = null; 25836 } else if (name.type === 'Identifier' && args.length === 1 && 25837 hasProp(fnExpScope, name.name)) { 25838 //define(e) where e is a UMD identifier for the factory 25839 //function. 25840 isUmd = true; 25841 factory = name; 25842 name = null; 25843 } else if (name.type !== 'Literal') { 25844 //An object literal, just null out 25845 name = deps = factory = null; 25846 } 25847 25848 if (name && name.type === 'Literal' && deps) { 25849 if (isFnExpression(deps)) { 25850 //deps is the factory 25851 factory = deps; 25852 deps = null; 25853 } else if (deps.type === 'ObjectExpression') { 25854 //deps is object literal, null out 25855 deps = factory = null; 25856 } else if (deps.type === 'Identifier') { 25857 if (args.length === 2) { 25858 //define('id', factory) 25859 deps = factory = null; 25860 } else if (args.length === 3 && isFnExpression(factory)) { 25861 //define('id', depsIdentifier, factory) 25862 //Since identifier, cannot know the deps, but do not 25863 //error out, assume they are taken care of outside of 25864 //static parsing. 25865 deps = null; 25866 } 25867 } 25868 } 25869 25870 if (deps && deps.type === 'ArrayExpression') { 25871 deps = getValidDeps(deps); 25872 } else if (isFnExpression(factory)) { 25873 //If no deps and a factory function, could be a commonjs sugar 25874 //wrapper, scan the function for dependencies. 25875 cjsDeps = parse.getAnonDepsFromNode(factory); 25876 if (cjsDeps.length) { 25877 deps = cjsDeps; 25878 } 25879 } else if (deps || (factory && !isUmd)) { 25880 //Does not match the shape of an AMD call. 25881 return; 25882 } 25883 25884 //Just save off the name as a string instead of an AST object. 25885 if (name && name.type === 'Literal') { 25886 name = name.value; 25887 } 25888 25889 return onMatch("define", null, name, deps, node, 25890 (factory && factory.type === 'Identifier' ? factory.name : undefined), 25891 fnExpScope); 25892 } else if (node.type === 'CallExpression' && node.callee && 25893 isFnExpression(node.callee) && 25894 node.callee.body && node.callee.body.body && 25895 node.callee.body.body.length === 1 && 25896 node.callee.body.body[0].type === 'IfStatement') { 25897 bodyNode = node.callee.body.body[0]; 25898 //Look for a define(Identifier) case, but only if inside an 25899 //if that has a define.amd test 25900 if (bodyNode.consequent && bodyNode.consequent.body) { 25901 exp = bodyNode.consequent.body[0]; 25902 if (exp.type === 'ExpressionStatement' && exp.expression && 25903 parse.hasDefine(exp.expression) && 25904 exp.expression.arguments && 25905 exp.expression.arguments.length === 1 && 25906 exp.expression.arguments[0].type === 'Identifier') { 25907 25908 //Calls define(Identifier) as first statement in body. 25909 //Confirm the if test references define.amd 25910 traverse(bodyNode.test, function (node) { 25911 if (parse.refsDefineAmd(node)) { 25912 refsDefine = true; 25913 return false; 25914 } 25915 }); 25916 25917 if (refsDefine) { 25918 return onMatch("define", null, null, null, exp.expression, 25919 exp.expression.arguments[0].name, fnExpScope); 25920 } 25921 } 25922 } 25923 } 25924 }; 25925 25926 /**
25927 * Converts an AST node into a JS source string by extracting 25928 * the node's location from the given contents string. Assumes 25929 * esprima.parse() with loc was done. 25930 * @param {String} contents 25931 * @param {Object} node 25932 * @returns {String} a JS source string. 25933 */ 25934 parse.nodeToString = function (contents, node) { 25935 var extracted, 25936 loc = node.loc, 25937 lines = contents.split('\n'), 25938 firstLine = loc.start.line > 1 ? 25939 lines.slice(0, loc.start.line - 1).join('\n') + '\n' : 25940 '', 25941 preamble = firstLine + 25942 lines[loc.start.line - 1].substring(0, loc.start.column); 25943 25944 if (loc.start.line === loc.end.line) { 25945 extracted = lines[loc.start.line - 1].substring(loc.start.column, 25946 loc.end.column); 25947 } else { 25948 extracted = lines[loc.start.line - 1].substring(loc.start.column) + 25949 '\n' + 25950 lines.slice(loc.start.line, loc.end.line - 1).join('\n') + 25951 '\n' + 25952 lines[loc.end.line - 1].substring(0, loc.end.column); 25953 } 25954 25955 return { 25956 value: extracted, 25957 range: [ 25958 preamble.length, 25959 preamble.length + extracted.length 25960 ] 25961 }; 25962 }; 25963 25964 /** 25965 * Extracts license comments from JS text. 25966 * @param {String} fileName 25967 * @param {String} contents 25968 * @returns {String} a string of license comments. 25969 */ 25970 parse.getLicenseComments = function (fileName, contents) { 25971 var commentNode, refNode, subNode, value, i, j, 25972 //xpconnect's Reflect does not support comment or range, but 25973 //prefer continued operation vs strict parity of operation, 25974 //as license comments can be expressed in other ways, like 25975 //via wrap args, or linked via sourcemaps. 25976 ast = esprima.parse(contents, { 25977 comment: true, 25978 range: true 25979 }), 25980 result = '', 25981 existsMap = {}, 25982 lineEnd = contents.indexOf('\r') === -1 ? '\n' : '\r\n'; 25983 25984 if (ast.comments) { 25985 for (i = 0; i < ast.comments.length; i++) { 25986 commentNode = ast.comments[i]; 25987 25988 if (commentNode.type === 'Line') { 25989 value = '//' + commentNode.value + lineEnd; 25990 refNode = commentNode; 25991 25992 if (i + 1 >= ast.comments.length) { 25993 value += lineEnd; 25994 } else { 25995 //Look for immediately adjacent single line comments 25996 //since it could from a multiple line comment made out 25997 //of single line comments. Like this comment. 25998 for (j = i + 1; j < ast.comments.length; j++) { 25999 subNode = ast.comments[j]; 26000 if (subNode.type === 'Line' && 26001 subNode.range[0] === refNode.range[1] + 1) { 26002 //Adjacent single line comment. Collect it. 26003 value += '//' + subNode.value + lineEnd; 26004 refNode = subNode; 26005 } else { 26006 //No more single line comment blocks. Break out 26007 //and continue outer looping. 26008 break; 26009 } 26010 } 26011 value += lineEnd; 26012 i = j - 1; 26013 } 26014 } else { 26015 value = '/*' + commentNode.value + '*/' + lineEnd + lineEnd; 26016 } 26017 26018 if (!existsMap[value] && (value.indexOf('license') !== -1 || 26019 (commentNode.type === 'Block' && 26020 value.indexOf('/*!') === 0) || 26021 value.indexOf('opyright') !== -1 || 26022 value.indexOf('(c)') !== -1)) { 26023 26024 result += value; 26025 existsMap[value] = true; 26026 } 26027 26028 } 26029 } 26030 26031 return result; 26032 }; 26033 26034 return parse; 26035}); 26036/*global define */ 26037 26038define('transform', [ './esprimaAdapter', './parse', 'logger', 'lang'], 26039function (esprima, parse, logger, lang) { 26040 'use strict'; 26041 var transform, 26042 baseIndentRegExp = /^([ \t]+)/, 26043 indentRegExp = /\{[\r\n]+([ \t]+)/, 26044 keyRegExp = /^[_A-Za-z]([A-Za-z\d_]*)$/, 26045 bulkIndentRegExps = { 26046 '\n': /\n/g, 26047 '\r\n': /\r\n/g 26048 }; 26049 26050 function applyIndent(str, indent, lineReturn) { 26051 var regExp = bulkIndentRegExps[lineReturn]; 26052 return str.replace(regExp, '$&' + indent); 26053 } 26054 26055 transform = { 26056 toTransport: function (namespace, moduleName, path, contents, onFound, options) { 26057 options = options || {}; 26058 26059 var astRoot, contentLines, modLine, 26060 foundAnon, 26061 scanCount = 0, 26062 scanReset = false, 26063 defineInfos = [], 26064 applySourceUrl = function (contents) { 26065 if (options.useSourceUrl) { 26066 contents = 'eval("' + lang.jsEscape(contents) + 26067 '\\n//# sourceURL=' + (path.indexOf('/') === 0 ? '' : '/') + 26068 path + 26069 '");\n'; 26070 } 26071 return contents; 26072 }; 26073 26074 try { 26075 astRoot = esprima.parse(contents, { 26076 loc: true 26077 }); 26078 } catch (e) { 26079 logger.trace('toTransport skipping ' + path + ': ' + 26080 e.toString()); 26081 return contents; 26082 } 26083 26084 //Find the define calls and their position in the files. 26085 parse.traverse(astRoot, function (node) { 26086 var args, firstArg, firstArgLoc, factoryNode, 26087 needsId, depAction, foundId, init, 26088 sourceUrlData, range, 26089 namespaceExists = false; 26090 26091 // If a bundle script with a define declaration, do not 26092 // parse any further at this level. Likely a built layer 26093 // by some other tool. 26094 if (node.type === 'VariableDeclarator' && 26095 node.id && node.id.name === 'define' && 26096 node.id.type === 'Identifier') { 26097 init = node.init; 26098 if (init && init.callee && 26099 init.callee.type === 'CallExpression' && 26100 init.callee.callee && 26101 init.callee.callee.type === 'Identifier' && 26102 init.callee.callee.name === 'require' && 26103 init.callee.arguments && init.callee.arguments.length === 1 && 26104 init.callee.arguments[0].type === 'Literal' && 26105 init.callee.arguments[0].value && 26106 init.callee.arguments[0].value.indexOf('amdefine') !== -1) { 26107 // the var define = require('amdefine')(module) case, 26108 // keep going in that case. 26109 } else { 26110 return false; 26111 } 26112 } 26113 26114 namespaceExists = namespace && 26115 node.type === 'CallExpression' && 26116 node.callee && node.callee.object && 26117 node.callee.object.type === 'Identifier' && 26118 node.callee.object.name === namespace && 26119 node.callee.property.type === 'Identifier' && 26120 node.callee.property.name === 'define'; 26121 26122 if (namespaceExists || parse.isDefineNodeWithArgs(node)) { 26123 //The arguments are where its at. 26124 args = node.arguments; 26125 if (!args || !args.length) { 26126 return; 26127 } 26128 26129 firstArg = args[0]; 26130 firstArgLoc = firstArg.loc; 26131 26132 if (args.length === 1) { 26133 if (firstArg.type === 'Identifier') { 26134 //The define(factory) case, but 26135 //only allow it if one Identifier arg,
26136 //to limit impact of false positives. 26137 needsId = true; 26138 depAction = 'empty'; 26139 } else if (parse.isFnExpression(firstArg)) { 26140 //define(function(){}) 26141 factoryNode = firstArg; 26142 needsId = true; 26143 depAction = 'scan'; 26144 } else if (firstArg.type === 'ObjectExpression') { 26145 //define({}); 26146 needsId = true; 26147 depAction = 'skip'; 26148 } else if (firstArg.type === 'Literal' && 26149 typeof firstArg.value === 'number') { 26150 //define('12345'); 26151 needsId = true; 26152 depAction = 'skip'; 26153 } else if (firstArg.type === 'UnaryExpression' && 26154 firstArg.operator === '-' && 26155 firstArg.argument && 26156 firstArg.argument.type === 'Literal' && 26157 typeof firstArg.argument.value === 'number') { 26158 //define('-12345'); 26159 needsId = true; 26160 depAction = 'skip'; 26161 } else if (firstArg.type === 'MemberExpression' && 26162 firstArg.object && 26163 firstArg.property && 26164 firstArg.property.type === 'Identifier') { 26165 //define(this.key); 26166 needsId = true; 26167 depAction = 'empty'; 26168 } 26169 } else if (firstArg.type === 'ArrayExpression') { 26170 //define([], ...); 26171 needsId = true; 26172 depAction = 'skip'; 26173 } else if (firstArg.type === 'Literal' && 26174 typeof firstArg.value === 'string') { 26175 //define('string', ....) 26176 //Already has an ID. 26177 needsId = false; 26178 if (args.length === 2 && 26179 parse.isFnExpression(args[1])) { 26180 //Needs dependency scanning. 26181 factoryNode = args[1]; 26182 depAction = 'scan'; 26183 } else { 26184 depAction = 'skip'; 26185 } 26186 } else { 26187 //Unknown define entity, keep looking, even 26188 //in the subtree for this node. 26189 return; 26190 } 26191 26192 range = { 26193 foundId: foundId, 26194 needsId: needsId, 26195 depAction: depAction, 26196 namespaceExists: namespaceExists, 26197 node: node, 26198 defineLoc: node.loc, 26199 firstArgLoc: firstArgLoc, 26200 factoryNode: factoryNode, 26201 sourceUrlData: sourceUrlData 26202 }; 26203 26204 //Only transform ones that do not have IDs. If it has an 26205 //ID but no dependency array, assume it is something like 26206 //a phonegap implementation, that has its own internal 26207 //define that cannot handle dependency array constructs, 26208 //and if it is a named module, then it means it has been 26209 //set for transport form. 26210 if (range.needsId) { 26211 if (foundAnon) { 26212 logger.trace(path + ' has more than one anonymous ' + 26213 'define. May be a built file from another ' + 26214 'build system like, Ender. Skipping normalization.'); 26215 defineInfos = []; 26216 return false; 26217 } else { 26218 foundAnon = range; 26219 defineInfos.push(range); 26220 } 26221 } else if (depAction === 'scan') { 26222 scanCount += 1; 26223 if (scanCount > 1) { 26224 //Just go back to an array that just has the 26225 //anon one, since this is an already optimized 26226 //file like the phonegap one. 26227 if (!scanReset) { 26228 defineInfos = foundAnon ? [foundAnon] : []; 26229 scanReset = true; 26230 } 26231 } else { 26232 defineInfos.push(range); 26233 } 26234 } 26235 } 26236 }); 26237 26238 26239 if (!defineInfos.length) { 26240 return applySourceUrl(contents); 26241 } 26242 26243 //Reverse the matches, need to start from the bottom of 26244 //the file to modify it, so that the ranges are still true 26245 //further up. 26246 defineInfos.reverse(); 26247 26248 contentLines = contents.split('\n'); 26249 26250 modLine = function (loc, contentInsertion) { 26251 var startIndex = loc.start.column, 26252 //start.line is 1-based, not 0 based. 26253 lineIndex = loc.start.line - 1, 26254 line = contentLines[lineIndex]; 26255 contentLines[lineIndex] = line.substring(0, startIndex) + 26256 contentInsertion + 26257 line.substring(startIndex, 26258 line.length); 26259 }; 26260 26261 defineInfos.forEach(function (info) { 26262 var deps, 26263 contentInsertion = '', 26264 depString = ''; 26265 26266 //Do the modifications "backwards", in other words, start with the 26267 //one that is farthest down and work up, so that the ranges in the 26268 //defineInfos still apply. So that means deps, id, then namespace. 26269 if (info.needsId && moduleName) { 26270 contentInsertion += "'" + moduleName + "',"; 26271 } 26272 26273 if (info.depAction === 'scan') { 26274 deps = parse.getAnonDepsFromNode(info.factoryNode); 26275 26276 if (deps.length) { 26277 depString = '[' + deps.map(function (dep) { 26278 return "'" + dep + "'"; 26279 }) + ']'; 26280 } else { 26281 depString = '[]'; 26282 } 26283 depString += ','; 26284 26285 if (info.factoryNode) { 26286 //Already have a named module, need to insert the 26287 //dependencies after the name. 26288 modLine(info.factoryNode.loc, depString); 26289 } else { 26290 contentInsertion += depString; 26291 } 26292 } 26293 26294 if (contentInsertion) { 26295 modLine(info.firstArgLoc, contentInsertion); 26296 } 26297 26298 //Do namespace last so that ui does not mess upthe parenRange 26299 //used above. 26300 if (namespace && !info.namespaceExists) { 26301 modLine(info.defineLoc, namespace + '.'); 26302 } 26303 26304 //Notify any listener for the found info 26305 if (onFound) { 26306 onFound(info); 26307 } 26308 }); 26309 26310 contents = contentLines.join('\n'); 26311 26312 return applySourceUrl(contents); 26313 }, 26314 26315 /** 26316 * Modify the contents of a require.config/requirejs.config call. This 26317 * call will LOSE any existing comments that are in the config string. 26318 * 26319 * @param {String} fileContents String that may contain a config call 26320 * @param {Function} onConfig Function called when the first config 26321 * call is found. It will be passed an Object which is the current 26322 * config, and the onConfig function should return an Object to use 26323 * as the config. 26324 * @return {String} the fileContents with the config changes applied. 26325 */ 26326 modifyConfig: function (fileContents, onConfig) { 26327 var details = parse.findConfig(fileContents), 26328 config = details.config; 26329 26330 if (config) { 26331 config = onConfig(config); 26332 if (config) { 26333 return transform.serializeConfig(config, 26334 fileContents, 26335 details.range[0], 26336 details.range[1], 26337 { 26338 quote: details.quote 26339 }); 26340 } 26341 } 26342 26343 return fileContents; 26344 }, 26345 26346 serializeConfig: function (config, fileContents, start, end, options) { 26347 //Calculate base level of indent
26348 var indent, match, configString, outDentRegExp, 26349 baseIndent = '', 26350 startString = fileContents.substring(0, start), 26351 existingConfigString = fileContents.substring(start, end), 26352 lineReturn = existingConfigString.indexOf('\r') === -1 ? '\n' : '\r\n', 26353 lastReturnIndex = startString.lastIndexOf('\n'); 26354 26355 //Get the basic amount of indent for the require config call. 26356 if (lastReturnIndex === -1) { 26357 lastReturnIndex = 0; 26358 } 26359 26360 match = baseIndentRegExp.exec(startString.substring(lastReturnIndex + 1, start)); 26361 if (match && match[1]) { 26362 baseIndent = match[1]; 26363 } 26364 26365 //Calculate internal indentation for config 26366 match = indentRegExp.exec(existingConfigString); 26367 if (match && match[1]) { 26368 indent = match[1]; 26369 } 26370 26371 if (!indent || indent.length < baseIndent) { 26372 indent = ' '; 26373 } else { 26374 indent = indent.substring(baseIndent.length); 26375 } 26376 26377 outDentRegExp = new RegExp('(' + lineReturn + ')' + indent, 'g'); 26378
26379 configString = transform.objectToString(config, { 26380 indent: indent, 26381 lineReturn: lineReturn, 26382 outDentRegExp: outDentRegExp, 26383 quote: options && options.quote 26384 }); 26385 26386 //Add in the base indenting level. 26387 configString = applyIndent(configString, baseIndent, lineReturn); 26388 26389 return startString + configString + fileContents.substring(end); 26390 }, 26391 26392 /** 26393 * Tries converting a JS object to a string. This will likely suck, and 26394 * is tailored to the type of config expected in a loader config call. 26395 * So, hasOwnProperty fields, strings, numbers, arrays and functions, 26396 * no weird recursively referenced stuff. 26397 * @param {Object} obj the object to convert 26398 * @param {Object} options options object with the following values: 26399 * {String} indent the indentation to use for each level 26400 * {String} lineReturn the type of line return to use 26401 * {outDentRegExp} outDentRegExp the regexp to use to outdent functions 26402 * {String} quote the quote type to use, ' or ". Optional. Default is " 26403 * @param {String} totalIndent the total indent to print for this level 26404 * @return {String} a string representation of the object. 26405 */ 26406 objectToString: function (obj, options, totalIndent) { 26407 var startBrace, endBrace, nextIndent, 26408 first = true, 26409 value = '', 26410 lineReturn = options.lineReturn, 26411 indent = options.indent, 26412 outDentRegExp = options.outDentRegExp, 26413 quote = options.quote || '"'; 26414 26415 totalIndent = totalIndent || ''; 26416 nextIndent = totalIndent + indent; 26417 26418 if (obj === null) { 26419 value = 'null'; 26420 } else if (obj === undefined) { 26421 value = 'undefined'; 26422 } else if (typeof obj === 'number' || typeof obj === 'boolean') { 26423 value = obj; 26424 } else if (typeof obj === 'string') { 26425 //Use double quotes in case the config may also work as JSON. 26426 value = quote + lang.jsEscape(obj) + quote; 26427 } else if (lang.isArray(obj)) { 26428 lang.each(obj, function (item, i) { 26429 value += (i !== 0 ? ',' + lineReturn : '' ) + 26430 nextIndent + 26431 transform.objectToString(item, 26432 options, 26433 nextIndent); 26434 }); 26435 26436 startBrace = '['; 26437 endBrace = ']'; 26438 } else if (lang.isFunction(obj) || lang.isRegExp(obj)) { 26439 //The outdent regexp just helps pretty up the conversion 26440 //just in node. Rhino strips comments and does a different 26441 //indent scheme for Function toString, so not really helpful 26442 //there. 26443 value = obj.toString().replace(outDentRegExp, '$1'); 26444 } else { 26445 //An object 26446 lang.eachProp(obj, function (v, prop) { 26447 value += (first ? '': ',' + lineReturn) + 26448 nextIndent + 26449 (keyRegExp.test(prop) ? prop : quote + lang.jsEscape(prop) + quote )+ 26450 ': ' + 26451 transform.objectToString(v, 26452 options, 26453 nextIndent); 26454 first = false; 26455 }); 26456 startBrace = '{'; 26457 endBrace = '}'; 26458 } 26459 26460 if (startBrace) { 26461 value = startBrace + 26462 lineReturn + 26463 value + 26464 lineReturn + totalIndent + 26465 endBrace; 26466 } 26467 26468 return value; 26469 } 26470 }; 26471 26472 return transform; 26473}); 26474/*jslint regexp: true, plusplus: true */ 26475/*global define: false */ 26476 26477define('pragma', ['parse', 'logger'], function (parse, logger) { 26478 'use strict'; 26479 function Temp() {} 26480 26481 function create(obj, mixin) { 26482 Temp.prototype = obj; 26483 var temp = new Temp(), prop; 26484 26485 //Avoid any extra memory hanging around 26486 Temp.prototype = null; 26487 26488 if (mixin) { 26489 for (prop in mixin) { 26490 if (mixin.hasOwnProperty(prop) && !temp.hasOwnProperty(prop)) { 26491 temp[prop] = mixin[prop]; 26492 } 26493 } 26494 } 26495 26496 return temp; // Object 26497 } 26498 26499 var pragma = { 26500 conditionalRegExp: /(exclude|include)Start\s*\(\s*["'](\w+)["']\s*,(.*)\)/, 26501 useStrictRegExp: /(^|[^{]\r?\n)['"]use strict['"];/g,
26502 hasRegExp: /has\s*\(\s*['"]([^'"]+)['"]\s*\)/g, 26503 configRegExp: /(^|[^\.])(requirejs|require)(\.config)\s*\(/g, 26504 nsWrapRegExp: /\/\*requirejs namespace: true \*\//, 26505 apiDefRegExp: /var requirejs,\s*require,\s*define;/, 26506 defineCheckRegExp: /typeof(\s+|\s*\(\s*)define(\s*\))?\s*===?\s*["']function["']\s*&&\s*define\s*\.\s*amd/g, 26507 defineStringCheckRegExp: /typeof\s+define\s*===?\s*["']function["']\s*&&\s*define\s*\[\s*["']amd["']\s*\]/g, 26508 defineTypeFirstCheckRegExp: /\s*["']function["']\s*==(=?)\s*typeof\s+define\s*&&\s*define\s*\.\s*amd/g, 26509 defineJQueryRegExp: /typeof\s+define\s*===?\s*["']function["']\s*&&\s*define\s*\.\s*amd\s*&&\s*define\s*\.\s*amd\s*\.\s*jQuery/g, 26510 defineHasRegExp: /typeof\s+define\s*==(=)?\s*['"]function['"]\s*&&\s*typeof\s+define\.amd\s*==(=)?\s*['"]object['"]\s*&&\s*define\.amd/g, 26511 defineTernaryRegExp: /typeof\s+define\s*===?\s*['"]function["']\s*&&\s*define\s*\.\s*amd\s*\?\s*define/, 26512 defineExistsRegExp: /\s+typeof\s+define\s*!==?\s*['"]undefined["']\s*/, 26513 defineExistsAndAmdRegExp: /typeof\s+define\s*!==?\s*['"]undefined["']\s*&&\s*define\s*\.\s*amd\s*/, 26514 amdefineRegExp: /if\s*\(\s*typeof define\s*\!==\s*['"]function['"]\s*\)\s*\{\s*[^\{\}]+amdefine[^\{\}]+\}/g, 26515 26516 removeStrict: function (contents, config) { 26517 return config.useStrict ? contents : contents.replace(pragma.useStrictRegExp, '$1'); 26518 }, 26519 26520 namespace: function (fileContents, ns, onLifecycleName) { 26521 if (ns) { 26522 //Namespace require/define calls 26523 fileContents = fileContents.replace(pragma.configRegExp, '$1' + ns + '.$2$3('); 26524 26525 26526 fileContents = parse.renameNamespace(fileContents, ns); 26527 26528 //Namespace define ternary use: 26529 fileContents = fileContents.replace(pragma.defineTernaryRegExp, 26530 "typeof " + ns + ".define === 'function' && " + ns + ".define.amd ? " + ns + ".define"); 26531 26532 //Namespace define jquery use: 26533 fileContents = fileContents.replace(pragma.defineJQueryRegExp, 26534 "typeof " + ns + ".define === 'function' && " + ns + ".define.amd && " + ns + ".define.amd.jQuery"); 26535 26536 //Namespace has.js define use: 26537 fileContents = fileContents.replace(pragma.defineHasRegExp, 26538 "typeof " + ns + ".define === 'function' && typeof " + ns + ".define.amd === 'object' && " + ns + ".define.amd"); 26539 26540 //Namespace async.js define use: 26541 fileContents = fileContents.replace(pragma.defineExistsAndAmdRegExp, 26542 "typeof " + ns + ".define !== 'undefined' && " + ns + ".define.amd"); 26543 26544 //Namespace define checks. 26545 //Do these ones last, since they are a subset of the more specific 26546 //checks above. 26547 fileContents = fileContents.replace(pragma.defineCheckRegExp, 26548 "typeof " + ns + ".define === 'function' && " + ns + ".define.amd"); 26549 fileContents = fileContents.replace(pragma.defineStringCheckRegExp, 26550 "typeof " + ns + ".define === 'function' && " + ns + ".define['amd']"); 26551 fileContents = fileContents.replace(pragma.defineTypeFirstCheckRegExp, 26552 "'function' === typeof " + ns + ".define && " + ns + ".define.amd"); 26553 fileContents = fileContents.replace(pragma.defineExistsRegExp, 26554 "typeof " + ns + ".define !== 'undefined'"); 26555 26556 //Check for require.js with the require/define definitions 26557 if (pragma.apiDefRegExp.test(fileContents) && 26558 fileContents.indexOf("if (!" + ns + " || !" + ns + ".requirejs)") === -1) { 26559 //Wrap the file contents in a typeof check, and a function 26560 //to contain the API globals. 26561 fileContents = "var " + ns + ";(function () { if (!" + ns + " || !" + ns + ".requirejs) {\n" + 26562 "if (!" + ns + ") { " + ns + ' = {}; } else { require = ' + ns + '; }\n' + 26563 fileContents + 26564 "\n" + 26565 ns + ".requirejs = requirejs;" + 26566 ns + ".require = require;" + 26567 ns + ".define = define;\n" + 26568 "}\n}());"; 26569 } 26570 26571 //Finally, if the file wants a special wrapper because it ties 26572 //in to the requirejs internals in a way that would not fit 26573 //the above matches, do that. Look for /*requirejs namespace: true*/ 26574 if (pragma.nsWrapRegExp.test(fileContents)) { 26575 //Remove the pragma. 26576 fileContents = fileContents.replace(pragma.nsWrapRegExp, ''); 26577 26578 //Alter the contents. 26579 fileContents = '(function () {\n' + 26580 'var require = ' + ns + '.require,' + 26581 'requirejs = ' + ns + '.requirejs,' + 26582 'define = ' + ns + '.define;\n' + 26583 fileContents + 26584 '\n}());'; 26585 } 26586 } 26587 26588 return fileContents; 26589 }, 26590 26591 /** 26592 * processes the fileContents for some //>> conditional statements 26593 */ 26594 process: function (fileName, fileContents, config, onLifecycleName, pluginCollector) { 26595 /*jslint evil: true */ 26596 var foundIndex = -1, startIndex = 0, lineEndIndex, conditionLine, 26597 matches, type, marker, condition, isTrue, endReg
26597Exp, endMatches, 26598 endMarkerIndex, shouldInclude, startLength, lifecycleHas, deps, 26599 i, dep, moduleName, collectorMod, 26600 lifecyclePragmas, pragmas = config.pragmas, hasConfig = config.has, 26601 //Legacy arg defined to help in dojo conversion script. Remove later 26602 //when dojo no longer needs conversion: 26603 kwArgs = pragmas; 26604 26605 //Mix in a specific lifecycle scoped object, to allow targeting 26606 //some pragmas/has tests to only when files are saved, or at different 26607 //lifecycle events. Do not bother with kwArgs in this section, since 26608 //the old dojo kwArgs were for all points in the build lifecycle. 26609 if (onLifecycleName) { 26610 lifecyclePragmas = config['pragmas' + onLifecycleName]; 26611 lifecycleHas = config['has' + onLifecycleName]; 26612 26613 if (lifecyclePragmas) { 26614 pragmas = create(pragmas || {}, lifecyclePragmas); 26615 } 26616 26617 if (lifecycleHas) { 26618 hasConfig = create(hasConfig || {}, lifecycleHas); 26619 } 26620 } 26621 26622 //Replace has references if desired 26623 if (hasConfig) { 26624 fileContents = fileContents.replace(pragma.hasRegExp, function (match, test) { 26625 if (hasConfig.hasOwnProperty(test)) { 26626 return !!hasConfig[test]; 26627 } 26628 return match; 26629 }); 26630 } 26631 26632 if (!config.skipPragmas) { 26633 26634 while ((foundIndex = fileContents.indexOf("//>>", startIndex)) !== -1) { 26635 //Found a conditional. Get the conditional line. 26636 lineEndIndex = fileContents.indexOf("\n", foundIndex); 26637 if (lineEndIndex === -1) { 26638 lineEndIndex = fileContents.length - 1; 26639 } 26640 26641 //Increment startIndex past the line so the next conditional search can be done. 26642 startIndex = lineEndIndex + 1; 26643 26644 //Break apart the conditional. 26645 conditionLine = fileContents.substring(foundIndex, lineEndIndex + 1); 26646 matches = conditionLine.match(pragma.conditionalRegExp); 26647 if (matches) { 26648 type = matches[1]; 26649 marker = matches[2]; 26650 condition = matches[3]; 26651 isTrue = false; 26652 //See if the condition is true. 26653 try { 26654 isTrue = !!eval("(" + condition + ")"); 26655 } catch (e) { 26656 throw "Error in file: " + 26657 fileName + 26658 ". Conditional comment: " + 26659 conditionLine + 26660 " failed with this error: " + e; 26661 } 26662 26663 //Find the endpoint marker. 26664 endRegExp = new RegExp('\\/\\/\\>\\>\\s*' + type + 'End\\(\\s*[\'"]' + marker + '[\'"]\\s*\\)', "g"); 26665 endMatches = endRegExp.exec(fileContents.substring(startIndex, fileContents.length)); 26666 if (endMatches) { 26667 endMarkerIndex = startIndex + endRegExp.lastIndex - endMatches[0].length; 26668 26669 //Find the next line return based on the match position. 26670 lineEndIndex = fileContents.indexOf("\n", endMarkerIndex); 26671 if (lineEndIndex === -1) { 26672 lineEndIndex = fileContents.length - 1; 26673 } 26674 26675 //Should we include the segment? 26676 shouldInclude = ((type === "exclude" && !isTrue) || (type === "include" && isTrue)); 26677 26678 //Remove the conditional comments, and optionally remove the content inside 26679 //the conditional comments. 26680 startLength = startIndex - foundIndex; 26681 fileContents = fileContents.substring(0, foundIndex) + 26682 (shouldInclude ? fileContents.substring(startIndex, endMarkerIndex) : "") + 26683 fileContents.substring(lineEndIndex + 1, fileContents.length); 26684 26685 //Move startIndex to foundIndex, since that is the new position in the file 26686 //where we need to look for more conditionals in the next while loop pass. 26687 startIndex = foundIndex; 26688 } else { 26689 throw "Error in file: " + 26690 fileName + 26691 ". Cannot find end marker for conditional comment: " + 26692 conditionLine; 26693 26694 } 26695 } 26696 } 26697 } 26698 26699 //If need to find all plugin resources to optimize, do that now, 26700 //before namespacing, since the namespacing will change the API 26701 //names. 26702 //If there is a plugin collector, scan the file for plugin resources. 26703 if (config.optimizeAllPluginResources && pluginCollector) { 26704 try { 26705 deps = parse.findDependencies(fileName, fileContents); 26706 if (deps.length) { 26707 for (i = 0; i < deps.length; i++) { 26708 dep = deps[i]; 26709 if (dep.indexOf('!') !== -1) { 26710 moduleName = dep.split('!')[0]; 26711 collectorMod = pluginCollector[moduleName]; 26712 if (!collectorMod) { 26713 collectorMod = pluginCollector[moduleName] = []; 26714 } 26715 collectorMod.push(dep); 26716 } 26717 } 26718 } 26719 } catch (eDep) { 26720 logger.error('Parse error looking for plugin resources in ' + 26721 fileName + ', skipping.'); 26722 } 26723 } 26724 26725 //Strip amdefine use for node-shared modules. 26726 if (!config.keepAmdefine) { 26727 fileContents = fileContents.replace(pragma.amdefineRegExp, ''); 26728 } 26729 26730 //Do namespacing 26731 if (onLifecycleName === 'OnSave' && config.namespace) { 26732 fileContents = pragma.namespace(fileContents, config.namespace, onLifecycleName); 26733 } 26734 26735 26736 return pragma.removeStrict(fileContents, config); 26737 } 26738 }; 26739 26740 return pragma; 26741}); 26742 26743if(env === 'browser') { 26744/*jslint strict: false */ 26745/*global define: false */ 26746 26747define('browser/optimize', {}); 26748 26749} 26750 26751if(env === 'node') { 26752/*jslint strict: false */ 26753/*global define: false */ 26754 26755define('node/optimize', {}); 26756 26757} 26758 26759if(env === 'rhino') { 26760/*jslint sloppy: true, plusplus: true */ 26761/*global define, java, Packages, com */ 26762 26763define('rhino/optimize', ['logger', 'env!env/file'], function (logger, file) { 26764 26765 //Add .reduce to Rhino so UglifyJS can run in Rhino, 26766 //inspired by https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/reduce
26767 //but rewritten for brevity, and to be good enough for use by UglifyJS. 26768 if (!Array.prototype.reduce) { 26769 Array.prototype.reduce = function (fn /*, initialValue */) { 26770 var i = 0, 26771 length = this.length, 26772 accumulator; 26773 26774 if (arguments.length >= 2) { 26775 accumulator = arguments[1]; 26776 } else { 26777 if (length) { 26778 while (!(i in this)) { 26779 i++; 26780 } 26781 accumulator = this[i++]; 26782 } 26783 } 26784 26785 for (; i < length; i++) { 26786 if (i in this) { 26787 accumulator = fn.call(undefined, accumulator, this[i], i, this); 26788 } 26789 } 26790 26791 return accumulator; 26792 }; 26793 } 26794 26795 var JSSourceFilefromCode, optimize, 26796 mapRegExp = /"file":"[^"]+"/; 26797 26798 //Bind to Closure compiler, but if it is not available, do not sweat it. 26799 try { 26800 // Try older closure compiler that worked on Java 6 26801 JSSourceFilefromCode = java.lang.Class.forName('com.google.javascript.jscomp.JSSourceFile').getMethod('fromCode', [java.lang.String, java.lang.String]); 26802 } catch (e) { 26803 try { 26804 // Try for newer closure compiler that needs Java 7+ 26805 JSSourceFilefromCode = java.lang.Class.forName('com.google.javascript.jscomp.SourceFile').getMethod('fromCode', [java.lang.String, java.lang.String]); 26806 } catch (e) { 26807 try { 26808 // Try Nashorn style 26809 var stringClass = Java.type("java.lang.String").class; 26810 JSSourceFilefromCode = Java.type("com.google.javascript.jscomp.SourceFile").class.getMethod("fromCode", [stringClass, stringClass]); 26811 } catch (e) {} 26812 } 26813 } 26814 26815 //Helper for closure compiler, because of weird Java-JavaScript interactions. 26816 function closurefromCode(filename, content) { 26817 return JSSourceFilefromCode.invoke(null, [filename, content]); 26818 } 26819 26820 26821 function getFileWriter(fileName, encoding) { 26822 var outFile = new java.io.File(fileName), outWriter, parentDir; 26823 26824 parentDir = outFile.getAbsoluteFile().getParentFile(); 26825 if (!parentDir.exists()) { 26826 if (!parentDir.mkdirs()) { 26827 throw "Could not create directory: " + parentDir.getAbsolutePath(); 26828 } 26829 } 26830 26831 if (encoding) { 26832 outWriter = new java.io.OutputStreamWriter(new java.io.FileOutputStream(outFile), encoding); 26833 } else { 26834 outWriter = new java.io.OutputStreamWriter(new java.io.FileOutputStream(outFile)); 26835 } 26836 26837 return new java.io.BufferedWriter(outWriter); 26838 } 26839 26840 optimize = { 26841 closure: function (fileName, fileContents, outFileName, keepLines, config) { 26842 config = config || {}; 26843 var result, mappings, optimized, compressed, baseName, writer, 26844 outBaseName, outFileNameMap, outFileNameMapContent, 26845 srcOutFileName, concatNameMap, 26846 jscomp = Packages.com.google.javascript.jscomp, 26847 flags = Packages.com.google.common.flags, 26848 //Set up source input 26849 jsSourceFile = closurefromCode(String(fileName), String(fileContents)), 26850 sourceListArray = new java.util.ArrayList(), 26851 externList = new java.util.ArrayList(), 26852 options, option, FLAG_compilation_level, compiler, externExportsPath, 26853 Compiler = Packages.com.google.javascript.jscomp.Compiler, 26854 CommandLineRunner = Packages.com.google.javascript.jscomp.CommandLineRunner; 26855 26856 logger.trace("Minifying file: " + fileName); 26857 26858 baseName = (new java.io.File(fileName)).getName(); 26859 26860 //Set up options 26861 options = new jscomp.CompilerOptions(); 26862 for (option in config.CompilerOptions) { 26863 // options are false by default and jslint wanted an if statement in this for loop 26864 if (config.CompilerOptions[option]) { 26865 options[option] = config.CompilerOptions[option]; 26866 } 26867 26868 } 26869 options.prettyPrint = keepLines || options.prettyPrint; 26870 26871 FLAG_compilation_level = jscomp.CompilationLevel[config.CompilationLevel || 'SIMPLE_OPTIMIZATIONS']; 26872 FLAG_compilation_level.setOptionsForCompilationLevel(options); 26873 26874 if (config.generateSourceMaps) { 26875 mappings = new java.util.ArrayList(); 26876 26877 mappings.add(new com.google.javascript.jscomp.SourceMap.LocationMapping(fileName, baseName + ".src.js")); 26878 options.setSourceMapLocationMappings(mappings); 26879 options.setSourceMapOutputPath(fileName + ".map"); 26880 } 26881 26882 //If we need to pass an externs file to Closure so that it does not create aliases 26883 //for certain symbols, do so here. 26884 externList.addAll(CommandLineRunner.getDefaultExterns()); 26885 if (config.externExportsPath) { 26886 externExportsPath = config.externExportsPath; 26887 externList.add(jscomp.SourceFile.fromFile(externExportsPath)); 26888 } 26889 26890 //Trigger the compiler 26891 Compiler.setLoggingLevel(Packages.java.util.logging.Level[config.loggingLevel || 'WARNING']); 26892 compiler = new Compiler(); 26893 26894 //fill the sourceArrrayList; we need the ArrayList because the only overload of compile 26895 //accepting the getDefaultExterns return value (a List) also wants the sources as a List 26896 sourceListArray.add(jsSourceFile); 26897 26898 result = compiler.compile(externList, sourceListArray, options); 26899 if (result.success) { 26900 optimized = String(compiler.toSource()); 26901 26902 if (config.generateSourceMaps && result.sourceMap && outFileName) {
26903 outBaseName = (new java.io.File(outFileName)).getName(); 26904 26905 srcOutFileName = outFileName + ".src.js"; 26906 outFileNameMap = outFileName + ".map"; 26907 26908 //If previous .map file exists, move it to the ".src.js" 26909 //location. Need to update the sourceMappingURL part in the 26910 //src.js file too. 26911 if (file.exists(outFileNameMap)) { 26912 concatNameMap = outFileNameMap.replace(/\.map$/, '.src.js.map'); 26913 file.saveFile(concatNameMap, file.readFile(outFileNameMap)); 26914 file.saveFile(srcOutFileName, 26915 fileContents.replace(/\/\# sourceMappingURL=(.+).map/, 26916 '/# sourceMappingURL=$1.src.js.map')); 26917 } else { 26918 file.saveUtf8File(srcOutFileName, fileContents); 26919 } 26920 26921 writer = getFileWriter(outFileNameMap, "utf-8"); 26922 result.sourceMap.appendTo(writer, outFileName); 26923 writer.close(); 26924 26925 //Not sure how better to do this, but right now the .map file 26926 //leaks the full OS path in the "file" property. Manually 26927 //modify it to not do that. 26928 file.saveFile(outFileNameMap, 26929 file.readFile(outFileNameMap).replace(mapRegExp, '"file":"' + baseName + '"')); 26930 26931 fileContents = optimized + "\n//# sourceMappingURL=" + outBaseName + ".map"; 26932 } else { 26933 fileContents = optimized; 26934 } 26935 return fileContents; 26936 } else { 26937 throw new Error('Cannot closure compile file: ' + fileName + '. Skipping it.'); 26938 } 26939 26940 return fileContents; 26941 } 26942 }; 26943 26944 return optimize; 26945}); 26946} 26947 26948if(env === 'xpconnect') { 26949define('xpconnect/optimize', {}); 26950} 26951/*jslint plusplus: true, nomen: true, regexp: true */ 26952/*global define: false */ 26953 26954define('optimize', [ 'lang', 'logger', 'env!env/optimize', 'env!env/file', 'parse', 26955 'pragma', 'uglifyjs', 26956 'source-map'], 26957function (lang, logger, envOptimize, file, parse, 26958 pragma, uglify, 26959 sourceMap) { 26960 'use strict'; 26961 26962 var optimize, 26963 cssImportRegExp = /\@import\s+(url\()?\s*([^);]+)\s*(\))?([\w, ]*)(;)?/ig, 26964 cssCommentImportRegExp = /\/\*[^\*]*@import[^\*]*\*\//g, 26965 cssUrlRegExp = /\url\(\s*([^\)]+)\s*\)?/g, 26966 protocolRegExp = /^\w+:/, 26967 SourceMapGenerator = sourceMap.SourceMapGenerator, 26968 SourceMapConsumer = sourceMap.SourceMapConsumer, 26969 es5PlusGuidance = 'If the source uses ES2015 or later syntax, please pass "optimize: \'none\'" to r.js and use an ES2015+ compatible minifier after running r.js. The included UglifyJS only understands ES5 or earlier syntax.'; 26970 26971 /** 26972 * If an URL from a CSS url value contains start/end quotes, remove them. 26973 * This is not done in the regexp, since my regexp fu is not that strong, 26974 * and the CSS spec allows for ' and " in the URL if they are backslash escaped. 26975 * @param {String} url 26976 */ 26977 function cleanCssUrlQuotes(url) { 26978 //Make sure we are not ending in whitespace. 26979 //Not very confident of the css regexps above that there will not be ending 26980 //whitespace. 26981 url = url.replace(/\s+$/, ""); 26982 26983 if (url.charAt(0) === "'" || url.charAt(0) === "\"") { 26984 url = url.substring(1, url.length - 1); 26985 } 26986 26987 return url; 26988 } 26989 26990 function fixCssUrlPaths(fileName, path, contents, cssPrefix) { 26991 return contents.replace(cssUrlRegExp, function (fullMatch, urlMatch) { 26992 var firstChar, hasProtocol, parts, i, 26993 fixedUrlMatch = cleanCssUrlQuotes(urlMatch); 26994 26995 fixedUrlMatch = fixedUrlMatch.replace(lang.backSlashRegExp, "/"); 26996 26997 //Only do the work for relative URLs. Skip things that start with / or #, or have 26998 //a protocol. 26999 firstChar = fixedUrlMatch.charAt(0);
27000 hasProtocol = protocolRegExp.test(fixedUrlMatch); 27001 if (firstChar !== "/" && firstChar !== "#" && !hasProtocol) { 27002 //It is a relative URL, tack on the cssPrefix and path prefix 27003 urlMatch = cssPrefix + path + fixedUrlMatch; 27004 } else if (!hasProtocol) { 27005 logger.trace(fileName + "\n URL not a relative URL, skipping: " + urlMatch); 27006 } 27007 27008 //Collapse .. and . 27009 parts = urlMatch.split("/"); 27010 for (i = parts.length - 1; i > 0; i--) { 27011 if (parts[i] === ".") { 27012 parts.splice(i, 1); 27013 } else if (parts[i] === "..") { 27014 if (i !== 0 && parts[i - 1] !== "..") { 27015 parts.splice(i - 1, 2); 27016 i -= 1; 27017 } 27018 } 27019 } 27020 27021 return "url(" + parts.join("/") + ")"; 27022 }); 27023 } 27024 27025 /** 27026 * Inlines nested stylesheets that have @import calls in them. 27027 * @param {String} fileName the file name 27028 * @param {String} fileContents the file contents 27029 * @param {String} cssImportIgnore comma delimited string of files to ignore 27030 * @param {String} cssPrefix string to be prefixed before relative URLs 27031 * @param {Object} included an object used to track the files already imported 27032 */ 27033 function flattenCss(fileName, fileContents, cssImportIgnore, cssPrefix, included, topLevel) { 27034 //Find the last slash in the name. 27035 fileName = fileName.replace(lang.backSlashRegExp, "/"); 27036 var endIndex = fileName.lastIndexOf("/"), 27037 //Make a file path based on the last slash. 27038 //If no slash, so must be just a file name. Use empty string then. 27039 filePath = (endIndex !== -1) ? fileName.substring(0, endIndex + 1) : "", 27040 //store a list of merged files 27041 importList = [], 27042 skippedList = []; 27043 27044 //First make a pass by removing any commented out @import calls. 27045 fileContents = fileContents.replace(cssCommentImportRegExp, ''); 27046 27047 //Make sure we have a delimited ignore list to make matching faster 27048 if (cssImportIgnore && cssImportIgnore.charAt(cssImportIgnore.length - 1) !== ",") { 27049 cssImportIgnore += ","; 27050 } 27051 27052 fileContents = fileContents.replace(cssImportRegExp, function (fullMatch, urlStart, importFileName, urlEnd, mediaTypes) { 27053 //Only process media type "all" or empty media type rules. 27054 if (mediaTypes && ((mediaTypes.replace(/^\s\s*/, '').replace(/\s\s*$/, '')) !== "all")) { 27055 skippedList.push(fileName); 27056 return fullMatch; 27057 } 27058 27059 importFileName = cleanCssUrlQuotes(importFileName); 27060 27061 //Ignore the file import if it is part of an ignore list. 27062 if (cssImportIgnore && cssImportIgnore.indexOf(importFileName + ",") !== -1) { 27063 return fullMatch; 27064 } 27065 27066 //Make sure we have a unix path for the rest of the operation. 27067 importFileName = importFileName.replace(lang.backSlashRegExp, "/"); 27068 27069 try { 27070 //if a relative path, then tack on the filePath. 27071 //If it is not a relative path, then the readFile below will fail, 27072 //and we will just skip that import. 27073 var fullImportFileName = importFileName.charAt(0) === "/" ? importFileName : filePath + importFileName, 27074 importContents = file.readFile(fullImportFileName), 27075 importEndIndex, importPath, flat; 27076 27077 //Skip the file if it has already been included. 27078 if (included[fullImportFileName]) { 27079 return ''; 27080 } 27081 included[fullImportFileName] = true; 27082 27083 //Make sure to flatten any nested imports. 27084 flat = flattenCss(fullImportFileName, importContents, cssImportIgnore, cssPrefix, included); 27085 importContents = flat.fileContents; 27086 27087 if (flat.importList.length) { 27088 importList.push.apply(importList, flat.importList); 27089 } 27090 if (flat.skippedList.length) { 27091 skippedList.push.apply(skippedList, flat.skippedList); 27092 } 27093 27094 //Make the full import path 27095 importEndIndex = importFileName.lastIndexOf("/"); 27096 27097 //Make a file path based on the last slash. 27098 //If no slash, so must be just a file name. Use empty string then. 27099 importPath = (importEndIndex !== -1) ? importFileName.substring(0, importEndIndex + 1) : ""; 27100 27101 //fix url() on relative import (#5) 27102 importPath = importPath.replace(/^\.\//, ''); 27103 27104 //Modify URL paths to match the path represented by this file. 27105 importContents = fixCssUrlPaths(importFileName, importPath, importContents, cssPrefix); 27106 27107 importList.push(fullImportFileName); 27108 return importContents; 27109 } catch (e) { 27110 logger.warn(fileName + "\n Cannot inline css import, skipping: " + importFileName); 27111 return fullMatch; 27112 } 27113 }); 27114 27115 if (cssPrefix && topLevel) { 27116 //Modify URL paths to match the path represented by this file. 27117 fileContents = fixCssUrlPaths(fileName, '', fileContents, cssPrefix); 27118 } 27119 27120 return { 27121 importList : importList, 27122 skippedList: skippedList, 27123 fileContents : fileContents 27124 }; 27125 } 27126 27127 optimize = { 27128 /** 27129 * Optimizes a file that contains JavaScript content. Optionally collects 27130 * plugin resources mentioned in a file, and then passes the content 27131 * through an minifier if one is specified via config.optimize. 27132 * 27133 * @param {String} fileName the name of the file to optimize 27134 * @param {String} fileContents the contents to optimize. If this is 27135 * a null value, then fileName will be used to read the fileContents. 27136 * @param {String} outFileName the name of the file to use for the 27137 * saved optimized content. 27138 * @param {Object} config the build config object. 27139 * @param {Array} [pluginCollector] storage for any plugin resources 27140 * found. 27141 */ 27142 jsFile: function (fileName, fileContents, outFileName, config, pluginCollector) { 27143 if (!fileContents) { 27144 fileContents = file.readFile(fileName); 27145 } 27146 27147 fileContents = optimize.js(fileName, fileContents, outFileName, config, pluginCollector); 27148 27149 file.saveUtf8File(outFileName, fileContents); 27150 }, 27151 27152 /** 27153 * Optimizes a file that contains JavaScript content. Optionally collects 27154 * plugin resources mentioned in a file, and then passes the content 27155 * through an minifier if one is specified via config.optimize. 27156 * 27157 * @param {String} fileName the name of the file that matches the 27158 * fileContents. 27159 * @param {String} fileContents the string of JS to optimize. 27160 * @param {Object} [config] the build config object. 27161 * @param {Array} [pluginCollector] storage for any plugin resources 27162 * found. 27163 */ 27164 js: function (fileName, fileContents, outFileName, config, pluginCollector) { 27165 var optFunc, optConfig, 27166 parts = (String(config.optimize)).split('.'), 27167 optimizerName = parts[0], 27168 keepLines = parts[1] === 'keepLines', 27169 licenseContents = ''; 27170 27171 config = config || {}; 27172 27173 //Apply pragmas/namespace renaming 27174 fileContents = pragma.process(fileName, fileContents, config, 'OnSave', pluginCollector); 27175 27176 //Optimize the JS files if asked. 27177 if (optimizerName && optimizerName !== 'none') { 27178 optFunc = envOptimize[optimizerName] || optimize.optimizers[optimizerName]; 27179 if (!optFunc) { 27180 throw new Error('optimizer with name of "' + 27181 optimizerName + 27182 '" not found for this environment'); 27183 } 27184 27185 optConfig = config[optimizerName] || {}; 27186 if (config.generateSourceMaps) { 27187 optConfig.generateSourceMaps = !!config.generateSourceMaps; 27188 optConfig._buildSourceMap = config._buildSourceMap;
27189 } 27190 27191 try { 27192 if (config.preserveLicenseComments) { 27193 //Pull out any license comments for prepending after optimization. 27194 try { 27195 licenseContents = parse.getLicenseComments(fileName, fileContents); 27196 } catch (e) { 27197 throw new Error('Cannot parse file: ' + fileName + ' for comments. Skipping it. Error is:\n' + e.toString()); 27198 } 27199 } 27200 27201 if (config.generateSourceMaps && licenseContents) { 27202 optConfig.preamble = licenseContents; 27203 licenseContents = ''; 27204 } 27205 27206 fileContents = licenseContents + optFunc(fileName, 27207 fileContents, 27208 outFileName, 27209 keepLines, 27210 optConfig); 27211 if (optConfig._buildSourceMap && optConfig._buildSourceMap !== config._buildSourceMap) { 27212 config._buildSourceMap = optConfig._buildSourceMap; 27213 } 27214 } catch (e) { 27215 if (config.throwWhen && config.throwWhen.optimize) { 27216 throw e; 27217 } else { 27218 logger.error(e); 27219 } 27220 } 27221 } else { 27222 if (config._buildSourceMap) { 27223 config._buildSourceMap = null; 27224 } 27225 } 27226 27227 return fileContents; 27228 }, 27229 27230 /** 27231 * Optimizes one CSS file, inlining @import calls, stripping comments, and 27232 * optionally removes line returns. 27233 * @param {String} fileName the path to the CSS file to optimize 27234 * @param {String} outFileName the path to save the optimized file. 27235 * @param {Object} config the config object with the optimizeCss and 27236 * cssImportIgnore options. 27237 */ 27238 cssFile: function (fileName, outFileName, config) { 27239 27240 //Read in the file. Make sure we have a JS string. 27241 var originalFileContents = file.readFile(fileName), 27242 flat = flattenCss(fileName, originalFileContents, config.cssImportIgnore, config.cssPrefix, {}, true), 27243 //Do not use the flattened CSS if there was one that was skipped. 27244 fileContents = flat.skippedList.length ? originalFileContents : flat.fileContents, 27245 startIndex, endIndex, buildText, comment; 27246 27247 if (flat.skippedList.length) { 27248 logger.warn('Cannot inline @imports for ' + fileName + 27249 ',\nthe following files had media queries in them:\n' + 27250 flat.skippedList.join('\n')); 27251 } 27252 27253 //Do comment removal. 27254 try { 27255 if (config.optimizeCss.indexOf(".keepComments") === -1) { 27256 startIndex = 0; 27257 //Get rid of comments. 27258 while ((startIndex = fileContents.indexOf("/*", startIndex)) !== -1) { 27259 endIndex = fileContents.indexOf("*/", startIndex + 2); 27260 if (endIndex === -1) { 27261 throw "Improper comment in CSS file: " + fileName; 27262 } 27263 comment = fileContents.substring(startIndex, endIndex); 27264 27265 if (config.preserveLicenseComments && 27266 (comment.indexOf('license') !== -1 || 27267 comment.indexOf('opyright') !== -1 || 27268 comment.indexOf('(c)') !== -1)) { 27269 //Keep the comment, just increment the startIndex 27270 startIndex = endIndex; 27271 } else { 27272 fileContents = fileContents.substring(0, startIndex) + fileContents.substring(endIndex + 2, fileContents.length); 27273 startIndex = 0; 27274 } 27275 } 27276 } 27277 //Get rid of newlines. 27278 if (config.optimizeCss.indexOf(".keepLines") === -1) { 27279 fileContents = fileContents.replace(/[\r\n]/g, " "); 27280 fileContents = fileContents.replace(/\s+/g, " "); 27281 fileContents = fileContents.replace(/\{\s/g, "{"); 27282 fileContents = fileContents.replace(/\s\}/g, "}"); 27283 } else { 27284 //Remove multiple empty lines. 27285 fileContents = fileContents.replace(/(\r\n)+/g, "\r\n"); 27286 fileContents = fileContents.replace(/(\n)+/g, "\n"); 27287 } 27288 //Remove unnecessary whitespace 27289 if (config.optimizeCss.indexOf(".keepWhitespace")
27289=== -1) { 27290 //Remove leading and trailing whitespace from lines 27291 fileContents = fileContents.replace(/^[ \t]+/gm, ""); 27292 fileContents = fileContents.replace(/[ \t]+$/gm, ""); 27293 //Remove whitespace after semicolon, colon, curly brackets and commas 27294 fileContents = fileContents.replace(/(;|:|\{|}|,)[ \t]+/g, "$1"); 27295 //Remove whitespace before opening curly brackets 27296 fileContents = fileContents.replace(/[ \t]+(\{)/g, "$1"); 27297 //Truncate double whitespace 27298 fileContents = fileContents.replace(/([ \t])+/g, "$1"); 27299 //Remove empty lines 27300 fileContents = fileContents.replace(/^[ \t]*[\r\n]/gm,''); 27301 } 27302 } catch (e) { 27303 fileContents = originalFileContents; 27304 logger.error("Could not optimized CSS file: " + fileName + ", error: " + e); 27305 } 27306 27307 file.saveUtf8File(outFileName, fileContents); 27308 27309 //text output to stdout and/or written to build.txt file 27310 buildText = "\n"+ outFileName.replace(config.dir, "") +"\n----------------\n"; 27311 flat.importList.push(fileName); 27312 buildText += flat.importList.map(function(path){ 27313 return path.replace(config.dir, ""); 27314 }).join("\n"); 27315 27316 return { 27317 importList: flat.importList, 27318 buildText: buildText +"\n" 27319 }; 27320 }, 27321 27322 /** 27323 * Optimizes CSS files, inlining @import calls, stripping comments, and 27324 * optionally removes line returns. 27325 * @param {String} startDir the path to the top level directory 27326 * @param {Object} config the config object with the optimizeCss and 27327 * cssImportIgnore options. 27328 */ 27329 css: function (startDir, config) { 27330 var buildText = "", 27331 importList = [], 27332 shouldRemove = config.dir && config.removeCombined, 27333 i, fileName, result, fileList; 27334 if (config.optimizeCss.indexOf("standard") !== -1) { 27335 fileList = file.getFilteredFileList(startDir, /\.css$/, true); 27336 if (fileList) { 27337 for (i = 0; i < fileList.length; i++) { 27338 fileName = fileList[i]; 27339 logger.trace("Optimizing (" + config.optimizeCss + ") CSS file: " + fileName); 27340 result = optimize.cssFile(fileName, fileName, config); 27341 buildText += result.buildText; 27342 if (shouldRemove) { 27343 result.importList.pop(); 27344 importList = importList.concat(result.importList); 27345 } 27346 } 27347 } 27348 27349 if (shouldRemove) { 27350 importList.forEach(function (path) { 27351 if (file.exists(path)) { 27352 file.deleteFile(path); 27353 } 27354 }); 27355 } 27356 } 27357 return buildText; 27358 }, 27359 27360 optimizers: { 27361 uglify: function (fileName, fileContents, outFileName, keepLines, config) { 27362 var result, existingMap, resultMap, finalMap, sourceIndex, 27363 uconfig = {}, 27364 existingMapPath = outFileName + '.map', 27365 baseName = fileName && fileName.split('/').pop(); 27366 27367 config = config || {}; 27368 27369 lang.mixin(uconfig, config, true); 27370 27371 uconfig.fromString = true; 27372 27373 if (config.preamble) { 27374 uconfig.output = {preamble: config.preamble}; 27375 } 27376 27377 27378 if (config.generateSourceMaps && (outFileName || config._buildSourceMap)) { 27379 uconfig.outSourceMap = baseName + '.map'; 27380 27381 if (config._buildSourceMap) { 27382 existingMap = JSON.parse(config._buildSourceMap); 27383 uconfig.inSourceMap = existingMap; 27384 } else if (file.exists(existingMapPath)) { 27385 uconfig.inSourceMap = existingMapPath; 27386 existingMap = JSON.parse(file.readFile(existingMapPath)); 27387 } 27388 } 27389 27390 logger.trace("Uglify file: " + fileName); 27391 27392 try { 27393 //var tempContents = fileContents.replace(/\/\/\# sourceMappingURL=.*$/, ''); 27394 result = uglify.minify(fileContents, uconfig, baseName + '.src.js'); 27395 if (uconfig.outSourceMap && result.map) { 27396 resultMap = result.map; 27397 if (!existingMap && !config._buildSourceMap) { 27398 file.saveFile(outFileName + '.src.js', fileContents); 27399 } 27400 27401 fileContents = result.code; 27402 27403 if (config._buildSourceMap) { 27404 config._buildSourceMap = resultMap;
27405 } else { 27406 file.saveFile(outFileName + '.map', resultMap); 27407 } 27408 } else { 27409 fileContents = result.code; 27410 } 27411 } catch (e) { 27412 var errorString = e.toString(); 27413 var isSyntaxError = /SyntaxError/.test(errorString); 27414 throw new Error('Cannot uglify file: ' + fileName + 27415 '. Skipping it. Error is:\n' + errorString + 27416 (isSyntaxError ? '\n\n' + es5PlusGuidance : '')); 27417 } 27418 return fileContents; 27419 } 27420 } 27421 }; 27422 27423 return optimize; 27424}); 27425/* 27426 * This file patches require.js to communicate with the build system. 27427 */ 27428 27429//Using sloppy since this uses eval for some code like plugins, 27430//which may not be strict mode compliant. So if use strict is used 27431//below they will have strict rules applied and may cause an error. 27432/*jslint sloppy: true, nomen: true, plusplus: true, regexp: true */ 27433/*global require, define: true */ 27434 27435//NOT asking for require as a dependency since the goal is to modify the 27436//global require below 27437define('requirePatch', [ 'env!env/file', 'pragma', 'parse', 'lang', 'logger', 'commonJs', 'prim'], function ( 27438 file, 27439 pragma, 27440 parse, 27441 lang, 27442 logger, 27443 commonJs, 27444 prim 27445) { 27446 27447 var allowRun = true, 27448 hasProp = lang.hasProp, 27449 falseProp = lang.falseProp, 27450 getOwn = lang.getOwn, 27451 // Used to strip out use strict from toString()'d functions for the 27452 // shim config since they will explicitly want to not be bound by strict, 27453 // but some envs, explicitly xpcshell, adds a use strict. 27454 useStrictRegExp = /['"]use strict['"];/g, 27455 //Absolute path if starts with /, \, or x: 27456 absoluteUrlRegExp = /^[\/\\]|^\w:/; 27457 27458 //Turn off throwing on resolution conflict, that was just an older prim 27459 //idea about finding errors early, but does not comply with how promises 27460 //should operate. 27461 prim.hideResolutionConflict = true; 27462 27463 //This method should be called when the patches to require should take hold. 27464 return function () { 27465 if (!allowRun) { 27466 return; 27467 } 27468 allowRun = false; 27469 27470 var layer, 27471 pluginBuilderRegExp = /(["']?)pluginBuilder(["']?)\s*[=\:]\s*["']([^'"\s]+)["']/, 27472 oldNewContext = require.s.newContext, 27473 oldDef, 27474 27475 //create local undefined values for module and exports, 27476 //so that when files are evaled in this function they do not 27477 //see the node values used for r.js 27478 exports, 27479 module; 27480 27481 /** 27482 * Reset "global" build caches that are kept around between 27483 * build layer builds. Useful to do when there are multiple 27484 * top level requirejs.optimize() calls. 27485 */ 27486 require._cacheReset = function () { 27487 //Stored raw text caches, used by browser use. 27488 require._cachedRawText = {}; 27489 //Stored cached file contents for reuse in other layers. 27490 require._cachedFileContents = {}; 27491 //Store which cached files contain a require definition. 27492 require._cachedDefinesRequireUrls = {}; 27493 }; 27494 require._cacheReset(); 27495 27496 /** 27497 * Makes sure the URL is something that can be supported by the 27498 * optimization tool. 27499 * @param {String} url 27500 * @returns {Boolean} 27501 */ 27502 require._isSupportedBuildUrl = function (url) { 27503 //Ignore URLs with protocols, hosts or question marks, means either network 27504 //access is needed to fetch it or it is too dynamic. Note that 27505 //on Windows, full paths are used for some urls, which include 27506 //the drive, like c:/something, so need to test for something other 27507 //than just a colon. 27508 if (url.indexOf("://") === -1 && url.indexOf("?") === -1 && 27509 url.indexOf('empty:') !== 0 && url.indexOf('//') !== 0) { 27510 return true; 27511 } else { 27512 if (!layer.ignoredUrls[url]) { 27513 if (url.indexOf('empty:') === -1) { 27514 logger.info('Cannot optimize network URL, skipping: ' + url); 27515 } 27516 layer.ignoredUrls[url] = true; 27517 } 27518 return false; 27519 } 27520 }; 27521 27522 function normalizeUrlWithBase(context, moduleName, url) { 27523 //Adjust the URL if it was not transformed to use baseUrl, but only 27524 //if the URL is not already an absolute path. 27525 if (require.jsExtRegExp.test(moduleName) && 27526 !absoluteUrlRegExp.test(url)) { 27527 url = (context.config.dir || context.config.dirBaseUrl) + url; 27528 } 27529 return url; 27530 } 27531
27532 //Overrides the new context call to add existing tracking features. 27533 require.s.newContext = function (name) { 27534 var context = oldNewContext(name), 27535 oldEnable = context.enable, 27536 moduleProto = context.Module.prototype, 27537 oldInit = moduleProto.init, 27538 oldCallPlugin = moduleProto.callPlugin; 27539 27540 //Only do this for the context used for building. 27541 if (name === '_') { 27542 //For build contexts, do everything sync 27543 context.nextTick = function (fn) { 27544 fn(); 27545 }; 27546 27547 context.needFullExec = {}; 27548 context.fullExec = {}; 27549 context.plugins = {}; 27550 context.buildShimExports = {}; 27551 27552 //Override the shim exports function generator to just 27553 //spit out strings that can be used in the stringified 27554 //build output. 27555 context.makeShimExports = function (value) { 27556 var fn; 27557 if (context.config.wrapShim) { 27558 fn = function () { 27559 var str = 'return '; 27560 // If specifies an export that is just a global 27561 // name, no dot for a `this.` and such, then also 27562 // attach to the global, for `var a = {}` files 27563 // where the function closure would hide that from 27564 // the global object. 27565 if (value.exports && value.exports.indexOf('.') === -1) { 27566 str += 'root.' + value.exports + ' = '; 27567 } 27568 27569 if (value.init) { 27570 str += '(' + value.init.toString() 27571 .replace(useStrictRegExp, '') + '.apply(this, arguments))'; 27572 } 27573 if (value.init && value.exports) { 27574 str += ' || '; 27575 } 27576 if (value.exports) { 27577 str += value.exports; 27578 } 27579 str += ';'; 27580 return str; 27581 }; 27582 } else { 27583 fn = function () { 27584 return '(function (global) {\n' + 27585 ' return function () {\n' + 27586 ' var ret, fn;\n' + 27587 (value.init ? 27588 (' fn = ' + value.init.toString() 27589 .replace(useStrictRegExp, '') + ';\n' + 27590 ' ret = fn.apply(global, arguments);\n') : '') + 27591 (value.exports ? 27592 ' return ret || global.' + value.exports + ';\n' : 27593 ' return ret;\n') + 27594 ' };\n' + 27595 '}(this))'; 27596 }; 27597 } 27598 27599 return fn; 27600 }; 27601 27602 context.enable = function (depMap, parent) { 27603 var id = depMap.id, 27604 parentId = parent && parent.map.id, 27605 needFullExec = context.needFullExec, 27606 fullExec = context.fullExec, 27607 mod = getOwn(context.registry, id); 27608 27609 if (mod && !mod.defined) { 27610 if (parentId && getOwn(needFullExec, parentId)) { 27611 needFullExec[id] = depMap; 27612 } 27613 27614 } else if ((getOwn(needFullExec, id) && falseProp(fullExec, id)) || 27615 (parentId && getOwn(needFullExec, parentId) && 27616 falseProp(fullExec, id))) { 27617 context.require.undef(id); 27618 } 27619 27620 return oldEnable.apply(context, arguments); 27621 }; 27622 27623 //Override load so that the file paths can be collected. 27624 context.load = function (moduleName, url) { 27625 /*jslint evil: true */ 27626 var contents, pluginBuilderMatch, builderName, 27627 shim, shimExports; 27628 27629 //Do not mark the url as fetched if it is 27630 //not an empty: URL, used by the optimizer. 27631 //In that case we need to be sure to call 27632 //load() for each module that is mapped to 27633 //empty: so that dependencies are satisfied 27634 //correctly. 27635 if (url.indexOf('empty:') === 0) { 27636 delete context.urlFetched[url]; 27637 } 27638 27639 //Only handle urls that can be inlined, so that means avoiding some 27640 //URLs like ones that require network access or may be too dynamic, 27641 //like JSONP 27642 if (require._isSupportedBuildUrl(url)) { 27643 //Adjust the URL if it was not transformed to use baseUrl. 27644 url = normalizeUrlWithBase(context, moduleName, url); 27645 27646 //Save the module name to path and path to module name mappings. 27647 layer.buildPathMap[moduleName] = url; 27648 layer.buildFileToModule[url] = moduleName; 27649 27650 if (hasProp(context.plugins, moduleName)) { 27651 //plugins need to have their source evaled as-is. 27652 context.needFullExec[moduleName] = true; 27653 } 27654 27655 prim().start(function () { 27656 if (hasProp(require._cachedFileContents, url) && 27657 (falseProp(context.needFullExec, moduleName) || 27658 getOwn(context.fullExec, moduleName))) { 27659 contents = require._cachedFileContents[url]; 27660 27661 //If it defines require, mark it so it can be hoisted. 27662 //Done here and in the else below, before the 27663 //else block removes code from the contents. 27664 //Related to #263 27665 if (!layer.existingRequireUrl && require._cachedDefines
27665RequireUrls[url]) { 27666 layer.existingRequireUrl = url; 27667 } 27668 } else { 27669 //Load the file contents, process for conditionals, then 27670 //evaluate it. 27671 return require._cacheReadAsync(url).then(function (text) { 27672 contents = text; 27673 27674 if (context.config.cjsTranslate && 27675 (!context.config.shim || !lang.hasProp(context.config.shim, moduleName))) { 27676 contents = commonJs.convert(url, contents); 27677 } 27678 27679 //If there is a read filter, run it now. 27680 if (context.config.onBuildRead) { 27681 contents = context.config.onBuildRead(moduleName, url, contents); 27682 } 27683 27684 contents = pragma.process(url, contents, context.config, 'OnExecute'); 27685 27686 //Find out if the file contains a require() definition. Need to know 27687 //this so we can inject plugins right after it, but before they are needed, 27688 //and to make sure this file is first, so that define calls work. 27689 try { 27690 if (!layer.existingRequireUrl && parse.definesRequire(url, contents)) { 27691 layer.existingRequireUrl = url; 27692 require._cachedDefinesRequireUrls[url] = true; 27693 } 27694 } catch (e1) { 27695 throw new Error('Parse error using esprima ' + 27696 'for file: ' + url + '\n' + e1); 27697 } 27698 }).then(function () { 27699 if (hasProp(context.plugins, moduleName)) { 27700 //This is a loader plugin, check to see if it has a build extension, 27701 //otherwise the plugin will act as the plugin builder too. 27702 pluginBuilderMatch = pluginBuilderRegExp.exec(contents); 27703 if (pluginBuilderMatch) { 27704 //Load the plugin builder for the plugin contents. 27705 builderName = context.makeModuleMap(pluginBuilderMatch[3], 27706 context.makeModuleMap(moduleName), 27707 null, 27708 true).id; 27709 return require._cacheReadAsync(context.nameToUrl(builderName)); 27710 } 27711 } 27712 return contents; 27713 }).then(function (text) { 27714 contents = text; 27715 27716 //Parse out the require and define calls. 27717 //Do this even for plugins in case they have their own 27718 //dependencies that may be separate to how the pluginBuilder works. 27719 try { 27720 if (falseProp(context.needFullExec, moduleName)) { 27721 contents = parse(moduleName, url, contents, { 27722 insertNeedsDefine: true, 27723 has: context.config.has, 27724 findNestedDependencies: context.config.findNestedDependencies 27725 }); 27726 } 27727 } catch (e2) { 27728 throw new Error('Parse error using esprima ' + 27729 'for file: ' + url + '\n' + e2); 27730 } 27731 27732 require._cachedFileContents[url] = contents; 27733 }); 27734 } 27735 }).then(function () { 27736 if (contents) { 27737 eval(contents); 27738 } 27739 27740 try { 27741 //If have a string shim config, and this is 27742 //a fully executed module, try to see if 27743 //it created a variable in this eval scope 27744 if (getOwn(context.needFullExec, moduleName)) { 27745 shim = getOwn(context.config.shim, moduleName); 27746 if (shim && shim.exports) { 27747 shimExports = eval(shim.exports); 27748 if (typeof shimExports !== 'undefined') { 27749 context.buildShimExports[moduleName] = shimExports; 27750 } 27751 } 27752 } 27753 27754 //Need to close out completion of this module 27755 //so that listeners will get notified that it is available. 27756 context.completeLoad(moduleName); 27757 } catch (e) { 27758 //Track which module could not complete loading. 27759 if (!e.moduleTree) { 27760 e.moduleTree = []; 27761 } 27762 e.moduleTree.push(moduleName); 27763 throw e; 27764 } 27765 }).then(null, function (eOuter) { 27766 27767 if (!eOuter.fileName) {
27768 eOuter.fileName = url; 27769 } 27770 throw eOuter; 27771 }).end(); 27772 } else { 27773 //With unsupported URLs still need to call completeLoad to 27774 //finish loading. 27775 context.completeLoad(moduleName); 27776 } 27777 }; 27778 27779 //Marks module has having a name, and optionally executes the 27780 //callback, but only if it meets certain criteria. 27781 context.execCb = function (name, cb, args, exports) { 27782 var buildShimExports = getOwn(layer.context.buildShimExports, name); 27783 27784 if (buildShimExports) { 27785 return buildShimExports; 27786 } else if (cb.__requireJsBuild || getOwn(layer.context.needFullExec, name)) { 27787 return cb.apply(exports, args); 27788 } 27789 return undefined; 27790 }; 27791 27792 moduleProto.init = function (depMaps) { 27793 if (context.needFullExec[this.map.id]) { 27794 lang.each(depMaps, lang.bind(this, function (depMap) { 27795 if (typeof depMap === 'string') { 27796 depMap = context.makeModuleMap(depMap, 27797 (this.map.isDefine ? this.map : this.map.parentMap), 27798 false, true); 27799 } 27800 27801 if (!context.fullExec[depMap.id]) { 27802 context.require.undef(depMap.id); 27803 } 27804 })); 27805 } 27806 27807 return oldInit.apply(this, arguments); 27808 }; 27809 27810 moduleProto.callPlugin = function () { 27811 var map = this.map, 27812 pluginMap = context.makeModuleMap(map.prefix), 27813 pluginId = pluginMap.id, 27814 pluginMod = getOwn(context.registry, pluginId); 27815 27816 context.plugins[pluginId] = true; 27817 context.needFullExec[pluginId] = map; 27818 27819 //If the module is not waiting to finish being defined, 27820 //undef it and start over, to get full execution. 27821 if (falseProp(context.fullExec, pluginId) && (!pluginMod || pluginMod.defined)) { 27822 context.require.undef(pluginMap.id); 27823 } 27824 27825 return oldCallPlugin.apply(this, arguments); 27826 }; 27827 } 27828 27829 return context; 27830 }; 27831 27832 //Clear up the existing context so that the newContext modifications 27833 //above will be active. 27834 delete require.s.contexts._; 27835 27836 /** Reset state for each build layer pass. */ 27837 require._buildReset = function () { 27838 var oldContext = require.s.contexts._; 27839 27840 //Clear up the existing context. 27841 delete require.s.contexts._; 27842 27843 //Set up new context, so the layer object can hold onto it. 27844 require({}); 27845 27846 layer = require._layer = { 27847 buildPathMap: {}, 27848 buildFileToModule: {}, 27849 buildFilePaths: [], 27850 pathAdded: {}, 27851 modulesWithNames: {}, 27852 needsDefine: {}, 27853 existingRequireUrl: "", 27854 ignoredUrls: {}, 27855 context: require.s.contexts._ 27856 }; 27857 27858 //Return the previous context in case it is needed, like for 27859 //the basic config object. 27860 return oldContext; 27861 }; 27862 27863 require._buildReset(); 27864 27865 //Override define() to catch modules that just define an object, so that 27866 //a dummy define call is not put in the build file for them. They do 27867 //not end up getting defined via context.execCb, so we need to catch them 27868 //at the define call. 27869 oldDef = define; 27870 27871 //This function signature does not have to be exact, just match what we 27872 //are looking for. 27873 define = function (name) { 27874 if (typeof name === "string" && falseProp(layer.needsDefine, name)) { 27875 layer.modulesWithNames[name] = true; 27876 } 27877 return oldDef.apply(require, arguments); 27878 }; 27879 27880 define.amd = oldDef.amd; 27881 27882 //Add some utilities for plugins 27883 require._readFile = file.readFile; 27884 require._fileExists = function (path) { 27885 return file.exists(path);
27886 }; 27887 27888 //Called when execManager runs for a dependency. Used to figure out 27889 //what order of execution. 27890 require.onResourceLoad = function (context, map) { 27891 var id = map.id, 27892 url; 27893 27894 // Fix up any maps that need to be normalized as part of the fullExec 27895 // plumbing for plugins to participate in the build. 27896 if (context.plugins && lang.hasProp(context.plugins, id)) { 27897 lang.eachProp(context.needFullExec, function(value, prop) { 27898 // For plugin entries themselves, they do not have a map 27899 // value in needFullExec, just a "true" entry. 27900 if (value !== true && value.prefix === id && value.unnormalized) { 27901 var map = context.makeModuleMap(value.originalName, value.parentMap); 27902 context.needFullExec[map.id] = map; 27903 } 27904 }); 27905 } 27906 27907 //If build needed a full execution, indicate it 27908 //has been done now. But only do it if the context is tracking 27909 //that. Only valid for the context used in a build, not for 27910 //other contexts being run, like for useLib, plain requirejs 27911 //use in node/rhino. 27912 if (context.needFullExec && getOwn(context.needFullExec, id)) { 27913 context.fullExec[id] = map; 27914 } 27915 27916 //A plugin. 27917 if (map.prefix) { 27918 if (falseProp(layer.pathAdded, id)) { 27919 layer.buildFilePaths.push(id); 27920 //For plugins the real path is not knowable, use the name 27921 //for both module to file and file to module mappings. 27922 layer.buildPathMap[id] = id; 27923 layer.buildFileToModule[id] = id; 27924 layer.modulesWithNames[id] = true; 27925 layer.pathAdded[id] = true; 27926 } 27927 } else if (map.url && require._isSupportedBuildUrl(map.url)) { 27928 //If the url has not been added to the layer yet, and it 27929 //is from an actual file that was loaded, add it now. 27930 url = normalizeUrlWithBase(context, id, map.url); 27931 if (!layer.pathAdded[url] && getOwn(layer.buildPathMap, id)) { 27932 //Remember the list of dependencies for this layer. 27933 layer.buildFilePaths.push(url); 27934 layer.pathAdded[url] = true; 27935 } 27936 } 27937 }; 27938 27939 //Called by output of the parse() function, when a file does not 27940 //explicitly call define, probably just require, but the parse() 27941 //function normalizes on define() for dependency mapping and file 27942 //ordering works correctly. 27943 require.needsDefine = function (moduleName) { 27944 layer.needsDefine[moduleName] = true; 27945 }; 27946 }; 27947}); 27948/*jslint */ 27949/*global define: false, console: false */ 27950 27951define('commonJs', ['env!env/file', 'parse'], function (file, parse) { 27952 'use strict'; 27953 var commonJs = { 27954 //Set to false if you do not want this file to log. Useful in environments 27955 //like node where you want the work to happen without noise. 27956 useLog: true, 27957 27958 convertDir: function (commonJsPath, savePath) { 27959 var fileList, i, 27960 jsFileRegExp = /\.js$/, 27961 fileName, convertedFileName, fileContents; 27962 27963 //Get list of files to convert. 27964 fileList = file.getFilteredFileList(commonJsPath, /\w/, true); 27965 27966 //Normalize on front slashes and make sure the paths do not end in a slash. 27967 commonJsPath = commonJsPath.replace(/\\/g, "/"); 27968 savePath = savePath.replace(/\\/g, "/"); 27969 if (commonJsPath.charAt(commonJsPath.length - 1) === "/") { 27970 commonJsPath = commonJsPath.substring(0, commonJsPath.length - 1); 27971 } 27972 if (savePath.charAt(savePath.length - 1) === "/") { 27973 savePath = savePath.substring(0, savePath.length - 1); 27974 } 27975 27976 //Cycle through all the JS files and convert them. 27977 if (!fileList || !fileList.length) { 27978 if (commonJs.useLog) { 27979 if (commonJsPath === "convert") { 27980 //A request just to convert one file. 27981 console.log('\n\n' + commonJs.convert(savePath, file.readFile(savePath))); 27982 } else { 27983 console.log("No files to convert in directory: " + commonJsPath); 27984 } 27985 } 27986 } else { 27987 for (i = 0; i < fileList.length; i++) { 27988 fileName = fileList[i]; 27989 convertedFileName = fileName.replace(commonJsPath, savePath); 27990 27991 //Handle JS files. 27992 if (jsFileRegExp.test(fileName)) { 27993 fileContents = file.readFile(fileName); 27994 fileContents = commonJs.convert(fileName, fileContents); 27995 file.saveUtf8File(convertedFileName, fileContents); 27996 } else {
27997 //Just copy the file over. 27998 file.copyFile(fileName, convertedFileName, true); 27999 } 28000 } 28001 } 28002 }, 28003 28004 /** 28005 * Does the actual file conversion. 28006 * 28007 * @param {String} fileName the name of the file. 28008 * 28009 * @param {String} fileContents the contents of a file :) 28010 * 28011 * @returns {String} the converted contents 28012 */ 28013 convert: function (fileName, fileContents) { 28014 //Strip out comments. 28015 try { 28016 var preamble = '', 28017 commonJsProps = parse.usesCommonJs(fileName, fileContents); 28018 28019 //First see if the module is not already RequireJS-formatted. 28020 if (parse.usesAmdOrRequireJs(fileName, fileContents) || !commonJsProps) { 28021 return fileContents; 28022 } 28023 28024 if (commonJsProps.dirname || commonJsProps.filename) { 28025 preamble = 'var __filename = module.uri || "", ' + 28026 '__dirname = __filename.substring(0, __filename.lastIndexOf("/") + 1); '; 28027 } 28028 28029 //Construct the wrapper boilerplate. 28030 fileContents = 'define(function (require, exports, module) {' + 28031 preamble + 28032 fileContents + 28033 '\n});\n'; 28034 28035 } catch (e) { 28036 console.log("commonJs.convert: COULD NOT CONVERT: " + fileName + ", so skipping it. Error was: " + e); 28037 return fileContents; 28038 } 28039 28040 return fileContents; 28041 } 28042 }; 28043 28044 return commonJs; 28045}); 28046/*jslint plusplus: true, nomen: true, regexp: true */ 28047/*global define, requirejs, java, process, console */ 28048 28049 28050define('build', function (require) { 28051 'use strict'; 28052 28053 var build, 28054 lang = require('lang'), 28055 prim = require('prim'), 28056 logger = require('logger'), 28057 file = require('env!env/file'), 28058 parse = require('parse'), 28059 optimize = require('optimize'), 28060 pragma = require('pragma'), 28061 transform = require('transform'), 28062 requirePatch = require('requirePatch'), 28063 env = require('env'), 28064 commonJs = require('commonJs'), 28065 SourceMapGenerator = require('source-map').SourceMapGenerator, 28066 hasProp = lang.hasProp, 28067 getOwn = lang.getOwn, 28068 falseProp = lang.falseProp, 28069 endsWithSemiColonRegExp = /;\s*$/, 28070 endsWithSlashRegExp = /[\/\\]$/, 28071 resourceIsModuleIdRegExp = /^[\w\/\\\.]+$/, 28072 deepCopyProps = { 28073 layer: true 28074 }; 28075 28076 //Deep copy a config object, but do not copy over the "layer" property, 28077 //as it can be a deeply nested structure with a full requirejs context. 28078 function copyConfig(obj) { 28079 return lang.deeplikeCopy(obj, deepCopyProps); 28080 } 28081 28082 prim.nextTick = function (fn) { 28083 fn(); 28084 }; 28085 28086 //Now map require to the outermost requirejs, now that we have 28087 //local dependencies for this module. The rest of the require use is 28088 //manipulating the requirejs loader. 28089 require = requirejs; 28090 28091 //Caching function for performance. Attached to 28092 //require so it can be reused in requirePatch.js. _cachedRawText 28093 //set up by requirePatch.js 28094 require._cacheReadAsync = function (path, encoding) { 28095 var d; 28096 28097 if (lang.hasProp(require._cachedRawText, path)) { 28098 d = prim(); 28099 d.resolve(require._cachedRawText[path]); 28100 return d.promise; 28101 } else { 28102 return file.readFileAsync(path, encoding).then(function (text) { 28103 require._cachedRawText[path] = text; 28104 return text; 28105 }); 28106 } 28107 }; 28108 28109 function makeBuildBaseConfig() { 28110 return { 28111 appDir: "", 28112 pragmas: {}, 28113 paths: {}, 28114 optimize: "uglify", 28115 optimizeCss: "standard.keepLines.keepWhitespace", 28116 inlineText: true, 28117 isBuild: true, 28118 optimizeAllPluginResources: false, 28119 findNestedDependencies: false, 28120 preserveLicenseComments: true, 28121 writeBuildTxt: true, 28122 //Some builds can take a while, up the default limit. 28123 waitSeconds: 30, 28124 //By default, all files/directories are copied, unless 28125 //they match this regexp, by default just excludes .folders 28126 dirExclusionRegExp: file.dirExclusionRegExp, 28127 _buildPathToModuleIndex: {} 28128 }; 28129 } 28130 28131 /** 28132 * Some JS may not be valid if concatenated with other JS, in particular 28133 * the style of omitting semicolons and rely on ASI. Add a semicolon in 28134 * those cases. 28135 */ 28136 function addSemiColon(text, config) { 28137 if (config.skipSemiColonInsertion || endsWithSemiColonRegExp.test(text)) { 28138 return text; 28139 } else {
28140 return text + ";"; 28141 } 28142 } 28143 28144 function endsWithSlash(dirName) { 28145 if (dirName.charAt(dirName.length - 1) !== "/") { 28146 dirName += "/"; 28147 } 28148 return dirName; 28149 } 28150 28151 function endsWithNewLine(text) { 28152 if (text.charAt(text.length - 1) !== "\n") { 28153 text += "\n"; 28154 } 28155 return text; 28156 } 28157 28158 //Method used by plugin writeFile calls, defined up here to avoid 28159 //jslint warning about "making a function in a loop". 28160 function makeWriteFile(namespace, layer) { 28161 function writeFile(name, contents) { 28162 logger.trace('Saving plugin-optimized file: ' + name); 28163 file.saveUtf8File(name, contents); 28164 } 28165 28166 writeFile.asModule = function (moduleName, fileName, contents) { 28167 writeFile(fileName, 28168 build.toTransport(namespace, moduleName, fileName, contents, layer)); 28169 }; 28170 28171 return writeFile; 28172 } 28173 28174 /** 28175 * Appends singleContents to fileContents and returns the result. If a sourceMapGenerator 28176 * is provided, adds singleContents to the source map. 28177 * 28178 * @param {string} fileContents - The file contents to which to append singleContents 28179 * @param {string} singleContents - The additional contents to append to fileContents 28180 * @param {string} path - An absolute path of a file whose name to use in the source map. 28181 * The file need not actually exist if the code in singleContents is generated. 28182 * @param {{out: ?string, baseUrl: ?string}} config - The build configuration object. 28183 * @param {?{_buildPath: ?string}} module - An object with module information. 28184 * @param {?SourceMapGenerator} sourceMapGenerator - An instance of Mozilla's SourceMapGenerator, 28185 * or null if no source map is being generated. 28186 * @returns {string} fileContents with singleContents appended 28187 */ 28188 function appendToFileContents(fileContents, singleContents, path, config, module, sourceMapGenerator) { 28189 var refPath, sourceMapPath, resourcePath, pluginId, sourceMapLineNumber, lineCount, parts, i; 28190 if (sourceMapGenerator) { 28191 if (config.out) { 28192 refPath = config.baseUrl; 28193 } else if (module && module._buildPath) { 28194 refPath = module._buildPath; 28195 } else { 28196 refPath = ""; 28197 } 28198 parts = path.split('!'); 28199 if (parts.length === 1) { 28200 //Not a plugin resource, fix the path 28201 sourceMapPath = build.makeRelativeFilePath(refPath, path); 28202 } else { 28203 //Plugin resource. If it looks like just a plugin 28204 //followed by a module ID, pull off the plugin 28205 //and put it at the end of the name, otherwise 28206 //just leave it alone. 28207 pluginId = parts.shift(); 28208 resourcePath = parts.join('!'); 28209 if (resourceIsModuleIdRegExp.test(resourcePath)) { 28210 sourceMapPath = build.makeRelativeFilePath(refPath, require.toUrl(resourcePath)) + 28211 '!' + pluginId; 28212 } else { 28213 sourceMapPath = path; 28214 } 28215 } 28216 28217 sourceMapLineNumber = fileContents.split('\n').length - 1; 28218 lineCount = singleContents.split('\n').length; 28219 for (i = 1; i <= lineCount; i += 1) { 28220 sourceMapGenerator.addMapping({ 28221 generated: { 28222 line: sourceMapLineNumber + i, 28223 column: 0 28224 }, 28225 original: { 28226 line: i, 28227 column: 0 28228 }, 28229 source: sourceMapPath 28230 }); 28231 } 28232 28233 //Store the content of the original in the source 28234 //map since other transforms later like minification 28235 //can mess up translating back to the original 28236 //source. 28237 sourceMapGenerator.setSourceContent(sourceMapPath, singleContents); 28238 } 28239 fileContents += singleContents; 28240 return fileContents; 28241 } 28242 28243 /** 28244 * Main API entry point into the build. The args argument can either be 28245 * an array of arguments (like the onese passed on a command-line), 28246 * or it can be a JavaScript object that has the format of a build profile 28247 * file. 28248 * 28249 * If it is an object, then in addition to the normal properties allowed in 28250 * a build profile file, the object should contain one other property: 28251 *
28252 * The object could also contain a "buildFile" property, which is a string 28253 * that is the file path to a build profile that contains the rest 28254 * of the build profile directives. 28255 * 28256 * This function does not return a status, it should throw an error if 28257 * there is a problem completing the build. 28258 */ 28259 build = function (args) { 28260 var buildFile, cmdConfig, errorMsg, errorStack, stackMatch, errorTree, 28261 i, j, errorMod, 28262 stackRegExp = /( {4}at[^\n]+)\n/, 28263 standardIndent = ' '; 28264 28265 return prim().start(function () { 28266 if (!args || lang.isArray(args)) { 28267 if (!args || args.length < 1) { 28268 logger.error("build.js buildProfile.js\n" + 28269 "where buildProfile.js is the name of the build file (see example.build.js for hints on how to make a build file)."); 28270 return undefined; 28271 } 28272 28273 //Next args can include a build file path as well as other build args. 28274 //build file path comes first. If it does not contain an = then it is 28275 //a build file path. Otherwise, just all build args. 28276 if (args[0].indexOf("=") === -1) { 28277 buildFile = args[0]; 28278 args.splice(0, 1); 28279 } 28280 28281 //Remaining args are options to the build 28282 cmdConfig = build.convertArrayToObject(args); 28283 cmdConfig.buildFile = buildFile; 28284 } else { 28285 cmdConfig = args; 28286 } 28287 28288 return build._run(cmdConfig); 28289 }).then(null, function (e) { 28290 var err; 28291 28292 errorMsg = e.toString(); 28293 errorTree = e.moduleTree; 28294 stackMatch = stackRegExp.exec(errorMsg); 28295 28296 if (stackMatch) { 28297 errorMsg += errorMsg.substring(0, stackMatch.index + stackMatch[0].length + 1); 28298 } 28299 28300 //If a module tree that shows what module triggered the error, 28301 //print it out. 28302 if (errorTree && errorTree.length > 0) { 28303 errorMsg += '\nIn module tree:\n'; 28304 28305 for (i = errorTree.length - 1; i > -1; i--) { 28306 errorMod = errorTree[i]; 28307 if (errorMod) { 28308 for (j = errorTree.length - i; j > -1; j--) { 28309 errorMsg += standardIndent; 28310 } 28311 errorMsg += errorMod + '\n'; 28312 } 28313 } 28314 28315 logger.error(errorMsg); 28316 } 28317 28318 errorStack = e.stack; 28319 28320 if (typeof args === 'string' && args.indexOf('stacktrace=true') !== -1) { 28321 errorMsg += '\n' + errorStack; 28322 } else { 28323 if (!stackMatch && errorStack) { 28324 //Just trim out the first "at" in the stack. 28325 stackMatch = stackRegExp.exec(errorStack); 28326 if (stackMatch) { 28327 errorMsg += '\n' + stackMatch[0] || ''; 28328 } 28329 } 28330 } 28331 28332 err = new Error(errorMsg); 28333 err.originalError = e; 28334 throw err; 28335 }); 28336 }; 28337 28338 build._run = function (cmdConfig) { 28339 var buildPaths, fileName, fileNames, 28340 paths, i, 28341 baseConfig, config, 28342 modules, srcPath, buildContext, 28343 destPath, moduleMap, parentModuleMap, context, 28344 resources, resource, plugin, fileContents, 28345 pluginProcessed = {}, 28346 buildFileContents = "", 28347 pluginCollector = {}; 28348 28349 return prim().start(function () { 28350 var prop; 28351 28352 //Can now run the patches to require.js to allow it to be used for 28353 //build generation. Do it here instead of at the top of the module 28354 //because we want normal require behavior to load the build tool 28355 //then want to switch to build mode. 28356 requirePatch(); 28357 28358 config = build.createConfig(cmdConfig); 28359 paths = config.paths; 28360 28361 //Remove the previous build dir, in case it contains source transforms, 28362 //like the ones done with onBuildRead and onBuildWrite. 28363 if (config.dir && !config.keepBuildDir && file.exists(config.dir)) { 28364 file.deleteFile(config.dir); 28365 } 28366 28367 if (!config.out && !config.cssIn) { 28368 //This is not just a one-off file build but a full build profile, with 28369 //lots of files to process. 28370 28371 //First copy all the baseUrl content 28372 file.copyDir((config.appDir || config.baseUrl), config.dir, /\w/, true); 28373 28374 //Adjust baseUrl if config.appDir is in play, and set up build output paths. 28375 buildPaths = {}; 28376 if (config.appDir) { 28377 //All the paths should be inside the appDir, so just adjust 28378 //the paths to use the dirBaseUrl 28379 for (prop in paths) { 28380 if (hasProp(paths, prop)) { 28381 buildPaths[prop] = paths[prop].replace(config.appDir, config.dir); 28382 } 28383 } 28384 } else { 28385 //If no appDir, then make sure to copy the other paths to this directory. 28386 for (prop in paths) { 28387 if (hasProp(paths, prop)) { 28388 //Set up build path for each path prefix, but only do so 28389 //if the path falls out of the current baseUrl 28390 if (paths[prop].indexOf(config.baseUrl) === 0) { 28391 buildPaths[prop] = paths[prop].replace(config.baseUrl, config.dirBaseUrl); 28392 } else { 28393 buildPaths[prop] = paths[prop] === 'empty:' ? 'empty:' : prop; 28394 28395 //Make sure source path is fully formed with baseUrl, 28396 //if it is a relative URL. 28397 srcPath = paths[prop]; 28398 if (srcPath.indexOf('/') !== 0 && srcPath.indexOf(':') === -1) { 28399 srcPath = config.baseUrl + srcPath; 28400 } 28401 28402 destPath = config.dirBaseUrl + buildPaths[prop]; 28403 28404 //Skip empty: paths 28405 if (srcPath !== 'empty:') { 28406 //If the srcPath is a directory, copy the whole directory. 28407 if (file.exists(srcPath) && file.isDirectory(srcPath)) { 28408 //Copy files to build area. Copy all files (the /\w/ regexp) 28409 file.copyDir(srcPath, destPath, /\w/, true); 28410 } else { 28411 //Try a .js extension 28412 srcPath += '.js'; 28413 destPath += '.js'; 28414 file.copyFile(srcPath, destPath); 28415 } 28416 } 28417 } 28418 } 28419 } 28420 } 28421 } 28422 28423 //Figure out source file location for each module layer. Do this by seeding require 28424 //with source area configuration. This is needed so that later the module layers 28425 //can be manually copied over to the source area, since the build may be 28426 //require multiple times and the above copyDir call only copies newer files. 28427 require({ 28428 baseUrl: config.baseUrl, 28429 paths: paths, 28430 packagePaths: config.packagePaths, 28431 packages: config.packages 28432 }); 28433 buildContext = require.s.contexts._; 28434 modules = config.modules; 28435 28436 if (modules) {
28437 modules.forEach(function (module) { 28438 if (module.name) { 28439 module._sourcePath = buildContext.nameToUrl(module.name); 28440 //If the module does not exist, and this is not a "new" module layer, 28441 //as indicated by a true "create" property on the module, and 28442 //it is not a plugin-loaded resource, and there is no 28443 //'rawText' containing the module's source then throw an error. 28444 if (!file.exists(module._sourcePath) && !module.create && 28445 module.name.indexOf('!') === -1 && 28446 (!config.rawText || !lang.hasProp(config.rawText, module.name))) { 28447 throw new Error("ERROR: module path does not exist: " + 28448 module._sourcePath + " for module named: " + module.name + 28449 ". Path is relative to: " + file.absPath('.')); 28450 } 28451 } 28452 }); 28453 } 28454 28455 if (config.out) { 28456 //Just set up the _buildPath for the module layer. 28457 require(config); 28458 if (!config.cssIn) { 28459 config.modules[0]._buildPath = typeof config.out === 'function' ? 28460 'FUNCTION' : config.out; 28461 } 28462 } else if (!config.cssIn) { 28463 //Now set up the config for require to use the build area, and calculate the 28464 //build file locations. Pass along any config info too. 28465 baseConfig = { 28466 baseUrl: config.dirBaseUrl, 28467 paths: buildPaths 28468 }; 28469 28470 lang.mixin(baseConfig, config); 28471 require(baseConfig); 28472 28473 if (modules) { 28474 modules.forEach(function (module) { 28475 if (module.name) { 28476 module._buildPath = buildContext.nameToUrl(module.name, null); 28477 28478 //If buildPath and sourcePath are the same, throw since this 28479 //would result in modifying source. This condition can happen 28480 //with some more tricky paths: config and appDir/baseUrl 28481 //setting, which is a sign of incorrect config. 28482 if (module._buildPath === module._sourcePath && 28483 !config.allowSourceOverwrites) { 28484 throw new Error('Module ID \'' + module.name + 28485 '\' has a source path that is same as output path: ' + 28486 module._sourcePath + 28487 '. Stopping, config is malformed.'); 28488 } 28489 28490 // Copy the file, but only if it is not provided in rawText. 28491 if (!module.create && (!config.rawText || !lang.hasProp(config.rawText, module.name))) { 28492 file.copyFile(module._sourcePath, module._buildPath); 28493 } 28494 } 28495 }); 28496 } 28497 } 28498 28499 //Run CSS optimizations before doing JS module tracing, to allow 28500 //things like text loader plugins loading CSS to get the optimized 28501 //CSS. 28502 if (config.optimizeCss && config.optimizeCss !== "none" && config.dir) { 28503 buildFileContents += optimize.css(config.dir, config); 28504 } 28505 }).then(function() { 28506 baseConfig = copyConfig(require.s.contexts._.config); 28507 }).then(function () { 28508 var actions = []; 28509 28510 if (modules) { 28511 actions = modules.map(function (module, i) { 28512 return function () { 28513 //Save off buildPath to module index in a hash for quicker 28514 //lookup later. 28515 config._buildPathToModuleIndex[file.normalize(module._buildPath)] = i; 28516 28517 //Call require to calculate dependencies.
28518 return build.traceDependencies(module, config, baseConfig) 28519 .then(function (layer) { 28520 module.layer = layer; 28521 }); 28522 }; 28523 }); 28524 28525 return prim.serial(actions); 28526 } 28527 }).then(function () { 28528 var actions; 28529 28530 if (modules) { 28531 //Now build up shadow layers for anything that should be excluded. 28532 //Do this after tracing dependencies for each module, in case one 28533 //of those modules end up being one of the excluded values. 28534 actions = modules.map(function (module) { 28535 return function () { 28536 if (module.exclude) { 28537 module.excludeLayers = []; 28538 return prim.serial(module.exclude.map(function (exclude, i) { 28539 return function () { 28540 //See if it is already in the list of modules. 28541 //If not trace dependencies for it. 28542 var found = build.findBuildModule(exclude, modules); 28543 if (found) { 28544 module.excludeLayers[i] = found; 28545 } else { 28546 return build.traceDependencies({name: exclude}, config, baseConfig) 28547 .then(function (layer) { 28548 module.excludeLayers[i] = { layer: layer }; 28549 }); 28550 } 28551 }; 28552 })); 28553 } 28554 }; 28555 }); 28556 28557 return prim.serial(actions); 28558 } 28559 }).then(function () { 28560 if (modules) { 28561 return prim.serial(modules.map(function (module) { 28562 return function () { 28563 if (module.exclude) { 28564 //module.exclude is an array of module names. For each one, 28565 //get the nested dependencies for it via a matching entry 28566 //in the module.excludeLayers array. 28567 module.exclude.forEach(function (excludeModule, i) { 28568 var excludeLayer = module.excludeLayers[i].layer, 28569 map = excludeLayer.buildFileToModule; 28570 excludeLayer.buildFilePaths.forEach(function(filePath){ 28571 build.removeModulePath(map[filePath], filePath, module.layer); 28572 }); 28573 }); 28574 } 28575 if (module.excludeShallow) { 28576 //module.excludeShallow is an array of module names. 28577 //shallow exclusions are just that module itself, and not 28578 //its nested dependencies. 28579 module.excludeShallow.forEach(function (excludeShallowModule) { 28580 var path = getOwn(module.layer.buildPathMap, excludeShallowModule); 28581 if (path) { 28582 build.removeModulePath(excludeShallowModule, path, module.layer); 28583 } 28584 }); 28585 } 28586 28587 //Flatten them and collect the build output for each module. 28588 return build.flattenModule(module, module.layer, config).then(function (builtModule) { 28589 var finalText, baseName; 28590 //Save it to a temp file for now, in case there are other layers that 28591 //contain optimized content that should not be included in later 28592 //layer optimizations. See issue #56. 28593 if (module._buildPath === 'FUNCTION') { 28594 module._buildText = builtModule.text; 28595 module._buildSourceMap = builtModule.sourceMap;
28596 } else { 28597 finalText = builtModule.text; 28598 if (builtModule.sourceMap) { 28599 baseName = module._buildPath.split('/'); 28600 baseName = baseName.pop(); 28601 finalText += '\n//# sourceMappingURL=' + baseName + '.map'; 28602 file.saveUtf8File(module._buildPath + '.map', builtModule.sourceMap); 28603 } 28604 file.saveUtf8File(module._buildPath + '-temp', finalText); 28605 28606 } 28607 buildFileContents += builtModule.buildText; 28608 }); 28609 }; 28610 })); 28611 } 28612 }).then(function () { 28613 var moduleName, outOrigSourceMap, 28614 bundlesConfig = {}, 28615 bundlesConfigOutFile = config.bundlesConfigOutFile; 28616 28617 if (modules) { 28618 //Now move the build layers to their final position. 28619 modules.forEach(function (module) { 28620 var entryConfig, 28621 finalPath = module._buildPath; 28622 28623 if (finalPath !== 'FUNCTION') { 28624 if (file.exists(finalPath)) { 28625 file.deleteFile(finalPath); 28626 } 28627 file.renameFile(finalPath + '-temp', finalPath); 28628 28629 //If bundles config should be written out, scan the 28630 //built file for module IDs. Favor doing this reparse 28631 //since tracking the IDs as the file is built has some 28632 //edge cases around files that had more than one ID in 28633 //them already, and likely loader plugin-written contents. 28634 if (bundlesConfigOutFile) { 28635 entryConfig = bundlesConfig[module.name] = []; 28636 var bundleContents = file.readFile(finalPath); 28637 var excludeMap = {}; 28638 excludeMap[module.name] = true; 28639 var parsedIds = parse.getAllNamedDefines(bundleContents, excludeMap); 28640 entryConfig.push.apply(entryConfig, parsedIds); 28641 } 28642 28643 //And finally, if removeCombined is specified, remove 28644 //any of the files that were used in this layer. 28645 //Be sure not to remove other build layers. 28646 if (config.removeCombined && !config.out) { 28647 module.layer.buildFilePaths.forEach(function (path) { 28648 var isLayer = modules.some(function (mod) { 28649 return mod._buildPath === path; 28650 }), 28651 relPath = build.makeRelativeFilePath(config.dir, path); 28652 28653 if (file.exists(path) && 28654 // not a build layer target 28655 !isLayer && 28656 // not outside the build directory 28657 relPath.indexOf('..') !== 0) { 28658 file.deleteFile(path); 28659 } 28660 }); 28661 } 28662 } 28663 28664 //Signal layer is done 28665 if (config.onModuleBundleComplete) { 28666 config.onModuleBundleComplete(module.onCompleteData); 28667 } 28668 }); 28669 28670 //Write out bundles config, if it is wanted. 28671 if (bundlesConfigOutFile) { 28672 var text = file.readFile(bundlesConfigOutFile); 28673 text = transform.modifyConfig(text, function (config) { 28674 if (!config.bundles) { 28675 config.bundles = {}; 28676 } 28677 28678 lang.eachProp(bundlesConfig, function (value, prop) { 28679 config.bundles[prop] = value; 28680 }); 28681 28682 return config; 28683 }); 28684 28685 file.saveUtf8File(bundlesConfigOutFile, text); 28686 } 28687 } 28688 28689 //If removeCombined in play, remove any empty directories that 28690 //may now exist because of its use 28691 if (config.removeCombined && !config.out && config.dir) { 28692 file.deleteEmptyDirs(config.dir); 28693 } 28694 28695 //Do other optimizations. 28696 if (config.out && !config.cssIn) { 28697 //Just need to worry about one JS file. 28698 fileName = config.modules[0]._buildPath; 28699 if (fileName === 'FUNCTION') { 28700 outOrigSourceMap = config.modules[0]._buildSourceMap;
28701 config._buildSourceMap = outOrigSourceMap; 28702 config.modules[0]._buildText = optimize.js((config.modules[0].name || 28703 config.modules[0].include[0] || 28704 fileName) + '.build.js', 28705 config.modules[0]._buildText, 28706 null, 28707 config); 28708 if (config._buildSourceMap && config._buildSourceMap !== outOrigSourceMap) { 28709 config.modules[0]._buildSourceMap = config._buildSourceMap; 28710 config._buildSourceMap = null; 28711 } 28712 } else { 28713 optimize.jsFile(fileName, null, fileName, config); 28714 } 28715 } else if (!config.cssIn) { 28716 //Normal optimizations across modules. 28717 28718 //JS optimizations. 28719 fileNames = file.getFilteredFileList(config.dir, /\.js$/, true); 28720 fileNames.forEach(function (fileName) { 28721 var cfg, override, moduleIndex; 28722 28723 //Generate the module name from the config.dir root. 28724 moduleName = fileName.replace(config.dir, ''); 28725 //Get rid of the extension 28726 moduleName = moduleName.substring(0, moduleName.length - 3); 28727 28728 //If there is an override for a specific layer build module, 28729 //and this file is that module, mix in the override for use 28730 //by optimize.jsFile. 28731 moduleIndex = getOwn(config._buildPathToModuleIndex, fileName); 28732 //Normalize, since getOwn could have returned undefined 28733 moduleIndex = moduleIndex === 0 || moduleIndex > 0 ? moduleIndex : -1; 28734 28735 //Try to avoid extra work if the other files do not need to 28736 //be read. Build layers should be processed at the very 28737 //least for optimization. 28738 if (moduleIndex > -1 || !config.skipDirOptimize || 28739 config.normalizeDirDefines === "all" || 28740 config.cjsTranslate) { 28741 //Convert the file to transport format, but without a name 28742 //inserted (by passing null for moduleName) since the files are 28743 //standalone, one module per file. 28744 fileContents = file.readFile(fileName); 28745 28746 28747 //For builds, if wanting cjs translation, do it now, so that 28748 //the individual modules can be loaded cross domain via 28749 //plain script tags. 28750 if (config.cjsTranslate && 28751 (!config.shim || !lang.hasProp(config.shim, moduleName))) { 28752 fileContents = commonJs.convert(fileName, fileContents); 28753 } 28754 28755 if (moduleIndex === -1) { 28756 if (config.onBuildRead) { 28757 fileContents = config.onBuildRead(moduleName, 28758 fileName, 28759 fileContents); 28760 } 28761 28762 //Only do transport normalization if this is not a build 28763 //layer (since it was already normalized) and if 28764 //normalizeDirDefines indicated all should be done. 28765 if (config.normalizeDirDefines === "all") { 28766 fileContents = build.toTransport(config.namespace, 28767 null, 28768 fileName, 28769 fileContents); 28770 } 28771 28772 if (config.onBuildWrite) { 28773 fileContents = config.onBuildWrite(moduleName, 28774 fileName, 28775 fileContents); 28776 } 28777 } 28778 28779 override = moduleIndex > -1 ? 28780 config.modules[moduleIndex].override : null; 28781 if (override) { 28782 cfg = build.createOverrideConfig(config, override); 28783 } else { 28784 cfg = config; 28785 } 28786 28787 if (moduleIndex > -1 || !config.skipDirOptimize) { 28788 optimize.jsFile(fileName, fileContents, fileName, cfg, pluginCollector); 28789 } 28790 } 28791 }); 28792 28793 //Normalize all the plugin resources. 28794 context = require.s.contexts._; 28795 28796 for (moduleName in pluginCollector) { 28797 if (hasProp(pluginCollector, moduleName)) { 28798 parentModuleMap = context.makeModuleMap(moduleName); 28799 resources = pluginCollector[moduleName]; 28800 for (i = 0; i < resources.length; i++) { 28801 resource = resources[i];
28802 moduleMap = context.makeModuleMap(resource, parentModuleMap); 28803 if (falseProp(context.plugins, moduleMap.prefix)) { 28804 //Set the value in context.plugins so it 28805 //will be evaluated as a full plugin. 28806 context.plugins[moduleMap.prefix] = true; 28807 28808 //Do not bother if the plugin is not available. 28809 if (!file.exists(require.toUrl(moduleMap.prefix + '.js'))) { 28810 continue; 28811 } 28812 28813 //Rely on the require in the build environment 28814 //to be synchronous 28815 context.require([moduleMap.prefix]); 28816 28817 //Now that the plugin is loaded, redo the moduleMap 28818 //since the plugin will need to normalize part of the path. 28819 moduleMap = context.makeModuleMap(resource, parentModuleMap); 28820 } 28821 28822 //Only bother with plugin resources that can be handled 28823 //processed by the plugin, via support of the writeFile 28824 //method. 28825 if (falseProp(pluginProcessed, moduleMap.id)) { 28826 //Only do the work if the plugin was really loaded. 28827 //Using an internal access because the file may 28828 //not really be loaded. 28829 plugin = getOwn(context.defined, moduleMap.prefix); 28830 if (plugin && plugin.writeFile) { 28831 plugin.writeFile( 28832 moduleMap.prefix, 28833 moduleMap.name, 28834 require, 28835 makeWriteFile( 28836 config.namespace 28837 ), 28838 context.config 28839 ); 28840 } 28841 28842 pluginProcessed[moduleMap.id] = true; 28843 } 28844 } 28845 28846 } 28847 } 28848 28849 //console.log('PLUGIN COLLECTOR: ' + JSON.stringify(pluginCollector, null, " ")); 28850 28851 28852 //All module layers are done, write out the build.txt file. 28853 if (config.writeBuildTxt) { 28854 file.saveUtf8File(config.dir + "build.txt", buildFileContents); 28855 } 28856 } 28857 28858 //If just have one CSS file to optimize, do that here. 28859 if (config.cssIn) { 28860 buildFileContents += optimize.cssFile(config.cssIn, config.out, config).buildText; 28861 } 28862 28863 if (typeof config.out === 'function') { 28864 config.out(config.modules[0]._buildText, config.modules[0]._buildSourceMap); 28865 } 28866 28867 //Print out what was built into which layers. 28868 if (buildFileContents) { 28869 logger.info(buildFileContents); 28870 return buildFileContents; 28871 } 28872 28873 return ''; 28874 }); 28875 }; 28876 28877 /** 28878 * Converts command line args like "paths.foo=../some/path" 28879 * result.paths = { foo: '../some/path' } where prop = paths, 28880 * name = paths.foo and value = ../some/path, so it assumes the 28881 * name=value splitting has already happened. 28882 */ 28883 function stringDotToObj(result, name, value) { 28884 var parts = name.split('.'); 28885 28886 parts.forEach(function (prop, i) { 28887 if (i === parts.length - 1) { 28888 result[prop] = value; 28889 } else { 28890 if (falseProp(result, prop)) { 28891 result[prop] = {}; 28892 } 28893 result = result[prop]; 28894 } 28895 28896 }); 28897 } 28898 28899 build.objProps = { 28900 paths: true, 28901 wrap: true, 28902 pragmas: true, 28903 pragmasOnSave: true, 28904 has: true, 28905 hasOnSave: true, 28906 uglify: true, 28907 uglify2: true, 28908 closure: true, 28909 map: true, 28910 throwWhen: true, 28911 rawText: true 28912 }; 28913 28914 build.hasDotPropMatch = function (prop) { 28915 var dotProp, 28916 index = prop.indexOf('.'); 28917 28918 if (index !== -1) { 28919 dotProp = prop.substring(0, index); 28920 return hasProp(build.objProps, dotProp); 28921 } 28922 return false; 28923 }; 28924 28925 /** 28926 * Converts an array that has String members of "name=value" 28927 * into an object, where the properties on the object are the names in the array. 28928 * Also converts the strings "true" and "false" to booleans for the values. 28929 * member name/value pairs, and converts some comma-separated lists into 28930 * arrays. 28931 * @param {Array} ary 28932 */ 28933 build.convertArrayToObject = function (ary) { 28934 var result = {}, i, separatorIndex, prop, value, 28935 needArray = { 28936 "include": true, 28937 "exclude": true, 28938 "excludeShallow": true, 28939 "insertRequire": true, 28940 "stubModules": true, 28941 "deps": true, 28942 "mainConfigFile": true, 28943 "wrap.startFile": true, 28944 "wrap.endFile": true 28945 }; 28946 28947 for (i = 0; i < ary.length; i++) { 28948 separatorIndex = ary[i].indexOf("="); 28949 if (separatorIndex === -1) { 28950 throw "Malformed name/value pair: [" + ary[i] + "]. Format should be name=value"; 28951 } 28952 28953 value = ary[i].substring(separatorIndex + 1, ary[i].length); 28954 if (value === "true") { 28955 value = true; 28956 }
28956 else if (value === "false") { 28957 value = false; 28958 } 28959 28960 prop = ary[i].substring(0, separatorIndex); 28961 28962 //Convert to array if necessary 28963 if (getOwn(needArray, prop)) { 28964 value = value.split(","); 28965 } 28966 28967 if (build.hasDotPropMatch(prop)) { 28968 stringDotToObj(result, prop, value); 28969 } else { 28970 result[prop] = value; 28971 } 28972 } 28973 return result; //Object 28974 }; 28975 28976 build.makeAbsPath = function (path, absFilePath) { 28977 if (!absFilePath) { 28978 return path; 28979 } 28980 28981 //Add abspath if necessary. If path starts with a slash or has a colon, 28982 //then already is an abolute path. 28983 if (path.indexOf('/') !== 0 && path.indexOf(':') === -1) { 28984 path = absFilePath + 28985 (absFilePath.charAt(absFilePath.length - 1) === '/' ? '' : '/') + 28986 path; 28987 path = file.normalize(path); 28988 } 28989 return path.replace(lang.backSlashRegExp, '/'); 28990 }; 28991 28992 build.makeAbsObject = function (props, obj, absFilePath) { 28993 var i, prop; 28994 if (obj) { 28995 for (i = 0; i < props.length; i++) { 28996 prop = props[i]; 28997 if (hasProp(obj, prop) && typeof obj[prop] === 'string') { 28998 obj[prop] = build.makeAbsPath(obj[prop], absFilePath); 28999 } 29000 } 29001 } 29002 }; 29003 29004 /** 29005 * For any path in a possible config, make it absolute relative 29006 * to the absFilePath passed in. 29007 */ 29008 build.makeAbsConfig = function (config, absFilePath) { 29009 var props, prop, i; 29010 29011 props = ["appDir", "dir", "baseUrl"]; 29012 for (i = 0; i < props.length; i++) { 29013 prop = props[i]; 29014 29015 if (getOwn(config, prop)) { 29016 //Add abspath if necessary, make sure these paths end in 29017 //slashes 29018 if (prop === "baseUrl") { 29019 config.originalBaseUrl = config.baseUrl; 29020 if (config.appDir) { 29021 //If baseUrl with an appDir, the baseUrl is relative to 29022 //the appDir, *not* the absFilePath. appDir and dir are 29023 //made absolute before baseUrl, so this will work. 29024 config.baseUrl = build.makeAbsPath(config.originalBaseUrl, config.appDir); 29025 } else { 29026 //The dir output baseUrl is same as regular baseUrl, both 29027 //relative to the absFilePath. 29028 config.baseUrl = build.makeAbsPath(config[prop], absFilePath); 29029 } 29030 } else { 29031 config[prop] = build.makeAbsPath(config[prop], absFilePath); 29032 } 29033 29034 config[prop] = endsWithSlash(config[prop]); 29035 } 29036 } 29037 29038 build.makeAbsObject((config.out === "stdout" ? ["cssIn"] : ["out", "cssIn"]), 29039 config, absFilePath); 29040 build.makeAbsObject(["startFile", "endFile"], config.wrap, absFilePath); 29041 build.makeAbsObject(["externExportsPath"], config.closure, absFilePath); 29042 }; 29043 29044 /** 29045 * Creates a relative path to targetPath from refPath. 29046 * Only deals with file paths, not folders. If folders, 29047 * make sure paths end in a trailing '/'. 29048 */ 29049 build.makeRelativeFilePath = function (refPath, targetPath) { 29050 var i, dotLength, finalParts, length, targetParts, targetName, 29051 refParts = refPath.split('/'), 29052 hasEndSlash = endsWithSlashRegExp.test(targetPath), 29053 dotParts = []; 29054 29055 targetPath = file.normalize(targetPath); 29056 if (hasEndSlash && !endsWithSlashRegExp.test(targetPath)) { 29057 targetPath += '/'; 29058 } 29059 targetParts = targetPath.split('/'); 29060 //Pull off file name 29061 targetName = targetParts.pop(); 29062 29063 //Also pop off the ref file name to make the matches against 29064 //targetParts equivalent. 29065 refParts.pop(); 29066 29067 length = refParts.length; 29068 29069 for (i = 0; i < length; i += 1) { 29070 if (refParts[i] !== targetParts[i]) { 29071 break; 29072 } 29073 } 29074 29075 //Now i is the index in which they diverge. 29076 finalParts = targetParts.slice(i); 29077 29078 dotLength = length - i; 29079 for (i = 0; i > -1 && i < dotLength; i += 1) { 29080 dotParts.push('..'); 29081 } 29082 29083 return dotParts.join('/') + (dotParts.length ? '/' : '') + 29084 finalParts.join('/') + (finalParts.length ? '/' : '') + 29085 targetName; 29086 }; 29087 29088 build.nestedMix = { 29089 paths: true, 29090 has: true, 29091 hasOnSave: true, 29092 pragmas: true, 29093 pragmasOnSave: true 29094 }; 29095 29096 /** 29097 * Mixes additional source config into target config, and merges some 29098 * nested config, like paths, correctly. 29099 */ 29100 function mixConfig(target, source, skipArrays) { 29101 var prop, value, isArray, targetValue; 29102 29103 for (prop in source) { 29104 if (hasProp(source, prop)) { 29105 //If the value of the property is a plain object, then 29106 //allow a one-level-deep mixing of it. 29107 value = source[prop]; 29108 isArray = lang.isArray(value); 29109 if (typeof value === 'object' && value && 29110 !isArray && !lang.isFunction(value) && 29111 !lang.isRegExp(value)) { 29112 29113 // TODO: need to generalize this work, maybe also reuse 29114 // the work done in requirejs configure, perhaps move to 29115 // just a deep copy/merge overall. However, given the 29116 // amount of observable change, wait for a dot release. 29117 // This change is in relation to #645 29118 if (prop === 'map') { 29119 if (!target.map) { 29120 target.map = {}; 29121 }
29122 lang.deepMix(target.map, source.map); 29123 } else { 29124 target[prop] = lang.mixin({}, target[prop], value, true); 29125 } 29126 } else if (isArray) { 29127 if (!skipArrays) { 29128 // Some config, like packages, are arrays. For those, 29129 // just merge the results. 29130 targetValue = target[prop]; 29131 if (lang.isArray(targetValue)) { 29132 target[prop] = targetValue.concat(value); 29133 } else { 29134 target[prop] = value; 29135 } 29136 } 29137 } else { 29138 target[prop] = value; 29139 } 29140 } 29141 } 29142 29143 //Set up log level since it can affect if errors are thrown 29144 //or caught and passed to errbacks while doing config setup. 29145 if (lang.hasProp(target, 'logLevel')) { 29146 logger.logLevel(target.logLevel); 29147 } 29148 } 29149 29150 /** 29151 * Converts a wrap.startFile or endFile to be start/end as a string. 29152 * the startFile/endFile values can be arrays. 29153 */ 29154 function flattenWrapFile(config, keyName, absFilePath) { 29155 var wrap = config.wrap, 29156 keyFileName = keyName + 'File', 29157 keyMapName = '__' + keyName + 'Map'; 29158 29159 if (typeof wrap[keyName] !== 'string' && wrap[keyFileName]) { 29160 wrap[keyName] = ''; 29161 if (typeof wrap[keyFileName] === 'string') { 29162 wrap[keyFileName] = [wrap[keyFileName]]; 29163 } 29164 wrap[keyMapName] = []; 29165 wrap[keyFileName].forEach(function (fileName) { 29166 var absPath = build.makeAbsPath(fileName, absFilePath), 29167 fileText = endsWithNewLine(file.readFile(absPath)); 29168 wrap[keyMapName].push(function (fileContents, cfg, sourceMapGenerator) { 29169 return appendToFileContents(fileContents, fileText, absPath, cfg, null, sourceMapGenerator); 29170 }); 29171 wrap[keyName] += fileText; 29172 }); 29173 } else if (wrap[keyName] === null || wrap[keyName] === undefined) { 29174 //Allow missing one, just set to empty string. 29175 wrap[keyName] = ''; 29176 } else if (typeof wrap[keyName] === 'string') { 29177 wrap[keyName] = endsWithNewLine(wrap[keyName]); 29178 wrap[keyMapName] = [ 29179 function (fileContents, cfg, sourceMapGenerator) { 29180 var absPath = build.makeAbsPath("config-wrap-" + keyName + "-default.js", absFilePath); 29181 return appendToFileContents(fileContents, wrap[keyName], absPath, cfg, null, sourceMapGenerator); 29182 } 29183 ]; 29184 } else { 29185 throw new Error('wrap.' + keyName + ' or wrap.' + keyFileName + ' malformed'); 29186 } 29187 } 29188 29189 function normalizeWrapConfig(config, absFilePath) { 29190 //Get any wrap text. 29191 try { 29192 if (config.wrap) { 29193 if (config.wrap === true) { 29194 //Use default values. 29195 config.wrap = { 29196 start: '(function () {\n', 29197 end: '}());', 29198 __startMap: [ 29199 function (fileContents, cfg, sourceMapGenerator) { 29200 return appendToFileContents(fileContents, "(function () {\n", 29201 build.makeAbsPath("config-wrap-start-default.js", 29202 absFilePath), cfg, null, 29203 sourceMapGenerator); 29204 } 29205 ], 29206 __endMap: [ 29207 function (fileContents, cfg, sourceMapGenerator) { 29208 return appendToFileContents(fileContents, "}());", 29209 build.makeAbsPath("config-wrap-end-default.js", absFilePath), 29210 cfg, null, sourceMapGenerator); 29211 } 29212 ] 29213 }; 29214 } else { 29215 flattenWrapFile(config, 'start', absFilePath); 29216 flattenWrapFile(config, 'end', absFilePath); 29217 } 29218 } 29219 } catch (wrapError) { 29220 throw new Error('Malformed wrap config: ' + wrapError.toString()); 29221 } 29222 } 29223 29224 /** 29225 * Creates a config object for an optimization build. 29226 * It will also read the build profile if it is available, to create 29227 * the configuration. 29228 * 29229 * @param {Object} cfg config options that take priority 29230 * over defaults and ones in the build file. These options could 29231 * be from a command line, for instance. 29232 * 29233 * @param {Object} the created config object. 29234 */ 29235 build.createConfig = function (cfg) { 29236 /*jslint evil: true */ 29237 var buildFileContents, buildFileConfig, mainConfig, 29238 mainConfigFile, mainConfigPath, buildFile, absFilePath, 29239 config = {}, 29240 buildBaseConfig = makeBuildBaseConfig(); 29241 29242 //Make sure all paths are relative to current directory. 29243 absFilePath = file.absPath('.'); 29244 build.makeAbsConfig(cfg, absFilePath); 29245 build.makeAbsConfig(buildBaseConfig, absFilePath); 29246 29247 lang.mixin(config, buildBaseConfig); 29248 lang.mixin(config, cfg, true); 29249 29250 //Set up log level early since it can affect if errors are thrown 29251 //or caught and passed to errbacks, even while constructing config. 29252 if (lang.hasProp(config, 'logLevel')) { 29253 logger.logLevel(config.logLevel); 29254 } 29255 29256 if (config.buildFile) { 29257 //A build file exists, load it to get more config. 29258 buildFile = file.absPath(config.buildFile); 29259 29260 //Find the build file, and make sure it exists, if this is a build 29261 //that has a build profile, and not just command line args with an in=path 29262 if (!file.exists(buildFile)) { 29263 throw new Error("ERROR: build file does not exist: " + buildFile); 29264 } 29265 29266 absFilePath = config.baseUrl = file.absPath(file.parent(buildFile)); 29267 29268 //Load build file options. 29269 buildFileContents = file.readFile(buildFile); 29270 try { 29271 //Be a bit lenient in the file ending in a ; or ending with 29272 //a //# sourceMappingUrl comment, mostly for compiled languages 29273 //that create a config, like typescript. 29274 buildFileContents = buildFileContents 29275 .replace(/\/\/\#[^\n\r]+[\n\r]*$/, '') 29276 .trim() 29277 .replace(/;$/, ''); 29278 29279 buildFileConfig = eval("(" + buildFileContents + ")"); 29280 build.makeAbsConfig(buildFileConfig, absFilePath); 29281 29282 //Mix in the config now so that items in mainConfigFile can 29283 //be resolved relative to them if necessary, like if appDir 29284 //is set here, but the baseUrl is in mainConfigFile. Will 29285 //re-mix in the same build config later after mainConfigFile 29286 //is processed, since build config should take priority. 29287 mixConfig(config, buildFileConfig); 29288 } catch (e) { 29289 throw new Error("Build file " + buildFile + " is malformed: " + e); 29290 } 29291 } 29292 29293 mainConfigFile = config.mainConfigFile || (buildFileConfig && buildFileConfig.mainConfigFile); 29294 if (mainConfigFile) { 29295 if (typeof mainConfigFile === 'string') { 29296 mainConfigFile = [mainConfigFile]; 29297 } 29298 29299 mainConfigFile.forEach(function (configFile) { 29300 configFile = build.makeAbsPath(configFile, absFilePath); 29301 if (!file.exists(configFile)) { 29302 throw new Error(configFile + ' does not exist.'); 29303 } 29304 try { 29305 mainConfig = parse.findConfig(file.readFile(configFile)).config; 29306 } catch (configError) { 29307 throw new Error('The config in mainConfigFile ' + 29308 configFile + 29309 ' cannot be used because it cannot be evaluated' + 29310 ' correctly while running in the optimizer. Try only' + 29311 ' using a config that is also valid JSON, or do not use' + 29312 ' mainConfigFile and instead copy the config values needed' + 29313 ' into a build file or command line arguments given to the optimizer.\n' + 29314 'Source error from parsing: ' + configFile + ': ' + configError); 29315 } 29316 if (mainConfig) { 29317 mainConfigPath = configFile.substring(0, configFile.lastIndexOf('/')); 29318 29319 //Add in some existing config, like appDir, since they can be 29320 //used inside the configFile -- paths and baseUrl are 29321 //relative to them. 29322 if (config.appDir && !mainConfig.appDir) { 29323 mainConfig.appDir = config.appDir; 29324 } 29325 29326 //If no baseUrl, then use the directory holding the main config. 29327 if (!mainConfig.baseUrl) { 29328 mainConfig.baseUrl = mainConfigPath; 29329 } 29330 29331 build.makeAbsConfig(mainConfig, mainConfigPath); 29332 mixConfig(config, mainConfig); 29333 } 29334 }); 29335 } 29336 29337 //Mix in build file config, but only after mainConfig has been mixed in. 29338 //Since this is a re-application, skip array merging. 29339 if (buildFileConfig) { 29340 mixConfig(config, buildFileConfig, true); 29341 } 29342 29343 //Re-apply the override config values. Command line 29344 //args should take precedence over build file values. 29345 //Since this is a re-application, skip array merging. 29346 mixConfig(config, cfg, true); 29347
29348 //Fix paths to full paths so that they can be adjusted consistently 29349 //lately to be in the output area. 29350 lang.eachProp(config.paths, function (value, prop) { 29351 if (lang.isArray(value)) { 29352 throw new Error('paths fallback not supported in optimizer. ' + 29353 'Please provide a build config path override ' + 29354 'for ' + prop); 29355 } 29356 config.paths[prop] = build.makeAbsPath(value, config.baseUrl); 29357 }); 29358 29359 //Set final output dir 29360 if (hasProp(config, "baseUrl")) { 29361 if (config.appDir) { 29362 if (!config.originalBaseUrl) { 29363 throw new Error('Please set a baseUrl in the build config'); 29364 } 29365 config.dirBaseUrl = build.makeAbsPath(config.originalBaseUrl, config.dir); 29366 } else { 29367 config.dirBaseUrl = config.dir || config.baseUrl; 29368 } 29369 //Make sure dirBaseUrl ends in a slash, since it is 29370 //concatenated with other strings. 29371 config.dirBaseUrl = endsWithSlash(config.dirBaseUrl); 29372 } 29373 29374 if (config.bundlesConfigOutFile) { 29375 if (!config.dir) { 29376 throw new Error('bundlesConfigOutFile can only be used with optimizations ' + 29377 'that use "dir".'); 29378 } 29379 config.bundlesConfigOutFile = build.makeAbsPath(config.bundlesConfigOutFile, config.dir); 29380 } 29381 29382 //If out=stdout, write output to STDOUT instead of a file. 29383 if (config.out && config.out === 'stdout') { 29384 config.out = function (content) { 29385 var e = env.get(); 29386 if (e === 'rhino') { 29387 var out = new java.io.PrintStream(java.lang.System.out, true, 'UTF-8'); 29388 out.println(content); 29389 } else if (e === 'node') { 29390 process.stdout.write(content, 'utf8'); 29391 } else { 29392 console.log(content); 29393 } 29394 }; 29395 } 29396 29397 //Check for errors in config 29398 if (config.main) { 29399 throw new Error('"main" passed as an option, but the ' + 29400 'supported option is called "name".'); 29401 } 29402 if (config.out && !config.name && !config.modules && !config.include && 29403 !config.cssIn) { 29404 throw new Error('Missing either a "name", "include" or "modules" ' + 29405 'option'); 29406 } 29407 if (config.cssIn) { 29408 if (config.dir || config.appDir) { 29409 throw new Error('cssIn is only for the output of single file ' + 29410 'CSS optimizations and is not compatible with "dir" or "appDir" configuration.'); 29411 } 29412 if (!config.out) { 29413 throw new Error('"out" option missing.'); 29414 } 29415 } 29416 if (!config.cssIn && !config.baseUrl) { 29417 //Just use the current directory as the baseUrl 29418 config.baseUrl = './'; 29419 } 29420 if (!config.out && !config.dir) { 29421 throw new Error('Missing either an "out" or "dir" config value. ' + 29422 'If using "appDir" for a full project optimization, ' + 29423 'use "dir". If you want to optimize to one file, ' + 29424 'use "out".'); 29425 } 29426 if (config.appDir && config.out) { 29427 throw new Error('"appDir" is not compatible with "out". Use "dir" ' + 29428 'instead. appDir is used to copy whole projects, ' + 29429 'where "out" with "baseUrl" is used to just ' + 29430 'optimize to one file.'); 29431 } 29432 if (config.out && config.dir) { 29433 throw new Error('The "out" and "dir" options are incompatible.' + 29434 ' Use "out" if you are targeting a single file' + 29435 ' for optimization, and "dir" if you want the appDir' + 29436 ' or baseUrl directories optimized.'); 29437 } 29438 29439 29440 if (config.dir) { 29441 // Make sure the output dir is not set to a parent of the 29442 // source dir or the same dir, as it will result in source 29443 // code deletion. 29444 if (!config.allowSourceOverwrites && (config.dir === config.baseUrl || 29445 config.dir === config.appDir || 29446 (config.baseUrl && build.makeRelativeFilePath(config.dir, 29447 config.baseUrl).indexOf('..') !== 0) || 29448 (config.appDir && 29449 build.makeRelativeFilePath(config.dir, config.appDir).indexOf('..') !== 0))) { 29450 throw new Error('"dir" is set to a parent or same directory as' + 29451 ' "appDir" or "baseUrl". This can result in' + 29452 ' the deletion of source code. Stopping. If' + 29453 ' you want to allow possible overwriting of' + 29454 ' source code, set "allowSourceOverwrites"' + 29455 ' to true in the build config, but do so at' + 29456 ' your own risk. In that case, you may want' + 29457 ' to also set "keepBuildDir" to true.'); 29458 } 29459 } 29460 29461 if (config.insertRequire && !lang.isArray(config.insertRequire)) { 29462 throw new Error('insertRequire should be a list of module IDs' + 29463 ' to insert in to a require([]) call.'); 29464 } 29465 29466 //Support older configs with uglify2 settings, but now that uglify1 has 29467 //been removed, just translate it to 'uglify' settings. 29468 if (config.optimize === 'uglify2') { 29469 config.optimize = 'uglify'; 29470 } 29471 if (config.uglify2) { 29472 config.uglify = config.uglify2; 29473 delete config.uglify2; 29474 } 29475 29476 if (config.generateSourceMaps) { 29477 if (config.preserveLicenseComments && !(config.optimize === 'none' || config.optimize === 'uglify')) { 29478 throw new Error('Cannot use preserveLicenseComments and ' + 29479 'generateSourceMaps together, unless optimize is set ' + 29480 'to \'uglify\'. Either explicitly set preserveLicenseComments ' +
29481 'to false (default is true) or turn off generateSourceMaps. ' + 29482 'If you want source maps with license comments, see: ' + 29483 'http://requirejs.org/docs/errors.html#sourcemapcomments'); 29484 } else if (config.optimize !== 'none' && 29485 config.optimize !== 'closure' && 29486 config.optimize !== 'uglify') { 29487 //Allow optimize: none to pass, since it is useful when toggling 29488 //minification on and off to debug something, and it implicitly 29489 //works, since it does not need a source map. 29490 throw new Error('optimize: "' + config.optimize + 29491 '" does not support generateSourceMaps.'); 29492 } 29493 } 29494 29495 if ((config.name || config.include) && !config.modules) { 29496 //Just need to build one file, but may be part of a whole appDir/ 29497 //baseUrl copy, but specified on the command line, so cannot do 29498 //the modules array setup. So create a modules section in that 29499 //case. 29500 config.modules = [ 29501 { 29502 name: config.name, 29503 out: config.out, 29504 create: config.create, 29505 include: config.include, 29506 exclude: config.exclude, 29507 excludeShallow: config.excludeShallow, 29508 insertRequire: config.insertRequire, 29509 stubModules: config.stubModules 29510 } 29511 ]; 29512 delete config.stubModules; 29513 } else if (config.modules && config.out) { 29514 throw new Error('If the "modules" option is used, then there ' + 29515 'should be a "dir" option set and "out" should ' + 29516 'not be used since "out" is only for single file ' + 29517 'optimization output.'); 29518 } else if (config.modules && config.name) { 29519 throw new Error('"name" and "modules" options are incompatible. ' + 29520 'Either use "name" if doing a single file ' + 29521 'optimization, or "modules" if you want to target ' + 29522 'more than one file for optimization.'); 29523 } 29524 29525 if (config.out && !config.cssIn) { 29526 //Just one file to optimize. 29527 29528 //Does not have a build file, so set up some defaults. 29529 //Optimizing CSS should not be allowed, unless explicitly 29530 //asked for on command line. In that case the only task is 29531 //to optimize a CSS file. 29532 if (!cfg.optimizeCss) { 29533 config.optimizeCss = "none"; 29534 } 29535 } 29536 29537 //Normalize cssPrefix 29538 if (config.cssPrefix) { 29539 //Make sure cssPrefix ends in a slash 29540 config.cssPrefix = endsWithSlash(config.cssPrefix); 29541 } else { 29542 config.cssPrefix = ''; 29543 } 29544 29545 //Cycle through modules and normalize 29546 if (config.modules && config.modules.length) { 29547 config.modules.forEach(function (mod) { 29548 if (lang.isArray(mod) || typeof mod === 'string' || !mod) { 29549 throw new Error('modules config item is malformed: it should' + 29550 ' be an object with a \'name\' property.'); 29551 } 29552 29553 //Combine any local stubModules with global values. 29554 if (config.stubModules) { 29555 mod.stubModules = config.stubModules.concat(mod.stubModules || []); 29556 } 29557 29558 //Create a hash lookup for the stubModules config to make lookup 29559 //cheaper later. 29560 if (mod.stubModules) { 29561 mod.stubModules._byName = {}; 29562 mod.stubModules.forEach(function (id) { 29563 mod.stubModules._byName[id] = true; 29564 }); 29565 } 29566 29567 // Legacy command support, which allowed a single str
29567ing ID 29568 // for include. 29569 if (typeof mod.include === 'string') { 29570 mod.include = [mod.include]; 29571 } 29572 29573 //Allow wrap config in overrides, but normalize it. 29574 if (mod.override) { 29575 normalizeWrapConfig(mod.override, absFilePath); 29576 } 29577 }); 29578 } 29579 29580 normalizeWrapConfig(config, absFilePath); 29581 29582 //Do final input verification 29583 if (config.context) { 29584 throw new Error('The build argument "context" is not supported' + 29585 ' in a build. It should only be used in web' + 29586 ' pages.'); 29587 } 29588 29589 //Set up normalizeDirDefines. If not explicitly set, if optimize "none", 29590 //set to "skip" otherwise set to "all". 29591 if (!hasProp(config, 'normalizeDirDefines')) { 29592 if (config.optimize === 'none' || config.skipDirOptimize) { 29593 config.normalizeDirDefines = 'skip'; 29594 } else { 29595 config.normalizeDirDefines = 'all'; 29596 } 29597 } 29598 29599 //Set file.fileExclusionRegExp if desired 29600 if (hasProp(config, 'fileExclusionRegExp')) { 29601 if (typeof config.fileExclusionRegExp === "string") { 29602 file.exclusionRegExp = new RegExp(config.fileExclusionRegExp); 29603 } else { 29604 file.exclusionRegExp = config.fileExclusionRegExp; 29605 } 29606 } else if (hasProp(config, 'dirExclusionRegExp')) { 29607 //Set file.dirExclusionRegExp if desired, this is the old 29608 //name for fileExclusionRegExp before 1.0.2. Support for backwards 29609 //compatibility 29610 file.exclusionRegExp = config.dirExclusionRegExp; 29611 } 29612 29613 //Track the deps, but in a different key, so that they are not loaded 29614 //as part of config seeding before all config is in play (#648). Was 29615 //going to merge this in with "include", but include is added after 29616 //the "name" target. To preserve what r.js has done previously, make 29617 //sure "deps" comes before the "name". 29618 if (config.deps) { 29619 config._depsInclude = config.deps; 29620 } 29621 29622 29623 //Remove things that may cause problems in the build. 29624 //deps already merged above 29625 delete config.deps; 29626 delete config.jQuery; 29627 delete config.enforceDefine; 29628 delete config.urlArgs; 29629 29630 return config; 29631 }; 29632 29633 /** 29634 * finds the module being built/optimized with the given moduleName, 29635 * or returns null. 29636 * @param {String} moduleName 29637 * @param {Array} modules 29638 * @returns {Object} the module object from the build profile, or null. 29639 */ 29640 build.findBuildModule = function (moduleName, modules) { 29641 var i, module; 29642 for (i = 0; i < modules.length; i++) { 29643 module = modules[i]; 29644 if (module.name === moduleName) { 29645 return module; 29646 } 29647 } 29648 return null; 29649 }; 29650 29651 /** 29652 * Removes a module name and path from a layer, if it is supposed to be 29653 * excluded from the layer. 29654 * @param {String} moduleName the name of the module 29655 * @param {String} path the file path for the module 29656 * @param {Object} layer the layer to remove the module/path from 29657 */ 29658 build.removeModulePath = function (module, path, layer) { 29659 var index = layer.buildFilePaths.indexOf(path); 29660 if (index !== -1) { 29661 layer.buildFilePaths.splice(index, 1); 29662 } 29663 }; 29664 29665 /** 29666 * Uses the module build config object to trace the dependencies for the 29667 * given module. 29668 * 29669 * @param {Object} module the module object from the build config info. 29670 * @param {Object} config the build config object. 29671 * @param {Object} [baseLoaderConfig] the base loader config to use for env resets. 29672 * 29673 * @returns {Object} layer information about what paths and modules should 29674 * be in the flattened module. 29675 */
29676 build.traceDependencies = function (module, config, baseLoaderConfig) { 29677 var include, override, layer, context, oldContext, 29678 rawTextByIds, 29679 syncChecks = { 29680 rhino: true, 29681 node: true, 29682 xpconnect: true 29683 }, 29684 deferred = prim(); 29685 29686 //Reset some state set up in requirePatch.js, and clean up require's 29687 //current context. 29688 oldContext = require._buildReset(); 29689 29690 //Grab the reset layer and context after the reset, but keep the 29691 //old config to reuse in the new context. 29692 layer = require._layer; 29693 context = layer.context; 29694 29695 //Put back basic config, use a fresh object for it. 29696 if (baseLoaderConfig) { 29697 require(copyConfig(baseLoaderConfig)); 29698 } 29699 29700 logger.trace("\nTracing dependencies for: " + (module.name || 29701 (typeof module.out === 'function' ? 'FUNCTION' : module.out))); 29702 include = config._depsInclude || []; 29703 include = include.concat(module.name && !module.create ? [module.name] : []); 29704 if (module.include) { 29705 include = include.concat(module.include); 29706 } 29707 29708 //If there are overrides to basic config, set that up now.; 29709 if (module.override) { 29710 if (baseLoaderConfig) { 29711 override = build.createOverrideConfig(baseLoaderConfig, module.override); 29712 } else { 29713 override = copyConfig(module.override); 29714 } 29715 require(override); 29716 } 29717 29718 //Now, populate the rawText cache with any values explicitly passed in 29719 //via config. 29720 rawTextByIds = require.s.contexts._.config.rawText; 29721 if (rawTextByIds) { 29722 lang.eachProp(rawTextByIds, function (contents, id) { 29723 var url = require.toUrl(id) + '.js'; 29724 require._cachedRawText[url] = contents; 29725 }); 29726 } 29727 29728 29729 //Configure the callbacks to be called. 29730 deferred.reject.__requireJsBuild = true; 29731 29732 //Use a wrapping function so can check for errors. 29733 function includeFinished(value) { 29734 //If a sync build environment, check for errors here, instead of 29735 //in the then callback below, since some errors, like two IDs pointed 29736 //to same URL but only one anon ID will leave the loader in an 29737 //unresolved state since a setTimeout cannot be used to check for 29738 //timeout. 29739 var hasError = false; 29740 if (syncChecks[env.get()]) { 29741 try { 29742 build.checkForErrors(context, layer); 29743 } catch (e) { 29744 hasError = true; 29745 deferred.reject(e); 29746 } 29747 } 29748 29749 if (!hasError) { 29750 deferred.resolve(value); 29751 } 29752 } 29753 includeFinished.__requireJsBuild = true; 29754 29755 //Figure out module layer dependencies by calling require to do the work. 29756 require(include, includeFinished, deferred.reject); 29757 29758 // If a sync env, then with the "two IDs to same anon module path" 29759 // issue, the require never completes, need to check for errors 29760 // here. 29761 if (syncChecks[env.get()]) { 29762 build.checkForErrors(context, layer); 29763 } 29764 29765 return deferred.promise.then(function () { 29766 //Reset config 29767 if (module.override && baseLoaderConfig) { 29768 require(copyConfig(baseLoaderConfig)); 29769 } 29770 29771 build.checkForErrors(context, layer); 29772 29773 return layer; 29774 }); 29775 }; 29776 29777 build.checkForErrors = function (context, layer) { 29778 //Check to see if it all loaded. If not, then throw, and give 29779 //a message on what is left. 29780 var id, prop, mod, idParts, pluginId, pluginResources, 29781 errMessage = '', 29782 failedPluginMap = {}, 29783 failedPluginIds = [], 29784 errIds = [], 29785 errUrlMap = {}, 29786 errUrlConflicts = {}, 29787 hasErrUrl = false, 29788 hasUndefined = false, 29789 defined = context.defined, 29790 registry = context.registry; 29791 29792 function populateErrUrlMap(id, errUrl, skipNew) { 29793 // Loader plugins do not have an errUrl, so skip them. 29794 if (!errUrl) { 29795 return; 29796 } 29797 29798 if (!skipNew) { 29799 errIds.push(id); 29800 } 29801 29802 if (errUrlMap[errUrl]) { 29803 hasErrUrl = true; 29804 //This error module has the same URL as another 29805 //error module, could be misconfiguration. 29806 if (!errUrlConflicts[errUrl]) { 29807 errUrlConflicts[errUrl] = []; 29808 //Store the original module that had the same URL. 29809 errUrlConflicts[errUrl].push(errUrlMap[errUrl]); 29810 } 29811 errUrlConflicts[errUrl].push(id); 29812 } else if (!skipNew) { 29813 errUrlMap[errUrl] = id; 29814 } 29815 } 29816 29817 for (id in registry) { 29818 if (hasProp(registry, id) && id.indexOf('_@r') !== 0) { 29819 hasUndefined = true; 29820 mod = getOwn(registry, id); 29821 idParts = id.split('!'); 29822 pluginId = idParts[0]; 29823 29824 if (id.indexOf('_unnormalized') === -1 && mod && mod.enabled) { 29825 populateErrUrlMap(id, mod.map.url); 29826 } 29827 29828 //Look for plugins that did not call load() 29829 //But skip plugin IDs that were already inlined and called 29830 //define() with a name. 29831 if (!hasProp(layer.modulesWithNames, id) && idParts.length > 1) { 29832 if (falseProp(failedPluginMap, pluginId)) { 29833 failedPluginIds.push(pluginId); 29834 } 29835 pluginResources = failedPluginMap[pluginId]; 29836 if (!pluginResources) { 29837 pluginResources = failedPluginMap[pluginId] = []; 29838 } 29839 pluginResources.push(id + (mod.error ? ': ' + mod.error : '')); 29840 } 29841 } 29842 } 29843 29844 // If have some modules that are not defined/stuck in the registry, 29845 // then check defined modules for URL overlap. 29846 if (hasUndefined) { 29847 for (id in defined) { 29848 if (hasProp(defined, id) && id.indexOf('!') === -1) { 29849 populateErrUrlMap(id, require.toUrl(id) + '.js', true); 29850 } 29851 } 29852 } 29853 29854 if (errIds.length || failedPluginIds.length) { 29855 if (failedPluginIds.length) { 29856 errMessage += 'Loader plugin' + 29857 (failedPluginIds.length === 1 ? '' : 's') + 29858 ' did not call ' + 29859 'the load callback in the build:\n' + 29860 failedPluginIds.map(function (pluginId) { 29861 var pluginResources = failedPluginMap[pluginId]; 29862 return pluginId + ':\n ' + pluginResources.join('\n '); 29863 }).join('\n') + '\n'; 29864 }
29865 errMessage += 'Module loading did not complete for: ' + errIds.join(', '); 29866 29867 if (hasErrUrl) { 29868 errMessage += '\nThe following modules share the same URL. This ' + 29869 'could be a misconfiguration if that URL only has ' + 29870 'one anonymous module in it:'; 29871 for (prop in errUrlConflicts) { 29872 if (hasProp(errUrlConflicts, prop)) { 29873 errMessage += '\n' + prop + ': ' + 29874 errUrlConflicts[prop].join(', '); 29875 } 29876 } 29877 } 29878 throw new Error(errMessage); 29879 } 29880 }; 29881 29882 build.createOverrideConfig = function (config, override) { 29883 var cfg = copyConfig(config), 29884 oride = copyConfig(override); 29885 29886 lang.eachProp(oride, function (value, prop) { 29887 if (hasProp(build.objProps, prop)) { 29888 //An object property, merge keys. Start a new object 29889 //so that source object in config does not get modified. 29890 cfg[prop] = {}; 29891 lang.mixin(cfg[prop], config[prop], true); 29892 lang.mixin(cfg[prop], override[prop], true); 29893 } else { 29894 cfg[prop] = override[prop]; 29895 } 29896 }); 29897 29898 return cfg; 29899 }; 29900 29901 /** 29902 * Uses the module build config object to create an flattened version 29903 * of the module, with deep dependencies included. 29904 * 29905 * @param {Object} module the module object from the build config info. 29906 * 29907 * @param {Object} layer the layer object returned from build.traceDependencies. 29908 * 29909 * @param {Object} the build config object. 29910 * 29911 * @returns {Object} with two properties: "text", the text of the flattened 29912 * module, and "buildText", a string of text representing which files were 29913 * included in the flattened module text. 29914 */ 29915 build.flattenModule = function (module, layer, config) { 29916 var fileContents, sourceMapGenerator, 29917 sourceMapBase, 29918 buildFileContents = ''; 29919 29920 return prim().start(function () { 29921 var reqIndex, currContents, fileForSourceMap, 29922 moduleName, shim, packageName, 29923 parts, builder, writeApi, 29924 namespace, namespaceWithDot, stubModulesByName, 29925 context = layer.context, 29926 onLayerEnds = [], 29927 onLayerEndAdded = {}, 29928 pkgsMainMap = {}; 29929 29930 //Use override settings, particularly for pragmas 29931 //Do this before the var readings since it reads config values. 29932 if (module.override) { 29933 config = build.createOverrideConfig(config, module.override); 29934 } 29935 29936 namespace = config.namespace || ''; 29937 namespaceWithDot = namespace ? namespace + '.' : ''; 29938 stubModulesByName = (module.stubModules && module.stubModules._byName) || {}; 29939 29940 //Start build output for the module. 29941 module.onCompleteData = { 29942 name: module.name, 29943 path: (config.dir ? module._buildPath.replace(config.dir, "") : module._buildPath), 29944 included: [] 29945 }; 29946 29947 buildFileContents += "\n" + 29948 module.onCompleteData.path + 29949 "\n----------------\n"; 29950 29951 //If there was an existing file with require in it, hoist to the top. 29952 if (layer.existingRequireUrl) { 29953 reqIndex = layer.buildFilePaths.indexOf(layer.existingRequireUrl); 29954 if (reqIndex !== -1) { 29955 layer.buildFilePaths.splice(reqIndex, 1); 29956 layer.buildFilePaths.unshift(layer.existingRequireUrl); 29957 } 29958 } 29959 29960 if (config.generateSourceMaps) { 29961 sourceMapBase = config.dir || config.baseUrl; 29962 if (module._buildPath === 'FUNCTION') { 29963 fileForSourceMap = (module.name || module.include[0] || 'FUNCTION') + '.build.js'; 29964 } else if (config.out) { 29965 fileForSourceMap = module._buildPath.split('/').pop(); 29966 } else { 29967 fileForSourceMap = module._buildPath.replace(sourceMapBase, ''); 29968 } 29969 sourceMapGenerator = new SourceMapGenerator({ 29970 file: fileForSourceMap 29971 }); 29972 } 29973 29974 //Create a reverse lookup for packages main module IDs to their package 29975 //names, useful for knowing when to write out define() package main ID
29976 //adapters. 29977 lang.eachProp(layer.context.config.pkgs, function(value, prop) { 29978 pkgsMainMap[value] = prop; 29979 }); 29980 29981 //Write the built module to disk, and build up the build output. 29982 fileContents = ""; 29983 if (config.wrap && config.wrap.__startMap) { 29984 config.wrap.__startMap.forEach(function (wrapFunction) { 29985 fileContents = wrapFunction(fileContents, config, sourceMapGenerator); 29986 }); 29987 } 29988 29989 return prim.serial(layer.buildFilePaths.map(function (path) { 29990 return function () { 29991 var singleContents = ''; 29992 29993 moduleName = layer.buildFileToModule[path]; 29994 29995 //If the moduleName is a package main, then hold on to the 29996 //packageName in case an adapter needs to be written. 29997 packageName = getOwn(pkgsMainMap, moduleName); 29998 29999 return prim().start(function () { 30000 //Figure out if the module is a result of a build plugin, and if so, 30001 //then delegate to that plugin. 30002 parts = context.makeModuleMap(moduleName); 30003 builder = parts.prefix && getOwn(context.defined, parts.prefix); 30004 if (builder) { 30005 if (builder.onLayerEnd && falseProp(onLayerEndAdded, parts.prefix)) { 30006 onLayerEnds.push(builder); 30007 onLayerEndAdded[parts.prefix] = true; 30008 } 30009 30010 if (builder.write) { 30011 writeApi = function (input) { 30012 singleContents += "\n" + addSemiColon(input, config); 30013 if (config.onBuildWrite) { 30014 singleContents = config.onBuildWrite(moduleName, path, singleContents); 30015 } 30016 }; 30017 writeApi.asModule = function (moduleName, input) { 30018 singleContents += "\n" + 30019 addSemiColon(build.toTransport(namespace, moduleName, path, input, layer, { 30020 useSourceUrl: layer.context.config.useSourceUrl 30021 }), config); 30022 if (config.onBuildWrite) { 30023 singleContents = config.onBuildWrite(moduleName, path, singleContents); 30024 } 30025 }; 30026 30027 builder.write(parts.prefix, parts.name, writeApi, { 30028 name: module.onCompleteData.name, 30029 path: module.onCompleteData.path 30030 }); 30031 } 30032 return; 30033 } else { 30034 return prim().start(function () { 30035 if (hasProp(stubModulesByName, moduleName)) { 30036 //Just want to insert a simple module definition instead 30037 //of the source module. Useful for plugins that inline 30038 //all their resources. 30039 if (hasProp(layer.context.plugins, moduleName)) { 30040 //Slightly different content for plugins, to indicate 30041 //that dynamic loading will not work. 30042 return 'define({load: function(id){throw new Error("Dynamic load not allowed: " + id);}});'; 30043 } else { 30044 return 'define({});'; 30045 } 30046 } else { 30047 return require._cacheReadAsync(path);
30048 } 30049 }).then(function (text) { 30050 var hasPackageName; 30051 30052 currContents = text; 30053 30054 if (config.cjsTranslate && 30055 (!config.shim || !lang.hasProp(config.shim, moduleName))) { 30056 currContents = commonJs.convert(path, currContents); 30057 } 30058 30059 if (config.onBuildRead) { 30060 currContents = config.onBuildRead(moduleName, path, currContents); 30061 } 30062 30063 if (packageName) { 30064 hasPackageName = (packageName === parse.getNamedDefine(currContents)); 30065 } 30066 30067 if (namespace) { 30068 currContents = pragma.namespace(currContents, namespace); 30069 } 30070 30071 currContents = build.toTransport(namespace, moduleName, path, currContents, layer, { 30072 useSourceUrl: config.useSourceUrl 30073 }); 30074 30075 if (packageName && !hasPackageName) { 30076 currContents = addSemiColon(currContents, config) + '\n'; 30077 currContents += namespaceWithDot + "define('" + 30078 packageName + "', ['" + moduleName + 30079 "'], function (main) { return main; });\n"; 30080 } 30081 30082 if (config.onBuildWrite) { 30083 currContents = config.onBuildWrite(moduleName, path, currContents); 30084 } 30085 30086 //Semicolon is for files that are not well formed when 30087 //concatenated with other content. 30088 singleContents += addSemiColon(currContents, config); 30089 }); 30090 } 30091 }).then(function () { 30092 var shimDeps, shortPath = path.replace(config.dir, ""); 30093 30094 module.onCompleteData.included.push(shortPath); 30095 buildFileContents += shortPath + "\n"; 30096 30097 //Some files may not have declared a require module, and if so, 30098 //put in a placeholder call so the require does not try to load them 30099 //after the module is processed. 30100 //If we have a name, but no defined module, then add in the placeholder. 30101 if (moduleName && falseProp(layer.modulesWithNames, moduleName) && !config.skipModuleInsertion) { 30102 shim = config.shim && (getOwn(config.shim, moduleName) || (packageName && getOwn(config.shim, packageName))); 30103 if (shim) { 30104 shimDeps = lang.isArray(shim) ? shim : shim.deps; 30105 if (config.wrapShim) { 30106 30107 singleContents = '(function(root) {\n' + 30108 namespaceWithDot + 'define("' + moduleName + '", ' + 30109 (shimDeps && shimDeps.length ? 30110 build.makeJsArrayString(shimDeps) + ', ' : '[], ') + 30111 'function() {\n' + 30112 ' return (function() {\n' + 30113 singleContents + 30114 // Start with a \n in case last line is a comment 30115 // in the singleContents, like a sourceURL comment. 30116 '\n' + (shim.exportsFn ? shim.exportsFn() : '') + 30117 '\n' + 30118 ' }).apply(root, arguments);\n' + 30119 '});\n' + 30120 '}(this));\n'; 30121 } else { 30122 singleContents += '\n' + namespaceWithDot + 'define("' + moduleName + '", ' + 30123 (shimDeps && shimDeps.length ? 30124 build.makeJsArrayString(shimDeps) + ', ' : '') + 30125 (shim.exportsFn ? shim.exportsFn() : 'function(){}') + 30126 ');\n'; 30127 } 30128 } else { 30129 singleContents += '\n' + namespaceWithDot + 'define("' + moduleName + '", function(){});\n'; 30130 } 30131 } 30132 30133 //Add line break at end of file, instead of at beginning, 30134 //so source map line numbers stay correct, but still allow 30135 //for some space separation between files in case ASI issues 30136 //for concatenation would cause an error otherwise. 30137 singleContents += '\n'; 30138 30139 //Add to the source map and to the final contents 30140 fileContents = appendToFileContents(fileContents, singleContents, path, config, module, 30141 sourceMapGenerator); 30142 }); 30143 }; 30144 })).then(function () { 30145 if (onLayerEnds.length) { 30146 onLayerEnds.forEach(function (builder, index) { 30147 var path; 30148 if (typeof module.out === 'string') { 30149 path = module.out; 30150 } else if (typeof module._buildPath === 'string') { 30151 path = module._buildPath; 30152 } 30153 builder.onLayerEnd(function (input) { 30154 fileContents = 30155 appendToFileContents(fileContents, "\n" + addSemiColon(input, config), 30156 'onLayerEnd' + index + '.js', config, module, sourceMapGenerator); 30157 }, { 30158 name: module.name, 30159 path: path 30160 }); 30161 }); 30162 } 30163 30164 if (module.create) { 30165 //The ID is for a created layer. Write out 30166 //a module definition for it in case the 30167 //built file is used with enforceDefine 30168 //(#432) 30169 fileContents = 30170 appendToFileContents(fileContents, '\n' + namespaceWithDot + 'define("' + module.name + 30171 '", function(){});\n', 'module-create.js', config, module, 30172 sourceMapGenerator); 30173 } 30174 30175 //Add a require at the end to kick start module execution, if that 30176 //was desired. Usually this is only specified when using small shim 30177 //loaders like almond. 30178 if (module.insertRequire) { 30179 fileContents = 30180 appendToFileContents(fileContents, '\n' + namespaceWithDot + 'require(["' + module.insertRequire.join('", "') + 30181 '"]);\n', 'module-insertRequire.js', config, module, 30182 sourceMapGenerator); 30183 } 30184 }); 30185 }).then(function () { 30186 if (config.wrap && config.wrap.__endMap) {
30187 config.wrap.__endMap.forEach(function (wrapFunction) { 30188 fileContents = wrapFunction(fileContents, config, sourceMapGenerator); 30189 }); 30190 } 30191 return { 30192 text: fileContents, 30193 buildText: buildFileContents, 30194 sourceMap: sourceMapGenerator ? 30195 JSON.stringify(sourceMapGenerator.toJSON(), null, ' ') : 30196 undefined 30197 }; 30198 }); 30199 }; 30200 30201 //Converts an JS array of strings to a string representation. 30202 //Not using JSON.stringify() for Rhino's sake. 30203 build.makeJsArrayString = function (ary) { 30204 return '["' + ary.map(function (item) { 30205 //Escape any double quotes, backslashes 30206 return lang.jsEscape(item); 30207 }).join('","') + '"]'; 30208 }; 30209 30210 build.toTransport = function (namespace, moduleName, path, contents, layer, options) { 30211 var baseUrl = layer && layer.context.config.baseUrl; 30212 30213 function onFound(info) { 30214 //Only mark this module as having a name if not a named module, 30215 //or if a named module and the name matches expectations. 30216 if (layer && (info.needsId || info.foundId === moduleName)) { 30217 layer.modulesWithNames[moduleName] = true; 30218 } 30219 } 30220 30221 //Convert path to be a local one to the baseUrl, useful for 30222 //useSourceUrl. 30223 if (baseUrl) { 30224 path = path.replace(baseUrl, ''); 30225 } 30226 30227 return transform.toTransport(namespace, moduleName, path, contents, onFound, options); 30228 }; 30229 30230 return build; 30231}); 30232 30233 } 30234 30235 30236 /** 30237 * Sets the default baseUrl for requirejs to be directory of top level 30238 * script. 30239 */ 30240 function setBaseUrl(fileName) { 30241 //Use the file name's directory as the baseUrl if available. 30242 dir = fileName.replace(/\\/g, '/'); 30243 if (dir.indexOf('/') !== -1) { 30244 dir = dir.split('/'); 30245 dir.pop(); 30246 dir = dir.join('/'); 30247 //Make sure dir is JS-escaped, since it will be part of a JS string. 30248 exec("require({baseUrl: '" + dir.replace(/[\\"']/g, '\\$&') + "'});"); 30249 } 30250 } 30251 30252 function createRjsApi() { 30253 //Create a method that will run the optimzer given an object 30254 //config. 30255 requirejs.optimize = function (config, callback, errback) { 30256 if (!loadedOptimizedLib) { 30257 loadLib(); 30258 loadedOptimizedLib = true; 30259 } 30260 30261 //Create the function that will be called once build modules 30262 //have been loaded. 30263 var runBuild = function (build, logger, quit) { 30264 //Make sure config has a log level, and if not, 30265 //make it "silent" by default. 30266 config.logLevel = config.hasOwnProperty('logLevel') ? 30267 config.logLevel : logger.SILENT; 30268 30269 //Reset build internals first in case this is part 30270 //of a long-running server process that could have 30271 //exceptioned out in a bad state. It is only defined 30272 //after the first call though. 30273 if (requirejs._buildReset) { 30274 requirejs._buildReset(); 30275 requirejs._cacheReset(); 30276 } 30277 30278 function done(result) { 30279 //And clean up, in case something else triggers 30280 //a build in another pathway. 30281 if (requirejs._buildReset) { 30282 requirejs._buildReset(); 30283 requirejs._cacheReset(); 30284 } 30285 30286 // Ensure errors get propagated to the errback 30287 if (result instanceof Error) { 30288 throw result; 30289 } 30290 30291 return result; 30292 } 30293 30294 errback = errback || function (err) { 30295 // Using console here since logger may have 30296 // turned off error logging. Since quit is 30297 // called want to be sure a message is printed. 30298 console.log(err); 30299 quit(1); 30300 }; 30301 30302 build(config).then(done, done).then(callback, errback); 30303 }; 30304 30305 requirejs({ 30306 context: 'build' 30307 }, ['build', 'logger', 'env!env/quit'], runBuild); 30308 }; 30309 30310 requirejs.tools = { 30311 useLib: function (contextName, callback) { 30312 if (!callback) { 30313 callback = contextName; 30314 contextName = 'uselib'; 30315 } 30316 30317 if (!useLibLoaded[contextName]) { 30318 loadLib();
30319 useLibLoaded[contextName] = true; 30320 } 30321 30322 var req = requirejs({ 30323 context: contextName 30324 }); 30325 30326 req(['build'], function () { 30327 callback(req); 30328 }); 30329 } 30330 }; 30331 30332 requirejs.define = define; 30333 } 30334 30335 //If in Node, and included via a require('requirejs'), just export and 30336 //THROW IT ON THE GROUND! 30337 if (env === 'node' && reqMain !== module) { 30338 setBaseUrl(path.resolve(reqMain ? reqMain.filename : '.')); 30339 30340 createRjsApi(); 30341 30342 module.exports = requirejs; 30343 return; 30344 } else if (env === 'browser') { 30345 //Only option is to use the API. 30346 setBaseUrl(location.href); 30347 createRjsApi(); 30348 return; 30349 } else if ((env === 'rhino' || env === 'xpconnect') && 30350 //User sets up requirejsAsLib variable to indicate it is loaded 30351 //via load() to be used as a library. 30352 typeof requirejsAsLib !== 'undefined' && requirejsAsLib) { 30353 //This script is loaded via rhino's load() method, expose the 30354 //API and get out. 30355 setBaseUrl(fileName); 30356 createRjsApi(); 30357 return; 30358 } 30359 30360 if (commandOption === 'o') { 30361 //Do the optimizer work. 30362 loadLib(); 30363 30364 /* 30365 * Create a build.js file that has the build options you want and pass that 30366 * build file to this file to do the build. See example.build.js for more information. 30367 */ 30368 30369/*jslint strict: false, nomen: false */ 30370/*global require: false */ 30371 30372require({ 30373 baseUrl: require.s.contexts._.config.baseUrl, 30374 //Use a separate context than the default context so that the 30375 //build can use the default context. 30376 context: 'build', 30377 catchError: { 30378 define: true 30379 } 30380}, ['env!env/args', 'env!env/quit', 'logger', 'build'], 30381function (args, quit, logger, build) { 30382 build(args).then(function () {}, function (err) { 30383 logger.error(err); 30384 quit(1); 30385 }); 30386}); 30387 30388 30389 } else if (commandOption === 'v') { 30390 console.log('r.js: ' + version + 30391 ', RequireJS: ' + this.requirejsVars.require.version + 30392 ', UglifyJS: 2.8.29'); 30393 } else if (commandOption === 'convert') { 30394 loadLib(); 30395 30396 this.requirejsVars.require(['env!env/args', 'commonJs', 'env!env/print'], 30397 function (args, commonJs, print) { 30398 30399 var srcDir, outDir; 30400 srcDir = args[0]; 30401 outDir = args[1]; 30402 30403 if (!srcDir || !outDir) { 30404 print('Usage: path/to/commonjs/modules output/dir'); 30405 return; 30406 } 30407 30408 commonJs.convertDir(args[0], args[1]); 30409 }); 30410 } else { 30411 //Just run an app 30412 30413 //Load the bundled libraries for use in the app. 30414 if (commandOption === 'lib') { 30415 loadLib(); 30416 } 30417 30418 setBaseUrl(fileName); 30419 30420 if (exists(fileName)) { 30421 exec(readFile(fileName), fileName); 30422 } else { 30423 showHelp(); 30424 } 30425 } 30426 30427}((typeof console !== 'undefined' ? console : undefined), 30428 (typeof Packages !== 'undefined' || (typeof window === 'undefined' && 30429 typeof Components !== 'undefined' && Components.interfaces) ? 30430 Array.prototype.slice.call(arguments, 0) : []), 30431 (typeof readFile !== 'undefined' ? readFile : undefined)));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.