UNPKG

28.4 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 has,
36 sameValue,
37 estraverse,
38 escope;
39
40 estraverse = require('estraverse');
41 escope = require('escope');
42
43 Syntax = estraverse.Syntax;
44
45 // See also tools/generate-unicode-regex.py.
46 Regex = {
47 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]'),
48 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]')
49 };
50
51 isArray = Array.isArray;
52 if (!isArray) {
53 isArray = function isArray(array) {
54 return Object.prototype.toString.call(array) === '[object Array]';
55 };
56 }
57
58 function isObject(obj) {
59 return typeof obj === 'object' && obj !== null;
60 }
61
62 has = (function () {
63 var method = {}.hasOwnProperty;
64 return function has(obj, prop) {
65 return method.call(obj, prop);
66 };
67 }());
68
69 // ES6 Array.from
70 arrayFrom = (function () {
71 var slice = Array.prototype.slice;
72 return function arrayFrom(array) {
73 return slice.call(array);
74 };
75 }());
76
77 // ES6 Array.of
78 arrayOf = (function () {
79 var slice = Array.prototype.slice;
80 return function arrayOf() {
81 return slice.call(arguments);
82 };
83 }());
84
85 function arrayLast(array) {
86 return array[array.length - 1];
87 }
88
89 function arrayEmpty(array) {
90 return array.length === 0;
91 }
92
93 function stringRepeat(str, num) {
94 var result = '';
95
96 for (num |= 0; num > 0; num >>>= 1, str += str) {
97 if (num & 1) {
98 result += str;
99 }
100 }
101
102 return result;
103 }
104
105 // see http://wiki.ecmascript.org/doku.php?id=harmony:egal
106 // ECMA262 SameValue algorithm
107 if (Object.is) {
108 sameValue = Object.is;
109 } else {
110 sameValue = function sameValue(x, y) {
111 if (x === y) {
112 // 0 === -0, but they are not identical
113 return x !== 0 || 1 / x === 1 / y;
114 }
115
116 // NaN !== NaN, but they are identical.
117 // NaNs are the only non-reflexive value, i.e., if x !== x,
118 // then x is a NaN.
119 // isNaN is broken: it converts its argument to number, so
120 // isNaN("foo") => true
121 return x !== x && y !== y;
122 };
123 }
124
125 function deepCopy(obj) {
126 function deepCopyInternal(obj, result) {
127 var key, val;
128 for (key in obj) {
129 if (key.lastIndexOf('__', 0) === 0) {
130 continue;
131 }
132 if (obj.hasOwnProperty(key)) {
133 val = obj[key];
134 if (typeof val === 'object' && val !== null) {
135 if (val instanceof RegExp) {
136 val = new RegExp(val);
137 } else {
138 val = deepCopyInternal(val, isArray(val) ? [] : {});
139 }
140 }
141 result[key] = val;
142 }
143 }
144 return result;
145 }
146 return deepCopyInternal(obj, isArray(obj) ? [] : {});
147 }
148
149 function assert(cond, text) {
150 if (!cond) {
151 throw new Error(text);
152 }
153 }
154
155 function unreachable() {
156 throw new Error('Unreachable point. logically broken.');
157 }
158
159 // 7.6.1.2 Future Reserved Words
160
161 function isFutureReservedWord(id) {
162 switch (id) {
163
164 // Future reserved words.
165 case 'class':
166 case 'enum':
167 case 'export':
168 case 'extends':
169 case 'import':
170 case 'super':
171 return true;
172 }
173
174 return false;
175 }
176
177 function isStrictModeReservedWord(id) {
178 switch (id) {
179
180 // Strict Mode reserved words.
181 case 'implements':
182 case 'interface':
183 case 'package':
184 case 'private':
185 case 'protected':
186 case 'public':
187 case 'static':
188 case 'yield':
189 case 'let':
190 return true;
191 }
192
193 return false;
194 }
195
196 function isRestrictedWord(id) {
197 return id === 'eval' || id === 'arguments';
198 }
199
200 // 7.6.1.1 Keywords
201
202 function isKeyword(id) {
203 var keyword = false;
204 switch (id.length) {
205 case 2:
206 keyword = (id === 'if') || (id === 'in') || (id === 'do');
207 break;
208 case 3:
209 keyword = (id === 'var') || (id === 'for') || (id === 'new') || (id === 'try');
210 break;
211 case 4:
212 keyword = (id === 'this') || (id === 'else') || (id === 'case') || (id === 'void') || (id === 'with');
213 break;
214 case 5:
215 keyword = (id === 'while') || (id === 'break') || (id === 'catch') || (id === 'throw');
216 break;
217 case 6:
218 keyword = (id === 'return') || (id === 'typeof') || (id === 'delete') || (id === 'switch');
219 break;
220 case 7:
221 keyword = (id === 'default') || (id === 'finally');
222 break;
223 case 8:
224 keyword = (id === 'function') || (id === 'continue') || (id === 'debugger');
225 break;
226 case 10:
227 keyword = (id === 'instanceof');
228 break;
229 }
230
231 if (keyword) {
232 return true;
233 }
234
235 switch (id) {
236 // Future reserved words.
237 // 'const' is specialized as Keyword in V8.
238 case 'const':
239 return true;
240
241 // For compatiblity to SpiderMonkey and ES.next
242 case 'yield':
243 case 'let':
244 return true;
245 }
246
247 if (isStrictModeReservedWord(id)) {
248 return true;
249 }
250
251 return isFutureReservedWord(id);
252 }
253
254 function isDecimalDigit(ch) {
255 return '0123456789'.indexOf(ch) >= 0;
256 }
257
258 function isHexDigit(ch) {
259 return '0123456789abcdefABCDEF'.indexOf(ch) >= 0;
260 }
261
262 function isOctalDigit(ch) {
263 return '01234567'.indexOf(ch) >= 0;
264 }
265
266
267 // 7.2 White Space
268
269 function isWhiteSpace(ch) {
270 return (ch === ' ') || (ch === '\u0009') || (ch === '\u000B') ||
271 (ch === '\u000C') || (ch === '\u00A0') ||
272 (ch.charCodeAt(0) >= 0x1680 &&
273 '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\uFEFF'.indexOf(ch) >= 0);
274 }
275
276 // 7.3 Line Terminators
277
278 function isLineTerminator(ch) {
279 return (ch === '\n' || ch === '\r' || ch === '\u2028' || ch === '\u2029');
280 }
281
282 // 7.6 Identifier Names and Identifiers
283
284 function isIdentifierStart(ch) {
285 return (ch === 36) || (ch === 95) || // $ (dollar) and _ (underscore)
286 (ch >= 65 && ch <= 90) || // A..Z
287 (ch >= 97 && ch <= 122) || // a..z
288 (ch === 92) || // \ (backslash)
289 ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch)));
290 }
291
292 function isIdentifierPart(ch) {
293 return (ch === 36) || (ch === 95) || // $ (dollar) and _ (underscore)
294 (ch >= 65 && ch <= 90) || // A..Z
295 (ch >= 97 && ch <= 122) || // a..z
296 (ch >= 48 && ch <= 57) || // 0..9
297 (ch === 92) || // \ (backslash)
298 ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch)));
299 }
300
301 function isIdentifier(name) {
302 var i, iz, ch;
303
304 // fallback for ES3
305 if (isKeyword(name) || isRestrictedWord(name)) {
306 return false;
307 }
308 if (name.length === 0) {
309 return false;
310 }
311
312 ch = name.charCodeAt(0);
313 if (!isIdentifierStart(ch) || ch === 92) { // \ (backslash)
314 return false;
315 }
316
317 for (i = 1, iz = name.length; i < iz; ++i) {
318 ch = name.charCodeAt(i);
319 if (!isIdentifierPart(ch) || ch === 92) { // \ (backslash)
320 return false;
321 }
322 }
323 return true;
324 }
325
326 function mayBeCompletionValue(node, ancestors) {
327 var i, ancestor;
328
329 if (node.type !== Syntax.ExpressionStatement) {
330 return true;
331 }
332
333 for (i = ancestors.length - 1; i >= 0; --i, node = ancestor) {
334 ancestor = ancestors[i];
335
336 switch (ancestor.type) {
337 case Syntax.FunctionExpression:
338 case Syntax.FunctionDeclaration:
339 return false;
340
341 case Syntax.BlockStatement:
342 case Syntax.Program:
343 if (arrayLast(ancestor.body) !== node) {
344 return false;
345 }
346 break;
347
348 case Syntax.SwitchCase:
349 if (arrayLast(ancestor.consequent) !== node) {
350 return false;
351 }
352 break;
353 }
354 }
355
356 return true;
357 }
358
359 function moveLocation(from, to) {
360 if (from.loc == null) {
361 return to;
362 }
363 to.loc = deepCopy(from.loc);
364 return to;
365 }
366
367 function deleteLocation(node) {
368 if (node.hasOwnProperty('loc')) {
369 return delete node.loc;
370 }
371 return false;
372 }
373
374 function convertToEmptyStatement(node) {
375 var i, iz, keys;
376 keys = estraverse.VisitorKeys[node.type];
377 for (i = 0, iz = keys.length; i < iz; ++i) {
378 delete node[keys[i]];
379 }
380 node.type = Syntax.EmptyStatement;
381 return node;
382 }
383
384 function isNegative(value) {
385 return value === value && (value < 0 || (value === 0 && 1 / value < 0));
386 }
387
388 function isFunctionBody(node, parent) {
389 return node.type === Syntax.BlockStatement && (parent.type === Syntax.FunctionDeclaration || parent.type === Syntax.FunctionExpression);
390 }
391
392 function isNumberLiteral(node) {
393 return node.type === Syntax.Literal && typeof node.value === 'number';
394 }
395
396 function isOptimizedArgument(argument) {
397 return isNumberLiteral(argument) && String(argument.value).length === 1;
398 }
399
400 function generateNegativeNode(value, node) {
401 var result;
402 result = {
403 type: Syntax.UnaryExpression,
404 operator: '-',
405 argument: {
406 type: Syntax.Literal,
407 value: -value
408 }
409 };
410 return (node) ? moveLocation(node, result) : result;
411 }
412
413 function isNegativeNode(node) {
414 return node.type === Syntax.UnaryExpression && node.operator === '-' && isNumberLiteral(node.argument);
415 }
416
417 function generateUndefined(node) {
418 var result = {
419 type: Syntax.UnaryExpression,
420 operator: 'void',
421 argument: {
422 type: Syntax.Literal,
423 value: 0
424 }
425 };
426 return (node) ? moveLocation(node, result) : result;
427 }
428
429 function isUndefined(node) {
430 return node.type === Syntax.UnaryExpression && node.operator === 'void' && isOptimizedArgument(node.argument);
431 }
432
433 function generateNaN(node) {
434 var result = {
435 type: Syntax.BinaryExpression,
436 operator: '/',
437 left: {
438 type: Syntax.Literal,
439 value: 0
440 },
441 right: {
442 type: Syntax.Literal,
443 value: 0
444 }
445 };
446 return (node) ? moveLocation(node, result) : result;
447 }
448
449 function isNaNNode(node) {
450 if (node.type === Syntax.BinaryExpression) {
451 if (isOptimizedArgument(node.left) && isOptimizedArgument(node.right)) {
452 return node.left.value === 0 && node.right.value === 0;
453 }
454 }
455 return false;
456 }
457
458 function generateFromValue(value) {
459 if (typeof value === 'number') {
460 if (isNaN(value)) {
461 return generateNaN();
462 }
463 if (isNegative(value)) {
464 return generateNegativeNode(value);
465 }
466 }
467 if (value === undefined) {
468 return generateUndefined();
469 }
470 return {
471 type: Syntax.Literal,
472 value: value
473 };
474 }
475
476 function isReference(node) {
477 var type = node.type;
478 return type === Syntax.Identifier || type === Syntax.MemberExpression;
479 }
480
481 // @param last last element of SequenceExpression
482 // @param parent parent element of SequenceExpression
483 // @param scope scope
484 function canExtractSequence(last, parent, scope) {
485 var ref;
486 if (parent.type === Syntax.CallExpression) {
487 if (last.type === Syntax.Identifier) {
488 if (last.name === 'eval') {
489 // This becomes direct call to eval.
490 return false;
491 }
492 ref = scope.resolve(last);
493 return ref && ref.isStatic();
494 }
495 return last.type !== Syntax.MemberExpression;
496 } else if (parent.type === Syntax.UnaryExpression) {
497 if (parent.operator === 'delete') {
498 return !isReference(last);
499 } else if (parent.operator === 'typeof') {
500 if (last.type === Syntax.Identifier) {
501 ref = scope.resolve(last);
502 return ref && ref.isStatic();
503 }
504 }
505 } else if (parent.type === Syntax.UpdateExpression) {
506 return !isReference(last);
507 }
508 return true;
509 }
510
511 function delegateVariableDeclarations(stmt, func) {
512 var decls, target;
513
514 decls = [];
515
516 estraverse.traverse(stmt, {
517 enter: function (node) {
518 var i, iz, decl;
519 if (node.type === Syntax.VariableDeclaration) {
520 if (node.kind === 'let' || node.kind === 'const') {
521 return;
522 }
523 for (i = 0, iz = node.declarations.length; i < iz; ++i) {
524 decl = node.declarations[i];
525 delete decl.init;
526 decls.push(decl);
527 }
528 return estraverse.VisitorOption.Skip;
529 } else if (escope.Scope.isVariableScopeRequired(node)) {
530 return estraverse.VisitorOption.Skip;
531 }
532 }
533 });
534
535 if (!decls.length) {
536 return null;
537 }
538
539 target = null;
540
541 estraverse.traverse(func.body, {
542 enter: function (node, parent) {
543 if (node === stmt) {
544 return estraverse.VisitorOption.Skip;
545 } else if (escope.Scope.isVariableScopeRequired(node)) {
546 return estraverse.VisitorOption.Skip;
547 } else if (node.type === Syntax.VariableDeclaration && node.kind === 'var') {
548 // list is not allowed
549 if (parent.type !== Syntax.ForInStatement) {
550 target = node;
551 return estraverse.VisitorOption.Break;
552 }
553 }
554 }
555 });
556
557 if (target) {
558 target.declarations = target.declarations.concat(decls);
559 return null;
560 } else {
561 return {
562 type: Syntax.VariableDeclaration,
563 kind: 'var',
564 declarations: decls
565 };
566 }
567 }
568
569 function isScopedDeclaration(node) {
570 if (node.type === Syntax.VariableDeclaration && (node.kind === 'let' || node.kind === 'const')) {
571 return true;
572 } else if (node.type === Syntax.FunctionDeclaration) {
573 return true;
574 }
575 return false;
576 }
577
578 exports.deepCopy = deepCopy;
579 exports.stringRepeat = stringRepeat;
580 exports.sameValue = sameValue;
581
582 exports.Array = {
583 isArray: isArray,
584 from: arrayFrom,
585 of: arrayOf,
586 last: arrayLast,
587 empty: arrayEmpty
588 };
589
590 exports.Object = {
591 isObject: isObject,
592 has: has
593 };
594
595 exports.Syntax = Syntax;
596 exports.traverse = estraverse.traverse;
597 exports.replace = estraverse.replace;
598 exports.VisitorKeys = estraverse.VisitorKeys;
599 exports.VisitorOption = estraverse.VisitorOption;
600
601 exports.assert = assert;
602 exports.unreachable = unreachable;
603 exports.isFutureReservedWord = isFutureReservedWord;
604 exports.isStrictModeReservedWord = isStrictModeReservedWord;
605 exports.isRestrictedWord = isRestrictedWord;
606 exports.isKeyword = isKeyword;
607 exports.isIdentifier = isIdentifier;
608
609 exports.isDecimalDigit = isDecimalDigit;
610 exports.isHexDigit = isHexDigit;
611 exports.isOctalDigit = isOctalDigit;
612 exports.isWhiteSpace = isWhiteSpace;
613 exports.isLineTerminator= isLineTerminator;
614
615 exports.moveLocation = moveLocation;
616 exports.deleteLocation = deleteLocation;
617 exports.convertToEmptyStatement = convertToEmptyStatement;
618
619 exports.mayBeCompletionValue = mayBeCompletionValue;
620
621 exports.isNegative = isNegative;
622
623 exports.isFunctionBody = isFunctionBody;
624 exports.SpecialNode = {
625 generateNegative: generateNegativeNode,
626 isNegative: isNegativeNode,
627 generateUndefined: generateUndefined,
628 isUndefined: isUndefined,
629 generateNaN: generateNaN,
630 isNaN: isNaNNode,
631 isReference: isReference,
632 canExtractSequence: canExtractSequence,
633 generateFromValue: generateFromValue
634 };
635
636 exports.delegateVariableDeclarations = delegateVariableDeclarations;
637
638 exports.isScopedDeclaration = isScopedDeclaration;
639}());
640/* vim: set sw=4 ts=4 et tw=80 : */