UNPKG

28 kBJavaScriptView Raw
1/*
2 Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
3 Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
18 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24*/
25
26/*jslint bitwise:true */
27(function () {
28 'use strict';
29
30 var Syntax,
31 Regex,
32 isArray,
33 arrayFrom,
34 arrayOf,
35 sameValue,
36 estraverse,
37 escope,
38 NameSequence,
39 ZeroSequenceCache;
40
41 estraverse = require('estraverse');
42 escope = require('escope');
43
44 Syntax = estraverse.Syntax;
45
46 // See also tools/generate-unicode-regex.py.
47 Regex = {
48 NonAsciiIdentifierStart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\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\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\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\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-\u0c33\u0c35-\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-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\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-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\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]'),
49 NonAsciiIdentifierPart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0300-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u0483-\u0487\u048a-\u0527\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\u08a2-\u08ac\u08e4-\u08fe\u0900-\u0963\u0966-\u096f\u0971-\u0977\u0979-\u097f\u0981-\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\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\u0c01-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c58\u0c59\u0c60-\u0c63\u0c66-\u0c6f\u0c82\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\u0d02\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d44\u0d46-\u0d48\u0d4a-\u0d4e\u0d57\u0d60-\u0d63\u0d66-\u0d6f\u0d7a-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\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\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\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-\u191c\u1920-\u192b\u1930-\u193b\u1946-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u19d0-\u19d9\u1a00-\u1a1b\u1a20-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1aa7\u1b00-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1bf3\u1c00-\u1c37\u1c40-\u1c49\u1c4d-\u1c7d\u1cd0-\u1cd2\u1cd4-\u1cf6\u1d00-\u1de6\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\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\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\u2e2f\u3005-\u3007\u3021-\u302f\u3031-\u3035\u3038-\u303c\u3041-\u3096\u3099\u309a\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-\ua62b\ua640-\ua66f\ua674-\ua67d\ua67f-\ua697\ua69f-\ua6f1\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua827\ua840-\ua873\ua880-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f7\ua8fb\ua900-\ua92d\ua930-\ua953\ua960-\ua97c\ua980-\ua9c0\ua9cf-\ua9d9\uaa00-\uaa36\uaa40-\uaa4d\uaa50-\uaa59\uaa60-\uaa76\uaa7a\uaa7b\uaa80-\uaac2\uaadb-\uaadd\uaae0-\uaaef\uaaf2-\uaaf6\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\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\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe00-\ufe0f\ufe20-\ufe26\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]')
50 };
51
52 isArray = Array.isArray;
53 if (!isArray) {
54 isArray = function isArray(array) {
55 return Object.prototype.toString.call(array) === '[object Array]';
56 };
57 }
58
59 // ES6 Array.from
60 arrayFrom = (function () {
61 var slice = Array.prototype.slice;
62 return function arrayFrom(array) {
63 return slice.call(array);
64 };
65 }());
66
67 // ES6 Array.of
68 arrayOf = (function () {
69 var slice = Array.prototype.slice;
70 return function arrayOf() {
71 return slice.call(arguments);
72 };
73 }());
74
75 function arrayLast(array) {
76 return array[array.length - 1];
77 }
78
79 function arrayEmpty(array) {
80 return array.length === 0;
81 }
82
83 function stringRepeat(str, num) {
84 var result = '';
85
86 for (num |= 0; num > 0; num >>>= 1, str += str) {
87 if (num & 1) {
88 result += str;
89 }
90 }
91
92 return result;
93 }
94
95 // see http://wiki.ecmascript.org/doku.php?id=harmony:egal
96 // ECMA262 SameValue algorithm
97 if (Object.is) {
98 sameValue = Object.is;
99 } else {
100 sameValue = function sameValue(x, y) {
101 if (x === y) {
102 // 0 === -0, but they are not identical
103 return x !== 0 || 1 / x === 1 / y;
104 }
105
106 // NaN !== NaN, but they are identical.
107 // NaNs are the only non-reflexive value, i.e., if x !== x,
108 // then x is a NaN.
109 // isNaN is broken: it converts its argument to number, so
110 // isNaN("foo") => true
111 return x !== x && y !== y;
112 };
113 }
114
115 function deepCopy(obj) {
116 function deepCopyInternal(obj, result) {
117 var key, val;
118 for (key in obj) {
119 if (obj.hasOwnProperty(key)) {
120 val = obj[key];
121 if (typeof val === 'object' && val !== null) {
122 if (val instanceof RegExp) {
123 val = new RegExp(val);
124 } else {
125 val = deepCopyInternal(val, isArray(val) ? [] : {});
126 }
127 }
128 result[key] = val;
129 }
130 }
131 return result;
132 }
133 return deepCopyInternal(obj, isArray(obj) ? [] : {});
134 }
135
136 function assert(cond, text) {
137 if (!cond) {
138 throw new Error(text);
139 }
140 }
141
142 function unreachable() {
143 throw new Error('Unreachable point. logically broken.');
144 }
145
146 // 7.6.1.2 Future Reserved Words
147
148 function isFutureReservedWord(id) {
149 switch (id) {
150
151 // Future reserved words.
152 case 'class':
153 case 'enum':
154 case 'export':
155 case 'extends':
156 case 'import':
157 case 'super':
158 return true;
159 }
160
161 return false;
162 }
163
164 function isStrictModeReservedWord(id) {
165 switch (id) {
166
167 // Strict Mode reserved words.
168 case 'implements':
169 case 'interface':
170 case 'package':
171 case 'private':
172 case 'protected':
173 case 'public':
174 case 'static':
175 case 'yield':
176 case 'let':
177 return true;
178 }
179
180 return false;
181 }
182
183 function isRestrictedWord(id) {
184 return id === 'eval' || id === 'arguments';
185 }
186
187 // 7.6.1.1 Keywords
188
189 function isKeyword(id) {
190 var keyword = false;
191 switch (id.length) {
192 case 2:
193 keyword = (id === 'if') || (id === 'in') || (id === 'do');
194 break;
195 case 3:
196 keyword = (id === 'var') || (id === 'for') || (id === 'new') || (id === 'try');
197 break;
198 case 4:
199 keyword = (id === 'this') || (id === 'else') || (id === 'case') || (id === 'void') || (id === 'with');
200 break;
201 case 5:
202 keyword = (id === 'while') || (id === 'break') || (id === 'catch') || (id === 'throw');
203 break;
204 case 6:
205 keyword = (id === 'return') || (id === 'typeof') || (id === 'delete') || (id === 'switch');
206 break;
207 case 7:
208 keyword = (id === 'default') || (id === 'finally');
209 break;
210 case 8:
211 keyword = (id === 'function') || (id === 'continue') || (id === 'debugger');
212 break;
213 case 10:
214 keyword = (id === 'instanceof');
215 break;
216 }
217
218 if (keyword) {
219 return true;
220 }
221
222 switch (id) {
223 // Future reserved words.
224 // 'const' is specialized as Keyword in V8.
225 case 'const':
226 return true;
227
228 // For compatiblity to SpiderMonkey and ES.next
229 case 'yield':
230 case 'let':
231 return true;
232 }
233
234 if (isStrictModeReservedWord(id)) {
235 return true;
236 }
237
238 return isFutureReservedWord(id);
239 }
240
241 function isDecimalDigit(ch) {
242 return '0123456789'.indexOf(ch) >= 0;
243 }
244
245 function isHexDigit(ch) {
246 return '0123456789abcdefABCDEF'.indexOf(ch) >= 0;
247 }
248
249 function isOctalDigit(ch) {
250 return '01234567'.indexOf(ch) >= 0;
251 }
252
253
254 // 7.2 White Space
255
256 function isWhiteSpace(ch) {
257 return (ch === ' ') || (ch === '\u0009') || (ch === '\u000B') ||
258 (ch === '\u000C') || (ch === '\u00A0') ||
259 (ch.charCodeAt(0) >= 0x1680 &&
260 '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\uFEFF'.indexOf(ch) >= 0);
261 }
262
263 // 7.3 Line Terminators
264
265 function isLineTerminator(ch) {
266 return (ch === '\n' || ch === '\r' || ch === '\u2028' || ch === '\u2029');
267 }
268
269 // 7.6 Identifier Names and Identifiers
270
271 function isIdentifierStart(ch) {
272 return (ch === 36) || (ch === 95) || // $ (dollar) and _ (underscore)
273 (ch >= 65 && ch <= 90) || // A..Z
274 (ch >= 97 && ch <= 122) || // a..z
275 (ch === 92) || // \ (backslash)
276 ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch)));
277 }
278
279 function isIdentifierPart(ch) {
280 return (ch === 36) || (ch === 95) || // $ (dollar) and _ (underscore)
281 (ch >= 65 && ch <= 90) || // A..Z
282 (ch >= 97 && ch <= 122) || // a..z
283 (ch >= 48 && ch <= 57) || // 0..9
284 (ch === 92) || // \ (backslash)
285 ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch)));
286 }
287
288 function isIdentifier(name) {
289 var i, iz, ch;
290
291 // fallback for ES3
292 if (isKeyword(name) || isRestrictedWord(name)) {
293 return false;
294 }
295 if (name.length === 0) {
296 return false;
297 }
298
299 ch = name.charCodeAt(0);
300 if (!isIdentifierStart(ch) || ch === 92) { // \ (backslash)
301 return false;
302 }
303
304 for (i = 1, iz = name.length; i < iz; ++i) {
305 ch = name.charCodeAt(i);
306 if (!isIdentifierPart(ch) || ch === 92) { // \ (backslash)
307 return false;
308 }
309 }
310 return true;
311 }
312
313 function moveLocation(from, to) {
314 if (from.loc == null) {
315 return to;
316 }
317 to.loc = deepCopy(from.loc);
318 return to;
319 }
320
321 function deleteLocation(node) {
322 if (node.hasOwnProperty('loc')) {
323 return delete node.loc;
324 }
325 return false;
326 }
327
328 function convertToEmptyStatement(node) {
329 var i, iz, keys;
330 keys = estraverse.VisitorKeys[node.type];
331 for (i = 0, iz = keys.length; i < iz; ++i) {
332 delete node[keys[i]];
333 }
334 node.type = Syntax.EmptyStatement;
335 return node;
336 }
337
338 // generateNextName
339
340 ZeroSequenceCache = [];
341
342 function zeroSequence(num) {
343 var res = ZeroSequenceCache[num];
344 if (res !== undefined) {
345 return res;
346 }
347 res = stringRepeat('0', num);
348 ZeroSequenceCache[num] = res;
349 return res;
350 }
351
352 NameSequence = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$'.split('');
353
354 function generateNextName(name) {
355 var ch, index, cur;
356
357 cur = name.length - 1;
358 do {
359 ch = name.charAt(cur);
360 index = NameSequence.indexOf(ch);
361 if (index !== (NameSequence.length - 1)) {
362 return name.substring(0, cur) + NameSequence[index + 1] + zeroSequence(name.length - (cur + 1));
363 }
364 --cur;
365 } while (cur >= 0);
366 return 'a' + zeroSequence(name.length);
367 }
368
369 function isNegative(value) {
370 return value === value && (value < 0 || (value === 0 && 1 / value < 0));
371 }
372
373 function isFunctionBody(node, parent) {
374 return node.type === Syntax.BlockStatement && (parent.type === Syntax.FunctionDeclaration || parent.type === Syntax.FunctionExpression);
375 }
376
377 function isNumberLiteral(node) {
378 return node.type === Syntax.Literal && typeof node.value === 'number';
379 }
380
381 function isOptimizedArgument(argument) {
382 return isNumberLiteral(argument) && String(argument.value).length === 1;
383 }
384
385 function generateNegativeNode(value, node) {
386 var result;
387 result = {
388 type: Syntax.UnaryExpression,
389 operator: '-',
390 argument: {
391 type: Syntax.Literal,
392 value: -value
393 }
394 };
395 return (node) ? moveLocation(node, result) : result;
396 }
397
398 function isNegativeNode(node) {
399 return node.type === Syntax.UnaryExpression && node.operator === '-' && isNumberLiteral(node.argument);
400 }
401
402 function generateUndefined(node) {
403 var result = {
404 type: Syntax.UnaryExpression,
405 operator: 'void',
406 argument: {
407 type: Syntax.Literal,
408 value: 0
409 }
410 };
411 return (node) ? moveLocation(node, result) : result;
412 }
413
414 function isUndefined(node) {
415 return node.type === Syntax.UnaryExpression && node.operator === 'void' && isOptimizedArgument(node.argument);
416 }
417
418 function generateNaN(node) {
419 var result = {
420 type: Syntax.BinaryExpression,
421 operator: '/',
422 left: {
423 type: Syntax.Literal,
424 value: 0
425 },
426 right: {
427 type: Syntax.Literal,
428 value: 0
429 }
430 };
431 return (node) ? moveLocation(node, result) : result;
432 }
433
434 function isNaNNode(node) {
435 if (node.type === Syntax.BinaryExpression) {
436 if (isOptimizedArgument(node.left) && isOptimizedArgument(node.right)) {
437 return node.left.value === 0 && node.right.value === 0;
438 }
439 }
440 return false;
441 }
442
443 function generateFromValue(value) {
444 if (typeof value === 'number') {
445 if (isNaN(value)) {
446 return generateNaN();
447 }
448 if (isNegative(value)) {
449 return generateNegativeNode(value);
450 }
451 }
452 if (value === undefined) {
453 return generateUndefined();
454 }
455 return {
456 type: Syntax.Literal,
457 value: value
458 };
459 }
460
461 function isReference(node) {
462 var type = node.type;
463 return type === Syntax.Identifier || type === Syntax.MemberExpression;
464 }
465
466 // @param last last element of SequenceExpression
467 // @param parent parent element of SequenceExpression
468 // @param scope scope
469 function canExtractSequence(last, parent, scope) {
470 var ref;
471 if (parent.type === Syntax.CallExpression) {
472 if (last.type === Syntax.Identifier) {
473 if (last.name === 'eval') {
474 // This becomes direct call to eval.
475 return false;
476 }
477 ref = scope.resolve(last);
478 return ref && ref.isStatic();
479 }
480 return last.type !== Syntax.MemberExpression;
481 } else if (parent.type === Syntax.UnaryExpression) {
482 if (parent.operator === 'delete') {
483 return !isReference(last);
484 } else if (parent.operator === 'typeof') {
485 if (last.type === Syntax.Identifier) {
486 ref = scope.resolve(last);
487 return ref && ref.isStatic();
488 }
489 }
490 } else if (parent.type === Syntax.UpdateExpression) {
491 return !isReference(last);
492 }
493 return true;
494 }
495
496 function delegateVariableDeclarations(stmt, func) {
497 var decls, target;
498
499 decls = [];
500
501 estraverse.traverse(stmt, {
502 enter: function (node) {
503 var i, iz, decl;
504 if (node.type === Syntax.VariableDeclaration) {
505 if (node.kind === 'let' || node.kind === 'const') {
506 return;
507 }
508 for (i = 0, iz = node.declarations.length; i < iz; ++i) {
509 decl = node.declarations[i];
510 delete decl.init;
511 decls.push(decl);
512 }
513 return estraverse.VisitorOption.Skip;
514 } else if (escope.Scope.isVariableScopeRequired(node)) {
515 return estraverse.VisitorOption.Skip;
516 }
517 }
518 });
519
520 if (!decls.length) {
521 return null;
522 }
523
524 target = null;
525
526 estraverse.traverse(func.body, {
527 enter: function (node, parent) {
528 if (node === stmt) {
529 return estraverse.VisitorOption.Skip;
530 } else if (escope.Scope.isVariableScopeRequired(node)) {
531 return estraverse.VisitorOption.Skip;
532 } else if (node.type === Syntax.VariableDeclaration && node.kind === 'var') {
533 // list is not allowed
534 if (parent.type !== Syntax.ForInStatement) {
535 target = node;
536 return estraverse.VisitorOption.Break;
537 }
538 }
539 }
540 });
541
542 if (target) {
543 target.declarations = target.declarations.concat(decls);
544 return null;
545 } else {
546 return {
547 type: Syntax.VariableDeclaration,
548 kind: 'var',
549 declarations: decls
550 };
551 }
552 }
553
554 function isScopedDeclaration(node) {
555 if (node.type === Syntax.VariableDeclaration && (node.kind === 'let' || node.kind === 'const')) {
556 return true;
557 } else if (node.type === Syntax.FunctionDeclaration) {
558 return true;
559 }
560 return false;
561 }
562
563 exports.deepCopy = deepCopy;
564 exports.stringRepeat = stringRepeat;
565 exports.sameValue = sameValue;
566
567 exports.Array = {
568 isArray: isArray,
569 from: arrayFrom,
570 of: arrayOf,
571 last: arrayLast,
572 empty: arrayEmpty
573 };
574 // deprecated export
575 exports.isArray = isArray;
576
577 exports.Syntax = Syntax;
578 exports.traverse = estraverse.traverse;
579 exports.replace = estraverse.replace;
580 exports.VisitorKeys = estraverse.VisitorKeys;
581 exports.VisitorOption = estraverse.VisitorOption;
582
583 exports.assert = assert;
584 exports.unreachable = unreachable;
585 exports.isFutureReservedWord = isFutureReservedWord;
586 exports.isStrictModeReservedWord = isStrictModeReservedWord;
587 exports.isRestrictedWord = isRestrictedWord;
588 exports.isKeyword = isKeyword;
589 exports.isIdentifier = isIdentifier;
590
591 exports.isDecimalDigit = isDecimalDigit;
592 exports.isHexDigit = isHexDigit;
593 exports.isOctalDigit = isOctalDigit;
594 exports.isWhiteSpace = isWhiteSpace;
595 exports.isLineTerminator= isLineTerminator;
596
597 exports.moveLocation = moveLocation;
598 exports.deleteLocation = deleteLocation;
599 exports.convertToEmptyStatement = convertToEmptyStatement;
600
601 exports.generateNextName = generateNextName;
602
603 exports.isNegative = isNegative;
604
605 exports.isFunctionBody = isFunctionBody;
606 exports.SpecialNode = {
607 generateNegative: generateNegativeNode,
608 isNegative: isNegativeNode,
609 generateUndefined: generateUndefined,
610 isUndefined: isUndefined,
611 generateNaN: generateNaN,
612 isNaN: isNaNNode,
613 isReference: isReference,
614 canExtractSequence: canExtractSequence,
615 generateFromValue: generateFromValue
616 };
617
618 exports.delegateVariableDeclarations = delegateVariableDeclarations;
619
620 exports.isScopedDeclaration = isScopedDeclaration;
621}());
622/* vim: set sw=4 ts=4 et tw=80 : */